Blog Dropdown Filter Search

We have a blog search bar module called the Activity Finder. It’s a form including two dropdowns (Topic and Age) and a submit button in order for the user to search through activity posts only.

Since we now have both “resources” and “activity” blog posts within one blog, I figured to separate the activity posts with an additional “Activity” Tag and find a solution to search through them.

Essentially, the form should submit results from the 3 tag items: The “Topic”, and “Age” user selections if they have the “Activity” tag.

I’ve gathered a lot from these resources but I’m not able to come up with a viable solution as to what code goes where:

  1. https://community.hubspot.com/t5/CMS-Development/Multiple-filters-in-blog/td-p/198720
  2. https://community.hubspot.com/t5/CMS-Development/How-do-I-filter-blogs-with-multiple-Tags-i-e-Tag-1-AND-Tag-2-AND/m-p/347289
  3. https://community.hubspot.com/t5/CMS-Development/How-to-filter-Blog-post-using-multiple-tags/td-p/209522
  4. https://community.hubspot.com/t5/CMS-Development/Filtering-blog-posts-with-2-tags-on-listing-template/m-p/647861#M29068

From my understanding:

  • The Custom (Activity Finder) Module: contains the form with the request_query_dict variable.
    • In my current module, I included code with an empty array to append the two selections from the dropdowns. I assume this is where I could add the “Activity” tag as the first category/parameter collected by default, and then append the two from the dropdowns after it to further filter.

Here is the Activity Finder code where I combined two different solutions with the request_query_dict array and “if currentURL==” but I’m not sure which to use effeciently:

