Actions and Filters make WordPress more powerful than one would expect from what was originally a simple blogging platform. While actions are relatively easy to explain and implement, filters are more involved, hence a bit of a steeper learning curve.
An action can be as simple as a block of code to execute at a given time in the WP lifecycle, a function that receives a variable number of arguments and outputs something for you.
Suppose you are tasked with adding Google Analytics code to every page, and have no need for a plugin – or don’t want the overhead from one. You can do something like this:
add_action( 'theme_output_analytics_code', function() { ?> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-XXXXXXX-X', 'auto'); ga('send', 'pageview'); </script> <?php });
Then, in what is usually in the header.php file:
<body <?php body_class(); ?>> <?php do_action( 'theme_output_analytics_code' ); ?>
All set. This is your own custom action, or hook, so you can use it however you want.
Filters, however, “hook” into existing code. add_filter() only becomes useful when combined with apply_filters(). It may not appear that way at first, as you may have used add_filter() without any thought as to where the corresponding apply_filters() is. This is because it’s already baked in to a plugin or theme.
Let’s say you want to let users show / hide the title of a page. In some instances, content editors will have already added an H1 / H2 in the content area that’s large enough to fight with your actual title, or you simply want to hide it for some templates. To keep this simple, this goes in your theme’s functions.php file:
Then, usually with a custom field that the user can select Yes / No for, we output the filter in a page / post template:
$customFieldReturnValue = FALSE;
<header class="entry-header"> <?= apply_filters( 'filter_the_title', get_the_title(), $customFieldReturnValue ); ?> </header><!-- .entry-header -->
We pass the title using the customary template tag as the second argument, then a third argument that determines whether to display the title or not.