Archives: Snippets | Page 14

Change the Default Excerpt Length in WordPress

The following filter lets you set the excerpt length that WordPress displays when calling the the_excerpt function. In this example we set the excerpt length to 20 words (the default is 55):

function sv_excerpt_length( $length ) {
	return 20;
}
add_filter( 'excerpt_length', 'sv_excerpt_length', 999 );

The filter only affects excerpts that WordPress generates automatically from the post content. A manual excerpt entered in the editor is shown in full. The priority of 999 makes sure your value wins over a theme or plugin that sets its own length.

This uses the excerpt_length filter. Learn more in WordPress Hooks Explained.

Include Custom Post Types in WordPress Search Results

Custom Post Types (CPTs) are not included in WordPress search results by default. The following snippet lets you choose which custom post types to add to WordPress search results. Add this code to your theme’s functions.php file and change the post type names as needed:

function custom_post_type_search( $query ) {
     if ($query->is_search) {
          $query->set('post_type', array( 'post', 'myCustomPostType1', 'myCustomPostType2', 'myCustomPostType3'));
     }
     return $query;
}
add_filter( 'pre_get_posts', 'custom_post_type_search' );

If you want more advanced search options, take a look at the post “Improving search with Relevanssi“.

Display Content for Mobile Only with wp_is_mobile

There is a function called wp_is_mobile that provides a condition to display content only when the user is viewing on mobile. The function returns true when the site is loaded on mobile. Use it like this:

<?php  if( wp_is_mobile()){  ?>
// mobile stuff goes here
<?php } else { ?>
// desktop stuff goes here
<?php  } ?>

Note: Make sure your caching mechanism caches separately for mobile and desktop. You can do this for example with the WP-Rocket plugin.

Add Class to the First Post in the WordPress Loop

Say you want to highlight the first post in the loop in some way. You can add a specific class to it and then style it with CSS. Do this in functions.php:

function wps_first_post_class( $classes ) {
    global $wp_query;
    if( 0 == $wp_query->current_post )
        $classes[] = 'first';
        return $classes;
}
add_filter( 'post_class', 'wps_first_post_class' );

For more on customizing the WordPress loop, see WordPress Template Hierarchy.

Add Tracking Code to WooCommerce Thank You Page

The following code lets you add tracking code to the WooCommerce Thank You page after a purchase. The $order variable contains all the relevant information for that order so you can send the details to the tracking service you use.

Pay attention to the comments in the code to understand where to add the tracking code and how to use this variable:

/**
 * Add custom tracking code to the thank-you page
 */

function my_custom_tracking( $order_id ) {

	// Lets grab the order
	$order = wc_get_order( $order_id );

	/**
	 * Put your tracking code here
	 * You can get the order total etc e.g. $order->get_total();
	 */
	 
	// This is the order total
	$order->get_total();
 
	// This is how to grab line items from the order 
	$line_items = $order->get_items();

	// This loops over line items
	foreach ( $line_items as $item ) {
  		// This will be a product
  		$product = $order->get_product_from_item( $item );
 
  		// This is the products SKU
		$sku = $product->get_sku();
		
		// This is the qty purchased
		$qty = $item['qty'];
		
		// Line item total cost including taxes and rounded
		$total = $order->get_line_total( $item, true, true );
		
		// Line item subtotal (before discounts)
		$subtotal = $order->get_line_subtotal( $item, true, true );
	}
}
add_action( 'woocommerce_thankyou', 'my_custom_tracking' );

Auto Display First Post Image or Default Fallback Image

Say you want to use the featured image (post thumbnail) that WordPress provides, but you have an archive with many posts and it would take a long time to add that featured image to each of them.

For new posts you can use the featured image in the standard way, but for old posts you want to use the first image in the post content as the featured image, or a default image if there are no images in that specific post. Add the following code to functions.php:

function catch_that_image() {
  global $post, $posts;
  $first_img = '';
  ob_start();
  ob_end_clean();
  $output = preg_match_all('/<img.+?src=['"]([^'"]+)['"].*?>/i', $post->post_content, $matches);
  $first_img = $matches[1][0];

  if(empty($first_img)) {
    $first_img = "/path/to/default.png";
  }
  return $first_img;
}

And to use this inside the WordPress loop:

if ( get_the_post_thumbnail($post_id) != '' ) {

  echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
   the_post_thumbnail();
  echo '</a>';

} else {

 echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
 echo '<img src="';
 echo catch_that_image();
 echo '" alt="" />';
 echo '</a>';

}

For more on WordPress image handling, see Image Sizes in WordPress.

Add Category Name to body_class in WordPress

The body_class function helps add classes to the body tag, which usually contains information about what type of page is currently displayed, and allows you to style specific elements on that page by that specific class.

For some reason WordPress does not add a class describing which category (or categories) you are in on a single post page (e.g. single.php). To add the category name to that body tag, use the following code:

