Adding a logo uploader to your WordPress theme with the Theme Customizer

Let’s create a logo uploader using the new Theme Customizer, which was released with WordPress 3.4. This will allow users to place an image in our theme’s header; if no logo has been uploaded, we’ll fall back to displaying the site title and description instead.

Update, January 2015: There’s a much easier way now to add a logo to your theme: just add support for Site Logo in Jetpack.

For a more in-depth description of the Theme Customizer, including practical examples, code and more, see Otto’s excellent tutorials. If you are completely new to the Theme Customizer, I highly recommend at least scanning through them, to better understand the methods we’ll be calling in our code.

When working with the Theme Customizer, we should be creating sections, settings and controls within a function being fired on the customize_register hook. Create this function in your theme’s functions.php. The next three code blocks will go within this function.

function themeslug_theme_customizer( $wp_customize ) {
    // Fun code will go here
}
add_action( 'customize_register', 'themeslug_theme_customizer' );

First, we’ll create a new section for our logo upload. Note that the description will not be displayed when using the Theme Customizer; it is simply used for the section heading’s title attribute.

$wp_customize->add_section( 'themeslug_logo_section' , array(
    'title'       => __( 'Logo', 'themeslug' ),
    'priority'    => 30,
    'description' => 'Upload a logo to replace the default site name and description in the header',
) );

Next, we register our new setting. It doesn’t get any easier than this:

$wp_customize->add_setting( 'themeslug_logo' );

Lastly, we tell the Theme Customizer to let us use an image uploader for setting our logo:

$wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, 'themeslug_logo', array(
    'label'    => __( 'Logo', 'themeslug' ),
    'section'  => 'themeslug_logo_section',
    'settings' => 'themeslug_logo',
) ) );

That wraps up our work in functions.php.

To output our new logo to the screen, we’ll need to call our setting with get_theme_mod somewhere in our theme’s header (I’ll be working in my theme’s header.php template file). However, if the user hasn’t set a logo, we’ll want to output the site title and description instead.

<?php if ( get_theme_mod( 'themeslug_logo' ) ) : ?>
    <div class='site-logo'>
        <a href='<?php echo esc_url( home_url( '/' ) ); ?>' title='<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>' rel='home'><img src='<?php echo esc_url( get_theme_mod( 'themeslug_logo' ) ); ?>' alt='<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>'></a>
    </div>
<?php else : ?>
    <hgroup>
        <h1 class='site-title'><a href='<?php echo esc_url( home_url( '/' ) ); ?>' title='<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>' rel='home'><?php bloginfo( 'name' ); ?></a></h1>
        <h2 class='site-description'><?php bloginfo( 'description' ); ?></h2>
    </hgroup>
<?php endif; ?>

Style your logo container as desired, and you’re done! For an example of the above code in action, check out my Debut starter theme on GitHub.

Published by

Kirk Wight

I am a Code Wrangler at Automattic, helping make WordPress.com the best it can be. Pender Island, British Columbia, Canada is where I call home. Lover, not a fighter.

