Powerful WordPress Tips And Tricks

About The Author

Hello, I’m Daniel and I make things for the web. I’m the CTO at Kinsta and I write for a number of amazing publications like Smashing Magazine and … More about Daniel ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 200,000+ folks.

Daniel Pataki has been working with WordPress since the dawn of time, and he still discovers new tips and tricks. He has compiled his own list of 21 techniques that are handy, fun or best practices rarely followed. He hopes everyone finds something new in the list!

I’ve been working with WordPress since the dawn of time, and even though I peek at the source code regularly, I still discover new tips and tricks. I’ve compiled my own list of 21 techniques that are handy, clever, fun or best practices rarely followed. I hope everyone finds something new in the list!

21 tips

1. WordPress Has A Ton Of Built-In Scripts

Using the great wp_enqueue_script() and wp_enqueue_style(), you can include styles and scripts easily with dependency management. But did you know that WordPress has a lot of scripts already built in? jQuery, many elements of jQuery UI, jQuery Form, SWF Object, Tiny MCE, Jcrop and Thickbox are just some the better known ones. The whole list can be found in the WordPress Codex. If you’re interested in learning how to use the enqueue functions effectively, I recommend “The Developer’s Guide to Conflict-Free JavaScript and CSS in WordPress” right here on Smashing Magazine!

2. Replace Built-In Scripts By Deregistering Them

If you live on the bleeding edge, you can use versions of scripts other than the built-in ones. Using a newer jQuery version is common (though not necessarily good) practice, which can be done in the following way.

function my_scripts_method() {
   wp_deregister_script( 'jquery' );
   wp_register_script( 'jquery', get_template_directory_uri() . '/js/jquery-new.js');
   wp_enqueue_script( 'jquery' );
}
add_action('wp_enqueue_scripts', 'my_scripts_method');

But do not do this just to brag about using latest stuff. WordPress includes the version of jQuery that it does to ensure maximum compatibility.

Use another version of jQuery only when encountering compatibility issues, such a plugin that specifically requires it.

3. Force Perfect JPG Images

This is a classic example of why working on a team is beneficial. My good friend Lars told me that WordPress doesn’t use 100% quality for images served on the website, to conserve space and bandwidth. He also showed me a solution, of course:

add_filter( 'jpeg_quality', 'smashing_jpeg_quality' );
function smashing_jpeg_quality() {
   return 100;
}

Wordpress uses a default quality of 90%. This is fine in most cases; I doubt many people can see the difference. But if top-notch image quality is a must on your website (for a portfolio, photography, etc.), modifying the value might be best.

4. FeedBurner Redirection

FeedBurner is used on almost every blog that I’ve worked on, and yet I never know how exactly to set it up by heart. Thanks to Elio for writing “10 Tips to Optimize Your WordPress Theme,” which contains this snippet:

add_action( 'template_redirect' , 'smashing_rss_redirect');
function smashing_rss_redirect() {
   if ( is_feed() AND !preg_match( '/feedburner|feedvalidator/i', $_SERVER['HTTP_USER_AGENT'] ) ){
      header( 'Location: https://feeds.feedburner.com/my_smashing_feed' );
      header( 'HTTP/1.1 302 Temporary Redirect' );
   }
}

5. Using General Taxonomy Functions

A number of taxonomy functions can handle your custom taxonomies as well as the built-in tags and categories. The Codex’s reference of functions contains the full list of taxonomy functions. I particularly like using get_term(), get_terms() and wp_get_object_terms(). To make things more modular, I use these functions as much as I can, even for tags and categories.

6. Setting Up Sessions In WordPress

Sessions are great for storing information between pages and are widely used on websites. WordPress doesn’t use them at all internally, so the session is never set. Using the following method, you can start a session on all pages before any output.

add_action( 'init', 'smashing_session_start' );
function smashing_session_start() {
   if ( !session_id() ) {
      session_start();
   }
}

Note that, while sessions are generally pretty safe, implement IP checking or added nonce protection just to be on the safe side. As long as you’re transmitting non-sensitive data, though, you’ll fine. Check out Mark Jaquith’s great article on nonces for more info.

7. List All Hooked Functions

I started writing a function to do this. When I did a quick Google search, it turned out that WP Recipes had exactly what I needed.

function list_hooked_functions($tag=false){
   global $wp_filter;
   if ($tag) {
      $hook[$tag]=$wp_filter[$tag];
      if (!is_array($hook[$tag])) {
         trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
         return;
      }
   }
   else {
      $hook=$wp_filter;
      ksort($hook);
   }

   echo '<pre>';

   foreach($hook as $tag => $priority){
      echo "<br />&gt;&gt;&gt;&gt;&gt;t<strong>$tag</strong><br />";
      ksort($priority);
      foreach($priority as $priority => $function){
         echo $priority;
         foreach($function as $name => $properties) {
            echo "t$name<br />";
         }
      }
   }
   echo '</pre>';
   return;
}