function sv_add_category_to_single($classes) {
    if (is_single() ) {
        global $post;
        foreach((get_the_category($post->ID)) as $category) {
            // add category slug to the $classes array
            $classes[] = $category->category_nicename;
        }
    }
    // return the $classes array
    return $classes;
}
add_filter('body_class','sv_add_category_to_single');

This uses the body_class filter. Learn more in WordPress Hooks Explained.

Get the Featured Image URL in WordPress

To get the featured image URL in WordPress, use get_the_post_thumbnail_url(). It returns just the image URL instead of a full <img> tag, which is what you need for a CSS background-image, an Open Graph tag or a JavaScript slider.

get_the_post_thumbnail() returns the complete image element, and it is the right choice when you want an <img> with srcset. For the URL alone, use the snippets below.

Get the Featured Image URL

Add this inside the WordPress loop, in a template such as single.php or a template part:

<?php
if ( has_post_thumbnail() ) {
    $thumb_url = get_the_post_thumbnail_url( get_the_ID(), 'large' );
    ?>
    <div class="post-hero" style="background-image: url('<?php echo esc_url( $thumb_url ); ?>');"></div>
    <?php
}
?>

The variable $thumb_url holds the URL of the current post’s featured image in the large size.

How It Works

get_the_post_thumbnail_url( $post, $size ) has been in core since WordPress 4.4 (see the function reference). Both parameters are optional:

  • $post: a post ID or WP_Post object. Defaults to the global post in the loop.
  • $size: any registered size name, such as thumbnail, medium, large or full, or an array of width and height. Defaults to post-thumbnail.

The function returns false when the post has no featured image, so check has_post_thumbnail() first.

If the size name is not registered, WordPress returns the original image URL. See How to Define New Image Sizes in WordPress for adding your own sizes.

To print the URL directly, the_post_thumbnail_url( 'large' ) echoes it already escaped. The Featured Image panel only appears in the editor when your theme declares add_theme_support( 'post-thumbnails' ) in functions.php.

Outside the Loop or by Post ID

Pass the post ID as the first argument when you are outside the loop, for example in a widget or a hook:

$thumb_url = get_the_post_thumbnail_url( 42, 'full' );

When you also need the image dimensions, get the attachment ID first and use wp_get_attachment_image_src():

$thumb_id = get_post_thumbnail_id( 42 );
$image    = wp_get_attachment_image_src( $thumb_id, 'large' );

if ( $image ) {
    list( $url, $width, $height ) = $image;
}

If you only need the URL from an attachment ID, wp_get_attachment_image_url( $thumb_id, 'large' ) is the shorter version.

Featured Image URL from the REST API

A post object from the REST API only includes featured_media, which is the attachment ID. Add _embed=wp:featuredmedia to get the image data in the same request:

fetch( '/wp-json/wp/v2/posts?_embed=wp:featuredmedia' )
    .then( ( response ) => response.json() )
    .then( ( posts ) => {
        posts.forEach( ( post ) => {
            const media = post._embedded?.[ 'wp:featuredmedia' ]?.[ 0 ];
            const url   = media?.source_url;                        // original image
            const large = media?.media_details?.sizes?.large?.source_url; // large size, if generated
            console.log( post.id, url, large );
        } );
    } );

Limiting _embed to one relation works since WordPress 5.4, as described in the REST API global parameters docs.

If you also use _fields, include _links and _embedded in the list, or the embed is skipped. For a full example, see Show Posts from another Blog using REST API.

FAQs

Common questions about getting the featured image URL in WordPress:

How do I get the full-size featured image URL?
Pass 'full' as the size: get_the_post_thumbnail_url( get_the_ID(), 'full' ). This returns the URL of the uploaded image instead of a resized copy.
Why does get_the_post_thumbnail_url return false?
The post has no featured image set, or the function is looking at a different post than you expect. Outside the loop the global post may not be the one you want, so pass the post ID explicitly.
What is the difference between get_the_post_thumbnail and get_the_post_thumbnail_url?
get_the_post_thumbnail() returns a complete <img> tag with srcset, alt and dimensions. get_the_post_thumbnail_url() returns only the URL string.
Where is source_url in the REST API response?
With _embed, it is at _embedded['wp:featuredmedia'][0].source_url. Resized versions are under media_details.sizes, each with its own source_url.

Add Class to next_posts_link and previous_posts_link

These functions, if you are not familiar, create links to the previous and next post. They have many options but not one that lets you add a class to the link. If you want to do that, add the following code to your functions.php file:

add_filter('next_posts_link_attributes', 'posts_link_attributes');
add_filter('previous_posts_link_attributes', 'posts_link_attributes');

function posts_link_attributes() {
  return 'class="styled-button"';
}

For more on pagination, see Add Pagination to WordPress Templates.