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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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'); |
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
- Custom Logo (codex)
- Custom Logo (trac)
- Sage
- Bootstrap
- GitHub Gist
Thank you! This was great!
However i needed to add “()” to the
Thanks, glad it was helpful!