Jul 20, 201711:58 AM - edited Jul 20, 201711:59 AM
Top Contributor
Create a blog filter for resource type
How can I create a filter for resource type that can be used as well as a topic filter? I have set up a custom field in my blog post that captures the resource type: {% choice "resource_type" label='Choose the resource type', value='type', choices='eBook, Case Study, Infographic, Technical, Video, White Paper', export_to_template_context=True %}
How do I use this info to be able to filter the blog posts in a dropdown? This is what I am currently using for the topic filter: <div class="dropdown"> <button onclick="myFunction()" class="dropbtn">Filter resources by ▼</button> <div id="myDropdown" class="dropdown-content"> {% post_filter "posts_by_topic" select_blog='5124593000', expand_link_text='see all', overrideable=False, filter_type='topic', label='Posts by Topic' %} </div> </div>
Can I write something similar for the resource type?
The way I do it is on the same track to what you are doing.
First, I create a custom field on the post page like you did with your choice module:
{% choice "resource_type" label='Choose the resource type', value='type', choices='eBook, Case Study, Infographic, Technical, Video, White Paper', export_to_template_context=True %}
You then want to reference this choice field's choices as your drop down:
<ul>
{% for choice in content.widgets.resource_type.body.choices %}
<li><a href="{{ group.absolute_url }}?q={{ choice|lower }}">{{ choice }}</a></li>
{% endfor %}
</ul>
Notice I looped throug the choices from the choice field, creating a list item and link for each one, and the link is the group absolute url with a query at the end which is unique to the choice.
** this next part is done on the listing page **
Now you need to grab your query:
{% set query = request.query_dict.q|lower %}
Then filter Your content based on the query:
{% if query is defined %}
{% for content in contents %}
{% set type = content.widgets.resource_type.body.value|lower %}
{% if query equals type %}
{# blog item markup for filtered results #}
{% endif %}
{% endfor %}
{% else %}
{% for content in contents %}
{# blog item markup for regular listing #}
{% endfor %}
{% endif %}
Just so you know, this is pretty heavy. I'll try to break it down for you.
In your post template code You want to place the choice module for your custom topic:
{% choice "resource_type" label='Choose the resource type', value='type', choices='eBook, Case Study, Infographic, Technical, Video, White Paper', export_to_template_context=True %}
In outer blog template, not in your post template or your listing template but the main template holding the blog module, you want to place your dropdown:
<ul>
{% for choice in content.widgets.resource_type.body.choices %}
<li><a href="{{ group.absolute_url }}?q={{ choice|lower }}">{{ choice }}</a></li>
{% endfor %}
</ul>
In your listing template code you want to set up the logic to filter your posts if there is a query, and use a basic contents for loop if there isn't a query. Like this:
{% if query is defined %}
{% for content in contents %}
{% set type = content.widgets.resource_type.body.value|lower %}
{% if query equals type %}
{# blog item markup for filtered results #}
{% endif %}
{% endfor %}
{% else %}
{% for content in contents %}
{# blog item markup for regular listing #}
{% endfor %}
{% endif %}
Check out the comment code between the {# #}. It tells you which loop works for which. The top for loops is for if there is a query, the bottom for loop is for if there isn't a query. Your mark up will probably be pretty much the same unless you want your layout to be different based on whether or not a query exists.
Where to put your this code is going to depend on where you want your blog list. In your case, it looks like your current for loop is at the top of your code:
So modify this part of your code. Specifically you want to do this:
<div class="blog-section portfolio">
<div class="blog-listing-wrapper cell-wrapper">
<div class="row same-height-parent isotope" style="display:flex; flex-wrap:wrap;">
{% if query is defined %}
{% for content in contents %}
{% set type = content.widgets.resource_type.body.value|lower %}
{% if query equals type %}
{# blog item markup for filtered results #}
<div class="span4 resource-listing-thumb original inspire-site {{ content.widgets.filter.body.value }} {{ content.widgets.resource_type.body.value }}">
<!--<a href="{{ content.absolute_url }}" class="inspire-block"> -->
<a href="{{ content.widgets.resource_link.body.value }}" class="inspire-block">
<div class="portfolio-image-wrapper">
<img class="portfolio-image" src="{{ content.widgets.thumbnail_image.body.src }}" alt="{{ content.widgets.listingimage.body.alt }}" />
<!--<span class="cta orange">See More</span> -->
</div>
<!--<span class="portfolio-title same-height"> {{ content.name}} </span> -->
<h4>{{content.name }}</h4>
</a>
</div>
{% endif %}
{% endfor %}
{% else %}
{% for content in contents %}
{# blog item markup for regular listing #}
<div class="span4 resource-listing-thumb original inspire-site {{ content.widgets.filter.body.value }} {{ content.widgets.resource_type.body.value }}">
<!--<a href="{{ content.absolute_url }}" class="inspire-block"> -->
<a href="{{ content.widgets.resource_link.body.value }}" class="inspire-block">
<div class="portfolio-image-wrapper">
<img class="portfolio-image" src="{{ content.widgets.thumbnail_image.body.src }}" alt="{{ content.widgets.listingimage.body.alt }}" />
<!--<span class="cta orange">See More</span> -->
</div>
<!--<span class="portfolio-title same-height"> {{ content.name}} </span> -->
<h4>{{content.name }}</h4>
</a>
</div>
{% endfor %}
{% endif %}
</div>
</div>
<hr >
<div class="blog-pagination">
{% if contents.total_page_count > 0 %}
{% if widget.range == 10 %}
{% set base = 10 %}
{% set loop_ = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] %}
{% else %}
{% set base = 5 %}
{% set loop_ = ['1', '2', '3', '4', '5'] %}
{% endif %}
{% set current_pg_index = last_page_num + 1 %}
{% set range_start = ((1 - current_pg_index) % base) + current_pg_index %}
{# EXTRA: calculate start of previous range and end of next
{% set range_end = range_start + (base)-1 %}
{% set previous_range_start = ((6 - current_pg_index) % base) + current_pg_index - base %}
{% if previous_range_start < 1 %}
{% set previous_range_start = 1 %}
{% endif %}
#}
<ul>
<li class="first-posts-link {% if current_pg_index <= 1 %}hide{% endif %}"><a href="{{ blog_page_link(1) }}"><i class="fa fa-angle-double-left"></i></a></li>
<li class="previous-posts-link {% if !last_page_num %}hide{% endif %}"><a href="{{ blog_page_link(last_page_num) }}"><i class="fa fa-angle-left"></i></a></li>
<span class="pg">
{% set i = range_start %}
{% for pg in loop_ %} {# effectively, for i=1 to i=base #}
{% if i <= contents.total_page_count %}
<li{% if i == current_pg_index %} class="active"{% endif %}><a href="{{ blog_page_link(i) }}">{{ i }}</a></li>
{% set i = i + 1 %}
{% endif %}
{% endfor %}
</span>
<li class="next-posts-link {% if current_pg_index == contents.total_page_count %}hide{% endif %}"><a href="{{ blog_page_link(next_page_num) }}"><i class="fa fa-angle-right"></i></a></li>
<li class="last-posts-link {% if current_pg_index == contents.total_page_count %}hide{% endif %}"><a href="{{ blog_page_link(contents.total_page_count) }}"><i class="fa fa-angle-double-right"></i></a></li>
</ul>
{% endif %}
</div>
</div>
Notice that it is the same exact mark up in bloth for loops. You can customize it if you would like. I like to add some text at the top of the filtered loop that states the query the list is filtered by. You can also add "no results" or "end of list" messages.
<script>/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("topicDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("topic-dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
Can I recycle the above code for the new resource type dropdown? For example:
You might want to go to your listing page, click the Hubspot "sprocket" in the top right corner, click developer info, and on the page that opens find your choice module by searching with ctrl (or cmd) + F for the module system name. There you will see:
1. if the module is available on the listing page outside of the contents loop
2. the structure if the module to see if you are targeting the choices correctly
You may need to just set an array with the same value as the choices in the module:
and loop through this to create your drop down menu:
<ul>
{% for choice in choicearray %}
<li><a href="{{ group.absolute_url }}?q={{ choice|lower }}">{{ choice }}</a></li>
{% endfor %}
</ul>
because you can't access content items outside of the contents loop. If you need to update or change this list of choices you will need to do it to both the choicearray and the choice module. This should create your list though.
Aug 15, 201710:35 AM - edited Aug 15, 201710:37 AM
HubSpot Employee
Create a blog filter for resource type
Hi @Woodsy, thanks for posting! It looks like the HubL correctly matches the format ourlined in our Designer's documentation for for creating a choice module so I'm wondering if the issue is perhaps related to the HTML.
Is the topic filter HTML something that you've customized, or is that the standard filter module from a HubSpot Template? Is it working for the topic?
Lastly, have you tried to adjust that code so you can use resource_type instead of topic? What did that code look like and what was the result?