Příručka:Registrace rozšíření
Verze MediaWiki: | ≥ 1.25 Gerrit change 166705 |
Registrace rozšíření je mechanismus, který používá MediaWiki pro načítání rozšíření (extensions) a vzhledů (skins).
Konfigurační data se zapisují do souboru s názvem extension.json
, či v případě grafického vzhledu skin.json
, který by měl být umístěn v kořenovém adresáři vašeho rozšíření nebo vzhledu. A ten MediaWiki použije k registraci vašeho rozšíření, či grafického vzhledu (skinu).
Změna, kterou musí udělat administrátor na straně serveru
Až do verze 1.25 se registrace rozšíření a vzhledů MediaWiki prováděla prostřednictvím PHP souboru, pojmenovaného názvem rozšíření, resp. vzhledu. Např. MyExtension.php
či MySkin.php
.
require_once "$IP/extensions/Hello/Hello.php";
require_once "$IP/extensions/FooBar/FooBar.php";
$wgFooBarEnable = true;
require_once "$IP/skins/Baz/Baz.php";
require_once "/tmp/extension/some/where/else/BarFoo/BarFoo.php";
Výše uvedený kód, pokud máte vytvořen odpovídající registrační soubory ve formátu JSON, pak můžete změnit následovně:
wfLoadExtensions( [ 'Hello', 'FooBar' ] );
$wgFooBarEnable = true;
wfLoadSkin( 'Baz' );
wfLoadExtension( 'BarFoo', '/tmp/extension/some/where/else/BarFoo/extension.json' );
Vlastní umístění
Toto je nutné provést před načtením jakýchkoli rozšíření nebo vzhledů z nestandardních umístění adresáře:
- Pokud svá rozšíření uchováváte na jiném místě než
$IP/extensions
, musíte přepsat$wgExtensionDirectory
nebo použít druhý parametrwfLoadExtension()
k určení adresáře, ve kterém chcete rozšíření najít.- Pokud je jedno nebo více vašich rozšíření uloženo v dalších umístěních, použijte druhý parametr
wfLoadExtension()
k určení umístění souboru.json
pro každé z těchto rozšíření. wfLoadExtensions()
(množné číslo) vždy používá$wgExtensionDirectory
a nelze jej přepsat.
- Pokud je jedno nebo více vašich rozšíření uloženo v dalších umístěních, použijte druhý parametr
$wgExtensionDirectory = '/some/path'; wfLoadExtension( 'FooBar' ); // Hledá $wgExtensionDirectory na /some/path/FooBar/extension.json wfLoadExtension( 'Hello', '/some/other/path/HelloV2/Hello.json' ); // Hledá na /some/other/path/HelloV2/Hello.json
- Pokud vaše vzhledy nejsou v
$IP/skins
, musíte přepsat špatně pojmenovaný$wgStyleDirectory
, nebo použít druhý parametrwfLoadSkin()
, abyste určili adresář, ve kterém se má vzhled najít.- Pokud je jeden nebo více vašich vzhledů uloženo v dalších umístěních, použijte druhý parametr
wfLoadSkin()
k určení umístění souboru.json
pro každý z těchto vzhledů. wfLoadSkins()
(množné číslo) vždy používá$wgStyleDirectory
a nelze jej přepsat.
- Pokud je jeden nebo více vašich vzhledů uloženo v dalších umístěních, použijte druhý parametr
$wgStyleDirectory = '/my/skins'; wfLoadSkins( [ 'BarBaz', 'BazBar' ] ); // Vyhledá v $wgStyleDirectory za oba /my/skins/BarBaz/skin.json a /my/skins/BazBar/skin.json wfLoadSkin( 'BamBam', '/yet/another/path/BamBam/skin.json' ); // Hledá na /yet/another/path/BamBam/skin.json
Migrace pro vývojáře rozšíření
Od MW 1.30 mohou být ID jmenného prostoru definovaná lokálně v extension.json
před načtením rozšíření přepsána definováním příslušné konstanty v LocalSettings.php
.
Zvažte například následující deklaraci jmenného prostoru v souboru extension.json
:
"namespaces": [
{
"id": 1212,
"constant": "NS_FOO",
"name": "Foo"
},
{
"id": 1213,
"constant": "NS_FOO_TALK",
"name": "Foo_Talk"
}
]
To by ve výchozím nastavení způsobilo, že konstanta NS_FOO bude definována na hodnotu 1212. Toto však lze přepsat definováním příslušné konstanty v LocalSettings.php:
define( 'NS_FOO', 6688 );
define( 'NS_FOO_TALK', 6689 );
wfLoadExtension( "Foo" );
To by způsobilo, že jmenný prostor "Foo" bude registrován s ID 6688 namísto 1212. Při přepisování ID jmenného prostoru nezapomeňte, že všechny jmenné prostory talk musí mít lichá ID a ID jmenného prostoru talk musí být vždy ID jmenného prostoru subjektu plus jedna.
Skript maintenance/convertExtensionToRegistration.php
vám pomůže s migrací ze vstupních bodů PHP do souboru metadat JSON.
Pokud vaše rozšíření podporuje starší verze MediaWiki, měli byste si ponechat vstupní bod PHP FooBar/FooBar.php
, dokud neukončíte podporu pro tyto starší verze.
Ukázky příkazových řádků:
$ cd core
$ php maintenance/convertExtensionToRegistration.php extensions/MassMessage/MassMessage.php
$ php maintenance/convertExtensionToRegistration.php skins/MonoBook/MonoBook.php --skin
Možná budete muset odinstalovat své rozšíření z LocalSettings.php
, pokud se zobrazí chyby, že konstanty nebo funkce nelze předefinovat.
Soubor vstupního bodu PHP (FooBar.php) byste měli nahradit něčím podobným, jako je následující, aby nedošlo k přerušení wiki během procesu upgradu.
<?php
if ( function_exists( 'wfLoadExtension' ) ) {
wfLoadExtension( 'FooBar' );
// Udržujte i18n globals, aby se mergeMessageFileList.php nezměnil
$wgMessagesDirs['FooBar'] = __DIR__ . '/i18n';
$wgExtensionMessagesFiles['FooBarAlias'] = __DIR__ . '/FooBar.alias.php';
wfWarn(
'Deprecated PHP entry point used for the FooBar extension. ' .
'Please use wfLoadExtension() instead, ' .
'see https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extension_registration for more details.'
);
return;
} else {
die( 'This version of the FooBar extension requires MediaWiki 1.29+' );
}
Nebo vzhledů
<?php
if ( function_exists( 'wfLoadSkin' ) ) {
wfLoadSkin( 'FooBar' );
// Udržujte i18n globals, aby se mergeMessageFileList.php nezměnil
$wgMessagesDirs['FooBar'] = __DIR__ . '/i18n';
$wgExtensionMessagesFiles['FooBarAlias'] = __DIR__ . '/FooBar.alias.php';
wfWarn(
'Deprecated PHP entry point used for the FooBar skin. Please use wfLoadSkin instead, ' .
'see https://www.mediawiki.org/wiki/Extension_registration for more details.'
);
return;
} else {
die( 'This version of the FooBar skin requires MediaWiki 1.25+' );
}
Uchovávání dokumentace
Vstupní body PHP mají obvykle nějakou dokumentaci konfiguračních nastavení, která je užitečná a neměla by se ztratit.
Bohužel JSON nepodporuje komentáře. Doporučuje se přenést konfigurační dokumentaci do souboru README
v úložišti rozšíření.
Konfiguraci byste také měli zdokumentovat na wiki na stránce Rozšíření:MyExtension.
Část dokumentace je také možné zahrnout přímo do souboru extension.json
.
Registrace rozšíření ignoruje jakýkoli klíč v extension.json
začínající znakem '@
' ve struktuře nejvyšší úrovně, takže do těchto částí souboru JSON můžete vkládat komentáře. Například:
{
"@note": "This file must be kept in sync with LocalisationUpdate.php",
"@name": ...
Verze 1 formátu extension.json
také umožňovala @note
v sekci config
, ale to již není doporučeno ani podporováno ve verzi 2. Místo toho by mělo být použito pole description
konfigurační proměnné.
Toto by mělo být použito pouze pro krátké poznámky a komentáře.
Funkce
Pokud načítáte velký počet rozšíření, registrace rozšíření poskytne zvýšení výkonu, pokud máte nainstalováno APC (nebo APCu). Rozšíření načtená společně s wfLoadExtensions
(s množným číslem -s) budou uložena do mezipaměti společně.
Atributy
Neustálý problémem byl v tom, jak něco "zaregistrovat" pro jiné rozšíření.
Obvykle to znamenalo, že se nějaké rozšíření muselo načíst dřív než jiné.
Například VisualEditor, který pracoval s proměnnou $wgVisualEditorPluginModules
, do které mohly ostatní rozšíření přidávat své moduly.
Nepočítal s tím, že by už mohla existovat, takže ji v kódu inicializoval takto:
$wgVisualEditorPluginModules = [];
Takže pokud si do ní nějaké rozšíření přidalo svůj záznam před načtením VisualEditoru, byl zahozen.
Některá rozšíření závisela na konkrétním pořadí načítání, jiná to obcházela pomocí $wgExtensionFunctions
.
Registrace rozšíření řeší tento problém pomocí "atributů".
V rozšíření Math by jeho extension.json
mělo něco jako:
{
"VisualEditorPluginModules": [
"ext.math.visualEditor"
]
}
Počínaje verzí 2 musí být atributy definovány v samostatné sekci attributes
.
Attributes
musí být objekt s názvem rozšíření jako klíčem a objektem párů atribut/hodnota jako hodnotou. Pamatujte, že klíč v podobjektu nesmí obsahovat název rozšíření!
{
"attributes": {
"VisualEditor": {
"PluginModules": [
"ext.math.visualEditor"
]
}
},
"manifest_version": 2
}
Když chce VisualEditor získat přístup k tomuto atributu, použije:
ExtensionRegistry::getInstance()->getAttribute( 'VisualEditorPluginModules' );
Požadavky (závislosti)
Registrace rozšíření má sekci requires
(vyžaduje), která funguje podobně jako sekce require
Composeru.
Umožňuje vývojáři rozšíření specifikovat několik požadavků na rozšíření, jako je konkrétní verze MediaWiki (nebo vyšší/menší než) nebo jiné rozšíření/vzhled.
Chcete-li například přidat závislost na verzi MediaWiki, která je větší než 1.26.0, můžete do extension.json
přidat následující kód: [1]
{
"requires": {
"MediaWiki": ">= 1.26.0"
}
}
Klíč objektu requires
je název závislosti (před MediaWiki 1.29.0 byla podporována pouze MediaWiki
), hodnota je platné omezení verze (formát je podle volby autora).
V MediaWiki 1.29.0 a vyšší můžete také přidat závislosti na vzhledech a dalších rozšířeních, jako jsou:
{
"requires": {
"MediaWiki": ">= 1.29.0",
"extensions": {
"ExampleExtension": "*"
},
"skins": {
"ExampleSkin": "*"
}
}
}
- Rozšíření a vzhledy uvedené zde, aby fungovaly, musí také používat systém registrace rozšíření popsaný na této stránce.
- Řetězec přidaný k určení přípony nebo vzhledu musí být shodný s řetězcem uvedeným v poli "name" příslušného souboru "extension.json" nebo "skin.json".
- Pro rozšíření využívající kontinuální integrace Wikimedie, je také třeba přidat závislosti do zuul/parameter_functions.py
V MediaWiki 1.33.0 (?!??) a výše můžete také přidat závislosti na PHP, jako je:
{
"requires": {
"MediaWiki": ">= 1.33.0",
"platform": {
"php": ">= 7.0.3"
}
}
}
Zkontrolujte, zda je rozšíření načteno, aniž by bylo ve skutečnosti vyžadováno
Mnoho rozšíření může poskytovat funkce, které fungují pouze v případě, že je načteno i jiné rozšíření, aniž by tuto funkci skutečně potřebovali pro fungování základní funkce rozšíření. Jako příklad: Pokud je načteno rozšíření B, může rozšíření A poskytovat skutečný WYSIWYG editor, jinak bude používat jednoduchou textovou oblast. Rozšíření A může těžit z rozšíření B (pokud je načteno), ale ke správnému fungování nevyžaduje, aby bylo načteno. Za tímto účelem obvykle zkontrolujete, zda je rozšíření načteno, spíše než jej přidáte jako tvrdou závislost.
Pro implementaci standardizovaného způsobu kontroly, zda je rozšíření načteno nebo ne (bez nutnosti práce navíc v rozšíření, která je v jiném rozšíření měkkou závislostí), lze použít registraci rozšíření. Implementuje metodu isLoaded
, která vrací jednoduchý boolean, pokud je rozšíření načteno nebo ne (aby to fungovalo, musí být rozšíření načteno s registrací rozšíření). Příklad:
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB' ) ) {
// používejte pouze v případě, že je načteno rozšíření B
}
Verze MediaWiki: | ≥ 1.32 Gerrit change 455752 |
Od MediaWiki 1.32 je také možné zkontrolovat, zda je rozšíření načteno a zda splňuje dané omezení verze:
if ( ExtensionRegistry::getInstance()->isLoaded( 'ExtensionB', '>=1.2' ) ) {
// používejte pouze v případě, že je načteno rozšíření B a má verzi 1.2 nebo vyšší.
}
Pokud byste chtěli zkontrolovat, zda je v dřívějších verzích MediaWiki načtena konkrétní verze rozšíření, lze podobné informace extrahovat pomocí metody getAllThings
, která vrací informace o kreditu pro všechna načtená rozšíření. Příklad:
$bVersion = ExtensionRegistry::getInstance()->getAllThings()['ExtensionB']['version'] ?? null;
if ( $bVersion !== null && version_compare( $bVersion, '2.1.0', '>=' ) ) {
// používejte pouze v případě, že je načteno rozšíření B a má číslo verze větší nebo rovné 2.1.0
}
Alternativně, pokud rozšíření B definuje speciální konstantu určenou pro tento účel během načítání, je možné zkontrolovat, zda je definována:
if ( defined( 'ExtensionBVersion' ) ) { // You could also check for a version, if the constant holds the version
// používejte pouze v případě, že je načteno rozšíření B
}
Křehčím způsobem, kterému je třeba se vyhnout, je zkontrolovat, zda specifická třída rozšíření B existuje nebo ne, např. pomocí tohoto kódu:
if ( class_exists( 'ExtensionBHooks' ) ) {
// používejte pouze v případě, že existují třídy rozšíření B
}
To může přestat fungovat, pokud přípona existuje v systému souborů, ale není načtena, např. pokud byl pro automatické načítání použit composer. Pokud byla třída přejmenována nebo přestane existovat (např. protože není balíček public), dojde také k přerušení.
Obecně je upřednostňováno sdílení kódu prostřednictvím komponent pro composer namísto rozšíření. Pokud třídy rozšíření potřebují pouze existovat, ale rozšíření nemusí být konfigurováno ani načteno, pro to, co chcete dělat, je to silný indikátor toho, že by tento kód měl být rozdělen na komponentu composer, na kterou byste se měli spolehnout. namísto.
Configs (Vaše nastavení rozšíření/vzhledů)
Ve výchozím nastavení extension.json
předpokládá, že vaše konfigurační nastavení začíná předponou "wg".
Pokud tomu tak není, můžete předponu přepsat pomocí speciálního klíče:
{
"config": {
"_prefix": "eg",
"MyExtSetting": true
}
}
To by použilo předponu "eg" a nastavilo globální proměnnou $egMyExtSetting
na hodnotu true.
Počínaje zveřejněním verze 2 poskytuje konfigurační sekce registrace rozšíření mnohem více funkcí a umožňuje vám popsat možnosti konfigurace mnohem podrobněji. Namísto jediného klíče -> úložiště hodnot pro možnosti konfigurace můžete také přidat následující informace.
Obecná struktura config
se mírně mění na následující, více objektově orientovanou verzi:
{
"config_prefix": "eg",
"config": {
"MyExtSetting": {
"value": true,
"path": false,
"description": "Popis konfigurace",
"descriptionmsg": "myextension-config-myextsetting",
"public": true
}
},
"manifest_version": 2
}
value
Hodnota konfigurace se přesunula na toto místo. Toto je jediný požadovaný klíč pro konfigurační objekt.
path
Booleovská hodnota klíče path
identifikuje, zda má být hodnota konfigurační volby interpretována jako cesta souborového systému vzhledem ke kořenu adresáře rozšíření.
Pokud je například hodnota konfigurace myFile.png
a path
je pravdivá, skutečná hodnota bude /path/to/the/wiki/extensions/MyExtension/myFile.png
.
description
Klíč description
pro možnost konfigurace může obsahovat nelokalizovaný řetězec, který lze použít k vysvětlení možnosti konfigurace dalším vývojářům nebo uživatelům (správcům systému) vašeho rozšíření.
Může být také použit jako popisný text v sekci parametrů informačního pole rozšíření na stránce popisu rozšíření MediaWiki.org.
Hodnota klíče popisu obvykle není vystavena frontendu wiki, ale podívejte se do přehledu, kde najdete další informace, jak by se tato funkce mohla v budoucnu používat!
descriptionmsg
Existuje také možnost přidat klíč zprávy interního lokalizačního systému MediaWiki jako popis (descriptionmsg
), který bude v budoucnu použit k odhalení popisu v rozhraní instalace MediaWiki.
public / private
Tato volba je booleovská, jejíž výchozí hodnota je false
, což znamená, že konfigurační volba a hodnota jsou označeny jako "private".
Tato hodnota se momentálně nikde nepoužívá, podívejte se do přehledu, kde se o této možnosti dozvíte více.
Výhled
Výše uvedené změny jsou také přípravnými kroky pro vylepšenou správu konfigurace v MediaWiki. Výše uvedené změny nám umožňují např. odhalit možnosti konfigurace rozšíření v uživatelském rozhraní MediaWiki. K tomu je zapotřebí zpráva s lokalizovaným popisem (descriptionmsg
a description
) a indikace, zda má být konfigurační volba (public
) veřejná nebo ne.
Automatické zjišťování testů jednotek
MediaWiki umožňuje libovolné rozšíření pro registraci testů phpunit. Bez registrace rozšíření byste museli zaregistrovat obslužný program pro háček UnitTestsList , který by vypadal asi takto:
public static function onUnitTestsList( array &$paths ) {
$paths[] = __DIR__ . '/tests/phpunit/';
}
(jak je popsáno v příručce). Tento kód však vypadá stejně pro mnoho rozšíření, takže byste to mohli nazvat zbytečnou duplikací kódu.
Pokud vaše rozšíření používá registraci rozšíření a vaše testy phpunit jsou umístěny v podadresáři tests/phpunit/
vašeho rozšíření, wraper phpunit MediaWiki automaticky objeví testy jednotek pomocí registrace rozšíření.
Proto již nemusíte háček registrovat a nemusíte specifikovat, že vaše testy jednotek jsou uloženy ve výchozím adresáři.
Přizpůsobení registrace
Také composer.json
Pokud má rozšíření nebo vzhled knihovny závislosti, může je mít také soubor composer.json
, viz Manual:Composer.json best practices . Použijte pole load_composer_autoloader
, aby MediaWiki používala automatické načítání Composer, když je to vhodné.
Některá pole metadat se překrývají mezi extension.json
a composer.json
(diskutované v úkol T89456), včetně:
url
ahomepage
license-name
alicense
Správce kódu
- Spravováno Core Platform tým .
- Živý chat (IRC): #mediawiki-core připojit se
- Nástroj pro sledování problémů: Phabricator MediaWiki-Configuration (nahlášení problému)
Související stránky
- Příručka:extension.json/Schéma
- Hlášení chyb v projektu MediaWiki-Configuration.
- Staré verze Manual:Developing extensions#Setup (před květnem 2015) a
$wgExtensionCredits
popisují starý přístup deklarování informací o rozšíření v kódu PHP a proměnných - Známá omezení
- Přehled architektury
docs/extension.schema.v2.json
je schéma proextension.json
(a skin.json).- RfC o implementaci registrace rozšíření
- Zeď superschopností pro registraci rozšíření! — přehled rozšíření, která je ještě třeba převést.
- úkol T98668 — Sledovací karta pro převod všech rozšíření a vzhledů na Gitu pro použití registrace rozšíření.