Category Archives: WordPress Tips & Tricks

Display WordPress featured image, thumbnail, or YouTube thumb

Huge thanks to Vladimir Prelovac, who wrote the original function. I use it a ton and have adapted it a bit to check for:

  1. Featured image; then
  2. First image attached to the post; then
  3. The first image inserted in the post; then
  4. The thumbnail of the first YouTube video inserted in the post

All I added was the featured image bit. :)

Here’s the full function, plus 3 helper functions, which should all be inserted in your theme’s functions.php file:

  • [UPDATED 2013.03.09 to return correct size for inserted images AND to allow for the function to return the featured-image only. This baby is getting long, let me know if you find a way to hone it down!]
/**** 
IMAGE PARSING FUNCTIONS 
****/

/** HELPER FUNCTION 1: **/
// GET YOUTUBE ID FROM URL
// see http://webgarb.com/tutorials/how-to-get-youtube-video-id-from-url-perfect-way/
function youtubeID($url){
     $res = explode("v=",$url);
     if(isset($res[1])) {
        $res1 = explode('&',$res[1]);
        if(isset($res1[1])){
            $res[1] = $res1[0];
        }
        $res1 = explode('#',$res[1]);
        if(isset($res1[1])){
            $res[1] = $res1[0];
        }
     }
     return substr($res[1],0,12);
     return false;
}

/*** HELPER FUNCTION 2: ***/
// FIND YOUTUBE URLS IN CONTENT AND CONVERT TO SIMPLE FORMAT
// adapted from answer here: http://stackoverflow.com/a/5831191/107244 
function parseYouTubeURLs($mm_text) {
    $mm_text = preg_replace('~
        # Match non-linked youtube URL in the wild. (Rev:20111012)
        https?://         # Required scheme. Either http or https.
        (?:[0-9A-Z-]+\.)? # Optional subdomain.
        (?:               # Group host alternatives.
          youtu\.be/      # Either youtu.be,
        | youtube\.com    # or youtube.com followed by
          \S*             # Allow anything up to VIDEO_ID,
          [^\w\-\s]       # but char before ID is non-ID char.
        )                 # End host alternatives.
        ([\w\-]{11})      # $1: VIDEO_ID is exactly 11 chars.
        (?=[^\w\-]|$)     # Assert next char is non-ID or EOS.
        [?=&+%\w-]*        # Consume any URL (query) remainder.
        ~ix', 
        'http://www.youtube.com/watch?v=$1',
        $mm_text);
    return $mm_text;
}

/*** HELPER FUNCTION 3: ***/
// GET ATTACHMENT ID
// see http://wordpress.stackexchange.com/a/7094
if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        $query['meta_query'][0]['key'] = '_wp_attached_file';

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

/*** MAIN FUNCTION, GET THUMBNAIL ***/
// Your theme must support post thumbnails for this function to work. If you are getting an error try adding add_theme_support('post-thumbnails'); to your functions.php file 
// NOTE: If $feature is set to true, the image will only be returned if it is set as a featured image.
function vp_get_thumb_url($text, $size, $feature = false) {
    global $post;
    $imageurl="";

    // Check to see which image is set as "Featured Image"
    $featuredimg = get_post_thumbnail_id($post->ID);
    // Get source for featured image
    $img_src = wp_get_attachment_image_src($featuredimg, $size);
    // Set $imageurl to Featured Image
    $imageurl = $img_src[0];

    // if not returning only the featured image, move on and get something else
    if ($feature == false) {

        // If there is no "Featured Image" set, move on and get the first image attached to the post
        if (!$imageurl) {
            // Extract the thumbnail from the first attached imaged
            $allimages =&get_children('post_type=attachment&post_mime_type=image&post_parent=' . $post->ID );

            foreach ($allimages as $img){
                $img_src = wp_get_attachment_image_src($img->ID, $size);
                break;
            }
            // Set $imageurl to first attached image
            $imageurl=$img_src[0];
        }

        // If there is no image attached to the post, look for anything that looks like an image and get that
        if (!$imageurl) {
            preg_match('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*)/i' , $text, $matches);
            $imageurl=$matches[1];

            // get image ID - uses helper function get_attachment_id() )
            $image_id = get_attachment_id($imageurl);

            // retrieve the relevant size of our image
            $image_src = wp_get_attachment_image_src($image_id, $size);

            // set $imageurl to first inserted image
            $imageurl = $image_src[0];
        }

        // YOUTUBE
        // If there's no image attached or inserted in the post, look for a YouTube video
        if (!$imageurl) {

            // FIND FIRST YOUTUBE URL IN CONTENT
            // uses helper function parseYouTubeURLs
            $youtubeurl = parseYouTubeURLs($text);

            // GET YOUTUBE ID FROM URL
            // users helper function youtubeID();
            $videokey = youtubeID($youtubeurl);

            if ($videokey) {
                // Get the thumbnail YouTube automatically generates
                // '0' is the biggest version, use 1 2 or 3 for smaller versions
                $imageurl = "http://i.ytimg.com/vi/{$videokey}/0.jpg";
            }
        }

        // DEFAULT IMAGE
        // if there's no image or embedded YouTube, show a default image
        if (!$imageurl) {

        }

    } // feature = false

    // Spit out the image path
    return $imageurl;
}
/*** END FEATURED IMAGE PARSING FUNCTIONS ***/

