Extension talk:PageAfterAndBefore

Add topic
From mediawiki.org
Latest comment: 11 years ago by Verdy p in topic Lack of Looping

Any ideas on how to link to the previous or next page? When I surround a {{}} command in [[ ]], it somehow displays as a heading:

[[{{#pagebefore:}}]] | [[{{#pageafter:}}]]

you could try the latest version; get it here. Jean-Lou Dupont 23:59, 23 August 2007 (UTC)Reply

Trouble with usage[edit]

Could you give an example of how to insert this into a wiki page? I don't understand the instructions. I've tried:

{{#pagebefore: [context]|Main|Title_of_my_Page|Category_Name }}

And all I get is the final page within that category. Help?

The brackets [ ] mean optional parameters.
Some examples:
Jean-Lou Dupont 11:44, 15 November 2007 (UTC)Reply

MySQL problem with apostrophes (RESOLVED)[edit]

Whenever I try to use this extension on an article that has an apostrophe in the title, the saved page displays the following error message:

A database query syntax error has occurred. This may indicate a bug in the software. The last attempted database query was:
(SQL query hidden)
from within function "". MySQL returned error "1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[title of article after the apostrophe]')=-1 AND `wiki_categorylinks`.cl_to = 'Tran' at line 1 (mysql.[my database])".

Do you know how this can be fixed?


Many thanks to you! I had forgotten to 'escape' properly the parameters before passing them to the DB layer -> potential for SQL injection attacks. I have fixed the issue in v1.0.2. Just do pear upgrade mediawiki/pageafterandbefore (assuming you are using PEAR). Jean-Lou Dupont 16:36, 20 November 2007 (UTC)Reply


After looking through the code (although I am not fluent in PHP) and what documentation there is, I am baffled as to the actual functionality of the filtercurrent parameter.

If I set filtercurrent=yes in a call to firstpage on the first page of the category, it has the same behavior as if filtercurrent is not set.

It appears that filtercurrent is supposed cause firstpage to do nothing if it is called on the first page of the set. Instead, it always returns the name of the first article in the set, no matter what.

What am I not understanding? —Twisted86 08:08, 21 December 2007 (UTC)Reply

I have added some clarifications text on the main page. Hope this helps. Jean-Lou Dupont 14:03, 21 December 2007 (UTC)Reply

Thanks for the clarification. So, filtercurrent is supposed to do what I thought it was supposed to. Unfortunately, if I call #firstpage on the first page of the set, it returns the name of the article regardless of what filtercurrent is set to be.

A bug perhaps? Thanks. —Twisted86 22:15, 21 December 2007 (UTC)Reply

Somewhat ;-) The format of the article title was the database one (i.e. with the underscores instead of the spaces). I have changed this to the normal article title format. Please try it out in version 1.0.3. Jean-Lou Dupont 00:44, 22 December 2007 (UTC)Reply
Oooppss... I think I broke something in the process... please wait for my signal before trying 1.0.3. Sorry! Jean-Lou Dupont 01:19, 22 December 2007 (UTC)Reply


The extension gets confused when there is a page with a {{DEFAULTSORT}} magic word in use. The page in question behaves just fine, but the next page after it does not link properly. —Twisted86 09:54, 21 December 2007 (UTC)Reply

I've looked succinctly at the MediaWiki parser code but I can't really figure out (in two minutes) what would be the expected behavior if I were to add support for DEFAULTSORT; what would be yours? Jean-Lou Dupont 14:08, 21 December 2007 (UTC)Reply

Fair enough. I would expect PAAB to respect DEFAULTSORT, so that articles in a given category would be ordered by PAAB as follows:

Article Comment

What presently happens is that Bar nexts to Fubar and Foobar prevs to Fubar, but calling #pagebefore or #pagenext in Fubar returns immediately with no article name (#firstpage and #lastpage work just fine).

Thanks for the speedy reply. —Twisted86 22:01, 21 December 2007 (UTC)Reply

I am still unclear on how I am going to address this limitation (if at all). It seems to me I would need to perform more processing on the database on each call to the parser function. If I get sufficient demand for this feature, I'll consider implementing it. Jean-Lou Dupont 00:47, 22 December 2007 (UTC)Reply

If I knew more about PHP programming and MySQL, I'd make an intelligent suggestion. I think I can come up with a wiki-kluge in the meanwhile. Thanks. —Twisted86 01:52, 22 December 2007 (UTC)Reply

I very much need this feature. After a brief glance at the code I assumed that changing the ORDER BY clause of the SQL to cl_sortkey instead of page_title would do the trick, but it in fact seemed to produce unexpected results the exact nature of which I couldn't even determine. --Agrestis 16:06, 25 October 2009 (UTC)Reply

In fact the current code is even more tricky, because:
  • It does not only use an SQL ORDER BY clause, to order a list of at most 2 items (2 items are returned only to support the external removal of the curently viewed page if filtercurrent=yes, but in my opinion is it overkill, it should directly add a "AND title<>$current" in the WHERE clause in the SQL query, so that it will use "LIMIT 1" always in that query, or even better using an SQL MIN (or MAX) aggregate in "HAVING cl_key=MIN(cl_key)", which won't use any costly ORDER BY clause and unnecessary LIMIT clause (it will allow more efficent execution using the existing index on page titles).
  • But it also uses a very tricky call to STRCMP to compare strings and return rows for which it returns 1 or -1 depending on the already specified order. However STRCMP() is NOT consistant with the ORDER BY.
  • even if you use a STRCMP predicate or ORDER BY clause or MIN() aggregate, you need to make sure which characters encoding (is it UTF-8 ?) is used to get results consistant with the ordering of the category tested.
  • When there's no specified category, the global indexes of all pages is used, which is NOT ordered by category keys : as you won't be able to join the pages tables with the category members tables, there will be no "cl_key", but an aggregate function remains possible on the page title column
  • But be careful ! the page title is not the only element to consider, as these 4 functions have an optional "namespace=*" parameter : if it's specified and is empty and there's no "title=*" parameter specified or it's empty, then this means returning any pages from the global pages index, whatever the namespaces in which they are found. In that case the condition for unicity will require the aggregate "HAVING namespace+':'+title = MIN(namespace+':'+title)", which may be more costly than using a LIMIT 1 with "ORDER BY namespace ASC, title ASC" (replace ASC and DESC as needed), which still uses the SQL index on the global table of all pages in all namespaces.

apostrophes and parentheses[edit]

I hate to be the squeaky wheel, but calls to #pageafter and #pagebefore where the article has an apostrophe ( ' ) in the title or where the article has parentheses in the title return empty.

The calls are in a template that is transcluded into the page in question. The page name is being passed to #pagebefore/after using {{PAGENAMEE}}. —Twisted86 22:42, 21 December 2007 (UTC)Reply

I believe I have addressed this bug in version 1.0.3 available right now in SVN/PEAR. Please try it out and let me know. Jean-Lou Dupont 00:45, 22 December 2007 (UTC)Reply
Oooppss... I think I broke something in the process... please wait for my signal before trying 1.0.3. Sorry! Jean-Lou Dupont 01:20, 22 December 2007 (UTC)Reply

Okay. Just post here when you're ready. Thanks! —Twisted86 05:58, 23 December 2007 (UTC)Reply

Could you try upgrading to the latest v1.0.7 and let me know. Jean-Lou Dupont 01:48, 3 January 2008 (UTC)Reply

not getting expected output[edit]

i created three pages and put them all in a category 'download instructions' on each page, i put the following:

[[{{#firstpage:download instructions}}]]
[[{{#pagebefore:download instructions}}]]
[[{{#pageafter:download instructions}}]]
[[{{#lastpage:download instructions}}]]

the firstpage and lastpage do not work at all. they seem to be pulling the first and last page of all the pages in the wiki. the pagebefore works as expected, but the pageafter works only until i get to the last page in the series, and then as far as i can tell, it is a random page.

i am not certain what i am doing wrong . . .

have you tried with underscores replacing the spaces e.g. download_instructions ? Jean-Lou Dupont 22:42, 28 January 2008 (UTC)Reply

i thought that might have been the problem so i tested it with another group 'downloadinstructions'. i have also tried it with 'download_instructions' but the behaviour is still incorrect.

How silly of me! I forgot to mention that you need to specify category=download_instructions ! Jean-Lou Dupont 01:27, 29 January 2008 (UTC)Reply

okay, now i have the following:


unfortunately this totally kills it, and the links appear on the page like so:

[[]] [[]] [[]] [[]]

the bottom of each of the pages has the following [that has been the case all along]:

 [[category:download instructions]]

Error whilst upgrading Semantic Mediawiki store[edit]

Hi Jean-Lou. I've just upgraded my SMW to version 1.2.1. When I run the database refresh scripts I get the following errors:

PHP Fatal error:  Call to a member function getNamespace() on a non-object in C:
 on line 101
Fatal error: Call to a member function getNamespace() on a non-object in C:\www\
webapps\mediawiki\extensions\PageAfterAndBefore\PageAfterAndBefore.body.php on l
ine 101

Any idea what this might be? Thanks. User:Mitchelln 12:27, 13 August 2008 (UTC)Reply

Hi - I am unfortunately not knowledgeable on SMW. Sorry. Jean-Lou Dupont 12:49, 13 August 2008 (UTC)Reply
No problem. Do you know happen to know if getNamespace is a php library function or a mediwiki function? Thanks. User:Mitchelln 09:13, 14 August 2008 (UTC)Reply
It is a method from the Mediawiki class title. Jean-Lou Dupont 10:21, 14 August 2008 (UTC)Reply
Thanks Jean-Lou. I'll see if I can work out why it's failing. User:Mitchelln 15:01, 14 August 2008 (UTC)Reply

error: "unexpected T_PAAMAYIM_NEKUDOTAYIM" (PHP 5.3 Namespace issue)[edit]

I don't know if anyone aside from me still uses this extension, but just in case:

After upgrading to PHP 5.3, pages using the PageAfterAndBefore extension would not load, and I got this error in /var/log/httpd/error_log:

PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting T_NS_SEPARATOR in $PATHTOWIKI/extensions/PageAfterAndBefore/PageAfterAndBefore.body.php on line 103, referer: $MYWIKIURL

After some googling, I learned that PHP 5.3 added support for namespaces, and so reserved the keyword "Namespace". This is a problem because older versions of MediaWiki had a class named Namespace, and this extension uses it. I was able to resolve the issue pretty simply by doing the following (though I barely know any PHP, so caveat emptor):

  1. Install the latest MediaWiki (the crucial change is listed in the changelog for 1.13)
  2. Change every reference in PageAfterAndBefore.body.php to the Namespace class (though not every use of the string "Namespace") to MWNamespace (there should be 4: on lines 103, 136, 145, and 164—I've put up the modified code here for reference)

After that everything worked again.

Lack of Looping[edit]

After realizing that DPL couldn't do what I was aiming to, I found this extension. My goal was to create an automatically generated "scrollbar" by embedding #pagebefore and #pageafter into a template. This extension works, or at least I thought it did. Then I came to the last page in the category. #pageafter returns no results. It does not loop back to the first page.

Basically, I want it to return the first page in a category, when it reaches the last, and vice versa (with #pagebefore, to return the last page when you're on the first). This "issue" has broken the chain (loop) I thought I had finally connected (without the need for user input). I can make parameters within the template to have users manually add the links to the scrollbar but, that would defeat the point (of an automatically generated scrollbar). Is there some way around this? Is it a bug or was it just not intended to do so? (Also, does any one even visit/monitor this page anymore?)-- 01:58, 16 October 2011 (UTC)Reply

You can use the #ifeq to test the result and go to first/last page if no before/after exists. For example:
  • Before: [[{{#ifeq: {{#pagebefore:category=CATEGORY}} | | {{#lastpage:category=CATEGORY}} | {{#pagebefore:category=CATEGORY}} }}]]
  • After: [[{{#ifeq: {{#pageafter:category=CATEGORY}} | | {{#firstpage:category=CATEGORY}} | {{#pageafter:category=CATEGORY}} }}]]
So what it's doing is if the #pageafter return value equals nothing, it uses #firstpage instead. Hope that works for your situation! --Renophaston 15:47, 18 October 2011 (UTC)Reply
There's a bug in your logic: if the loop contains only 1 page, it is the currently viewed page which is both the first and the last page in the category). In that case:
  • the 'Before' link will be formed as the result of the call to #lastpage; but as the filtercurrent=yes by default, it will try to return a page before it, which does not exist, so it will return an empty result, so this code will generate [[]] which results in the following unexpected display: [[]] instead of nothing;
  • the 'After' link will be formed as the result of the call to #firstpage; but as the filtercurrent=yes by default, it will try to return a page after it, which does not exist, so it will return an empty result, so this code will generate [[]] which results in the following unexpected display: [[]] instead of nothing;
  • if you pass explicitly the optional parameter filtercurrent=yes, then the two generated links will return the title of the currently viewed page and the generated link will appear as the same current page title in bold text, without any active link.
To display nothing in that case, you still need to test the result of #pagefirst and #pagelast to see if it's empty:
  • Before: {{#if: {{#pagebefore: category=CATEGORY}} | [[{{#pagebefore: category=CATEGORY}}]] | {{#if: {{#lastpage: category=CATEGORY}} | [[{{#lastpage: category=CATEGORY}}]] }} }}
  • After: {{#if: {{#pageafter: category=CATEGORY}} | [[{{#pageafter: category=CATEGORY}}]] | {{#if: {{#firstpage: category=CATEGORY}} | [[{{#firstpage: category=CATEGORY}}]] }} }}
But you still need to pass the category : this assumes that the currently viewed page is in that category, but this is not an obligation: you could start by a page in another category, and then loop within that category only and that target category may even be empty not ontaining the starting page currently viewed (this may be useful for example if you have a parent presentation page which will chain into a loop listing all pages in a category, if they exist, but to return to the initial page, your template will still need a "parent" link to the introduction page.)
You don't need in your example to pass the "namespace=NAMESPACE" parameter, because you don't pass the "title=" parameter in order to assume the currently viewed page, in that case you are already assuming the the builtin functions will use the namespace of the page currently viewed. However, if the first page being viewed and using the template is an introduction page not part of that category, it may be in a different namespace than the one in which you'll find the pages to insert in the loop. In that case you'll need to specify in your template the target namespace to search for pages in the specified category, and to pass explicitly an empty "title=" parameter. If you want to create your loop with pages in any namespaces, you must pass both "namespace=" and "title=" explicitly by name, with blank values (the filtercurrent=yes option will still apply, if ever the currently viewed page is listed in the specified target category).
In my opinion, the functions #firstpage, #lastpage, #pagebefore and #pageafter should support:
  • an additional optional parameter loop=yes (default=no) to avoid the first test (the loop of links will be created implicitly unless the currently viewed page is the only one in the loop and the default filtercurrent=yes restriction is in effect).
  • an additional optional parameter link=yes (default=no) to indicate we want to generate a valid link rather than a raw page title (without having to perform an addition #if test in the Wiki code to avoid the incorrect raw display as empty double brackets). It should also automatically detect if the found page falls within some special namespaces that are not rendered by a simple link (notably the "Category:" and "File:" namespaces), unless they are prefexed by an additional colon (that these functions will generate automatically as needed).
  • If a namespace=File (or image) parameter is specified, it may also support the additional parameters that will be added to render images or similar media files : thumb, border, size=widthxheightpx, upright=*, align=left/center/right, but I think it will be overkill : it seems enough in that case to return only the raw image title as a textual link without generating the rendered image if link=yes, and using link=yes will just render a raw link to the image page, by inserting the initial colon automatically for every returned page which falls in another namespace than the main namespace.
In that case the wiki code will be simplified a lot into (no need to use any double square brackets) without any tests:
  • Before: {{#pagebefore: category=CATEGORY | link=yes | loop=yes}}
  • After: {{#pageafter: category=CATEGORY | link=yes | loop=yes}}
Verdy p (talk) 01:35, 8 November 2012 (UTC)Reply