Learn and Discover Open Source with Daily Genuine Experience. From Coding, Front End, Back End, Database, and Static Site Generator.
 
 


Preface

Goal: Bringing screen reader accessability in pagination.

Table of Content

  • Preface: Table of Content

  • 1: Source

  • 2: Prepare

  • 3: Navigation: Previous and Next

  • 4: Navigation: First and Last

  • 5: Middle Pagination

  • 6: Conclusion

  • What is Next ?


1: Source

I just follow bootstrap guidance:

To hidden content visually, you simply need to add sr-only.

<span class="sr-only">Hidden Content</span>

This content can be read by screenreader.


2: Prepare

Preview: General

Nomore preview. This is screen reader.

Layout: List

As usual, change the script to use responsive partial.

  {{ $paginator := .Paginate (where .Site.Pages "Type" "post") }}
  {{ partial "pagination-screenreader.html" (dict "p" $paginator "s" .Scratch) }}

3: Navigation: Previous and Next

Just a slight modification.

    {{ if $p.HasPrev }}
      <li class="page-item blog_previous">
        <a class="page-link" href="{{ $p.Prev.URL }}" 
           aria-label="Previous" rel="prev">
          <span aria-hidden="true">&laquo;</span>
          <span class="sr-only">Previous</span>
        </a>
      </li>
    {{ else }}
      <li class="page-item blog_previous disabled">
        <span class="page-link">&laquo;</span>
      </li>
    {{ end }}
    {{ if $p.HasNext }}
      <li class="page-item blog_next">
        <a class="page-link" href="{{ $p.Next.URL }}"
           aria-label="Next" rel="next">
          <span aria-hidden="true">&raquo;</span>
          <span class="sr-only">Next</span>
        </a>
      </li>
    {{ else }}
      <li class="page-item blog_next disabled">
        <span class="page-link">&raquo;</span>
      </li>
    {{ end }}

4: Navigation: First and Last

Just a slight modification.

      {{ if gt (sub $p.PageNumber $adjacent_links) 1 }}
        <li class="page-item first">
          <a class="page-link" href="{{ $p.First.URL }}">
            <span class="sr-only">Page </span>1</a>
        </li>
      {{ end }}
      {{ if lt (add $p.PageNumber $adjacent_links) $p.TotalPages }}
        <li class="page-item last">
          <a class="page-link" href="{{ $p.Last.URL }}">
            <span class="sr-only">Page </span>{{ $p.TotalPages }}</a>
        </li>
      {{ end }}

5: Middle Navigation: Number

      <li class="page-item{{ if eq $pagenumber .PageNumber }} active{{ end }} {{ $s.Get "page_offset_class" }}">
        {{ if not (eq $pagenumber .PageNumber) }} 
          <a href="{{ .URL }}" class="page-link">
            <span class="sr-only">Page </span>{{ .PageNumber }}</a>
        {{ else }}
          <span class="page-link page-item">
            <span class="sr-only">Page </span>{{ .PageNumber }}</span>
        {{ end }}
      </li>

6: Conclusion

As a summary of this pagination tutorial, the complete code is here below:

