Відмінності між версіями «Ttt»!!!

Матеріал з wiki
Перейти до: навігація, пошук
Onpage keywords chain search with * wildcard. Example: sear* my nam* will find Searh my names and search my Name


(Створена сторінка: test page with english text Category:Персоналії Category:Person Category:AAAAA Category:BBBB)
 
 
Рядок 1: Рядок 1:
 
test page with english text
 
test page with english text
 +
 +
<languages/>
 +
{{ExtensionTypes}}
 +
[[File:MediaWiki-extensions-icon.svg|125px|alt=MediaWiki extensions|{{dir|{{pagelang}}|left|right}}]]
 +
<translate>
 +
<!--T:1-->
 +
'''Special pages''' are pages that are created by the software on demand to perform a specific function.
 +
 +
<!--T:2-->
 +
For example, a special page might show all pages that have one or more links to an external site or it might create a form providing user submitted feedback.
 +
</translate>
 +
 +
<translate><!--T:3--> Special pages are located in their own [[<tvar name=1>Special:MyLanguage/Manual:Namespace</tvar>|namespace]] ('''''Special:''''') and are not editable directly like other pages.</translate>
 +
<translate><!--T:4--> <tvar name=1>{{ll|Developers}}</tvar> can also create new special pages.</translate>
 +
 +
<translate><!--T:5--> These pages by default are user-accessible and will generally show up in the list of all special pages at <tvar name=SpecialPages>[[Special:SpecialPages]]</tvar>.</translate>
 +
<translate><!--T:6--> Some special pages are only accessible to users with certain permissions and accesses.</translate>
 +
<translate><!--T:7--> Other special pages don't show up on the special page list at all and are only used by the wiki internally.</translate>
 +
 +
<translate>
 +
==General Information== <!--T:8-->
 +
</translate>
 +
<translate><!--T:9--> All built-in special pages that come with MediaWiki are called <tvar name=php><code>SpecialSomename.php</code></tvar> and are located in the <tvar name=includes><code>includes/specials</code></tvar> directory.</translate>
 +
<translate><!--T:270--> Core special pages must be registered in the core list located in <tvar name=1><code>includes/specialpage/SpecialPageFactory.php</code></tvar> in order to be loaded by MediaWiki.</translate>
 +
<translate><!--T:10--> Special pages created by third party developers are generally stored in the <tvar name=extensions><code>extensions</code></tvar> directory in their own file or as part of a larger extension.</translate>
 +
<translate><!--T:11--> All special pages inherit from a class called <tvar name=SpecialPage>{{class doclink|SpecialPage}}</tvar> which is defined in <tvar name=includesSpecialPage><code>includes/specialpage/SpecialPage.php</code></tvar>.</translate>
 +
<translate><!--T:12--> When a new special page is created, the user rights needed to access the page can be defined.</translate>
 +
<translate><!--T:13--> These rights specify, among other things, whether the page will show up on <tvar name=special>[[Special:SpecialPages]]</tvar> and whether the page is includable in other pages.</translate>
 +
 +
<translate><!--T:14--> Special pages also have unique names that can be customized on a wiki.</translate> 
 +
<translate><!--T:15--> The general form is "Special:Pagename" where both "Special" and "Pagename" are customizable.</translate> 
 +
<translate><!--T:16--> The Special pseudo <tvar name=manual>{{ll|Manual:Namespaces|namespace}}</tvar> can be translated in other languages.</translate> 
 +
<translate><!--T:17--> This translated namespace can be produced with the wikitext <tvar name=nsspecial><nowiki>{{ns:special}}</nowiki></tvar>, on this wiki giving "{{ns:special}}".</translate> 
 +
<translate><!--T:18--> The '''name''' of the special page can also be redefined in a system message, for the site language, with the generic name of the special page as the ID.</translate>
 +
 +
<translate><!--T:19--> A special page may or may not allow input.</translate> 
 +
<translate><!--T:20--> For example, <tvar name=Export>[[Special:Export]]</tvar> allows a user to define a specific page to export by calling <tvar name=exportsun>[[Special:Export/Sun]]</tvar>.</translate> 
 +
<translate><!--T:21--> If the special page allows complex input, additional parameters will be sent to the [[W:Query string|query string]] component of the URL for processing, e.g. https://www.mediawiki.org/w/index.php?title=Special:Recentchanges&days=3&limit=250.</translate>
 +
 +
{{Note|1=<nowiki/>
 +
<translate>
 +
<!--T:22-->
 +
* There are various ways to make [[<tvar name=special1>Special:MyLanguage/Help:Special pages</tvar>|special pages]], but the one below is used by the bulk of official <tvar name=man>{{ll|Manual:Extensions|extensions}}</tvar>, and adherence to this style is recommended.</translate> <translate><!--T:23--> Also, be sure to include a credits block in the new special page for 'specialpage'. See <tvar name=1><code>{{ll|Manual:$wgExtensionCredits|$wgExtensionCredits}}</code></tvar> for more details.</translate>
 +
<translate>
 +
<!--T:24-->
 +
* After making a new special page, be sure to add it to <tvar name=1>{{ll|Category:Special page extensions}}</tvar> so other people can find it.</translate>
 +
<translate>
 +
<!--T:25-->
 +
* This method is only valid for MediaWiki running on PHP5 and above.  If you're using an earlier version of MediaWiki on a more-recent version of PHP, <tvar name=upgrade>{{ll|Manual:Upgrading|upgrade MediaWiki}}</tvar>.</translate>
 +
<translate>
 +
<!--T:26-->
 +
* Special pages cannot be included within frames unless you use <code>$wgOut->allowClickjacking();</code></translate>
 +
}}
 +
 +
<translate>
 +
==Basic special page template== <!--T:27-->
 +
