Filtering the WordPress Custom Logo

WordPress 4.5 added the custom logo feature. It’s pretty nice, and where possible I try to use native WordPress functionality, but the default markup returned by get_custom_logo() isn’t always what I’m looking for. Fortunately there’s a filter included just for this.

I build my sites with Sage, most of them using Bootstrap for the front end. Here’s a little function I wrote to leverage the native Custom Logo function, and give me back the markup I want.

The Goal

So, here’s what I’m trying to achieve. The default custom logo gives us markup that looks like this –


<a href="some-link" class="custom-logo-link" rel="home" itemprop="url">
  <img src="some-logo">
</a>

Whereas I’m generally lookng for something like this –


<a class="navbar-brand" href="some-link">
  <span class="sr-only">Some Site</span>
  <img class="img-responsive" src="some-logo">
</a>

I like to include the site title regardless, and just hide it with a screen-reader friendly class when a logo is present. I also like to bake the conditional logic right into my function as a way of keeping my templates a little cleaner. Every little bit helps!

The Stuff

For sarters, the first thing to do is enable custom-logo support. I use Sage, and in versions < 9 I’ll generally drop it in lib/setup.php


// Enable custom logo support
// https://codex.wordpress.org/Theme_Logo
add_theme_support( 'custom-logo' );

And here’s the function I use to filter the markup.


<?php
/**
* Site Brand
*
* Output site branding
*
* Use native WordPress site logo with custom (bootstrap friendly) markup
* Falls back to text title if logo is not set.
*
* @param $html
*
* @return string
*/
function siteBrand($html)
{
// grab the site name as set in customizer options
$site = get_bloginfo('name');
// Wrap the site name in an H1 if on home, in a paragraph tag if not.
is_front_page() ? $title = '<h1>' . $site . '</h1>' : $title = '<p>' . $site . '</p>';
// Grab the home URL
$home = esc_url(home_url('/'));
// Class for the link
$class = 'navbar-brand';
// Set anchor content to $title
$content = $title;
// Check if there is a custom logo set in customizer options…
if (has_custom_logo()) {
// get the URL to the logo
$logo = wp_get_attachment_image(get_theme_mod('custom_logo'), 'full', false, array(
'class' => 'brand-logo img-responsive',
'itemprop' => 'logo',
));
// we have a logo, so let's update the $content variable
$content = $logo;
// include the site name markup, hidden with screen reader friendly styles
$content .= '<span class="sr-only">' . $title . '</span>';
}
// construct the final html
$html = sprintf('<a href="%1$s" class="%2$s" rel="home" itemprop="url">%3$s</a>', $home, $class, $content);
// return the result to the front end
return $html;
}
add_filter('get_custom_logo', __NAMESPACE__ . '\\siteBrand');

view raw

brand.php

hosted with ❤ by GitHub

Everything is commented, but here’s the run-down.

  • The function is filtering the custom logo function, so it takes that html as its input.

  • The first thing I do is grab the site name, since I like to always include it with my output.

  • First I check to see if we’re on the home page – if so I’ll wrap the site title in an H1, otherwise I’ll wrap it in a paragraph tag since those pages will use the H1’s for their own titles. I’ll stash that in a variable called $title.

  • Now that I’ve got the site title squared away I set up a variable containing the link to the home page, $home and a variable to hold my css classes, $class.

  • Next I set up my $content variable, which serves as my fallback, and check to see if there’s a custom logo.

    (I know, I’m kind of variable happy – Here’s why I stash the site title in a variable called $content. $home, $title and $class remain constant, but $content will get updated if a custom logo is present, otherwise it just gets passed along to the output as is. Make sense?)

  • If has_custom_logo() returns true, I just mirror what’s in the native function, with my own small tweaks. I update the content to include the src to the logo file, then append the title variable, wrapped in a span tag and hidden with Bootstraps sr-only class. Otherwise, the unaltered $content is passed along.

  • Finally, the markup is put together using sprintf, again, mirroring the native function, and returned to the template file.

Output

Since we’re just filtering the existing custom logo function nothing special is required to use it. In a typical Sage 8 site, in my header.php template, I’ll replace:

<a class="navbar-brand" href="<?= esc_url(home_url('/')); ?>"><?php bloginfo('name'); ?></a>

With:

<?php the_custom_logo; ?>

That’s it!

The resulting markup looks something like this:


<a href="http://local.wordpress.dev/" class="navbar-brand" rel="home" itemprop="url">
  <img width="150" height="150" src="/wp-content/uploads/2013/03/image-alignment-150x150.jpg" class="brand-logo img-responsive" alt="Image Alignment 150x150" itemprop="logo">
  <span class="sr-only"><h1>Local WordPress Dev</h1></span>
</a>

And the fallback, without a logo added:


<a href="http://local.wordpress.dev/" class="navbar-brand" rel="home" itemprop="url">
  <h1>Local WordPress Dev</h1>
</a>

That’s it! A quick, nice fallback that leverages various native WordPress super powers. 🙂 Pretty handy.

How do you work with logos in WordPress?

Resources

2 responses to “Filtering the WordPress Custom Logo

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.