{"id":101,"date":"2018-04-27T08:45:27","date_gmt":"2018-04-27T05:45:27","guid":{"rendered":"http:\/\/wds.gr\/sites\/?p=101"},"modified":"2018-04-27T08:45:27","modified_gmt":"2018-04-27T05:45:27","slug":"wordpress-actions-filters-and-hooks-a-guide-for-non-developers","status":"publish","type":"post","link":"http:\/\/wds.gr\/sites\/blog\/wordpress-actions-filters-and-hooks-a-guide-for-non-developers\/","title":{"rendered":"WordPress Actions, Filters, and Hooks : A guide for non-developers"},"content":{"rendered":"<p>When I was learning how to use hooks in WordPress and the\u00a0<a href=\"https:\/\/presscustomizr.com\/customizr\" target=\"_blank\" rel=\"noopener\">Customizr theme<\/a>, I got tired of searching for articles that explained actions, filters and hooks, in simple terms. Most articles are complex, are written for developers, and start like this:<\/p>\n<blockquote><p>Actions and filters allow you add your own functionality or modify your site\u2019s behaviour by hooking a callback function onto a specific tag in the core code, setting priorities and using parameters and arguments passed to the callback function.<\/p><\/blockquote>\n<div>Whoa!<\/div>\n<div>Don\u2019t worry.\u00a0<em>This<\/em>\u00a0isn\u2019t\u00a0<em>that<\/em>\u00a0sort of article. If you don\u2019t understand anything in that paragraph, but wish you did, read on\u2026.<\/div>\n<h2>The basics<\/h2>\n<div>A WordPress page is made up of a whole load of functions and database queries, with WordPress and the theme working together to output text, images, stylesheets, and other files. The browser interprets all of these and puts them all together into one web page.<\/div>\n<div>Throughout its code, WordPress has included \u201chooks\u201d, so that people can \u201chang\u201d their own code on those hooks. A lot of the Customizr theme\u00a0\u00a0<a href=\"http:\/\/presscustomizr.com\/code-snippets\" target=\"_blank\" rel=\"noopener\">code snippets<\/a>\u00a0are written in PHP, using them.<\/div>\n<div>There are two types of hooks: actions and filters.<\/div>\n<ul>\n<li>Actions allow you to add extra functionality at a specific point in the processing of the page\u2014for example, you might want to add extra widgets or menus, or add a promotional message to your page.<\/li>\n<li>Filters allow you to intercept and modify data as it is processed\u2014for example, you might want to insert another CSS class in a WordPress HTML element, or modify some of your pages blocks.<\/li>\n<\/ul>\n<div><strong>In brief: actions do stuff; filters change stuff.<\/strong><\/div>\n<div><strong>\u00a0<\/strong><\/div>\n<h2>Getting down to details<\/h2>\n<blockquote><p>When Gill comes by, tell her to go to the store to get some paint. When Jack comes by bragging about how great he is, get him to say that Gill is better.<\/p><\/blockquote>\n<div>Wait, what? I thought this was an article about actions, filters and hooks? Instead, we\u2019re talking about arrogant home-improvers? Well yes. These are ways of understanding what\u2019s going on when you use actions and filters.<\/div>\n<div>Let\u2019s look at actions and filters in turn.<\/div>\n<h3>Actions:<\/h3>\n<blockquote><p>When Gill comes by, tell her to go to the store to get some paint.<\/p><\/blockquote>\n<div>We can do this by hooking onto an action hook. That is, we can use the add_action function (written add_action()) to add functionality\u2014do stuff\u2014at a particular point.<\/div>\n<div>Sending Gill to the store to get paint might look like this in PHP:<\/div>\n<pre style=\"padding-left: 30px;\">\/\/ Send Gill to get paint\r\nadd_action( 'after_gill_arrives' , 'send_gill_to_get_paint', 10 , 2 );\r\nfunction send_gill_to_get_paint( $gill_has_keys, $gill_has_car ) {\r\n  \/\/ If $gill_has_keys and $gill_has_car are both true\r\n  if ( $gill_has_keys &amp;&amp; $gill_has_car ) {\r\n    echo 'Gill, please go to the store and get some paint. Thank you!';\r\n  }\r\n}&lt;br&gt;\r\n<\/pre>\n<h4>What did we just do there?<\/h4>\n<ul>\n<li>We watched for a particular thing to happen\u2014Gill having arrived; in programming terms the \u2018after_gill_arrives\u2019 hook;<\/li>\n<li>When it happened, we did something\u2014we sent her to the store to get paint; in programming terms we added an action to call the send_gill_to_get_paint() function, which prints a message on the page;<\/li>\n<li>We used the $gill_has_keys and $gill_has_car arguments to perform some basic logic;<\/li>\n<li>We set other information:\n<ul>\n<li>The priority of this action: Whether it will run before, or after, other functions attached to the same hook. In this case we set the priority to 10, the default. If we want another function to run before this, we would give the other function a lower value (which means it will be executed first).<\/li>\n<li>How many arguments (variables) that the function accepts. These arguments are passed from the action hook to our function. In this case, we set this value to 2.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>How did it work?<\/h4>\n<div>In simple terms, add_action() tells WordPress to do something when it arrives at the specified do_action() hook.<\/div>\n<div>But we can only use our add_action() in the example above if we know that the \u2018after_gill_arrives\u2019 action hook exists in our theme\/plugin. Our theme\/plugin needs to have something like this in it:<\/div>\n<div>do_action( \u2018after_gill_arrives\u2019 , $gill_has_keys = true , $gill_has_car = true );<\/div>\n<div>This tells WordPress to create a hook called \u2018after_gill_arrives\u2019, run any actions that are attached to this hook, and pass the arguments $gill_has_keys and $gill_has_car to those actions (the 2 arguments we specified above).<\/div>\n<h4>A simple add_action() example<\/h4>\n<div>Now let\u2019s look at a simple example using the Customizr theme. Let\u2019s add some text after the header:<\/div>\n<pre style=\"padding-left: 30px;\">\/\/ Add some text after the header\r\nadd_action( '__after_header' , 'add_promotional_text' );\r\nfunction add_promotional_text() {\r\n  \/\/ If we're not on the home page, do nothing\r\n  if ( !is_front_page() )\r\n    return;\r\n  \/\/ Echo the html\r\n  echo \"&lt;div&gt;Special offer! June only: Free chocolate for everyone!&lt;\/div&gt;\";\r\n}&lt;br&gt;\r\n<\/pre>\n<div>Inside the Customizr core code, as the very last action in header.php, Customizr has:<\/div>\n<pre style=\"padding-left: 30px;\">do_action ( '__after_header' )\r\n<\/pre>\n<div style=\"padding-left: 30px;\">This is where our add_action() is hooking itself.<\/div>\n<div>You can also use remove_action() to remove actions from their hooks. For example,\u00a0\u00a0<a href=\"http:\/\/www.presscustomizr.com\/snippet\/moving-slider-anywhere\/\" target=\"_blank\" rel=\"noopener\">this snippet removes the slider<\/a>\u00a0from one place\u2014using remove_action() to unhook it from where it\u2019s currently hooked\u2014and adds it somewhere else.<\/div>\n<div>And how do we add the remove_action() to the page\u2019s code? Yes, that\u2019s right: with an add_action(). In the case of snippet for moving the slider, we hook our function in the &lt;head&gt; section at the very top of the page, to make sure it\u2019s executed after all the actions are loaded, but before the rest of the page is built. Take a look at that slider snippet to see if it makes more sense to you now.<\/div>\n<h3>Filters:<\/h3>\n<blockquote><p>When Jack comes by, bragging about how he\u2019s the best, tone down his boasting.<\/p><\/blockquote>\n<div>We can change Jack\u2019s boasting comments by hooking onto a filter. That is, we can use add_filter() to modify functionality\u2014change stuff\u2014at a particular point.<\/div>\n<div>Toning down his boasting might look like this in PHP:<\/div>\n<pre style=\"padding-left: 30px;\">\/\/ Cut Jack's boasting\r\nadd_filter( 'jacks_boast' , 'cut_the_boasting');\r\nfunction cut_the_boasting($boast) {\r\n  \/\/ Replace \"best\" with \"second-best\"\r\n  $boast = str_replace ( \"best\" , \"second-best\" , $boast );\r\n  \/\/ Append another phrase at the end of his boast\r\n  $boast = $boast . ' However, Gill can outshine me any day.';\r\n  return $boast;\r\n}&lt;br&gt;\r\n<\/pre>\n<h4>What did we just do there?<\/h4>\n<ul>\n<li>We looked for a particular thing that we wanted to change\u2014Jack\u2019s boast that he\u2019s the best; in programming terms the \u2018jacks_boast\u2019 filter;<\/li>\n<li>When we found it, we changed it\u2014we changed \u201cbest\u201d to \u201csecond-best\u201d and we added another phrase on the end; in programming terms, we filtered the output by calling the cut_the_boasting() function, which replaced part of the string and appended another string (the \u201c.\u201d character concatenates two PHP strings);<\/li>\n<li>We used the $boast argument (in this case a string that says something like \u201cI\u2019m the best!\u201d) as the basis for our changes.<\/li>\n<li>We returned a string at the end of the function. This is very important. If you don\u2019t return a string in a filter, you might disrupt the functioning of a program (in this case, we would simply silence Jack \u2026 which may not be a bad thing).<\/li>\n<\/ul>\n<h4>How did it work?<\/h4>\n<div>In simple terms, add_filter() tells WordPress to swap its data with ours when it arrives at the \u2018jacks_boast\u2019 filter hook. Neat!<\/div>\n<div>But we can only use our add_filter() filter in the example above if we know that the \u2018jacks_boast\u2019 filter hook exists in our theme\/plugin. (If the hook doesn\u2019t exist, our function will simply never be called.) Behind the scenes, the theme\/plugin has to have something like this in it:<\/div>\n<pre style=\"padding-left: 30px;\">echo apply_filters('jacks_boast', \"I'm the best in the world.\");\r\n<\/pre>\n<div style=\"padding-left: 30px;\">This tells WordPress to create a hook called \u2018jacks_boast\u2019, apply any filters that are attached to this hook, and pass those filters the string \u201cI\u2019m the best in the world.\u201d. If there are no filters attached to the hook, then the apply_filters() function will simply return the string \u201cI\u2019m the best in the world.\u201d: effectively a default.<\/div>\n<h4>A simple add_filter() example<\/h4>\n<div>Now let\u2019s look at an easy example in the Customizr theme. Let\u2019s change the url of the link in the logo:<\/div>\n<pre style=\"padding-left: 30px;\">\/\/ Change url that is linked from logo\r\nadd_filter( 'tc_logo_link_url', 'change_site_main_link' );\r\nfunction change_site_main_link() {\r\n  return 'http:\/\/example.com';\r\n}&lt;br&gt;\r\n<\/pre>\n<div>Inside the Customizr core code, in the function that displays the logo (in class-header-header_main.php), Customizr has:<\/div>\n<pre style=\"padding-left: 30px;\">apply_filters( \u2018tc_logo_link_url\u2019, esc_url( home_url( \u2018\/\u2019 ) ) )\r\n<\/pre>\n<div style=\"padding-left: 30px;\">This is where our add_filter() is hooking itself. The esc_url() function eliminates invalid characters etc. in urls and the home_url() function retrieves the home url for the site. So without any filtering, the \u2018tc_logo_link_url\u2019 filter returns the home page\u2019s address.<\/div>\n<div>In this example, we didn\u2019t even take any notice of the incoming arguments (the home url), because we knew we were just going to completely overwrite it.<\/div>\n<div>Remember: When you use a filter, you must always return something.<\/div>\n<h2>Why use hooks?<\/h2>\n<div>Now you know how they work, you can see that understanding hooks is absolutely necessary for anyone developing with WordPress. It\u2019s also very useful even if you are not a developer but want to modify WordPress\u2019s\u2014or your theme\u2019s\u2014 behaviour.<\/div>\n<div>With an understanding of hooks, you can:<\/div>\n<ul>\n<li><strong>Change almost anything in WordPress\u2014even quite fundamental things\u2014because a lot of WordPress\u2019s core functions use actions and filters;<\/strong><\/li>\n<li>Make changes easily: once you\u2019ve understood the concepts, you can make some incredibly complex changes very quickly;<\/li>\n<li>Change a theme&#8217;s behaviour at the source, rather than trying to retro-fit an inappropriate solution with HTML and CSS;<\/li>\n<li>Make your own changes easy to understand and easier to debug, because your code is reduced to a minimum;<\/li>\n<li>Enable and disable your changes easily because each piece of code is a small unit in your functions.php;<\/li>\n<li>Make your changes relatively upgrade-proof because you no longer need to edit or copy WordPress or any themes and plugins core files;<\/li>\n<li>Share your knowledge and swap code snippets with others.<\/li>\n<\/ul>\n<div>Fully understanding hooks can take a few hours or (much) longer, depending on your skills, but it will save you days of time in the future.<\/div>\n<h2>Try it yourself<\/h2>\n<div>All the above examples are working examples. If you have a test installation of WordPress to play with, you can try using the code above in the functions.php in your child theme. Some things to bear in mind:<\/div>\n<ul>\n<li>In the add_action() example that echoes text for Gill:\n<ul>\n<li>You will need to include the line do_action( \u2018after_gill_arrives\u2019 , $gill_has_keys = true , $gill_has_car = true ); in your code, because this action hook isn\u2019t in Customizr.<\/li>\n<li>If both $gill_has_keys and $gill_has_car are set to true, then your website will display \u201cGill, please go to the store and get some paint. Thank you!\u201d at the top of the page. If you change either one or both of these values to false, the message will not display.<\/li>\n<\/ul>\n<\/li>\n<li>In the add_action() example to add promotional text: Don\u2019t include the \u2018__after_header\u2019 hook in your code, because this already included in Customizr\u2019s core code.<\/li>\n<li>In the add_filter() example that changes Jack\u2019s words:\n<ul>\n<li>You will need to include line echo apply_filters(\u2018jacks_boast\u2019,\u201dI\u2019m the best in the world.\u201d); in your code, because this filter hook isn\u2019t in Customizr.<\/li>\n<li>Your website will display \u201cI\u2019m the second-best in the world. However, Gill can outshine me any day.\u201d at the top of the page.<\/li>\n<\/ul>\n<\/li>\n<li>In the add_filter() example to change the logo url: Don\u2019t include the \u2018tc_logo_link_url\u2019 filter hook in your code, because this already included in Customizr\u2019s core code.<\/li>\n<\/ul>\n<h3>Where to copy\/paste this code?<\/h3>\n<div><u>In your functions.php file. We strongly recommend you create a\u00a0<\/u>\u00a0<a href=\"https:\/\/codex.wordpress.org\/Child_Themes\" target=\"_blank\" rel=\"noopener\">child theme.<\/a><\/div>\n<div><u>Remember:<\/u>\u00a0you shouldn\u2019t edit the theme\u2019s functions.php, nor should you put a copy of it into your child theme.<\/div>\n<div><\/div>\n<div>\n<hr \/>\n<p>\u038c\u03bb\u03bf \u03c4\u03bf \u03ac\u03c1\u03b8\u03c1\u03bf, \u03b5\u03b4\u03ce:\u00a0<a href=\"https:\/\/docs.presscustomizr.com\/article\/26-wordpress-actions-filters-and-hooks-a-guide-for-non-developers\">https:\/\/docs.presscustomizr.com\/article\/26-wordpress-actions-filters-and-hooks-a-guide-for-non-developers<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>When I was learning how to use hooks in WordPress and the\u00a0Customizr theme, I got tired of searching for articles that explained actions, filters and hooks, in simple terms. Most articles are complex, are&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":102,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[22,30,12,31],"class_list":["post-101","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-article","tag-coding","tag-howto","tag-tip","tag-wordpress-core"],"_links":{"self":[{"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/posts\/101"}],"collection":[{"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/comments?post=101"}],"version-history":[{"count":1,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/posts\/101\/revisions"}],"predecessor-version":[{"id":103,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/posts\/101\/revisions\/103"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/media\/102"}],"wp:attachment":[{"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/media?parent=101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/categories?post=101"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/wds.gr\/sites\/wp-json\/wp\/v2\/tags?post=101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}