10 Useful WordPress Hook Hacks

Advertisement

Hooks are very useful in WordPress. They allow you to “hook” a custom function to an existing function, which allows you to modify WordPress’ functionality without editing core files. In this article, we have compiled 10 extremely useful ready-to-use WordPress hooks, along with examples and coding explanations.

What Is A Hook?

To achieve a particular effect on a WordPress blog, you have to modify how WordPress works. Some of these modifications are made to what WordPress developers call “core files,” files required by WordPress to work properly.

But modifying core files is always a bad idea. It may create a security loophole. Also, you will have lost the modification when you upgrade your WordPress installation.

Still, developers need to overwrite some of WordPress’ functionality, which is why WordPress provides the Plugin API1.

Hooks are one of the main building blocks of WordPress plug-ins. Almost every plug-in uses a hook to overwrite WordPress’ core functionality.

How to Use Hooks on Your WordPress Blog

Unless you’re writing a plug-in, you would write hooks in the functions.php file. This file is located in the wp-content/themes/yourtheme directory.

A hook, as you would expect, “hooks” one function to another. For example, you could write a custom function and attach it to one of WordPress’ core functions:

add_action ( 'publish_post', 'myCustomFunction' );

In this example, we hook our own custom function to WordPress’ publish-post function, which means that every time WordPress executes the publish-post function, it will also execute this hooked function.

Of course, we can also remove hooks using the remove_action() function:

remove_action ( 'publish_post', 'myCustomFunction' );

Hooks resources:

1. Disable WordPress’ Automatic Formatting

Screenshot

The problem.
You have probably noticed that, by default, WordPress converts normal quotes to “curly” quotes, and makes other little formatting changes when a post is displayed.

This is very cool for people who publish normal content, but anyone who uses their blog to discuss code will be annoyed because, when pasted in a text editor, code with curly quotes returns syntax errors.

The solution.
Simply paste the following code in your functions.php file:

function my_formatter($content) {
  $new_content = '';
  $pattern_full = '{([raw].*?[/raw])}is';
  $pattern_contents = '{[raw](.*?)[/raw]}is';
  $pieces = preg_split($pattern_full, $content, -1, PREG_SPLIT_DELIM_CAPTURE);

  foreach ($pieces as $piece) {
    if (preg_match($pattern_contents, $piece, $matches)) {
      $new_content .= $matches[1];
    } else {
      $new_content .= wptexturize(wpautop($piece));
    }
  }

  return $new_content;
}

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

add_filter('the_content', 'my_formatter', 99);

Once that’s done, you can use the [raw] shortcode in your posts:

[raw]This text will not be automatically formatted.[/raw]

Code explanation.
Our first step here was to create a function that uses a regular expression to find the [raw] shortcode in your posts’ content.

Then we hook our my_formatter() function to WordPress’ the_content() function, which means that my_formatter() will now be automatically called every time the_content() is called.

To remove the automatic formatting, we use the remove_filter() function, which lets you delete a hook on a specific function.

Source:

2. Detect The Visitor’s Browser Using A Hook

Screenshot

The problem.
Cross-browser compatibility is probably the most common problem in Web development. You will save yourself a lot of headaches if you are able to detect the browsers that people use to visit your website and then create a custom class wrapped in the body tag. Few people are aware of it, but WordPress can already detect browsers, and a few global variables are available for us to use.

The solution.
Nothing hard here: just paste the code below in your functions.php file, then save the file and you’re done!

<?php
add_filter('body_class','browser_body_class');
function browser_body_class($classes) {
  global $is_lynx, $is_gecko, $is_IE, $is_opera, $is_NS4, $is_safari, $is_chrome, $is_iphone;

  if($is_lynx) $classes[] = 'lynx';
  elseif($is_gecko) $classes[] = 'gecko';
  elseif($is_opera) $classes[] = 'opera';
  elseif($is_NS4) $classes[] = 'ns4';
  elseif($is_safari) $classes[] = 'safari';
  elseif($is_chrome) $classes[] = 'chrome';
  elseif($is_IE) $classes[] = 'ie';
  else $classes[] = 'unknown';

  if($is_iphone) $classes[] = 'iphone';
  return $classes;
}
?>

Once you have saved the file, the function will automatically add a CSS class to the body tag, as shown in the example below:

<body class="home blog logged-in safari">

Code explanation.
WordPress has global variables that return true if a visitor is using a particular browser. If the visitor’s browser is Google Chrome, the $is_chrome variable will return true. This is why we create the browser_body_class() function, which returns the name of the visitor’s browser. Once that’s done, we just hook the function to WordPress’ body_class() function.

