Jump to content

Manual:Hooks/GetPreferences

From mediawiki.org
GetPreferences
Available from version 1.16.0
Modify user preferences.
Define function:
public static function onGetPreferences( User $user, array &$preferences ) { ... }
Attach hook: In extension.json:
{
	"Hooks": {
		"GetPreferences": "MediaWiki\\Extension\\MyExtension\\Hooks::onGetPreferences"
	}
}
Called from: File(s): preferences/DefaultPreferencesFactory.php
Interface: GetPreferencesHook.php

For more information about attaching hooks, see Manual:Hooks .
For examples of extensions using this hook, see Category:GetPreferences extensions.


Since REL1_35:

Define function:
public function onGetPreferences( $user, &$preferences ) { ... }
Attach hook: In extension.json:
{
	"Hooks": {
		"GetPreferences": "example_tag"
	},
	"HookHandlers": {
		"example_tag": {
			"class": "MediaWiki\\Extension\\ExampleExtension\\Hooks",
			"services": [
				"MainConfig",
				"UserOptionsLookup"
			]
		}
	}
}
Interface: GetPreferencesHook.php

Usage

[edit]

Parameters

[edit]
Parameter/Option Description
$user User whose preferences are being modified
&$preferences Preferences description array, to be fed to an HTMLForm object

Tabs and sections

[edit]

The section array key specifies which tab and section of Preferences contains your preferences. If your section value is foo/bar, this means your preference will appear on the foo tab (named by system message prefs-foo) within the bar section (named by system message prefs-bar). If no such tab or section exists, it is created automatically.

List of default tabs

[edit]
Identifier Displays as
personal User profile
rendering Appearance
editing Editing
rc Recent changes
watchlist Watchlist
misc Misc

Supported types

[edit]

Visible types

[edit]

The type can take on various values found in the HTMLForm::$typeMappings array in the file includes/htmlform/HTMLForm.php, including info, multiselect, radio, etc.

Most preferences are stored in the same format as is used by the HTMLFormField, but in the case of 'type' => 'usersmultiselect' a transformation should be carried out from a newline-separated list of usernames (which is what the form widget works with) and a newline-separated list of user IDs (which is what gets stored in the database). See the treatment of email-blacklist (in core) or echo-notifications-blacklist (in Echo ) for examples of this.

Floats

[edit]

For float types, you can set min and max, which will be validated on save.

API preferences

[edit]

API preferences use type api. They are not displayed in Special:Preferences. They are usually set via custom front-end interfaces that call the API.

Note that you should not use 'type' => 'hidden' for API preferences (that type exists for HTML forms, not preferences).

Default preferences

[edit]

