Pagination links for alphabetically sorted blog

Occasional Contributor

Hi,

 

I'm creating an online glossary of terms using a HubSpot blog module. From reading the excellent posts by @Jsum and others, I was able to figure out how to create a listing page that sorts the posts alphabetically by name / title.

 

However, I have not been able to create the "previous page / next page" pagination for the bottom of each blog post page that works alphabetically. The issue is that HubSpot's {{ content.previous_post_name }} and {{ content.next_post_name }} functions seem to be based on {{ content.id }} order and can't be changed to work in alphabetical sort order.

 

Usual blog page pagination looks something like this:

 

{#--- Previous Page link ---#}
<a href="{{ blog_page_link(last_page_num) }}"><i class="fa fa-angle-left"></i> {{ content.previous_post_name }}</a>

{#--- Next Page link ---#} <a href="{{ blog_page_link(next_page_num) }}">{{ content.next_post_name }} <i class="fa fa-angle-right"></i></a>

To address this, I created a new list/dict that creates and adds an alphabetical order index to other existing {{ content }} information. However, once I can determine what that current blog page's order is in the alphabetical order, I can't find a way to use the information outside the for loop (which I need to use to replace {{ content.previous_post_name }} and {{ content.next_post_name }} in the link text.

 

Here's my current code:

  {% set post_list = {} %}  
  {% set int_var myindex = 0 %}
  {% set int_var current_post_index = 0 %}
  
  {% set posts = blog_recent_posts('default', 10) %}
  
  {% for post in posts|sort(False, False, 'name') %}
 
      <p>loop.index: {{ loop.index }} <a href="{{ post.absolute_url }}">{{ post.name }}</a>  post.id: {{ post.id }} </p>
      {% set post_list2 = post_list.update({"loop.index": loop.index, "post.id": post.id, "post.name": post.name, "post.absolute_url": post.absolute_url}) %}   
 
      {% if post.id == content.id %}
          <p><b>TRUE!</b>  </p>
 
          {% set current_post_index = loop.index %}    

      {% endif %}

    <p>This works! Current page's alphabetical order / index is: {{ current_post_index }}</p>

  {% endfor %}
  <hr>
  <p>This does NOT work! Current page's alphabetical order / index is: {{ current_post_index }}</p>

BTW, I looked into using HubDB for this but want to have a Comments section on each page and didn't know how to do that.

 

Please help is you can!

 

Kurt

Reply
0 Upvotes
5 Replies
Occasional Contributor

Hi @Jsum,

 

Thank you. I already tried @tjoyce's macro approach but still couldn't access the dict /array values outside the for loop. I could never access the alphabetical index variable / counter of the current page from outside the for loop.

 

I'm traveling for the next few days but will try again when I return to the office.

 

Kurt

@KurtShuler

Top Advisor

@KurtShuler,

 

Sorry, I had my hands full the other day.

 

You should pay attention to how he creates the {{ counter }} variable:

{% set variable_1 = "" %}
{% set variable_2 = '"" %}

{% for item in loop %}

    {% set variable_ 1 = item.name %}
    {% set variable_ 2 = item.description %}

{% endfor %}

{{ variable_1 }}
{{ variable_2 }}

Create the variables outside the loop, change their value in the loop, then you can use them outside the loop with their new value.

 

You should remove 'int_var' from yoru variables though. I've never used that and I can't find an examples of use in the jinja2 or Hubl docs so my guess is your variables are broken.

 

Also, a variable with one value in a loop will end with the last value. If you want a collection of values you'll want to set your varaiable to a list:

 

{% set titles = [] %}

{% for content in contents %} 
  {% set x = title.append(content.name) %}
{% endfor %}

{{ title }}

what this does is add the title of each blog in a contents loop to a list called 'titles'. you could now loop through this list:

{%  for title in titles %}
    {{ title }}
{% endfor %}

or target an index in the list:

{{ title[0] }}

Try this though. The only built in pagination in Hubspot is only useable with/in a blog template specifcailly for the contents loop, but I was able to create my own using a recent posts function and url queries:

{% set posts = blog_recent_posts('default', 200) %}
{% set query = request.query_dict.page %}
{% set controlNumber = 3 %}
{% set base = query * controlNumber %}
{% set step = base - controlNumber %}
{% set page = posts[step: base] %}


{% for p in page %}
  {{loop.index}}: {{ p.id }}<br>
{% endfor %}
<br><br><br>

{% macro urlContstructor(i) %}

    {% set find = ("page=" + query)|string %}
    {% set replace = "page=" + (query|int + i)|string %}
 
    {{ request.full_url + request.query|replace(find, replace ) }}
 
{% endmacro %}

<br><br><br>

<a href="{{ urlContstructor(-1) }}">prev</a>

<a href="{{ urlContstructor(1) }}">next</a>

You should be able to copy and paste this, unfortunately you cannot play with queries in hubl in the module previewer so you have to create page from a template containing this code.  It's best to use a live page, I didn't so I am not sure if the link urls work, but should be close. In the page preview it parses the urls from the hubl tokens without their protocol, unless I add the protocol then it prints twice. didn't want to publish the page. 

 

This adds a "page=" query to the url. The value of this is set as "query", "controlNumber" is the pagination number. Multiply it by the query to get the stop point for the slice, and subtract the controlNumber from that new value to get the start for the slice. 

 

You can see in the loop that I am outputting the loop index and the item id. You will see that the loop index always starts at 1 and goes to your controlNumber, however if you change the query in the url you will see the blog id's change. 

 

Ideally the links would have  url that take you to the same page but change the value of the page query which would refilter the blog post collection that is output, but wasn't able to test it. 

Occasional Contributor

Jsum,

 

Thanks for the advice. I'm at CES this week but will hack away some more starting Friday. I'll start by getting your examples working on my end, then iterate/hack to create the alphabetical pagination. I'll post the working code when I get it done!

 

Kurt

Occasional Contributor

@Jsum,

 

Thanks for your help! I did it!

 

The code is below. I'm not sure this is the most efficient way to do this, because I cycle through the blog_recent_posts function twice.

 

Here's the code:

 

  {#--------------- CREATE MASTER ALPHABETIZED LIST OF POSTS WITH URL AND ID  ----------------#} 
      {#--- initialize list of posts (which will be similar to Python list of lists?) ---#}  
      {% set new_list = [] %}

      {#---  get HubSpot list of posts sorted using HubSpot blog_recent_posts function  ----------------#} 
      {% set rec_posts = blog_recent_posts('default', 200) %}
      
      {#--- sort HubSpot list by name using HubSpot sort filter----------------#} 
      {% for rec_post in rec_posts|sort(False, False, 'name') %}
          
          {#---  add each post name, URL and ID to my new_list list  ----------------#} 
          {% set new_list2 = new_list.append([rec_post.name, rec_post.absolute_url, rec_post.id]) %}
   
      {% endfor %}
  
 
  {#--------------- FIND THE ALPHABEITCAL LOCATION INDEX OF CURRENT POST IN PREVIOUS LIST AND CREATE PREVIOUS AND NEXT PAGE LINKS ----------------#}  
  
      {#--- initialize a new list of posts ---#}  
      {% set post_list = [] %}  
  
      {#--- initialize variables outside of for loop ---#}  
      {% set current_post_index = 0 %}
      {% set next_post_index = 0 %}
      {% set previous_post_index = 0 %}
      {% set current_post_name = NULL %}
      {% set current_post_url = NULL %}  
      
  
      {#---  get HubSpot list of posts sorted using HubSpot blog_recent_posts function  ----------------#} 
      {% set posts = blog_recent_posts('default', 200) %}
      
      {#--- sort HubSpot list by name using HubSpot sort filter----------------#}   
      {% for post in posts|sort(False, False, 'name') %}
         
              {#--- if post in loop matches the current post ---#}
              {% if post.id == content.id %}
                  {#--- create vars for current post based on vars in the loop ---#}
                  {% set current_post_index = loop.index0 %} 
                  {% set current_post_name = post.name %}  
                  {% set current_post_url = post.absolute_url %}    
            
                  {#--- to detemine next post page in alphabetical, test if current post index is last in index ---#}
                  {% if current_post_index == loop.length|add(-1) %}
                      {#--- if so, then make it the first page in alphabetical list ---#}
                      {% set next_post_index = 0 %}
                  {% else %}
                      {#--- else, make it the next page in the list ---#}
                      {% set next_post_index = current_post_index|add(1) %}
                  {% endif %}
  
              {#--- calculate previous posts index ---#}
              {% set previous_post_index = current_post_index|add(-1) %}
  
              {#--- display the pagination text ---#}
                  <div class="act-fusapedia-pagination">
                      <a class="act-fusapedia-pagination-previous" href="{{ new_list[previous_post_index][1] }}"><i class="fa fa-angle-left"></i> {{ new_list[previous_post_index][0] }}</a>
                      <a class="act-fusapedia-pagination-all" href="{{ group.absolute_url }}/all">INDEX</a>
                      <a class="act-fusapedia-pagination-next" href="{{ new_list[next_post_index][1] }}">{{ new_list[next_post_index][0] }} <i class="fa fa-angle-right"></i></a>
                  </div>
  
              {% endif %}

        {% endfor %}

Thanks again!

 

Kurt