Last active
August 19, 2020 15:42
-
-
Save jameswilson/678e7f9fcc50cc92fbeb to your computer and use it in GitHub Desktop.
Drupal 7 Accessible Pager (Backport from Drupal 8)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Place this file your theme's "templates" folder. | |
/** | |
* @file | |
* Theme override to display a pager. | |
* | |
* This is a backport of pager.html.twig from Drupal 8 to Drupal 7, which add | |
* accessibility support for WCAG 2.0 section 2.4.9. | |
* | |
* Available variables: | |
* - items: List of pager items. | |
* The list is keyed by the following elements: | |
* - first: Item for the first page; not present on the first page of results. | |
* - previous: Item for the previous page; not present on the first page | |
* of results. | |
* - next: Item for the next page; not present on the last page of results. | |
* - last: Item for the last page; not present on the last page of results. | |
* - pages: List of pages, keyed by page number. | |
* Sub-sub elements: | |
* items.first, items.previous, items.next, items.last, and each item inside | |
* items.pages contain the following elements: | |
* - href: URL with appropriate query parameters for the item. | |
* - attributes: A keyed list of HTML attributes for the item. | |
* - text: The visible text used for the item link, such as "‹ previous" | |
* or "next ›". | |
* - current: The page number of the current page. | |
* - ellipses: If there are more pages than the quantity allows, then an | |
* ellipsis before or after the listed pages may be present. | |
* - previous: Present if the currently visible list of pages does not start | |
* at the first page. | |
* - next: Present if the visible list of pages ends before the last page. | |
* | |
* @see template_preprocess_pager() | |
*/ | |
?> | |
<?php if (count($items)) : ?> | |
<nav class="item-list item-list--pager" role="navigation" aria-labelledby="pagination-heading"> | |
<h4 id="pagination-heading" class="element-invisible"><?= t('Pagination') ?></h4> | |
<ul class="pager"> | |
<?php // Print first item if we are not on the first page. ?> | |
<?php if ($items['first']) : ?> | |
<li class="pager-first"> | |
<a href="<?= $items['first']['href'] ?>" title="<?= t('Go to first page') ?>"<?= $items['first']['attributes'] ?>> | |
<span class="element-invisible"><?= t('First page') ?></span> | |
<span aria-hidden="true"><?= t('« first') ?></span> | |
</a> | |
</li> | |
<?php endif; ?> | |
<?php // Print previous item if we are not on the first page. ?> | |
<?php if ($items['previous']) : ?> | |
<li class="pager-previous"> | |
<a href="<?= $items['previous']['href'] ?>" title="<?= t('Go to previous page') ?>" rel="prev"<?= $items['previous']['attributes'] ?>> | |
<span class="element-invisible"><?= t('Previous page') ?></span> | |
<span aria-hidden="true"><?= t('‹ previous') ?></span> | |
</a> | |
</li> | |
<?php endif; ?> | |
<?php // Add an ellipsis if there are further previous pages. ?> | |
<?php if ($ellipses['previous']) : ?> | |
<li class="pager-ellipsis" role="presentation">…</li> | |
<?php endif; ?> | |
<?php // Now generate the actual pager piece. ?> | |
<?php foreach($items['pages'] as $key => $item) : ?> | |
<li class="pager-item<?= $current == $key ? ' pager-current' : '' ?>"> | |
<?php if ($current == $key) : ?> | |
<?php $title = t('Current page'); ?> | |
<?php else : ?> | |
<?php $title = t('Go to page @key', array('@key' => $key)); ?> | |
<?php endif; ?> | |
<a href="<?= $item['href'] ?>" title="<?= $title ?>" class="<?= $current == $key ? ' active' : '' ?>"> | |
<span class="element-invisible"> | |
<?= $current == $key ? t('Current page') : t('Page'); ?> | |
</span><?= $key ?> | |
</a> | |
</li> | |
<?php endforeach; ?> | |
<?php // Add an ellipsis if there are further next pages. ?> | |
<?php if ($ellipses['next']) : ?> | |
<li class="pager-ellipsis" role="presentation">…</li> | |
<?php endif; ?> | |
<?php // Print next item if we are not on the last page. ?> | |
<?php if ($items['next']) : ?> | |
<li class="pager-next"> | |
<a href="<?= $items['next']['href'] ?>" title="<?= t('Go to next page') ?>" rel="next"<?= $items['next']['attributes'] ?>> | |
<span class="element-invisible"><?= t('Next page') ?></span> | |
<span aria-hidden="true"><?= t('next ›') ?></span> | |
</a> | |
</li> | |
<?php endif; ?> | |
<?php // Print last item if we are not on the last page. ?> | |
<?php if ($items['last']) : ?> | |
<li class="pager-last"> | |
<a href="<?= $items['last']['href'] ?>" title="<?= t('Go to last page') ?>"<?= $items['last']['attributes'] ?>> | |
<span class="element-invisible"><?= t('Last page') ?></span> | |
<span aria-hidden="true"><?= t('last »') ?></span> | |
</a> | |
</li> | |
<?php endif; ?> | |
</ul> | |
</nav> | |
<?php endif; ?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Paste the code below in your theme's template.php file. | |
/** | |
* Implements hook_preprocess_pager(). | |
* | |
* This is a backport of template_preprocess_pager from Drupal 8. | |
*/ | |
function template_preprocess_pager(&$variables) { | |
$element = $variables['element']; | |
$parameters = $variables['parameters']; | |
$quantity = $variables['quantity']; | |
$route_name = $_GET['q']; | |
global $pager_page_array, $pager_total; | |
// Nothing to do if there is only one page. | |
if ($pager_total[$element] <= 1) { | |
return; | |
} | |
$tags = $variables['tags']; | |
// Calculate various markers within this pager piece: | |
// Middle is used to "center" pages around the current page. | |
$pager_middle = ceil($quantity / 2); | |
// current is the page we are currently paged to | |
$pager_current = $pager_page_array[$element] + 1; | |
// first is the first page listed by this pager piece (re quantity) | |
$pager_first = $pager_current - $pager_middle + 1; | |
// last is the last page listed by this pager piece (re quantity) | |
$pager_last = $pager_current + $quantity - $pager_middle; | |
// max is the maximum page number | |
$pager_max = $pager_total[$element]; | |
// End of marker calculations. | |
// Prepare for generation loop. | |
$i = $pager_first; | |
if ($pager_last > $pager_max) { | |
// Adjust "center" if at end of query. | |
$i = $i + ($pager_max - $pager_last); | |
$pager_last = $pager_max; | |
} | |
if ($i <= 0) { | |
// Adjust "center" if at start of query. | |
$pager_last = $pager_last + (1 - $i); | |
$i = 1; | |
} | |
// End of generation loop preparation. | |
// Create the "first" and "previous" links if we are not on the first page. | |
if ($pager_page_array[$element] > 0) { | |
$items['first'] = array(); | |
$options = array( | |
'query' => pager_query_add_page($parameters, $element, 0), | |
); | |
$items['first']['href'] = url($route_name, $options); | |
if (isset($tags[0])) { | |
$items['first']['text'] = $tags[0]; | |
} | |
$items['previous'] = array(); | |
$options = array( | |
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] - 1), | |
); | |
$items['previous']['href'] = url($route_name, $options); | |
if (isset($tags[1])) { | |
$items['previous']['text'] = $tags[1]; | |
} | |
} | |
if ($i != $pager_max) { | |
// Add an ellipsis if there are further previous pages. | |
if ($i > 1) { | |
$variables['ellipses']['previous'] = TRUE; | |
} | |
// Now generate the actual pager piece. | |
for (; $i <= $pager_last && $i <= $pager_max; $i++) { | |
$options = array( | |
'query' => pager_query_add_page($parameters, $element, $i - 1), | |
); | |
$items['pages'][$i]['href'] = url($route_name, $options); | |
if ($i == $pager_current) { | |
$variables['current'] = $i; | |
} | |
} | |
// Add an ellipsis if there are further next pages. | |
if ($i < $pager_max + 1) { | |
$variables['ellipses']['next'] = TRUE; | |
} | |
} | |
// Create the "next" and "last" links if we are not on the last page. | |
if ($pager_page_array[$element] < ($pager_max - 1)) { | |
$items['next'] = array(); | |
$options = array( | |
'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1), | |
); | |
$items['next']['href'] = url($route_name, $options); | |
if (isset($tags[3])) { | |
$items['next']['text'] = $tags[3]; | |
} | |
$items['last'] = array(); | |
$options = array( | |
'query' => pager_query_add_page($parameters, $element, $pager_max - 1), | |
); | |
$items['last']['href'] = url($route_name, $options); | |
if (isset($tags[4])) { | |
$items['last']['text'] = $tags[4]; | |
} | |
} | |
$variables['items'] = $items; | |
} | |
/** | |
* Backport of pager_query_add_page() from Drupal 8. | |
*/ | |
function pager_query_add_page(array $query, $element, $index) { | |
global $pager_page_array; | |
// Determine the first result to display on the linked page. | |
$page_new = pager_load_array($index, $element, $pager_page_array); | |
$page = isset($_GET['page']) ? $_GET['page'] : ''; | |
if ($new_page = implode(',', pager_load_array($page_new[$element], $element, explode(',', $page)))) { | |
$query['page'] = $new_page; | |
} | |
// Merge the query parameters passed to this function with the parameters | |
// from the current request. In case of collision, the parameters passed | |
// into this function take precedence. | |
if ($current_request_query = pager_get_query_parameters()) { | |
$query = array_merge($current_request_query, $query); | |
} | |
return $query; | |
} |
I've created an issue on Drupal.org to get this officially backported: https://www.drupal.org/node/2550929
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I believe I've not correctly written the functionality to allow proper ability to override the "tags" text. (first, last, next, previous)
^ doesn't properly take the $items['last']['text'] into account..