{"id":1948280,"date":"2020-10-22T07:22:12","date_gmt":"2020-10-22T11:22:12","guid":{"rendered":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/?post_type=tribe-knowledgebase&#038;p=1948280"},"modified":"2022-01-21T08:59:03","modified_gmt":"2022-01-21T13:59:03","slug":"using-the-template-management-filters","status":"publish","type":"post","link":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/using-the-template-management-filters\/","title":{"rendered":"Using Template Management Filters"},"content":{"rendered":"\n<p>There are lots of ways to customize The Events Calendar, from <a href=\"https:\/\/dev.theeventscalendar.com\/knowledgebase\/k\/customizing-css\/\" target=\"_blank\" rel=\"noreferrer noopener\">minor CSS changes<\/a> to completely <a href=\"https:\/\/dev.theeventscalendar.com\/knowledgebase\/k\/customizing-template-files-2\/\" target=\"_blank\" rel=\"noreferrer noopener\">overriding any of the template files<\/a> with your own markup. We&#8217;re going to look at template filters- an advanced customization technique that completely bypasses the calendar&#8217;s template files, allowing you to display calendar content in any of your existing theme templates, or build your own from scratch using event data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-meet-the-template-hierarchy-aka-template-hijack-filter\">Meet the Template Hierarchy (aka &#8220;Template Hijack&#8221;) filter<\/h2>\n\n\n\n<p>We introduced a brand new filter in The Events Calendar 5.3:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ntribe_events_views_v2_use_wp_template_hierarchy\n<\/pre><\/div>\n\n\n<p>With this template filter, we can tell The Events Calendar to use the <a href=\"https:\/\/developer.wordpress.org\/themes\/basics\/template-hierarchy\/\" target=\"_blank\" rel=\"noreferrer noopener\">WordPress template hierarchy<\/a> for events instead of its own templates.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2020\/10\/archive-1024x710.png\" alt=\"\" class=\"wp-image-1948342\"\/><figcaption>In this example, events are displayed with the theme&#8217;s archive template instead of the calendar template that comes with the plugin. The calendar template is a custom archive template, but using this new filter ignores that template in favor of the <a href=\"https:\/\/developer.wordpress.org\/themes\/basics\/template-hierarchy\/\">WordPress template hierarchy<\/a>, forcing the calendar to behave like any other post archive.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-basic-template-filte-usage\">Basic template filte usage<\/h2>\n\n\n\n<p>Here&#8217;s an example of the template filter at its most basic in a theme&#8217;s <code>functions.php<\/code> file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nadd_filter(\n  &#039;tribe_events_views_v2_use_wp_template_hierarchy&#039;,\n  function( $hijack, $template, $context, $query ) {\n    if ( ! is_singular() ) {\n      $hijack = true;\n    }\n\n    return $hijack;\n  },\n  10,\n  4\n);\n<\/pre><\/div>\n\n\n<p>There are four arguments in there, with <code>$hijack<\/code> being the only required one. It&#8217;s a boolean that transitions the calendar from plugin templates to theme templates when set to <code>true<\/code>.<\/p>\n\n\n\n<p>In this basic example, we&#8217;ve wrapped the <code>$hijack<\/code> argument inside a condition that checks if the current view is <strong>not<\/strong> a single event post. In other words, are we looking at an event or at the calendar? If it&#8217;s not an event, then let the WordPress template hierarchy hijack the calendar and leave the individual event posts alone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-template-filter-arguments\">Template filter arguments<\/h2>\n\n\n\n<p>We just covered the <code>$hijack<\/code> argument, but there are three additional ones that are optional:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><code>$template<\/code>:<\/strong> The template located by WordPress (e.g. \u201cevent-single.php\u201d)<\/li><li><strong><code>$context<\/code>:<\/strong> The immutable, global object instance that serves as the Tribe template context.<\/li><li><strong><code>$query<\/code>:<\/strong> The global <code>$wp_query<\/code><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-custom-templates\">Custom templates<\/h2>\n\n\n\n<p>The benefit of the Template Hierarchy filter is two-fold:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>It allows us to use your existing theme templates for calendar content.<\/li><li>It allows us to leverage the WordPress template hierarchy to build your own archive and single templates for the calendar and events.<\/li><\/ol>\n\n\n\n<p>If we want to create a custom template in our theme for this calendar, which again is an archive of event posts, we can add a file to the theme&#8217;s root folder named <code>archive-tribe_events.php<\/code> just as you would do when <a href=\"https:\/\/developer.wordpress.org\/themes\/template-files-section\/custom-post-type-template-files\/#custom-post-type-templates\">creating an archive template for a custom post type<\/a>. So, let&#8217;s do that!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-examples\">Examples<\/h2>\n\n\n\n<p class=\"has-text-color has-background\" style=\"background-color:var(--global-palette8);color:#141827\">\ud83d\udc4b For these examples, we&#8217;re using the <a rel=\"noreferrer noopener\" href=\"https:\/\/wordpress.org\/themes\/twentytwenty\/\" target=\"_blank\">Twenty Twenty<\/a> theme, so the images may not quite reflect what you see if you are using a different theme. <a href=\"\/knowledgebase\/wp-content\/uploads\/2020\/10\/template-manager-filters.zip\">Download the example files<\/a> if you would like to follow along.<\/p>\n\n\n\n<p>First, we copy the existing archive template. If you&#8217;ve worked with Twenty Twenty before, then you know it doesn&#8217;t have an <code>archive.php<\/code> file. Instead, it relies on the <code>index.php<\/code> file. That&#8217;s what we want to copy instead. But since we don&#8217;t want our copy of the template to affect the theme&#8217;s homepage or other views, let&#8217;s rename it <code>archive-tribe_events.php<\/code>.<\/p>\n\n\n\n<p>Go ahead and remove the search section, as well as the hardcoded <code>$archive_title<\/code> and <code>$archive_subtitle<\/code> strings so it&#8217;s more obvious that we&#8217;re using the template specifically for the <code>tribe_events<\/code> custom post type. Now the archive looks a little more tailored to events.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2020\/10\/archive-2-1024x674.png\" alt=\"\" class=\"wp-image-1948343\"\/><figcaption>All we changed is what displays at the top of the archive.<\/figcaption><\/figure>\n\n\n\n<p>Awesome, let&#8217;s do the same thing, but this time with events! Again, if the calendar is a custom post type archive, then an event is a post single. That means our function will look almost identical to the last one in <code>functions.php<\/code>, but instead of checking that we&#8217;re <strong>not<\/strong> on a post single, we&#8217;ll check that we <strong>are<\/strong> on a post single:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [4]; title: ; notranslate\" title=\"\">\nadd_filter(\n  &#039;tribe_events_views_v2_use_wp_template_hierarchy&#039;,\n  function( $hijack, $template, $context, $query ) {\n    if ( is_singular() ) {\n      $hijack = true;\n    }\n\n    return $hijack;\n  },\n  10,\n  4\n);\n<\/pre><\/div>\n\n\n<p>See the small difference? We&#8217;re now testing for <code>is_singular()<\/code> to be <code>true<\/code> instead of <code>! is_singular<\/code>. If we wanted to hijack the archive and single at the same time, we can combine them in the same function like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\nadd_filter( &#039;tribe_events_views_v2_use_wp_template_hierarchy&#039;, &#039;__return_true&#039; );\n<\/pre><\/div>\n\n\n<p>OK, back to our example. Let&#8217;s check out our single event:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2020\/10\/single-958x1024.png\" alt=\"\" class=\"wp-image-1948344\"\/><\/figure>\n\n\n\n<p>That looks fine. No, really! But do you notice something? All we&#8217;re showing is the post content and featured image. Where&#8217;s the rest of the event&#8217;s content, like the date and time, the venue, and the organizer?<\/p>\n\n\n\n<p>The Events Calendar passes a lot of data into the event single that isn&#8217;t built into a standard template. Chances are you&#8217;re going to want those things in your template, so let&#8217;s create a new template in the theme folder that specifically displays event data.<\/p>\n\n\n\n<p>Twenty Twenty uses <code>singular.php<\/code> for single posts. Let&#8217;s copy that and rename it using the WordPress template hierarchy format for a custom post type single, <code>single-tribe_events.php<\/code>.<\/p>\n\n\n\n<p>We&#8217;re going to add one line of code at the very beginning of the file, right before the line with <code>get_header();<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [1,2]; title: ; notranslate\" title=\"\">\n\/\/ Get the event w\/data:\n$event = tribe_get_event( get_the_ID() );\n\nget_header();\n<\/pre><\/div>\n\n\n<p>That little line provides all the event data we need. Let&#8217;s use it to display the event title:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [3,4,5,6,7,8,9,10,11,12,13]; title: ; notranslate\" title=\"\">\n&lt;main id=&quot;site-content&quot; role=&quot;main&quot; class=&quot;single-event&quot;&gt;\n\n  &lt;h2 style=&quot;text-align:center&quot;&gt;\n\n    &lt;?php\n      echo sprintf(\n        \/* Translators: event title test string *\/\n        esc_html__( &#039;%1$s&#039;, &#039;my-textdomain&#039; ),\n        $event-&gt;title\n      );\n    ?&gt;\n\n  &lt;\/h2&gt;\n\n  &lt;?php\n<\/pre><\/div>\n\n\n<p>All we&#8217;re doing here is displaying the event&#8217;s title by calling the <code>$event<\/code> object, and asking for the <code>title<\/code>. We&#8217;re just testing things here, but it&#8217;s always a good idea to make strings compatible with translations, so we&#8217;ve included that in the example. Another thing to note is that we usually wouldn&#8217;t use inline CSS like this, but we are adding the CSS <code>text-align<\/code> property for the sake of presentation. Let&#8217;s take a look:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2020\/10\/single-altered-910x1024.png\" alt=\"\" class=\"wp-image-1948354\"\/><\/figure>\n\n\n\n<p>Well, we&#8217;re not going to win any design awards with this, but it&#8217;s a start! From here you should be able to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Use the template filter to force events to use your theme&#8217;s templates<\/li><li>Hijack single events, event archives, or both<\/li><li>Create a specific template for the event archive and event singles<\/li><li>Access event data in the event single template.<\/li><\/ul>\n\n\n\n<p>Happy coding!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are lots of ways to customize The Events Calendar, from minor CSS changes to completely overriding any of the template files with your own markup. We&#8217;re going to look at template filters- an advanced customization technique that completely bypasses the calendar&#8217;s template files, allowing you to display calendar content in any of your existing&#8230;<\/p>\n","protected":false},"author":3,"featured_media":1955565,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_swpsp_post_exclude":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"ep_exclude_from_search":false,"footnotes":""},"categories":[84],"tags":[25,58],"stellar-product-taxonomy":[161],"class_list":["post-1948280","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-theming-overview","tag-customizations","tag-php","stellar-product-taxonomy-the-events-calendar"],"acf":[],"taxonomy_info":{"category":[{"value":84,"label":"Templating &amp; Layout"}],"post_tag":[{"value":25,"label":"Customizations"},{"value":58,"label":"PHP"}],"stellar-product-taxonomy":[{"value":161,"label":"The Events Calendar"}]},"featured_image_src_large":["https:\/\/images.theeventscalendar.com\/kb\/uploads\/2023\/02\/social-share-1024x538.png",1024,538,true],"author_info":{"display_name":"Jaime Marchwinski","author_link":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/author\/jaimetri-be\/"},"comment_info":0,"category_info":[{"term_id":84,"name":"Templating &amp; Layout","slug":"theming-overview","term_group":0,"term_taxonomy_id":84,"taxonomy":"category","description":"","parent":24,"count":59,"filter":"raw","term_order":"0","cat_ID":84,"category_count":59,"category_description":"","cat_name":"Templating &amp; Layout","category_nicename":"theming-overview","category_parent":24}],"tag_info":[{"term_id":25,"name":"Customizations","slug":"customizations","term_group":0,"term_taxonomy_id":25,"taxonomy":"post_tag","description":"","parent":0,"count":177,"filter":"raw","term_order":"0"},{"term_id":58,"name":"PHP","slug":"php","term_group":0,"term_taxonomy_id":58,"taxonomy":"post_tag","description":"","parent":20,"count":128,"filter":"raw","term_order":"0"}],"_links":{"self":[{"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1948280","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/comments?post=1948280"}],"version-history":[{"count":1,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1948280\/revisions"}],"predecessor-version":[{"id":1955984,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1948280\/revisions\/1955984"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media\/1955565"}],"wp:attachment":[{"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media?parent=1948280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/categories?post=1948280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/tags?post=1948280"},{"taxonomy":"stellar-product-taxonomy","embeddable":true,"href":"https:\/\/dev.theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/stellar-product-taxonomy?post=1948280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}