What the Queries

I’ve never been a fan of IDEs, complex debugging tools with breakpoints, variable watch lists and all that fancy stuff. var_dump() and print_r() have always been my best friends.

Recently I was playing around with the caching arguments in WP_Query, trying to combine that with update_meta_cache() while sticking wp_suspend_cache_addition() somewhere there in the middle, and it quickly became a mess, so I wanted to know what queries am I actually running under the hood.

I came up with this little piece, which I think I’ll use more often from now on:

// Assuming SAVEQUERIES in set to true.
$GLOBALS['wpdb']->queries = array();

// All the magic goes here

var_dump( $GLOBALS['wpdb']->queries );

This gives you a nice list of SQL queries that were triggered only by that magic code in between. Works great when you need a quick sanity check on all those caching arguments, priming meta or term caches, splitting queries and whatnot.

Obviously it empties the initial set of queries, so anything in Debug Bar, Query Monitor, etc. will no longer be accurate.

What’s your favorite way to keep track of queries?

How to: Disable HTTP Calls in WordPress

Sometimes you’re travelling on a plane or on a boat, in the metro or on the road. Sometimes you just have a crappy Internet connection, and you’ll notice that a local WordPress install (mostly admin pages) takes several seconds to load. That could create a big problem if you’re developing a theme or plugin, and have to refresh eighty times per minute.

WordPress uses its HTTP API (the WP_Http class and wrapper functions) to look for plugin, themes and core updates, fetch RSS feeds or talk to third party API (such as a Twitter widget plugin) and with no Internet connection, calls to such functions will timeout in a few seconds, thus the long page load time. A simple solution is to simply disable all HTTP calls and luckily, WordPress allows us to do that in a single filter for our theme (functions.php) or plugin file:

add_filter( 'pre_http_request', '__return_true', 100 );

The smarter way would be to intercept the request and let it pass or block it based on the request URL, that way you’ll be able to work with local APIs. Yet another benefit of using the WordPress HTTP API and not file_get_contents or curl_exec :)

Update: As Dion Hulse mentioned on Twitter, you can also use WP_HTTP_BLOCK_EXTERNAL in your config file to achieve the same thing, but in a more “cron friendly” way. More information about this can be found somewhere around this line.

Native Image Sizing “On the Fly” with WordPress

I tweeted it out not too long ago, and it seems to have gotten people’s attention. So why do WordPress theme developers still use TimThumb? One of the valid reasons seems to be dynamic image sizing. Of course if you’re using TimThumb for post thumbnails in your theme, your life saver is the add_image_size function — you don’t need “dynamic resizing” since all your thumbnails are of equal sizes throughout your theme.

However, the valid reason I seem to have bumped in, is the fact that sometimes you would want to use a specific size for an image, but only once, for one post or page. The add_image_size function here will add a lot of overhead, crunching all the uploaded images into the size you want to use only once. Like a shortcode that can resize and crop an image from your media library to whatever dimensions you tell it to:

[image src="http://example.org/wp-content/uploads/2012/03/image.png" width="150" height="150"]

Right, a shortcode (argh!) to dynamically resize an image. Fair enough, a lot of premium themes seem to have something similar, but mostly use TimThumb because it’s so simple. However, I’ve created an image shortcode function that resizes and crops images from the media library on the fly using the image_make_intermediate_size function available as early as WordPress 2.5!

It saves the resized image on disk, and returns the absolute URL to that image. Of course you’d want to add things like captions, alt tags and so on, but the basic idea is there. Why is this better than TimThumb?

  • It stores the image files on disk and uses absolute URLs to those images, meaning you won’t have problems hosting your thumbnails on a CDN.
  • It uses functions native to WordPress and works with the WordPress media library, so extra files are deleted when an attachment is deleted — no more junk in your cache/folder.
  • It doesn’t have a zero-day vulnerability :)

