Fun with template tags: dynamic_sidebar

The last couple of weeks I’ve been reading the core code more and more. I like it. Came to the conclusion I really don’t know every hook or filter. I don’t claim to though. I like knowing enough to make a functional theme or even a plugin. Yes, I’ve been recently dabbling with one but that’s for another post.

The reason for this post is to share some knowledge. Hopefully somebody finds this useful or helpful.

The function

For this post I will be using dynamic_sidebar(). It’s a fairly common template tag in themes. It gets a widgetized area and outputs them in a designated area. In order for that to happen you must first have a registered area. We do that by using register_sidebar(). For demonstrational purposes we will use:

register_sidebar( array(
	'name'          => __( 'Footer Area', 'dademo' ),
	'id'            => 'footer-area',
	'description'   => __( 'Add widgets here to appear in your sidebar.', 'dademo' ),
	'before_widget' => '<aside id="%1$s" class="widget %2$s">',
	'after_widget'  => '</aside>',
	'before_title'  => '<h2 class="widget-title">',
	'after_title'   => '</h2>',
) );

Great! So we created a widgetized area with an ID of footer-area. It can be anything we want but we will currently stick to simple naming conventions. Now, let us look at the core code, shall we?

The core code

The function itself is quite a few lines of code. Approximately 160 lines. I’m not going to post all of that code. The developer reference page has it and you can even view on trac. The ones that matter most for this post are two lines.

The first line:

do_action( 'dynamic_sidebar_before', $index, true );

The second line:

do_action( 'dynamic_sidebar_after', $index, true );

Notice something a little strange about it? I’m referring to the $index part of course. This is the neat part of it all. What does that little part mean?

Our hook

The cool part is that you can hook to specific widgetized areas if you want. I know you may be asking what I mean by this so I’ll demonstrate a little bit. Take our previous example of footer-area above and we will wrap it within a <section> element tag with a class of row.

add_action( 'dynamic_sidebar_before', 'demo_sidebar_before' );
function demo_sidebar_before( $index ){
	if ( $index == 'footer-area' ){
		echo '<section class="row">';
	}
}
add_action( 'dynamic_sidebar_after', 'demo_sidebar_after' );
function demo_sidebar_after( $index ){
	if ( $index == 'footer-area' ){
		echo '</section><!-- Widgetized footer area -->';
	}
}

From there it would render:

<section class="row">
	<aside id="recent-posts-4" class="widget widget_recent_entries">
	<h2 class="widget-title">Recent Posts</h2>
	<ul>
		<li>
		<a href="/2015/04/13/aesop-testing/">Aesop testing</a>
		/li>
		<li>
		<a href="/2015/04/13/sampling-some-code/">Sampling some code</a>
		</li>
		<li>
		<a href="/2015/04/08/another-gallery/">another gallery</a>
		</li>
		<li>
		<a href="/2015/04/08/gallery-7/">gallery 7</a>
		</li>
		<li>
		<a href="/2015/04/08/gallery-6/">gallery 6</a>
		</li>
	</ul>
	</aside>
</section><!-- Widgetized footer area -->

As you can see it created the section element and inside of it is a simple recent posts widget. Now, as I mentioned that is for specific widgetized areas. The thing to remember is to use the ID of the widgetized area to conditionally add or remove. It is that $index that is used to test. You can add things to every single dynamic_sidebar call by not even checking. Let’s say we have two widgetized areas. One in the footer and the other just above the content. We will call that section, “content-above.”

I know, very creative. I said it would be simplistic, didn’t I?

Okay, we wanted to add few things. Let’s say we wanted to add an image to both of those sections. We could edit two different files depending on how your theme is structured. Sounds a little painful, right? So, we will use our handy-dandy little hook:

add_action( 'dynamic_sidebar_before', 'demo_sidebar_before' );
function demo_sidebar_before( $index ){
	echo '<section class="row">';
	echo '<img src="' . get_template_directory_uri() . '/img/divider.png" />';
}
add_action( 'dynamic_sidebar_after', 'demo_sidebar_after' );
function demo_sidebar_after( $index ){
	echo '</section><!-- Widgetized area with image -->';
}

Pretty cool, right? What’s super cool is it will render like:

<section class="row">
<img src="path/to/img" />
<!-- widgets -->

</section><!-- Widgetized area with image -->
<section class="content row">
<!-- the_content -->
</section>

<section class="row">
<img src="path/to/img" />
<!-- widgets -->
</section><!-- Widgetized area with image -->

Yes, all that markup where ever you are using dynamic_sidebar().

Advanced fun

This part I’m writing as my left eye is twitching only because it deals with widgets in themes. Yes, I’ve never liked including them. This part deals with hooking to particular widgets in your theme.

Yes, you could simply edit the file that has the widget but where is the fun in that? This time we will use an action hook.

add_action( 'dynamic_sidebar', 'demo_sidebar' );
function demo_sidebar( $obj ){
	
	if ( $obj['callback'][0]->id_base == 'meta' ){
		printf( '<span>%s</span>', __( 'So much meta', 'dademo' ) );
	}
	// Alternatively
	// if ( preg_match( '/meta-/', $obj['id'] ) ){
	//	printf( '<span>%s</span>', __( 'So much meta', 'dademo' ) );
	// }
}

Does look a little complex, right? Let’s break it down a little.

First, we create the hook in line 1. Then we create our callback function in line 2. Doing good so far. Line 3 is where it does get a little odd. What does it mean? What does it mean?!

Okay, it may look a little complex to some but I’ll explain a little bit more.

When using dynamic_sidbar() it uses an array for the widgets. If there are no widgets then the function returns a false value. If there are it creates an associative array of the widget instance. That array is what we pass our callback function. In the example it is called $obj. In that array we have a key called callback. It, too, is an array.

We are looking for the first item on there because it holds the important part. The information about the widget object. The example is looking for the id_base of the widget. You know that little part you named when you registered the widget.

The alternative uses preg_match to match the ID of the widget’s instance. Yes, you can do specific instances as well.

By Jose

Born in El Salvador. Loves to read, write, draw, paint, build, test, typography, hike, photography, art, design, sewing, and many other things.