And to display the image in your theme, often on archive.php or index.php within the loop, add this:

// Show featured image, or first image if no featured, or YouTube thumbnail
if (function_exists('vp_get_thumb_url')) {

	// Set the desired image size. Swap out 'thumbnail' for 'medium', 'large', or custom size
	$thumb=vp_get_thumb_url($post->post_content, 'thumbnail');

	if ($thumb!='') { ?>

		<a href="<?php the_permalink() ?>" title="<?php the_title(); ?>" rel="bookmark"><img class="alignleft" src="<?php echo $thumb; ?>" alt="<?php get_the_title(); ?>" /></a>

	<?php }
}
Body classes with page-parent-name and page-name

Add post/page name + page parent name to body class

This will add a page-slug class and a page-parent-slug class to your body tag, along with all the other defaults. Put this in your functions.php file:

function wpprogrammer_post_name_in_body_class( $classes ){
if( is_singular() ) {
     global $post;
     $parent = get_page($post->post_parent);
     array_push( $classes, "{$post->post_type}-{$post->post_name}" );
     array_push( $classes, "{$post->post_type}-parent-{$parent->post_name}" );
     }
return $classes;
}
add_filter( 'body_class', 'wpprogrammer_post_name_in_body_class' );

Also make sure your open body tag looks like this (you can probably find it in header.php):


<body <?php body_class(); ?>>

Many thanks to Utkarsh Kuketri for the original function!

How I created the scaling post thumbnails on Friendly (blog)

Creating the post thumbnails on this blog

The thumbnails on this blog don’t look much different from most other thumbnails out on the web. They’re all set to a standard 650px wide by 120px tall, automatically cropped thanks to WordPress. But there are a few nice things happening behind the scenes, so I thought I’d share how I did it.

First, I added a few lines into my functions.php file to create that new, custom image size since I didn’t want to have to use up my thumbnail size (because I might want truly small thumbnails to appear in sidebars or elsewhere on the site).

// This theme uses post thumbnails
 add_theme_support( 'post-thumbnails' );

// Add a custom image size called "pagewidth"
if ( function_exists( 'add_image_size' ) ) {
 add_image_size( 'pagewidth', 650, 120, true );
 }

Next I added a function to my functions.php which automatically yanks the “Featured” image, or first image, or YouTube video screengrab, for each post. I found this brilliant function on Vladimir Prelovac’s blog – here’s a link to the original. My version is slightly different. I’ve commented in my changes:


function vp_get_thumb_url($text)
{
 global $post;

 $imageurl="";

 // extract the thumbnail from attached imaged
 $allimages =&get_children('post_type=attachment&post_mime_type=image&post_parent=' . $post->ID );

 foreach ($allimages as $img){
 // CHANGE FOLLOWING TO USE 'PAGEWIDTH' IMAGE SIZE RATHER THAN DEFAULT (THUMBNAIL)
 $img_src = wp_get_attachment_image_src($img->ID,'pagewidth');
 break;
 }

 $imageurl=$img_src[0];

 // try to get any image
 if (!$imageurl)
 {
 preg_match('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*)/i' ,  $text, $matches);
 $imageurl=$matches[1];
 }

 // try to get youtube video thumbnail
 if (!$imageurl)
 {
 preg_match("/([a-zA-Z0-9\-\_]+\.|)youtube\.com\/watch(\?v\=|\/v\/)([a-zA-Z0-9\-\_]{11})([^<\s]*)/", $text, $matches2);

 $youtubeurl = $matches2[0];
 if ($youtubeurl)
// CHANGED TO 0.jpg INSTEAD OF 1.jpg AS THIS IS THE LARGER VERSION OF THE YOUTUBE THUMBNAIL.
// STILL WORKING ON HOW TO GET BETTER SCREENGRABS FOR YOUTUBE VIDS BUT FOR NOW THIS WORKS
$imageurl = "http://i.ytimg.com/vi/{$matches2[3]}/0.jpg";
 }

return $imageurl;
}