<nav aria-label="Page navigation">
  {{ $s := .s }}
  {{ $p := .p }}

  {{ if gt $p.TotalPages 1 }}
  <ul class="pagination justify-content-center">

    <!-- Page numbers. -->
    {{- $pagenumber := $p.PageNumber -}}

    <!-- Number of links either side of the current page. -->
    {{ $adjacent_links := 2 }}

    <!-- $max_links = ($adjacent_links * 2) + 1 -->
    {{ $max_links := (add (mul $adjacent_links 2) 1) }}

    <!-- $lower_limit = 1 + $adjacent_links -->
    {{ $lower_limit := (add 1 $adjacent_links) }}

    <!-- $upper_limit = $paginator.TotalPages - $adjacent_links -->
    {{ $upper_limit := (sub $p.TotalPages $adjacent_links) }}

    <!-- Previous Page. -->
    {{ if $p.HasPrev }}
      <li class="page-item blog_previous">
        <a class="page-link" href="{{ $p.Prev.URL }}" 
           aria-label="Previous" rel="prev">
          <span aria-hidden="true">&laquo;</span>
          <span class="sr-only">Previous</span>
        </a>
      </li>
    {{ else }}
      <li class="page-item blog_previous disabled">
        <span class="page-link">&laquo;</span>
      </li>
    {{ end }}

    {{ if gt $p.TotalPages $max_links }}
      <!-- First Page. -->
      {{ if gt (sub $p.PageNumber $adjacent_links) 1 }}
        <li class="page-item first">
          <a class="page-link" href="{{ $p.First.URL }}">
            <span class="sr-only">Page </span>1</a>
        </li>
      {{ end }}

      <!-- Early (More Pages) Indicator. -->
      {{ if gt (sub $p.PageNumber $adjacent_links) 2 }}
        <li class="pages-indicator first disabled">
          <span class="page-link">...</span>
        </li>
      {{ end }}
    {{ end }}

    {{- range $p.Pagers -}}
      {{ $s.Set "page_number_flag" false }}
      {{ $s.Set "page_offset" false }}

      <!-- Complex page numbers. -->
      {{ if gt $p.TotalPages $max_links }}

        <!-- Lower limit pages. -->
        <!-- If the user is on a page which is in the lower limit.  -->
        {{ if le $p.PageNumber $lower_limit }}

          <!-- If the current loop page is less than max_links. -->
          {{ if le .PageNumber $max_links }}
            {{ $s.Set "page_number_flag" true }}
          {{ end }}

        <!-- Upper limit pages. -->
        <!-- If the user is on a page which is in the upper limit. -->
        {{ else if ge $p.PageNumber $upper_limit }}

          <!-- If the current loop page is greater than total pages minus $max_links -->
          {{ if gt .PageNumber (sub .TotalPages $max_links) }}
            {{ $s.Set "page_number_flag" true }}
          {{ end }}

        <!-- Middle pages. -->
        {{ else }}
          
          {{ if and ( ge .PageNumber (sub $p.PageNumber $adjacent_links) ) ( le .PageNumber (add $p.PageNumber $adjacent_links) ) }}
            {{ $s.Set "page_number_flag" true }}
          {{ end }}

        {{ end }}

      <!-- Simple page numbers. -->
      {{ else }}

        {{ $s.Set "page_number_flag" true }}
      {{ end }}

      {{- if eq ($s.Get "page_number_flag") true -}}
      <!-- Calculate Offset Class. -->
        {{ $s.Set "page_offset" (sub .PageNumber $p.PageNumber) }}

        {{ $s.Set "page_offset_class" "" }}
        {{- if ge ($s.Get "page_offset") 0 -}}
          {{ $s.Set "page_offset_class" (print "pagination--offset-" ($s.Get "page_offset") ) }}
        {{- else -}}
          {{ $s.Set "page_offset_class" (print "pagination--offset" ($s.Get "page_offset") ) }}
        {{- end -}}

      <!-- Show Pager. -->
      <li class="page-item{{ if eq $pagenumber .PageNumber }} active{{ end }} {{ $s.Get "page_offset_class" }}">
        {{ if not (eq $pagenumber .PageNumber) }} 
          <a href="{{ .URL }}" class="page-link">
            <span class="sr-only">Page </span>{{ .PageNumber }}</a>
        {{ else }}
          <span class="page-link page-item">
            <span class="sr-only">Page </span>{{ .PageNumber }}</span>
        {{ end }}
      </li>
      {{- end -}}
    {{ end }}

    {{ if gt $p.TotalPages $max_links }}
      <!-- Late (More Pages) Indicator. -->
      {{ if lt (add $p.PageNumber $adjacent_links) (sub $p.TotalPages 1) }}
        <li class="pages-indicator last disabled">
          <span class="page-link">...</span>
        </li>
      {{ end }}

      <!-- Last Page. -->
      {{ if lt (add $p.PageNumber $adjacent_links) $p.TotalPages }}
        <li class="page-item last">
          <a class="page-link" href="{{ $p.Last.URL }}">
            <span class="sr-only">Page </span>{{ $p.TotalPages }}</a>
        </li>
      {{ end }}
    {{ end }}

    <!-- Next Page. -->
    {{ if $p.HasNext }}
      <li class="page-item blog_next">
        <a class="page-link" href="{{ $p.Next.URL }}"
           aria-label="Next" rel="next">
          <span aria-hidden="true">&raquo;</span>
          <span class="sr-only">Next</span>
        </a>
      </li>
    {{ else }}
      <li class="page-item blog_next disabled">
        <span class="page-link">&raquo;</span>
      </li>
    {{ end }}

  </ul>
  {{ end }}

</nav>

Now the pagination tutorial is done.

I think this is all for now.


What is Next ?

Feels like tired, after finishing pagination Tutorial ? This kitten, need some sleep now.. Just like the kitten, you may need some rest too. Our pagination tutorial is finished. But you may continue to explore other challenging topic, tomorrow, or right away.

adorable kitten

There are, some interesting topic for using Bootstrap in Hugo Content, such as Header, Footer, and Navigation. Consider continue reading [ Hugo - Bootstrap - Blog Post ].

Thank you for reading.