Create pagination for search results template

sgoodman
Participant

I have the following custom module in my search results template. It basically finds blogs matching a tag that the user inputs. I'd like to break up my results though that it shows only maybe 10 blogs at a time and you can click next to see the next 10, instead of showing them all at once. Can anyone tell me if this is posisble and if so, how to achieve this?

 

The module is: 

{% set input = request.query_dict.term|replace(' ', ',') %}

{% set tag_posts = blog_recent_tag_posts('default', input, 100) %}
<div class = "search-results-container">
{% for tag_post in tag_posts %}
   <a href="{{tag_post.absolute_url}}" title="" class="result-link">
    <div class = "result-image-container">
      <img src="{{ tag_post.featured_image }}" alt=" image"/>
    </div>
     <div class = "result-about">
        <div class="result-tags">
         {% if tag_post.topic_list %}
        {% for topic in tag_post.topic_list %}
        {% if loop.first %}
        <span class="ed-tag">{{ topic.name }}</span>
        {% endif %}
        {% endfor %}
        {% endif %}
      </div>
       <div class="result-date">
          <p>{{ tag_post.publish_date_local_time|datetimeformat('%B %e, %Y') }}</p>
        </div>
      </div>
    <div class = "result-text-container">
      <h4>{{ tag_post.name }}</h4>
      <p class = "result-description">{{ tag_post.meta_description }}</p>

     </div>
    </a>
  {% endfor %}
</div>

Any help is really appreciated!

 

0 Upvotes
13 Replies 13
dennisedson
Community Manager

@sgoodman 

Good question!

Throwing the a-team at this for you 😀

@piersg@Kevin-C@stefen@Anton 

(I had to tag four people to complete the cast of the a-team)

2 questions:

  1. Do you guys have some ideas for @sgoodman ?
  2. Which character would you be in the A-Team?

 

Thanks,

Dennis


We are excited to announce that the Community will be launching a weekly newsletter on November 2, 2020!
Sign up today!
0 Upvotes
Kevin-C
Recognized Expert | Partner

Thanks @dennisedson

FACEMAN!

 

Hey @sgoodman 

 

This is definitely possible! And I'd be there are at least 3 ways to accomplish this. But I doubt there is an out of the box solution.

 

My first assumption would be that you can use an additional query param to communicate/simulate pages.

Then you'll want to decide if the logic is handled with JS or HUBL.

 

When you GET the blog posts is is returned as a dict. This dict is essentially raw data can them be used however you like! A mini VUE app might be cool and simple or just use hubl to build pagination UI and URLs with that query param.

 

I might have a chance this weekend to take a stab at a hubl option!

sgoodman
Participant

Hi Kevin,

 

Thanks for your reply!

 

I'm still quite new to this so not really sure how I would approach doing this. Delighted it could be a possibility though, would love to know more. 

 

Thanks,

 

Shauna

 

Anton
Key Advisor | Diamond Partner

Hi @sgoodman,

 

have you thought about the default HS pagination snippet?

so basicly it's 

 

{% if not simple_list_page %}
    <div class="pages-navigation flex-row align-center">
        {% if current_page_num > 1 %}
        {% set previous = current_page_num - 1 %}
        <a rel="nofollow" href="{{ blog_page_link(previous) }}"> 
            <img class="blue-arrow-reverse" src="" alt="blue arrow">
        </a>
      {% endif %} {% if current_page_num %}
      <a href="{{ content.post_slug }}" class="page-number current">
        <span>{{ current_page_num }}</span>
      </a>
      {% endif %} {% if next_page_num %}
      <a href="{{ blog_page_link(next_page_num) }}" class="page-number">
        <span>{{next_page_num }}</span>
      </a>
      <a rel="nofollow" href="{{ blog_page_link(next_page_num) }}">
        <img src="" alt="blue arrow">
      </a>
      {% endif %}
    </div>
				{% endif %}

 

 

The biggest difference is that this needs to be in the/ a " if not simple_list_page" statement. otherwise it won't work inside the blog. ( At least for my knowledge).

 

To do so:
Either you paste your whole module code into the {% if not simple_list_page %} loop of your blog listing(!) template or you paste the module snippet with or without the pagination part into the same loop as mentioned. If you paste the snippet without the pagination I recomend to paste it above the pagination of the loop. Otherwise the tag-listing will be below the pagination. 

 

hope this helps

 

best,

Anton

@dennisedson : MURDOCK!




check
Did my post help answer your query? Help the Community by marking it as a solution



sgoodman
Participant

Hey @Anton ,

 

This makes sense, and I think from your advice it would look like my snippet below, but what I don't understand is how does it know what page it's on, or determine how many posts appear per page? For example, with one option I will receive 40 results. I'd like it to show 10 of these results, and then when I click next, it shows the next 10 results. 

 

Not sure if this would work. What do you think?

 

{% if not simple_list_page %}
{% set input = request.query_dict.term|replace(' ', ',') %}

