How to add wordpress like add_filter hooks in your PHP framework

I simply love wordpress mainly because of the architectural design it follows to deliver the good. WordPress provide a hook or filter functionality to almost everything that appears on your blog. If you are a wordpress plugin developer you surely must have used one of them, specially add_filter() hook.

add_filter functionality provides plugin developer a way to apply custom hooks on various page sections. For instance add_filter('the_content', 'HelloWorld') will force the content to be passed through the function HelloWorld($content) before being displayed to your blog users.

In this blog post I will show you how can you achieve doing the same thing for your custom PHP frameworks. Otherwise you can also use this in your day to day projects. We will start with a simple directory structure, assuming this is all we have in our framework to start with:

Files/Folder structure of our framework
– addHooks
    – index.php
    – applyHooks.php
    – hooks
          – Subscribe.php
          – Signature.php

addHooks: Our framework root directory.
index.php: Homepage for our framework.
applyHooks.php: Responsible for including and implementing various hooks.
hooks: Our hooks directory. We will put all our hooks here.
Subscribe.php: A simple hook which will add a subscribe my feed link.
Signature.php: Another simple hook which adds my signature.

Source code
Download the complete source code from here.

index.php

  // define some content
  // in this demo i will show to how to apply hook to $content, similar to wordpress blog $content
  $content = "In this blog post I will show you how to add wordpress like add_filter hooks in your PHP framework.";

  // Include our hook management file
  require_once("applyHooks.php");
  

Subscribe.php

  function Subscribe($content) {
    $subscribe = '';
    $subscribe .= 'Subscribe to my RSS feed';
    $subscribe .= '

'; return $subscribe.$content; } add_filter('the_content', 'Subscribe');

Signature.php

  function Signature($content) {
    $signature = '

'; $signature .= 'Abhinav Singh
'; $signature .= 'Follow on twitter @imoracle
'; return $content.$signature; } add_filter('the_content', 'Signature');

applyHooks.php

  /* plugin directory */
  $hook_dir = "hooks/";

  /* get all plugin files */
  $hook_files = glob($hook_dir."*.php");

  /* array saving all our hooks on the_content */
  $hooks['the_content'] = array();

  /* add_filter functionality */
  function add_filter($on, $func) {
    global $hooks;
    array_push($hooks[$on], $func);
  }

  /* include plugin files */
  foreach($hook_files as $hook_file) {
    require_once($hook_file);
  }

  /* implement the hooks */
  foreach($hooks['the_content'] as $hook) {
    $content = call_user_func($hook, $content);
  }

  echo $content;
  

Final Result
When you try to visit your framework opening page on your browser, i.e. index.php. You will see your $content being filtered/modified and displayed as:
add_filter_output

How does applyHooks.php works
So what allows us adding such hooks in our framework. call_user_func is a PHP function which allows you to call a user defined function. Here is in short how applyHooks.php work:

  1. applyHooks.php adds a method called add_filter($on, $func) before including the hook files
  2. add_filter() essentially takes input as $on = the element on which you want to apply the hook and $func = the hook you want to apply $on element.
  3. If you see our Signature.php code, you will find add_filter('the_content', 'Signature');. Which essentially means, apply the filter called $func=’Signature’, $on=’the_content’
  4. The applyHooks.php file keep registering these hooks and save them in $hooks array
  5. Finally it implement all hook one by one by calling the call_user_func function (PS: You may also want to use call_user_func_array)

Extending applyHooks.php
In this blog post I have shown a demo, how you can create a add_filter type functionality. You may want to extend this to include hooks like:

  • remove_filter
  • add_shortcode

and others.

Hope this will help you making your web apps more expendable and manageable. :D

  • P. Arbogast

    This is a nice tutorial. I am not a plugin developer but still wondered how does wordpress apply plugins :)
    You solved the mystery

  • Pingback: How to add wordpress like add_filter hooks in your PHP framework …

  • Pingback: How to add wordpress like add_filter hooks in your PHP framework … – Wordpress Plugins

  • http://blog.xfile.us nick

    wow nice blog!Please visit back my blogthank you :)

  • Pingback: Building a Custom PHP Framework with a custom template caching engine using Output Control functions | Abhi's Weblog

  • http://julianvidal.com Julian Vidal

    One thing to note though for people new to hooks is that you can load up all the hooks but might want to delay execution until you really need it.

    Excellent tutorial!

  • http://aaronsaray.com Aaron Saray

    Good post.
    I like the way that systems like Elgg and WordPress implement the observer pattern.  I rambled on some about the observer pattern in my blog (link below) before I wrote the PHP Design Patterns book.  In my own system on a recent project, I have been using static methods of a class – so the include method you wrote would cause me problems.  I used spl autoload instead.  I would encourage you to expand on this entry and make it more versatile.  In my opinion, the observer pattern is one of the most amazing patterns available in PHP.
     
    My blog on the observer pattern:
    http://aaronsaray.com/blog/2008/11/22/the-observer-pattern-in-php-refactored/

  • http://abhinavsingh.com Abhinav Singh

    Yeah I have read your blog on observer pattern before. A nice one :D But check this post of mine, on how can you make the controller more stronger and make the classic MVC architecture do all the work for you including from add filters to everything wordpress provides.

    Link on “Building a Custom PHP Framework with a custom template caching engine using Output Control functions” – http://tinyurl.com/ogy8yh

    Use output control function intelligently and one can do everything within controller itself.

  • Dave

    Hi.. visitor from StumbleUpon. You asked for a thumbs-up. For that alone, you get a thumbs-down. You also have a very irritating little “social” bar at the bottom, that had a chat window open by default. For that, you get a block. Enjoy your one hit plus postback from me.

    • http://abhinavsingh.com Abhinav Singh

      Hi Dave,

      Thanks for your visit and a negative feedback after long time is always welcomed.

      1st thing i don’t remember asking for a thumb up. Infact i m little active on stumble upon. I am not sure what made you think so.

      Social bar, yeah that’s memchat installation. I enabled auto opening on window since this is still in test phase and i needed users to use it so that i can complete my testing etc.

      Thanks again, do let me know when you postback :D

  • Tom B

    Abhi,

    You go to all this trouble to share this knowledge, and then some nose-picker wants to criticise you for it. Maybe it was the stress of xmas….
    Keep up the good work!

  • Raygun

    Thanks for this. You saved my day on searching like this. Bookmarking!

  • Zed

    How could this be expanded to allow setTemplate() to pull from a DB?

  • http://buzzknow.com buzzknow

    sometimes i wonder how wordpress apply their hook system, but now you can reveal it with simple way :)

    regards

  • http://smartbuzz.net Ajay kumar

    awesome post. Thank you for valuable information. Thank you very much indeed

  • http://www.failover.co.za Jethro

    Thanks for this article!
    I had known how to write WordPress-style action hooks – but filters evaded me. I used your concept and turned it into simple functional code, almost matching my method for action hooks and compiled a 3-part tutorial (part 3 yet to be posted.)
    So, for anyone looking for action hooks, see part 1

  • Shantanu

    Thanks for this article! You saved my day on searching like this.1st thing i don’t remember asking for a thumb up. Infact i m little active on stumble upon. I am not sure what made you think so.

  • http://takien.com takien

    aargh…great..
    I found your article finally after I created similar topic in my blog, however your article is more complete and detail. Simply agree with you, filter functionality is the one make me loving WordPress.

  • coudynews

    function add_action($action, $function) {

    global $actions;

    $actions[$action] = $function;

    }

    function do_action($action) {

    global $actions;

    foreach($actions as $key => $act) {

    if ($key == $action) {

    $act();

    }

    }

    }