Changing ‘Stock Availability’ Text for Product Variations

This documents one method to change the ‘Stock Availability’ text for Woocommerce Product Variations.

My requirement was that when a Product Variation was selected by the user on the frontend, in the following instances I wanted to show the corresponding availability text:

  • Available: ‘[number] units available for your purchase.’ instead of the default ‘Available’.
  • Out Of Stock: ‘Oops, we have no stock left.’ instead of the default ‘Out of stock’.

In order to do this, we need to override the template found in the plugin directory woocommerce/single-product/add-to-cart/variable.php. This is where the ‘Add to Cart’ code for the Variable Product’s page is found.

In this template, you’ll find the following:

<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo htmlspecialchars( json_encode( $available_variations ) ) ?>">

json_encode( $available_variations ) provides the data which is used for updating (via javascript) the corresponding information such as minimum quantity, stock availability on the product page whenever the user selects a product variation on the dropdown select.

The variable $available_variations is an array passed into the page from a WooCommerce function woocommerce_variable_add_to_cart found in includes/wc-template-functions.php. Note that this variable is derived from $product->get_available_variations(), and it returns values (such as min and max quantity, stock availability) for all available Variations found under a Variable Product.

Therefore, we need to update the availability_html value to reflect what we want for each variation, and then output the updated $available_variations that will be parsed by json_encode().

So in the variable.php template, I added the following code before the <form> element:

