Příručka:Modely obsahu stránek
ContentHandler představený v MediaWiki 1.21 vám umožňuje přidávat nové modely obsahu jiné než wikitext. Umožňuje, aby stránky wiki byly složeny z jiných dat než wikitext a byly reprezentovány jakýmkoli způsobem – například: Markdown, reStructuredText, icalendar nebo vlastní formát XML. Zobrazení a úpravy těchto modelů obsahu lze provádět vlastními způsoby (např. různé zvýraznění syntaxe nebo zcela nové formuláře pro zadávání dat).
Tato stránka popisuje, jak vytvořit nový model obsahu v rozšíření. Předpokládá určitou znalost obecných postupů vývoje rozšíření. Stručné shrnutí požadavků naleznete v sekci Souhrn ve spodní části této stránky.
Pro příklady bude použit nesmyslný obsahový model "Goat". Můžete také prozkoumat rozšíření DataPages, které je součástí Extension:Examples .
Registrace
Nejprve přidejte název modelu obsahu a třídu manipulátoru do svého extension.json:
"ContentHandlers": {
"goat": "MediaWiki\\Extension\\GoatExt\\GoatContentHandler"
}
- Hodnota vlevo je zde název typu obsahu, může to být libovolný jedinečný řetězec, který chcete, a existuje vedle pěti vestavěných typů obsahu: 'wikitext', 'JavaScript', 'CSS', 'plain text', 'JSON'. Tato hodnota je uživatelům vystavena na místech, jako jsou Special:ChangeContentModel a informace o stránce.
- Hodnota napravo je plně kvalifikovaný název třídy, která přesahuje ContentHandler.
To bude vyžadovat vytvoření dvou nových tříd, například \MediaWiki\Extension\GoatExt\GoatContent
a \MediaWiki\Extension\GoatExt\GoatContentHandler
(ujistěte se, že jejich jmenný prostor je registrován v AutoloadNamespaces).
Další informace o těchto třídách jsou uvedeny níže.
Volitelné konstanty modelu obsahu
Řetězec 'goat' výše je model obsahu IS (v kódu se obecně nazývá $modelId
) a je obvykle také definován jako konstanta.
Tyto konstanty jsou definovány pro všechny modely vestavěného obsahu a mnoho dokumentace odkazuje na konstanty "CONTENT_MODEL_XXX".
Pokud jste je nedefinovali, může to být trochu matoucí.
Definice by měla být provedena prostřednictvím položky zpětné volání v extension.json
. Například:
V extension.json
:
"callback": "MediaWiki\\Extension\\GoatExt\\Hooks::registrationCallback"
V includes/Hooks.php
:
namespace MediaWiki\Extension\GoatExt;
class Hooks {
public static function registrationCallback() {
// Must match the name used in the 'ContentHandlers' section of extension.json
define( 'CONTENT_MODEL_GOAT', 'goat' );
}
}
Nemusíte to dělat tímto způsobem a můžete použít pouze řetězec.
Přiřazení modelů obsahu ke stránkám
U stránek lze ručně změnit typ obsahu, ale je užitečné mít je jako výchozí na správný. Dva běžné způsoby, jak toho dosáhnout, jsou podle jmenného prostoru a podle přípony souboru.
Podle jmenného prostoru: Pokud chcete, aby měl celý jmenný prostor wiki výchozí model obsahu, můžete jej jako takový definovat v extension.json:
"namespaces": [
{
"id": 550,
"constant": "NS_GOAT",
"name": "Goat",
"subpages": false,
"content": true,
"defaultcontentmodel": "goat"
},
{
"id": 551,
"constant": "NS_GOAT_TALK",
"name": "Goat_talk",
"subpages": true,
"content": false,
"defaultcontentmodel": "wikitext"
}
]
Upozorňujeme, že publikovaná rozšíření by měla zaregistrovat ID jmenného prostoru, která používají (550
a 551
výše) na stránce Výchozí jmenné prostory rozšíření .
Podle přípony souboru: Pokud chcete určit typ obsahu přidáním přípony typu kvazi souboru k názvu stránky wiki, můžete použít háček ContentHandlerDefaultModelFor . Například:
namespace MediaWiki\Extension\GoatExt;
class Hooks {
public static function onContentHandlerDefaultModelFor( \Title $title, &$model ) {
// Any page title (in any namespace) ending in '.goat'.
$ext = '.goat';
if ( substr( $title->getText(), -strlen( $ext ) ) === $ext ) {
// This is the constant you defined earlier.
$model = CONTENT_MODEL_GOAT;
// If you change the content model, return false.
return false;
}
// If you don't change it, return true.
return true;
}
}
ContentHandler
Další věcí, kterou je třeba definovat, je třída GoatContentHandler, kde také určujeme, v jakém formátu bude tento typ obsahu uložen (v tomto případě text). ContentHandlers nevědí nic o žádném konkrétním obsahu stránky, ale určují obecnou strukturu a uložení obsahu.
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContentHandler extends \ContentHandler {
public function __construct( $modelId = 'goat' ) {
parent::__construct( $modelId, [ CONTENT_FORMAT_TEXT ] );
}
public function serializeContent( \Content $content, $format = null ) {
}
public function unserializeContent( $blob, $format = null ) {
}
public function makeEmptyContent() {
return new GoatContent();
}
public function supportsDirectEditing() {
return true;
}
}
Obsah
Třída GoatContent
představuje data obsahu a neví nic o stránkách, revizích ani o tom, jak jsou uloženy v databázi.
Kromě požadovaných sedmi zděděných metod můžete přidat další veřejné metody, které jsou specifické pro doménu. V tomto případě chceme být schopni získat jméno Goat.
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContent extends \AbstractContent {
public function __construct( $modelId = 'goat' ) {
parent::__construct( $modelId );
}
public function getTextForSearchIndex() {
}
public function getWikitextForTransclusion() {
}
public function getTextForSummary( $maxLength = 250 ) {
}
public function getNativeData() {
}
public function getSize() {
}
public function copy() {
}
public function isCountable( $hasLinks = null ) {
}
public function getName() {
return 'Garry';
}
}
Úprava formuláře
Teď už máme kostru nastavenou, budeme chtít zkusit upravit Goat.
Za tímto účelem vytvoříme GoatContentHandler::getActionOverrides()
a určíme, jaké akce chceme mapovat na jaké třídy.
Pro začátek se budeme zabývat pouze 'edit' (což odpovídá ?action=edit
v URL).
public function getActionOverrides() {
return [
'edit' => GoatEditAction::class,
];
}
A vytvoříme naši novou třídu GoatEditAction
, v podstatě stejnou jako základní EditAction
, ale použijeme naše vlastní GoatEditPage
:
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatEditAction extends \EditAction {
public function show() {
$this->useTransactionalTimeLimit();
$editPage = new GoatEditPage( $this->getArticle() );
$editPage->setContextTitle( $this->getTitle() );
$editPage->edit();
}
}
Naše nová třída GoatEditPage
je místem, kde se akce odehrává (omluvte slovní hříčku):
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatEditPage extends \MediaWiki\EditPage\EditPage {
protected function showContentForm() {
$out = $this->context->getOutput();
// Get the data.
$name = $this->getCurrentContent()->getGoatName();
// Create the form.
$nameField = new \OOUI\FieldLayout(
new \OOUI\TextInputWidget( [ 'name' => 'goat_name', 'value' => $name ] ),
[ 'label' => 'Name', 'align' => 'left' ]
);
$out->addHTML( $nameField );
}
}
Nyní byste měli být schopni upravit stránku a zobrazit svůj formulář. Ale když do něj vložíte data a stisknete 'náhled', uvidíte, že věci ještě nefungují plně a že nemáte žádný výstup, ani se váš odeslaný text znovu nezobrazuje ve formuláři.
Musíme tedy přepsat i akci 'odeslat' novou třídou GoatSubmitAction
a přidáním 'submit' => GoatSubmitAction::class,
k naší metodě GoatContentHandler::getActionOverrides()
.
Naše třída GoatSubmitAction
by měla být stejná jako třída core, ale dědit z našich GoatEditAction
.
Zobrazení
Model obsahu je odpovědný za vytváření jakéhokoli požadovaného výstupu pro zobrazení. To obvykle zahrnuje práci s jeho daty a vytváření HTML nějakým způsobem, který se přidá k výstupu analyzátoru.
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContent extends \AbstractContent {
protected function fillParserOutput(
Title $title, $revId, ParserOptions $options, $generateHtml, ParserOutput &$output
) {
// e.g. $output->setText( $html );
}
}
Zobrazení popis/dokumentace
Někdy můžete chtít zobrazit nějaké informace nebo nějakou dokumentaci k článku, který má vlastní model obsahu, jako je JSON. Ve skutečnosti neexistují systémové zprávy pro zobrazení nějakého textu nad takovými stránkami (kromě MediaWiki:Clearyourcache zobrazených pouze nad stránkami JavaScript a CSS). Možná budete chtít vidět phab:T206395 pro další podrobnosti.
Porovnání revizí
Třída GoatDifferenceEngine
představuje rozdíl mezi obsahem Goat.
Přepíšeme výchozí metodu generateContentDiffBody
pro generování rozdílu.
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatDifferenceEngine extends \DifferenceEngine {
public function generateContentDiffBody( Content $old, Content $new ) {
}
}
Abychom MediaWiki řekli, aby použila náš GoatDifferenceEngine
, přepíšeme getDiffEngineClass
na naše GoatContentHandler
.
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContentHandler extends \ContentHandler {
public function getDiffEngineClass() {
return GoatDifferenceEngine::class;
}
}
Shrnutí
Chcete-li implementovat nový model obsahu s vlastním formulářem pro úpravy, vytvořte následující:
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContent extends \AbstractContent {
public function __construct( $modelId = 'goat' ) {
parent::__construct($modelId);
}
protected function fillParserOutput( \Title $title, $revId, \ParserOptions $options, $generateHtml, \ParserOutput &$output) {}
public function getTextForSearchIndex() {}
public function getWikitextForTransclusion() {}
public function getTextForSummary( $maxLength = 250 ) {}
public function getNativeData() {}
public function getSize() {}
public function copy() {}
public function isCountable( $hasLinks = null ) {}
}
<?php
namespace MediaWiki\Extension\GoatExt;
class GoatContentHandler extends \ContentHandler {
public function __construct( $modelId = CONTENT_MODEL_GOAT, $formats = ['text/x-goat'] ) {
parent::__construct($modelId, $formats);
}
protected function getContentClass() {}
public function supportsDirectEditing() {}
public function serializeContent( \Content $content, $format = null ) {}
public function unserializeContent( $blob, $format = null ) {}
public function makeEmptyContent() {}
public function getActionOverrides() {}
}
Související odkazy
- Manual:Hooks/ContentHandlerDefaultModelFor
- Nápověda:ChangeContentModel - pro dokumentaci pro koncového uživatele o změně modelu obsahu.
- Extension:Examples - pro příklad vlastního modelu obsahu (ale zatím ne pro vlastní editační formulář).