</translate>
 +
{{ombox|text=<translate><!--T:28--> MediaWiki 1.25 introduced a [[<tvar name=1>Manual:Extension registration</tvar>|new way]] to load an extension. For older unsupported versions of MediaWiki, see an [<tvar name=url>https://www.mediawiki.org/w/index.php?title=Manual:Special_pages&oldid=2331671</tvar> older revision].</translate>}}
 +
 +
<translate>
 +
<!--T:29-->
 +
Most special page extensions require three files:
 +
 +
<!--T:281-->
 +
* Small setup file, which loads every time MediaWiki starts.</translate>
 +
<translate>
 +
<!--T:282-->
 +
* File with the bulk of the code.</translate>
 +
<translate>
 +
<!--T:283-->
 +
* Localisation file
 +
 +
<!--T:30-->
 +
MediaWiki coding conventions define the three files like this:
 +
</translate>
 +
 +
*<code>MyExtension/extension.json</code> - <translate><!--T:31--> The setup file.</translate>
 +
*<code>MyExtension/includes/Special.php</code> - <translate><!--T:32--> The special page code.</translate>
 +
*<code>i18n/*.json</code> - <translate><!--T:33--> The <tvar name=localisation>{{ll|localisation file}}</tvar>.</translate>
 +
 +
<translate>
 +
<!--T:34-->
 +
Place all of the files in a new directory inside your MediaWiki <tvar name=extens><code>extensions/</code></tvar> directory.
 +
</translate>
 +
 +
<translate><!--T:35--> You should name the special page file after the extension. For example, <tvar name=1>{{ll|Extension:Gadgets}}</tvar> contains the file <tvar name=2><code>SpecialGadgets.php</code></tvar>.</translate>
 +
<translate><!--T:36--> If your extension uses more than one special page, you'll need more names.</translate>
 +
 +
<translate>
 +
<!--T:37-->
 +
In the example below, the special page's name is '''MyExtension'''.
 +
 +
<!--T:38-->
 +
After creating the files listed below, adding the following line to '''LocalSettings.php''' enables the extension:
 +
</translate>
 +
 +
<syntaxhighlight lang=php>
 +
wfLoadExtension( 'MyExtension' );
 +
</syntaxhighlight>
 +
 +
<translate>
 +
===The setup file=== <!--T:39-->
 +
 +
<!--T:40-->
 +
Example setup file for <code>MyExtension/extension.json</code>:
 +
</translate>
 +
{{#tag:syntaxhighlight|
 +
{
 +
"name": "MyExtension",
 +
"version": "0.0.0",
 +
"author": [
 +
"Your Name"
 +
],
 +
"url": "https://www.mediawiki.org/wiki/Extension:MyExtension",
 +
"descriptionmsg": "myextension-desc",
 +
"license-name": "MIT",
 +
"type": "other",
 +
"AutoloadNamespaces": {
 +
"MediaWiki\\Extension\\MyExtension\\": "src/"
 +
},
 +
"SpecialPages": {
 +
"MyExtension": "MediaWiki\\Extension\\MyExtension\\Special"
 +
},
 +
"MessagesDirs": {
 +
"MyExtension": [
 +
"i18n"
 +
]
 +
},
 +
"manifest_version": 2,
 +
"requires": {
 +
"MediaWiki": ">= {{MW legacy branch number}}.0",
 +
"platform": {
 +
"php": ">= 5.6"
 +
},
 +
"extensions": {
 +
"dependendExtension": "*"
 +
}
 +
}
 +
}
 +
|lang=json}}
 +
 +
<translate>
 +
<!--T:41-->
 +
This file registers several important and mandatory things:
 +
 +
<!--T:42-->
 +
* The location of the <tvar name=1>MediaWiki\Extension\MyExtension\Special</tvar> class;</translate>
 +
<translate>
 +
<!--T:43-->
 +
* The location of the localisation files;</translate>
 +
<translate>
 +
<!--T:44-->
 +
* The new special page and its class name.
 +
 +
===The special page file=== <!--T:45-->
 +
</translate>
 +
<translate><!--T:46--> The body file (<tvar name=php><code>MyExtension/src/Special.php</code></tvar>) should contain a subclass of <code>SpecialPage</code> or one of its subclasses.</translate>
 +
<translate><!--T:47--> This file loads automatically when someone requests the special page.</translate>
 +
<translate><!--T:48--> The example below implements the subclass SpecialMyExtension.</translate>
 +
 +
<translate><!--T:49--> You need the <tvar name=conduct><code>__construct()</code></tvar> constructor because its first parameter names your special page.</translate>
 +
 +
<translate><!--T:50--> <tvar name=execute><code>execute()</code></tvar> is the main function called when a special page is accessed.</translate> 
 +
<translate><!--T:51--> This function overrides the function <tvar name=SpecialPage>{{phpi|SpecialPage::execute()}}</tvar>.</translate>
 +
<translate><!--T:52--> It passes the single parameter <tvar name=par><code>$par</code></tvar>, the subpage component of the current title.</translate> 
 +
<translate><!--T:53--> For example, if someone follows a link to <tvar name=blah>[[Special:MyExtension/blah]]</tvar>, <tvar name=par1><code>$par</code></tvar> contains "blah".</translate>
 +
 +
<translate>
 +
<!--T:54-->
 +
You should run Wikitext and HTML output through <tvar name=1><code>$wgOut</code></tvar>. Do not use 'print' or 'echo' directly when working within the wiki's user interface.
 +
 +
<!--T:55-->
 +
However, if you use your special page as an access point to custom XML or binary output, see <tvar name=1>{{ll|Taking over output in your special page}}</tvar>.
 +
</translate>
 +
 +
<syntaxhighlight lang="php">
 +
<?php
 +
namespace MediaWiki\Extension\MyExtension;
 +
class SpecialMyExtension extends \SpecialPage {
 +
function __construct() {
 +
parent::__construct( 'MyExtension' );
 +
}
 +
 +
function execute( $par ) {
 +
$request = $this->getRequest();
 +
$output = $this->getOutput();
 +
$this->setHeaders();
 +
 +
# <translate nowrap><!--T:56--> Get request data from, e.g.</translate>
 +
$param = $request->getText( 'param' );
 +
 +
# <translate nowrap><!--T:57--> Do stuff</translate>
 +
# ...
 +
$wikitext = 'Hello world!';
 +
$output->addWikiTextAsInterface( $wikitext );
 +
}
 +
}
 +
</syntaxhighlight>
 +
 +
{{anchor|The Messages/Internationalization File}}
 +
<translate>
 +
===The localisation file=== <!--T:58-->
 +
</translate>
 +
 +
:''<translate><!--T:59--> See <tvar name=1>{{ll|Help:System message#Adding new messages}}</tvar> for how to get them translated.</translate>''
 +
 +
<translate>
 +
<!--T:60-->
 +
All special pages specify a title, like <tvar name=Myextension><code>'My Extension'</code></tvar>.
 +
 +
<!--T:61-->
 +
* The title is used in the <tvar name=title>{{tag|title|open}}</tvar>  and <tvar name=H1>{{tag|h1|open}}</tvar> elements of the extension's page and on <tvar name=SpecialPages>[[Special:SpecialPages]]</tvar>.</translate>
 +
<translate>
 +
<!--T:62-->
 +
* It can be anything, but should describe the special page and extension.</translate>
 +
<translate>
 +
<!--T:63-->
 +
* It's specified through a message. The structure of the message is a key-value pair. The key, <tvar name=myext><code>'myextension'</code></tvar>, ''must'' be all lowercase.
 +
 +
<!--T:64-->
 +
An example of a localisation file in <tvar name=i18n><code>MyExtension/i18n/en.json</code></tvar>:
 +
</translate>
 +
 +
<syntaxhighlight lang="javascript">
 +
{
 +
"@metadata": {
 +
"authors": [
 +
"<your username>"
 +
]
 +
},
 +
"myextension": "My Extension",
 +
"myextension-desc": "Adds the MyExtension functionality.",
 +
"myextension-summary": "On this special page, do this simple thing and earn wonders.",
 +
"group-myextensionrole": "Role of myextension",
 +
"group-myextensionrole-member": "Member of role of myextension",
 +
"grouppage-myextensionrole": "{{ns:project}}:Role of myextension",
 +
"action-myextension": "XYZ doing.",
 +
"right-myextension": "to do xyz"
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:65--> In <tvar name=qqq><code>i18n/qqq.json</code></tvar>, the [[<tvar name=msgdoc>Special:MyLanguage/Help:System message#Message documentation</tvar>|message documentation]]:</translate>
 +
 +
<syntaxhighlight lang="javascript">
 +
{
 +
"@metadata": {
 +
"authors": [
 +
"<your username>"
 +
]
 +
},
 +
"myextension": "The name of the extension's entry in Special:SpecialPages",
 +
"myextension-desc": "{{desc}}",
 +
"myextension-summary": "Description appearing on top of Special:MyExtension.",
 +
"action-myextension": "{{doc-action|myextension}}",
 +
"right-myextension": "{{doc-right|myextension}}"
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:67--> Note that IDs should not start with an uppercase letter, and that a space in the ID should be written in the code as an underscore.</translate>
 +
 +
<translate><!--T:68--> The -summary message is optional.</translate>
 +
<translate><!--T:69--> It's created automatically by the parent class and shown on top of the special page, usually for a concise description of what the user can do on it.</translate>
 +
<translate><!--T:70--> If you don't define its content, it will only be used when wiki administrators customize it on the wiki.</translate>
 +
 +
<translate>
 +
=== The aliases file === <!--T:71-->
 +
</translate>
 +
<translate><!--T:273--> You can also internationalize the name of the special page by creating aliases for it. The example below uses the file "<tvar name=1>MyExtension.i18n.alias.php</tvar>".</translate>
 +
<translate><!--T:72--> In this example, the special page <tvar name=MyExtension><code>MyExtension</code></tvar> registers an ''alias'' so the page becomes accessible at <tvar name=tt><code>.../Special:My Extension</code></tvar> and <tvar name=tt1><code>.../Spezial:Meine_Erweiterung</code></tvar> in German.</translate>
 +
 +
<translate><!--T:267--> Add your alias file to <tvar name=file><code>extension.json</code></tvar>:</translate>
 +
 +
<syntaxhighlight lang="javascript">
 +
...
 +
"ExtensionMessagesFiles": {
 +
"MyExtensionAlias": "MyExtension.i18n.alias.php"
 +
},
 +
...
 +
</syntaxhighlight>
 +
 +
<translate><!--T:268--> Add special page aliases to <tvar name=file><code>MyExtension.i18n.alias.php</code></tvar>:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
<?php
 +
/**
 +
* Aliases for myextension
 +
*
 +
* @file
 +
* @ingroup Extensions
 +
*/
 +
 +
$specialPageAliases = [];
 +
 +
/** English
 +
* @author <<translate nowrap><!--T:73--> your username</translate>>
 +
*/
 +
$specialPageAliases['en'] = [
 +
'MyExtension' => [ 'MyExtension', 'My Extension' ],
 +
];
 +
 +
/** Deutsch
 +
* @author <<translate nowrap><!--T:74--> your username</translate>>
 +
*/
 +
$specialPageAliases['de'] = [
 +
'MyExtension' => [ 'MeineErweiterung', 'Meine Erweiterung' ],
 +
];
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:75-->
 +
Again, you should write a space in the ID and an underscore in the code.
 +
 +
<!--T:76-->
 +
For the page header and linking, the usual rules for page names apply.
 +
 +
<!--T:77-->
 +
If <tvar name=1><code>{{ll|Manual:$wgCapitalLinks|$wgCapitalLinks}}</code></tvar> is true, a lowercase letter is converted to uppercase, and an underscore is displayed as a space.
 +
 +
<!--T:78-->
 +
For example, instead of the above, we could use <tvar name=code><code>'my_extension' => 'My extension'</code></tvar>, assuming we consistently identified the extension as <tvar name=tt2><code>my_extension</code></tvar> elsewhere.
 +
 +
<!--T:79-->
 +
Note that in the associative array for the English language, the string identifying our SpecialPage (<tvar name=code1><code>MyExtension</code></tvar> in the example) is ''also'' a valid title.
 +
 +
<!--T:80-->
 +
Also note, the first element of <tvar name=specialPageAliases>{{phpi|$specialPageAliases['en']['MyExtension']}}</tvar> ''must'' be the same as the key (<tvar name=code2><code>'MyExtension'</code></tvar>)! Otherwise <tvar name=special>[[Special:Specialpages]]</tvar> will not list the page.
 +
 +
====Special page group==== <!--T:81-->
 +
 +
<!--T:82-->
 +
You can set which group your special page appears under on <tvar name=special>[[Special:SpecialPages]]</tvar> by overriding <code>SpecialPage::getGroupName()</code> in your subclass.
 +
</translate>
 +
 +
<syntaxhighlight lang="php">
 +
    /**
 +
    * <translate nowrap><!--T:83--> Override the parent to set where the special page appears on Special:SpecialPages</translate>
 +
    * <translate nowrap><!--T:84--> 'other' is the default. If that's what you want, you do not need to override.</translate>
 +
    * <translate nowrap><!--T:85--> Specify 'media' to use the <tvar name=specialpagesgroupmedia><code>specialpages-group-media</code></tvar> system interface message, which translates to 'Media reports and uploads' in English;</translate>
 +
    *
 +
    * @return string
 +
    */
 +
    function getGroupName() {
 +
        return 'media';
 +
    }
 +
</syntaxhighlight>
 +
 +
<translate><!--T:86--> Some common values are 'login', 'maintenance', 'media', 'other', 'pagetools', 'redirects', 'users'.</translate> 
 +
<translate><!--T:87--> You can see the accepted values at <tvar name=AllMessages><nowiki>Special:AllMessages</nowiki></tvar> (search for '''specialpages-group''') or browse the wiki using the pseudo language 'qqx' by going to <tvar name=uselang><nowiki>Special:SpecialPages?uselang=qqx</nowiki></tvar>) and looking at the headings.</translate> 
 +
<translate><!--T:88--> Specify the word 'media' to use the interface message 'specialpages-group-media'.</translate>
 +
 +
<translate><!--T:89--> If your special page doesn't fit into any of the preconfigured headings, you can add a new heading by adding it to your localisation file, see [[<tvar name=1>#The localisation file</tvar>|The localisation file]]).</translate>
 +
 +
<translate><!--T:90--> The standard page groups that come with MediaWiki are listed in the localisation file. For example, the English messages are in <tvar name=json><code>languages/i18n/en.json</code></tvar> and begin with <tvar name=specialpagesgroup><code>specialpages-group-</code></tvar>.</translate>
 +
<translate><!--T:91--> If you want to categorize your special page under <tvar name=users><code>users</code></tvar>, then the message is <tvar name=msg><code>specialpages-group-users</code></tvar>.</translate>
 +
<translate><!--T:92--> The value for this key is the text that appears as the name of that category, for example, <code>Users and rights</code>.</translate>
 +
 +
<translate><!--T:93--> If your special page does not seem to fit under any of the existing categories, you can always make a new one.</translate>
 +
<translate><!--T:94--> In your extension's localisation file simply insert a new key for the <tvar name=messages><code>messages</code></tvar> array.</translate>
 +
<translate><!--T:95--> In this example, we define the <tvar name=gamification><code>gamification</code></tvar> group:</translate>
 +
 +
<syntaxhighlight lang="json">
 +
{
 +
    "myextension": "My Extension",
 +
"myextension-desc": "Adds the MyExtension functionality.",
 +
"myextension-summary": "On this special page, do this simple thing and earn wonders",
 +
"specialpages-group-gamification": "Gamification"
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:96--> Now, assuming you set the return value for the method <code>SpecialPage::getGroupName()</code> as <code>gamification</code> in your class definition, reload <tvar name=special>[[Special:SpecialPages]]</tvar> to see your new category.</translate>
 +
 +
<translate>
 +
==Other Important Files== <!--T:97-->
 +
</translate>
 +
 +
===SpecialPage.php===
 +
 +
<translate>
 +
====Constructor==== <!--T:99-->
 +
</translate>
 +
<translate><!--T:100--> You can [[w:Method overloading|overload]] the constructor to initialize your own data, but the main reason you would want to do it is to change the behavior of the SpecialPage class itself.</translate>
 +
<translate><!--T:101--> When you call the base class constructor from your child class, the following parameters are available:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
function __construct( $name = '', $restriction = '', $listed = true );
 +
</syntaxhighlight>
 +
 +
* ''string'' <code>$name</code> <translate><!--T:102--> Name of the special page, as seen in links and URLs</translate>
 +
* ''string'' <code>$restriction</code> <translate><!--T:103--> [[<tvar name=userright>Special:MyLanguage/Manual:User rights</tvar>|User right]] required, e.g. "block" or "delete"; also see [[<tvar name=Restrictingpageaccess>Special:MyLanguage/Manual:Special_pages#Restricting_page_access</tvar>|Restricting page access]]</translate>
 +
* ''boolean'' <code>$listed</code> <translate><!--T:104--> Whether the page is listed in Special:Specialpages</translate>
 +
 +
====<code>SpecialPage->setHeaders()</code>====
 +
 +
<translate><!--T:105--> This initialises the OutputPage object <tvar name=1><code>$wgOut</code></tvar> with the name and description of your special page.</translate>
 +
<translate><!--T:106--> It should always be called from your execute() method.</translate>
 +
 +
====<code>SpecialPage->getOutput()</code>====
 +
 +
<translate><!--T:107--> This method returns an OutputPage object which can be accessed as described below.</translate>
 +
<translate><!--T:108--> As in the example code, use</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output = $this->getOutput();
 +
$output->addWikiTextAsInterface( 'Hello, World' );
 +
</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:109-->
 +
instead of the deprecated <tvar name=1><code>$wgOut</code></tvar> global variable
 +
</translate>
 +
 +
====<code>SpecialPage->getRequest()</code>====
 +
 +
<translate><!--T:110--> This method returns a WebRequest object which can be accessed as described below.</translate>
 +
<translate><!--T:111--> As in the example code, use</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$request = $this->getRequest();
 +
$myparam = $request->getText( 'myparam' );
 +
</syntaxhighlight>
 +
 +
<translate><!--T:112--> instead of the deprecated <tvar name=1>{{$wg|Request}}</tvar> global variable</translate>
 +
 +
====<code>SpecialPage->including()</code>====
 +
 +
<translate><!--T:113--> Some special pages can be included from within another page.</translate>
 +
<translate><!--T:114--> For example, if you add <tvar name=1><nowiki>{{Special:RecentChanges}}</nowiki></tvar> to the wikitext of a page, it will insert a listing of recent changes within the existing content of the page.</translate>
 +
 +
<translate><!--T:115--> Including a special page from another web page is only possible if you declared the page to be includable in the constructor.</translate> 
 +
<translate><!--T:116--> You can do this by adding the following in the <tvar name=codeconstruct><code>__construct()</code></tvar> method after the parent class initialization:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$this->mIncludable = true;
 +
</syntaxhighlight>
 +
 +
<translate><!--T:117--> You can also define your special page class as extending the IncludableSpecialPage class.</translate>
 +
 +
<translate><!--T:118--> The SpecialPage->including() function returns a boolean value telling you what context the special page is being called from: false if it is a separate web page, and true if it is being included from within another web page.</translate>
 +
<translate><!--T:119--> Usually you will want to strip down the presentation somewhat if the page is being included.</translate>
 +
 +
{{anchor|execute}}
 +
====<code>SpecialPage->execute()</code>====
 +
 +
<translate><!--T:120--> This is the function which your child class should overload.</translate>
 +
<translate><!--T:121--> It passes a single parameter, usually referred to cryptically as <tvar name=codepar><code>$par</code></tvar> (short for $parameter, as it is the parameter the users can feed to your special page).</translate>
 +
<translate><!--T:122--> This parameter is the subpage component of the current title.</translate>
 +
<translate><!--T:123--> For example, if someone follows a link to <tvar name=myextensionblah>[[Special:MyExtension/blah]]</tvar>, <code>$par</code> will contain "blah".</translate>
 +
 +
<translate>
 +
=====Help page===== <!--T:124-->
 +
</translate>
 +
 +
{{MW 1.25|and later}}
 +
 +
<translate><!--T:125--> It's useful to add [[<tvar name=1>Special:MyLanguage/Project:PD help</tvar>|help pages]] on MediaWiki.org, where they'll be [[<tvar name=2>Special:MyLanguage/Project:Language policy</tvar>|translatable]].</translate>
 +
<translate><!--T:126--> To make sure users find your help page, it's advisable and very simple for your special page to link the help page in question:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$this->addHelpLink( 'Help:Extension:MyExtension' );
 +
</syntaxhighlight>
 +
 +
===OutputPage.php===
 +
 +
<translate><!--T:128--> OutputPage.php contains the class definition for objects of type <tvar name=OutputPage><code>OutputPage</code></tvar>.</translate>
 +
<translate><!--T:129--> You can get an object of this class from your SpecialPage using</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output = $this->getOutput();
 +
</syntaxhighlight>
 +
 +
<translate><!--T:130--> The variablename $output is, of course, arbitrary.</translate>
 +
<translate><!--T:131--> Whatever you call it, this is the variable you will use the most, because it is the way to send output to the browser (no, you don't use <tvar name=codeecho><code>echo</code></tvar> or <tvar name=print><code>print</code></tvar>).</translate>
 +
<translate><!--T:132--> If you want to use it somewhere, declare the variable global:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
function randomFunction() {
 +
        $output = $this->getOutput();
 +
$output->addHTML( '<b>This is not a pipe...</b>' );
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:133--> If you want to, you can create multiple OutputPage objects in different methods in your SpecialPage extension.</translate>
 +
<translate><!--T:134--> They will add to the output in the order they are executed.</translate>
 +
 +
<translate><!--T:135--> You can inspect the OutputPage class by viewing <tvar name=ManOutputPage><code>{{ll|Manual:OutputPage.php|includes/OutputPage.php}}</code></tvar> (indeed, all of these can be inspected), but there are a few methods you should definitely know about.</translate>
 +
 +
====<code>OutputPage->addHTML()</code>====
 +
<translate><!--T:136--> Essentially the quick and dirty substitute for <tvar name=echo><code>echo</code></tvar>.</translate>
 +
<translate><!--T:137--> It takes your input and adds it to the buffer: no questions asked.</translate>
 +
<translate><!--T:138--> In the below action, if <tvar name=action><code>$action</code></tvar> contains user-data, it could easily have XSS, evil stuff, or the spawn of [[w:Satan|Satan]] injected in.</translate>
 +
<translate><!--T:139--> You're better off using escaping (such as with the php function htmlentities) or the XML builders class to build trusted output.</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output->addHTML( '<form action="'.$action.'" method="post">' );
 +
</syntaxhighlight>
 +
 +
====<code>OutputPage->addWikiText()</code>====
 +
<translate><!--T:140--> For most output, you should be using this function.</translate>
 +
<translate><!--T:141--> It's a bit of a black magic function: wikitext goes in, HTML comes out, and a whole lotta arcane code and demon summonings happen in between.</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output->addWikiText("This is some ''lovely'' [[wikitext]] that will '''get''' parsed nicely.");
 +
</syntaxhighlight>
 +
 +
<translate><!--T:142--> What's worth noting is that the parser will view your chunks as cohesive wholes and paragraph accordingly. That is...</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output->addWikiText( '* Item 1' );
 +
$output->addWikiText( '* Item 2' );
 +
$output->addWikiText( '* Item 3' );
 +
</syntaxhighlight>
 +
 +
<translate><!--T:143--> Will output three lists with one item each, which probably wasn't intended.</translate>
 +
 +
{{Warning|1=<translate><!--T:144--> If your special page is intended to be included in other pages, you should probably not use <tvar name=addWikiText><code>addWikiText()</code></tvar> (or any other function that calls the parser except for message related functions that parse (<tvar name=1>$this->msg()</tvar>) which are OK to call on modern versions of MediaWiki).</translate> <translate><!--T:145--> Due to [<tvar name=url>http://www.ehartwell.com/TechNotes/MediaWikiExtensionParserDebug.htm</tvar> a bug in MediaWiki] (<tvar name=1>[[phab:T18129]]</tvar>), an included special page will mess up any inclusion before it on the same including page, showing strings like UNIQ10842e596cbb71da.</translate>}}
 +
 +
<translate><!--T:146--> Note however, if you just want to insert a system message and have it treated like parsed wikitext, you can use code like <tvar name=getOutput>{{phpi|$this->getOutput()->addHtml( $this->msg( 'key-of-message' )->parse() )}}</tvar>.</translate>
 +
<translate><!--T:147--> This will not have the issue with nested parser calls mentioned above.</translate>
 +
 +
<translate>
 +
=====workaround #1===== <!--T:148-->
 +
 +
<!--T:149-->
 +
Important: these work arounds are only needed if you are making a transcludable special page. Normal special pages do not need these.
 +
</translate>
 +
 +
<translate><!--T:150--> As a workaround, you can have your extensions convert Wikitext to HTML using a separate Parser object and then use <tvar name=addHTML><code>addHTML()</code>.</tvar></translate>
 +
<translate><!--T:151--> Example:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$wgOut->addHTML( $this->sandboxParse( "Here's some '''formatted''' text." ) );
 +
</syntaxhighlight>
 +
 +
<syntaxhighlight lang="php">
 +
# <translate nowrap><!--T:152--> Assuming this is inside the same class as the rest of your special page code</translate>
 +
function sandboxParse( $wikiText ) {
 +
$myParser = new Parser();
 +
        $user = $this->getUser();
 +
        $title = self::getTitleFor('YourCanonicalSpecialPageName');
 +
$myParserOptions = ParserOptions::newFromUser( $user );
 +
$result = $myParser->parse( $wikiText, $title, $myParserOptions );
 +
return $result->getText();
 +
}
 +
</syntaxhighlight>
 +
 +
<translate>
 +
=====workaround #2===== <!--T:153-->
 +
</translate>
 +
<translate><!--T:154--> I tried the above, and found that the same problem now applied to any tags in the transcluded text.</translate>
 +
<translate><!--T:155--> This won't be a problem for a lot of extensions, but the extension I was writing was intended to show wikitext from another page as part of its functionality, so this was a problem.</translate>
 +
 +
<translate><!--T:156--> The process for parsing a page which transcludes a special page seems to be this:</translate>
 +
 +
# <translate><!--T:157--> Replace <tvar name=special5><nowiki>{{Special:MyExtension}}</nowiki></tvar> with a [[Strip marker|UNIQ-QINU marker]] (because SpecialPage output is expected to be ready-to-output HTML)</translate>
 +
# <translate><!--T:158--> Replace any tags with [[Strip marker|QINU markers]] as above</translate>
 +
# <translate><!--T:159--> Parse everything else from wikitext to HTML</translate>
 +
# <translate><!--T:160--> Replace all [[Strip marker|QINU markers]] with their respective stored values, in a single pass</translate>
 +
 +
<translate><!--T:161--> The process for parsing a page which transcludes a ''non''-special page, though, is apparently like this:</translate>
 +
 +
# <translate><!--T:162--> Replace <tvar name=1><nowiki>{{:Normal Article Name}}</nowiki></tvar> or <tvar name=2><nowiki>{{Template Name}}</nowiki></tvar> with contents of transcluded page (because transcluded pages contain unparsed wikitext)</translate>
 +
# <translate><!--T:163--> Replace any tags with [[Strip marker|QINU markers]] as above</translate>
 +
# <translate><!--T:164--> Parse everything else from wikitext to HTML</translate>
 +
# <translate><!--T:165--> Replace all [[Strip marker|QINU markers]] with their respective stored values, in a single pass</translate>
 +
 +
<translate><!--T:166--> The problem is apparently that in the earlier case, the parsing of the SpecialPage's wiki text is lacking the final QINU decoding step (why?), so all the [[Strip marker|QINU markers]] are left undecoded.</translate>
 +
<translate><!--T:167--> (This may be a leftover from using the same syntax to invoke transclusion of a wikitext page, which is just pasted straight into the host page's wikitext contents and parsed, as is used to invoke transclusion of a SpecialPage, which must not be parsed at all. Wherever the code is that decides "wait, this is a special page -- replace it with a QINU", it should be doing the extra unstripGeneral before doing the QINU substitution.)</translate>
 +
{{void|1=
 +
<translate><!--T:168--> Wherever the code is that decides "wait, this is a special page -- replace it with a QINU", it should be doing the extra unstripGeneral before doing the QINU substitution.)</translate>
 +
}}
 +
 +
<translate><!--T:169--> So I just did the following -- after this line:</translate>
 +
<syntaxhighlight lang="php">$htOut = $wgParser->recursiveTagParse( $iText );</syntaxhighlight>
 +
<translate><!--T:170--> ...I added these lines (the second one is only because the function definition for the first one recommends it):</translate>
 +
<syntaxhighlight lang="php">
 +
$htOut = $wgParser->mStripState->unstripGeneral( $htOut );
 +
$htOut = $wgParser->mStripState->unstripNoWiki( $htOut );
 +
</syntaxhighlight>
 +
<translate><!--T:171--> Since I have now documented this, of course, I will now find a tragic flaw with it and feel really stupid... but as long as it seems to be working, I had to note it here.</translate>
 +
<translate><!--T:172--> (It is also important to note the problem with work-around #1.)</translate>
 +
<translate><!--T:173--> Also, I have only tested this with MediaWiki 1.10.1.</translate>
 +
<translate><!--T:174--> The problem still exists under MW 1.14, but this solution may or may not work.</translate>
 +
--[[User:Woozle|Woozle]] 18:26, 9 April 2009 (UTC)
 +
 +
====<code>OutputPage->showErrorPage()</code>====
 +
<translate><!--T:179--> An error page is shown.</translate>
 +
<translate><!--T:180--> The arguments <tvar name=codetitle><code>$title</code></tvar> and <tvar name=msg><code>$msg</code></tvar> specify keys into <tvar name=1>$this->msg()</tvar>, not text.</translate>
 +
<translate><!--T:181--> An example:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output->showErrorPage( 'error', 'badarticleerror' );
 +
</syntaxhighlight>
 +
 +
*<translate><!--T:182--> '<tvar name=1>error</tvar>' refers to the text ''"<tvar name=2>{{int|error}}</tvar>"''.</translate>
 +
*<translate><!--T:183--> '<tvar name=1>badarticleerror</tvar>' refers to the text ''"<tvar name=2>{{int|badarticleerror}}</tvar>"''.</translate>
 +
 +
<translate><!--T:184--> You can also specify message objects or add parameters:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$output->showErrorPage( 'error', 'badarticleerror', [ 'param1', 'param2' ] );
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="php">
 +
$messageObject = new Message(...);
 +
...
 +
$output->showErrorPage( 'error', $messageObject );
 +
</syntaxhighlight>
 +
<syntaxhighlight lang="php">
 +
$titleMessageObject = new Message(...);
 +
$messageObject = new Message(...);
 +
...
 +
$output->showErrorPage( $titleMessageObject, $messageObject );
 +
</syntaxhighlight>
 +
 +
===WebRequest.php===
 +
<translate><!--T:185--> The <tvar name=1>{{manual|WebRequest.php|WebRequest}}</tvar> class is used to obtain information from the GET and POST arrays.</translate>
 +
<translate><!--T:186--> Using this is recommended over directly accessing the superglobals.</translate>
 +
<translate><!--T:187--> The WebRequest object is accessible from extensions by using the <tvar name=RequestContext>{{ll|RequestContext}}</tvar>.</translate>
 +
 +
===Database.php===
 +
<translate><!--T:192--> MediaWiki has a load of convenience functions and wrappers for interacting with the database, using the <tvar name=1>{{manual|Database.php|\Wikimedia\Rdbms\Database}}</tvar> class.</translate>
 +
<translate><!--T:193--> It also has an interesting load balancing scheme in place.</translate>
 +
<translate><!--T:194--> It's recommended you use these wrappers.</translate>
 +
<translate><!--T:195--> Check out <tvar name=Database><code>{{ll|Manual:Database.php|Database.php}}</code></tvar> for a complete listing of all the convenience functions, because these docs will only tell you about the non-obvious caveats.</translate>
 +
<translate><!--T:196--> See <tvar name=1>{{ll|Manual:Database access}}</tvar>.</translate>
 +
 +
===User.php===
 +
<translate><!--T:202--> The <tvar name=1>{{manual|User.php|User}}</tvar> class is used to represent users on the system.</translate>
 +
<translate><!--T:271--> <tvar name=1>SpecialPage->getUser()</tvar> should be used to obtain a <tvar name=2>User</tvar> object for the currently logged in user.</translate>
 +
<translate><!--T:272--> The use of the global <tvar name=1><code>$wgUser</code></tvar> is deprecated</translate>
 +
 +
===Title.php===
 +
<translate><!--T:206--> Title represents the name of a page in the wiki.</translate>
 +
<translate><!--T:207--> This is useful because MediaWiki does all sorts of fun escaping and special case logic to page names, so instead of rolling your own convert title to URL function, you create a Title object with your page name, and then use <tvar name=escapeLocalURL><code>getLocalURL()</code></tvar> to get a URL to that page.</translate>
 +
 +
<translate><!--T:208--> To get a title object for your special page from outside of the special page class, you can use <tvar name=SpecialPageYourCanonical>{{phpi|SpecialPage::getTitleFor( 'YourCanonicalSpecialPageName' )}}</tvar>.</translate>
 +
<translate><!--T:209--> It will give you a localised title in the wiki's language.</translate>
 +
 +
<translate>
 +
==Custom special pages== <!--T:210-->
 +
 +
<!--T:211-->
 +
There are various ways to provide your own special pages not bundled within MediaWiki:
 +
</translate>
 +
 +
* <translate><!--T:212--> One method is to install an extension that generates a form to create or edit an article.  A list of extensions currently available, can be found at <tvar name=category>{{ll|Category:Special page extensions}}</tvar>.</translate>
 +
* <translate><!--T:213--> You can also write an extension which provides your own special page.  Writing your own extension requires [[w:PHP|PHP]] coding skill and comfort with object oriented design and databases also is helpful.  You will also need to know how to use code to create and edit MediaWiki articles. For more information, please see [[<tvar name=Articleswithembeddedforms>Special:MyLanguage/Manual:Forms#Articles_with_embedded_forms</tvar>|this discussion]].</translate>
 +
* <translate><!--T:214--> You can also display a custom page through JavaScript, in place of the default error message "Unknown special page" (or the "This page is intentionally left blank." message, if using a subpage of [[Special:BlankPage]]). In MediaWiki:Common.js, check for <tvar name=1>{{ll|Manual:Interface/JavaScript#mw.config|wgPageName}}</tvar>, then hide the MediaWiki-generated content (just appendCSS <tvar name=visibility><code>{visibility:hidden;}</code></tvar> ), and inject custom HTML (<tvar name=innerHTML><code>innerHTML</code></tvar>) into the <tvar name=bodyContent><code>document.getElementById('bodyContent')</code></tvar> or <tvar name=mwcontentholder><code>document.getElementById('mw_contentholder')</code></tvar>. For an example, see [[:meta:User:Krinkle/Tools/Real-Time Recent Changes]].</translate>
 +
 +
<translate>
 +
==FAQ== <!--T:215-->
 +
 +
===Setting an Extension Title=== <!--T:216-->
 +
</translate>
 +
<translate><!--T:217--> MediaWiki does not set the title of the extension, which is the developer's job.</translate>
 +
<translate><!--T:218--> It will look for the name of the extension when <tvar name=special>[[Special:Specialpages]]</tvar> is called or the special page is loaded.</translate> 
 +
<translate><!--T:219--> In the <tvar name=1>[[#execute|''function execute( $par )'']]</tvar> section, use OutputPage methods to title the extension like: <tvar name=setPageTitle>{{phpi|$this->getOutput()->setPageTitle("your title");}}</tvar></translate>
 +
 +
<translate><!--T:220--> The place where the extension can be found (as specified by what is passed into the SpecialPage constructor) is the key--'''except''' that it is not capitalized because of <tvar name=getDescription><code>getDescription()</code></tvar>, the internally used function that finds out the title (or, what they call description) of the special page, <tvar name=strtolower><code>strtolower</code></tvar> the name.</translate>
 +
<translate><!--T:221--> "ThisIsACoolSpecialPage"'s key would be "thisisacoolspecialpage."</translate>
 +
 +
<translate><!--T:222--> Theoretically, <tvar name=getDescription1><code>getDescription</code></tvar> can be overloaded in order to avoid interacting with the message cache but, as the source code states: "Derived classes can override this, but usually it is easier to keep the default behavior.</translate>
 +
<translate><!--T:224--> Furthermore, this prevents the MediaWiki namespace from overloading the message, as below.</translate>
 +
 +
<translate>
 +
===Localizing the Extension Name=== <!--T:225-->
 +
</translate>
 +
<translate><!--T:226--> So you've just installed a shiny new MediaWiki extension and realize: "Oh no, my wiki is in French, but the page is showing up as English!"</translate>
 +
<translate><!--T:227--> Most people wouldn't care, but it's actually a quite simple task to fix (as long as the developer used the method explained on this page).</translate>
 +
<translate><!--T:228--> No noodling around in source code.</translate>
 +
<translate><!--T:229--> Let's say the name of the page is <tvar name=DirtyPages><code>DirtyPages</code></tvar> and the name comes out to "List of Dirty Pages" but you want it to be (and [[wikipedia:Pardon my French|excuse my poor French]]) "Liste de Pages Sales".</translate>
 +
<translate><!--T:230--> Well, it's as simple as this:</translate>
 +
 +
# <translate><!--T:231--> Navigate to <tvar name=MediaWikiDirtyPages>[[MediaWiki:DirtyPages]]</tvar>, this page may not exist, but edit it anyway</translate>
 +
# <translate><!--T:232--> Insert "Liste de Pages Sales" and save</translate>
 +
 +
<translate><!--T:233--> And ''voilà'' (pardon the pun), the change is applied.</translate>
 +
 +
<translate><!--T:234--> This is also useful for customizing the title for your wiki within your language: for instance, the developer called it "List of Dirty Pages" but you don't like that name, so you rename it "List of Pages needing Cleanup".</translate> 
 +
<translate><!--T:235--> Check out <tvar name=Allmessages>[[Special:Allmessages]]</tvar> to learn more.</translate>
 +
 +
<translate><!--T:236--> Also, if your extension has a large block of text that does change, like a warning, don't directly output the text.</translate> 
 +
<translate><!--T:237--> Instead, add it to the message cache and when the time comes to output the text in your code, do this:</translate>
 +
 +
<syntaxhighlight lang="php">$wgOut->addWikiText( $this->msg( 'dirtypageshelp' ) );</syntaxhighlight>
 +
 +
<translate>
 +
<!--T:238-->
 +
Then this message too can be customized at <tvar name=Dirtypageshelp>[[MediaWiki:Dirtypageshelp]]</tvar>.
 +
 +
<!--T:239-->
 +
See also <tvar name=1>{{ll|Help:System message}}</tvar>.
 +
 +
===Restricting page access=== <!--T:240-->
 +
 +
====Do not display your Special Page on <tvar name=special>[[Special:SpecialPages]]</tvar>==== <!--T:241-->
 +
</translate>
 +
<translate><!--T:242--> Sometimes you may want to limit the visibility of your Special Page by removing it from <tvar name=special>[[Special:SpecialPages]]</tvar> and making it visible to only those users with a particular right.</translate>
 +
<translate><!--T:243--> You can do this in the [[<tvar name=1>#Constructor</tvar>|constructor]] by passing in a <tvar name=restriction><code>$restriction</code></tvar> parameter; e.g., “editinterface”, a right only assigned to sysops by default; see the [[<tvar name=UserRightsManual>Special:MyLanguage/Manual:User_rights</tvar>|User rights manual]] for other available user rights.</translate>
 +
 +
<syntaxhighlight lang="php">
 +
function __construct() {
 +
parent::__construct( 'MyExtension', 'editinterface' ); // <translate nowrap><!--T:244--> restrict to sysops</translate>
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:245--> Or you can create your own right in [[<tvar name=1>#The setup file</tvar>|the setup file]] and assign it to sysops, e.g.:</translate>
 +
 +
<syntaxhighlight lang="json">
 +
"AvailableRights": [
 +
"myextension-right"
 +
],
 +
"GroupPermissions": {
 +
"sysop": {
 +
"myextension-right": true
 +
}
 +
}
 +
</syntaxhighlight>
 +
 +
<translate><!--T:246--> and then call the constructor with your right:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
function __construct() {
 +
parent::__construct( 'MyExtension', 'myextension-right' );
 +
}
 +
</syntaxhighlight>
 +
 +
<translate>
 +
====Prevent access to your Special Page==== <!--T:247-->
 +
</translate>
 +
<translate><!--T:248--> Even if you restrict your page in the constructor, as mentioned above, it will still be viewable directly via the URL, e.g. at Special:MySpecialPage.</translate>
 +
<translate><!--T:249--> In order to actually limit access to your SpecialPage you must call <tvar name=checkPermissions>{{phpi|$this->checkPermissions()}}</tvar> in the <tvar name=execute><code>execute</code></tvar> method.</translate>
 +
 +
<translate><!--T:269--> If you need more fine-grained control over permissions, you can override <tvar name=checkPermissions>{{phpi|$this->checkPermissions()}}</tvar>, and/or add whatever permissions-checking is required for your extension.</translate>
 +
 +
<translate>
 +
===Disabling Special:UserLogin and Special:UserLogout pages=== <!--T:250-->
 +
</translate>
 +
<translate><!--T:251--> In LocalSettings.php you can use the <tvar name=Hooks>{{ll|Manual:Hooks/SpecialPage_initList|SpecialPage_initList hook}}</tvar> to ''unset'' unwanted built-in special pages.</translate>
 +
<translate><!--T:252--> See [[<tvar name=mailarchive>mailarchive:mediawiki-l/2009-June/031231.html</tvar>|"making a few SpecialPages restricted"]] if you need ''conditional'' unsetting of special pages for example for certain user groups.</translate>
 +
<translate><!--T:253--> The general message "You have requested an invalid special page." is shown if users try to access such unset special pages.</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$wgHooks['SpecialPage_initList'][] = function ( &$list ) {
 +
unset( $list['Userlogout'] );
 +
unset( $list['Userlogin'] );
 +
return true;
 +
};
 +
</syntaxhighlight>
 +
 +
<translate><!--T:274--> A different approach would be to use the <tvar name=1>DisabledSpecialPage</tvar> callback.</translate>
 +
<translate><!--T:275--> This approach may be preferred if you're only disabling the special page "temporarily", because the default message in this case would say: "<tvar name=1>{{int|disabledspecialpage-disabled}}</tvar>" instead of pretending the page does not exist at all.</translate>
 +
<translate><!--T:276--> This gives clear hint that the page maybe activated at a later time. </translate>
 +
 +
<syntaxhighlight lang="php">
 +
$wgSpecialPages['Userlogout'] = DisabledSpecialPage::getCallback( 'Userlogout' );
 +
$wgSpecialPages['Userlogin'] = DisabledSpecialPage::getCallback( 'Userlogin' );
 +
</syntaxhighlight>
 +
 +
<translate><!--T:277--> It is also possible to add custom lengthy explanation of why you're disabling the special page, by giving a message key as the second argument of the callback.</translate>
 +
<translate><!--T:278--> To do so first create a system message "<tvar name=1>MediaWiki:Userlogout-disable-reason</tvar>" and write all the explanation there.</translate>
 +
<translate><!--T:279--> The message will be parsed in a block format.</translate>
 +
<translate><!--T:280--> Then in LocalSettings.php add:</translate>
 +
 +
<syntaxhighlight lang="php">
 +
$wgSpecialPages['Userlogout'] = DisabledSpecialPage::getCallback( 'Userlogout', 'Userlogout-disable-reason' );
 +
</syntaxhighlight>
 +
 +
<translate>
 +
===Adding logs=== <!--T:254-->
 +
</translate>
 +
<translate><!--T:255--> On MediaWiki, all actions by users on wiki are tracked for transparency and collaboration.</translate>
 +
<translate><!--T:256--> See <tvar name=1>{{ll|Manual:Logging to Special:Log}}</tvar> for how to do it.</translate>
 +
 +
<translate>
 +
===Changing the groups on <tvar name=special>[[Special:Specialpages]]</tvar>=== <!--T:257-->
 +
 +
<!--T:258-->
 +
If you're an extension developer, you have to implement the <code>getGroupName()</code> method as described in [[<tvar name=1>#Special page group</tvar>|the Special page group section]] of this page.
 +
</translate>
 +
 +
<translate><!--T:259--> Since MediaWiki 1.21, the special page group can be overridden by editing a [[<tvar name=message>Special:MyLanguage/Help:System message</tvar>|system message]].</translate>
 +
<translate><!--T:260--> This method is not intended to be used by extension developers, but by site admins.</translate>
 +
<translate><!--T:261--> The group name must be placed in the <code><nowiki>specialpages-specialpagegroup-<special page name></nowiki></code> message, where <code><nowiki><special page name></nowiki></code> is the canonical name (in english) of the special page in lowercase.</translate>
 +
<translate><!--T:262--> For example, if you want to set the group under which "Special:MyLittlePage" is displayed on <tvar name=special>[[Special:Specialpages]]</tvar> to "MyLittleGroup", you just have to create "MediaWiki:Specialpages-specialpagegroup-mylittlepage" with content "MyLittleGroup".</translate>
 +
<translate><!--T:263--> "Special:MyLittlePage" will then show up under the group "MyLittleGroup", which you can name under "MediaWiki:Specialpages-group-mylittlegroup".</translate><br />
 +
<translate><!--T:264--> If you want to change the group of existing special pages, have a look on <tvar name=1>[https://www.mediawiki.org/w/index.php?title=Special:SpecialPages&uselang=qqx Special:SpecialPages&uselang=qqx]</tvar> and use those names instead of "mylittlepage".</translate>
 +
 +
<translate>
 +
===Unlisting the page from <tvar name=1>[[Special:Specialpages]]</tvar>=== <!--T:284-->
 +
</translate>
 +
<translate><!--T:285--> To remove a special page from the <tvar name=1>[[Special:Specialpages]]</tvar> altogether, pass a <tvar name=2>{{phpi|false}}</tvar> as a third parameter to the <tvar name=3>SpecialPage</tvar> parent constructor, as described in [[<tvar name=4>#Constructor</tvar>|the SpecialPage Constructor section]] of this page.</translate>
 +
<translate><!--T:286--> If you need more complicated logic to determine whether the page should be listed or not, you can also override the <tvar name=1><code>isListed()</code></tvar> function, but using the constructor parameter is simpler.</translate>
 +
 +
<translate>
 +
===Getting a list of special pages and their aliases on a wiki=== <!--T:287-->
 +
</translate>
 +
<translate><!--T:288--> Simply use the "siteinfo" API module to retrieve the information from the wiki like e.g. <tvar name=siteinfoapi>[https://www.mediawiki.org/w/api.php?action=query&meta=siteinfo&siprop=specialpagealiases /api.php?action=query&meta=siteinfo&siprop=specialpagealiases]</tvar>.</translate>
 +
<translate>
 +
==See also== <!--T:265-->
 +
</translate>
 +
*[[Special:MyLanguage/HTMLForm|HTMLForm]] – <translate><!--T:266--> Tutorial on creating checkboxes, text areas, radio buttons, etc. in special pages</translate>
 
[[Category:Персоналії]] [[Category:Person]]  
 
[[Category:Персоналії]] [[Category:Person]]  
 
[[Category:AAAAA]] [[Category:BBBB]]
 
[[Category:AAAAA]] [[Category:BBBB]]

Поточна версія на 01:35, 29 квітня 2023

test page with english text

<languages/> Шаблон:ExtensionTypes Шаблон:Dir <translate> Special pages are pages that are created by the software on demand to perform a specific function.

For example, a special page might show all pages that have one or more links to an external site or it might create a form providing user submitted feedback. </translate>

<translate> Special pages are located in their own [[<tvar name=1>Special:MyLanguage/Manual:Namespace</tvar>|namespace]] (Special:) and are not editable directly like other pages.</translate> <translate> <tvar name=1>Шаблон:Ll</tvar> can also create new special pages.</translate>

<translate> These pages by default are user-accessible and will generally show up in the list of all special pages at <tvar name=SpecialPages>Special:SpecialPages</tvar>.</translate> <translate> Some special pages are only accessible to users with certain permissions and accesses.</translate> <translate> Other special pages don't show up on the special page list at all and are only used by the wiki internally.</translate>

<translate>

General Information

</translate> <translate> All built-in special pages that come with MediaWiki are called <tvar name=php>SpecialSomename.php</tvar> and are located in the <tvar name=includes>includes/specials</tvar> directory.</translate> <translate> Core special pages must be registered in the core list located in <tvar name=1>includes/specialpage/SpecialPageFactory.php</tvar> in order to be loaded by MediaWiki.</translate> <translate> Special pages created by third party developers are generally stored in the <tvar name=extensions>extensions</tvar> directory in their own file or as part of a larger extension.</translate> <translate> All special pages inherit from a class called <tvar name=SpecialPage>Шаблон:Class doclink</tvar> which is defined in <tvar name=includesSpecialPage>includes/specialpage/SpecialPage.php</tvar>.</translate> <translate> When a new special page is created, the user rights needed to access the page can be defined.</translate> <translate> These rights specify, among other things, whether the page will show up on <tvar name=special>Special:SpecialPages</tvar> and whether the page is includable in other pages.</translate>

<translate> Special pages also have unique names that can be customized on a wiki.</translate> <translate> The general form is "Special:Pagename" where both "Special" and "Pagename" are customizable.</translate> <translate> The Special pseudo <tvar name=manual>Шаблон:Ll</tvar> can be translated in other languages.</translate> <translate> This translated namespace can be produced with the wikitext <tvar name=nsspecial>{{ns:special}}</tvar>, on this wiki giving "Спеціальна".</translate> <translate> The name of the special page can also be redefined in a system message, for the site language, with the generic name of the special page as the ID.</translate>

<translate> A special page may or may not allow input.</translate> <translate> For example, <tvar name=Export>Special:Export</tvar> allows a user to define a specific page to export by calling <tvar name=exportsun>Special:Export/Sun</tvar>.</translate> <translate> If the special page allows complex input, additional parameters will be sent to the query string component of the URL for processing, e.g. https://www.mediawiki.org/w/index.php?title=Special:Recentchanges&days=3&limit=250.</translate>

Шаблон:Note

<translate>

Basic special page template

</translate>

<translate> Most special page extensions require three files:

  • Small setup file, which loads every time MediaWiki starts.</translate>

<translate>

  • File with the bulk of the code.</translate>

<translate>

  • Localisation file

MediaWiki coding conventions define the three files like this: </translate>

  • MyExtension/extension.json - <translate> The setup file.</translate>
  • MyExtension/includes/Special.php - <translate> The special page code.</translate>
  • i18n/*.json - <translate> The <tvar name=localisation>Шаблон:Ll</tvar>.</translate>

<translate> Place all of the files in a new directory inside your MediaWiki <tvar name=extens>extensions/</tvar> directory. </translate>

<translate> You should name the special page file after the extension. For example, <tvar name=1>Шаблон:Ll</tvar> contains the file <tvar name=2>SpecialGadgets.php</tvar>.</translate> <translate> If your extension uses more than one special page, you'll need more names.</translate>

<translate> In the example below, the special page's name is MyExtension.

After creating the files listed below, adding the following line to LocalSettings.php enables the extension: </translate>

<syntaxhighlight lang=php> wfLoadExtension( 'MyExtension' ); </syntaxhighlight>

<translate>

The setup file

Example setup file for MyExtension/extension.json: </translate> <syntaxhighlight lang="json"> { "name": "MyExtension", "version": "0.0.0", "author": [ "Your Name" ], "url": "https://www.mediawiki.org/wiki/Extension:MyExtension", "descriptionmsg": "myextension-desc", "license-name": "MIT", "type": "other", "AutoloadNamespaces": { "MediaWiki\\Extension\\MyExtension\\": "src/" }, "SpecialPages": { "MyExtension": "MediaWiki\\Extension\\MyExtension\\Special" }, "MessagesDirs": { "MyExtension": [ "i18n" ] }, "manifest_version": 2, "requires": { "MediaWiki": ">= Шаблон:MW legacy branch number.0", "platform": { "php": ">= 5.6" }, "extensions": { "dependendExtension": "*" } } } </syntaxhighlight>

<translate> This file registers several important and mandatory things:

  • The location of the <tvar name=1>MediaWiki\Extension\MyExtension\Special</tvar> class;</translate>

<translate>

  • The location of the localisation files;</translate>

<translate>

  • The new special page and its class name.

The special page file

</translate> <translate> The body file (<tvar name=php>MyExtension/src/Special.php</tvar>) should contain a subclass of SpecialPage or one of its subclasses.</translate> <translate> This file loads automatically when someone requests the special page.</translate> <translate> The example below implements the subclass SpecialMyExtension.</translate>

<translate> You need the <tvar name=conduct>__construct()</tvar> constructor because its first parameter names your special page.</translate>

<translate> <tvar name=execute>execute()</tvar> is the main function called when a special page is accessed.</translate> <translate> This function overrides the function <tvar name=SpecialPage>Шаблон:Phpi</tvar>.</translate> <translate> It passes the single parameter <tvar name=par>$par</tvar>, the subpage component of the current title.</translate> <translate> For example, if someone follows a link to <tvar name=blah>Special:MyExtension/blah</tvar>, <tvar name=par1>$par</tvar> contains "blah".</translate>

<translate> You should run Wikitext and HTML output through <tvar name=1>$wgOut</tvar>. Do not use 'print' or 'echo' directly when working within the wiki's user interface.

However, if you use your special page as an access point to custom XML or binary output, see <tvar name=1>Шаблон:Ll</tvar>. </translate>

<syntaxhighlight lang="php"> <?php namespace MediaWiki\Extension\MyExtension; class SpecialMyExtension extends \SpecialPage { function __construct() { parent::__construct( 'MyExtension' ); }

function execute( $par ) { $request = $this->getRequest(); $output = $this->getOutput(); $this->setHeaders();

# <translate nowrap> Get request data from, e.g.</translate> $param = $request->getText( 'param' );

# <translate nowrap> Do stuff</translate> # ... $wikitext = 'Hello world!'; $output->addWikiTextAsInterface( $wikitext ); } } </syntaxhighlight>

Шаблон:Anchor <translate>

The localisation file

</translate>

<translate> See <tvar name=1>Шаблон:Ll</tvar> for how to get them translated.</translate>

<translate> All special pages specify a title, like <tvar name=Myextension>'My Extension'</tvar>.

  • The title is used in the <tvar name=title><title></tvar> and <tvar name=H1><h1></tvar> elements of the extension's page and on <tvar name=SpecialPages>Special:SpecialPages</tvar>.</translate>

<translate>

  • It can be anything, but should describe the special page and extension.</translate>

<translate>

  • It's specified through a message. The structure of the message is a key-value pair. The key, <tvar name=myext>'myextension'</tvar>, must be all lowercase.

An example of a localisation file in <tvar name=i18n>MyExtension/i18n/en.json</tvar>: </translate>

<syntaxhighlight lang="javascript"> { "@metadata": { "authors": [ "<your username>" ] }, "myextension": "My Extension", "myextension-desc": "Adds the MyExtension functionality.", "myextension-summary": "On this special page, do this simple thing and earn wonders.", "group-myextensionrole": "Role of myextension", "group-myextensionrole-member": "Member of role of myextension", "grouppage-myextensionrole": "Wiki:Role of myextension", "action-myextension": "XYZ doing.", "right-myextension": "to do xyz" } </syntaxhighlight>

<translate> In <tvar name=qqq>i18n/qqq.json</tvar>, the [[<tvar name=msgdoc>Special:MyLanguage/Help:System message#Message documentation</tvar>|message documentation]]:</translate>

<syntaxhighlight lang="javascript"> { "@metadata": { "authors": [ "<your username>" ] }, "myextension": "The name of the extension's entry in Special:SpecialPages", "myextension-desc": "Шаблон:Desc", "myextension-summary": "Description appearing on top of Special:MyExtension.", "action-myextension": "Шаблон:Doc-action", "right-myextension": "Шаблон:Doc-right" } </syntaxhighlight>

<translate> Note that IDs should not start with an uppercase letter, and that a space in the ID should be written in the code as an underscore.</translate>

<translate> The -summary message is optional.</translate> <translate> It's created automatically by the parent class and shown on top of the special page, usually for a concise description of what the user can do on it.</translate> <translate> If you don't define its content, it will only be used when wiki administrators customize it on the wiki.</translate>

<translate>

The aliases file

</translate> <translate> You can also internationalize the name of the special page by creating aliases for it. The example below uses the file "<tvar name=1>MyExtension.i18n.alias.php</tvar>".</translate> <translate> In this example, the special page <tvar name=MyExtension>MyExtension</tvar> registers an alias so the page becomes accessible at <tvar name=tt>.../Special:My Extension</tvar> and <tvar name=tt1>.../Spezial:Meine_Erweiterung</tvar> in German.</translate>

<translate> Add your alias file to <tvar name=file>extension.json</tvar>:</translate>

<syntaxhighlight lang="javascript"> ... "ExtensionMessagesFiles": { "MyExtensionAlias": "MyExtension.i18n.alias.php" }, ... </syntaxhighlight>

<translate> Add special page aliases to <tvar name=file>MyExtension.i18n.alias.php</tvar>:</translate>

<syntaxhighlight lang="php"> <?php /**

* Aliases for myextension
*
* @file
* @ingroup Extensions
*/

$specialPageAliases = [];

/** English

* @author <<translate nowrap> your username</translate>>
*/

$specialPageAliases['en'] = [ 'MyExtension' => [ 'MyExtension', 'My Extension' ], ];

/** Deutsch

* @author <<translate nowrap> your username</translate>>
*/

$specialPageAliases['de'] = [ 'MyExtension' => [ 'MeineErweiterung', 'Meine Erweiterung' ], ]; </syntaxhighlight>

<translate> Again, you should write a space in the ID and an underscore in the code.

For the page header and linking, the usual rules for page names apply.

If <tvar name=1>Шаблон:Ll</tvar> is true, a lowercase letter is converted to uppercase, and an underscore is displayed as a space.

For example, instead of the above, we could use <tvar name=code>'my_extension' => 'My extension'</tvar>, assuming we consistently identified the extension as <tvar name=tt2>my_extension</tvar> elsewhere.

Note that in the associative array for the English language, the string identifying our SpecialPage (<tvar name=code1>MyExtension</tvar> in the example) is also a valid title.

Also note, the first element of <tvar name=specialPageAliases>Шаблон:Phpi</tvar> must be the same as the key (<tvar name=code2>'MyExtension'</tvar>)! Otherwise <tvar name=special>Special:Specialpages</tvar> will not list the page.

Special page group

You can set which group your special page appears under on <tvar name=special>Special:SpecialPages</tvar> by overriding SpecialPage::getGroupName() in your subclass. </translate>

<syntaxhighlight lang="php">

   /**
    * <translate nowrap> Override the parent to set where the special page appears on Special:SpecialPages</translate>
    * <translate nowrap> 'other' is the default. If that's what you want, you do not need to override.</translate>
    * <translate nowrap> Specify 'media' to use the <tvar name=specialpagesgroupmedia>specialpages-group-media</tvar> system interface message, which translates to 'Media reports and uploads' in English;</translate>
    * 
    * @return string
    */
   function getGroupName() {
       return 'media';
   }

</syntaxhighlight>

<translate> Some common values are 'login', 'maintenance', 'media', 'other', 'pagetools', 'redirects', 'users'.</translate> <translate> You can see the accepted values at <tvar name=AllMessages>Special:AllMessages</tvar> (search for specialpages-group) or browse the wiki using the pseudo language 'qqx' by going to <tvar name=uselang>Special:SpecialPages?uselang=qqx</tvar>) and looking at the headings.</translate> <translate> Specify the word 'media' to use the interface message 'specialpages-group-media'.</translate>

<translate> If your special page doesn't fit into any of the preconfigured headings, you can add a new heading by adding it to your localisation file, see [[<tvar name=1>#The localisation file</tvar>|The localisation file]]).</translate>

<translate> The standard page groups that come with MediaWiki are listed in the localisation file. For example, the English messages are in <tvar name=json>languages/i18n/en.json</tvar> and begin with <tvar name=specialpagesgroup>specialpages-group-</tvar>.</translate> <translate> If you want to categorize your special page under <tvar name=users>users</tvar>, then the message is <tvar name=msg>specialpages-group-users</tvar>.</translate> <translate> The value for this key is the text that appears as the name of that category, for example, Users and rights.</translate>

<translate> If your special page does not seem to fit under any of the existing categories, you can always make a new one.</translate> <translate> In your extension's localisation file simply insert a new key for the <tvar name=messages>messages</tvar> array.</translate> <translate> In this example, we define the <tvar name=gamification>gamification</tvar> group:</translate>

<syntaxhighlight lang="json"> {

   "myextension": "My Extension",

"myextension-desc": "Adds the MyExtension functionality.", "myextension-summary": "On this special page, do this simple thing and earn wonders", "specialpages-group-gamification": "Gamification" } </syntaxhighlight>

<translate> Now, assuming you set the return value for the method SpecialPage::getGroupName() as gamification in your class definition, reload <tvar name=special>Special:SpecialPages</tvar> to see your new category.</translate>

<translate>

Other Important Files

</translate>

SpecialPage.php

<translate>

Constructor

</translate> <translate> You can overload the constructor to initialize your own data, but the main reason you would want to do it is to change the behavior of the SpecialPage class itself.</translate> <translate> When you call the base class constructor from your child class, the following parameters are available:</translate>

<syntaxhighlight lang="php"> function __construct( $name = , $restriction = , $listed = true ); </syntaxhighlight>

  • string $name <translate> Name of the special page, as seen in links and URLs</translate>
  • string $restriction <translate> [[<tvar name=userright>Special:MyLanguage/Manual:User rights</tvar>|User right]] required, e.g. "block" or "delete"; also see [[<tvar name=Restrictingpageaccess>Special:MyLanguage/Manual:Special_pages#Restricting_page_access</tvar>|Restricting page access]]</translate>
  • boolean $listed <translate> Whether the page is listed in Special:Specialpages</translate>

SpecialPage->setHeaders()

<translate> This initialises the OutputPage object <tvar name=1>$wgOut</tvar> with the name and description of your special page.</translate> <translate> It should always be called from your execute() method.</translate>

SpecialPage->getOutput()

<translate> This method returns an OutputPage object which can be accessed as described below.</translate> <translate> As in the example code, use</translate>

<syntaxhighlight lang="php"> $output = $this->getOutput(); $output->addWikiTextAsInterface( 'Hello, World' ); </syntaxhighlight>

<translate> instead of the deprecated <tvar name=1>$wgOut</tvar> global variable </translate>

SpecialPage->getRequest()

<translate> This method returns a WebRequest object which can be accessed as described below.</translate> <translate> As in the example code, use</translate>

<syntaxhighlight lang="php"> $request = $this->getRequest(); $myparam = $request->getText( 'myparam' ); </syntaxhighlight>

<translate> instead of the deprecated <tvar name=1>Шаблон:$wg</tvar> global variable</translate>

SpecialPage->including()

<translate> Some special pages can be included from within another page.</translate> <translate> For example, if you add <tvar name=1>{{Special:RecentChanges}}</tvar> to the wikitext of a page, it will insert a listing of recent changes within the existing content of the page.</translate>

<translate> Including a special page from another web page is only possible if you declared the page to be includable in the constructor.</translate> <translate> You can do this by adding the following in the <tvar name=codeconstruct>__construct()</tvar> method after the parent class initialization:</translate>

<syntaxhighlight lang="php"> $this->mIncludable = true; </syntaxhighlight>

<translate> You can also define your special page class as extending the IncludableSpecialPage class.</translate>

<translate> The SpecialPage->including() function returns a boolean value telling you what context the special page is being called from: false if it is a separate web page, and true if it is being included from within another web page.</translate> <translate> Usually you will want to strip down the presentation somewhat if the page is being included.</translate>

Шаблон:Anchor

SpecialPage->execute()

<translate> This is the function which your child class should overload.</translate> <translate> It passes a single parameter, usually referred to cryptically as <tvar name=codepar>$par</tvar> (short for $parameter, as it is the parameter the users can feed to your special page).</translate> <translate> This parameter is the subpage component of the current title.</translate> <translate> For example, if someone follows a link to <tvar name=myextensionblah>Special:MyExtension/blah</tvar>, $par will contain "blah".</translate>

<translate>

Help page

</translate>

Шаблон:MW 1.25

<translate> It's useful to add [[<tvar name=1>Special:MyLanguage/Project:PD help</tvar>|help pages]] on MediaWiki.org, where they'll be [[<tvar name=2>Special:MyLanguage/Project:Language policy</tvar>|translatable]].</translate> <translate> To make sure users find your help page, it's advisable and very simple for your special page to link the help page in question:</translate>

<syntaxhighlight lang="php"> $this->addHelpLink( 'Help:Extension:MyExtension' ); </syntaxhighlight>

OutputPage.php

<translate> OutputPage.php contains the class definition for objects of type <tvar name=OutputPage>OutputPage</tvar>.</translate> <translate> You can get an object of this class from your SpecialPage using</translate>

<syntaxhighlight lang="php"> $output = $this->getOutput(); </syntaxhighlight>

<translate> The variablename $output is, of course, arbitrary.</translate> <translate> Whatever you call it, this is the variable you will use the most, because it is the way to send output to the browser (no, you don't use <tvar name=codeecho>echo</tvar> or <tvar name=print>print</tvar>).</translate> <translate> If you want to use it somewhere, declare the variable global:</translate>

<syntaxhighlight lang="php"> function randomFunction() {

       $output = $this->getOutput();

$output->addHTML( 'This is not a pipe...' ); } </syntaxhighlight>

<translate> If you want to, you can create multiple OutputPage objects in different methods in your SpecialPage extension.</translate> <translate> They will add to the output in the order they are executed.</translate>

<translate> You can inspect the OutputPage class by viewing <tvar name=ManOutputPage>Шаблон:Ll</tvar> (indeed, all of these can be inspected), but there are a few methods you should definitely know about.</translate>

OutputPage->addHTML()

<translate> Essentially the quick and dirty substitute for <tvar name=echo>echo</tvar>.</translate> <translate> It takes your input and adds it to the buffer: no questions asked.</translate> <translate> In the below action, if <tvar name=action>$action</tvar> contains user-data, it could easily have XSS, evil stuff, or the spawn of Satan injected in.</translate> <translate> You're better off using escaping (such as with the php function htmlentities) or the XML builders class to build trusted output.</translate>

<syntaxhighlight lang="php"> $output->addHTML( '<form action="'.$action.'" method="post">' ); </syntaxhighlight>

OutputPage->addWikiText()

<translate> For most output, you should be using this function.</translate> <translate> It's a bit of a black magic function: wikitext goes in, HTML comes out, and a whole lotta arcane code and demon summonings happen in between.</translate>

<syntaxhighlight lang="php"> $output->addWikiText("This is some lovely wikitext that will get parsed nicely."); </syntaxhighlight>

<translate> What's worth noting is that the parser will view your chunks as cohesive wholes and paragraph accordingly. That is...</translate>

<syntaxhighlight lang="php"> $output->addWikiText( '* Item 1' ); $output->addWikiText( '* Item 2' ); $output->addWikiText( '* Item 3' ); </syntaxhighlight>

<translate> Will output three lists with one item each, which probably wasn't intended.</translate>

Шаблон:Warning

<translate> Note however, if you just want to insert a system message and have it treated like parsed wikitext, you can use code like <tvar name=getOutput>Шаблон:Phpi</tvar>.</translate> <translate> This will not have the issue with nested parser calls mentioned above.</translate>

<translate>

workaround #1

Important: these work arounds are only needed if you are making a transcludable special page. Normal special pages do not need these. </translate>

<translate> As a workaround, you can have your extensions convert Wikitext to HTML using a separate Parser object and then use <tvar name=addHTML>addHTML().</tvar></translate> <translate> Example:</translate>

<syntaxhighlight lang="php"> $wgOut->addHTML( $this->sandboxParse( "Here's some formatted text." ) ); </syntaxhighlight>

<syntaxhighlight lang="php">

  1. <translate nowrap> Assuming this is inside the same class as the rest of your special page code</translate>

function sandboxParse( $wikiText ) { $myParser = new Parser();

       $user = $this->getUser();
       $title = self::getTitleFor('YourCanonicalSpecialPageName');

$myParserOptions = ParserOptions::newFromUser( $user ); $result = $myParser->parse( $wikiText, $title, $myParserOptions ); return $result->getText(); } </syntaxhighlight>

<translate>

workaround #2

</translate> <translate> I tried the above, and found that the same problem now applied to any tags in the transcluded text.</translate> <translate> This won't be a problem for a lot of extensions, but the extension I was writing was intended to show wikitext from another page as part of its functionality, so this was a problem.</translate>

<translate> The process for parsing a page which transcludes a special page seems to be this:</translate>

  1. <translate> Replace <tvar name=special5>{{Special:MyExtension}}</tvar> with a UNIQ-QINU marker (because SpecialPage output is expected to be ready-to-output HTML)</translate>
  2. <translate> Replace any tags with QINU markers as above</translate>
  3. <translate> Parse everything else from wikitext to HTML</translate>
  4. <translate> Replace all QINU markers with their respective stored values, in a single pass</translate>

<translate> The process for parsing a page which transcludes a non-special page, though, is apparently like this:</translate>

  1. <translate> Replace <tvar name=1>{{:Normal Article Name}}</tvar> or <tvar name=2>{{Template Name}}</tvar> with contents of transcluded page (because transcluded pages contain unparsed wikitext)</translate>
  2. <translate> Replace any tags with QINU markers as above</translate>
  3. <translate> Parse everything else from wikitext to HTML</translate>
  4. <translate> Replace all QINU markers with their respective stored values, in a single pass</translate>

<translate> The problem is apparently that in the earlier case, the parsing of the SpecialPage's wiki text is lacking the final QINU decoding step (why?), so all the QINU markers are left undecoded.</translate> <translate> (This may be a leftover from using the same syntax to invoke transclusion of a wikitext page, which is just pasted straight into the host page's wikitext contents and parsed, as is used to invoke transclusion of a SpecialPage, which must not be parsed at all. Wherever the code is that decides "wait, this is a special page -- replace it with a QINU", it should be doing the extra unstripGeneral before doing the QINU substitution.)</translate> Шаблон:Void

<translate> So I just did the following -- after this line:</translate> <syntaxhighlight lang="php">$htOut = $wgParser->recursiveTagParse( $iText );</syntaxhighlight> <translate> ...I added these lines (the second one is only because the function definition for the first one recommends it):</translate> <syntaxhighlight lang="php"> $htOut = $wgParser->mStripState->unstripGeneral( $htOut ); $htOut = $wgParser->mStripState->unstripNoWiki( $htOut ); </syntaxhighlight> <translate> Since I have now documented this, of course, I will now find a tragic flaw with it and feel really stupid... but as long as it seems to be working, I had to note it here.</translate> <translate> (It is also important to note the problem with work-around #1.)</translate> <translate> Also, I have only tested this with MediaWiki 1.10.1.</translate> <translate> The problem still exists under MW 1.14, but this solution may or may not work.</translate> --Woozle 18:26, 9 April 2009 (UTC)

OutputPage->showErrorPage()

<translate> An error page is shown.</translate> <translate> The arguments <tvar name=codetitle>$title</tvar> and <tvar name=msg>$msg</tvar> specify keys into <tvar name=1>$this->msg()</tvar>, not text.</translate> <translate> An example:</translate>

<syntaxhighlight lang="php"> $output->showErrorPage( 'error', 'badarticleerror' ); </syntaxhighlight>

  • <translate> '<tvar name=1>error</tvar>' refers to the text "<tvar name=2>Шаблон:Int</tvar>".</translate>
  • <translate> '<tvar name=1>badarticleerror</tvar>' refers to the text "<tvar name=2>Шаблон:Int</tvar>".</translate>

<translate> You can also specify message objects or add parameters:</translate>

<syntaxhighlight lang="php"> $output->showErrorPage( 'error', 'badarticleerror', [ 'param1', 'param2' ] ); </syntaxhighlight> <syntaxhighlight lang="php"> $messageObject = new Message(...); ... $output->showErrorPage( 'error', $messageObject ); </syntaxhighlight> <syntaxhighlight lang="php"> $titleMessageObject = new Message(...); $messageObject = new Message(...); ... $output->showErrorPage( $titleMessageObject, $messageObject ); </syntaxhighlight>

WebRequest.php

<translate> The <tvar name=1>Шаблон:Manual</tvar> class is used to obtain information from the GET and POST arrays.</translate> <translate> Using this is recommended over directly accessing the superglobals.</translate> <translate> The WebRequest object is accessible from extensions by using the <tvar name=RequestContext>Шаблон:Ll</tvar>.</translate>

Database.php

<translate> MediaWiki has a load of convenience functions and wrappers for interacting with the database, using the <tvar name=1>Шаблон:Manual</tvar> class.</translate> <translate> It also has an interesting load balancing scheme in place.</translate> <translate> It's recommended you use these wrappers.</translate> <translate> Check out <tvar name=Database>Шаблон:Ll</tvar> for a complete listing of all the convenience functions, because these docs will only tell you about the non-obvious caveats.</translate> <translate> See <tvar name=1>Шаблон:Ll</tvar>.</translate>

User.php

<translate> The <tvar name=1>Шаблон:Manual</tvar> class is used to represent users on the system.</translate> <translate> <tvar name=1>SpecialPage->getUser()</tvar> should be used to obtain a <tvar name=2>User</tvar> object for the currently logged in user.</translate> <translate> The use of the global <tvar name=1>$wgUser</tvar> is deprecated</translate>

Title.php

<translate> Title represents the name of a page in the wiki.</translate> <translate> This is useful because MediaWiki does all sorts of fun escaping and special case logic to page names, so instead of rolling your own convert title to URL function, you create a Title object with your page name, and then use <tvar name=escapeLocalURL>getLocalURL()</tvar> to get a URL to that page.</translate>

<translate> To get a title object for your special page from outside of the special page class, you can use <tvar name=SpecialPageYourCanonical>Шаблон:Phpi</tvar>.</translate> <translate> It will give you a localised title in the wiki's language.</translate>

<translate>

Custom special pages

There are various ways to provide your own special pages not bundled within MediaWiki: </translate>

  • <translate> One method is to install an extension that generates a form to create or edit an article. A list of extensions currently available, can be found at <tvar name=category>Шаблон:Ll</tvar>.</translate>
  • <translate> You can also write an extension which provides your own special page. Writing your own extension requires PHP coding skill and comfort with object oriented design and databases also is helpful. You will also need to know how to use code to create and edit MediaWiki articles. For more information, please see [[<tvar name=Articleswithembeddedforms>Special:MyLanguage/Manual:Forms#Articles_with_embedded_forms</tvar>|this discussion]].</translate>
  • <translate> You can also display a custom page through JavaScript, in place of the default error message "Unknown special page" (or the "This page is intentionally left blank." message, if using a subpage of Special:BlankPage). In MediaWiki:Common.js, check for <tvar name=1>Шаблон:Ll</tvar>, then hide the MediaWiki-generated content (just appendCSS <tvar name=visibility>{visibility:hidden;}</tvar> ), and inject custom HTML (<tvar name=innerHTML>innerHTML</tvar>) into the <tvar name=bodyContent>document.getElementById('bodyContent')</tvar> or <tvar name=mwcontentholder>document.getElementById('mw_contentholder')</tvar>. For an example, see meta:User:Krinkle/Tools/Real-Time Recent Changes.</translate>

<translate>

FAQ

Setting an Extension Title

</translate> <translate> MediaWiki does not set the title of the extension, which is the developer's job.</translate> <translate> It will look for the name of the extension when <tvar name=special>Special:Specialpages</tvar> is called or the special page is loaded.</translate> <translate> In the <tvar name=1>function execute( $par )</tvar> section, use OutputPage methods to title the extension like: <tvar name=setPageTitle>Шаблон:Phpi</tvar></translate>

<translate> The place where the extension can be found (as specified by what is passed into the SpecialPage constructor) is the key--except that it is not capitalized because of <tvar name=getDescription>getDescription()</tvar>, the internally used function that finds out the title (or, what they call description) of the special page, <tvar name=strtolower>strtolower</tvar> the name.</translate> <translate> "ThisIsACoolSpecialPage"'s key would be "thisisacoolspecialpage."</translate>

<translate> Theoretically, <tvar name=getDescription1>getDescription</tvar> can be overloaded in order to avoid interacting with the message cache but, as the source code states: "Derived classes can override this, but usually it is easier to keep the default behavior.</translate> <translate> Furthermore, this prevents the MediaWiki namespace from overloading the message, as below.</translate>

<translate>

Localizing the Extension Name

</translate> <translate> So you've just installed a shiny new MediaWiki extension and realize: "Oh no, my wiki is in French, but the page is showing up as English!"</translate> <translate> Most people wouldn't care, but it's actually a quite simple task to fix (as long as the developer used the method explained on this page).</translate> <translate> No noodling around in source code.</translate> <translate> Let's say the name of the page is <tvar name=DirtyPages>DirtyPages</tvar> and the name comes out to "List of Dirty Pages" but you want it to be (and excuse my poor French) "Liste de Pages Sales".</translate> <translate> Well, it's as simple as this:</translate>

  1. <translate> Navigate to <tvar name=MediaWikiDirtyPages>MediaWiki:DirtyPages</tvar>, this page may not exist, but edit it anyway</translate>
  2. <translate> Insert "Liste de Pages Sales" and save</translate>

<translate> And voilà (pardon the pun), the change is applied.</translate>

<translate> This is also useful for customizing the title for your wiki within your language: for instance, the developer called it "List of Dirty Pages" but you don't like that name, so you rename it "List of Pages needing Cleanup".</translate> <translate> Check out <tvar name=Allmessages>Special:Allmessages</tvar> to learn more.</translate>

<translate> Also, if your extension has a large block of text that does change, like a warning, don't directly output the text.</translate> <translate> Instead, add it to the message cache and when the time comes to output the text in your code, do this:</translate>

<syntaxhighlight lang="php">$wgOut->addWikiText( $this->msg( 'dirtypageshelp' ) );</syntaxhighlight>

<translate> Then this message too can be customized at <tvar name=Dirtypageshelp>MediaWiki:Dirtypageshelp</tvar>.

See also <tvar name=1>Шаблон:Ll</tvar>.

Restricting page access

Do not display your Special Page on <tvar name=special>Special:SpecialPages</tvar>

</translate> <translate> Sometimes you may want to limit the visibility of your Special Page by removing it from <tvar name=special>Special:SpecialPages</tvar> and making it visible to only those users with a particular right.</translate> <translate> You can do this in the [[<tvar name=1>#Constructor</tvar>|constructor]] by passing in a <tvar name=restriction>$restriction</tvar> parameter; e.g., “editinterface”, a right only assigned to sysops by default; see the [[<tvar name=UserRightsManual>Special:MyLanguage/Manual:User_rights</tvar>|User rights manual]] for other available user rights.</translate>

<syntaxhighlight lang="php"> function __construct() { parent::__construct( 'MyExtension', 'editinterface' ); // <translate nowrap> restrict to sysops</translate> } </syntaxhighlight>

<translate> Or you can create your own right in [[<tvar name=1>#The setup file</tvar>|the setup file]] and assign it to sysops, e.g.:</translate>

<syntaxhighlight lang="json"> "AvailableRights": [ "myextension-right" ], "GroupPermissions": { "sysop": { "myextension-right": true } } </syntaxhighlight>

<translate> and then call the constructor with your right:</translate>

<syntaxhighlight lang="php"> function __construct() { parent::__construct( 'MyExtension', 'myextension-right' ); } </syntaxhighlight>

<translate>

Prevent access to your Special Page

</translate> <translate> Even if you restrict your page in the constructor, as mentioned above, it will still be viewable directly via the URL, e.g. at Special:MySpecialPage.</translate> <translate> In order to actually limit access to your SpecialPage you must call <tvar name=checkPermissions>Шаблон:Phpi</tvar> in the <tvar name=execute>execute</tvar> method.</translate>

<translate> If you need more fine-grained control over permissions, you can override <tvar name=checkPermissions>Шаблон:Phpi</tvar>, and/or add whatever permissions-checking is required for your extension.</translate>

<translate>

Disabling Special:UserLogin and Special:UserLogout pages

</translate> <translate> In LocalSettings.php you can use the <tvar name=Hooks>Шаблон:Ll</tvar> to unset unwanted built-in special pages.</translate> <translate> See [[<tvar name=mailarchive>mailarchive:mediawiki-l/2009-June/031231.html</tvar>|"making a few SpecialPages restricted"]] if you need conditional unsetting of special pages for example for certain user groups.</translate> <translate> The general message "You have requested an invalid special page." is shown if users try to access such unset special pages.</translate>

<syntaxhighlight lang="php"> $wgHooks['SpecialPage_initList'][] = function ( &$list ) { unset( $list['Userlogout'] ); unset( $list['Userlogin'] ); return true; }; </syntaxhighlight>

<translate> A different approach would be to use the <tvar name=1>DisabledSpecialPage</tvar> callback.</translate> <translate> This approach may be preferred if you're only disabling the special page "temporarily", because the default message in this case would say: "<tvar name=1>Шаблон:Int</tvar>" instead of pretending the page does not exist at all.</translate> <translate> This gives clear hint that the page maybe activated at a later time. </translate>

<syntaxhighlight lang="php"> $wgSpecialPages['Userlogout'] = DisabledSpecialPage::getCallback( 'Userlogout' ); $wgSpecialPages['Userlogin'] = DisabledSpecialPage::getCallback( 'Userlogin' ); </syntaxhighlight>

<translate> It is also possible to add custom lengthy explanation of why you're disabling the special page, by giving a message key as the second argument of the callback.</translate> <translate> To do so first create a system message "<tvar name=1>MediaWiki:Userlogout-disable-reason</tvar>" and write all the explanation there.</translate> <translate> The message will be parsed in a block format.</translate> <translate> Then in LocalSettings.php add:</translate>

<syntaxhighlight lang="php"> $wgSpecialPages['Userlogout'] = DisabledSpecialPage::getCallback( 'Userlogout', 'Userlogout-disable-reason' ); </syntaxhighlight>

<translate>

Adding logs

</translate> <translate> On MediaWiki, all actions by users on wiki are tracked for transparency and collaboration.</translate> <translate> See <tvar name=1>Шаблон:Ll</tvar> for how to do it.</translate>

<translate>

Changing the groups on <tvar name=special>Special:Specialpages</tvar>

If you're an extension developer, you have to implement the getGroupName() method as described in [[<tvar name=1>#Special page group</tvar>|the Special page group section]] of this page. </translate>

<translate> Since MediaWiki 1.21, the special page group can be overridden by editing a [[<tvar name=message>Special:MyLanguage/Help:System message</tvar>|system message]].</translate> <translate> This method is not intended to be used by extension developers, but by site admins.</translate> <translate> The group name must be placed in the specialpages-specialpagegroup-<special page name> message, where <special page name> is the canonical name (in english) of the special page in lowercase.</translate> <translate> For example, if you want to set the group under which "Special:MyLittlePage" is displayed on <tvar name=special>Special:Specialpages</tvar> to "MyLittleGroup", you just have to create "MediaWiki:Specialpages-specialpagegroup-mylittlepage" with content "MyLittleGroup".</translate> <translate> "Special:MyLittlePage" will then show up under the group "MyLittleGroup", which you can name under "MediaWiki:Specialpages-group-mylittlegroup".</translate>
<translate> If you want to change the group of existing special pages, have a look on <tvar name=1>Special:SpecialPages&uselang=qqx</tvar> and use those names instead of "mylittlepage".</translate>

<translate>

Unlisting the page from <tvar name=1>Special:Specialpages</tvar>

</translate> <translate> To remove a special page from the <tvar name=1>Special:Specialpages</tvar> altogether, pass a <tvar name=2>Шаблон:Phpi</tvar> as a third parameter to the <tvar name=3>SpecialPage</tvar> parent constructor, as described in [[<tvar name=4>#Constructor</tvar>|the SpecialPage Constructor section]] of this page.</translate> <translate> If you need more complicated logic to determine whether the page should be listed or not, you can also override the <tvar name=1>isListed()</tvar> function, but using the constructor parameter is simpler.</translate>

<translate>

Getting a list of special pages and their aliases on a wiki

</translate> <translate> Simply use the "siteinfo" API module to retrieve the information from the wiki like e.g. <tvar name=siteinfoapi>/api.php?action=query&meta=siteinfo&siprop=specialpagealiases</tvar>.</translate> <translate>

See also

</translate>

  • HTMLForm – <translate> Tutorial on creating checkboxes, text areas, radio buttons, etc. in special pages</translate>
Developed by Інститут Програмних Систем