To set the default value for a preference (i.e. the value that is set for a new user that hasn't customized their preferences yet), add the setting to the $wgDefaultUserOptions global variable. Use the same key name as you use for $preferences in the hook.

Alternatively, if you're writing an extension, you can add to the DefaultUserOptions section of the file extensions.json.

Example since REL1_35

[edit]

See: Handling hooks in MediaWiki 1.35 and later

extension.json

[edit]

In extension.json:

	"Hooks": {
		"GetPreferences": "main"
	},
	"HookHandlers": {
		"main": {
			"class": "MediaWiki\\Extension\\ExampleExtension\\Hooks",
			"services": [
				"MainConfig",
				"UserOptionsLookup"
			]
		}
	},
	"AutoloadClasses": {
		"MediaWiki\\Extension\\ExampleExtension\\Hooks": "includes/Hooks.php",
	},
	"config": {
		"PersonalSettingsEnabledPageId": {
			"type": "boolean",
			"value": false
		},
		"PersonalSettingsNumberOfMostViewedPages": {
			"type": "int",
			"value": 50
		},
		"PersonalSettingsPeriodForLastViewedPages": {
			"type": "string",
			"value": "year"
		}
	},
	"manifest_version": 2

Hooks.json

[edit]

In includes/Hooks.php:

namespace MediaWiki\Extension\ExampleExtension;

use MediaWiki\Preferences\Hook\GetPreferencesHook;

use GlobalVarConfig;
use MediaWiki\MediaWikiServices;
use MediaWiki\User\UserOptionsLookup;

class Hooks implements GetPreferencesHook {
	private GlobalVarConfig $config;
	private UserOptionsLookup $userOptionsLookup;

	public function __construct(
		GlobalVarConfig $config,
		UserOptionsLookup $userOptionsLookup
	) {
		$this->config = $config;
		$this->userOptionsLookup = $userOptionsLookup;
	}

	public function onGetPreferences( $user, &$preferences ) {

		$your_new_extensions_section = 'exampleextension';

		// A checkbox
		$preferences_key = 'hitcounters-pageid';
		$preferences_default = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$this->config->get( 'PersonalSettingsEnabledPageId' ) );
		$preferences[$preferences_key] = [
			'type' => 'toggle',
			'label-message' => 'hitcounters-pageid-label',
			'default' => $preferences_default,
			'section' => $your_new_extensions_section
		];

		// An int input box
		$preferences_key = 'hitcounters-numberofmostviewedpages';
		$preferences_default = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$this->config->get( 'PersonalSettingsNumberOfMostViewedPages' ) );
		$preferences[$preferences_key] = [
			'type' => 'int',
			'help-message' => 'hitcounters-numberofmostviewedpages-help',
			'label-message' => 'hitcounters-numberofmostviewedpages-label',
			'maxLength' => 4,
			'default' => $preferences_default,
			'section' => $your_new_extensions_section
		];

		// A select box
		$ctx = RequestContext::getMain();
		$preferences_key = 'hitcounters-periodforlastviewedpages';
		$key_base = 'hitcounters-statistics-mostpopular';

		// Ensure that 'default' is always the 1st array item
		$preferences_default = $period = $this->config->get( 'PersonalSettingsPeriodForLastViewedPages' );
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray = [ $itemDisplayName => $period ];

		$period = 'week';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$period = 'month';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$period = 'year';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$usersItem = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$preferences_default );

		$preferences[$preferences_key] = [
			'type' => 'select',
			'options' => $itemArray,
			'default' => $usersItem,
			'label-message' => "$preferences_key-label",
			'section' => $your_new_extensions_section
		];

		// A set of radio buttons. Notice that in the 'options' array,
		// the keys are the text (not system messages), and the values are the HTML values.
		// They keys/values might be the opposite of what you expect. PHP's array_flip()
		// can be helpful here.
		$preferences_key = 'exampleextension-exampleselect';
		$key_base = 'exampleextension-select';
		$itemKey1 = 'choice1';
		$itemName1 = $ctx->msg( "$key_base-$itemKey1" )->text();
		$itemKey2 = 'choice2';
		$itemName2 = $ctx->msg( "$key_base-$itemKey2" )->text();
		$itemKey3 = 'choice3';
		$itemName3 = $ctx->msg( "$key_base-$itemKey3" )->text();

		// A 'default' key is required, ...
		$preferences_default = $itemKey1;
		// ..., but respect user's choice!
		$usersItem = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$preferences_default );

		$preferences[$preferences_key] = [
			'type' => 'radio',
			'help-message' => 'exampleextension-exampleselect-help', // a system message (optional)
			'label-message' => 'exampleextension-exampleselect-label', // a system message
			// Array of options. Key = text to display. Value = HTML <option> value.
			'options' => [
				$itemName1 => $itemKey1,
				$itemName2 => $itemKey2,
				$itemName3 => $itemKey3
			],
			'default' => $usersItem,  // A 'default' key is required!
			'section' => $your_new_extensions_section
		];
	}
<!-- [...] -->
}

i18n

[edit]

In i18n/en.json:

{
	"exampleextension-select-help": "Put a help message here!",
	"exampleextension-select-label": "Select an item:",
	"exampleextension-select-choice1": "Pick me please",
	"exampleextension-select-choice2": "No, pick me!",
	"exampleextension-select-choice3": "Seriously, pick me right now",
	"hitcounters-pageid-label": "Show page ID",
	"hitcounters-numberofmostviewedpages-label": "Number of most viewed pages",
	"hitcounters-periodforlastviewedpages-label": "Period for last viewed pages:",
	"hitcounters-statistics-mostpopular-week": "Most viewed pages in the current week",
	"hitcounters-statistics-mostpopular-month": "Most viewed pages in the current month",
	"hitcounters-statistics-mostpopular-year": "Most viewed pages in the current year",
}

Example Old School

[edit]

extension.json

[edit]

In extension.json:

	"Hooks": {
		"GetPreferences": "ExampleExtensionHooks::onGetPreferences",
	},
	"AutoloadClasses": {
		"ExampleExtensionHooks": "includes/Hooks.php",
	},
	"config": {
		"PersonalSettingsEnabledPageId": false,
		"PersonalSettingsNumberOfMostViewedPages": 50,
		"PersonalSettingsPeriodForLastViewedPages": "year"
	},
	"manifest_version": 1

