Always a work in progress

Yesterday I was able to change out the theme to this site. I spent most of the day just fiddling and trying to get things to just work. I took a theme from the free repository and scrapped a lot the unused files.

Yeah.

There were quite a few that I didn’t really need. Many of which were WooCommerce ones. Maybe I’ll get back to that one day but for now, this site will be for just random code things I guess.

The thing I do need to get working is the SCSS compiling because there are a lot of classes that are not really being used. And then getting the JS minification as well. I went the super old school way and just copy-pasted code from one file to another. It was fun getting back to basics. The fun part was actually getting to use a decent header image that I took a long time ago.

Being able to use a photo of my own definitely makes it more fun too. I honestly don’t recall when I took the photo but I do know that I wanted to use it for something.

I’m sure there are more things I probably missed along the way but for now it works and the site is a bit faster too. I do want to improve on that little but that’s going to be for some other time.

🤣

Copy paste is hurting your theme

I’ve seen quite a few themes that have been doing this thing of passing an argument to the function when they could be using a filter. I get it we all have our methods. But when there is a better practice would you rather use the better practice or a wrong one?

I choose the better practice. Any day. The last several themes I’ve encountered have been using a snippet that has driven me up a wall. A very unhappy wall. The following code appears to be used a quite a few themes and it needs to stop. Like quickly.

<?php
$commenter = wp_get_current_commenter();
$req = get_option( 'require_name_email' );
$aria_req = ( $req ? " aria-required='true'" : '' );

$comments_args = array(
	// change the title of send button
	// 'label_submit'=>'Send',
	// change the title of the reply section
	// 'title_reply'=>'Write a Reply or Comment',
	// remove "Text or HTML to be displayed after the set of comment fields"
	'comment_notes_after' => ' ',
	// redefine your own textarea (the comment body)
	'comment_field' => '<p class="comment-form-comment"><textarea id="comment" name="comment" aria-required="true" placeholder="'. __('Your Message...', 'text-domain') .'" rows="8" cols="37" wrap="hard"></textarea></p>',
	'fields' => apply_filters( 'comment_form_default_fields', array(
		'author' => '<div class="row"><div class="col-md-4"><p class="comment-form-author">' . '<input id="author" placeholder="'. __('Your name *....', 'text-domain') .'" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' />' . ( $req ? '<span style="color:red" class="required"></span>' : '' ) . '</p></div>',
		'email' => '<div class="col-md-4"><p class="comment-form-email">' . '<input id="email" placeholder="'. __('Your email *...','text-domain') .'" name="email" type="text" value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' />' . ( $req ? '<span style="color:red" class="required"></span>' : '' ) . '</p></div>',
		'url' => '<div class="col-md-4"><p class="comment-form-url">' . '<input id="url" placeholder="'.  __('Your website...', 'text-domain') .'" name="url" type="text" value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30" /></p></div></div>'
		) ),
);

comment_form($comments_args); ?>

The biggest reason is that you can use a filter for all of that. Not only is it cleaner it is much, much child-theme friendlier as well. Actually there are two filters that you can use as well! The first one is the comment_form_default_fields. The second is the comment_form_defaults. Each one returns an associative array.

Let’s look at the first one:

Default Fields

The default fields filter is super simple and you can add, remove and modify the input fields for the comment form. I can’t think of a major reason to want to add to that in a theme but that is a possibility. Let’s see a quick example of just removing the wrapping p tags:

