Blog Listing With Ajax Pagination and Tag filters

PHOTO EMBED

Thu Mar 06 2025 06:36:31 GMT+0000 (Coordinated Universal Time)

Saved by @B2BForever_Dev

<div class="blog_listing">
  <div class="blog_nav col_padd">
    <div class="page-center">
      <div class="smart_hr_wrap">
        <div class="smart_hr first">
          <hr>
        </div>
        <div class="smar_btm">
          <ul>
            <li>{% set href = module.beadcrumbs.link.url.href %}
              {% if module.beadcrumbs.link.url.type is equalto "EMAIL_ADDRESS" %}
              {% set href = "mailto:" + href %}
              {% endif %}
              <a
                 {% if module.beadcrumbs.link.url.type is equalto "CALL_TO_ACTION"  %}
                 href="{{ href }}" 
                 {% else %}
                 href="{{ href|escape_url }}"
                 {% endif %}
                 {% if module.beadcrumbs.link.open_in_new_tab %}
                 target="_blank"
                 {% endif %}
                 {% if module.beadcrumbs.link.rel %}
                 rel="{{ module.beadcrumbs.link.rel|escape_attr }}"
                 {% endif %}
                 >
                {{ module.beadcrumbs.link_text }}
              </a></li>
            <span class="arrow_icn">
              <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M10.1724 7.50586L15.1768 12.5102L10.1724 17.5146" stroke="#343935" stroke-width="2.00175" stroke-linecap="round" stroke-linejoin="round"/>
              </svg>
            </span>
            <li><a href="{{group.absolute_url}}">{{group.public_title}}</a></li>
            {% if topic %}             <span class="arrow_icn">
            <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M10.1724 7.50586L15.1768 12.5102L10.1724 17.5146" stroke="#343935" stroke-width="2.00175" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            </span><li><span>{{ topic|replace('-',' ') }}</span></li>{% endif %}
          </ul>
        </div>
        <div class="smart_hr last">
          <hr>
        </div>
      </div>
    </div>
  </div>
  {% if module.image_field.src %}
  <div class="blog_featured col_padd">
    <div class="page-center">
      <div class="featured_image_wrap">
        {% set sizeAttrs = 'width="{{ module.image_field.width|escape_attr }}" height="{{ module.image_field.height|escape_attr }}"' %}
        {% if module.image_field.size_type == 'auto' %}
        {% set sizeAttrs = 'width="{{ module.image_field.width|escape_attr }}" height="{{ module.image_field.height|escape_attr }}" style="max-width: 100%; height: auto;"' %}
        {% elif module.image_field.size_type == 'auto_custom_max' %}
        {% set sizeAttrs = 'width="{{ module.image_field.max_width|escape_attr }}" height="{{ module.image_field.max_height|escape_attr }}" style="max-width: 100%; height: auto;"' %}
        {% endif %}
        {% set loadingAttr = module.image_field.loading != 'disabled' ? 'loading="{{ module.image_field.loading|escape_attr }}"' : '' %}
        <img src="{{ module.image_field.src|escape_url }}" alt="{{ module.image_field.alt|escape_attr }}" {{ loadingAttr }} {{ sizeAttrs }}>
      </div>
    </div>
  </div>
  {% endif %}
  <div class="blog_tags col_padd">
    <div class="page-center">
      <div class="top_title">
        <h3>Blog Tags</h3>
      </div>
      <div class="topics">
        {% set my_topics = blog_topics(group.id, 250) %} 
        <a href="{{group.absolute_url}}" class="category_filter">All</a> 
        <svg width="3" height="4" viewBox="0 0 3 4" fill="none" xmlns="http://www.w3.org/2000/svg">
          <circle cx="1.5" cy="2" r="1.5" fill="#B2B0B0"/>
        </svg>
        {% for item in my_topics %}
        <a href="{{ blog_tag_url(group.id, item.slug) }}" class="category_filter">{{ item }}</a>
        {% if not loop.last %}
        <svg width="3" height="4" viewBox="0 0 3 4" fill="none" xmlns="http://www.w3.org/2000/svg">
          <circle cx="1.5" cy="2" r="1.5" fill="#B2B0B0"/>
        </svg>
        {% endif %}
        {% endfor %}
      </div>
    </div>
  </div>
  <div class="blog_main col4_row">
    <div class="page-center">
      <div class="blog_list flex_row">
        {% for content in contents %}
        <div class="post_item col4">
          <div class="post_item_inner">
            {% if content.featured_image %}
            <div class="image">
              <a href="{{content.absolute_url}}">
                <img src="{{content.featured_image}}" alt="{{content.name|stiptags}}">
              </a>
            </div>
            {% endif %}
            <div class="content">
              <div class="article">Article</div>
              {% if content.title %}
              <div class="title">
                <h3>
                  <a href="{{content.absolute_url}}">{{content.title}}</a>
                </h3>
              </div>
              {% endif %}
              <div class="subtitle">
                <p>{{ content.post_list_content|safe|striptags|truncatehtml(155, '…' , false) }}</p>
              </div>
              <div class="read_more">
                <a href="{{content.absolute_url}}">Read more</a>
              </div>
            </div>
          </div>
        </div>
        {% endfor %}
      </div>
    </div>
  </div>

  <div class="blog_pagination_wrap">
    <div class="page-center">
      <div class="blog_pagination col_padd">
        <div class="blog-pagination">
          {% set page_list = [-2, -1, 0, 1, 2] %}
          {% if contents.total_page_count - current_page_num == 1 %}{% set offset = -1 %}
          {% elif contents.total_page_count - current_page_num == 0 %}{% set offset = -2 %}
          {% elif current_page_num == 2 %}{% set offset = 1 %}
          {% elif current_page_num == 1 %}{% set offset = 2 %}
          {% else %}{% set offset = 0 %}{% endif %}
          <div class="blog-pagination-center">
            {% for page in page_list %}
            {% set this_page = current_page_num + page + offset %}
            {% if this_page > 0 and this_page <= contents.total_page_count %}
            <a href="{{ blog_page_link(this_page) }}" class="page-link {% if this_page == current_page_num %}active{% endif %}">{{ this_page }}</a>
            {% endif %}
            {% endfor %}
          </div>
        </div>
      </div>
    </div>
  </div>

  {% require_js %}
  <script>
    $(document).ready(function () {
      function setActiveCategory(categoryURL) {
        $('.category_filter').removeClass('active');
        $('.category_filter[href="' + categoryURL + '"]').addClass('active');
      }

      function setActivePage(pageURL) {
        $('.page-link').removeClass('active');

        var foundMatch = false;
        $('.page-link').each(function () {
          if ($(this).attr('href') === pageURL) {
            $(this).addClass('active');
            foundMatch = true;
          }
        });

        // If no match found (like when on the first page without page number in URL), set first page active
        if (!foundMatch) {
          $('.page-link').first().addClass('active');
        }
      }

      function updateBlogPosts(url) {
        $('.blog_main').load(url + " .blog_main .blog_list", function () {
          loadPagination(url);
        });
      }

      function loadPagination(url) {
        $('.blog_pagination_wrap').load(url + " .blog_pagination_wrap", function () {
          setActivePage(window.location.href);
        });
      }

      // Handle category click event
      $('.category_filter').on('click', function (e) {
        e.preventDefault();
        var categoryURL = $(this).attr('href');

        history.pushState(null, null, categoryURL);
        setActiveCategory(categoryURL);
        updateBlogPosts(categoryURL);
      });

      // Handle pagination click event
      $(document).on('click', '.blog-pagination a', function (e) {
        e.preventDefault();
        var pageURL = $(this).attr('href');

        history.pushState(null, null, pageURL);
        setActivePage(pageURL);
        updateBlogPosts(pageURL);
      });

      // Preserve active states on load
      setActiveCategory(window.location.href);
      setActivePage(window.location.href);
    });

  </script>
  {% end_require_js %}

</div>
content_copyCOPY