Used without an argument, you’ll get a nice list of all hooked functions. This will be a bit long, so you can specify a hook to narrow the list a bit. This is particularly useful when debugging or fiddling around with hook priorities. Knowing what’s hooked into wp_head() in what order is important, and this function is a great asset!

8. Automatically Add Paragraph Tags To Anything

WordPress does this automatically to the content and the excerpt, but there’s no reason not to use it elsewhere. The function responsible for turning double line breaks into paragraphs is wpautop().

$my_text = 'Welcome!
Smashing Magazine is a great place to learn new things.
I hope you’re having a nice time!';

echo wpautop( $my_text );

Sometimes you’ll want to disable this filter by default, which you can do by removing it from the content and excerpt, like so:

remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );

9. Send Emails Using WordPress

A little while back, I wrote a long article on “Creating Perfect Emails for Your WordPress Website,” a part of which has to do with using the wp_mail() functions. These functions let you use built-in WordPress awesomeness to send emails to users.

$message = 'Hello, thanks for reading my post! I hope to see you back soon.';
wp_mail( 'someonesemail@example.com', 'Thanks for reading my post!', $message);

You can also send HTML content by using a filter:

add_filter ("wp_mail_content_type", "smashing_mail_content_type");
function smashing_mail_content_type() {
   return "text/html";
}

It came as a surprise to me about six months ago that you don’t need any plugins to pull off proper paging (i.e. not just “Previous” and “Next” links); you can do it with a native function. The paginate_links() function is a handy little thing that lets you show pagination for any type of content, not just a WordPress loop.

// Pagination for a WordPress loop
$list = new WP_Query( $query_args );
$pagination = array(
   'base'       => str_replace( 99999, '%#%', get_pagenum_link( 99999 ) ),
   'format'     => '?paged=%#%',
   'current'    => max( 1, get_query_var( 'paged' ) ),
   'total'      => $list->max_num_pages,
   'next_text'  => 'next',
   'prev_text'  => 'previous'
);
echo '<div class="pagination primary-links">' . paginate_links( $pagination ) . '</div>';

// Pagination for anything
$list = range(1, 100);
$items_per_page = 12;
$pagination = array(
   'base'       => get_bloginfo( 'url' ) . '/mypage/%_%',
   'format'     => '?paged=%#%',
   'current'    => $_GET['current_page'],
   'total'      => ceil( max($list) / $items_per_page ),
   'next_text'  => 'go forth',
   'prev_text'  => 'go back'
);
echo '<div class="pagination primary-links">' . paginate_links( $pagination ) . '</div>';

11. Upload Files With Ease

WordPress has a bunch of great uploading functions for everything from checking the file type to finding the uploads directory. A more obscure function is wp_upload_bits(), which you can use to upload a file to the uploads directory.

$upload = wp_upload_bits( $_FILES['myfile']['name'], null, file_get_contents( $_FILES['myfile']['tmp_name'] ) );
echo 'Well uploaded! The path to this file is ' . $upload['file'] . ' and the url to this file is ' . $upload['url'];

12. Twitter-Like Time Display

This was another shock to me a while back, especially since it has been in WordPress since version 1.5! If you’d like to show viewers a relative date in a human-readable format, like “5 minutes ago” or “one month ago,” try the human_timed_diff() function.

$diff = human_time_diff( '2012-05-05 12:05:00', '2012-05-05 12:10:00' );
echo 'This comment was submitted ' . $diff . 'ago';

// Output: This comment was submitted 5 minutes ago

13. Log In As Any User

If you’re building a complex website with many roles, being able to switch between them quickly and easily would be useful. The wp_set_auth_cookie() lets you log the current user in based on ID.

$user_id = 4;
   wp_set_auth_cookie( $user_id );

Take great care when using this function; left unchecked, it could log every user in as user number 4. Even while testing, I target it specifically to my IP, and maybe even to a special URL string just to be sure. That said, with proper safety, it can be used as part of a custom log-in script.

14. Add Custom Profile Fields In The Admin Area

I can’t say that WordPress offers much in the way of profile customization in the administration area. Especially nowadays, when you want to show the Twitter and other social accounts of authors, this is a shortcoming. It can be fixed easily, though. Have a look here:

<?php
add_action( 'show_user_profile', 'smashing_profile_fields' );
add_action( 'edit_user_profile', 'smashing_profile_fields' );