add_filter( 'comment_form_default_fields', 'jmc_commentd_fields' );
function jmc_commentd_fields( $fields ) {

	// get the current commenter if available
	$commenter = wp_get_current_commenter();

	// core functionality
	$req      = get_option( 'require_name_email' );
	$aria_req = ( $req ? " aria-required='true'" : '' );
	$html_req = ( $req ? " required='required'" : '' );

	// Change just the author field
	$fields['author'] = '<label for="author">' . __( 'Name:', 'text-domain' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label><input id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30" maxlength="245"' . $aria_req . $html_req . ' />';
	return $fields;

}

For those fields, there are three that are available:

  • name
  • email
  • url

Do make sure that that you are somehow showing that the site owner does or does not require the name and email to be filled out.

Form Defaults

The comment_form_defaults is very much like the comment_form_default_fields in that it returns an associative array as well. The possible keys are:

  • fields
  • comment_field
  • must_log_in
  • logged_in_as
  • comment_notes_before
  • comment_notes_after
  • action
  • id_form
  • id_submit
  • class_form
  • class_submit
  • name_submit
  • title_reply
  • title_reply_to
  • title_reply_before
  • title_reply_after
  • cancel_reply_before
  • cancel_reply_after
  • cancel_reply_link
  • label_submit
  • submit_button
  • submit_field
  • format

Very much like the previous filter we can use something like:

add_filter( 'comment_form_defaults', 'jmc_change_comment_form' );
function jmc_change_comment_form( $defaults ) {

	// Change the "cancel" to "I would rather not comment" and use a span instead
	$defaults['cancel_reply_before'] = '<span class="cancel-reply">';
	$defaults['cancel_reply_link'] = __( 'I would rather not comment', 'text-domain' );
	$defaults['cancle_reply_acter'] = '</span>';

	return $defaults;
}

It is very important that you return that array otherwise your fields will not show.

Some theme review videos

It’s been some time since I was last able to record some video on theme reviews. The last time I did it was a quick overview of my review process. Super simplistic overview of a theme review. Today I was able to record an overview of what an admin review can be.

As you can see I tend to keep a tab open to the requirement list. Part of that reason is so that I can quickly link to the section that needs to be addressed. The other video I was able to create was of a quick overview of the approved themes list. This is where themes go once the reviewer feels all things have been met so an admin can look over just in case things were missed. That video is:

Hope that helps out at least one person in how WordPress theme reviews work as well as the workflow. If you really want to learn more then read about the entire process here or even join the team.

Working with paginate_links

It is no secret that I try to advocate the use of core functions when possible. The idea of maintaining less code is a great one for any developer. It’s the old set it and forget mentality.

What I do see a lot of is the use of my_theme_pagination that uses get_pagenum_link in order to get all the page links. Yes it does use a core function but it uses it several times. Why not just use a core function that has been available since 2.1? Talk about way back, right? The best part is that you are given a few options when you use paginate_links.

The core code

Let us take a look at the core code. The function is found in the general-template.php file of the wp-includes folder. There are approximately 142 lines that make up this function. As you can see there is quite a bit of logic behind it to work. We will look at the key things. The first one being the array we can pass as an argument, and the second being the type key in that array.

You can use the function without passing anything to it and it will work. There is a reason for that. The $args parameter that can be passed gets merged with a few defaults. What are those, you ask? Here they are:

$defaults = array(
	'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below)
	'format' => $format, // ?page=%#% : %#% is replaced by the page number
	'total' => $total,
	'current' => $current,
	'show_all' => false,
	'prev_next' => true,
	'prev_text' => __('&laquo; Previous'),
	'next_text' => __('Next &raquo;'),
	'end_size' => 1,
	'mid_size' => 2,
	'type' => 'plain',
	'add_args' => array(), // array of query args to add
	'add_fragment' => '',
	'before_page_number' => '',
	'after_page_number' => ''
);

$args = wp_parse_args( $args, $defaults );

Quite a few options available to use. For the sake of this post we will focus on mostly on the type. There are three possible return types. They are array,list, and an empty value. We can see those towards the end of the function:

switch ( $args['type'] ) {
	case 'array' :
		return $page_links;

	case 'list' :
		$r .= "<ul class='page-numbers'>\n\t<li>";
		$r .= join("</li>\n\t<li>", $page_links);
		$r .= "</li>\n</ul>\n";
		break;

	default :
		$r = join("\n", $page_links);
		break;
}

It uses a switch statement to set the $r value that is ultimately returned. Yes, paginate_links returns and does not output any content. This is where we can actually take advantage of that.

Usage

Now with that in mind let us create some example usage, yeah? This is the part that gets fun! So we will take a look at using all three options and how they can be expanded or altered to suit your theme’s needs.

Array

Returning the array is one of the neater ways of using the function. The reason is that it returns an array of links. The amount of links is the amount of keys available for us to manipulate. Yes, we can style to our choosing. Let’s look at a sample return:

Array
(
    [0] => <span class='page-numbers current'>1</span>
    [1] => <a class='page-numbers' href='http://localhost/page/2/'>2</a>
    [2] => <a class='page-numbers' href='http://localhost/page/3/'>3</a>
    [3] => <span class="page-numbers dots">&hellip;</span>
    [4] => <a class='page-numbers' href='http://localhost/page/10/'>10</a>
    [5] => <a class="next page-numbers" href="http://localhost/page/2/">Next &raquo;</a>
)

What’s cool about that is you can see that by default you have the CSS classes page-number, current, and dots that you can use for some styling. Pretty awesome if you ask me. You can now expand upon that markup. A good way is by using the foreach to loop over and create your HTML markup. A quick example is:

$links = paginate_links( array( 'type' => 'array' ) );

echo '<div class="pagination col-6">';
foreach( $links as $link ){
	echo $link;
}
echo '</div>';

Yes, that is a super quick way of doing things but you get the idea. You can expand upon that to your heart’s content and add your needed classes or markup.

List

Another way is returning the list. An already HTML markup of our links in an unordered list. The returning text looks a little like:

<ul class='page-numbers'>
	<li><span class='page-numbers current'>1</span></li>
	<li><a class='page-numbers' href='http://locahost/page/2/'>2</a></li>
	<li><a class='page-numbers' href='http://localhost/page/3/'>3</a></li>
	<li><span class="page-numbers dots">&hellip;</span></li>
	<li><a class='page-numbers' href='http://localhost/page/10/'>10</a></li>
	<li><a class="next page-numbers" href="http://localhost/page/2/">Next &raquo;</a></li>
</ul>

What is super awesome about it is you can use just one line of code:

echo paginate_links( array( 'type' => 'list' ) );

Super awesome, right? The reason I love that is you can just leave that code and style it all. No special markup to worry about as it is already taken care of. You can use something like:

ul.page-numbers {
  clear: both;
  font-size: 1.4em;
  color: #deaf01;
}

ul.page-numbers li {
  display: inline-block;
}

It doesn’t have to be super crazy but you get the idea.

Empty value

Now for the simplest way of using the function.

echo paginate_links();

A lot of work, right? Super, super simple and you don’t have to worry about creating any extra markup. That is if you don’t want to. It returns a string of all the links and you can go about your business. If you really like super simple HTML markup then please use that.

User changes

Yes, we can have a user change a few of the things too if we want. Let’s take a quick look at how we can change the amount of links to show around the current page.

function jc_pagination(){
	echo paginate_links( 
		array(
		'show_all' => get_theme_mod( 'all-links', false ),
		'type' => 'list',
		'mid_size' => get_theme_mod( 'mid-links', 3 )
		)
	)
}

Pretty cool, right? With that get_theme_mod you can now have the user decide how many links will show before and after the current page. Yes, it is a minor touch but it can go a long way with some users.

Three sliders, one option, and a few tears later

Yes, sliders have a special place in my heart. Granted a super tiny place in my theme reviewer’s heart. Now, I’ve created a few tutorials, guides, resources, links, what you will on this site in order to share some of my insights into WordPress theme development and perhaps some WordPress theme reviews along the way.

There are a lot of things I have learned and a lot of things I had to learn. I think the biggest takeaway from this post will be that integrating a slider plugin to a theme is fairly easy to do but a pain in the butt to fully integrate.

So, let’s get the show on the road!

First steps

Okay, we need to figure out first what slider we would like to play nice with, right? I chose sort of at random three different plugins that all create sliders.

I was going to use Meta Slider but they actually have a fairly extensive documentation section on theme integration. So major kudos for them on providing those code snippets!

As you can see we have our three sliders to choose from and now we need to determine if they are active or not. I know some will want to use is_plugin_active() but I will tell you not to. The reason for not doing so is so that you don’t load an extra file. So instead we will use some basic PHP functions to check.

function jc_get_sliders(){
	$sliders = array();
	
	if ( class_exists( 'Soliloquy_Lite' ) ){
		$sliders['soliloquy'] = 'Soliloquy';
	}
	
	if ( function_exists( 'huge_it_slider_activate' ) ){
		$sliders['huge_it_slider'] = 'Huge IT Slider';
	}
	
	if ( function_exists( 'wd_slider' ) ){
		$sliders['wds'] = 'Slider WD';
	}
	
	return $sliders;
}

I know some of you are wondering why I chose to use the class and functions I chose to check for. Those are the classes and functions those respective plugins use when they are activated. If those plugins are not active they will not exist.

Now that we have our options for plugins we can create our theme customizer options.

add_action( 'customize_register', function( $wp_customize ){
	// Set up the section
	$wp_customize->add_section( 'slider-section',
		array(
		'title' => __( 'Select a slider', 'jc-domain' ),
		'priority' => 30,
		) );
	// register the setting
	$wp_customize->add_setting( 'slider-type',
		array(
		'default' => '',
		'sanitize_callback' => 'jc_valid_slider',
		) );
	// register the setting's control but only output if those sliders exist
	$wp_customize->add_control( 'slider-type-input',
		array(
		'label' => __( 'Select the slider to use', 'jc-domain' ),
		'settings' => 'slider-type',
		'section' => 'slider-section',
		'type' => 'select',
		'choices' => jc_get_sliders(),
		'active_callback' => 'jc_sliders_exist'
		) );
	// register the setting
	$wp_customize->add_setting( 'slider-id',
		array(
		'default' => '',
		'sanitize_callback' => 'absint',
		) );
	// register the setting's control but only output if those sliders exist
	$wp_customize->add_control( 'slider-id-input',
		array(
		'label' => __( 'Input the ID of the slider you would like to use', 'jc-domain' ),
		'settings' => 'slider-id',
		'section' => 'slider-section',
		'type' => 'number',
		'active_callback' => 'jc_sliders_exist'
		) );
	
});

Great! Now you can see that I am using an active_callback for the controls. This is so that the section will not show if there are no active plugins to choose from. That means we have to create that callback. Fairly simple:

function jc_sliders_exist(){
	if ( !empty( jc_get_sliders() ) )
		return true;
	return false;
}

As you see we can utilize the first function we created that gets the sliders to our advantage. If the array is not empty we return true, otherwise we return false. Straight-forward. Now, you may notice one function we may need to create and that is jc_valid_slider. This is what will check if the option is a valid option and return it. So, let’s create that shall we:

function jc_valid_slider( $value, $control ){
	return ( array_key_exists( $value, jc_get_sliders() ) ) ? $value : $control->default;
}

Yes, you can see we are still using jc_get_sliders() to get our values. No need to create another wheel when we already have one, right?

The output

I know you are now wondering, “But Jose, how will you display the slider?” Well, let me show you how! We use get_theme_mod() and do_shortcode() with a quick check to output our slider.

add_action( 'jc_slider_area', 'jc_create_slider' );
function jc_create_slider(){
	// get the setting for the type of slider
	$type = get_theme_mod( 'slider-type' );
	// get the setting for the ID of the slider to use
	$id = get_theme_mod( 'slider-id' );
	
	// Check if we have chosen a slider
	if( !$type ){
		return;
	}
	
	echo do_shortcode( "[$type id='$id']" );
}

Great! But I know you are probably wondering why I’m using an action hook rather than creating a function and calling it. What’s super cool about using a hook is that this can be extended or removed with a child theme or functionality plugin. Super great way of making your theme extendable and child theme friendly. So, in the last step all we need to do is create that action hook.

<?php do_action( 'jc_slider_area' ); ?>

By adding that to where you want the slider to show, you can create a great hook for any theme developer to utilize.

Minor note

If you hadn’t noticed, I registered the customizer settings using an anonymous function. This will work on PHP versions 5.3 and higher so please make sure you are aware of what your environment you are developing for. So go, explore and try to break things along the way!

Why theme documentation matters

Creating WordPress themes can be fun. Sharing them with everybody is even better. What happens when those users then ask you how to do something? Often times what is the simplest task to you may seem like a trip to Mordor for others. You don’t always know the person’s knowledge base when you share your theme. They could be a developer that began using BASIC when it was first introduced, or a person who has just picked up a book on how to build a website using WordPress.

What’s cool is we can meet both those worlds in the middle. One way is by using code comments. Code comments can make it easier for not only yourself but others to know what exactly the code is doing. A good example of this is the comment block below, taken from the wp_get_theme function:

/**
 * Gets a WP_Theme object for a theme.
 *
 * @since 3.4.0
 *
 * @global array $wp_theme_directories
 *
 * @param string $stylesheet Directory name for the theme. Optional. Defaults to current theme.
 * @param string $theme_root Absolute path of the theme root to look in. Optional. If not specified, get_raw_theme_root()
 * 	                         is used to calculate the theme root for the $stylesheet provided (or current theme).
 * @return WP_Theme Theme object. Be sure to check the object's exists() method if you need to confirm the theme's existence.
 */

Yes, it can look like a lot of information but not all your code has to be as robust as that. You can use simple documentation and still do just the same. While that does go for some developers, we cannot forget those that just want to use the theme and are possibly afraid of code, or don’t know how to code. Great! This is where other forms of documentation come in handy.

Types

There are other forms of documentation that you can use to your advantage. A few I like are:

  • Videos
  • Images
  • Readme file

Please note, images and videos may not always be view-able by all so you may have to take that into consideration on your path to documentation bliss. Now, let us explore those a little more.

Videos

I love me a good video. A video tutorial, that is. Now, your theme does not have to have a step by step video on how to setup every single option, or possibility your theme offers but you do want to have some of the basic, and perhaps most common things. A few examples are installing the theme, accessing your theme options, showing how to setup possible social links, or even using page templates. You don’t have to have audio but it does help. There are several programs out there that allow you to capture video and create video screen casts.

Images

Yes! Images can make a huge difference for many. Even better when they move. I am talking about gif images. They can be a great way to showcase a few steps without having to create a two minute video to show how to access extra options. If you have an image editing program it can be used to highlight what you want in order to emphasize parts of the image.

Readme File

The basic and standard file you need to include. Okay, that’s just me saying it but I’m sure there are more people who would agree with that statement. This is the part that really irks me because you can include some basic steps that can go a long way. A great example is setting up social link profiles. There are several ways of creating those and not all themes follow a standard. It is nice to know where to look and how to use it.

== Setting up social links ==
1. From Dashboard go to Appearance
2. Click Customize
3. Go down to Social section
4. Type username or ID ( depending on network )

Looks fairly simple, right? It can be for some but there may be others that may still get confused. Okay, we covered a simple setup but what happens when a user gets what they feel is an unexpected result?

What do I mean by this?

Let’s say the theme has a menu location at the bottom and you only want it to display one level of menu items. They may open a support request, thread, ticket, whatchumacallit, or what ever system of support you are using and ask why it isn’t showing all the menu items. This is where your theme’s documentation can come in super handy and essential. If it is a design choice then it should be stated in the documentation. A good way would be something like:

=== Limitations ==
* Featured images should be minimum 600 pixels wide and 400 pixels tall for best results
* The `footer-nav` menu location, by design, only displays one level of menu items
* The `ad-loc-1` widget area is only used in the page template `fullwidth-ads`
* If pages do not have a featured image set, the chosen header image will be used

Yes, even what sounds -or seems- strange is super helpful to the user of your theme. Knowing what the best size for an image is useful, just like knowing the right size of tire for your car or bicycle.

So please, please make sure you are documenting for not only yourself but for your users as well.

WordPress Static Front Page

Themes are a great way to showcase user content. Themes can often times add a bit of functionality to a site and that’s great! The hardest one to grasp is the use of a front page template. Yep, that can of worms. One of the common things I’ve noticed is authors creating two or more files with the same code. It hurts. The more common pattern of course is:

get_header();
	if ( get_option( 'show_on_front' ) == 'posts' ) {
        // If they want to show "Latests Posts"
		get_template_part( 'index', 'homepage' ) ;
	} elseif ( get_option( 'show_on_front' ) == 'page' ) {
        // otherwise we show the front page
		get_template_part( 'index' ) ;
	}
		
get_footer();

Or at least something close to that. They check in particular what the setting is. It’s this:

if ( get_option( 'show_on_front' ) == 'posts' ) { // code here }

That checks in particular what the user setting is. It basically says, if the user selected to use the latests post we run the following code. Usually it would be comprised of the amount of posts the user has set. Some like to show 5 post while some like showing 10. That doesn’t include stickies but I won’t get into that. That’s another can of worms not really worth opening right now.

There are several tutorials and other posts that are out there which can help you understand. One of my favorites is Chip Bennett’s on home page, front page, and templates. Really in-depth and a great starting point. If you don’t understand it, read it again. It will make sense eventually.

One thing I do find super weird is the way it checks. Not jump from the template hierarchy but in the way the query is as well. The core markup ( as of 4.3 ) is:

// @return bool True, if front of site.
public function is_front_page() {
    // most likely case
    if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
        return true;
    elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
        return true;
    else
        return false;
}

// @return bool True if blog view homepage.
public function is_home() {
	return (bool) $this->is_home;
}

It does two checks to make sure we are on the front of the site. Yeah a little odd but it does the trick. So, with that slight insight we can get a better understanding of how WordPress front-page, home, and index sort of fall into place.

Now, what can we do about it? The best method is using a filter. Yes. A filter. They are the lifeblood of any and all great themes and plugins. Use them like they are going out of style. Okay, perhaps a little extreme but they are super useful. I know that some people will be hesitant at first but once you get the hang of them and what to look for it will be a game changer for how you code.

The filter we’ll use is the get_query_template filter. This function/filter is found in the wp-includes/template file. The function is simplistic in nature and is filterable to your choosing. The code is:

function get_query_template( $type, $templates = array() ) {
	$type = preg_replace( '|[^a-z0-9-]+|', '', $type );

	if ( empty( $templates ) )
		$templates = array("{$type}.php");

	$template = locate_template( $templates );

	return apply_filters( "{$type}_template", $template );
}

So, let us break it down a little. This function accepts two arguments. The first one is required to be passed because it needs to know what file to look for otherwise it will give an error. The second one is an optional array of templates to look for. From there it will use locate_template to look first in the child theme for the file and if it doesn’t find it there it will use the parent folder to locate the template. Finally, we have our filter!

This is the fun part. In order to use the filter, we first have to know what template we would like to override. In our case it is the front-page.php; though it does something a little odd, in that it removes the - so we need to use frontpage as the template name. So the filter hook would look like:

add_filter( 'frontpage_template', 'jc_frontpage_template' );

Super simple, right? Now to write out the logic, or our callback function. In that function all we have to return is a string of where our replacement file is. Let’s say that we have a landing page that we would like to use. Just don’t forget to document that otherwise people may get confused on the unexpected behavior. In order to do so we can use something like:

function jc_frontpage_template( $template ){
	if ( is_home() ){
		get_home_template();
	} else {
		return locate_template( 'templates/landing.php' );
	}
}

Pretty sweet, right? I think so. So, go, explore those filters, break things and learn from it.

Using active callbacks in the Customizer

One thing I haven’t seen many themes use is active callbacks to their advantage. What are they and how can they used? It’s actually quite simple and there are two methods that the customizer has available. The first one is when you first create the section, panel, or control.

$wp_customize->add_section( 'meta-slider-section',
	array(
		'title' => __( 'Meta Slider Section', 'jc-domain' ),
		'description' => __( 'Input the ID of a slider and it will display on this section of the theme', 'jc-domain' ),
		'active_callback' => 'is_meta_active',
	)
);

Great! We have a section but how do make sure that it will only be seen when the plugin is active? The 'active_callback' function will be used. In that function we can setup our logic so that the section will only show if the meta slider plugin is active.

function is_meta_active(){
	// Check for the slider plugin class
	if( !class_exists( 'MetaSliderPlugin' ) ) {
	// If it doesn't exist it won't show the section/panel/control
		return false;
	} else {
	// If it does, we do show it
		return true;
	}
}

Fairly neat right? What’s really awesome is that you can do this with controls as well. Let’s say we want a control to only show with a specific page template. You can use the callback function to look something like:

function is_certain_page_template() {
	// Get the page's template
	$template = get_post_meta( get_the_ID(), '_wp_page_template', true );
	$is_template = preg_match( '%fullwidth.php%', $template );	if ( $is_template == 0 ) {
		return false;
	} else {
		return true;
	}
}

Now, I mentioned there are two methods of using active callbacks. The second method is by using an extending class. Let’s say we have a custom control class that we only want to show when an option is selected.

Now, I mentioned there are two methods of using active callbacks. The second method is by using an extending class. Let’s say we have a custom control class that we only want to show when an option is selected.

if ( class_exists( 'WP_Customize_Manager' ) ):
class JC_Manic_Control extends WP_Customize_Control {
	function active_callback(){
		// This is the function that will house the logic so our control
		// shows only when we need it to. This will override the
		// WP_Customize_Control's active_callback function.
		return false;
	}
	function render_content(){
		// other code goes here, keeping it simple for demonstration purposes.
	}
}
endif;

Pretty darn cool if you ask me. Now, with those two methods you can create a much better experience with your theme options and customizations. So, go on and explore and experiment with active callbacks. Add it to your repertoire of theme tools and WordPress knowledge!

Customizer: dropdown category selection

This is just a quick code snippet that may help at least one person. I know it will. Earlier today I was looking over a theme and it was driving me crazy to see them re-inventing the wheel. A simple dropdown that core uses in order to display the categories. The way core uses choices is an associative array. The array key is the $value and the array value is used for the label. What does this mean?

It means that often times you have to flip things around because core can get certain values in a different manner. A great example is the get_page_templates function. The following is one way of creating this array.

// we get all the available templates
$templates = array_flip( get_page_templates() );

// new array is
$templates = 
	array (
	'templates/home.php' => 'home',
	'templates/featured.php' => 'featured posts',
	'templates/widgetized.php' => 'Widgetized Page'
	)

Do keep in mind that is just for that particular function. There are several other functions that return either arrays or objects, so it is in your best interest to learn how and what each function returns data. I say this because the above code uses a basic PHP function in order to re-create the array. The function itself returns things the other way around. The codex page does a good job of explaining it.

In this post we will go over the get_categories function. It returns an array but not the way we want in order to use in the customizer. In order to do so we have to get a little creative in building the array.

// create an empty array
$cats = array();

// we loop over the categories and set the names and
// labels we need
foreach ( get_categories() as $categories => $category ){
	$cats[$category->term_id] = $category->name;
}

// we register our new setting
$wp_customize->add_setting( 'cats_elect', array(
	'default' => 1,
	'sanitize_callback' => 'absint'
) );

// we create our control for the setting
$wp_customize->add_control( 'cat_contlr', array(
	'settings' => 'cats_elect',
	'type' => 'select',
	'choices' => $cats,
	'section' => 'my_section',  // depending on where you want it to be
) );

This will return an integer for the category. Hence the absint sanitation callback. From there all we would have to do to get our setting is use:

$cat_id = intval( get_theme_mod( 'cats_elect', 1 ) );

You’ll notice I’ve used intval around the get_theme_mod function, that is so we make sure that we are getting an integer from our saved setting just in case. You can never be too careful, right?

So, there you have it! Just a few lines of code and we have a dropdown of our categories.

Using the_post_thumbnail

For some time I’ve noticed one thing that many people like doing. Recreating core functions. One being the_post_thumbnail(). The reason it drives me crazy is because it means maintaining more code in your theme. Why would you do that to yourself? One of the common things is to wrap it in a conditional check and then use the function if there is a thumbnail. Great! Looks like:

if ( has_post_thumbnail() ){
	the_post_thumbnail();
} else {
	custom_post_thumbnail();
}

The problem

Rewriting a core template tag to suit the theme’s design. Yes, it drives me insane when I know that there is a filter or a hook that can be applied to core functions. Yes. Core has a lot of hook and filters to modify. I’m not saying learn them all but merely suggesting look at the core code when you want to see what and how things are done.

Core file

In order to create our little function let us look at the actual core code, shall we? All the workings are actually placed in the wp-includes/post-thumbnail-template.php file. A little crazy, right? Let’s take a look at the code:

function the_post_thumbnail( $size = 'post-thumbnail', $attr = '' ) {
	echo get_the_post_thumbnail( null, $size, $attr );
}

There it is. So what does it do? It creates a default size ( post-thumbnail ) and passes a null argument to get_the_post_thumbnail. A little weird but makes sense, right? So let’s look at the actual function that gets us the image, yeah?

function get_the_post_thumbnail( $post_id = null, $size = 'post-thumbnail', $attr = '' ) {
	$post_id = ( null === $post_id ) ? get_the_ID() : $post_id;
	$post_thumbnail_id = get_post_thumbnail_id( $post_id );

	$size = apply_filters( 'post_thumbnail_size', $size );

	if ( $post_thumbnail_id ) {

		do_action( 'begin_fetch_post_thumbnail_html', $post_id, $post_thumbnail_id, $size );
		if ( in_the_loop() )
			update_post_thumbnail_cache();
		$html = wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr );

		do_action( 'end_fetch_post_thumbnail_html', $post_id, $post_thumbnail_id, $size );

	} else {
		$html = '';
	}

	return apply_filters( 'post_thumbnail_html', $html, $post_id, $post_thumbnail_id, $size, $attr );
}

As you can see it looks like quite a bit. So we will break it down a little bit more. Go down the lines and explain a little more.

Breakdown: the arguments

The first thing you will see is that it asks for a $post_id, then an image size and an attribute. Cool. Still with me? Good. Now let’s move on to the next line of code:

$post_id = ( null === $post_id ) ? get_the_ID() : $post_id;

It tests if the $post_id is identical to null and if it is, we get the post’s ID by using get_the_ID(). Pretty neat if you ask me.

Next, it passes that ID to get_post_thumbnail_id in order to get the image’s attachment ID. You read it right.

The next line is where we come across our first filter. Yay! And it is post_thumbnail_size. What this means is that if you wanted to use

the_post_thumbnail( 'my-theme-image' );

You can add a filter and make it a conditional setting as well. You can use:

add_filter( 'post_thumbnail_size', 'my_new_sizes' );
function my_new_sizes( $size ){
	if ( is_front_page() || is_home() ){
		return 'my-large-front-image';
	}
	return 'my-theme-image';
}

Awesome, right? I like to think so. The next several lines are what create the actual code.

First it checks if it is a true value and if it is we can continue with our code. Then we see an interesting line:

do_action( 'begin_fetch_post_thumbnail_html', $post_id, $post_thumbnail_id, $size );

Kind of a neat little hook. You can print things just before the image tag. From there it updates the thumbnail cache, and then finally it gets the image’s markup by using wp_get_attachment_image( $post_thumbnail_id, $size, false, $attr ). Cool, right? Right. But we are not done just yet.

We have another hook:

do_action( 'end_fetch_post_thumbnail_html', $post_id, $post_thumbnail_id, $size );

With this particular one you can also print things out before the image’s markup. For example:

add_action( 'end_fetch_post_thumbnail_html', 'demo_before_image' );
function demo_before_image(){
	_e( 'I appear before the image', 'textdomain' );
}

The end result will be:

I appear before the image<img width="522" height="270" src="http://sample.dev/wp-content/uploads/2013/03/featured-image-horizontal.jpg">;

Super cool, right?

The next and final steps in the function is the setting of $html. You’ll see that if the $post_thumbnail_id isn’t set then it returns an empty string. From there the last line of code is:

return apply_filters( 'post_thumbnail_html', $html, $post_id, $post_thumbnail_id, $size, $attr );

So, it returns the HTML. Great. As you can see you can filter this.

New filter

Yes, we will use a filter because that is what all good developers like to use and should use.

add_filter( 'post_thumbnail_html', 'theme_slug_post_thumbnail', 10, 2 );
function theme_slug_post_thumbnail( $html, $size ) {
	// get featured image based on $post->ID
	$post_thumbnail_id = get_post_thumbnail_id( get_the_ID() );

	// set size
	$size = (string) apply_filters( 'post_thumbnail_size', 'my-theme-image' );

	//do your magic here
	if ( $post_thumbnail_id ) {
		if ( in_the_loop() ) {
			update_post_thumbnail_cache();
		}
		$html = wp_get_attachment_image( $post_thumbnail_id, $size );
	} else {
		$html = '<img class="featured-image" src="' . get_template_directory_uri() . '/img/custom-thumb.jpg" alt="Image">';
	}

	return '<div class="feature-image-wrapper">' . $html . '</div>';
}

As you can see it is a simplified filter because we aren’t changing every variable the function has to offer. You can, of course, explore more and create your own version. You will see that the one filter I kept was the post_thumbnail_size and that is because if a child theme is created, the child theme can change that with a simple filter.