{# Get current activities for list and filter #}
{% if request.query_dict != '' %} {# if there is a paramater/filter selected #}
{% set categories = [] %} {# create array to collect category #}

{% for item in request.query|split('&') %} {# split paramaters together with values #}

{% set currect_categories = item|split('=') %} {# split value from paramater #}
{% if currect_categories[0] == 'category' %} {# check if it's a activity #}
{% do categories.append(currect_categories[1]) %} {# add to selected activties array #}
{% endif %}

{% endfor %}
{% endif %}

{% set my_tags = blog_tags('default', 250) %}
{% set currentURL = content.absolute_url|regex_replace('^(http|https):', '') %}

<form method="get" form action="{{ group.absolute_url|replace('http', 'https') }}/all" id="activity-finder">
<div class="row collapse">
<div class="large-2 medium-3 columns">
<label for="right-label" class="right">I'm looking for</label>
</div>

<div class="large-3 medium-3 columns">

<select class="radius" id="selectTopic">
<option {% if currentURL == group.absolute_url|regex_replace('^(http|https):', '') %}selected="selected"{% endif %} value="{{ group.absolute_url }}">Select Topic</option>
{% for item in my_tags %}
{% if item == 'Art' || item == 'Cooking' || item == 'Fall' || item == 'Language' || item == 'Literacy' || item == 'Math' || item == 'Movement and Play' || item == 'Music' || item == 'Science' || item == 'Social and Emotional' || item == 'Spring' || item == 'Summer' || item == 'Technology' || item == 'Winter' %}
<option {% if currentURL == blog_tag_url(group.id, item.slug) %}selected="selected"{% endif %} name="category" value="{{ blog_tag_url(group.id, item.slug)|regex_replace('^(http|https):', '') }}">{{ item }}</option>
{% endif %}
{% endfor %}
</select>
</div>

<div class="medium-1 columns">
<label for="right-label" class="text-align-center">for</label>
</div>
<div class="large-3 medium-2 columns">
<select class="radius radius-two" name="age" id="selectAge">
<option {% if currentURL == group.absolute_url|regex_replace('^(http|https):', '') %}selected="selected"{% endif %} value="{{ group.absolute_url }}">Any Age</option>
{% for item in my_tags %}
{% if item == 'Infant' || item == 'Preschool' || item == 'Toddler' || item == 'Elementary' %}
<option {% if currentURL == blog_tag_url(group.id, item.slug) %}selected="selected"{% endif %} name="category" value="{{ blog_tag_url(group.id, item.slug)|regex_replace('^(http|https):', '') }}">{{ item }}</option>
{% endif %}
{% endfor %}
</select>
</div>

<div class="large-3 medium-3 columns">
<input type="submit" class="button secondary radius small" id="activity_finder_button" value="Seleted option">
</div>

</div>
</form>
  • The Blog Listings Module: I’m guessing this module could contain the blog listing logic and render results from the module dynamically..but I’m also not sure.
    • Since the button is clicked, the queries should reflect in the URL and I don’t know whether to apply a “Return false;” for same page results or linking to another page using the “form action=”"
    • I read that you could use the /all page to render results using the:

{% if not simple_list_page %}​

And apply it within the Blog Listing Module like:

{% if not simple_list_page %}
Regular Blog Listings Template Code
 {% else %}
Show user results from submitted Activity Finder Code
{% endif %}​

Here is the Blog Listing Code that I have so far and I probably don’t need the redundancy of rendering the same thing in the “else” statement but it seems pretty complex at this point:

<div class="sidebar {{ module.number_of_columns }}">
 <section class="blog-index">
 {% if tag %}
 <div class="blog-index__tag-header">
 <div class="blog-index__tag-subtitle">Posts about</div>
 <h1 class="blog-index__tag-heading">{{ page_meta.html_title|split(' | ')|last }}</h1>
 </div>
 {% endif %}

 {# Blog listing #}
 {% if not simple_list_page %} {# if it's not "/all", "/tag", or "author", then do this: #}
 {% for content in contents %}

 {# Set featured image #}
 {# This checks to see if a user is opted into the blog listing editing experience. If they are it uses the conditional from the module. If they are not it uses the conditional from blog settings #}
 {% set show_featured_image = false %}
 {% if content.featured_image %}
 {% if blog.listing_page_id %}
 {% if module.featured_image %}
 {% set show_featured_image = true %}
 {% endif %}
 {% else %}
 {% if group.use_featured_image_in_summary %}
 {% set show_featured_image = true %}
 {% endif %}
 {% endif %}
 {% endif %}
 {# End set featured image #}

 <article class="blog-index__post blog-index__post--small" aria-label="Blog post summary: {{ content.name }}" id="{{ content.name|lower|replace(' ','')|replace('$','')|replace(",","")|replace("#","") }}">
 <div class="blog-index__post-inner-card{% if not content.featured_image %} no-image{% endif %}">
 {% if show_featured_image == true %}
 <a class="blog-index__post-image blog-index__post-image--small" style="background-image: url('{{ content.featured_image }}');" href="{{ content.absolute_url }}" aria-label="{% if content.featured_image_alt_text %}Featured image: {{ content.featured_image_alt_text }} - {% endif %}Read full post: {{ content.name }}">
 </a>
 {% endif %}
 <div class="blog-index__post-content blog-index__post-content--small">

 {# Tags #}
 {% if module.tags %}
 {% if content.tag_list %}
 <div class="blog-post__tags">
 {% for tag in content.tag_list %}
 <a class="blog-post__tag-link" href="{{ blog_tag_url(group.id, tag.slug) }}">{{ tag.name }}</a>{% if not loop.last %},{% endif %}
 {% endfor %}
 </div>
 {% endif %}
 {% endif %}
 {# End tags #}

 {# Title #}
 {% if module.post_title %}
 <h2><a href="{{ content.absolute_url }}">{{ content.name }}</a></h2>
 {% endif %}
 {# End title #}

 {# Summary #}
 {# This checks to see if a user is opted into the blog listing editing experience. If they are it uses the conditional from the module. If they are not it uses the conditional from blog settings #}
 {% if blog.listing_page_id %}
 {% if module.description %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% else %}
 {% if content_group.show_summary_in_listing %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% endif %}
 {# End summary #}

 <div class="blog-post__meta-section{% if !module.reading_minutes %} no-min{% endif %}">

 {# Reading Minutes #}
 {% if module.reading_minutes %}
 <div class="blog-post__read-minutes">
 {% set initialPostWords = content.post_body|striptags|wordcount %}
 {% set calculatedPostWords = (initialPostWords/100) * 100 %}
 {% set finishedPostWords = calculatedPostWords|divide(300)|round(2) %}
 {% set number = finishedPostWords|round %}
 {% if number < 1 %}
 {% else %}
 {{ finishedPostWords|round }} minute read
 {% endif %}
 </div>
 {% endif %}
 {# End reading minutes #}

 {# Read more button #}
 {% if module.read_more %}
 <div class="blog-post__read-more">
 <a href="{{ content.absolute_url }}">{{ module.read_more_text }}<span class="read-more__arrow">{% icon name="long-arrow-alt-right" style="SOLID" %}</span></a>
 </div>
 {% endif %}
 {# End read more button #}

 </div>
 </div>
 </div>
 </article>
 {% endfor %}
 {# End blog listing #}

 {% else %} {# if it's "/all", then do this: #}

 {# Check if Tags parameter exists in url querystring #}
 {% if request.query_dict.tag %}
 {# Reconvert it into string and split by | separator #}
 {% for reqParam in request.query_dict.tag|string|split('|') %}
 {% set filteredTagPost = blog_recent_tag_posts("default", reqParam) %}
 {# Loop through each of the post #}
 {% for blogPost in filteredTagPost %}
 {# Check if blogpost was found #}
 {% if blogPost %}
 {# Loop through each tag of the current post #}
 {% for blogTag in blogPost.tag_list %}
 {% if blogTag.slug == reqParam %}
 Match Found for Blog: {{ blogPost.title }} <br>
 {% set show_featured_image = false %}
 {% if content.featured_image %}
 {% if blog.listing_page_id %}
 {% if module.featured_image %}
 {% set show_featured_image = true %}
 {% endif %}
 {% else %}
 {% if group.use_featured_image_in_summary %}
 {% set show_featured_image = true %}
 {% endif %}
 {% endif %}
 {% endif %}
 {# End set featured image #}

 <article class="blog-index__post blog-index__post--small" aria-label="Blog post summary: {{ content.name }}" id="{{ content.name|lower|replace(' ','')|replace('$','')|replace(",","")|replace("#","") }}">
 <div class="blog-index__post-inner-card{% if not content.featured_image %} no-image{% endif %}">
 {% if show_featured_image == true %}
 <a class="blog-index__post-image blog-index__post-image--small" style="background-image: url('{{ content.featured_image }}');" href="{{ content.absolute_url }}" aria-label="{% if content.featured_image_alt_text %}Featured image: {{ content.featured_image_alt_text }} - {% endif %}Read full post: {{ content.name }}">
 </a>
 {% endif %}
 <div class="blog-index__post-content blog-index__post-content--small">

 {# Tags #}
 {% if module.tags %}
 {% if content.tag_list %}
 <div class="blog-post__tags">
 {% for tag in content.tag_list %}
 <a class="blog-post__tag-link" href="{{ blog_tag_url(group.id, tag.slug) }}">{{ tag.name }}</a>{% if not loop.last %},{% endif %}
 {% endfor %}
 </div>
 {% endif %}
 {% endif %}
 {# End tags #}

 {# Title #}
 {% if module.post_title %}
 <h2><a href="{{ content.absolute_url }}">{{ content.name }}</a></h2>
 {% endif %}
 {# End title #}

 {# Summary #}
 {# This checks to see if a user is opted into the blog listing editing experience. If they are it uses the conditional from the module. If they are not it uses the conditional from blog settings #}
 {% if blog.listing_page_id %}
 {% if module.description %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% else %}
 {% if content_group.show_summary_in_listing %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% endif %}
 {# End summary #}

 <div class="blog-post__meta-section{% if !module.reading_minutes %} no-min{% endif %}">

 {# Reading Minutes #}
 {% if module.reading_minutes %}
 <div class="blog-post__read-minutes">
 {% set initialPostWords = content.post_body|striptags|wordcount %}
 {% set calculatedPostWords = (initialPostWords/100) * 100 %}
 {% set finishedPostWords = calculatedPostWords|divide(300)|round(2) %}
 {% set number = finishedPostWords|round %}
 {% if number < 1 %}
 {% else %}
 {{ finishedPostWords|round }} minute read
 {% endif %}
 </div>
 {% endif %}
 {# End reading minutes #}

 {# Read more button #}
 {% if module.read_more %}
 <div class="blog-post__read-more">
 <a href="{{ content.absolute_url }}">{{ module.read_more_text }}<span class="read-more__arrow">{% icon name="long-arrow-alt-right" style="SOLID" %}</span></a>
 </div>
 {% endif %}
 {# End read more button #}

 </div>
 </div>
 </div>
 </article>
 {% endif %}
 {% endfor %}
 {% endif %}
 {% endfor %}
 {% endfor %}
 {% endif %}
 </section>
</div>
  • Blog listing template: could be where the “if_simple_listing_page” could apply the logic as well..but then again..I’m not sure!

So if anyone could help this come together with me, that would be awesome! Thanks in advance!

Hey, @TamaraH :waving_hand: Welcome to the community! Thank you for your well-thought-out question and for including all those details. Hey, @Jnix284 @Anton @Indra, do you have any experience with building out a custom search in the manner @TamaraH is describing?

Thank you! — Jaycee

Thank you @Jaycee_Lewis !

I’ve actually been working on this and I’m getting closer to the solution. I achieved querying the selected topics in the URL. However, I’m just at the point of making the results render correctly on the /all page.

In the code below, I’m attempting to create/grab the slugs from the two search queries in order to implement the posts of those tags and insert the Tag Names into the title (if I can).

This is the current state of an example search query on this page:

Activity Finder Module Code:

<!-- Getting the query concatenation -->
{# Get current activities for list and filter #}
{% if request.query_dict != '' %} {# if there is a paramater/filter selected #}
 {% set activities = [] %} {# create array to collect my_tag #}

 {% for item in request.query|split('&') %} {# split paramaters together with values #}

 {% set current_activities = item|split('=') %} {# split value from paramater #}
 {% if current_activities[0] == 'tag' %} {# check if it's a activity #}
 {% do activities.append(current_activities[1]) %} {# add to selected activities array #} 
 {% endif %}

 {% endfor %}
{% endif %}

{% set my_tags = blog_tags('default', 250) %}

<form method="get" id="tags" action="https://blog.gryphonhouse.com/resources/all" id="activity-finder">
 <div class="row collapse">
 <div class="large-2 medium-3 columns">
 <label for="right-label" class="right">I'm looking for</label>
 </div>

 <div class="large-3 medium-3 columns">
 <select class="radius" id="selectTopic" name="Topic" required>
 <option>Select Topic</option>
 {% for my_tag in my_tags %}
 {% if my_tag == 'Art' || my_tag == 'Cooking' || my_tag == 'Fall' || my_tag == 'Language' || my_tag == 'Literacy' || my_tag == 'Math' || my_tag == 'Movement and Play' || my_tag == 'Music' || my_tag == 'Science' || my_tag == 'Social and Emotional' || my_tag == 'Spring' || my_tag == 'Summer' || my_tag == 'Technology' || my_tag == 'Winter' %}
 <option form="tags" value="{{ my_tag }}" name="tag">{{ my_tag }}</option>
 {% endif %}
 {% endfor %}
 </select>
 </div>

 <div class="medium-1 columns">
 <label for="right-label" class="text-align-center">for</label>
 </div>

 <div class="large-3 medium-2 columns">
 <select class="radius radius-two" name="Age" id="selectAge">
 <option>Any Age</option>
 {% for my_tag in my_tags %}
 {% if my_tag == 'Infant' || my_tag == 'Preschool' || my_tag == 'Toddler' || my_tag == 'Elementary' %}
 <option form="tags" value="{{ my_tag }}" name="tag">{{ my_tag }}</option>
 {% endif %}
 {% endfor %}
 </select>
 </div>

 <div class="large-3 medium-3 columns">
 <input type="submit" class="button secondary radius small" id="activity_finder_button" value="Find Activities">
 </div>

 </div>
</form>

Activity Finder Javascript

$( "#activity_finder_button" ).click(function() {
 $( "#tags" ).submit();
});

Blog Listings Code:

<div class="sidebar {{ module.number_of_columns }}">
 <section class="blog-index">
<!--============== If the user clicked on a tag: ==============--> 
 {% if tag %}
 <div class="blog-index__tag-header">
 <div class="blog-index__tag-subtitle">Posts about</div>
 <h1 class="blog-index__tag-heading">{{ page_meta.html_title|split(' | ')|last }}</h1>
 </div>
 {% endif %}

<!--============== If the user submitted Activity Finder: ==============--> 
 {% unless not simple_list_page %} {# if it's not "/all", "/tag", or "author", then do this: #}
 <div class="blog-index__tag-header">
 <div class="blog-index__tag-subtitle">Activities Found:</div>
 </div> 

<!--============== Posts Using the Tags Selected ==============--> 
 {# if it's "/all", then do this: #}
{# Check if top parameter exists in url querystring #}
{% if request.query_dict.Topic && request.query_dict.Age %}
 {% set user_topic = request.query_dict.Topic|string %}
 {% set user_age = request.query_dict.Age|string %}
 {# Reconvert it into string and split by | separator #}
 {% for reqParam in request.query_dict.Age && request.query_dict.Topic %}
 {% set filteredTopicPost = blog_popular_posts('default', "activity", user_topic, user_age, 1) %}
 {# Loop through each of the post #}
 {% for blogPost in filteredTopicPost %}
 {# Check if blogpost was found #}
 {% if blogPost %}
 {# Loop through each tag of the current post #}
 {% for blogTopic in blogPost.tag_list %}
 {% if blogTopic.slug == reqParam %}
 Match Found for Blog: {{ blogPost.title }} <br>
 {% endif %}
 {% endfor %}
 {% endif %}
 {% endfor %}
 {% endfor %}
{% endif %}
 {# End set featured image #}

{# End Activity Finder Blog Listings #} 

<!--============== Regular Blog Postings ==============--> 
 {% else %}
 {% for content in contents %}

 {# Set featured image #}
 {# This checks to see if a user is opted into the blog listing editing experience. If they are it uses the conditional from the module. If they are not it uses the conditional from blog settings #}
 {% set show_featured_image = false %}
 {% if content.featured_image %}
 {% if blog.listing_page_id %}
 {% if module.featured_image %}
 {% set show_featured_image = true %}
 {% endif %}
 {% else %}
 {% if group.use_featured_image_in_summary %}
 {% set show_featured_image = true %}
 {% endif %}
 {% endif %}
 {% endif %}
 {# End set featured image #}

 <article class="blog-index__post blog-index__post--small" aria-label="Blog post summary: {{ content.name }}" id="{{ content.name|lower|replace(' ','')|replace('$','')|replace(",","")|replace("#","") }}">
 <div class="blog-index__post-inner-card{% if not content.featured_image %} no-image{% endif %}">
 {% if show_featured_image == true %}
 <a class="blog-index__post-image blog-index__post-image--small" style="background-image: url('{{ content.featured_image }}');" href="{{ content.absolute_url }}" aria-label="{% if content.featured_image_alt_text %}Featured image: {{ content.featured_image_alt_text }} - {% endif %}Read full post: {{ content.name }}">
 </a>
 {% endif %}
 <div class="blog-index__post-content blog-index__post-content--small">

 {# Tags #}
 {% if module.tags %}
 {% if content.tag_list %}
 <div class="blog-post__tags">
 {% for tag in content.tag_list %}
 <a class="blog-post__tag-link" href="{{ blog_tag_url(group.id, tag.slug) }}">{{ tag.name }}</a>{% if not loop.last %},{% endif %}
 {% endfor %}
 </div>
 {% endif %}
 {% endif %}
 {# End tags #}

 {# Title #}
 {% if module.post_title %}
 <h2><a href="{{ content.absolute_url }}">{{ content.name }}</a></h2>
 {% endif %}
 {# End title #}

 {# Summary #}
 {# This checks to see if a user is opted into the blog listing editing experience. If they are it uses the conditional from the module. If they are not it uses the conditional from blog settings #}
 {% if blog.listing_page_id %}
 {% if module.description %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% else %}
 {% if content_group.show_summary_in_listing %}
 {{ content.post_list_content|truncatehtml(100)|striptags|safe }}
 {% endif %}
 {% endif %}
 {# End summary #}

 <div class="blog-post__meta-section{% if !module.reading_minutes %} no-min{% endif %}">

 {# Reading Minutes #}
 {% if module.reading_minutes %}
 <div class="blog-post__read-minutes">
 {% set initialPostWords = content.post_body|striptags|wordcount %}
 {% set calculatedPostWords = (initialPostWords/100) * 100 %}
 {% set finishedPostWords = calculatedPostWords|divide(300)|round(2) %}
 {% set number = finishedPostWords|round %}
 {% if number < 1 %}
 {% else %}
 {{ finishedPostWords|round }} minute read
 {% endif %}
 </div>
 {% endif %}
 {# End reading minutes #}

 {# Read more button #}
 {% if module.read_more %}
 <div class="blog-post__read-more">
 <a href="{{ content.absolute_url }}">{{ module.read_more_text }}<span class="read-more__arrow">{% icon name="long-arrow-alt-right" style="SOLID" %}</span></a>
 </div>
 {% endif %}
 {# End read more button #}

 </div>
 </div>
 </div>
 </article>
 {% endfor %}
 {# End blog listing #}

 {% endunless %}

 </section>
</div>

Updating here: I managed to get this working. I will update if I have any further questions.

Thanks for the update, @TamaraH :raising_hands: Have fun building! – Jaycee