Jump to content

Příručka:Modely obsahu stránek

From mediawiki.org
This page is a translated version of the page Manual:Page content models and the translation is 100% complete.
Pro content pages vs. non-content pages se podívejte na stránku: Manual:Using custom namespaces#Content namespaces.

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 .

Varování Varování: Některé části této stránky jsou zastaralé. V MW 1,38 byly Content::getParserOutput a AbstractContent::fillParserOutput tvrdě znehodnoceny ve prospěch ContentRenderer::getParserOutput. Rozšíření definující model obsahu by měla přepsat ContentHandler::fillParserOutput.

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