Filtering Blog Posts By Category

This tutorial will walk you through how to display your blog post categories and use them as filters to dynamically show associated posts. This is helpful for creating custom layouts or blog landing pages.

1) Setup Post Categories

  1. Go to Posts > Categories in your Dashboard.
  2. Create a Parent Category (e.g., "News")
  3. Create Child Categories under that parent (e.g., "Updates", "Tips", "Media")

This structure helps when filtering posts later on. If you're not familiar with creating Post Categories, read the tutorial here.

Make sure to take note of the Category ID of your parent category as you’ll need it in the HTML code later. To find it, click on the parent category and look at the top of the page. You’ll see something like “Editing Post Category #”. This number is your Category ID.

2) Create the Blog Page

You can add the category filter to any new or existing page. In the page editor, click Source from the left panel, then paste the HTML code below to the HTML tab.

Don’t forget to replace every instance of PARENT_CATEGORY_ID in the HTML with the actual ID of your parent category — there are three in total (lines 6 and 8).

<ajax:event id="category_id_ajaxevent" updateregions="category_id_ajaxregions" /> <forms:form id="post_filter"> <forms:radiobuttongroup name="post_category_id" validations="mandatory"> <div class="template-categoryItem"> <forms:radiobutton value="PARENT_CATEGORY_ID" valuechecked="PARENT_CATEGORY_ID" validations="mandatory" onchangeajax="category_id_ajaxevent">All</forms:radiobutton> </div> <data:repeater as="category" datasource="\Components\Website\Posts\Categories::getChildren(PARENT_CATEGORY_ID)" datafilter="[? [['post_count', '!=', 0]] ?]"> <div class="template-categoryItem"> <forms:radiobutton valuechecked="[? $category['post_category_id'] ?]" validations="mandatory" onchangeajax="category_id_ajaxevent">[? $category['post_category_title'] ?]</forms:radiobutton> </div> </data:repeater> </forms:radiobuttongroup> <p><br /><br /></p> <ajax:region id="category_id_ajaxregions"> <data:postrepeater templatetype="list" postcategory="[? $post_filter.getValueForFormItem('post_category_id') ?]" /> </ajax:region> </forms:form>

Add the following CSS for basic styling, and feel free to tweak it to match your website’s look and feel:

.template-categoryItem { position: relative; font-size: 1rem; color: #27304b; font-weight: 500; } .template-categoryItem.is_selected { font-weight: bold; } .template-categoryItem .s8-radiobutton-container { position: absolute; width: 100%; height: 100%; } .template-categoryItem label.s8-radiobutton-container input ~ .s8-radiobutton, .template-categoryItem label.s8-radiobutton-container input ~ .s8-radiobutton:before { border: none !important; background-color: unset !important; } #post_filter .s8-radiobuttongroup { display: flex; flex-direction: initial; flex-wrap: wrap; gap: 2rem; justify-content: center; } .s8-radiobutton-container input[type="radio"]:checked ~ .s8-radiobutton::after { content: ""; position: absolute; top: unset; right: 0; left: 0; bottom: 0; background: #000000; height: 10%; width: 100%; border-radius: 0px; margin: 0 !important; }