- Log in to post comments
If you want to optimize your Drupal site pages to have HTML link elements rel=”next” and rel=”prev” to indicate the relationship between component URLs in a paginated series here is what you need to do (note that this example is written for Drupal 6, but Drupal 7 solution should be similar).
Drupal pager rendering is controlled by couple of theme functions theme_pager, theme_pager_first, theme_pager_last, theme_pager_previous, theme_pager_next, theme_pager_link. Of all this theme function best is to override theme_pager_link which you will add into your template.php theme file. You just to change end of theme_pager_link function and add next lines of code:
<?php
$query = count($query) ? implode('&', $query) : NULL;
// Pagination with rel=“next” and rel=“prev”. Does not support well multiple
// pagers on the same page - it will create relnext and relprev links
// in header for that case only for the first pager that is rendered.
static $rel_prev = FALSE, $rel_next = FALSE;
if (!$rel_prev && $text == t('‹ previous')) {
$rel_prev = TRUE;
drupal_set_html_head('<link rel="prev" href="' . url($url, array('query' => $query)) . '" />');
}
if (!$rel_next && $text == t('next ›')) {
$rel_next = TRUE;
drupal_set_html_head('<link rel="next" href="' . url($url, array('query' => $query)) . '" />');
}
return l($text, $url, array('attributes' => $attributes, 'query' => $query));
?>
So your whole function should look like this:
<?php
function theme_pager_link($text, $page_new, $element, $parameters = array(), $attributes = array()) {
$page = isset($_GET['page']) ? $_GET['page'] : '';
if ($new_page = implode(',', pager_load_array($page_new[$element], $element, explode(',', $page)))) {
$parameters['page'] = $new_page;
}
$query = array();
if (count($parameters)) {
$query[] = drupal_query_string_encode($parameters, array());
}
$querystring = pager_get_querystring();
if ($querystring != '') {
$query[] = $querystring;
}
// Set each pager link title
if (!isset($attributes['title'])) {
static $titles = NULL;
if (!isset($titles)) {
$titles = array(
t('« first') => t('Go to first page'),
t('‹ previous') => t('Go to previous page'),
t('next ›') => t('Go to next page'),
t('last »') => t('Go to last page'),
);
}
if (isset($titles[$text])) {
$attributes['title'] = $titles[$text];
}
else if (is_numeric($text)) {
$attributes['title'] = t('Go to page @number', array('@number' => $text));
}
}
$query = count($query) ? implode('&', $query) : NULL;
// Pagination with rel=“next” and rel=“prev”. Does not support well multiple
// pagers on the same page - it will create relnext and relprev links
// in header for that case only for the first pager that is rendered.
static $rel_prev = FALSE, $rel_next = FALSE;
if (!$rel_prev && $text == t('‹ previous')) {
$rel_prev = TRUE;
drupal_set_html_head('<link rel="prev" href="' . url($url, array('query' => $query)) . '" />');
}
if (!$rel_next && $text == t('next ›')) {
$rel_next = TRUE;
drupal_set_html_head('<link rel="next" href="' . url($url, array('query' => $query)) . '" />');
}
return l($text, $url, array('attributes' => $attributes, 'query' => $query));
}
?>
Note that this solution will work well when you have only one pager on your page, but it will not work well in situation if you have multiple pagers on your page this code will create rel prev/next head links only for first rendered pager.
Comments
Drupal 7 code
Thanks for this, for Drupal 7 I used drupal_add_html_head_link:
drupal_add_html_head_link(array('rel' => 'next', 'href' => url($_GET['q'], array('query' => $query))));
I also removed the following line as it was causing an error:
$query = count($query) ? implode('&', $query) : NULL;
I've not been able to get
I've not been able to get this to work on Drupal 7. Maybe I'm putting the code into the wrong file? Can someone provide very explicit instructions (in the form of: in this file, insert this code)?
Thanks!
Updated to Drupal 7
http://www.netentropy.com/how-create-pagination-uses-relnext-and-relprev-drupal-7
D7 solution
D7 solution:
add two section code in theme_pager function(include/pager.inc), we could hook in template.php
1.rel="prev"
if ($li_previous) {
$items[] = array(
'class' => array('prev'),//pager-previous=>prev
'data' => $li_previous,
);
//Pages: rel="next" & rel="prev" on paginated pages
preg_match("/<a.+?href=['\"](.+)['\"]>/i", $li_previous, $prev_match);
$prev_link = invmodule_url_rewrite($prev_match[1]);
drupal_add_html_head_link(array('rel' => 'prev', 'href' => $prev_link));
}
2.rel="next"
if ($li_next) {
$items[] = array(
'class' => array('next'),//pager-next=>next
'data' => $li_next,
);
//Pages: rel="next" & rel="prev" on paginated pages
preg_match("/<a.+?href=['\"](.+)['\"]>/i", $li_next, $next_match);
$next_link = invmodule_url_rewrite($next_match[1]);
drupal_add_html_head_link(array('rel' => 'next', 'href' => $next_link));
}
Fix to invmodule_url_rewrite()
invmodule_url_rewrite() gives not defined error. You can replace this line to get it working:
$next_link = invmodule_url_rewrite($next_match[1]);
with this line:
$next_link = $GLOBALS['base_url'] . $next_match[1];
Clean Pagination Drupal Module
Drupal 7 has a module called Clean Pager: https://drupal.org/project/cleanpager, that can automatically accomplish this!
Pager links disabled after implementing revised script
Hi,
Thank you for this post. I replaced the function theme_pager_link in the /includes/pager.inc file with the one provided by NetEntropy and the rel="prev" and rel="next" appears correctly in the source code now:
<link rel="prev" href="/blog-post/" />
<link rel="next" href="/blog-post/?page=2" />
But unfortunately, the pager links at the bottom no longer work. The numbers appear at the bottom, but I can't click on them to get to the next page. Has anyone else run into this? Any guidance would be great.
Thanks!
buttons not working
Hi ForTheWin, were you able to find a fix for the buttons not working?
Add new comment | pivica.me
Hello would you mind sharing which blog platform you're working with?
I'm looking to start my own blog in the near future but I'm having a tough time selecting
between BlogEngine/Wordpress/B2evolution and
Drupal. The reason I ask is because your design and style seems different
then most blogs and I'm looking for something completely unique.
P.S Apologies for being off-topic but I had to ask!
Yeah this is Drupal 7 using
A slightly improved rewrite for v6 ?
function yourtheme_pager_link($text, $page_new, $element, $parameters = array(), $attributes = array()) {
// Pagination with rel=“next” and rel=“prev”. Does not support well multiple
// pagers on the same page - it will create relnext and relprev links
// in header for that case only for the first pager that is rendered.
static $rel_prev = FALSE, $rel_next = FALSE;
if (!$rel_prev && $text == t('‹ previous')) {
$rel_prev = TRUE;
drupal_set_html_head('<link rel="prev" href="' . url($url, array('query' => $query)) . '" />');
}
if (!$rel_next && $text == t('next ›')) {
$rel_next = TRUE;
drupal_set_html_head('<link rel="next" href="' . url($url, array('query' => $query)) . '" />');
}
return theme_pager_link($text, $page_new, $element, $parameters = array(), $attributes = array());
}
This way as long as signature to theme_pager_link does not change you are ok in the event of the function itself changing
It wouldn't work properly for
It wouldn't work properly for me as $url wasn't defined. This helped:
$url = $_GET['q'];