WordPress 3.5 came out with an awesome feature of ordering by post__in
(Codex). So when I got to my current issue, I noticed that I could not use the default orderby options (alphabetical title, ID, etc.), so the code used to create the post__in orderby
can also be extended to be used for get_terms
, which by default is not available in WordPress core. However, there is a great filter to enable this (see WordPress ticket).
Call get_terms()
So, first, I need to setup the function. In this scenario, I am using WooCommerce, but it could work with any theme, or ecommerce solution. For more information on get_terms() please see the WordPress Codex.
<?php | |
/** | |
* Output the homepage categories HTML Markup | |
* | |
* @uses wps_category_image() Outputs image HTML Markup | |
*/ | |
function wps_homepage_categories() { | |
$args = array( | |
'orderby' => 'include', | |
'order' => 'ASC', | |
'hide_empty' => false, | |
'include' => array( 28 /* Appearal */, 27 /* Accessories */, 30 /* Outerwear */, 29 /* Hiking */, 22 /* Grooming */, ), | |
'fields' => 'all', | |
'pad_counts' => false, | |
'd2c_home' => true, //optional | |
); | |
$product_cats = get_terms( 'product_cat', $args ); | |
foreach ( $product_cats as $cat ) { | |
wps_category_image( $cat->term_id, $size ); | |
} | |
} |
In this code, I use wps_category_image()
which outputs the WooCommerce category image.
<?php | |
/** | |
* Outputs HTML markup for category image for WooCommerce. | |
* | |
* @param int $cat_id Category ID. | |
* @param string $size Image size. | |
* @param array $attr Image attributes. | |
* @return string $orderby Modified orderby SQL string. | |
*/ | |
function wps_category_image( $cat_id, $size, $attr = array() ) { | |
// get the thumbnail id user the term_id | |
$thumbnail_id = get_woocommerce_term_meta( $cat_id, 'thumbnail_id', true ); | |
// get the image URL | |
$image = wp_get_attachment_url( $thumbnail_id ); | |
// print the IMG HTML | |
echo wp_get_attachment_image( $thumbnail_id, $size, false, $attr ); | |
} |
Filter get_terms_orderby
Next, is the really cool part. You want to filter the get_terms_orderby SQL.
<?php | |
add_filter( 'get_terms_orderby', 'wps_get_terms_orderby', 10, 2 ); | |
/** | |
* Modifies the get_terms_orderby argument if orderby == include | |
* | |
* @param string $orderby Default orderby SQL string. | |
* @param array $args get_terms( $taxonomy, $args ) arg. | |
* @return string $orderby Modified orderby SQL string. | |
*/ | |
function wps_get_terms_orderby( $orderby, $args ) { | |
if ( isset( $args['orderby'] ) && 'include' == $args['orderby'] ) { | |
$include = implode(',', array_map( 'absint', $args['include'] )); | |
$orderby = "FIELD( t.term_id, $include )"; | |
} | |
return $orderby; | |
} |
First, you need to check to see if include is the preferred orderby argument.
Second, you want to sanitize it with absint()
.
Third, set the order to the FIELD include (see here for more information).