Sources:

3. Define Default Text In TinyMCE

Screenshot

The problem.
Many bloggers almost always use the same layout for their blog posts. Posts on my own blog WpRecipes.com are always displayed the same way: some text, some code and then some more text.

What about saving time by forcing tinyMCE (WordPress’ visual editor) to display default text?

The solution.
Once again, hooks are the solution. Just open your functions.php file, paste the code and let the hooks work their magic!

<?php
add_filter('default_content', 'my_editor_content');

function my_editor_content( $content ) {
  $content = "If you enjoyed this post, make sure to subscribe to my rss feed.";
  return $content;
}
?>

Code explanation.
This code is powerful, and yet the method is so simple. Just create a function that returns the desired text (in this example, we have defined some simple text that asks readers to subscribe to the blog’s RSS feed), and hook the function to WordPress’ default_content() function. That’s it.

Sources:

4. Insert Content Automatically After Each Post

Screenshot

The problem.
Most blogs use the single.php template to insert some text, images or ads just after a post. Sure, this can be done by opening single.php and pasting the desired text after the the_content() function. But the text won’t show up in your RSS feed? Hooks and the technique described below solve this problem.

The solution.
One again, simply paste the code below in the functions.php file of your theme. That’s it.

function insertFootNote($content) {
        if(!is_feed() && !is_home()) {
                $content.= "<div class='subscribe'>";
                $content.= "<h4>Enjoyed this article?</h4>";
                $content.= "<p>Subscribe to our  <a href='http://feeds2.feedburner.com/WpRecipes'>RSS feed</a> and never miss a recipe!</p>";
                $content.= "</div>";
        }
        return $content;
}
add_filter ('the_content', 'insertFootNote');

Code explanation.
The purpose of the insertFootNote() function is pretty simple: it simply concatenates text of your choice to the $content variable, which contains your post’s content.

Then, our insertFootNote() function is hooked to the the_content() function, and it is automatically called every time the the_content is called. Using this function is basically the same as typing in the text at the end of each post.

Notice the (!is_feed) condition on line 2, which prevents the text from being inserted in the RSS feed. If you want the text to appear in your RSS feed, replace line 2 with the following:

if (!is_home()) {

Sources:

5. Disable The “Please Update Now” Message On WordPress Dashboard

Screenshot

The problem.
Your dashboard automatically lets you know when a new version of WordPress is released by inserting a message at the top of admin pages. This is definitely a good thing, because updating gives your blog the latest functions and security fixes. But if the blog is a client project, letting the client control updates may not be a good idea.

The solution.
Just paste these four lines of code in your functions.php file:

if (!current_user_can('edit_users')) {
  add_action( 'init', create_function( '$a', "remove_action( 'init', 'wp_version_check' );" ), 2 );
  add_filter( 'pre_option_update_core', create_function( '$a', "return null;" ) );
}

Once you save functions.php, you won’t see the message on the dashboard.

Code explanation.
The first thing we do here is make sure the current user has sufficient administrative rights to update WordPress. Once we do that, we just create two hooks to overwrite the automatic check for updates and message display.

Sources:

6. Disable WordPress From Auto-Saving Posts

Screenshot
Photo by thatcanadiangirl12

The problem.
As you type a post in the dashboard, WordPress periodically saves the content. This is a useful feature, but sometimes you may want to disable it.

The solution.
To disable WordPress’ auto-saving functionality, simply open the functions.php file and paste the following function:

function disableAutoSave(){
    wp_deregister_script('autosave');
}
add_action( 'wp_print_scripts', 'disableAutoSave' );

Code explanation.
Again, nothing hard about this code. We simply create an action (on line 4) and hook the disableAutoSave() function that we created on line 1 to WordPress’ wp_print_scripts().

The result is that our disableAutoSave() function is called every time WordPress executes wp_print_scripts(). This way, we make sure the auto-save functionality is disabled.

Sources:

7. Prevent Duplicate Content On Comment Pages

Screenshot

The problem.
Duplicate content is an SEO problem for many websites. It can also be a problem for your WordPress blog if you don’t apply a few tricks.

Introduced in version 2.7, paged comments is a great addition to WordPress because it lets bloggers split comments into multiple pages. The only problem, again, is the risk of duplicate content.

Let’s use the new rel="canonical" attribute to prevent duplicate content in paged comments.

The solution.
Simply paste the following code in your function.php file:

function canonical_for_comments() {
  global $cpage, $post;
  if ( $cpage > 1 ) :
    echo "n";
      echo "<link rel='canonical' href='";
      echo get_permalink( $post->ID );
      echo "' />n";
   endif;
}

add_action( 'wp_head', 'canonical_for_comments' );

Code explanation.
First, we create a function to add the rel="canonical" attribute to comment pages, except page 1. Then we hook this function to WordPress’ wp_head() function. As simple as that!

Sources:

8. Get Entire Post Or Page In A PHP Variable

Screenshot

The problem.
Being able to get the entire current post or page as a PHP variable is definitely a good thing. You could, for example, replace parts of the content using the str_replace() PHP function, and much more.

The solution.
Once again, nothing hard. Just paste the following in your function.php file.

function callback($buffer) {
  // modify buffer here, and then return the updated code
  return $buffer;
}

function buffer_start() {
  ob_start("callback");
}

function buffer_end() {
  ob_end_flush();
}

add_action('wp_head', 'buffer_start');
add_action('wp_footer', 'buffer_end');

Code explanation.
To achieve this hack, we need three functions:

  • callback(): this function returns the whole page as a variable called $buffer. You can modify it before returning it by using regular expressions, for example.
  • buffer_start(): this function simply starts the buffer. It is hooked to WordPress’ wp_head() function.
  • buffer_end(): this function clears the buffer. It is hooked to WordPress’ wp_footer() function.

Once we have our function, we just hook it to existing WordPress functions.

Sources:

9. Use Hooks And Cron To Schedule Events

Screenshot

The problem.
You probably already know that WordPress can schedule events. For example, it can publish posts at preset dates and times. Using hooks and wp-cron, we can easily schedule our own events. In this example, we will get our WordPress blog to send us an email once hourly.

The solution.
Paste the following code block in the functions.php file of your theme.

if (!wp_next_scheduled('my_task_hook')) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  wp_mail('you@yoursite.com', 'Automatic email', 'Hello, this is an automatically scheduled email from WordPress.');
}

