A limitation of Drupal's pager system, that comes as a disappointment to some SEO "freaks"
is the separate "page" query in the URLs to browse multiple pages. Say, a third page on a paginated node would have node/1?page=0,2 in the URL. Instead here's a method to accomplish a better looking version (like node/1/page/3). "Paging Sweet Urls" is a module that converts the "page/X" part in the URL into the actual "page" query that the pager system understands. We also need to override theme_pager_links() to set proper hyperlinks in pager navigation. Still this implementation has a limitation that it cannot handle the functionality with aliased URLs (see below). I believe, it'll need a mod_rewrite apache directive to be able to handle URL aliases. But I'll take up with it some other time.
Also, there's Clean Pagination module providing similar functionality, but not for node pages. It can, however, handle views, etc. URLs. Find the code and instructions ahead.

Download "Paging Sweet Urls" module
Contents of paging_sweet_urls.info:
name = Paging Sweet Urls
description = Clean URLs for paging module.
core = 6.x
Contents of paging_sweet_urls.module:
<?php
/**
* Implementation of hook_init().
*/
function paging_sweet_urls_init() {
$args = arg();
// We use array_pop() instead of arg(x), because the url query can be
// node/X/page/2 or node/X/view/page/2 (Default local task URL for nodes).
$page_no = array_pop($args) - 1;
$page = array_pop($args);
// Check if we are on the node/X or node/X/page/X path or node/X/view/page/X paths.
if ($args[0] == 'node' && is_numeric($args[1]) && ($args[2] != 'view' || $args[2] != 'page') && $page == 'page') {
$_GET['q'] = implode('/', $args);
$pages = explode(',', $_GET['page']);
$pages[0] = !empty($pages[0]) ? $pages[0] : 0;
$pages[1] = $page_no < 0 ? 0 : $page_no;
$_GET['page'] = implode(',', $pages);
}
}
Append this function to the theme's template.php file.
function phptemplate_pager_link($text, $page_new, $element, $parameters = array(), $attributes = array()) {
$args = arg();
$page_no = array_pop($args);
$page = array_pop($args);
// Check if we are not on the node/X or node/X/page/X path or node/X/view/page/X paths.
// Still using arg(x) for some checks to avoid popped $args for certain conditions.
if ((arg(0) != 'node' || !is_numeric(arg(1))) && (arg(2) != 'view' || (!empty($page) && $page != 'page')) && $element != 1) {
// Don't mingle when the required module is absent.
if (!module_exists('paging_sweet_urls')) {
return theme_pager_link($text, $page_new, $element, $parameters, $attributes);
}
}
$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));
}
}
$nid = arg(1);
$page_no = $page_new[1] + 1;
return l($text, "node/$nid/page/$page_no", array('attributes' => $attributes, 'query' => count($query) ? implode('&', $query) : NULL));
}
Download
27 Comments
improvement
you can override the theme function in the module, no need to modify the theme to 'complete' the module's work.
http://www.lullabot.com/articles/overriding-theme-functions-in-modules
Good idea but I believe
Good idea but I believe this wouldn't let the theme override the same function. I could even package the phptemplate_pager_link() function in the module itself, but that won't be the best.
Above all this, there are a very few cases when one would need to override that theme function. So, we can assume it safe to package the override in the module itself by either of the method.
Drupal 5 version
Hi Gurpartap,
thanks for the nice module. Since I'm still using Drupal 5, I changed some lines of your module code to make it work there.
Therefore, I only had to include a copy of the drupal 6 version of arg() and to change the last line of your template function.
Unfortunately, I couldn't attach the files to my post – so here are the changes in clear text:
Thanks and best wishes,
Oli
small fix for template function
Hi,
me again. I faced an issue on admin page that uses paging (e.g. 'admin/content/node'). In case the module exists AND arg(0) != 'node', the function continues happily.
The fix:
Always return with the standard theme_pager_link() if arg != 'node' etc. So the function should check for this no matter if the module 'paging_sweet_urls' exists or not.
Thanks for your
Thanks for your contribution. I've added this module along with paging module but it seems like the code snippet added to template.php file makes other pager not function properly. For example in the url aliases admin page, i have 3 pages but each time i click to go to 2nd page it gives me a page not found whereas it was working before. Seems like it breaks paging used on other section of the site. This was tested on Drupal 6.9
Thanks,
Interesting
The filter logic there should not allow it to happen on that page, however, I shall test it out. Thanks for reporting!
Thanks for this fix, it
Thanks for this fix, it definitely cleans up the URL. What's the best way to tweak the line below so that we display the PATHAUTO URL instead of the raw NODE url?
I'd prefer to keep using PATHAUTO URL for consistency. Thanks!
return l($text, "node/$nid/page/$page_no", array('attributes' => $attributes, 'query' => count($query) ?
Actually not this way
Handling URL aliases for this is quite tricky and may require the use of Apache directives in the .htaccess files, as Drupal in no way is aware of the aliased path (because it is converted into system path upon bootstrap).
If time permits, I'll work on it.
Will look into this
I have a Lyrics site that is all php templates. been thing about moving over to drupal and have Drupal manage all the content. This pagination module will definately help as my site must be SEO friendly
Will look into this
I have a lyrics site that is currently using php templates. I want to move over to drupal to manage the CMS. This paging module is important as the site must be url friendly.
paging
how ro create paging functionality without node value directlu created function and without query
Can't get D5 version to work
Hiya!
I tried the above change(s) to the D6 module to work with D5 and all I got was a page full of php errors upon module install conformation.
Amy suggestions?
Thanks!
-Brian
Hey! Must say a nice module,
Hey!
Must say a nice module, thanks a lot for this. I can use it on few of my sites but most of my sites have clean URLs
error on index
Your module seems to have problems with paging on the index of a drupal site e.g. if you habe 20 posts on www.domain.tld and want paging to break after 10 posts the modules generates garbage.
If $nid is NULL in "phptemplate_pager_link" you get
http://www.domain.tld/node/%252Fpage/1
it would be very handy to get
http://www.domain.tld/page/1
Any suggestions?
regards!
I must say great website. I
I must say great website. I have just googled it nice info out there.
Drupal 5 Alias Fix
We recently implemented this on a site but did however discover that the aliases were needed. So we went ahead and appended some code to the Drupal 5 version to get the aliases working. Figured it would only be fair to share the code as it might be useful to others as well as potentially useful for getting the aliases to work under Drupal 6 if they don't already.
The modified paging_sweet_urls.module file:
A packaged version is available here.
Hope this helps...
paging_sweet_urls.module not working
i have installed this module but the pagination url for pages get same link as and it shows the page not found when clicked on the page link. I am working drupal 5 and i need this urgent for my site kinldy help.
Awesome
The improvements looks really good. i like they structure of the code. I will keep these as reference, thanks.
Remove page
How to remove that "page"?
At this moment url looks like this: /something/page/3
My goal is to look like this: /something/3
Try removing the /page from
Try removing the
/pagefrom the return statement in the phptemplate theme function.No teme
Hello from Russia!
Can I quote a post in your blog with the link to you?
No problem
No problem as long as it maintains the correct reference and link.
help on the layout an d emoticons
hullo:
Very useful site for these specific Drupal use cases
On a separate topic though, I notice that you have a very interesting layout for your "Post new comment " area as well as a gr8 set of large Emoticons.
Can you plz provide a run down on how to achieve something similar? I'm starting out with Drupal and don't have much idea about how to get this type of Emoticons and also how to design the the layout of the Post Comment area.
Any help is very much appreciated.
Thanks and cheers.
You need the paging module for this to work
Hey, thanks a lot for this code, it works like a charm on one site I administer.
One important detail that you should mention is that your module works on top of the paging module. You should even modify the .info file for having that module as a requirement.
Why don't you add this to drupal.org? It will be easier to find and track improvements over there.
Cheers!
how to call
hi,
which function is need to call to apply paging. this is code work for custom modules
best refards,
Kamran Sohail
hi
ssa bai ji good 2 c a nice site from a sikh
URL alias function is must
Thanks for a nice article. I must say that ur contribution of Paging module is very valuable as it fills a big void in Drupal in terms of its innate inability to provide page breaks. For some websites it is must as it breaks big articles into more readable parts. However, in its present form, the paging module is not SEO friendly, as you urself admitted, due to that URL thing. This so called sweet URL rather makes it worse as it adds nameless meaningless words like Node and number which make no sense from SEO point of view. I wish you would rather have utilized ur efforts to somehow add URL alias aspects in paging module itself instead of this sweet URL. We are really eagerly looking forward to getting a really good tool from you. Thanks
Post new comment