Hooks.json

[edit]

In includes/Hooks.php:

class ExampleExtensionHooks extends Hooks {

	public static function onGetPreferences( $user, &$preferences ) {

		global $wgPersonalSettingsEnabledPageId, $PersonalSettingsNumberOfMostViewedPages, $PersonalSettingsPeriodForLastViewedPages;

		$your_new_extensions_section = 'exampleextension';

		// A checkbox
		$preferences_key = 'hitcounters-pageid';
		$preferences_default = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$wgPersonalSettingsEnabledPageId );
		$preferences[$preferences_key] = [
			'type' => 'toggle',
			'label-message' => 'hitcounters-pageid-label',
			'default' => $preferences_default,
			'section' => $your_new_extensions_section
		];

		// An int input box
		$preferences_key = 'hitcounters-numberofmostviewedpages';
		$preferences_default = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$PersonalSettingsNumberOfMostViewedPages );
		$preferences[$preferences_key] = [
			'type' => 'int',
			'help-message' => 'hitcounters-numberofmostviewedpages-help',
			'label-message' => 'hitcounters-numberofmostviewedpages-label',
			'maxLength' => 4,
			'default' => $preferences_default,
			'section' => $your_new_extensions_section
		];

		// A select box
		$ctx = RequestContext::getMain();
		$preferences_key = 'hitcounters-periodforlastviewedpages';
		$key_base = 'hitcounters-statistics-mostpopular';

		// Ensure that 'default' is always the 1st array item
		$preferences_default = $period = $PersonalSettingsPeriodForLastViewedPages;
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray = [ $itemDisplayName => $period ];

		$period = 'week';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$period = 'month';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$period = 'year';
		$itemDisplayName = $ctx->msg( "$key_base-$period" )->text();
		$itemArray[$itemDisplayName] = $period;

		$usersItem = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$preferences_default );

		$preferences[$preferences_key] = [
			'type' => 'select',
			'options' => $itemArray,
			'default' => $usersItem,
			'label-message' => "$preferences_key-label",
			'section' => $your_new_extensions_section
		];

		// A set of radio buttons. Notice that in the 'options' array,
		// the keys are the text (not system messages), and the values are the HTML values.
		// They keys/values might be the opposite of what you expect. PHP's array_flip()
		// can be helpful here.
		$preferences_key = 'exampleextension-exampleselect';
		$key_base = 'exampleextension-select';
		$itemKey1 = 'choice1';
		$itemName1 = $ctx->msg( "$key_base-$itemKey1" )->text();
		$itemKey2 = 'choice2';
		$itemName2 = $ctx->msg( "$key_base-$itemKey2" )->text();
		$itemKey3 = 'choice3';
		$itemName3 = $ctx->msg( "$key_base-$itemKey3" )->text();

		// A 'default' key is required, ...
		$preferences_default = $itemKey1;
		// ..., but respect user's choice!
		$usersItem = $this->userOptionsLookup->getOption(
						$user,
						$preferences_key,
						$preferences_default );

		$preferences[$preferences_key] = [
			'type' => 'radio',
			'help-message' => 'exampleextension-exampleselect-help', // a system message (optional)
			'label-message' => 'exampleextension-exampleselect-label', // a system message
			// Array of options. Key = text to display. Value = HTML <option> value.
			'options' => [
				$itemName1 => $itemKey1,
				$itemName2 => $itemKey2,
				$itemName3 => $itemKey3
			],
			'default' => $usersItem,  // A 'default' key is required!
			'section' => $your_new_extensions_section
		];
	}
<!-- [...] -->
}

i18n

[edit]

In i18n/en.json:

{
	"exampleextension-select-help": "Put a help message here!",
	"exampleextension-select-label": "Select an item:",
	"exampleextension-select-choice1": "Pick me please",
	"exampleextension-select-choice2": "No, pick me!",
	"exampleextension-select-choice3": "Seriously, pick me right now",
	"hitcounters-pageid-label": "Show page ID",
	"hitcounters-numberofmostviewedpages-label": "Number of most viewed pages",
	"hitcounters-periodforlastviewedpages-label": "Period for last viewed pages:",
	"hitcounters-statistics-mostpopular-week": "Most viewed pages in the current week",
	"hitcounters-statistics-mostpopular-month": "Most viewed pages in the current month",
	"hitcounters-statistics-mostpopular-year": "Most viewed pages in the current year",
}