function smashing_profile_fields( $user ) { 
?>

   <h3>Social Sites</h3>

   <table class="form-table">

      <tr>
         <th><label for="twitter">Twitter</label></th>

         <td>
            <input type="text" name="twitter" id="twitter" value="<?php echo esc_attr( get_the_author_meta( 'twitter', $user->ID ) ); ?>" /><br />
            <span class="description">Your Twitter Username</span>
         </td>
      </tr>

      <tr>
         <th><label for="twitter">Facebook</label></th>

         <td>
            <input type="text" name="facebook" id="facebook" value="<?php echo esc_attr( get_the_author_meta( 'facebook', $user->ID ) ); ?>" /><br />
            <span class="description">Your Facebook Profile URL</span>
         </td>
      </tr>

      <tr>
         <th><label for="twitter">Linkedin</label></th>

         <td>
            <input type="text" name="linkedin" id="linkedin" value="<?php echo esc_attr( get_the_author_meta( 'linkedin', $user->ID ) ); ?>" /><br />
            <span class="description">Your Linkedin Profile URL</span>
         </td>
      </tr>

   </table>

<?php
}
add_action( 'personal_options_update', 'smashing_save_profile_fields' );
add_action( 'edit_user_profile_update', 'smashing_save_profile_fields' );

function smashing_save_profile_fields( $user_id ) {
   if ( !current_user_can( 'edit_user', $user_id ) )
      return false;

   update_user_meta( $user_id, 'twitter', $_POST['twitter'] );
   update_user_meta( $user_id, 'facebook', $_POST['facebook'] );
   update_user_meta( $user_id, 'linkedin', $_POST['linkedin'] );
}

15. Sanitize URLs With Ease

When working with URLs, always make sure they are properly formed and don’t contain any invalid or dangerous characters. The esc_url() function lets you do just that.

$my_url = 'https://mypage.com/?awesome=true';
   $url = esc_url( $my_url );

Be sure to check out all of the other escape functions. You can find a list of them at the bottom of the page that I linked to in the related section.

16. Empower Text Widgets

To make text widgets so much better, you can enable the use of shortcodes in them. This is a great tool for theme developers because it makes your product much more flexible for the user.

add_filter( 'widget_text', 'do_shortcode' );

17. Add Custom Post Types To The RSS Feed

Not being able to do this easily from the admin area is a big issue. Many website owners separate their content into custom posts, and they also want all of their items to show up in the feeds. Never fear — a function is here!

add_filter('request', 'smashing_custom_feed');
function smashing_custom_feed( $vars ) {
   if ( isset( $vars['feed'] ) ) {
      $vars['post_type'] = get_post_types();
   }
   return $vars;
}

While this is great, it forces all of your post types into the feed. If you’d like to add just some of your custom post types to the feed, you can list them separately.

add_filter('request', 'smashing_custom_feed');

$post_type_list = array( 'post', 'products' );
function smashing_custom_feed( $vars ) {
   if ( isset( $vars['feed'] ) AND !isset( $vars['post_type'] ) ) {
      $vars['post_type'] = $post_type_list;
   }
   return $vars;
}

18. Don’t Break WordPress Loops

Multiple loops are great but can wreak havoc if not used correctly. To make sure your loop runs smoothly and you can still use all of the functions that rely on globals, store the original query in a temporary variable.

$tmp_query = $wp_query;
query_posts('cat=5&order=ASC');
while( have_posts() ) : the_post() 
?>
   <a href="<?php the_permalink() ?>'><?php the_title() ?></a><br />
<?php
$wp_query = $tmp_query;

19. Custom Database Queries

If you need something more than what the default WordPress functions give you, you can use $wpdb, the WordPress database class to query the database directly.

$recent_users = $wpdb->get_results( "SELECT display_name, user_registered FROM $wpdb->users ORDER BY user_registered DESC LIMIT 0,10" );

This class has great features and functions. Take a look at “Interacting With the WordPress Database” for an in-depth tutorial.

20. Customize WordPress Post Revisions

The post revisions feature in WordPress is great, but the majority of users don’t use it. Database entries are created for revisions, even if they are not used. While they’re not a huge hit on your server’s performance, if you don’t use revisions, you can disable them by placing the following code in your wp-config.php file.

// To remove revisions
define( 'WP_POST_REVISIONS', FALSE );

// To limit them
define( 'WP_POST_REVISIONS', 5 );

20. Styling Author Comments

If you’d like author comments to jump out, simply use the bypostauthor class in your CSS.

li.bypostauthor {
   background:#fafafa;
   color:#555;
}

21. Storing Your Whole Page In A Variable

In some cases, storing your whole output in a variable can be very helpful. This allows you to make global changes, compress or obfuscate code and more very easily. All we need is PHP output buffering and two hooks.

add_action('wp_head', 'smashing_buffer_start');
add_action('wp_footer', 'smashing_buffer_end');

function smashing_buffer_start() {
   ob_start( 'smashing_callback' );
}

function buffer_end() {
   ob_end_flush();
}

function smashing_callback( $content ) {
   // Feel free to do things to the content here
   $content = str_replace( 'great', 'awesome', $content );
   echo $content;
}

And The List Goes On

Do you have any favorite WordPress tips and tricks or best practices that you wish were followed more? Please do share in the comments so that we can all learn something new!

Further Reading

Smashing Editorial (al, ea, mrn)