Page MenuHomePhabricator

Add CSS hook for current WikiPage action
Closed, ResolvedPublic


Author: colin.pitts

No CSS hook exists for distinguishing between content/history/etc actions for a given page title. This obviously prevents CSS from changing the appearance based on the action being performed.

This limitation appears to be inherent to all SkinTemplate.php derived skins, as I can see nothing in that code that references the action.

I was implementing a link highlighting suggestion made by Timwi in this WikiEN-l post:

With the <body class="ns-0">, I was able to restrict the behavior to only the article namespace. However, I found no way to prevent the behavior from appearing on edit, history, protection, deletion, move, and watch/unwatch pages for a given title.

A javascript workaround may exist.

Version: 1.6.x
Severity: enhancement



Event Timeline

bzimport raised the priority of this task from to Low.Nov 21 2014, 9:01 PM
bzimport set Reference to bz4438.

herd wrote:

An existing problem this could fix: The "View logs for this
page" link is in #contentSub which is hidden on the [[Main Page]] in css. It
would be nice to restore it.

Here is an experimental js for per-action CSS (should not be used except for

It first appends a class "action-actionname" to the body according to the
&action parameter value, such as: 'watch unwatch delete revert rollback protect
unprotect info markpatrolled purge credits submit edit history'. Note that 'raw'
and 'render' do not have a <body> tag.

It then overwrites this with "action-diff" if a 'diff' parameter is used
(because the actions above have almost no effect on diffs).

It then appends "action-oldid" if 'oldid' is defined (as oldid does affect diffs).

So for example:

Main_Page == class="mediawiki ns-0 ltr page-Main_Page action-view"

Main_Page?action=unwatch == class="mediawiki ns-0 ltr page-Main_Page action-unwatch"

Main_Page?action=edit&oldid=11112 == class="mediawiki ns-0 ltr page-Main_Page
action-edit action-oldid"

Main_Page?diff=14912&oldid=11112 == class="mediawiki ns-0 ltr page-Main_Page
action-diff action-oldid"

Possibly also useful would be classes for 'direction', 'curid', 'redirect',
'diffonly', 'rdfrom', 'from', 'until' (the pecking order would have to be worked

ayg wrote:

*** Bug 9758 has been marked as a duplicate of this bug. ***

md5 wrote:

I created a patch that is attached to #9758, but it simply takes the value of
the "action" parameter and creates a class with "action-" prepended (defaulting
to "action-view"). If I can get some guidance as to whether that simple behavior
or the more complex behavior outlined by Sparkla is desired, I can adjust the
patch and attach it here. Since a release candidate of 1.10 has already been
cut, I guess this will have to target 1.11-svn, not 1.10-svn as I put in #9758.

That sounds a bit fragile to me. I don't like relying on pulling a literal GET
param there either, we want to be more general in handling the action parameters
and in validating. Might work ok though, as long as there's not a problem with
whitespace/invalid chars/etc.

md5 wrote:

My patch was using Sanitizer::escapeClass to avoid potential problems with bad
characters. I agree that it is slightly fragile if people are hacking URLs, but
it will work all normal use cases (there is a fallback to "view" when "action"
is not provided). People who put in an action that isn't recognized get an error
page anyways.

I was hoping that there would be a $wgAction global that contained the validated
action name to avoid having to default to "view" in multiple places in the code,
but I couldn't find it. I ended up using the same code that populated the
"wgAction" JavaScript variable.

  • Bug 24895 has been marked as a duplicate of this bug. ***
  • Bug 25657 has been marked as a duplicate of this bug. ***
  • Bug 27370 has been marked as a duplicate of this bug. ***

What's so complicated about adding these useful classes? :(

Can't get Sparkla's JS solution working

For those who want to hardcode a solution: includes/Skin.php:

function getPageClasses( $title ) {

		global $wgRequest;
		$numeric = 'ns-'.$title->getNamespace();
		if( $title->getNamespace() == NS_SPECIAL ) {
			$type = 'ns-special';
		} elseif( $title->isTalkPage() ) {
			$type = 'ns-talk';
		} else {
			$type = 'ns-subject';
		$name = Sanitizer::escapeClass( 'page-'.$title->getPrefixedText() );
	  if (!$wgRequest->getVal('action')) {
	  	  } else {
	  	  $actionValue = $wgRequest->getVal('action');
		$action = 'action-'. $actionValue;
		return "$numeric $type $name $action";


This will add " action-edit" to the body class when you edit a page etc. and action-view when there is no action.

A slightly improved version will also add action-yes to catch all pages that have an action.

	  if (!$wgRequest->getVal('action')) {
	  	  $actionValue = 'action-no action-view';
	  	  } else {
	  	  $actionValue = 'action-yes action-'.$wgRequest->getVal('action');
		$action = $actionValue;

Now also considering diffs which don't use the action parameter.

	  if (!$wgRequest->getVal('action')) {
	  	  $actionValue = 'action-no action-view';
	  	  } else {
	  	  $actionValue = 'action-yes action-'.$wgRequest->getVal('action');
	  if ($wgRequest->getVal('diff')) {
	  	  $actionValue = 'action-yes action-diff';
		$action = $actionValue;

Fixed in r91871 (w/o action-no, just use body:not(.action-view) )

Please don't fix this locally, there is enough ad-hoc "what action" implementations already. Instead focus on bug 27930. Once that is fixed we can insert it into various places (mw.config wgAction and body-class "action-$1").

That way action=yes%20I%know will not end up with wgAction="yes i know" or <body class="action-yes I know" (3 classes).

Just escaping it to action-yes_i_know isn't acceptable either imho, bug 27930 :-)

action=yes%20I%know returns wgAction="nosuchaction" since r91870 . That rev needs some polish per CR, though

The fixes don't consider diffs.

if ($wgRequest->getVal('diff')) {

       $actionValue = 'action-yes action-diff';

Reopening as r94131 reverted this, didn't anyone notice ?