foreach( $available_variations as $i => $variation ) {
    //check if variation has stock or not 
    if ( $variation['is_in_stock'] ) {
        // Get max qty that user can purchase
        $max_qty = $variation['max_qty'];

        // Prepare availability html for stock available instance
        $availability_html = '<p class="stock in-stock">' . $max_qty . ' units available for your purchase.' . '</p>';
    } else {
        // Prepare availability html for out of stock instance
        $availability_html = '<p class="stock out-of-stock">Oops, we have no stock left.</p>';
    $available_variations[$i]['availability_html'] = $availability_html;

And the json_encode found at the form’s data-product_variations attribute will create the updated data.

That’s it.

Querying Custom Post Types with Page Navigation on Front Page

I was experimenting with displaying custom post types on the front page of a wordpress site using various methods.

I had first tried using get_posts(), but it couldn’t deal with pagination.

The next alternative was to use WP_Query(). At first I had tried to implement this in the home.php template, but next_posts_link() returned an error 404. It had teh same result when I tried in on front-page.php.

My last try was to implement this as a page template, and in the “Reading Settings” of the WordPress admin, selected to display a static page that used the page template.


This made a difference, and it worked. So I’ve come to the conclusion that when implementing a solution to display custom post types with pagination on a website’s home page, using WP_Query() through a page template is the optimal way to do so.

Here’s the final code:

//get the correct paged figure on a static page - see related note (a)
if ( get_query_var('paged') ) {
   $paged = get_query_var('paged');
elseif ( get_query_var('page') ) {
   $paged = get_query_var('page');
else {
   $paged = 1;

// Query Custom Post Type posts. WP_query instead of get_posts for pagination purposes
$custom_posts = new WP_Query(
      'post_type' => 'my_custom_post_type',
      'paged' => $paged

// Start the loop
if ( $custom_posts->have_posts() ) :
   while ( $custom_posts->have_posts() ) :
      get_template_part( 'content-archive', get_post_type() );

// next_posts_link() usage with max_num_pages - see related note (b)
next_posts_link( 'Older Entries', $custom_posts->max_num_pages );
previous_posts_link( 'Newer Entries' );

Related notes:
(a) https://codex.wordpress.org/Pagination
(b) https://codex.wordpress.org/Function_Reference/next_posts_link

Adding Custom Styles Dropdown in WordPress TinyMCE Editor

I have been trying out a WordPress plugin called WP Code Prettify to make code snippets on this website look more presentable. Previously, I was simply using <pre> or <code> tags without any styling and it was difficult to read.

Well, WP Code Prettify will automatically style all <pre> or <code> tags specified with the prettyprint CSS class.

Everything’s pretty cool except that I had to manually type in class="prettyprint" in the WordPress text editor, which is going to be somewhat of a hassle in the long run.

Prior to WordPress 3.9, there was a ‘Formats’ dropdown, in which we could add custom styles which the user could then simply select to apply specific CSS classes to elements.

But in 3.9’s TinyMCE 4.0, the Formats dropdown is hidden by default. So the first thing I had to do was to reactivate it. This Formats dropdown “button” in TinyMCE is called styleselect. In functions.php in the theme, enable styleselect like this:

// Callback function to insert 'styleselect' into the $buttons array
function custom_mce_buttons_2( $buttons ) {
	array_unshift( $buttons, 'styleselect' );
	return $buttons;
// Register the callback to the appropriate filter
add_filter('mce_buttons_2', 'my_mce_buttons_2');

Note that ‘_2’ in the mce_buttons_2 filter refers to the second row of the TinyMCE buttons. I could use mce_buttons_3 which would add it to an empty third row but it wouldn’t look as good, sitting there all alone – wasting space as well.

Now I can go on to add custom styles to this Formats dropdown, which will allow me to simply select it from the list and apply it to <pre> elements:

// Callback function to filter the MCE settings
function custom_mce_before_init_insert_formats( $init_array ) {  
    // Define the style_formats array
    $style_formats = array(  
            'title' => 'Prettify',  
            'block' => 'pre',  
            'classes' => 'prettyprint',
            'styles' => array(
                'display' => 'block',
                'background' => '#eee',
                'white-space' => 'pre-wrap',
                'padding' => '10px'
            'title' => 'AnotherOne',  
            'inline' => 'span',  
            'classes' => 'class-a class-b etc'
            'title' => 'AnotherTwo',  
            'selector' => 'p',  
            'classes' => 'class-d'
    // Insert the array, JSON ENCODED, into 'style_formats'
    $init_array['style_formats'] = json_encode( $style_formats );  
    return $init_array;  

// Attach callback to 'tiny_mce_before_init' 
add_filter( 'tiny_mce_before_init', 'custom_mce_before_init_insert_formats' );

The above code will add 3 new style formats titled Prettify, AnotherOne and AnotherTwo to the Formats dropdown.

Selecting Prettify will apply the prettyprint class to an element. Since the block argument was specified as pre, it creates a new <pre> element with the style applied, and will replace the existing block element selected.

When AnotherOne is selected: since the inline argument was specified, it creates a new inline <span> element with the specified classes applied, and will wrap whatever is selected in the editor, not replacing any tags.

When AnotherTwo is selected: since the selector argument was specified, it limits the specified format to a specific HTML tag (in this case, the <p>), and will apply the specified classes to an existing tag instead of creating one.

You can refer to the WP Codex for the full Style Format Arguments specified for $style_formats. Just an additional note regarding ‘styles’ argument – this is used for rendering the style of the element when shown in the editor. I could have added this in editor-style.css instead.

To go further, if I have many other format items to add to the dropdown, I could even categorise multiple format items by creating a nested dropdown by specifying $style_formats like this, :

// Creating nested format/style items with it's own settings
$style_formats = array(  
        'title' => 'Category 1',
        'items' => array(
                'title' => 'Item 1',  
                'block' => 'div',  
                'classes' => 'class-a'
                'title' => 'Item 1',  
                'block' => 'div',  
                'classes' => 'class-b'
        'title' => 'Category 2',
        'items' => array(
                'title' => 'Item 3',  
                'block' => 'div',  
                'classes' => 'class-c'
                'title' => 'Item 4',  
                'block' => 'div',  
                'classes' => 'class-d'

So that’s all, and not too difficult to implement. In my opinion, it is important to consider how you would want your user to use the style formats that you add to the Formats dropdown. So specifying the correct values to the inline | block | selector and wrapper arguments is crucial. For example, if wrapper is set to true for a format, and the user keeps on applying it to a block element without first clearing the formatting, we will end up creating nested block elements unknowingly.

Formats Dropdown

An example of a TinyMCE Formats nested dropdown button

Now, I hope the code snippets are easier to read than before!

Next and previous post link in same custom taxonomy

Until now, if you use next_post_link(‘%link’, ‘%title’, true) or previous_post_link(‘%link’, ‘%title’, true) to get the adjacent post for a custom post type which has a taxonomy assigned to it, it doesn’t work as intended. This is because these two functions are based on get_adjacent_post() which is hardcoded to look to the taxonomy ‘category’. So hard luck if you need them to work for your custom taxonomy.

There is a plugin that helps solve this issue: http://wordpress.org/extend/plugins/previous-and-next-post-in-same-taxonomy (update: this plugin is no longer available).  And work is ongoing to resolve this, which you might want to have a read: http://core.trac.wordpress.org/ticket/17807 .

However, if you have customised the order of your custom post type posts, the above plugin is not going to work, because the above mentioned functions are hardcoded to get next and previous posts based on their post dates.

So if you need to get next and previous post links in the same custom taxonomy, with a custom posts order, you might want to try these few lines of codes in your single.php template:

// get_posts in same custom taxonomy
$postlist_args = array(
   'posts_per_page'  => -1,
   'orderby'         => 'menu_order title',
   'order'           => 'ASC',
   'post_type'       => 'your_custom_post_type',
   'your_custom_taxonomy' => 'your_custom_taxonomy_term'
$postlist = get_posts( $postlist_args );

// get ids of posts retrieved from get_posts
$ids = array();
foreach ($postlist as $thepost) {
   $ids[] = $thepost->ID;

// get and echo previous and next post in the same taxonomy        
$thisindex = array_search($post->ID, $ids);
$previd = $ids[$thisindex-1];
$nextid = $ids[$thisindex+1];
if ( !empty($previd) ) {
   echo '<a rel="prev" href="' . get_permalink($previd). '">previous</a>';
if ( !empty($nextid) ) {
   echo '<a rel="next" href="' . get_permalink($nextid). '">next</a>';

Hope this helps!


The above issues to get adjacent posts based on taxonomy has been fixed according to http://core.trac.wordpress.org/ticket/17807 , but this is still limited to getting posts sorted by post date only. However, this is being resolved here: https://core.trac.wordpress.org/ticket/26937 .

You can now add a $taxonomy argument to each of the adjacent post functions. Previously, related functions took an array of category (IDs) to search. These can now be taxonomy term IDs and each function now has $taxonomy = ‘category’ as an optional argument.

Related functions affected: get_previous_post(), get_next_post(), get_adjacent_post(), get_adjacent_post_rel_link(), adjacent_posts_rel_link(), next_post_rel_link(), prev_post_rel_link(), get_boundary_post(), get_previous_post_link(), previous_post_link(), get_next_post_link(), next_post_link(), get_adjacent_post_link(), adjacent_post_link().

get_header_image() returns null

While working on a theme in wordpress 3.4.2, I realised that wordpress function get_header_image() returns null in a ‘mu-plugins’ plugin even though in the theme’s functions.php file I’ve set a ‘default-image’ like this:

add_theme_support( 'custom-header', array(
    'default-image' => get_template_directory_uri() . '/subdir/default-header-image.jpg'

In the theme template file header.php, I’ve called get_header_image(), and it returns the default image properly on the front-end.

It seems the ‘default-image’ defined in functions.php add_theme_support is not ‘saved’ into the database upon theme activation. And most probably because functions.php is loaded after mu-plugins, and therefore in the plugin it’s not possible to use get_header_image() to get the  ‘default-image’ defined in ‘add_theme_support’.

Well, now the question is whether wordpress should save the ‘default-image’ to database upon theme activation? Comments anyone?

WordPress Tinymce Dialogs

If you are trying to implement tinymce for your theme options page or plugins and the Insert/edit link doesn’t pop up the dialog after the button is clicked, try this:

add_action( 'admin_print_footer_scripts', 'wp_tiny_mce_preload_dialogs', 30 );
add_action( 'tiny_mce_preload_dialogs', 'wp_link_dialog', 30 );

This worked for me as of version 3.1.3.

Converting HTML entities to characters

I was trying to use WordPress post titles as email subject headers in such a way:

$subject = get_the_title();
wp_mail( $to, $subject, $message);

However this became a problem when the post title included smart quotes, em-dash, ellipsis and the likes of them. My email subject ended up looking like this:

Hey &#8211; This is my Post&#8217;s Title

where it should have been:

Hey - This is my Post's Title

Well, I solved this by using the php function html_entity_decode before sending the $subject to wp_mail():

$subject = html_entity_decode( get_the_title(), ENT_QUOTES, 'UTF-8' )

ENT_QUOTES denotes converting both double and single quotes. The last parameter defines the character set – it is set as UTF-8 since smart quotes and em-dashes are part of the UTF-8 set.

Extend WordPress Login Expiration

The default login session cookie is 48 hours. Although it’s usually enough for most users, it can be frustratingly short for developers and administrators. Here’s something useful for those who do not want the hassle of logging in now and then. Add this to your theme’s functions.php , or create a php file and load it in the Must Use Plugins folder:

add_filter( 'auth_cookie_expiration', 'new_login_session_period' );
function new_login_session_period( $expirein ) {
    return 31556926; // this equals to 1 year in seconds

But I guess you’ll also have to make sure that your browser settings does not expire your cookies within 1 year (or any figure that you’ve specified) for the above to work.

WordPress 3.1 and setup_postdata

After upgrading one of my websites to WordPress to version 3.1, the loops that contained setup_postdata() created a mess. After some testing, I realised that setup_postdata() will only return the correct data if the argument passed is $post, i.e. setup_postdata($post). I had used setup_postdata( $ancestor ) instead and it created a mess after the upgrade.

Now I had this running in my code:

foreach( $ancestors as $ancestor )  {
   setup_postdata( $ancestor );
   // Do things with the_title()
   // Do things with the_post_thumbnail()
   // Do things with the_permalink()
   // Do things with get_post_custom()
   // Do alot of other things with $ancestor

I could solve this mess by changing to the below code, but this required changing all $ancestor variables to $post

foreach( $ancestors as $post )  {
   setup_postdata( $post );
   // Do things with the_title()
   // Do things with the_post_thumbnail()
   // Do things with the_permalink()
   // Do things with get_post_custom()
   // Do alot of other things with $post 

But I reckoned it wasn’t as efficient, and also it might create more bugs due to the edit of so many variable calls. In the end I opted for a quick fix to pass $ancestor into the $post variable just before setup_postdata( $post ). In this way, I’ll still able to get the correct data from the_title(), the_post_thumbnail(), the_permalink() and get_post_custom(), without having to change all $ancestor calls to $post that come after.

foreach( $ancestors as $ancestor )  {
   $post = $ancestor;
   setup_postdata( $post );
   // Do things with the_title()
   // Do things with the_post_thumbnail()
   // Do things with the_permalink()
   // Do things with get_post_custom()
   // Do alot of other things with $ancestor

Ok, hope this might be useful if you faced the same issue. Anyone has alternative solutions?

Ways to load template files in WordPress

The below methods mostly uses get_template_directory() to retrieve the parent theme directory and get_stylesheet_directory() if you are using a child theme and retrieving the  of  child theme directory.

Using include() and require()

These are built-in PHP functions and you can use them to load template files like this. Note that they do not check file existence, and you’ll get an error if the file do not exist.

include( get_template_directory() . '/file.php' );
require( get_template_directory() . '/file.php' );
include( get_stylesheet_directory() . '/file.php' );
require( get_stylesheet_directory() . '/file.php' );
include( get_template_directory() . '/subdir/file.php' );
require( get_template_directory() . '/subdir/file.php' );
include( get_stylesheet_directory() . '/subdir/file.php' );
require( get_stylesheet_directory() . '/subdir/file.php' );

You can also use include_once() and require_once().

Using load_template()

load_template() is a WordPress function that works just like include() and require(). It does not check for file existence as well.

load_template( get_template_directory() . '/file.php' );
load_template( get_stylesheet_directory() . '/file.php' );

Using locate_template()

locate_template() checks for file existence. It searches files in both parent theme and child theme directory, and overloads from the child theme.

locate_template($template_names, $load, $require_once);
  • $template_names can be a single filename or an array of names.
  • $load is a boolean parameter. It defaults to false and when true, the searched file(s) are loaded.
  • $require_once is a boolean parameter and defaults to true – when true, it loads the file using php require_once() function, else it loads using php require().

You can code it like this

locate_template( 'file.php', true );
locate_template( 'subdir/file.php, true );
locate_template( array( 'file1.php', 'file2.php' ), true);

Using get_template_part()

get_template_part() (as of WordPress 3.0) loads a template part into a template (other than header, sidebar, footer). This makes it easier for a theme to reuse sections of code in an easy to overload way if using child themes. This function will load a file named “{slug}-{name}.php”. The $name is optional, and if it’s empty, the function will include file named “{slug}.php”.

get_template_part( $slug, $name );

If you want to load a file named options-general.php, you can code it like this:

get_template_part( 'options', 'general' );

If you want to load from a subdirectory, you can code it like this:

get_template_part( 'subdir/options', 'general' );

Best Practices

Although there are several ways to load files in WordPress, we have to consider carefully which methods are best for particular cases. Considerations might include whether we want to allow child themes to overwrite certain functions etc. Justin Tadlock has written a comprehensive article on how to load files within WordPress themes, and gives ample analysis for best practices.

© 2018 Bucket Press