{% set tag_posts = blog_recent_tag_posts('default', input, 40) %}
<div class = "search-results-container">
{% for tag_post in tag_posts %}
   <a href="{{tag_post.absolute_url}}" title="" class="result-link">
    <div class = "result-image-container">
      <img src="{{ tag_post.featured_image }}" alt=" image"/>
    </div>
     <div class = "result-about">
        <div class="result-tags">
         {% if tag_post.topic_list %}
        {% for topic in tag_post.topic_list %}
        {% if loop.first %}
        <span class="ed-tag">{{ topic.name }}</span>
        {% endif %}
        {% endfor %}
        {% endif %}
      </div>
       <div class="result-date">
          <p>{{ tag_post.publish_date_local_time|datetimeformat('%B %e, %Y') }}</p>
        </div>
      </div>
    <div class = "result-text-container">
      <h4>{{ tag_post.name }}</h4>
      <p class = "result-description">{{ tag_post.meta_description }}</p>

     </div>
    </a>
  {% endfor %}
</div>



    <div class="pages-navigation flex-row align-center">
        {% if current_page_num > 1 %}
        {% set previous = current_page_num - 1 %}
        <a rel="nofollow" href="{{ blog_page_link(previous) }}"> 
            <img class="blue-arrow-reverse" src="" alt="blue arrow">
        </a>
      {% endif %} {% if current_page_num %}
      <a href="{{ content.post_slug }}" class="page-number current">
        <span>{{ current_page_num }}</span>
      </a>
      {% endif %} {% if next_page_num %}
      <a href="{{ blog_page_link(next_page_num) }}" class="page-number">
        <span>{{next_page_num }}</span>
      </a>
      <a rel="nofollow" href="{{ blog_page_link(next_page_num) }}">
        <img src="" alt="blue arrow">
      </a>
      {% endif %}
    </div>
				{% endif %}
Anton
Key Advisor | Diamond Partner

Hi @sgoodman

let's call it "HubSpot magic". 😁

If you look closely at the blog template, it's quite simple

{% if author page%}
your author page
{% elif blog post %}
your blog post layout
{% elif blog listing %}
your blog listing
{% if not simple listing %}
{# the magic part #}
everything else; and since there is only tag/topic and search result left - you can place your pagination here.
Also you can put your "if topic_list" loop here to determine it more specific
{% endif %}

 

For your question "how does HubSpot knows how much results to show?" There is a setting for that which is located here: 
settings -> website -> blog -> select your desired blog -> templates -> number of listing elements. This number will determine how many results will show in your blog listing page, topic list AND search results.

 

 

hope this helps, 

 

 

best, 

Anton




check
Did my post help answer your query? Help the Community by marking it as a solution



sgoodman
Participant

Hey @Anton,

 

Thanks for getting back to me. 

 

I get that now thanks, and it is working like this on my template for my blog listing page. However, when I do that on this page, it still displays all results instead of how much is set here. Would it be because of the function I'm using 

{% set tag_posts = blog_recent_tag_posts('default', input, 100) %}

 That it is saying to show a limit of 100 results?

 

Thanks,

 

Shauna

 

stefen
Key Advisor | Partner

@sgoodman yes, that is saying to show up to 100. I've made blog searches with that same HubL function in the past and it can work. However, since the HubSpot Site Search API came out a while back you really should be using that API for best results. You can limit it to blog posts and the default site search module has decent pagination built-in.

Stefen Phelps, Community Champion, Kelp Web Developer
sgoodman
Participant

Hey @stefen ,

 

When I remove the 100, it just shows 10 blogs (I have it selected in the settings to show 9) and then there is no pagination even though I have it added in my code as above. 

 

I agree the search API is really fantastic, but the aim I have with this is to search for blogs with specific tags, rather than keywords in the blog posts.

stefen
Key Advisor | Partner

@sgoodman ah, gotcha. I think you could still do that with the search API if you limit it to a specific URL structure like "/blog/tags*"

 

But in any case, I looked at your code and it looks like your missing some of the logic data for the pagination. In order to use default HubL pagination you're code needs to know the current page number, the total number of results per page, and then you also need a way to offset the results. You can easily do the first two by creating variables for your code to reference but I don't think there is a way to offset results with that HubL function 😞

 

So, another way you could do it is with javascript instead of using HubL. Doing it this way it will still load all the results but it will be hidden from the user. So it might improve user experience but it won't improve performance. If that's okay then you can use an if statement in your loop that would use a class to hide any items after 9. Then use a Javascript click event listener on your next page button to reveal the next 9. Give that a shot and let me know if you have any questions.

Stefen Phelps, Community Champion, Kelp Web Developer
dennisedson
Community Manager
@stefen,
You must have missed this.
What a-team character would you be?
Thanks,

Dennis


We are excited to announce that the Community will be launching a weekly newsletter on November 2, 2020!
Sign up today!
stefen
Key Advisor | Partner

@dennisedson 🤣 — I'm gonna lose points for this but i never watched the show...

Stefen Phelps, Community Champion, Kelp Web Developer
dennisedson
Community Manager

welp.  Now I have to remove you as a Community Champion, @stefen  😉

Thanks,

Dennis


We are excited to announce that the Community will be launching a weekly newsletter on November 2, 2020!
Sign up today!