diff --git a/src/site/filters/liquid.js b/src/site/filters/liquid.js index 32355a081b..dcc9f349b5 100644 --- a/src/site/filters/liquid.js +++ b/src/site/filters/liquid.js @@ -1294,7 +1294,6 @@ module.exports = function registerFilters() { //* paginatePages has limitations, it is not yet fully operational. liquid.filters.paginatePages = (page, items, aria) => { const perPage = 10; - const ariaLabel = aria ? ` of ${aria}` : ''; const paginationPath = pageNum => { @@ -1308,6 +1307,7 @@ module.exports = function registerFilters() { for (let pageNum = 0; pageNum < pagedEntities.length; pageNum++) { let pagedPage = { ...page }; + if (pageNum > 0) { pagedPage = set( 'entityUrl.path', diff --git a/src/site/includes/README-pagination.md b/src/site/includes/README-pagination.md new file mode 100644 index 0000000000..933cfbce9a --- /dev/null +++ b/src/site/includes/README-pagination.md @@ -0,0 +1,97 @@ +# Pagination in Drupal static pages + +Template: [pagination.drupal.liquid](https://github.com/department-of-veterans-affairs/content-build/blob/main/src/site/includes/pagination.drupal.liquid) + +As of March 2024, content-build is using the V3 pagination web component ([docs here](https://design.va.gov/components/pagination)). + +On static pages, we cannot dynamically swap content on the page, so a full page reload is necessary for changing between sets of paginated items. The `` component requires a `pageSelect` event handler, so we use the `updateCurrentPage` function to handle pagination. + +There are two types of pagination methods that we know of. For Resources & Support (`support_resources_article_listing.drupal.liquid`), the pages exist at `/{path}/{pageNumber}`. For Story Listings (`story_listing.drupal.liquid`) and Press Releases (`press_releases_listing.drupal.liquid`), the pages exist at `/{path}/page-{pageNumber}`. This formatting comes from Drupal. + +## Code implementation summary + +Before the `updateCurrentPage` event handler is fired, we first select the `` parent element, and set its `page` attribute based on the landing URL. ``'s `page` attribute sets the active page number on the component. + +When the `updateCurrentPage` event handler is fired, we grab the page number that was clicked (`newPage`) and couple that with the landing URL to form the next page to display. + +## Full code explanation + +From `pagination.drupal.liquid`: + +``` + // Determine whether this is a Resources & Support page, Story Listing or Press Release + // This data is passed in through those respective templates. + const addPrefixToPage = !!'{{ pagePrefix }}'; + + // Select the `` element + const pagination = document.querySelector('va-pagination'); + + // The full URL for the page we're looking at currently + const landingUrl = '{{ entityUrl }}'; + + // Make URLs uniform with a trailing slash so appending page numbers will be straightforward + if (landingUrl.charAt(landingUrl.length - 1) !== '/') { + landingUrl = `${landingUrl}/`; + } + + // Break URL into parts, remove empty parts and focus on the last part (the page number if it exists) + let urlParts = landingUrl.split('/'); + urlParts = urlParts.filter(part => part !== ''); + const lastPart = urlParts[urlParts.length - 1]; + + let currentPage; + + // If the end of the URL has a Story Listing or Press Release page format (`/{path}/page-{pageNumber}`) + // Remove the `page-` part and assign that to the `currentPage` variable + // Then remove the page data from the URL + if (lastPart.includes('page')) { + currentPage = lastPart.replace('page-', ''); + urlParts.pop(lastPart); + // If the end of the URL has a Resources & Support page format (`/{path}/{pageNumber}`) + // Assign that to the `currentPage` variable + // Then remove the page data from the URL + } else if (Number(lastPart)) { + currentPage = lastPart; + urlParts.pop(lastPart); + // If the end of the URL is not a page number, we've landed on page 1 of a paginated page + } else { + currentPage = '1'; + } + + // Assign the `page` attribute to the `` component + // This highlights the correct number on the interface + pagination.setAttribute('page', currentPage); + + // ACTUAL PAGE CLICK HANDLER + const updateCurrentPage = event => { + // Save clicked number + let newPage = event?.detail?.page; + let newEntityUrl; + + // If the page is 1, the URL should not include a page number + if (newPage === '1') { + newPage = ''; + // If Story Listing or Press Release page format (`/{path}/page-{pageNumber}`) + // add page- to the newPage variable so it can be used to create the newEntityUrl + } else if (addPrefixToPage && newPage !== '1') { + newPage = `page-${newPage}`; + } + + // Join the segmented URL back together (array is created outside the event handler) + const joinedUrl = urlParts.join('/'); + + // Prepend a forward slash if needed and assign the newEntityUrl + if (joinedUrl.charAt(0) === '/') { + newEntityUrl = `${joinedUrl}/${newPage}`; + } else { + newEntityUrl = `/${joinedUrl}/${newPage}`; + } + + // Navigate to the newEntityUrl + window.location.href = newEntityUrl; + } + + pagination.addEventListener('pageSelect', updateCurrentPage); +``` + + diff --git a/src/site/includes/pagination.drupal.liquid b/src/site/includes/pagination.drupal.liquid index c5c25e5732..9d92ed250d 100644 --- a/src/site/includes/pagination.drupal.liquid +++ b/src/site/includes/pagination.drupal.liquid @@ -1,4 +1,6 @@ {% comment %} + See README-pagination.md for details about this template + paginator { prev: url or null page { @@ -11,46 +13,68 @@ } {% endcomment %} - {% assign paginatorCount = paginator.inner | size %} {% assign totalItems = paginatorCount %} -{% if numItems %} -{% assign totalItems = numItems | times: .1 %} -{% endif%} - {% if paginator != empty and totalItems <= paginatorCount %} + + + + {% endif %} diff --git a/src/site/layouts/press_releases_listing.drupal.liquid b/src/site/layouts/press_releases_listing.drupal.liquid index 7c35b2822d..7aeee3da3f 100644 --- a/src/site/layouts/press_releases_listing.drupal.liquid +++ b/src/site/layouts/press_releases_listing.drupal.liquid @@ -94,8 +94,10 @@ larger space in the Fayette Plaza at 627 Pittsburgh Road, Suite 2, Uniontown, {% if pagedItems.length < 1 %}
No news releases at this time.
{% endif %} - - {% include "src/site/includes/pagination.drupal.liquid" %} + {% include "src/site/includes/pagination.drupal.liquid" with + entityUrl = entityUrl.path + pagePrefix = true + %} {% include "src/site/includes/above-footer-elements.drupal.liquid" %} diff --git a/src/site/layouts/story_listing.drupal.liquid b/src/site/layouts/story_listing.drupal.liquid index 1bdd4ad0cf..d42e9b1feb 100644 --- a/src/site/layouts/story_listing.drupal.liquid +++ b/src/site/layouts/story_listing.drupal.liquid @@ -27,8 +27,10 @@ {% if stories.length == 0 %}
No stories at this time.
{% endif %} - - {% include "src/site/includes/pagination.drupal.liquid" %} + {% include "src/site/includes/pagination.drupal.liquid" with + entityUrl = entityUrl.path + pagePrefix = true + %} {% include "src/site/includes/above-footer-elements.drupal.liquid" %} diff --git a/src/site/layouts/support_resources_article_listing.drupal.liquid b/src/site/layouts/support_resources_article_listing.drupal.liquid index 6a52c206b6..700cf45646 100644 --- a/src/site/layouts/support_resources_article_listing.drupal.liquid +++ b/src/site/layouts/support_resources_article_listing.drupal.liquid @@ -31,7 +31,7 @@ {{ articleTypesByEntityBundle | get: article.entityBundle }}

- {{ article.title }} +

{% assign snippet = article.fieldIntroTextLimitedHtml %} @@ -49,7 +49,7 @@ {% endfor %} - {% include "src/site/includes/pagination.drupal.liquid" %} + {% include "src/site/includes/pagination.drupal.liquid" with entityUrl = path %}
diff --git a/src/site/paragraphs/lists_of_links.drupal.liquid b/src/site/paragraphs/lists_of_links.drupal.liquid index 9a824f6c66..5124fb3b50 100644 --- a/src/site/paragraphs/lists_of_links.drupal.liquid +++ b/src/site/paragraphs/lists_of_links.drupal.liquid @@ -15,18 +15,16 @@ {% for fieldLink in vaParagraph.entity.fieldLinks %}
  • - - {{ fieldLink.title }} - +
  • {% endfor %} {% if vaParagraph.entity.fieldLink.url.path %}
  • - - {{ vaParagraph.entity.fieldLink.title }} - + + +
  • {% endif %} @@ -49,18 +47,14 @@ {% for fieldLink in vaParagraph.entity.fieldLinks %}
  • - - {{ fieldLink.title }} - +
  • {% endfor %} {% if vaParagraph.entity.fieldLink.url.path %}
  • - - {{ vaParagraph.entity.fieldLink.title }} - +
  • {% endif %} @@ -91,6 +85,6 @@
    - +
    {% endif %}