Using Action & Filter Hooks

Hooks overview

WordPress hooks come in two flavors, action hooks and filter hooks: actions allow you to call certain functions in the execution of the theme and filters modify (or completely overwrite) certain code passed to a function or sent to the browser screen.

Themify implements a series of specific and additional actions and filters to make easy for you to plug in your own code into the theme, whether it is to add new HTML code or filter a certain text.

For example, with action hooks you could add a chunk of HTML code to the header in all pages without having to touch the header.php template, for example, to show an image. A more complex example would be to show an image in the header of the category pages, having a different image for each category.

On the other hand, with filter hooks we could change the format of the date shown in our posts.

UPDATE: we now have Hook Content which allows you to add hooks via Themify Panel without writing custom PHP functions.

Adding Hooks

To add filter or action hooks:

  1. Create a custom-functions.php file in the theme folder
  2. Now you may apply the action or filter to the hooks (read the sample usages below for examples)

Sample Hook Usages

The code samples below show what you can do with hooks.

Simple Usage

A common action hook usage is to add custom content to the page rendered in the browser. This sample code will add a text div tag to the header using the themify_header_end hook:

<?php
function theme_header_end() {
echo '<div class="custom-text">Custom Text</div>';
};
add_action('themify_header_end', 'theme_header_end');
?>

To add the content somewhere else, simply specify which action hook name you want to use as the insertion point. For example you can insert the content at the end of the post.

<?php
function theme_post_end() {
echo '<div class="custom-text">Custom Text at the end of the post</div>';
};
add_action('themify_post_end', 'theme_post_end');
?>

Conditional Tags

Inside the function called by the action hook, you can use WordPress conditional tags to display different content on different pages.


<?php
function my_text_before_content() {
if(is_home()) {
echo 'Text for home page.';
} elseif(is_page()){
if (is_page(7)) {
echo 'Text for page with ID 7.';
} else {
echo 'Text for regular page.';
}
} elseif(is_single()){
echo 'Text for single post.';
} elseif (is_category()) {
echo 'Text for category archive page.';
}
};
add_action('themify_content_before', 'my_text_before_content');
?>

Header Banner

Let's take the above samples to a practical use. For example, you can use it to display a header banner image without having to edit the header.php template.


<?php function add_banner_header_end(){
echo '<div class="header-banner"><img alt="header banner" src="http://example.com/url/to/image.jpg" /></div>';
}
add_action('themify_header_end', 'add_banner_header_end');
?>

Conditional Header Banner

To display different header banner on different pages:


<?php
function add_banner_header_end(){
if(is_home())
echo '<div class="header-banner"?><img alt="header banner" src="http://example.com/url/to/image-home.jpg" /?></div?>';
elseif(is_page(7))
echo '<div class="header-banner"?><img alt="header banner" src="http://example.com/url/to/image-page-id-7.jpg" /?></div?>';
elseif(is_page())
echo '<div class="header-banner"?><img alt="header banner" src="http://example.com/url/to/image-page.jpg" /?></div?>';
elseif(is_single())
echo '<div class="header-banner"?><img alt="header banner" src="http://example.com/url/to/image-single.jpg" /?></div?>';
elseif(is_category())
echo '<div class="header-banner"?><img alt="header banner" src="http://example.com/url/to/image-category.jpg" /?></div?>';
}
add_action('themify_header_end', 'add_banner_header_end');
?>

Add Welcome Message

To add a welcome message on the homepage:


<?php
function add_welcome_message(){
if(is_home()) {
echo '<div class="welcome-text">Welcome message</div>';
}
};
add_action('themify_content_before', 'add_welcome_message');
?>

Then you need to add this to Themify > Styling > Custom CSS to style the .welcome-message class:


.welcome-message {
padding: 15px;
font-size: 120%;
text-align: center;
}

Run Shortcodes

You can also run shortcodes in the hooks. The example below will add the [[post_slider]] shortcode right after the header area on the homepage only.


<?php
function show_post_slider_layout_before() {
echo do_shortcode('[post_slider limit="8" visible="4"]');
};
add_action('themify_layout_before', 'show_post_slider_layout_before');
?>

Add Header Widget

To add a custom widgetized area, first you need to register it as a sidebar:


<?php
function theme_register_sidebar(){
register_sidebar(array(
'name' => 'Custom Header Widget',
'id' => 'custom-header-widget',
'before_widget' => '
<div class="widget %2$s" id="%1$s">',
'after_widget' => '</div>',
'before_title' => '<strong class="widgettitle">',
'after_title' => '</strong>',
));
}
add_action( 'widgets_init', 'theme_register_sidebar' );
?>

Now add this code to display the header widget:


<?php
function new_header_widget(){
echo '<div class="header-widget">';
if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('custom-header-widget') ) ;
echo '</div>';
}
add_action('themify_header_end', 'new_header_widget');
?>

Run PHP Function

Some plugins requires you to add a PHP function call to the template files. Breadcrumb NavXT is one of them. You may use hooks to add PHP function without having to edit the template. The sample below will add the breadcrumb function in the post_start hook of the single post page.


<?php
function breadcrumbs_on_post_start(){
if(function_exists('bcn_display')){
echo '<div class="breadcrumbs">';
bcn_display();
echo '</div>';
}
}
add_action('themify_post_start', 'breadcrumbs_on_post_start');
?>

Additionally, if you would like to trigger this only on single views, you would use


