Conditionally disable Jetpackโ€™s Infinite Scroll

So you implemented Jetpack’s Infinite Scroll feature in your theme, but you don’t want it in a particular page, say a category archive page. Here’s the code you need to add to your theme’s functions.php file:

/**
 * Disable Jetpack's Infinite Scroll Conditionally
 *
 */
function _kucrut_disable_jetpack_infinite_scroll_conditionally() {
	if ( true === my_conditionals() ) {
		remove_theme_support( 'infinite-scroll' );
	}
}
add_action( 'template_redirect', '_kucrut_disable_jetpack_infinite_scroll_conditionally', 9 );

Just remember to change my_conditionals() with your actual conditionals and to never add the action callback after priority 9, otherwise it will be too late ๐Ÿ˜‰

Standard

Add HTML Tags in Post and Widget Titles

In a recent project, I needed to use <span /> tags to add some styles (just color, actually) to post and widget titles. By default โ€” and there’s no hook to disable this โ€” WordPress strips any HTML tags found in post and widget titles. Here’s my solution to this problem. Please keep in mind that I only needed to add <span /> tags, so if you need to add more tags, you should modify the code to fit your needs ๐Ÿ™‚

First, add the span tags to the desired post and widget titles, replacing the < and > characters with hashes ( # ):

Add fake span tags to post and widget titles

Now, let’s create a tiny mu-plugin to handle our HTML tags. We’ll be using four filter hooks for this:

  • the_title, triggered in post titles
  • the_title_rss, triggered in post titles for feeds
  • wp_title, triggered in HTML document title, and
  • widget_title, triggered in โ€” well, you guessed it right โ€” widget titles

The plugin:

/*
Plugin Name: Enable HTML tags in post and widget titles
Author: Dzikri Aziz
Author URI: /
Version: 0.1
License: GPL v2
*/


function kc_convert_title_html_tags( $string ) {
  global $wp_current_filter;
  $filter = end($wp_current_filter);
  $search = array('#span#', '#/span#');
  $replace = ( in_array($filter, array('wp_title', 'the_title_rss')) || ($filter == 'the_title' && (is_admin() || in_array('wp_head', $wp_current_filter))) ) ? '' : array('<span>', '</span>');
  $string = str_replace( $search, $replace, $string );

  return $string;
}

add_filter( 'the_title', 'kc_convert_title_html_tags' );
add_filter( 'the_title_rss', 'kc_convert_title_html_tags' );
add_filter( 'wp_title', 'kc_convert_title_html_tags' );
add_filter( 'widget_title', 'kc_convert_title_html_tags' );

Take a closer look to the replacement string. We need to strip our fake HTML tags from the post titles when:

  • kc_convert_title_html_tags() is called by wp_title or the_title_rss hook
  • the_title filter hook is triggered from within wp_head action hook (eg. the post title is used by the title attribute of feed links
  • we’re viewing a post table in admin area.

However, when we’re inside the <body />, they need to be converted to the real tags.

That’s it! ๐Ÿ™‚

Standard

Hacking Term List Table

Term list table, unlike post list table, is not very customizable. What I needed was to display the thumbnail/icon of each term, to make it easier for the content editors to distinguish one term from another.

I consider this as a hack, not because we’re going to edit a core file (never ever do that, please!), but because we’re (ab)using a filter hook to display the thumbnail, which should normally be done through an action hook. Unfortunately, if we take a look at wp-admin/includes/class-wp-terms-list-table.php file, there’s only one action hook in there, which can’t help us. However, there’s a filter hook that can be useful for our situation: "{$taxonomy}_row_actions", normally used to customize the action links that show up when we hover over a term row.

Before we begin, We need to decide how we attach an image to a term. There are many plugins out there that can help us with this, but in this guide we’ll be using my own plugin, KC Settings. By the way, if the plugin of your choice doesn’t use termmeta table to store terms metadata, I strongly suggest you to look for another plugin ๐Ÿ™‚

Let’s get started with creating a mu-plugin file, or editing a our theme’s function.php file (not recommended). We’ll be using the category taxonomy throughout this guide, but you can off course use other taxonomies.

First we’ll add an entry for KC Settings, (please refer to the sample files included in the plugin to learn about the setting array), or you can also use the Builder if you like.

function my_category_metadata( $groups ) {
  $groups[] = array(
    'category' => array(
      array(
        'id'        => 'category-meta',
        'title'     => 'Metadata',
        'fields'    => array(
          array(
            'id'    => 'icon',
            'title' => 'Icon',
            'type'  => 'file'
          )
        )
      )
    )
  );

  return $groups;
}
add_filter( 'kc_term_settings', 'my_category_metadata' );

Now we can attach an image when creating/editing a term:

Attach/set term icon

To get the data, we can use get_term_meta(). For example, assuming the category ID is 20:

print_r( get_metadata('term', 20, 'icon', true) );

โ€ฆwhich outputs:

Array
(
  [selected] => Array
    (
      [0] => 38
    )
  [files] => Array
    (
      [0] => 38
    )
)

Next, we’ll display each term’s icon on the term list table:

function my_category_column_hack( $actions, $term ) {
  if ( $icon = get_metadata('term', $term->term_id, 'icon', true) ) {
    if ( isset($icon['selected'][0]) && $img = wp_get_attachment_image( $icon['selected'][0]) )
      echo '<a href="'.get_edit_post_link($icon['selected'][0]).'" class="term-icon">'.$img.'</a>';
  }

  return $actions;
}
add_filter( 'category_row_actions', 'my_category_column_hack', 10, 2 );

We’re basically done, and the term table should now display the icons of each term. However, we need to add some CSS to make it look a little bit sexier and to match the Media screen.

function my_admin_inline_styles() {
  $screen = get_current_screen();
  if ( $screen->base == 'edit-tags' ) { ?>
<style>.term-icon {float:left;width:40px;height:40px;overflow:hidden;margin-right:10px} .term-icon img {max-width:100%;height:auto}</style>
  <?php }
}
add_action( 'admin_print_styles', 'my_admin_inline_styles', 99 );
Standard

Customize post type archive order

By now you’re probably already familiar with one of WordPress’ most loved features, custom post type. A custom post type could be hierarchical (like page) or non-hierarchical (like post). This snippet will modify the default posts order when the post type archive is being displayed.

Note:
Instead of adding these snippets into your theme’s functions.php file, I really recommend creating a mu-plugin file, so you will always get the functionality, no matter what theme you’re currently using (IMO, themes shouldn’t interfere with this kind of functionality anyway).

Register Post Type

For this to work, there are three things we need to pay attention to when registering our post type; it has to be set to hierarchical, it has to support page-attributes, and it has to support archive.

function my_custom_post_types_register() {
  register_post_type('work', array(
    'labels'        => array('name' => __('Works'), 'singular_name' => __('Work')),
    'public'        => true,
    'hierarchical'  => true,
    'supports'      => array('title', 'editor', 'thumbnail', 'page-attributes'),
    'has_archive'   => true,
    'rewrite'       => array('slug' => 'work', 'with_front' => false)
  ));
}
add_action( 'init', 'my_custom_post_types_register' );

Customize archive order

function my_custom_archive_order( $vars ) {
  if ( !is_admin() && isset($vars['post_type']) && is_post_type_hierarchical($vars['post_type']) ) {
    $vars['orderby'] = 'menu_order';
    $vars['order'] = 'ASC';
  }

  return $vars;
}
add_filter( 'request', 'my_custom_archive_order');

The code should be pretty self-explanatory; we will only modify the order if we’re on the front-end, and we’re viewing a hierarchical post type archive.

Actually, the hierarchical mode is not really needed for this, since custom-ordering posts can always be done if the post type supports page-attributes. However, IMO, custom order doesn’t really make sense for non-hierarchical posts, don’t you think? ๐Ÿ™‚

If you don’t want to set the post type to hierarchical, just replace the third logic in my_custom_archive_order, so it would check if the post type supports page-attributes:

if ( !is_admin() && isset($vars['post_type']) && post_type_supports($vars['post_type'], 'page-attributes') ) {
//...
}

To reorder the posts, you can manually edit their orders one by one, or use this plugin (only if you don’t have/need child pages, since it doesn’t support it yet).

Example? Try this ๐Ÿ™‚

Standard

Remove Protected Post Title Prefix

By default, WordPress will prefix protected post’s title with Protected. This is good when the password hasn’t been supplied. Unfortunately, it doesn’t remove this prefix when the correct password has been supplied which is not good IMO. Here’s a snippet to ‘fix’ this behavior:

function kc_protected_title_format( $format ) {
	if ( !post_password_required() )
		$format = '%s';

	return $format;
}
add_filter( 'protected_title_format', 'kc_protected_title_format' );
Standard

Insert Image with Custom Size into Post

Since version 2.9, WordPress provided a new function, add_image_size() to define additional image sizes along with the three default sizes: Thumbnail, Medium and Large. After defining the additional sizes, we can use them in our themes either using the_post_thumbnail(), wp_get_attachment_image(), or any other functions that suit your needs.

Update
I’ve created a plugin for this so you won’t need to edit your theme/plugin files anymore ๐Ÿ™‚ Download it from WordPress plugins repo.

function my_insert_custom_image_sizes( $sizes ) {
  global $_wp_additional_image_sizes;
  if ( empty($_wp_additional_image_sizes) )
    return $sizes;

  foreach ( $_wp_additional_image_sizes as $id => $data ) {
    if ( !isset($sizes[$id]) )
      $sizes[$id] = ucfirst( str_replace( '-', ' ', $id ) );
  }

  return $sizes;
}
add_filter( 'image_size_names_choose', 'my_insert_custom_image_sizes' );

The result

Note: The new code is adapted from here.

Standard

Unique post category/term

In WordPress, we can set multiple categories/terms for a post. This is true for both hierarchical taxonomies (ex: category) and non-hierarchical taxonomies (ex: post_tag). However, on a project I’ve worked on, the client wanted me to make the category metabox to use radio inputs (exactly like WordPress’ new post format feature) instead of checkboxes to prevent the editor from setting multiple categories for the post (s)he writes. This request forced me ๐Ÿ™‚ to come up with a solution. I was also inspired by Justin Tadlock’s idea on using a taxonomy for theme layout. Here’s my solution in hope it could be useful for others.

The result

Unique Taxonomy Metabox

Unique Taxonomy Metabox

The code

As usual, you can either add this code to your theme’s function.php file or create a new php file for it and place it inside wp-content/mu-plugins directory (preferred) so you can always have this feature no matter what theme you’re using.

<?php
function kc_unique_taxonomies() {
	$unique_taxonomies = apply_filters( 'kc_unique_taxonomies', array() );
	if ( empty($unique_taxonomies) )
		return;

	foreach ( $unique_taxonomies as $tax_name ) {
		$taxonomy = get_taxonomy( $tax_name );
		if ( !$taxonomy->hierarchical || !$taxonomy->show_ui || empty($taxonomy->object_type) )
			continue;

		foreach ( $taxonomy->object_type as $pt ) {
			# Remove default metabox
			remove_meta_box( "{$tax_name}div", $pt, 'side' );

			# Add our own
			add_meta_box( "unique-{$tax_name}-div", $taxonomy->labels->singular_name, 'kc_unique_taxonomies_metabox', $pt, 'side', 'low', array('taxonomy' => $tax_name) );
		}
	}
}
add_action( 'admin_menu', 'kc_unique_taxonomies' );


function kc_terms_radiolist( $post_id, $taxonomy, $echo = true ) {
	$terms = get_terms( $taxonomy, array('hide_empty' => false) );
	if ( empty($terms) )
		return;
	$name = ( $taxonomy == 'category' ) ? 'post_category' : "tax_input[{$taxonomy}]";

	$post_terms = get_the_terms( $post_id, $taxonomy );
	$nu_post_terms = array();
	if ( !empty($post_terms) ) {
		foreach ( $post_terms as $post_term )
			$nu_post_terms[] = $post_term->term_id;
	}

	$output = '';
	foreach ( $terms as $term ) {
		$output .= "<li class='selectit'>";
		$output .= "<label>";
		$output .= "<input type='radio' name='{$name}[]' value='{$term->term_id}' ".checked( in_array($term->term_id, $nu_post_terms), true, false )."/>";
		$output .= " {$term->name}</label>";
		$output .= "</li>n";
	}

	if ( $echo )
		echo $output;
	else
		return $output;
}

function kc_unique_taxonomies_metabox( $post, $box ) {
	if ( !isset($box['args']) || !is_array($box['args']) )
		$args = array();
	else
		$args = $box['args'];

	$defaults = array('taxonomy' => 'category');
	extract( wp_parse_args($args, $defaults), EXTR_SKIP );
	$tax = get_taxonomy($taxonomy);

	?>
	<div id="taxonomy-<?php echo $taxonomy; ?>" class="categorydiv">
		<?php
			$name = ( $taxonomy == 'category' ) ? 'post_category' : 'tax_input[' . $taxonomy . ']';
			echo "<input type='hidden' name='{$name}' value='0' />"; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks.
		?>
		<ul id="<?php echo $taxonomy; ?>checklist" class="list:<?php echo $taxonomy?> categorychecklist form-no-clear">
			<?php kc_terms_radiolist( $post->ID, $taxonomy ) ?>
		</ul>
	<?php if ( !current_user_can($tax->cap->assign_terms) ) { ?>
		<p><em><?php _e('You cannot modify this taxonomy.'); ?></em></p>
	<?php } ?>
	<?php if ( current_user_can($tax->cap->edit_terms) ) { ?>
			<div id="<?php echo $taxonomy; ?>-adder" class="wp-hidden-children">
				<h4>
					<a id="<?php echo $taxonomy; ?>-add-toggle" href="#<?php echo $taxonomy; ?>-add" class="hide-if-no-js" tabindex="3">
						<?php
							/* translators: %s: add new taxonomy label */
							printf( __( '+ %s' ), $tax->labels->add_new_item );
						?>
					</a>
				</h4>
				<p id="<?php echo $taxonomy; ?>-add" class="category-add wp-hidden-child">
					<label class="screen-reader-text" for="new<?php echo $taxonomy; ?>"><?php echo $tax->labels->add_new_item; ?></label>
					<input type="text" name="new<?php echo $taxonomy; ?>" id="new<?php echo $taxonomy; ?>" class="form-required form-input-tip" value="<?php echo esc_attr( $tax->labels->new_item_name ); ?>" tabindex="3" aria-required="true"/>
					<label class="screen-reader-text" for="new<?php echo $taxonomy; ?>_parent">
						<?php echo $tax->labels->parent_item_colon; ?>
					</label>
					<input type="button" id="<?php echo $taxonomy; ?>-add-submit" class="add:<?php echo $taxonomy ?>checklist:<?php echo $taxonomy ?>-add button category-add-sumbit" value="<?php echo esc_attr( $tax->labels->add_new_item ); ?>" tabindex="3" />
					<?php wp_nonce_field( 'add-'.$taxonomy, '_ajax_nonce-add-'.$taxonomy, false ); ?>
					<span id="<?php echo $taxonomy; ?>-ajax-response"></span>
				</p>
			</div>
		<?php } ?>
	</div>
<?php }

The explanation

The first function — kc_unique_taxonomies — will find if you have set a taxonomy (or more) to be unique. You will have to add the taxonomy IDs using the available kc_unique_taxonomies filter hook (we’ll talk about it shortly). If there’s a unique taxonomy found, it will then remove the taxonomy’s default metabox in the post editing page, and replace it with the new one.

Note:
This function will only search for hierarchical taxonomies, because I strongly believe that a post should be allowed to have multiple non-hierachical taxonomy terms (ex: tags). Also, non-public and orphan taxonomies (taxonomies that are not attached to a post type) will be ignored.

The second function — kc_terms_radiolist — will display the replacement metaboxes for each unique taxonomies that use radio inputs for the taxonomy’s terms. I basically just took WordPress default category metabox and adjusted some parts of it.

Usage

The last step is to actually set some taxonomies to be unique which you can either do from your theme or plugin. Just add this snippet of code:

function my_unique_taxonomies( $arr ) {
	$unique_taxonomies = array( 'category' );
	return array_merge( $arr, $unique_taxonomies );
}
add_filter( 'kc_unique_taxonomies', 'my_unique_taxonomies' );

You can add more taxonomies to the $unique_taxonomies array if you want.

Bugs, question? feel free to leave a comment below ๐Ÿ™‚

Standard

Add Custom Attributes to WordPressโ€™ Posts Navigation

The Problem

We need to add our custom class(es) to the posts navigation links to be able to add some styles.

The Solution

Use the available next_posts_link_attributes and previous_posts_link_attributes hooks.

How?

Open your theme’s function.php file and add these lines (must be inside the <?php ?> tag):

add_filter( 'next_posts_link_attributes', 'kc_next_post_link_attr' );
add_filter( 'previous_posts_link_attributes', 'kc_prev_post_link_attr' );

function kc_next_post_link_attr() {
	return 'class="next-page"';
}

function kc_prev_post_link_attr() {
	return 'class="prev-page"';
}
Standard