{"id":1959175,"date":"2024-01-19T12:32:24","date_gmt":"2024-01-19T17:32:24","guid":{"rendered":"https:\/\/theeventscalendar.com\/knowledgebase\/?p=1959175"},"modified":"2026-04-17T18:16:15","modified_gmt":"2026-04-17T22:16:15","slug":"customizing-filter-bar","status":"publish","type":"post","link":"https:\/\/theeventscalendar.com\/knowledgebase\/customizing-filter-bar\/","title":{"rendered":"Customizing the Event Filter Bar"},"content":{"rendered":"\n<p>The Filter Bar add-on includes admin settings for layout, default state, and which filters appear \u2014 but some customizations require a small snippet. This article collects three common recipes: adjusting how many venues and organizers are loaded into the filter dropdowns, forcing the Filter Bar to appear open on mobile, and forcing vertical filters to stay expanded on desktop.<\/p>\n\n\n\n<p>Before adding any of the snippets below, please review our <a href=\"https:\/\/theeventscalendar.com\/knowledgebase\/best-practices-for-implementing-custom-code-snippets\/\">Best Practices for Implementing Custom Code Snippets<\/a> guide. We recommend using a plugin like <a href=\"https:\/\/wordpress.org\/plugins\/code-snippets\/\">Code Snippets<\/a> rather than editing <code>functions.php<\/code> directly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-adjusting-venue-and-organizer-limits\">Adjusting Venue and Organizer Limits<\/h2>\n\n\n\n<p>By default, the Venue and Organizer filters in the Filter Bar dropdown are capped at 200 entries each. This cap exists to protect front-end performance \u2014 loading hundreds of venues or organizers into a filter dropdown on every calendar page view can slow things down significantly. If your site has more than 200 of either, you can raise the limit with a WordPress filter.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-filter-total-venues-in-filter-bar\">Filter: Total Venues in Filter Bar<\/h4>\n\n\n\n<p>This filter controls how many venues are loaded into the Filter Bar dropdown.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * Filter Total Venues in Filter Bar\n *\n * Use this with caution \u2014 this will load venues on the front-end and\n * may cause slow performance if there are many venues.\n *\n * The base limit is 200 for safety reasons.\n *\n * @param int   $limit       The number of venues to load (default: 200)\n * @param array $venue_ids   IDs of venues attached to events\n *\/\n$limit = apply_filters( 'tribe_eventsfilter_bar_venues_limit', 200, $venue_ids );<\/code><\/pre>\n\n\n\n<p><strong>Example: Increase the venue limit to 500<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'tribe_eventsfilter_bar_venues_limit', function( $limit ) {\n    return 500; \/\/ Increase the limit from 200 to 500\n});<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-filter-total-organizers-in-filter-bar\">Filter: Total Organizers in Filter Bar<\/h4>\n\n\n\n<p>This filter controls how many organizers are loaded into the Filter Bar dropdown.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/**\n * Filter Total Organizers in Filter Bar\n *\n * Use this with caution \u2014 this will load organizers on the front-end and\n * may cause slow performance if there are many organizers.\n *\n * The base limit is 200 for safety reasons.\n *\n * @param int   $limit          The number of organizers to load (default: 200)\n * @param array $organizer_ids  IDs of organizers attached to events\n *\/\n$limit = apply_filters( 'tribe_events_filter_bar_organizers_limit', 200, $organizer_ids );<\/code><\/pre>\n\n\n\n<p><strong>Example: Increase the organizer limit to 300<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_filter( 'tribe_events_filter_bar_organizers_limit', function( $limit ) {\n    return 300; \/\/ Increase the limit from 200 to 300\n});<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-performance-note\">Performance Note<\/h4>\n\n\n\n<p>Raising these limits significantly may impact performance, especially on sites with hundreds or thousands of venues and organizers. If you notice slow loading times on your calendar pages after raising a limit, consider lowering it again or optimizing your database.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-summary\">Summary<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Filter Name<\/th><th>Default Limit<\/th><th>Purpose<\/th><th>Caution<\/th><\/tr><\/thead><tbody><tr><td><code>tribe_events_filter_bar_venues_limit<\/code><\/td><td>200<\/td><td>Controls how many venues appear in the Filter Bar<\/td><td>May slow front-end loading<\/td><\/tr><tr><td><code>tribe_events_filter_bar_organizers_limit<\/code><\/td><td>200<\/td><td>Controls how many organizers appear in the Filter Bar<\/td><td>May slow front-end loading<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-showing-filter-bar-on-initial-page-load-on-mobile\">Showing Filter Bar on Initial Page Load on Mobile<\/h2>\n\n\n\n<p>Filter Bar can be set up with a vertical or horizontal layout. When using the horizontal layout, you can choose the default state under <em>Events \u2192 Settings \u2192 Filters<\/em>: either &#8220;collapsed until opened&#8221; or &#8220;show already on page load.&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/01\/filter-bar-layout-settings.jpg\" alt=\"Layout and default state settings for Filter Bar under Events &gt; Settings &gt; Filters\"\/><figcaption class=\"wp-element-caption\">Layout and default state settings for Filter Bar under <em>Events \u2192 Settings \u2192 Filters<\/em><\/figcaption><\/figure>\n\n\n\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/TIVKNGPpWDQ?si=Bylrqw2Odf81Cks7\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n\n\n\n<p>On smaller screens, however, Filter Bar is hidden by default to save room for content \u2014 regardless of the setting above. There is no built-in setting to change this. If you want Filter Bar to be open by default on mobile as well, the following snippet will do the trick.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\n\/**\n * Open the Filter Bar on mobile on initial pageload.\n *\n * By default, Filter Bar is closed on mobile regardless of the setting.\n * With this snippet Filter Bar will show on pageload (unless the \"Stay collapsed...\" option is set).\n *\n * @author: Andras Guseo\n *\n * Plugins required: The Events Calendar, Filter Bar\n * Created: January 19, 2024\n * Last updated: September 18, 2024\n *\/\nfunction tec_open_filterbar_on_mobile() {\n    $fb_state = tribe_get_option( 'events_filters_default_state', 'closed' );\n\n    \/\/ Bail if Filter Bar should start closed.\n    \/\/ Remove this if you want filters on mobile to be open even if the \"Stay collapsed...\" option is set.\n    if ( $fb_state === 'closed' ) {\n        return;\n    }\n\n    echo '&lt;script&gt;\n    let fbSelector = document.querySelector(\".tribe-filter-bar\");\n    if(fbSelector != null) {\n        fbSelector.classList += \" tribe-filter-bar--open\";\n        fbSelector.style.position = \"unset\";\n    }\n\n    let fbButtonSelector = document.querySelector(\".tribe-events-c-events-bar__filter-button\");\n    if(fbButtonSelector != null) {\n        fbButtonSelector.classList += \" tribe-events-c-events-bar__filter-button--active\";\n    }\n    &lt;\/script&gt;';\n}\n\nadd_action( 'wp_footer', 'tec_open_filterbar_on_mobile' );<\/code><\/pre>\n\n\n\n<p>The result looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2024\/01\/FilterBar-Mobile-New.png\" alt=\"Filter Bar open on mobile after applying the snippet\"\/><\/figure>\n\n\n\n<p><em>Snippet source: <a href=\"https:\/\/gist.github.com\/andrasguseo\/a22cbb1917c98a9fbf5a47c012b37d76\">Andras Guseo gist<\/a><\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-forcing-vertical-filters-to-always-be-open-on-desktop\">Forcing Vertical Filters to Always Be Open on Desktop<\/h2>\n\n\n\n<p>Sometimes you may want your vertical filters to always appear expanded on the main Events page. This can improve visibility and make it easier for users to browse events. A small CSS snippet will safely force all vertical filters to stay open on desktop and tablet devices, while leaving mobile behavior untouched.<\/p>\n\n\n\n<p>Add the following CSS via <em>Appearance \u2192 Customize \u2192 Additional CSS<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@media screen and (min-width: 816px) {\n\n    .post-type-archive-tribe_events .tribe-filter-bar--vertical .tribe-filter-bar-c-filter__container {\n        display: block !important;\n        height: auto !important;\n        visibility: visible !important;\n    }\n\n\/* Optional: Adjust filter toggle icons to appear 'open' (only on the specific page and layout) *\/\n    .post-type-archive-tribe_events .tribe-filter-bar--vertical .tribe-filter-bar-c-filter:not(.tribe-filter-bar-c-filter--open) .tribe-filter-bar-c-filter__toggle-icon--minus {\n        display: inline-block !important;\n    }\n\n    .post-type-archive-tribe_events .tribe-filter-bar--vertical .tribe-filter-bar-c-filter:not(.tribe-filter-bar-c-filter--open) .tribe-filter-bar-c-filter__toggle-icon--plus {\n        display: none !important;\n    }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-it-works\">How It Works<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>.post-type-archive-tribe_events<\/code> ensures the CSS only runs on the main Events archive page.<\/li>\n\n\n\n<li><code>.tribe-filter-bar--vertical<\/code> ensures only vertical filters are affected.<\/li>\n\n\n\n<li><code>@media screen and (min-width: 816px)<\/code> ensures this CSS only affects screens wider than 816px. On smaller screens (like mobile), the default filter behavior will still apply.<\/li>\n<\/ul>\n\n\n\n<p>Your horizontal filter bar or other pages remain unchanged.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-optional-toggle-icons\">Optional: Toggle Icons<\/h4>\n\n\n\n<p>The optional part of the CSS changes the filter toggle icons to appear as if the filters are already open:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The &#8220;minus&#8221; icon (used to collapse a filter) is shown.<\/li>\n\n\n\n<li>The &#8220;plus&#8221; icon (used to expand a filter) is hidden.<\/li>\n<\/ul>\n\n\n\n<p>This gives users a visual cue that all filters are expanded by default.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-advanced-create-custom-filters\">Advanced: Create Custom Filters<\/h2>\n\n\n\n<p>Suppose you have a calendar loaded with events that span all hours of the day. You can already filter by a pretty general time, as seen in the screenshot below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2019\/10\/filter-bar-vertical-time.png\" alt=\"\" class=\"wp-image-1944580\"\/><\/figure>\n\n\n\n<p>But what if you want to allow for more granular filtering, perhaps by a specific time? We\u2019ll show you how in this tutorial.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-getting-started\">Getting Started<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>\ud83d\udca1<\/strong> Make sure you have a backup of your site files and database.<\/p>\n<\/blockquote>\n\n\n\n<p>I&#8217;ve created a <code>tec-fbar-custom-filter<\/code> directory in my WordPress plugins directory. In my development installation the resulting path, relative to WP root directory, is <code>wp-content\/plugins\/tec-fbar-custom-filter<\/code>. Yours might not match this path exactly depending on your setup.&nbsp;<\/p>\n\n\n\n<p>The easiest way to create a new filter is to modify an existing filter.<br>You can find the filters in your plugins directory at: <code>\/events-filterbar\/src\/Tribe\/Filters\/<\/code><\/p>\n\n\n\n<p>The code I&#8217;ll show in this tutorial will live in a dedicated plugin.<\/p>\n\n\n\n<p>You can also use <a href=\"https:\/\/theeventscalendar.com\/extensions\/creating-a-custom-filter-for-filter-bar\/\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/theeventscalendar.com\/extensions\/creating-a-custom-filter-for-filter-bar\/\">this handy extension<\/a> to get you started.<\/p>\n\n\n\n<p>Since we\u2019ll be adding a custom filter that is similar to the existing Time of Day filter, I\u2019m going to grab that one.<\/p>\n\n\n\n<p>To keep the code organized I&#8217;ve created a main plugin file, <code>tribe-ext-custom-filter.php<\/code>, and a file that will hold my custom filter class, <code>Time_Of_Day_Custom_Filter.php<\/code>.<\/p>\n\n\n\n<p>My plugin directory looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">\n\u2006 \u2006 \u2006 \u2006 tec-fbar-custom-filter\n\u2006 \u2006 \u2006 \u2006 \u2514\u2500\u2500 tribe-ext-custom-filter.php\n\u2006 \u2006 \u2006 \u2006 \u251c\u2500\u2500 src\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2514 Time_Of_Day_Custom_Filter.php\n<\/pre><\/div>\n\n\n<p>In the <code>Time_Of_Day_Custom_Filter.php<\/code> file I&#8217;ve called my filter class <code>Time_Of_Day_Custom_Filter<\/code>. <em>(Keeping all the names the same helps keep them organized in my head.)<\/em><\/p>\n\n\n\n<p>I\u2019ll need to decide what type of filtering I want to display. The checkbox filter is a good fit for this, so I\u2019ll go ahead and keep that in place.<\/p>\n\n\n\n<p>So far, my class looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\n\/**\n * Customized version of the Time of Day filter that allows selecting by specific hour ranges in the afternoon.\n *\n * New filter available in WP-Admin &gt; Events &gt; Settings &gt; Filters\n *\/\n\n\/**\n * Class Time_Of_Day_Custom_Filter\n *\/\nclass Time_Of_Day_Custom_Filter extends \\Tribe__Events__Filterbar__Filter {\n\t\/**\n\t * The type of this filter.\n\t *\n\t * Available options are &#039;select&#039;, &#039;multiselect&#039;, &#039;checkbox&#039;, &#039;radio&#039;, and &#039;range&#039;.\n\t *\n\t * @var string\n\t *\/\n\tpublic $type = &#039;checkbox&#039;;\n\n}\n\n<\/pre><\/div>\n\n\n<p>The next part is where things get interesting. We need to change both the <code>get_values()&nbsp;<\/code>function, and the <code>setup_join_clause()<\/code> and <code>setup_where_clause()<\/code> functions in order for our new filters to work.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"array\">Changing the Array Values<\/h4>\n\n\n\n<p>The current code allows us to filter in six-hour blocks. We\u2019ll modify that to allow filtering by the hour.<\/p>\n\n\n\n<p>In the function <code>get_values()<\/code>, change the time of day array to look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n\/**\n * Returns the available values this filter will display on the front end, when the user clicks on it.\n *\n * @return array &lt;string,string&gt; A map of the available values relating values to their human-readable format.\n *\/\nprotected function get_values() {\n\u2006 \u2006 \u2006 \u2006 \/\/ The time-of-day filter.\n\u2006 \u2006 \u2006 \u2006 $time_of_day_array = &#x5B;\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;allday&#039; =&gt; __( &#039;All Day&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;12-13&#039; =&gt; __( &#039;12:00 - 1:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;13-14&#039; =&gt; __( &#039;1:00 - 2:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;14-15&#039; =&gt; __( &#039;2:00 - 3:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;15-16&#039; =&gt; __( &#039;3:00 - 4:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;16-17&#039; =&gt; __( &#039;4:00 - 5:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;17-18&#039; =&gt; __( &#039;5:00 - 6:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;18-19&#039; =&gt; __( &#039;6:00 - 7:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;19-20&#039; =&gt; __( &#039;7:00 - 8:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;20-21&#039; =&gt; __( &#039;8:00 - 9:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;21-22&#039; =&gt; __( &#039;9:00 - 10:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;22-23&#039; =&gt; __( &#039;10:00 - 11:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;23-24&#039; =&gt; __( &#039;11:00 - 12:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\u2006 \u2006 \u2006 \u2006 ];\n\n\u2006 \u2006 \u2006 \u2006 $time_of_day_values = &#x5B;];\n\n\u2006 \u2006 \u2006 \u2006 foreach ( $time_of_day_array as $value =&gt; $name ) {\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 $time_of_day_values&#x5B;] = &#x5B;\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;name&#039; =&gt; $name,\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 &#039;value&#039; =&gt; $value,\n\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 ];\n\u2006 \u2006 \u2006 \u2006 }\n\n\u2006 \u2006 \u2006 \u2006 return $time_of_day_values;\n}\n<\/pre><\/div>\n\n\n<p>The rest of the <code>get_values()<\/code> function will stay the same.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"var\">Changing the Variable Names<\/h4>\n\n\n\n<p>The next methods I&#8217;ll look at are the <code>setup_where_clause()<\/code> and <code>setup_join_clause()<\/code> ones . I&#8217;m not making any radical change to the logic, but I&#8217;m trimming down the code to fit my custom filter need.<\/p>\n\n\n\n<p>The new code for the <code>setup_join_clause<\/code> method looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n\/\/ These are needed to make the join aliases unique\nprotected $alias = &#039;&#039;;\nprotected $tod_start_alias = &#039;&#039;;\nprotected $tod_duration_alias = &#039;&#039;;\n\n\/**\n * Sets up the filter JOIN clause.\n *\n * This will be added to the running events query to add (JOIN) the tables the filter requires.\n *\n * Specifically, this filter will JOIN on the post meta table to use the event start time and all-day information.\n *\/\nprotected function setup_join_clause() {\n\tif ( function_exists( &#039;posts_join&#039; ) ) {\n\t\t\tadd_filter( &#039;posts_join&#039;, array( &#039;Tribe__Events__Query&#039;, &#039;posts_join&#039; ), 10, 2 );\n\t}\n\n\tglobal $wpdb;\n\t$values = $this-&gt;currentValue;\n\n\t$all_day_index = array_search( &#039;allday&#039;, $values );\n\tif ( false !== $all_day_index ) {\n\t\tunset( $values&#x5B; $all_day_index ] );\n\t}\n\n\t$this-&gt;alias = &#039;custom_all_day_&#039; . uniqid();\n\t$this-&gt;tod_start_alias = &#039;tod_start_date_&#039; . uniqid();\n\t$this-&gt;tod_duration_alias = &#039;tod_duration_&#039; . uniqid();\n\n\t$joinType = empty( $all_day_index ) ? &#039;LEFT&#039; : &#039;INNER&#039;;\n\n\t$this-&gt;joinClause .= &quot; {$joinType} JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;alias}.post_id AND {$this-&gt;alias}.meta_key = &#039;_EventAllDay&#039;)&quot;;\n\n\tif ( ! empty( $values ) ) { \/\/ values other than allday\n\t\t$this-&gt;joinClause .= &quot; INNER JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;tod_start_alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;tod_start_alias}.post_id AND {$this-&gt;tod_start_alias}.meta_key = &#039;_EventStartDate&#039;)&quot;;\n\t\t$this-&gt;joinClause .= &quot; INNER JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;tod_duration_alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;tod_duration_alias}.post_id AND {$this-&gt;tod_duration_alias}.meta_key = &#039;_EventDuration&#039;)&quot;;\n\t}\n}\n<\/pre><\/div>\n\n\n<p>The code of the <code>setup_where_clause()<\/code> method looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n\/**\n * Sets up the filter WHERE clause.\n *\n * This will be added to the running events query to apply the matching criteria, time-of-day, handled by the\n * custom filter.\n *\n * @throws Exception\n *\/\n protected function setup_where_clause() {\n\tglobal $wpdb;\n\t$clauses = &#x5B;];\n\n\tif ( in_array( &#039;allday&#039;, $this-&gt;currentValue, true ) ) {\n\t\t$clauses&#x5B;] = &quot;( {$this-&gt;alias}.meta_value = &#039;yes&#039; )&quot;;\n\t} else {\n\t\t$this-&gt;whereClause = &quot; AND ( {$this-&gt;alias}.meta_id IS NULL ) &quot;;\n\t}\n\n\tforeach ( $this-&gt;currentValue as $value ) {\n\t\tif ( &#039;allday&#039; === $value ) {\n\t\t\t\/\/ Handled earlier.\n\t\t\tcontinue;\n\t\t}\n\n\t\tlist( $start_hour, $end_hour ) = explode( &#039;-&#039;, $value );\n\t\t$start\u2006 \u2006 \u2006 \u2006 \u2006 = $start_hour . &#039;:00:00&#039;;\n\t\t$end\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 = $end_hour . &#039;:00:00&#039;;\n\t\t$clauses&#x5B;] = $wpdb-&gt;prepare(\n\t\t\t&quot;( TIME( CAST( {$this-&gt;tod_start_alias}.meta_value as DATETIME ) ) &gt;= %s\n\t\t\tAND TIME( CAST({$this-&gt;tod_start_alias}.meta_value as DATETIME)) &lt; %s )&quot;,\n\t\t\t$start,\n\t\t\t$end\n\t\t);\n\t}\n\n\t$clauses = implode( &#039; OR &#039;, $clauses );\n\n\t$this-&gt;whereClause .= &quot; AND ({$clauses})&quot;;\n}\n<\/pre><\/div>\n\n\n<p>To make it work with the previous version of the View architecture, the last thing I&#8217;ll need to do is to instantiate the custom filter class when Filter Bar initializes: I&#8217;m doing this in the <code>tribe-ext-custom-filter.php<\/code> file:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/**\n * Plugin Name:\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 Filter Bar Extension: Custom Time of Day Filter\n *\n * Description:\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 Create a custom filter for Filter Bar that filters displayed events down by time of day.\n *\/\n\n\/**\n * Includes the custom filter class and creates an instance of it.\n *\/\nfunction tec_kb_create_filter() {\n\tif ( ! class_exists( &#039;Tribe__Events__Filterbar__Filter&#039; ) ) {\n\t\treturn;\n\t}\n\n\tinclude_once __DIR__ . &#039;\/src\/Time_Of_Day_Custom_Filter.php&#039;;\n\n\tnew \\Time_Of_Day_Custom_Filter(\n\t__( &#039;Time Custom&#039;, &#039;tribe-events-filter-view&#039; ),\n\t&#039;filterbar_time_of_day_custom&#039;\n\t);\n}\n\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-making-it-work-in-calendar-views\">Making It Work in Calendar Views<\/h4>\n\n\n\n<p>First things first, in the <code>tribe-ext-custom-filter.php<\/code> file, add my custom filter to the ones handled by the calendar views available with Filter Bar. Here&#8217;s the updated code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/**\n * Filters the map of filters available on the front-end to include the custom one.\n *\n * @param array&lt;string,string&gt; $map A map relating the filter slugs to their respective classes.\n *\n * @return array&lt;string,string&gt; The filtered slug to filter class map.\n *\/\nfunction tec_kb_filter_map( array $map ) {\n\tif ( ! class_exists( &#039;Tribe__Events__Filterbar__Filter&#039; ) ) {\n\t\t\/\/ This would not make much sense, but let&#039;s be cautious.\n\t\treturn $map;\n\t}\n\n\t\/\/ Include the filter class.\n\tinclude_once __DIR__ . &#039;\/src\/Time_Of_Day_Custom_Filter.php&#039;;\n\n\t\/\/ Add the filter class to our filters map.\n\t$map&#x5B;&#039;filterbar_time_of_day_custom&#039;] = &#039;Time_Of_Day_Custom_Filter&#039;;\n\n\t\/\/ Return the modified $map.\n\treturn $map;\n}\n\n\/**\n * Filters the Context locations to let the Context know how to fetch the value of the filter from a request.\n *\n * Here we add the `time_of_day_custom` as a read-only Context location: we&#039;ll not need to write it.\n *\n * @param array&lt;string,array&gt; $locations A map of the locations the Context supports and is able to read from and write\n *\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 to.\n *\n * @return array&lt;string,array&gt; The filtered map of Context locations, with the one required from the filter added to it.\n *\/\nfunction tec_kb_filter_context_locations( array $locations ) {\n\t\/\/ Read the filter selected values, if any, from the URL request vars.\n   $locations&#x5B;&#039;filterbar_time_of_day_custom&#039;] = &#x5B; \n\t\t\t\t&#039;read&#039; =&gt; &#x5B; \n\t\t\t\t\t\\Tribe__Context::QUERY_VAR   =&gt; &#x5B; &#039;tribe_filterbar_time_of_day_custom&#039; ],\n\t\t\t\t\t\\Tribe__Context::REQUEST_VAR =&gt; &#x5B; &#039;tribe_filterbar_time_of_day_custom&#039; ]\n\t\t\t\t], \n\t\t\t];\n\n\t\/\/ Return the modified $locations.\n\treturn $locations;\n}\n\n\/\/ Make it work with calendar views.\nadd_filter( &#039;tribe_context_locations&#039;, &#039;tec_kb_filter_context_locations&#039; );\nadd_filter( &#039;tribe_events_filter_bar_context_to_filter_map&#039;, &#039;tec_kb_filter_map&#039; );\n<\/pre><\/div>\n\n\n<p>Read the inline docs to understand what we&#8217;re doing line-by-line.<\/p>\n\n\n\n<p>Or skip to the bottom of the article to get the full plugin code in its final version.<\/p>\n\n\n\n<p>Finally, to wrap up calendar views support, I need to <code>use<\/code> the <code>Tribe\\Events\\Filterbar\\Views\\V2\\Filters\\Context_Filter<\/code> in the custom filter class code. This will automagically take care of a number of issues and make the class, without further changes, compatible with views (in the screenshot, I&#8217;m showing only the class start, as there&#8217;s really nothing else changed):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; highlight: [9,15,16]; title: ; notranslate\" title=\"\">\n&lt;?php\n\n\/**\n * Customized version of the Time of Day filter that allows selecting by specific hour ranges in the afternoon.\n *\n * New filter available in WP-Admin &gt; Events &gt; Settings &gt; Filters\n *\/\n\nuse Tribe\\Events\\Filterbar\\Views\\V2\\Filters\\Context_Filter;\n\n\/**\n * Class Time_Of_Day_Custom_Filter\n *\/\nclass Time_Of_Day_Custom_Filter extends \\Tribe__Events__Filterbar__Filter {\n\t\/\/ Use the trait required for filters to correctly work with Views V2 code.\n\tuse Context_Filter;\n\n<\/pre><\/div>\n\n\n<h4 class=\"wp-block-heading\" id=\"h-the-final-code\">The Final Code<\/h4>\n\n\n\n<p>Our final <code>tribe-ext-custom-filter.php<\/code> code looks like this (If you download the extension, there is more code in there, but this is the part that matters for this tutorial):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\/**\n * Plugin Name:\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 Filter Bar Extension: Custom Time of Day Filter\n * Description:\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 Create a custom filter for Filter Bar that filters displayed events down by time of day.\n *\/\n\n\/**\n * Filters the map of filters available on the front-end to include the custom one.\n *\n * @param array&lt;string,string&gt; $map A map relating the filter slugs to their respective classes.\n *\n * @return array&lt;string,string&gt; The filtered slug to filter class map.\n *\/\nfunction tec_kb_filter_map( array $map ) {\n\tif ( ! class_exists( &#039;Tribe__Events__Filterbar__Filter&#039; ) ) {\n\t\/\/ This would not make much sense, but let&#039;s be cautious.\n\treturn $map;\n\t}\n\n\t\/\/ Include the filter class.\n\tinclude_once __DIR__ . &#039;\/src\/Time_Of_Day_Custom_Filter.php&#039;;\n\n\t\/\/ Add the filter class to our filters map.\n\t$map&#x5B;&#039;filterbar_time_of_day_custom&#039;] = &#039;Time_Of_Day_Custom_Filter&#039;;\n\n\t\/\/ Return the modified $map.\n\treturn $map;\n}\n\n\/**\n * Filters the Context locations to let the Context know how to fetch the value of the filter from a request.\n *\n * Here we add the `time_of_day_custom` as a read-only Context location: we&#039;ll not need to write it.\n *\n * @param array&lt;string,array&gt; $locations A map of the locations the Context supports and is able to read from and write\n *\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 to.\n *\n * @return array&lt;string,array&gt; The filtered map of Context locations, with the one required from the filter added to it.\n *\/\nfunction tec_kb_filter_context_locations( array $locations ) {\n\t\/\/ Read the filter selected values, if any, from the URL request vars.\n    $locations&#x5B;&#039;filterbar_time_of_day_custom&#039;] = &#x5B; \n\t\t\t\t&#039;read&#039; =&gt; &#x5B; \n\t\t\t\t\t\\Tribe__Context::QUERY_VAR   =&gt; &#x5B; &#039;tribe_filterbar_time_of_day_custom&#039; ],\n\t\t\t\t\t\\Tribe__Context::REQUEST_VAR =&gt; &#x5B; &#039;tribe_filterbar_time_of_day_custom&#039; ]\n\t\t\t\t], \n\t\t\t];\n\n\t\/\/ Return the modified $locations.\n\treturn $locations;\n}\n\n\/**\n * Includes the custom filter class and creates an instance of it.\n *\/\nfunction tec_kb_create_filter() {\n\tif ( ! class_exists( &#039;Tribe__Events__Filterbar__Filter&#039; ) ) {\n\t\treturn;\n\t}\n\n\tinclude_once __DIR__ . &#039;\/src\/Time_Of_Day_Custom_Filter.php&#039;;\n\n\tnew \\Time_Of_Day_Custom_Filter(\n\t__( &#039;Time Custom&#039;, &#039;tribe-events-filter-view&#039; ),\n\t&#039;filterbar_time_of_day_custom&#039;\n\t);\n}\n\n\n\n\/\/ Make it work with calendar views.\nadd_filter( &#039;tribe_context_locations&#039;, &#039;tec_kb_filter_context_locations&#039; );\nadd_filter( &#039;tribe_events_filter_bar_context_to_filter_map&#039;, &#039;tec_kb_filter_map&#039; );\n\n<\/pre><\/div>\n\n\n<p>While the <code>Time_Of_Day_Custom_Filter.php<\/code> custom filter code is this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: php; title: ; notranslate\" title=\"\">\n&lt;?php\n\n\/**\n * Customized version of the Time of Day filter that allows selecting by specific hour ranges in the afternoon.\n *\n * New filter available in WP-Admin &gt; Events &gt; Settings &gt; Filters\n *\/\n\nuse Tribe\\Events\\Filterbar\\Views\\V2\\Filters\\Context_Filter;\n\n\/**\n * Class Time_Of_Day_Custom_Filter\n *\/\nclass Time_Of_Day_Custom_Filter extends \\Tribe__Events__Filterbar__Filter {\n\t\/\/ Use the trait required for filters to correctly work with Views V2 code.\n\tuse Context_Filter;\n\n\t\/**\n\t * The type of this filter.\n\t *\n\t * Available options are &#039;select&#039;, &#039;multiselect&#039;, &#039;checkbox&#039;, &#039;radio&#039;, and &#039;range&#039;.\n\t *\n\t * @var string\n\t *\/\n\tpublic $type = &#039;checkbox&#039;;\n\n\n\t\/\/ These are needed to make the join aliases unique\n\tprotected $alias = &#039;&#039;;\n\tprotected $tod_start_alias = &#039;&#039;;\n\tprotected $tod_duration_alias = &#039;&#039;;\n\n\t\/**\n\t * Returns the available values this filter will display on the front end, when the user clicks on it.\n\t *\n\t * @return array &lt;string,string&gt; A map of the available values relating values to their human-readable format.\n\t *\/\n\tprotected function get_values() {\n\t\t\/\/ The time-of-day filter.\n\t\t$time_of_day_array = &#x5B;\n\t\t\t&#039;allday&#039; =&gt; __( &#039;All Day&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;12-13&#039; =&gt; __( &#039;12:00 - 1:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;13-14&#039; =&gt; __( &#039;1:00 - 2:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;14-15&#039; =&gt; __( &#039;2:00 - 3:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;15-16&#039; =&gt; __( &#039;3:00 - 4:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;16-17&#039; =&gt; __( &#039;4:00 - 5:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;17-18&#039; =&gt; __( &#039;5:00 - 6:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;18-19&#039; =&gt; __( &#039;6:00 - 7:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;19-20&#039; =&gt; __( &#039;7:00 - 8:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;20-21&#039; =&gt; __( &#039;8:00 - 9:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;21-22&#039; =&gt; __( &#039;9:00 - 10:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;22-23&#039; =&gt; __( &#039;10:00 - 11:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t\t&#039;23-24&#039; =&gt; __( &#039;11:00 - 12:00 pm&#039;, &#039;tribe-events-filter-view&#039; ),\n\t\t];\n\n\t\t$time_of_day_values = &#x5B;];\n\n\t\tforeach ( $time_of_day_array as $value =&gt; $name ) {\n\t\t\t$time_of_day_values&#x5B;] = &#x5B;\n\t\t\t\t&#039;name&#039; =&gt; $name,\n\t\t\t\t&#039;value&#039; =&gt; $value,\n\t\t\t];\n\t\t}\n\n\t\treturn $time_of_day_values;\n\t}\n\n\t\/**\n\t * Sets up the filter JOIN clause.\n\t *\n\t * This will be added to the running events query to add (JOIN) the tables the filter requires.\n\t *\n\t * Specifically, this filter will JOIN on the post meta table to use the event start time and all-day information.\n\t *\/\n\tprotected function setup_join_clause() {\n\t\tif ( function_exists( &#039;posts_join&#039; ) ) {\n\t\t\tadd_filter( &#039;posts_join&#039;, array( &#039;Tribe__Events__Query&#039;, &#039;posts_join&#039; ), 10, 2 );\n\t\t}\n\n\t\tglobal $wpdb;\n\t\t$values = $this-&gt;currentValue;\n\n\t\t$all_day_index = array_search( &#039;allday&#039;, $values );\n\t\tif ( false !== $all_day_index ) {\n\t\t\tunset( $values&#x5B; $all_day_index ] );\n\t\t}\n\n\t\t$this-&gt;alias = &#039;custom_all_day_&#039; . uniqid();\n\t\t$this-&gt;tod_start_alias = &#039;tod_start_date_&#039; . uniqid();\n\t\t$this-&gt;tod_duration_alias = &#039;tod_duration_&#039; . uniqid();\n\n\t\t$joinType = empty( $all_day_index ) ? &#039;LEFT&#039; : &#039;INNER&#039;;\n\n\t\t$this-&gt;joinClause .= &quot; {$joinType} JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;alias}.post_id AND {$this-&gt;alias}.meta_key = &#039;_EventAllDay&#039;)&quot;;\n\n\t\tif ( ! empty( $values ) ) { \/\/ values other than allday\n\t\t\t$this-&gt;joinClause .= &quot; INNER JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;tod_start_alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;tod_start_alias}.post_id AND {$this-&gt;tod_start_alias}.meta_key = &#039;_EventStartDate&#039;)&quot;;\n\t\t\t$this-&gt;joinClause .= &quot; INNER JOIN {$wpdb-&gt;postmeta} AS {$this-&gt;tod_duration_alias} ON ({$wpdb-&gt;posts}.ID = {$this-&gt;tod_duration_alias}.post_id AND {$this-&gt;tod_duration_alias}.meta_key = &#039;_EventDuration&#039;)&quot;;\n\t\t}\n\t}\n\n\t\/**\n\t * Sets up the filter WHERE clause.\n\t *\n\t * This will be added to the running events query to apply the matching criteria, time-of-day, handled by the\n\t * custom filter.\n\t *\n\t * @throws Exception\n\t *\/\n\tprotected function setup_where_clause() {\n\t\tglobal $wpdb;\n\t\t$clauses = &#x5B;];\n\n\t\tif ( in_array( &#039;allday&#039;, $this-&gt;currentValue, true ) ) {\n\t\t\t$clauses&#x5B;] = &quot;( {$this-&gt;alias}.meta_value = &#039;yes&#039; )&quot;;\n\t\t} else {\n\t\t\t$this-&gt;whereClause = &quot; AND ( {$this-&gt;alias}.meta_id IS NULL ) &quot;;\n\t\t}\n\n\t\tforeach ( $this-&gt;currentValue as $value ) {\n\t\t\tif ( &#039;allday&#039; === $value ) {\n\t\t\t\t\/\/ Handled earlier.\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlist( $start_hour, $end_hour ) = explode( &#039;-&#039;, $value );\n\t\t\t$start\u2006 \u2006 \u2006 \u2006 \u2006 = $start_hour . &#039;:00:00&#039;;\n\t\t\t$end\u2006 \u2006 \u2006 \u2006 \u2006 \u2006 \u2006 = $end_hour . &#039;:00:00&#039;;\n\t\t\t$clauses&#x5B;] = $wpdb-&gt;prepare(\n\t\t\t\t&quot;( TIME( CAST( {$this-&gt;tod_start_alias}.meta_value as DATETIME ) ) &gt;= %s\n\t\t\t\tAND TIME( CAST({$this-&gt;tod_start_alias}.meta_value as DATETIME)) &lt; %s )&quot;,\n\t\t\t\t$start,\n\t\t\t\t$end\n\t\t\t);\n\t\t}\n\n\t\t$clauses = implode( &#039; OR &#039;, $clauses );\n\n\t\t$this-&gt;whereClause .= &quot; AND ({$clauses})&quot;;\n\t}\n}\n\n<\/pre><\/div>\n\n\n<p>Once you have your code in place, you\u2019ll need to adjust your settings in <strong>Events<\/strong> \u2192&nbsp;<strong>Settings<\/strong> \u2192&nbsp;<strong>Filters<\/strong> so that your new filter will display on the front end.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/images.theeventscalendar.com\/kb\/uploads\/2017\/05\/Screen-Shot-2017-04-30-at-11.27.43-PM-665x432.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Once you have that done, you should have the new filters in the Filter Bar, like so:<\/p>\n\n\n\n\n\n<p><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"\/knowledgebase\/wp-content\/uploads\/2020\/09\/Screen-Shot-2020-09-28-at-2.25.51-PM-1024x554.png\" alt=\"\" class=\"wp-image-1948256\"\/><\/figure><\/div>\n\n\n<h4 class=\"wp-block-heading\">Final thoughts<\/h4>\n\n\n\n<p>Now that you\u2019ve seen how easy it is to modify and extend the existing filters, hopefully, this will spark some ideas for you to create your own!<\/p>\n\n\n\n<p>Let us know if you come up with anything cool. We\u2019d love it if you&#8217;d share with the community!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Filter Bar add-on includes admin settings for layout, default state, and which filters appear \u2014 but some customizations require a small snippet. This article collects three common recipes: adjusting how many venues and organizers are loaded into the filter dropdowns, forcing the Filter Bar to appear open on mobile, and forcing vertical filters to&#8230;<\/p>\n","protected":false},"author":84,"featured_media":1955565,"comment_status":"open","ping_status":"open","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":[24,59,79],"tags":[],"stellar-product-taxonomy":[],"class_list":["post-1959175","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-customizing","category-php-function-snippets","category-snippets"],"acf":[],"taxonomy_info":{"category":[{"value":24,"label":"Customizations"},{"value":59,"label":"PHP Functions &amp; Snippets"},{"value":79,"label":"Snippets"}]},"featured_image_src_large":["https:\/\/images.theeventscalendar.com\/kb\/uploads\/2023\/02\/social-share-1024x538.png",1024,538,true],"author_info":{"display_name":"The Events Calendar Team","author_link":"https:\/\/theeventscalendar.com\/knowledgebase\/author\/the_events_calendar_team\/"},"comment_info":0,"category_info":[{"term_id":24,"name":"Customizations","slug":"customizing","term_group":0,"term_taxonomy_id":24,"taxonomy":"category","description":"","parent":0,"count":76,"filter":"raw","term_order":"0","cat_ID":24,"category_count":76,"category_description":"","cat_name":"Customizations","category_nicename":"customizing","category_parent":0},{"term_id":59,"name":"PHP Functions &amp; Snippets","slug":"php-function-snippets","term_group":0,"term_taxonomy_id":59,"taxonomy":"category","description":"","parent":24,"count":63,"filter":"raw","term_order":"0","cat_ID":59,"category_count":63,"category_description":"","cat_name":"PHP Functions &amp; Snippets","category_nicename":"php-function-snippets","category_parent":24},{"term_id":79,"name":"Snippets","slug":"snippets","term_group":0,"term_taxonomy_id":79,"taxonomy":"category","description":"","parent":0,"count":44,"filter":"raw","term_order":"0","cat_ID":79,"category_count":44,"category_description":"","cat_name":"Snippets","category_nicename":"snippets","category_parent":0}],"tag_info":false,"_links":{"self":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1959175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/users\/84"}],"replies":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/comments?post=1959175"}],"version-history":[{"count":16,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1959175\/revisions"}],"predecessor-version":[{"id":1969374,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/posts\/1959175\/revisions\/1969374"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media\/1955565"}],"wp:attachment":[{"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/media?parent=1959175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/categories?post=1959175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/tags?post=1959175"},{"taxonomy":"stellar-product-taxonomy","embeddable":true,"href":"https:\/\/theeventscalendar.com\/knowledgebase\/wp-json\/wp\/v2\/stellar-product-taxonomy?post=1959175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}