<?php
function breadcrumbs_on_post_start(){
if( function_exists('bcn_display') && is_single()){
echo '<div class="breadcrumbs">';
bcn_display();
echo '</div>';
}
}
add_action('themify_post_start', 'breadcrumbs_on_post_start');
?>

Note the additional call to the is_single() function.

Usage of filter hooks

As an example, we will change the format of the date shown in the post.


<?php
function custom_date_format($date){
return 'Y/d/m';
}
add_filter('themify_loop_date', 'custom_date_format');
?>

You'll notice a few differences here compared to action hooks. For example, filters always receive at least one variable, and you can modify the content of this variable, of as in the example above, dismiss it by returning something else. Let's see an example where the variable is also returned, along with extra parameter, reversing the order of the posts shown in a Query Category page:


<?php function custom_post_order($query){
return $query . '&order=ASC';
}
add_filter('themify_query_posts_page_args', 'custom_post_order');
?>

Query Posts Page by Tags

To create a Query Posts page that queries posts by their tags instead of their categories, follow these steps:

1. edit or create the page to use as Query Posts
2. enable Query Posts selecting a category for the Query Category. This is necessary otherwise the page is a regular content page. While you're still in the edit screen, check the browser address bar, look for something like post.php?post=555 and take note of the number, for example, 555.
3. go to Posts > Tags and take note of the slug of the tag you'll be using, for example sometag.
4. use the following code in a custom-functions.php file


<?php
/**
 * Check if it's a certain page and if so, query by tag instead of by category.
 *
 * @param string $query Parameters for the query.
 * @return string
 */
function custom_themify_query_posts_page_args( $query ) {
	// Check that we're in the page whose ID is, for example, 555, the number we took note before.
	if ( is_page( 555 ) ) {
		// Remove the categories to query.
		$query = str_replace( '/cat=(.*?)&/', '', $query );
		// Add the tag slug that you took note before.
		$query = 'tag=sometag&' . $query;
	}
	// Return the query to be performed.
	return $query;
}
add_filter('themify_query_posts_page_args', 'custom_themify_query_posts_page_args');
?>

Common Problem: Blank Screen

You can write several blocks of PHP code in the custom-functions.php file like:


<?php
// function 1
?>

<?php
// function 2
?>

But you must be very careful to avoid leaving blank spaces, like a carriage return or a "space bar" white space before the first <?php in the file or after the last ?> in the file.

Hooks in Themify themes

Here's a list of the hooks found in all themes:


<body>

<?php themify_body_start(); ?>

<div id="pagewrap">

	<div id="headerwrap">

		<?php themify_header_before(); ?>

		<header id="header">

			<?php themify_header_start(); ?>

			<?php themify_header_end(); ?>

		</header>

		<?php themify_header_after(); ?>
	</div>

	<div id="body">

		<?php themify_layout_before(); ?>

		<div id="layout">

			<?php themify_content_before(); ?>

			<div id="content">

				<?php themify_content_start(); ?>

				<?php themify_post_before(); ?>

				<article class="post">

					<?php themify_post_start(); ?>

					<?php themify_post_end(); ?>

				</article>

				<?php themify_post_after(); ?>

				<?php themify_comment_before(); ?>

				<div class="commentwrap">

					<?php themify_comment_start(); ?>

					<?php themify_commentform_before(); ?>

					<div id="commentform">

						<?php themify_commentform_start(); ?>

						<?php themify_commentform_end(); ?>

					</div>

					<?php themify_commentform_after(); ?>

					<?php themify_comment_end(); ?>

				</div>

				<?php themify_comment_after(); ?>

				<?php themify_content_end(); ?>

			</div>

			<?php themify_content_after(); ?>

			<?php themify_sidebar_before(); ?>

			<div id="sidebar">

				<?php themify_sidebar_start(); ?>

				<?php themify_sidebar_end(); ?>
			</div>

			<?php themify_sidebar_after(); ?>
		</div>

		<?php themify_layout_after(); ?>

	</div>

	<div id="footerwrap">

		<?php themify_footer_before(); ?>

		<footer id="footer">

			<?php themify_footer_start(); ?>

			<?php themify_footer_end(); ?>

		</footer>

		<?php themify_footer_after(); ?>

	</div>

</div>

<?php themify_body_end(); ?>

</body>

Hooks in e-commerce themes

The e-commerce themes feature an additional set of hooks:
Before and after the breadcrumbs


<?php themify_breadcrumb_before(); ?>
<div class="breadcrumb breadcrumbs shopdock-breadcrumbs"></div>
<?php themify_breadcrumb_after(); ?>

For products


<div class="product product-<?php the_ID(); ?>"></div>
<div class="product-imagewrap"><figure class="product-image"><?php themify_product_image_start(); ?>
<a>
<img alt="" />
</a>
<?php themify_product_image_end(); ?></figure></div>
<h3 class="product-title"><?php themify_product_title_start(); ?></h3>
<?php themify_product_title_end(); ?>

For products in carousel


<ul class="product-slides">
	<li>
<div class="product product-##">
<div class="product-imagewrap"><figure class="product-image"><?php themify_product_image_start(); ?>
<img alt="" />
<?php themify_product_image_end(); ?></figure></div>
</div></li>
</ul>
<h3 class="product-title"><?php themify_product_title_start(); ?>
<a>
<?php the_title(); ?>
</a>
<?php themify_product_title_end(); ?></h3>