There are drawbacks too, like the fact that it’s a shortcode! Although I’m pretty sure we can use the same technique and hook it directly to the content, bypassing the shortcodes madness. Oh, and it doesn’t support remote files too, only the ones in your media library, but that’s a good thing, as we have all figured out by now.

Feel free to fork the Gist on Github and experiment with the code, I’m sure you can think of how to make it better, easier to use and faster. Thoughts and comments welcome, and thank you for stopping by!

How to Get the Current URL in WordPress

Here’s a quick tip! I was wandering around the web for the perfect solution to retrieve the current URL in a WordPress theme or plugin. I found a bunch of solutions for PHP, but not directly related to WordPress so I thought there has to be an easier way, and after a few hours of examining with global variables seems like I found it.

global $wp;
$current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) );

Beats all the $_SERVER approaches and no need to identify whether the host is using SSL, etc. You can add a trailing slash to that with trailingslashit if you need to, and it looks much cleaner too. Hope you enjoy that, and thanks for tweeting ;)

Change the year of all posts in a particular category to 2012

Snippet! Change the year of all posts in a particular category to 2012 with a single SQL query (use with phpMyAdmin or the MySQL command line interface)

UPDATE wp_posts AS p
  JOIN wp_term_relationships AS tr ON tr.object_id = p.id
  JOIN wp_term_taxonomy AS tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
  JOIN wp_terms AS t ON tt.term_id = t.term_id
  SET p.post_date = REPLACE(p.post_date, YEAR(p.post_date), 2012)
  WHERE t.slug = 'my-category-slug' AND tt.taxonomy = 'category';

Obviously replace my-category-slug with the category you’d like to target and perform the same magic on the p.post_date_gmt field. Not entirely sure why you would use such a technique, but it was asked by Jim Edwards on Twitter.

Varnish and Preview Posts in WordPress

I wrote earlier that I started playing around with Varnish here on my site and that post has a little snippet that strips all incoming and outgoing cookies (except the admin of course.) Today I stumbled on a problem where I had no permission to preview a post I was drafting in WordPress and they all turned 404’s when I tried to.

I first thought Varnish was stripping out the preview query string but I was wrong, the problem was that WordPress knew I was logged in and editing the post when I were in the admin panel, but when I tried to preview it on the front end Varnish was stripping out my login cookies, hence it didn’t display my draft post.

Here’s a snippet for vcl_recv and vcl_fetch that should go before the unset cookies statement which passes the request to the web server if preview=true is found in the request URL.

if (req.url ~ "preview=true") {
	return(pass);
}

Restart the Varnish service and voila! Your cookies aren’t stripped out anymore and you can now preview your posts and pages. Do note though that if somebody manually types in the preview query string in the browser, they’ll by-pass Varnish as well.

Attachments Filename and Directory in WordPress

I was trying to figure out how to get the absolute directory of an attachment post in WordPress. Turns out there’s no easy function that can give you one, but there is one called wp_upload_dir which will give you an array of the upload directories and URLs. So here’s the secret sauce:

$url = wp_get_attachment_url( $post_ID );
$uploads = wp_upload_dir();
$file_path = str_replace( $uploads['baseurl'], $uploads['basedir'], $url );

The $file_path variable will now contain an absolute path (filesystem path, not URL) to the location of your attachment file. You can then use it when sending attachments with wp_mail or perhaps when serving the file dynamically. Enjoy!

Cleaner Titles in WordPress

Quick Tip! What happens when your post title does not fit on one line? It wraps to the second line. What if it’s only one word? And what if that word is “it” or some other shorty? Your title won’t look too nice, eh? Here’s a solution, somewhere inside the loop:

$title = the_title( '<h2>', '</h2>', false );
if ( strlen( $title ) > 0 )
    echo substr_replace( $title, '&nbsp;', strrpos( $title, ' ' ), 1 );