92 thoughts on “Adding a logo uploader to your WordPress theme with the Theme Customizer”

  1. Crickey that’s so super easy. The theme customizer looks pretty powerful. Thanks for sharing. I’ll need to update my theme and get rid of the theme options in favour of the customizer.

    1. Honestly, I never got in to options panels because I found working with the Settings API to be a pain in the ass for little return. The Theme Customizer has changed all that for me 🙂

      For all things Theme Customizer, Otto’s tutorials are invaluable, particularly regarding the real-time postMessage transport stuff.

    1. More planned when time allows! The Theme Customizer is easily my favourite thing going on in WordPress themes these days.

  2. Nice tutorial.

    I noticed that you cannot define an ‘default logo’ image, or at least i’m not being able to display it, if there is no logo uploaded. Any hints?

    Thanks,
    Castle

    1. To have a default logo, just place it between the “else” and “endif” in your header.php file, replacing the <hgroup> I’ve used above. This is the code that gets displayed if no logo is set in the Theme Customizer.

  3. Not sure if there’s something wrong with the snippet copy & pasting, but this code didn’t work for me. Is there a full copy of the code for simple clean copy & paste? Thank You for the tut.

  4. Thank You for the tutorial. I found this on Github and thought you may find it interesting incase you haven’t found it yet. https://gist.github.com/eduardozulian/4739075

    This is supposed to extend the options of the custom image uploader to function properly like the background and header image do by default. For some reason, I cannot get it to work. I posted a request on the page as well, but haven’t gotten any responses, so I thought it would be useful for everyone to share this code snippet here.

    1. You would want anything to do with Google Analytics to persist regardless of the active theme, so a plugin is the only way to implement something like that. The Theme Customizer is only appropriate for theme-specific settings and options.

  5. 1. function wetlands_customize_register( $wp_customize ) {
    2. //All our sections, settings, and controls will be added here
    3. }
    4. add_action( ‘customize_register’, ‘wetlands_customize_register’ );
    5. $wp_customize->add_section( ‘wetlands_logo_section’ , array(
    6.    ‘title’ => __( ‘Logo’,’wetlands’ ),
    7.    ‘priority’ => 30,
    8.    ‘description’ => ‘Upload a logo to replace the default site name and description in the
    9. header’,
    10. ) );
    11. $wp_customize->add_setting( ‘wetlands_logo’ );
    12. $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize,
    13. ‘wetlands_logo’, array(
    14.    ‘label’    => __( ‘Logo’, ‘wetlands’ ),
    15.    ‘section’  => ‘wetlands_logo_section’,
    16.    ‘settings’ => ‘wetlands_logo’,
    17. ) ) );

    hello, im kinda new to this theme customizer then i tried this but i get an error: ”
    Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ‘)’ in C:WPInstantWP_4.3iwpserverhtdocswordpresswp-contentthemesBLANK-Themefunctions.php on line 6″

    i hope you can help me out on this. thank you.

    1. Hey Lunatech, you need to move lines 3 and 4 beneath line 17 so that the add section, add setting and add control all sit within the wetlands_customize_register function.
      I hope that helps – and makes sense!

  6. Most awesome, thanks so much for sharing!!! I’d previously lost the battle trying to do the same with the settings API. Theme Customizer and your tutorial rock!!

    1. Embed videos in the Customizer itself, or do you mean adding a video instead of the logo in the tutorial above?

      1. Hi Kirk!

        Yes maybe a video instead of logo to be put on the front page, is this possible? I have been searching for solutions, though I have solved the logo with you’re tutorial.

        regards!

  7. Great job… this came in handy. I’m usually all about doing things my way but the Theme Customization API isn’t as bad as I thought… in some areas. 🙂

    1. Hm, not sure. I just verified that it all works for me. Does your logo show up in the Logo section at all? Or do you mean it doesn’t show up on the site? (That would mean you still need to do the second part of the instructions above in header.php).

      1. the logo shows up as the default but when i try to upload another logo or image just to test it . i click “select a file” go to the folder and choose the image and nothing happens when the new image is choosen. im not quiet sure why ???

    2. and yeah, forgot to metion – the logo does not appear on upload in the customizer, or on the front end. Any help would be awesome!

    3. ok – figured it out – it was a permissions issue for my /uploads folder. pop’d a 775 on that n now we’re in business. thanks for the tut!

  8. i implemented this code to my functions.php and it looks like its all there but when you try to upload or drag and drop nothing happens??? any suggestions???

  9. This worked locally for me but when I uploaded it to my server, the image doesn’t show up on the page at all, img src is empty. Any thoughts, is it permissions? I’ve set them all to 775 as per the last comment.

    Thanks, A

  10. scratch that – I had changed the “get_theme_mod( ‘themeslug_logo’ )” part in functions but not in header!
    This was a great help by the way, many thanks.
    A

  11. i used your code but when i load a picture the whole theme goes blank; i used a jpeg image of 81*76 px .and also when picture is not loaded the default information is shown at tope of html page even though i have place header templete code inside tag of header.php

    1. The logo is only loaded if one is set in the Customizer, so when the user removes it from the Customizer setting, it will no longer display. No changes are needed to the above code.

      1. I guess what I’m asking is how do you remove the logo using the customizer setting? I don’t see any other way to remove the logo after it has been set.

        1. Oh, click the little black arrow to the right of the Customizer logo setting, and then click Remove Image at the bottom of the section that opens up.

          1. Are you on a recent version of WordPress? It’s a core thing, so it should just be there on any image uploader in the Customizer, I think.

  12. i implied the it in my new theme and got new error::
    Fatal error: Call to undefined function get_theme_mode() in

    in my header.php

  13. OMG … I just spent two days trying to do this the old (before the customizer) way using 10 times as much code !! Thanks for posting 🙂

  14. Hi Kirk,

    I appreciate the tutorial. I’m trying to modify it to work with two different images (one to be featured in the header, and one in the footer). When I upload the images, however, it doesn’t grab the URLs, and I end up with empty img tags.

    Here’s what I have in my functions.php:

    function themeslug_theme_customizer( $wp_customize ) {
    $wp_customize->add_section( ‘themeslug_logo_section’ , array(
    ‘title’ => __( ‘Logos’, ‘themeslug’ ),
    ‘priority’ => 30,
    ‘description’ => ‘Upload a logo for the header and footer of your site (header logo will replace the site title)’,
    ) );
    $wp_customize->add_setting( ‘themeslug_header_logo’ );
    $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, ‘themeslug_header_logo’, array(
    ‘label’ => __( ‘Header Logo’, ‘themeslug’ ),
    ‘section’ => ‘themeslug_logo_section’,
    ‘settings’ => ‘themeslug_header_logo’,
    ) ) );
    $wp_customize->add_setting( ‘themeslug_footer_logo’ );
    $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, ‘themeslug_footer_logo’, array(
    ‘label’ => __( ‘Footer Logo’, ‘themeslug’ ),
    ‘section’ => ‘themeslug_logo_section’,
    ‘settings’ => ‘themeslug_footer_logo’,
    ) ) );
    }
    add_action(‘customize_register’, ‘themeslug_theme_customizer’);

    And here’s what I have in my header:

    <a href='’ title=” rel=’home’><img src='’ alt=”>

    <a href='’ title=” rel=’home’>

    Am I missing something here?

    Any help you might offer would be greatly appreciated.

  15. Hi Kirk,

    I appreciate the tutorial. I’m trying to modify it to work with two different images (one to be featured in the header, and one in the footer). When I upload the images, however, it doesn’t grab the URLs, and I end up with empty img tags.

    Here’s what I have in my functions.php:

    function themeslug_theme_customizer( $wp_customize ) {
    $wp_customize->add_section( ‘themeslug_logo_section’ , array(
    ‘title’ => __( ‘Logos’, ‘themeslug’ ),
    ‘priority’ => 30,
    ‘description’ => ‘Upload a logo for the header and footer of your site (header logo will replace the site title)’,
    ) );
    $wp_customize->add_setting( ‘themeslug_header_logo’ );
    $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, ‘themeslug_header_logo’, array(
    ‘label’ => __( ‘Header Logo’, ‘themeslug’ ),
    ‘section’ => ‘themeslug_logo_section’,
    ‘settings’ => ‘themeslug_header_logo’,
    ) ) );
    $wp_customize->add_setting( ‘themeslug_footer_logo’ );
    $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, ‘themeslug_footer_logo’, array(
    ‘label’ => __( ‘Footer Logo’, ‘themeslug’ ),
    ‘section’ => ‘themeslug_logo_section’,
    ‘settings’ => ‘themeslug_footer_logo’,
    ) ) );
    }
    add_action(‘customize_register’, ‘themeslug_theme_customizer’);

    And here’s what I have in my header:

    Am I missing something here?

    Any help you might offer would be greatly appreciated.

  16. Edit: here’s what I have in my header:

    <a href='’ title=” rel=’home’><img src='’ alt=”>

    <a href='’ title=” rel=’home’>

  17. Hey man, Having trouble with this, I’ve put all the code in the right places but no idea how to then upload a chosen image? is there a place I need to put the url? my theme doesn’t have a header image uploader option

  18. Hey man, having issue with this, I’ve put the code in all the right places but nothing has changed on my dashboard or website. How do you actually upload an image once the code is put in?

      1. I hear ya, but under the customize tab in my dashboard it just has ‘Site Title and Tagline’. It is worth mentioning that my theme never had a ‘logo section’ in the customizing menu. Does this code still work for such themes?

          1. Okay, I’ve tried everything I can think of, moving the code around in certain places within function and header php but nothing works for me. I managed to get the tagline to display by default, but it hides behind my sidebar which already has the tagline written on it. And still no option to upload logo in the customizer section of dashboard.

            http://coloureval.co.uk

            This is what my website looks like currently.

            I’d be willing to give you my login and password to try yourself, as I really would like this to work!

          2. No worries, through perseverance I fixed it! Instead I used a Meta Slider, set just one image for it, then entered it in the correct part of the header.php body which added it to the sidebar!

            and because it’s supposed to be a feature slider, it let me add a URL right in

            Amazing stuff.

            thanks so much for the help though, very quick to reply!

  19. Wow thank you man , this helped a lot… An excellent tutorial and very concise… Can i do this for any images on my theme ?

  20. Great Tutorial Kirk.
    i am trying to add a custom image to logo, how can i do that and call the same image ?
    i have added a image size

    add_image_size( ‘logo-image’, ‘200’, ‘300’, true );
    I m not sure how to call it, to get specific width, height image there? can you help

    Thanks in advance.

  21. Nice article, although when I copied the code I noticed some of the php closing tags are incomplete (lines 1, 3 & 8 of the header.php content).

  22. Is there an updated version of this? This one didn’t seem to do anything for me and TAC gave warnings about some of the code not being right. I don’t remember what exactly it was, just that it was about add_setting

    1. Not sure what TAC is, but AFAIK nothing here is broken. I don’t worry about it much these days, as the whole process is way easier by just using Site Logo in Jetpack.

  23. Getting this error-> Fatal error: Call to a member function add_section() on a non-objects

  24. HI, thank you for the tutorial, it’s been very helpful.

    Is it possible to get the url of the logo as variable in the function?
    It would be great if you help me with this!

    Thanks again.

      1. I’m trying not to change the header.php file. So I check if a logo is uploaded, than I use css to remove the site title and description.

        But than I need the url of the logo to show the logo? Do you understand what I’m asking?

        Here is the code:

        if ( get_theme_mod( ‘jeton_logo’ )){

        ?>

        .site-title,
        .site-description {
        display: none;
        }
        .site-branding{
        // Here I need to show the logo
        }

        <?php
        }

        1. I’m afraid I don’t understand your approach to be able to help much, but the result of your `get_theme_mod` should be the URL to the image. Good luck!

          1. Yeah that’s exactly what I needed, get_theme-mod really returns the URL. Thank you very much, you’ve been very helpful.

            Now I can add logo uploader without touching the header.php.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s