Last modified: 2013-11-01 18:22:43 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T20596, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 18596 - parser function to detect if the current page is in a given category
parser function to detect if the current page is in a given category
Status: RESOLVED FIXED
Product: MediaWiki extensions
Classification: Unclassified
Extensions requests (Other open bugs)
unspecified
All All
: Low enhancement with 3 votes (vote)
: ---
Assigned To: Nobody - You can work on this!
:
: 27004 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-04-26 16:32 UTC by Cenarium
Modified: 2013-11-01 18:22 UTC (History)
12 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Cenarium 2009-04-26 16:32:18 UTC
It would be useful to be able to detect if the current page in in a given category, with a parser function, e.g. {{#ifincategory: Foo| value if true | value if false }} .

This could be used to refine template appearance, for sorting purposes (especially in maintenance), it would also allow to enable per-category editnotices, more efficiently than using editintro via common.js (doesn't work for sections, can't be hidden, etc).
Comment 1 P.Copp 2009-04-26 17:00:22 UTC
(In reply to comment #0)
> It would be useful to be able to detect if the current page in in a given
> category, with a parser function, e.g. {{#ifincategory: Foo| value if true |
> value if false }} .
> 
What would be the result of {{ifincategory: Foo | Bar | [[Category:Foo]] }} ?
Comment 2 Cenarium 2009-04-27 13:17:21 UTC
Good point, it could create cycles at evaluations.

We could remove the else parameter and return nothing if the page is not in [[Category:Foo]]. 

We wouldn't loose much essential functionality. Although, to keep it maximal, the content in the else argument could also not be allowed to categorize at all.

Disallowing categorization in Foo only would not solve the problem as a page could contain {{#ifincategory: Foo || [[Category:Bar]] }} and {{#ifincategory: Bar || [[Category:Foo]] }} , or more of them in cycle.
Comment 3 Roan Kattouw 2009-04-27 13:51:45 UTC
(In reply to comment #1)
> What would be the result of {{ifincategory: Foo | Bar | [[Category:Foo]] }} ?
> 
While interesting academically, it's obvious that such a conditional shouldn't be used for real. Simply telling users not to use it because it can lead to unexpected and/or unpredictable results is good enough IMO. That way, the parser can simply ignore this use case and handle it in the most convenient way.
Comment 4 Andrew Garrett 2009-04-27 13:56:52 UTC
The problem, of course, is that it would require an additional parsing stage to effectively handle (and the conflicts above are only the tip of the iceberg).

Seems certainly not worth the implementation cost.
Comment 5 Cenarium 2009-04-27 17:12:37 UTC
If the else argument doesn't transfer categories to the current page, it shouldn't create conflicts. If this can't be done or it's too expensive, then remove the else argument and simply provide {{#ifincategory: Foo| value if true }} (and returns nothing if false).
Comment 6 Helder 2009-09-28 00:20:44 UTC
(In reply to comment #5)
> If the else argument doesn't transfer categories to the current page, it
> shouldn't create conflicts.

And what would be the result of [[Category{{ifincategory: Foo | Bar |:}}Foo]] ?

Helder
Comment 7 Cenarium 2009-09-28 00:38:24 UTC
Another tricky case indeed, if they can't be efficiently handled, then I'd suggest only to have {{#ifincategory: Foo| value if true }}, and return nothing if false. Since it would be used to add new things when the page is in the given category (e.g. for per-category editnotices), there's no major need for an else argument. I don't think there are tricky cases without it.
Comment 8 Brad Jorsch 2009-11-01 21:01:06 UTC
(In reply to comment #7)
> Another tricky case indeed, if they can't be efficiently handled, then I'd
> suggest only to have {{#ifincategory: Foo| value if true }}, and return nothing
> if false. Since it would be used to add new things when the page is in the
> given category (e.g. for per-category editnotices), there's no major need for
> an else argument. I don't think there are tricky cases without it.

You can easily enough get an else with something like {{#if:{{#ifincategory:Foo|yes}}|value if true|value if false}}, so removing the else doesn't buy you anything in terms of reducing "tricky" cases.
Comment 9 Cenarium 2009-11-01 22:55:09 UTC
Right; since this is primarily aimed to be used in the interface, via mediawiki pages, there's no need to worry too much about how we handle categories - only if we want to use it in actual pages.

So ifincategory should not work outside of the interface: not be parsed by the software, left in plain text, but work in the interface where categories are not read. Actually, the editnotice interface shouldn't read categories at all, currently it does: categories (when not noincluded) are showed at the bottom of the edit window.
Comment 10 Platonides 2009-11-01 23:09:30 UTC
The problem is that the parser function will be evaluated in the same scope as categories are generated, so there're several options, none too good:
*The parser function returns the category membership of the previous revision (would evaluate the current if the page is purged after).
*The parser function returns the category membership with the information from categories defined before the parser function. Since the categories position standard is to place them at the bottom, not too useful.
*Add a new pass to the parser to determine this. Parserfunctions are evaluated before wikitext, and this would require preevaluating the wikitext. We shouldn't pollute the parser with those loops.
Comment 11 Cenarium 2009-11-07 03:33:19 UTC
This is a problem only if the parser function affects the category membership. It won't be a problem if this parser function is used only in the interface - and is designed to work only there. There would be ample use of this, for example in editnotices and descriptions of actions.
Comment 12 Happy-melon 2009-11-08 16:14:17 UTC
Writing a parser function that only works in the interface is a *horrible* idea; there are enough problematic inconsistencies between the parser behaviour in the interface vs the article body already.  

Implementationally, however, this information (in the simplest case) can either be drawn from the categorylinks table (corresponding to Platonides' option 1), or from the parser's own category array (option 3).  AFAICT, option 2 would require adding another parser pass *anyway*.  The first option, which is already what we do with {{REVISIONID}}, {{REVISIONUSER}}, etc, seems by far the sanest option.
Comment 13 Platonides 2009-11-08 16:29:16 UTC
Wouldn't checking the parser's own category array result in option 2?
Comment 14 Happy-melon 2009-11-08 16:31:27 UTC
As you said yourself, the category array is not populated until *after* the parser functions are expanded, so the result would always be false.
Comment 15 Alex Z. 2009-11-08 22:06:04 UTC
(In reply to comment #12)
> Implementationally, however, this information (in the simplest case) can either
> be drawn from the categorylinks table (corresponding to Platonides' option 1),
> or from the parser's own category array (option 3).  AFAICT, option 2 would
> require adding another parser pass *anyway*.  The first option, which is
> already what we do with {{REVISIONID}}, {{REVISIONUSER}}, etc, seems by far the
> sanest option.
> 

The difference is that the revision info is not set by the parser, so its possible to know the current revision info before parsing. Categories are set by the parser, so when saving a page, the function would be evaluated based on the categories on the previous revision, which means you could potentially get different behavior when saving vs. a null edit/cache expiry
Comment 16 Happy-melon 2009-11-08 22:30:17 UTC
In a sane implementation of the save process, the links tables would be updated as part of the save, and then the page would be parsed based on that information for the subsequent display.  Of course, very little about the parser is sane...  :-D
Comment 17 Alex Z. 2009-11-08 22:32:24 UTC
But you need to parse the page to determine what to update, so you would need (at least) a 2-pass parser.
Comment 18 Happy-melon 2009-11-08 22:41:59 UTC
The page is fully parsed on save to know what to update, as you say.  Then the editor is redirected back to the article, so they make a new GET request that *could* prompt a whole new parse, but I expect the on-save parse is cached to prevent that duplication of effort.  All we'd have to do is stop that, either overall or just for pages with wierd things like this.  

It all falls apart, of course, if the second parse doesn't get the latest categorylinks values, which could be tricky on replicated dbs.  Might have to do the second parse from the master?  Not sure what Domas would make of that :-D
Comment 19 Platonides 2009-11-08 22:44:27 UTC
You wouldn't rely on a browser redirect, you would just directly add the pass yourself. The user GET request is not relevant here.
Comment 20 Happy-melon 2009-11-08 22:56:57 UTC
Why?  The tables are correct, we just don't know what the resulting HTML looks like.  Who cares until someone asks to view the page?  We can't avoid the fact that people can build loops and statements that only work through after N parses, no one has any right to complain if they add 

{{#incategory: Foo
  |{{#incategory: Bar |                  | [[Category:Bar]] }}
  |{{#incategory: Bar | [[Category:Foo]] |                  }}
}} 

to a page and expect it to do something sensible.  One pass is all we need to update the tables for any sane usage, and thereafter we expect that correct HTML can be generated whenever it's needed by a second parse, which can happen whenever the HTML is actually asked for, like any other cache miss.
Comment 21 Roan Kattouw 2009-11-09 08:06:53 UTC
(In reply to comment #18)
> The page is fully parsed on save to know what to update, as you say.  Then the
> editor is redirected back to the article, so they make a new GET request that
> *could* prompt a whole new parse, but I expect the on-save parse is cached to
> prevent that duplication of effort.  All we'd have to do is stop that, either
> overall or just for pages with wierd things like this.  
> 
There is no on-save parse. The article's cache is just purged by the save, and the first GET request to the page (which is typically the editor being redirected back to the article view) causes a parse, which is then cached.
Comment 22 Roan Kattouw 2009-11-09 08:09:15 UTC
(In reply to comment #21)
> There is no on-save parse. The article's cache is just purged by the save, and
> the first GET request to the page (which is typically the editor being
> redirected back to the article view) causes a parse, which is then cached.
> 

Ignore that, I was wrong.
Comment 23 Happy-melon 2011-01-30 16:31:29 UTC
*** Bug 27004 has been marked as a duplicate of this bug. ***
Comment 24 Nemo 2013-01-25 07:25:24 UTC
*** Bug 44331 has been marked as a duplicate of this bug. ***
Comment 25 Gustronico 2013-01-25 14:53:22 UTC
(In reply to comment #24)
> *** Bug 44331 has been marked as a duplicate of this bug. ***

That's wrong. This bug requests a *current-page* category defection. Bug 44331 is
about a few (grammatical) properties of one page to be obtained *from another page*.
Comment 26 Bawolff (Brian Wolff) 2013-01-25 15:43:46 UTC
Note. I wrote an extension that does this. See [[extension:pageInCat]] (I think. The extension is named something like that). It only works for current page though (likely to change)

Only downside is it makes previews take a bit longer then they otherwise would. (Need to do the preview to determine current cats of page. And then again to determine if this affects instances of the parser function. It assumes users are not pathalogical-but even if they are you can already do pathalogical things with cats with current markup)
Comment 27 Brad Jorsch 2013-01-25 15:59:50 UTC
[[mw:Extension:PageInCat]] exists, so this bug is fixed. BTW, you might want to update the extension page to link to git instead of svn.

Requesting that this be enabled on WMF wikis would be a different bug.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links