This will look at the last space character in the title and replace it with a non-breaking space character meaning that the last word will always stick to the one before it, hence if the title wraps it’ll be at least two words. Let’s hope the two words are not “is it” :) Anyone know of a CSS solution that can do this?

Post Formats in WordPress: Breaking Down Those Quotes

Here’s a function that would grab the contents HTML and parse out the first quote (blockquote element) together with it’s cite (usually the quote author) and the remaining text that comes after the quote. This is useful for when dealing with the quote post format in WordPress.

function get_blockquote() {
    $dom = new DOMDocument;
    $dom->loadHTML( apply_filters( 'the_content', get_the_content( '' ) ) );
    $blockquotes = $dom->getElementsByTagname( 'blockquote' );

    if ( $blockquotes->length > 0 ) {

        // First blockquote
        $blockquote = $blockquotes->item(0);

        $cite = $blockquote->getElementsByTagName( 'cite' )->item( 0 );
        $p = $blockquote->getElementsByTagName( 'p' );

        $cite_content = '';
        if ( $cite && $p ) {

            // Remove the cite from the paragraph
            foreach ( $p as $paragraph )
                try { $paragraph->removeChild( $cite ); }
                catch( Exception $e ) {}

            $cite_content = $dom->saveXML( $cite );
        }

        $blockquote_content = '';
        foreach ( $p as $paragraph ) {
            if ( strlen( trim( $paragraph->nodeValue ) ) > 0 )
                $blockquote_content .= $dom->saveXML( $paragraph );
            else
                $paragraph->parentNode->removeChild( $paragraph );

        $blockquote->parentNode->removeChild( $blockquote );
        $remaining_content = $dom->saveXML();
    }
    return $blockquote_content; // $cite_content or $remaining_content
}

As you can see you have an option of returning the quote contents, the author contents or the stuff that’s not related to the first quote. You can also bundle all three of them in an array if needed. Anyways, as I said, this might come useful when dealing with the quote post format in WordPress.

Quote post format in WordPress

We’ve got a great example on Theme.fm and the best part is that you don’t need to change the way you write quotes and since you’ve got the quote content, the author and the rest of the content as separate entities, you can style your first (main) quote however you like.

This continues my discussion on Tumblr-like Post Formats by Alex King and Crowd Favorite. And obviously the code snippet can be improved, but hey, who needs regular expressions? ;)

Encode Entities Inside PRE Tags

Here’s a little Python script that searches through a given file for pre tags and encodes anything in between. This is useful for when escaping from syntax highlighting plugins and replacing every occurrence of the code shortcode with a pre tag.

import re, sys

# First argument is the filename, output is filename.encoded
filename = sys.argv[1]
f = file(filename)
output = open('%s.encoded' % filename, 'w+');

# Read the whole file, fire the regular expressions
contents = f.read()
expr = re.compile(r'<pre>(.*?)</pre>', re.MULTILINE|re.DOTALL)
matches = expr.findall(contents)

# Loop through each match and replace < > with &lt; and &gt;
for match in matches:
	contents = contents.replace(match, match.replace('<', '&lt;').replace('>', '&gt;'));

# Write output file and close both files
output.write(contents)
output.close()
f.close()

Most syntax highlighting plugins will encode all entities on the fly for you so when you stop using them your code might break. Also, most highlighting plugins will render your TinyMCE visual editor useless when working with code, and I think it’s quite common to work with code using the visual editor in WordPress. At least Twenty Ten and Twenty Eleven understand that ;)

However, as seen from the replacement part, I don’t really encode all entities but rather replace the greater than and less than symbols. It’s enough for most cases but if you need a real entity encoding you should use the cgi.escape function which is similar to htmlspecialchars in php.

Feed this script with your database dump and it’ll create a new file with an .encoded prefix which you can feed back to MySQL. Please note though that this script reads the entier input file which may lead to slow execution, high memory usage and swapping when working with large files. Worked fine on my 30 megabyte database though.