Code explanation.
The first thing we did, of course, was create a function that performs the desired action. In this example, the function is called my_task_function() and it just sends an email to the specified email address.

To schedule an event, we have to use the wp_schedule_event() function. The last argument has to be a hook, which is why we hook our my_task_function() function to my_task_hook.

Sources:

10. List All Hooked Functions

Screenshot

The problem.
When things go wrong, listing all hooked functions can be very useful for debugging.

The solution.
As with the others, this code has to be pasted in your functions.php file. When you have finished debugging, don’t forget to remove the code from functions.php, or else the debugging message will continue to appear.

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;
}

Once that’s done, simply call the list_hooked_functions() function, as shown below, to print all hooked WordPress functions on your screen.

list_hooked_functions();

Code explanation.
If no hook name is provided to the function as an argument, then hooks are printed to the screen using the global variable $wp_filter. Alternatively, you can list one particular hook by passing its name as an attribute:

list_hooked_functions('wp_head');

Sources:

Related posts

You may be interested in the following related posts:

(al)

↑ Back to topShare on Twitter

This guest post was written by Jean-Baptiste Jung, a 28-year-old blogger from Belgium, who blogs about Web Development on Cats Who Code, about WordPress at WpRecipes and about blogging on Cats Who Blog . You can stay in touch with Jean by following him on Twitter.

  1. 1

    Great article!
    Thank you!

    -1
  2. 2

    Thank you.

    0
  3. 3

    Wp is an amazing tool

    1
  4. 4

    Excellent! Thanks!

    0
  5. 5

    Awesome post on hooks. Is there a resource to find all the available wordpress hooks or filters? Seems like a very powerful way of customizating WordPress. I am familiar with hooks in thesis, but didn’t know wordpress had body hooks etc.

    0
  6. 6

    These are the types of articles I love seeing on Smashing Magazine. This is genuinely useful! Excellent work Jean-Baptiste.

    0
  7. 7

    Pedro Magalhães

    August 18, 2009 8:56 am

    Very usefull. Thank you!

    0
  8. 8

    Wow, thanks for including my function (again)! :) I am glad other find it of use, it helped me figure out hooks a looot.

    0
  9. 9

    WOW! That’s a POST! (and it means i like it)

    1
  10. 10

    Thanks a lot!
    Every little (or big) wordpress hack is always welcomed…

    0
  11. 11

    I really love and respect your resource wprecipes.com, but don’t think it’s a great idea just to copy-paste your articles here on SM.

    0
  12. 12

    Thanks. An helpful post. :)

    0
  13. 13

    There is a plugin for number 3: http://wordpress.org/extend/plugins/simple-post-template/

    It works. I know because I wrote it. :) Your method of modifying the starting text is interesting…I was not aware of that particular filter. I may modify mine to emulate your method in the future as it is slightly cleaner.

    0
  14. 14

    Great post! Something I’ve tagged under wordpress as it will be very handy in the future when doing client sites.

    I would like to see more advanced wordpress function posts. Having functions built into a theme is much easier than trying to use 4-5 bloaty plug-ins.

    On a side note, does anyone know of a way to create a custom write pannel by coding from functions.php?

    0
  15. 15

    Loads of information. Thank you so much.

    Scott

    0
  16. 16

    Nice – Sometimes it feels like I live and breathe WordPress and you still presented one or two NEW ideas to me. Keep it up.

    0
  17. 17

    Great post, thanks !

    0
  18. 18

    incredible article ! /me waves

    0
  19. 19

    Excelent article! Thanks for sharing! :))

    0
  20. 20

    Just what I need, especially the formatting one, thanks

    0
  21. 21

    In response to Nick above, Mark Jaquith operates a site, wphooks.flatearth.org, which is a brilliant index of all WordPress hooks and filters available, that will do exactly what you want.

    0
  22. 22

    @Wes Bos

    check out the flutter plugin for WP. It implements custom write panels for pages and posts and is very powerful. With this plugin, you can make WP much closer to a CMS than it is by default.

    0
  23. 23

    This is wicked – thanks very much! I will use the ‘insert text after every post’ hook.
    uncleboob

    0
  24. 24

    @Jeremy Thanks a ton for the link!

    0
  25. 25

    I am loving it. Point 4, 5, 8 and 9 are deadly useful. Thanks a lot for sharing this great information

    0
  26. 26

    regarding: 6. Disable WordPress From Auto-Saving Posts:

    how could I make this into a small plugin? I’d like to execute this globally for a wpmu isntallation… or can I just use the code and have it automatically inserted somehow somewhere?

    0
  27. 27

    Ahmed El.Hussaini

    August 18, 2009 11:43 pm

    Really well documented article. Many thanks.

    0
  28. 28

    A really great post on WP Hooks. Especially for those starting out on WP. Alot of major annoyances can be resolved this way without editing core files.

    0
  29. 29

    Awesome article, thank you. In relation to number 8 (Get Entire Post Or Page In A PHP Variable) – and please excuse my ignorance – does anyone know whether this technique could be used to add a php call at the end of a page template which would produce, in code format, the entire HTML of the given page? I ask because there are cases where it would be really useful to be able to allow people to copy and paste the html of a given page, without having to dig through the page source.

    Thanks in advance for any help anyone can provide.

    Richard

    0
  30. 30

    Roundabout way to get to my point but I find it amusing with the kill IE6 mentality making its’ way around. Now I laughed when I saw the hook about detecting which browser is calling the page. Problem isn’t to write a custom for each user agent the problem is coders/developers not sticking to the spec. Solution is to write for the spec and screw it if the user doesn’t have a spec compliant browser. Gee I don’t know but maybe if the code was written to spec the code would be cleaner and less headaches? If the browser can’t handle it it’s a failure. IE 6 should have been strangled when it was released but developers just went ohhh ok we’ll add-in workaround code for every other browser. Fast forward X amount of years and it’s still around because developers couldn’t sack up at the time.

    0
  31. 31

    Amazing News ” super article”
    Needful things
    Thank you!

    0
  32. 32

    Wonderfully helpful article, thank you. No doubt I will be referring to this in the future.

    @shawn re IE6: If developers have extended the life of IE6 by accommodating for it, it is only because we are doing our jobs well and building sites for our end users, not for ourselves. Like it or not, many corporate users are still stuck on IE6. As a developer I build sites for paying clients who reasonably expect that users of all major browsers will be able to view the site they paid for. At 14% market share IE6 is sadly too popular to be written off just yet: in the real world, more people still use IE6 than Safari, Chrome and Opera combined. No serious client is going to be willing to forgo that traffic simply for the convenience of their developer. That’s why they pay us: to solve problems.

    0
  33. 33

    Yipes! Why advise folks to use rel='canonical' to avoid duplicate content on comment pages? In effect, that tells search engines to ignore the material available on comment pages (like, say, the comments) and instead always look to the main post permalink. It’s far better, I would have thought, to remove the post content itself from the comment pages — that is what is being duplicated, after all — not include rel='canonical' on those pages, and leave the comments to be indexed.

    Greg’s High Performance SEO plugin, available at http://wordpress.org/extend/plugins/gregs-high-performance-seo/, will take care of this duplicate content problem with aplomb (if I do say so myself, cough, sputter, ahem).

    All the best,
    Greg

    0
  34. 34

    WordPress is more awesome than I know. Cool hacks!

    0
  35. 35

    Helpful post for wp designers, thanks for share..

    0
  36. 36

    I learned so much about wordpress since I started to follow smashing magazine

    thanks for the amazing content!

    0
  37. 37

    These are extraordinary. I was especially interested in the disabling “please update now” hook. Definitely a concern when building sites for clients. Now I don’t have to worry. Also liked the “Schedule Events” hook. I can see that being very handy. It would be interesting to see somebody write a plugin allowing you to take advantage of this hook and “customize” a message/action with it.

    0
  38. 38

    Great tips man! Keep ‘em coming!

    0
  39. 39

    Let’s me try on ;)

    0
  40. 40

    Just now I was looking for one of your hacks: Default text for the authors. It is possible to create a template with css which can be used for different kind of articles?
    So far, thanks.

    0
  41. 41

    This is really what I want, thx you ; )

    1
  42. 42

    Good one for WordPress Pro Bloggers!

    0
  43. 43

    Just use adminimize and the hooks plugin. and you don’t need to code a single thing.

    0
  44. 44

    You’re right! These are useful. Thank you.

    0
  45. 45

    Thanks so much for all the information.
    I find it amazing how much I don’t know.
    You have given me a look into something
    new and I just wanted to say thank you.

    0
  46. 46

    The filter on the body_class function is amazing, well done.

    0
  47. 47

    Whoah! I’m sure this comment will get lost in how many there are, but WHOAH!

    Number 5 is a BAD idea, and should never have made it on to this list. It’s not useful at all, it’s a very very bad idea.

    Unless of course you don’t mind having your site hacked the next time a security update is released and you don’t know about it.

    0
  48. 48

    Number 5 can be useful to stop clients calling asking about updating wordpress :-)

    Also in some cases 90% of my plugins are slightly customised and only work with the current WordPress version. Allowing the client to click that button would break their theme – and of course this would be my fault……

    0
  49. 49

    Concerning “Insert Content Automatically After Each Post” where exactly do we paste that code in the functions.php file?

    0
  50. 50

    Hi man, i like this post.. but i have some problem with hook..

    The problem is, i wrote some tweetmeme code to be shown on the right side of my posting, that’s cool. but the problem is when i see my homepage the tweetmeme icon is shown too. and my question is how to make some plugin that written in hooks just used inly in posting and pages not in homepages.. i think just to use it in single and pages not in home..
    thank you before..

    0
  51. 51

    Is it possible to do this?

    If i insert a tag like [pretext] in my post while writing, it has to replace it with something like this “This is the preset text” in the post that has been published…

    0
    • 52

      Yeah, go to edit your functions.php file and add this line:

      function preset() {
      return ‘This is the preset text’;
      }

      This code adds a function called “pretext” that returns a line when its used. There can be html and php values too.

      And then, below that line add this:

      add_shortcode(‘pretext’, ‘preset’);

      This will add shortcode, the first property (pretext) is the value that will be in “[ ]” to return the value given in the first code line. And the second property (preset) calls a function named “preset”, the function exists and if you write [pretext] in your post, this shortcode will search a function called “preset”, if it exist (exists) the value given will be displayed.

      Now when published, will be displayed:
      This is the preset text

      You can use ADsense too ;)

      0
  52. 53

    Quite possibly the most useful list I’ve ever read, thanks for posting this.

    0
  53. 54
  54. 55

    Very good information. Duplicate content is a problem we must avoid, you can see the solution that I created to minimize its effects.

    blogshill.com/avoid-duplicate-content-on-wordpress/

    I hope this helps.

    0
  55. 56

    Old post, but still useful :)

    Thanks so much to the Cats ;) #kidding

    0
  56. 57

    Number 2 is very useful. But how to observe the amount of users who use each browser once I place the code in the php file? In other words, once I write the hook, how do I monitor the browsers that my users are using?

    0
  57. 58

    Thanks so much. Really helpful post.

    0

↑ Back to top