Again, slight changes in the code used to display these images. Specifically I’ve added a conditional so that nothing happens if the post has no image or YouTube embed, and I’ve linked the image to the associated post. This goes in the Loop where your posts are getting spit out (in my case, loop.php; often in index.php):

<!-- Show featured image, or first image if no featured, or YouTube thumbnail  -->
 <?php $thumb=vp_get_thumb_url($post->post_content);
 if ($thumb!='') { ?>
 <div id="foreground">
 <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>" rel="bookmark"><img src="<?php echo $thumb; ?>" alt="<?php get_the_title(); ?>" /></a>
 </div>
 <?php } ?> 

Why wrap the image in that div, I hear you cry? Well a bit more magic comes into play in the CSS, so that bigger images don’t overflow the layout when the screen is resized down.

It’s a handy trick I found in Zoe Mickley Gillenwater’s smart post. Here’s the bit of CSS required for this site:

div#foreground {
 overflow: hidden;
 width: 100%;
 height: 126px;
 margin-bottom:1em;
 background-color:#000;
 text-align:center;
} 

And that is that!

Customizing Feedburner feed information

How to add custom RSS feeds or custom content to current feeds

A client wanted their blog feeds, which were being syndicated via email by Feedburner, to include post author information and a ‘tweet this’ link at the top of each email between the title and post content.

By default Feedburner strips out the native RSS2 author info (no idea why, nor at the time of this writing does anyone on the web that I can find), so I had to work up a custom solution to this issue.

The code below was partly drawn from http://www.seodenver.com/custom-rss-feed-in-wordpress/.

// CREATE A CUSTOM FEED
function create_my_customfeed() {
    load_template( TEMPLATEPATH . '/feed-rss-custom.php');
}
add_action('do_feed_customfeed', 'create_my_customfeed', 10, 1); // I believe 'do_feed_customfeed' determines the name of the feed. try do_feed_othername to see if that works.

// UPDATE REWRITE RULES SO CUSTOM FEED IS ACCESSIBLE
// Note: Go into Settings > Permalinks and re-save to make your permalinks pick up these new rules.
function custom_feed_rewrite($wp_rewrite) {
    $feed_rules = array(
        'feed/(.+)' =&gt; 'index.php?feed=' . $wp_rewrite-&gt;preg_index(1),
        '(.+).xml' =&gt; 'index.php?feed='. $wp_rewrite-&gt;preg_index(1)
    );
    $wp_rewrite-&gt;rules = $feed_rules + $wp_rewrite-&gt;rules;
}
add_filter('generate_rewrite_rules', 'custom_feed_rewrite');

// TWEET THIS FUNCTION
function tweet_this() {
    global $post;
    $tweet = sprintf( __('Currently reading %1$s %2$s'), $post-&gt;post_title, wp_get_shortlink() );
    echo '<a class="tweethis" href="http://twitter.com/home?status=' . urlencode( $tweet ) . '">Tweet this</a>';
}

function tweet_this_rss() {
    global $post;
    ob_start();
    $tweet = sprintf( __('%1$s %2$s'), $post-&gt;post_title, wp_get_shortlink() );
    echo '<a class="tweethis" href="http://twitter.com/home?status=' . urlencode( $tweet ) . '"><img src="http://blog.eloqua.com/wp-content/plugins/sociable-eloqua/images/twitter.png" border="0" alt="" />Tweet this</a>';
    return ob_get_clean();
}

function wpbeginner_postrss($content) {
    $author = get_the_author();
    if(is_feed()) {
        $content = '<span class="extrarssinfo">by ' . $author . ' | ' . tweet_this_rss() . '</span>' . $content;
    } elseif (is_feed('customfeed')) {
        // SWITCH THE IF/ELSE ORDER ONCE WORDPRESS 3.1 INSTALLED
        // I believe specification of custom feed names has been added to is_feed() in wp3.1
         $content = $content;
    }
return $content;
}
add_filter('the_excerpt_rss', 'wpbeginner_postrss');
add_filter('the_content', 'wpbeginner_postrss');