Aude has uploaded a new change for review. https://gerrit.wikimedia.org/r/269396
Change subject: New deployment build: wmf/1.27.0-wmf.13 ...................................................................... New deployment build: wmf/1.27.0-wmf.13 adds ArticlePlaceholder, which we want to enable on the test wikis. Change-Id: Ia6cc31c92f6d044c9cccfaf9ec3a3f9805bf2e2e --- M composer.json M composer.lock A extensions/ArticlePlaceholder/.gitignore A extensions/ArticlePlaceholder/.gitreview A extensions/ArticlePlaceholder/.jscsrc A extensions/ArticlePlaceholder/.jshintignore A extensions/ArticlePlaceholder/.jshintrc A extensions/ArticlePlaceholder/ArticlePlaceholder.alias.php A extensions/ArticlePlaceholder/ArticlePlaceholder.php A extensions/ArticlePlaceholder/Gruntfile.js A extensions/ArticlePlaceholder/Specials/SpecialAboutTopic.php A extensions/ArticlePlaceholder/composer.json A extensions/ArticlePlaceholder/i18n/ast.json A extensions/ArticlePlaceholder/i18n/cs.json A extensions/ArticlePlaceholder/i18n/de.json A extensions/ArticlePlaceholder/i18n/en.json A extensions/ArticlePlaceholder/i18n/eo.json A extensions/ArticlePlaceholder/i18n/es.json A extensions/ArticlePlaceholder/i18n/eu.json A extensions/ArticlePlaceholder/i18n/fr.json A extensions/ArticlePlaceholder/i18n/gl.json A extensions/ArticlePlaceholder/i18n/it.json A extensions/ArticlePlaceholder/i18n/ja.json A extensions/ArticlePlaceholder/i18n/jv.json A extensions/ArticlePlaceholder/i18n/ko.json A extensions/ArticlePlaceholder/i18n/ksh.json A extensions/ArticlePlaceholder/i18n/ku-latn.json A extensions/ArticlePlaceholder/i18n/lb.json A extensions/ArticlePlaceholder/i18n/lt.json A extensions/ArticlePlaceholder/i18n/mk.json A extensions/ArticlePlaceholder/i18n/mr.json A extensions/ArticlePlaceholder/i18n/ms.json A extensions/ArticlePlaceholder/i18n/oc.json A extensions/ArticlePlaceholder/i18n/om.json A extensions/ArticlePlaceholder/i18n/pl.json A extensions/ArticlePlaceholder/i18n/ps.json A extensions/ArticlePlaceholder/i18n/qqq.json A extensions/ArticlePlaceholder/i18n/ru.json A extensions/ArticlePlaceholder/i18n/sd.json A extensions/ArticlePlaceholder/i18n/sr-ec.json A extensions/ArticlePlaceholder/i18n/sr-el.json A extensions/ArticlePlaceholder/i18n/su.json A extensions/ArticlePlaceholder/i18n/sv.json A extensions/ArticlePlaceholder/i18n/tr.json A extensions/ArticlePlaceholder/i18n/tt-cyrl.json A extensions/ArticlePlaceholder/i18n/yi.json A extensions/ArticlePlaceholder/i18n/zh-hans.json A extensions/ArticlePlaceholder/i18n/zh-hant.json A extensions/ArticlePlaceholder/includes/Hooks.php A extensions/ArticlePlaceholder/includes/Lua/Identifier.lua A extensions/ArticlePlaceholder/includes/Lua/Scribunto_LuaArticlePlaceholderLibrary.php A extensions/ArticlePlaceholder/includes/Lua/mw.ext.articlePlaceholder.entityRenderer.lua A extensions/ArticlePlaceholder/includes/SearchHookHandler.php A extensions/ArticlePlaceholder/includes/Template/aboutTopic-template-module.xml A extensions/ArticlePlaceholder/modules/ext.articleplaceholder.createArticle.js A extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplay.css A extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplaySmall.css A extensions/ArticlePlaceholder/package.json A extensions/ArticlePlaceholder/phpcs.xml A extensions/ArticlePlaceholder/tests/phpunit/Specials/SpecialAboutTopicTest.php A extensions/ArticlePlaceholder/tests/phpunit/includes/HooksTest.php A extensions/ArticlePlaceholder/tests/phpunit/includes/SearchHookHandlerTest.php M vendor/composer/installed.json 63 files changed, 2,346 insertions(+), 3 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata refs/changes/96/269396/1 diff --git a/composer.json b/composer.json index 56225ec..4b6f089 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ ], "require": { "php": ">=5.3.0", + "mediawiki/article-placeholder": "dev-master", "propertysuggester/property-suggester": "~2.4.2", "wikibase/wikibase": "dev-wmf/1.27.0-wmf.12", "wikibase/wikimedia-badges": "dev-master", @@ -53,4 +54,4 @@ "classmap-authoritative": true, "preferred-install": "dist" } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index 2b74ad9..396150c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "79f06d4a6277edaa1ec67ee83b6f4e0d", - "content-hash": "eb15b534279575172797aeb34570b551", + "hash": "5c3a1d30068cbc37c03c3fa26784fdbf", + "content-hash": "6ef12e3509d6635a2efc6f8578b7dd4b", "packages": [ { "name": "composer/installers", @@ -773,6 +773,38 @@ "time": "2015-03-17 15:21:21" }, { + "name": "mediawiki/article-placeholder", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git", + "reference": "d3fff7b3144c9ba020380f08018c225e42ce49d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/d3fff7b3144c9ba020380f08018c225e42ce49d7", + "reference": "d3fff7b3144c9ba020380f08018c225e42ce49d7", + "shasum": "" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "0.5.1" + }, + "type": "mediawiki-extension", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Lucie-Aimée Kaffee" + } + ], + "description": "Provides a special page with Wikibase information about a certain topic, with invitation to create an article for the topic", + "homepage": "https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder", + "time": "2016-02-08 12:46:34" + }, + { "name": "propertysuggester/property-suggester", "version": "2.4.5", "source": { @@ -1528,6 +1560,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "mediawiki/article-placeholder": 20, "wikibase/wikibase": 20, "wikibase/wikimedia-badges": 20, "wikibase/wikidata.org": 20, diff --git a/extensions/ArticlePlaceholder/.gitignore b/extensions/ArticlePlaceholder/.gitignore new file mode 100644 index 0000000..f8cf2c3 --- /dev/null +++ b/extensions/ArticlePlaceholder/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +npm-debug.log + diff --git a/extensions/ArticlePlaceholder/.gitreview b/extensions/ArticlePlaceholder/.gitreview new file mode 100644 index 0000000..4fe5c65 --- /dev/null +++ b/extensions/ArticlePlaceholder/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=mediawiki/extensions/ArticlePlaceholder.git +defaultbranch=master +defaultrebase=0 diff --git a/extensions/ArticlePlaceholder/.jscsrc b/extensions/ArticlePlaceholder/.jscsrc new file mode 100644 index 0000000..8bb503d --- /dev/null +++ b/extensions/ArticlePlaceholder/.jscsrc @@ -0,0 +1,12 @@ +{ + "preset": "wikimedia", + "jsDoc": { + "checkAnnotations": { + "preset": "jsduck5", + "extra": { + "license": true, + "licence": true + } + } + } +} diff --git a/extensions/ArticlePlaceholder/.jshintignore b/extensions/ArticlePlaceholder/.jshintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/extensions/ArticlePlaceholder/.jshintignore @@ -0,0 +1 @@ +node_modules diff --git a/extensions/ArticlePlaceholder/.jshintrc b/extensions/ArticlePlaceholder/.jshintrc new file mode 100644 index 0000000..d123347 --- /dev/null +++ b/extensions/ArticlePlaceholder/.jshintrc @@ -0,0 +1,22 @@ +{ + // Enforcing + "bitwise": true, + "eqeqeq": true, + "latedef": true, + "noarg": true, + "nonew": true, + "undef": true, + "unused": true, + "strict": false, + + // Environment + "browser": true, + + "globals": { + "mw": false, + "$": false, + "jQuery": false, + "mediaWiki": false, + "OO": false + } +} diff --git a/extensions/ArticlePlaceholder/ArticlePlaceholder.alias.php b/extensions/ArticlePlaceholder/ArticlePlaceholder.alias.php new file mode 100644 index 0000000..42e7a35 --- /dev/null +++ b/extensions/ArticlePlaceholder/ArticlePlaceholder.alias.php @@ -0,0 +1,15 @@ +<?php +/** + * Aliases for special pages for extension ArticlePlaceholder + * + * @file + * @ingroup Extensions + */ +// @codingStandardsIgnoreFile + +$specialPageAliases = array(); + +/** English (English) */ +$specialPageAliases['en'] = array( + 'AboutTopic' => array( 'AboutTopic', 'FancyUnicorn' ), +); diff --git a/extensions/ArticlePlaceholder/ArticlePlaceholder.php b/extensions/ArticlePlaceholder/ArticlePlaceholder.php new file mode 100644 index 0000000..14d27cd --- /dev/null +++ b/extensions/ArticlePlaceholder/ArticlePlaceholder.php @@ -0,0 +1,80 @@ +<?php + +/** + * AticlePlaceholder extension + * + * @ingroup Extensions + * + * @author Lucie-Aimée Kaffee + * + * The license governing the extension code: + * @license GNU General Public Licence 2.0 or later + */ +$wgExtensionCredits['other'][] = array( + 'path' => __FILE__, + 'name' => 'ArticlePlaceholder', + 'author' => array( + 'Lucie-Aimée Kaffee', + ), + 'url' => 'https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder', + 'descriptionmsg' => 'articleplaceholder-desc', +); + +$wgArticlePlaceholderImageProperty = 'P18'; + +$wgAutoloadClasses['ArticlePlaceholder\Specials\SpecialAboutTopic'] + = __DIR__ . '/Specials/SpecialAboutTopic.php'; +$wgAutoloadClasses['ArticlePlaceholder\Lua\Scribunto_LuaArticlePlaceholderLibrary'] + = __DIR__ . '/includes/Lua/Scribunto_LuaArticlePlaceholderLibrary.php'; +$wgAutoloadClasses['ArticlePlaceholder\Hooks'] = __DIR__ . '/includes/Hooks.php'; +$wgAutoloadClasses['ArticlePlaceholder\SearchHookHandler'] + = __DIR__ . '/includes/SearchHookHandler.php'; + +$wgHooks['ScribuntoExternalLibraries'][] + = '\ArticlePlaceholder\Hooks::onScribuntoExternalLibraries'; +$wgHooks['ScribuntoExternalLibraryPaths'][] + = '\ArticlePlaceholder\Hooks::registerScribuntoExternalLibraryPaths'; +$wgHooks['SpecialSearchResultsAppend'][] + = '\ArticlePlaceholder\SearchHookHandler::onSpecialSearchResultsAppend'; + +$wgHooks['UnitTestsList'][] = 'ArticlePlaceholder\Hooks::onUnitTestsList'; + +$wgMessagesDirs['ArticlePlaceholder'] = __DIR__ . '/i18n'; +$wgExtensionMessagesFiles['ArticlePlaceholderAliases'] = __DIR__ . '/ArticlePlaceholder.alias.php'; + +$wgSpecialPages['AboutTopic'] = array( + 'ArticlePlaceholder\Specials\SpecialAboutTopic', + 'newFromGlobalState' +); + +preg_match( '+' . preg_quote( DIRECTORY_SEPARATOR ) . '(?:vendor|extensions)' + . preg_quote( DIRECTORY_SEPARATOR ) . '.*+', __DIR__, $remoteExtPath ); + +$commonModuleInfo = array( + 'localBasePath' => __DIR__ . '/modules', + 'remoteExtPath' => '..' . $remoteExtPath[0] . '/modules', +); + +$wgResourceModules['ext.articleplaceholder.createArticle'] = array( + 'position' => 'bottom', + 'scripts' => 'ext.articleplaceholder.createArticle.js', + 'dependencies' => array( + 'oojs-ui', + 'mediawiki.api', + 'mediawiki.Title', + 'mediawiki.util' + ), + 'messages' => array( + 'articleplaceholder-abouttopic-create-article', + 'articleplaceholder-abouttopic-article-exists-error', + 'articleplaceholder-abouttopic-create-article-submit-button' + ), +) + $commonModuleInfo; + +$wgResourceModules['ext.articleplaceholder.defaultDisplay'] = array( + 'styles' => array( + 'ext.articleplaceholder.defaultDisplay.css', + 'ext.articleplaceholder.defaultDisplaySmall.css' => array( 'media' => '(max-width: 880px)' ), + ), + 'position' => 'top', +) + $commonModuleInfo; diff --git a/extensions/ArticlePlaceholder/Gruntfile.js b/extensions/ArticlePlaceholder/Gruntfile.js new file mode 100644 index 0000000..56ff218 --- /dev/null +++ b/extensions/ArticlePlaceholder/Gruntfile.js @@ -0,0 +1,35 @@ +/*jshint node:true */ +module.exports = function ( grunt ) { + grunt.loadNpmTasks( 'grunt-contrib-jshint' ); + grunt.loadNpmTasks( 'grunt-jsonlint' ); + grunt.loadNpmTasks( 'grunt-banana-checker' ); + grunt.loadNpmTasks( 'grunt-jscs' ); + + grunt.initConfig( { + jshint: { + options: { + jshintrc: true + }, + all: [ + '*.js', + 'modules/**/*.js' + ] + }, + jscs: { + src: '<%= jshint.all %>' + }, + banana: { + all: 'i18n/' + }, + jsonlint: { + all: [ + '*.json', + '**/*.json', + '!node_modules/**' + ] + } + } ); + + grunt.registerTask( 'test', [ 'jshint', 'jscs', 'jsonlint', 'banana' ] ); + grunt.registerTask( 'default', 'test' ); +}; diff --git a/extensions/ArticlePlaceholder/Specials/SpecialAboutTopic.php b/extensions/ArticlePlaceholder/Specials/SpecialAboutTopic.php new file mode 100644 index 0000000..cc93f3e --- /dev/null +++ b/extensions/ArticlePlaceholder/Specials/SpecialAboutTopic.php @@ -0,0 +1,343 @@ +<?php + +namespace ArticlePlaceholder\Specials; + +use Html; +use OOUI; +use SiteStore; +use SpecialPage; +use Title; +use Wikibase\Client\Store\TitleFactory; +use Wikibase\Client\WikibaseClient; +use Wikibase\DataModel\Entity\EntityIdParser; +use Wikibase\DataModel\Entity\EntityIdParsingException; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Services\Lookup\EntityLookup; +use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory; +use Wikibase\Lib\Store\SiteLinkLookup; + +/** + * The AboutTopic SpecialPage for the ArticlePlaceholder extension + * + * @ingroup Extensions + * @author Lucie-Aimée Kaffee + * @license GNU General Public Licence 2.0 or later + */ +class SpecialAboutTopic extends SpecialPage { + + public static function newFromGlobalState() { + $wikibaseClient = WikibaseClient::getDefaultInstance(); + return new self( + $wikibaseClient->getEntityIdParser(), + $wikibaseClient->getLanguageFallbackLabelDescriptionLookupFactory(), + $wikibaseClient->getStore()->getSiteLinkLookup(), + $wikibaseClient->getSiteStore(), + new TitleFactory(), + $wikibaseClient->getSettings()->getSetting( 'siteGlobalID' ), + $wikibaseClient->getStore()->getEntityLookup() + ); + } + + /** + * @var EntityIdParser + */ + private $idParser; + + /** + * @var LanguageFallbackLabelDescriptionLookupFactory + */ + private $termLookupFactory; + + /** + * @var SitelinkLookup + */ + private $sitelinkLookup; + + /** + * @var SiteStore + */ + private $siteStore; + + /** + * @var TitleFactory + */ + private $titleFactory; + + /** + * @var string + */ + private $siteGlobalID; + + /** + * @var EntityLookup + */ + private $entityLookup; + + /** + * Initialize the special page. + */ + public function __construct( + EntityIdParser $idParser, + LanguageFallbackLabelDescriptionLookupFactory $termLookupFactory, + SiteLinkLookup $sitelinkLookup, + SiteStore $siteStore, + TitleFactory $titleFactory, + $siteGlobalID, + EntityLookup $entityLookup + ) { + $this->idParser = $idParser; + $this->termLookupFactory = $termLookupFactory; + $this->sitelinkLookup = $sitelinkLookup; + $this->siteStore = $siteStore; + $this->titleFactory = $titleFactory; + $this->siteGlobalID = $siteGlobalID; + $this->entityLookup = $entityLookup; + + parent::__construct( 'AboutTopic' ); + } + + /** + * @param string|null $sub + */ + public function execute( $sub ) { + $this->setHeaders(); + $this->showContent( $sub ); + } + + /** + * @param string|null $entityIdString + */ + private function showContent( $entityIdString ) { + $entityId = $this->getItemIdParam( 'entityid', $entityIdString ); + + if ( $entityId === null ) { + $this->createForm(); + return; + } + if ( !$this->entityLookup->hasEntity( $entityId ) ) { + $this->createForm(); + $message = $this->msg( 'articleplaceholder-abouttopic-no-entity-error' ); + $this->getOutput()->addWikiText( $message->text() ); + return; + } + + $articleOnWiki = $this->getArticleOnWiki( $entityId ); + + if ( $articleOnWiki !== null ) { + $this->getOutput()->redirect( $articleOnWiki ); + } else { + $this->showPlaceholder( $entityId ); + } + } + + /** + * @see SpecialPage::getDescription + * + * @return string + */ + public function getDescription() { + return $this->msg( 'articleplaceholder-abouttopic' )->text(); + } + + protected function getGroupName() { + return 'other'; + } + + /** + * Create html elements + */ + protected function createForm() { + // Form header + $this->getOutput()->addHTML( + Html::openElement( + 'form', + array( + 'method' => 'get', + 'action' => $this->getPageTitle()->getFullUrl(), + 'name' => 'ap-abouttopic', + 'id' => 'ap-abouttopic-form1', + 'class' => 'ap-form' + ) + ) + ); + + // Form elements + $this->getOutput()->addHTML( $this->getFormElements() ); + + // Form body + $this->getOutput()->addHTML( + Html::input( + 'submit', + $this->msg( 'articleplaceholder-abouttopic-submit' )->text(), + 'submit', + array( 'id' => 'submit' ) + ) + . Html::closeElement( 'fieldset' ) + . Html::closeElement( 'form' ) + ); + } + + /** + * Returns the form elements. + * + * @return string + * @todo exchange all those . Html::element( 'br' ) with something pretty + */ + protected function getFormElements() { + return Html::rawElement( + 'p', + array(), + $this->msg( 'articleplaceholder-abouttopic-intro' )->parse() + ) + . Html::element( 'br' ) + . Html::element( + 'label', + array( + 'for' => 'ap-abouttopic-entityid', + 'class' => 'ap-label' + ), + $this->msg( 'articleplaceholder-abouttopic-entityid' )->text() + ) + . Html::element( 'br' ) + . Html::input( + 'entityid', + $this->getRequest()->getVal( 'entityid' ), + 'text', array( + 'class' => 'ap-input', + 'id' => 'ap-abouttopic-entityid' + ) + ) + . Html::element( 'br' ); + } + + private function getTextParam( $name, $fallback ) { + $value = $this->getRequest()->getText( $name, $fallback ); + return trim( $value ); + } + + /** + * @param string $name + * @param string $fallback + * + * @return ItemId|null + * @throws @todo UserInputException + */ + private function getItemIdParam( $name, $fallback ) { + $rawId = $this->getTextParam( $name, $fallback ); + + if ( $rawId === '' ) { + return null; + } + + try { + $id = $this->idParser->parse( $rawId ); + if ( !( $id instanceof ItemId ) ) { + throw new EntityIdParsingException(); + } + + return $id; + } catch ( EntityIdParsingException $ex ) { + // @todo proper Exception Handling + $this->getOutput()->addWikiText( $ex->getMessage() ); + } + + return null; + } + + /** + * Show placeholder and include template to call lua module + * @param ItemId $entityId + */ + private function showPlaceholder( ItemId $entityId ) { + $this->getOutput()->addWikiText( '{{aboutTopic|' . $entityId->getSerialization() . '}}' ); + $label = $this->getLabel( $entityId ); + $this->showTitle( $label ); + $this->showCreateArticle( $label ); + $this->showLanguageLinks( $entityId ); + } + + private function showCreateArticle( $label ) { + $output = $this->getOutput(); + + $output->enableOOUI(); + $modules = array( + 'ext.articleplaceholder.createArticle', + 'ext.articleplaceholder.defaultDisplay' + ); + $output->addModules( $modules ); + $output->addJsConfigVars( 'apLabel', $label ); + + $button = new OOUI\ButtonWidget( array( + 'id' => 'create-article-button', + 'infusable' => true, + 'label' => $this->msg( 'articleplaceholder-abouttopic-create-article-button' )->text(), + 'target' => 'blank' + ) ); + + $output->addHTML( $button ); + } + + /** + * @param ItemId $entityId + * @return string|null label + */ + private function getLabel( ItemId $entityId ) { + $label = $this->termLookupFactory->newLabelDescriptionLookup( $this->getLanguage() ) + ->getLabel( $entityId ); + + if ( $label !== null ) { + return $label->getText(); + } + + return null; + } + + /** + * Show label as page title + * @param string|null $label + */ + private function showTitle( $label ) { + if ( $label !== null ) { + $this->getOutput()->setPageTitle( htmlspecialchars( $label ) ); + } + } + + /** + * Set language links + * @param ItemId $entityId + * @todo set links to other projects in sidebar, too! + */ + private function showLanguageLinks( ItemId $entityId ) { + $siteLinks = $this->sitelinkLookup->getSiteLinksForItem( $entityId ); + $languageLinks = array(); + + foreach ( $siteLinks as $siteLink ) { + $languageCode = $this->siteStore->getSite( $siteLink->getSiteId() )->getLanguageCode(); + + if ( $languageCode !== null ) { + $languageLinks[$languageCode] = $languageCode . ':' . $siteLink->getPageName(); + } + } + + $this->getOutput()->setLanguageLinks( $languageLinks ); + } + + /** + * @param ItemId $entityId + * @return Title + */ + private function getArticleOnWiki( ItemId $entityId ) { + $sitelinkTitles = $this->sitelinkLookup->getLinks( + array( $entityId->getNumericId() ), + array( $this->siteGlobalID ) + ); + + if ( isset( $sitelinkTitles[0][1] ) ) { + $sitelinkTitle = $sitelinkTitles[0][1]; + return $this->titleFactory->newFromText( $sitelinkTitle )->getLinkURL(); + } + + return null; + } + +} diff --git a/extensions/ArticlePlaceholder/composer.json b/extensions/ArticlePlaceholder/composer.json new file mode 100644 index 0000000..b939a11 --- /dev/null +++ b/extensions/ArticlePlaceholder/composer.json @@ -0,0 +1,26 @@ +{ + "name": "mediawiki/article-placeholder", + "type": "mediawiki-extension", + "description": "Provides a special page with Wikibase information about a certain topic, with invitation to create an article for the topic", + "homepage": "https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder", + "license": "GPL-2.0+", + "authors": [ + { + "name": "Lucie-Aimée Kaffee" + } + ], + "support": { + "issues": "https://phabricator.wikimedia.org/", + "irc": "irc://irc.freenode.net/wikidata" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "0.5.1" + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor", + "phpcs -p -s" + ] + } +} diff --git a/extensions/ArticlePlaceholder/i18n/ast.json b/extensions/ArticlePlaceholder/i18n/ast.json new file mode 100644 index 0000000..e206832 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ast.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Xuacu" + ] + }, + "articleplaceholder-desc": "Ufre una páxina especial con información de {{WBREPONAME}} sobro un tema determináu, con invitación a crear un artículu pal tema", + "articleplaceholder-abouttopic": "Tocante al asuntu", + "articleplaceholder-abouttopic-intro": "Esta páxina especial xenera una páxina de conteníu sobro un asuntu determináu con información de {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Escribe una ID d'entidá pa recibir una maqueta d'artículu xenerada automáticamente.", + "articleplaceholder-abouttopic-submit": "crear", + "articleplaceholder-abouttopic-no-entity-error": "Esta nun ye una id d'entidá válida.", + "articleplaceholder-abouttopic-create-article": "Crear un artículu nuevu col títulu", + "articleplaceholder-abouttopic-create-article-button": "Crear un artículu", + "articleplaceholder-abouttopic-create-article-submit-button": "Unviar", + "articleplaceholder-abouttopic-article-exists-error": "Yá esiste un artículu con esi nome.", + "articleplaceholder-abouttopic-lua-entity": "Entidá", + "articleplaceholder-abouttopic-lua-reference": "Referencia", + "articleplaceholder-abouttopic-lua-qualifier": "Cualificador", + "articleplaceholder-abouttopic-lua-identifier": "Identificador", + "articleplaceholder-search-header": "Descubrir datos del tema" +} diff --git a/extensions/ArticlePlaceholder/i18n/cs.json b/extensions/ArticlePlaceholder/i18n/cs.json new file mode 100644 index 0000000..3744e4d --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/cs.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Cvanca" + ] + }, + "articleplaceholder-abouttopic": "O Tématu" +} diff --git a/extensions/ArticlePlaceholder/i18n/de.json b/extensions/ArticlePlaceholder/i18n/de.json new file mode 100644 index 0000000..0f64b2b --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/de.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Metalhead64" + ] + }, + "articleplaceholder-desc": "Ergänzt eine Spezialseite mit {{WBREPONAME}}-Informationen über ein bestimmtes Thema mit einer Einladung zum Erstellen eines Artikels zum Thema", + "articleplaceholder-abouttopic": "Über Thema", + "articleplaceholder-abouttopic-intro": "Diese Spezialseite erzeugt eine Inhaltsseite über ein bestimmtes Thema mit Informationen aus {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Gib die Objektkennung ein, um einen automatisch erzeugten Artikelplatzhalter zu erhalten.", + "articleplaceholder-abouttopic-submit": "entwerfen", + "articleplaceholder-abouttopic-no-entity-error": "Dies ist keine gültige Objektkennung.", + "articleplaceholder-abouttopic-create-article": "Einen neuen Artikel mit dem Titel erstellen", + "articleplaceholder-abouttopic-create-article-button": "Einen Artikel erstellen", + "articleplaceholder-abouttopic-create-article-submit-button": "Übermitteln", + "articleplaceholder-abouttopic-article-exists-error": "Ein Artikel mit diesem Namen ist bereits vorhanden", + "articleplaceholder-abouttopic-lua-entity": "Objekt", + "articleplaceholder-abouttopic-lua-description": "Beschreibung:", + "articleplaceholder-abouttopic-lua-reference": "Referenz", + "articleplaceholder-abouttopic-lua-qualifier": "Qualifikator", + "articleplaceholder-abouttopic-lua-identifier": "Identifikator", + "articleplaceholder-search-header": "Daten zum Thema entdecken" +} diff --git a/extensions/ArticlePlaceholder/i18n/en.json b/extensions/ArticlePlaceholder/i18n/en.json new file mode 100644 index 0000000..c612e53 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/en.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Lucie-Aimée Kaffee" + ] + }, + "articleplaceholder-desc": "Provides a special page with {{WBREPONAME}} information about a certain topic, with invitation to create an article for the topic", + "articleplaceholder-abouttopic": "About topic", + "articleplaceholder-abouttopic-intro": "This special page generates a content page about a certain topic with {{WBREPONAME}} information", + "articleplaceholder-abouttopic-entityid": "Enter an entity id to get an auto-generated article placeholder.", + "articleplaceholder-abouttopic-submit": "craft", + "articleplaceholder-abouttopic-no-entity-error": "This is not a valid entity id.", + "articleplaceholder-abouttopic-create-article": "Create a new article with the title", + "articleplaceholder-abouttopic-create-article-button": "Create an article", + "articleplaceholder-abouttopic-create-article-submit-button": "Submit", + "articleplaceholder-abouttopic-article-exists-error": "An article with this name already exists", + "articleplaceholder-abouttopic-lua-entity": "Entity", + "articleplaceholder-abouttopic-lua-reference": "Reference", + "articleplaceholder-abouttopic-lua-qualifier": "Qualifier", + "articleplaceholder-abouttopic-lua-identifier": "Identifier", + "articleplaceholder-search-header": "Discover data on the topic" +} diff --git a/extensions/ArticlePlaceholder/i18n/eo.json b/extensions/ArticlePlaceholder/i18n/eo.json new file mode 100644 index 0000000..e0ac0fa --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/eo.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Robin van der Vliet", + "Venca24", + "KuboF" + ] + }, + "articleplaceholder-desc": "Provizas specialan paĝon kun informoj de {{WBREPONAME}} pri koncerna temo kun invito krei artikolon pri la temo", + "articleplaceholder-abouttopic": "Pri la temo", + "articleplaceholder-abouttopic-intro": "Tiu ĉi speciala paĝo generas enhavpaĝon pri iu temo kun informoj de {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Tajpu ento-identigilon por aŭtomate generitan anstataŭigon de artikolo.", + "articleplaceholder-abouttopic-submit": "ek", + "articleplaceholder-abouttopic-no-entity-error": "Tio ĉi ne estas ĝusta identigilo.", + "articleplaceholder-abouttopic-create-article": "Krei novan artikolon kun tiu ĉi titolo", + "articleplaceholder-abouttopic-create-article-button": "Krei artikolon", + "articleplaceholder-abouttopic-create-article-submit-button": "Ek", + "articleplaceholder-abouttopic-article-exists-error": "Artikolo kun tiu ĉi nomo jam ekzistas", + "articleplaceholder-abouttopic-lua-entity": "Ento", + "articleplaceholder-abouttopic-lua-reference": "Referenco(j)", + "articleplaceholder-abouttopic-lua-qualifier": "Kvalifilo", + "articleplaceholder-abouttopic-lua-identifier": "Identigilo", + "articleplaceholder-search-header": "Malkovru datumojn pri la temo" +} diff --git a/extensions/ArticlePlaceholder/i18n/es.json b/extensions/ArticlePlaceholder/i18n/es.json new file mode 100644 index 0000000..9f15c43 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/es.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Macofe", + "SinNovedades" + ] + }, + "articleplaceholder-desc": "Proporciona una página especial información de {{WBREPONAME}} acerca de un determinado tema, con invitación a crear un artículo para el tema", + "articleplaceholder-abouttopic": "Sobre el tema", + "articleplaceholder-abouttopic-intro": "Esta página especial genera una página de contenido sobre un tema determinado con información de {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Escribe un identificador de entidad para obtener un posicionador de artículo autogenerado.", + "articleplaceholder-abouttopic-submit": "crear", + "articleplaceholder-abouttopic-no-entity-error": "Este identificador de identidad no es válido.", + "articleplaceholder-abouttopic-create-article": "Crear un artículo nuevo con el título", + "articleplaceholder-abouttopic-create-article-button": "Crear un artículo", + "articleplaceholder-abouttopic-create-article-submit-button": "Enviar", + "articleplaceholder-abouttopic-article-exists-error": "Ya existe un arttículo con este nombre", + "articleplaceholder-abouttopic-lua-entity": "Entidad", + "articleplaceholder-abouttopic-lua-reference": "Referencia", + "articleplaceholder-abouttopic-lua-qualifier": "Calificador", + "articleplaceholder-abouttopic-lua-identifier": "Identificador", + "articleplaceholder-search-header": "Descubrir datos sobre el tema" +} diff --git a/extensions/ArticlePlaceholder/i18n/eu.json b/extensions/ArticlePlaceholder/i18n/eu.json new file mode 100644 index 0000000..0f6c914 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/eu.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Subi" + ] + }, + "articleplaceholder-abouttopic": "Gaiari buruz", + "articleplaceholder-abouttopic-lua-identifier": "Identifikatzailea" +} diff --git a/extensions/ArticlePlaceholder/i18n/fr.json b/extensions/ArticlePlaceholder/i18n/fr.json new file mode 100644 index 0000000..3ddbf4a --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/fr.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Gomoko", + "Wladek92" + ] + }, + "articleplaceholder-desc": "Fournit une page spéciale avec l’information {{WBREPONAME}} sur un certain sujet, avec une invitation à créer un article pour le sujet", + "articleplaceholder-abouttopic": "Sujet \"À propos\"", + "articleplaceholder-abouttopic-intro": "Cette page spéciale génère une page de contenu sur un certain sujet avec l’information {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Entrer un id d’entité pour obtenir un article fictif généré automatiquement.", + "articleplaceholder-abouttopic-submit": "réaliser", + "articleplaceholder-abouttopic-no-entity-error": "Ce n’est pas un id d’entité valide.", + "articleplaceholder-abouttopic-create-article": "Créer un nouvel article avec le titre", + "articleplaceholder-abouttopic-create-article-button": "Créer un article", + "articleplaceholder-abouttopic-create-article-submit-button": "Soumettre", + "articleplaceholder-abouttopic-article-exists-error": "Un article avec ce nom existe déjà", + "articleplaceholder-abouttopic-lua-entity": "Entité", + "articleplaceholder-abouttopic-lua-reference": "Référence", + "articleplaceholder-abouttopic-lua-qualifier": "Qualificatif", + "articleplaceholder-abouttopic-lua-identifier": "Identifiant", + "articleplaceholder-search-header": "Découvrir les données sur le sujet" +} diff --git a/extensions/ArticlePlaceholder/i18n/gl.json b/extensions/ArticlePlaceholder/i18n/gl.json new file mode 100644 index 0000000..55ea653 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/gl.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Elisardojm" + ] + }, + "articleplaceholder-desc": "Proporciona unha páxina especial con información de {{WBREPONAME}} sobre tema determinado, con invitación a crear un artigo para o tema", + "articleplaceholder-abouttopic": "Sobre o tema", + "articleplaceholder-abouttopic-intro": "Esta páxina especial xenera unha páxina de contido sobre un tema determinado con información de {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Indique un identificador de entidade para obter un marcador de artigo autoxenerado.", + "articleplaceholder-abouttopic-submit": "crear", + "articleplaceholder-abouttopic-no-entity-error": "Este identificador de identidade non é válido.", + "articleplaceholder-abouttopic-create-article": "Crear un artigo novo co título", + "articleplaceholder-abouttopic-create-article-button": "Crear un artigo", + "articleplaceholder-abouttopic-create-article-submit-button": "Enviar", + "articleplaceholder-abouttopic-article-exists-error": "Xa existe un artigo con ese nome.", + "articleplaceholder-abouttopic-lua-entity": "Entidade", + "articleplaceholder-abouttopic-lua-reference": "Referencia", + "articleplaceholder-abouttopic-lua-qualifier": "Cualificador", + "articleplaceholder-abouttopic-lua-identifier": "Identificador", + "articleplaceholder-search-header": "Descubrir datos sobre o tema" +} diff --git a/extensions/ArticlePlaceholder/i18n/it.json b/extensions/ArticlePlaceholder/i18n/it.json new file mode 100644 index 0000000..8aef5b4 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/it.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Beta16" + ] + }, + "articleplaceholder-desc": "Fornisce una pagina speciale con informazioni da {{WBREPONAME}} su un certo argomento, con l'invito a creare una voce su di esso", + "articleplaceholder-abouttopic": "Sull'argomento", + "articleplaceholder-abouttopic-intro": "Questa pagina speciale genera una pagina di contenuto su un certo argomento con informazioni da {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Inserisci un ID entità per ottenere una voce segnaposto auto-generata.", + "articleplaceholder-abouttopic-submit": "crea", + "articleplaceholder-abouttopic-no-entity-error": "Questo non è un ID entità valido.", + "articleplaceholder-abouttopic-create-article": "Crea una nuova voce con il titolo", + "articleplaceholder-abouttopic-create-article-button": "Crea una voce", + "articleplaceholder-abouttopic-create-article-submit-button": "Invia", + "articleplaceholder-abouttopic-article-exists-error": "Una voce con questo nome esiste già", + "articleplaceholder-abouttopic-lua-entity": "Entità", + "articleplaceholder-abouttopic-lua-description": "Descrizione:", + "articleplaceholder-abouttopic-lua-reference": "Riferimento", + "articleplaceholder-abouttopic-lua-qualifier": "Qualificatore", + "articleplaceholder-abouttopic-lua-identifier": "Identificatore", + "articleplaceholder-search-header": "Scopri i dati sull'argomento" +} diff --git a/extensions/ArticlePlaceholder/i18n/ja.json b/extensions/ArticlePlaceholder/i18n/ja.json new file mode 100644 index 0000000..4685ee6 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ja.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Sujiniku" + ] + }, + "articleplaceholder-abouttopic-no-entity-error": "これは有効なエンティティIDではありません。", + "articleplaceholder-abouttopic-create-article-button": "記事を作成する", + "articleplaceholder-abouttopic-create-article-submit-button": "提出する", + "articleplaceholder-abouttopic-lua-description": "説明:" +} diff --git a/extensions/ArticlePlaceholder/i18n/jv.json b/extensions/ArticlePlaceholder/i18n/jv.json new file mode 100644 index 0000000..56f923c --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/jv.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "NoiX180" + ] + }, + "articleplaceholder-desc": "Nyadhiyakaké kaca mirunggan mawa pratélan {{WBREPONAME}} bab rembug tinemtu, sarta undangan ngripta artikel jroning rembug iku", + "articleplaceholder-abouttopic": "Bab Rembug", + "articleplaceholder-abouttopic-intro": "Kaca mirunggan iki ngasilaké kaca isi bab rembug tinamtu mawa pratélan {{WBREPONAME}}", + "articleplaceholder-abouttopic-create-article": "Ngripta artikel anyar mawa sesirah iku", + "articleplaceholder-abouttopic-create-article-button": "Ngripta artikel", + "articleplaceholder-abouttopic-create-article-submit-button": "Kumpulaké", + "articleplaceholder-abouttopic-article-exists-error": "Artikel asesirah mangkéné wis ana", + "articleplaceholder-abouttopic-lua-reference": "Rujukan", + "articleplaceholder-search-header": "Temokaké data bab rembug iku" +} diff --git a/extensions/ArticlePlaceholder/i18n/ko.json b/extensions/ArticlePlaceholder/i18n/ko.json new file mode 100644 index 0000000..f8ed0bf --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ko.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Revi" + ] + }, + "articleplaceholder-desc": "특정 주제에 대한 {{WBREPONAME}} 정보를 다루는 특수 문서를 제공하며, 해당 주제에 대한 새 문서를 만들도록 추천합니다", + "articleplaceholder-abouttopic": "주제에 대하여", + "articleplaceholder-abouttopic-intro": "이 특수 문서는 {{WBREPONAME}}으로 특정한 주제에 대한 문서를 생성합니다.", + "articleplaceholder-abouttopic-entityid": "개체 ID를 입력하여 자동 생성된 문서를 얻어오세요.", + "articleplaceholder-abouttopic-no-entity-error": "유효한 개체 ID가 아닙니다.", + "articleplaceholder-abouttopic-create-article": "이 제목으로 새 문서 만들기", + "articleplaceholder-abouttopic-create-article-button": "새 문서 만들기", + "articleplaceholder-abouttopic-create-article-submit-button": "제출", + "articleplaceholder-abouttopic-article-exists-error": "이 제목으로 된 문서가 이미 존재합니다", + "articleplaceholder-abouttopic-lua-entity": "개체", + "articleplaceholder-abouttopic-lua-reference": "참고", + "articleplaceholder-abouttopic-lua-qualifier": "한정어", + "articleplaceholder-search-header": "주제에 대한 데이터 탐색" +} diff --git a/extensions/ArticlePlaceholder/i18n/ksh.json b/extensions/ArticlePlaceholder/i18n/ksh.json new file mode 100644 index 0000000..555d4fa --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ksh.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "articleplaceholder-desc": "Brängk en {{int:specialpage}} med Aanjahbe {{WBREPONAME}} övver e Tehma, met dä Bedd, doh drövver en neuje Sigg ze schrihve. ", + "articleplaceholder-abouttopic-submit": "Lohß Jonn!", + "articleplaceholder-abouttopic-create-article": "Donn en Sigg met dä Övverschreff aanlähje.", + "articleplaceholder-abouttopic-create-article-button": "Donn en Sigg met aanlähje.", + "articleplaceholder-abouttopic-create-article-submit-button": "Lohß jonn!", + "articleplaceholder-abouttopic-article-exists-error": "En Sigg met dä Övverschreff jidd_et ald.", + "articleplaceholder-abouttopic-lua-reference": "Fohßnoht", + "articleplaceholder-abouttopic-lua-identifier": "Kännong" +} diff --git a/extensions/ArticlePlaceholder/i18n/ku-latn.json b/extensions/ArticlePlaceholder/i18n/ku-latn.json new file mode 100644 index 0000000..0dcf879 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ku-latn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "George Animal" + ] + }, + "articleplaceholder-abouttopic": "Di derbarê mijarê de" +} diff --git a/extensions/ArticlePlaceholder/i18n/lb.json b/extensions/ArticlePlaceholder/i18n/lb.json new file mode 100644 index 0000000..1d62af9 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/lb.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Robby" + ] + }, + "articleplaceholder-abouttopic": "Iwwert Thema", + "articleplaceholder-abouttopic-create-article-button": "En Artikel uleeën", + "articleplaceholder-abouttopic-lua-entity": "Objet", + "articleplaceholder-abouttopic-lua-description": "Beschreiwung:", + "articleplaceholder-abouttopic-lua-reference": "Referenz" +} diff --git a/extensions/ArticlePlaceholder/i18n/lt.json b/extensions/ArticlePlaceholder/i18n/lt.json new file mode 100644 index 0000000..1373ad4 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/lt.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Zygimantus" + ] + }, + "articleplaceholder-abouttopic-lua-identifier": "Identifikatorius" +} diff --git a/extensions/ArticlePlaceholder/i18n/mk.json b/extensions/ArticlePlaceholder/i18n/mk.json new file mode 100644 index 0000000..adfea08 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/mk.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06" + ] + }, + "articleplaceholder-desc": "Дава службена страница со информации од {{WBREPONAME}} за извесна тема и покана за создавање на статија на таа тема", + "articleplaceholder-abouttopic": "За тема", + "articleplaceholder-abouttopic-intro": "Оваа службена страница создава содржинска страница за извесна тема во информации од {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Внесете ја назнаката на единицата за да дибиете самосоздаден пополнувач за статија.", + "articleplaceholder-abouttopic-submit": "изработи", + "articleplaceholder-abouttopic-no-entity-error": "Ова не е важечка назнака на единицата.", + "articleplaceholder-abouttopic-create-article": "Создај нова статија со овој наслов", + "articleplaceholder-abouttopic-create-article-button": "Создај статија", + "articleplaceholder-abouttopic-create-article-submit-button": "Поднеси", + "articleplaceholder-abouttopic-article-exists-error": "Веќе постои статија со тоа име.", + "articleplaceholder-abouttopic-lua-entity": "Единица", + "articleplaceholder-abouttopic-lua-description": "Опис:", + "articleplaceholder-abouttopic-lua-reference": "Навод", + "articleplaceholder-abouttopic-lua-qualifier": "Определница", + "articleplaceholder-abouttopic-lua-identifier": "Назнака", + "articleplaceholder-search-header": "Откријте ги податоците на темата" +} diff --git a/extensions/ArticlePlaceholder/i18n/mr.json b/extensions/ArticlePlaceholder/i18n/mr.json new file mode 100644 index 0000000..3f1ea96 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/mr.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "V.narsikar" + ] + }, + "articleplaceholder-abouttopic": "विषयाबद्दल", + "articleplaceholder-abouttopic-create-article-button": "लेख तयार करा", + "articleplaceholder-abouttopic-create-article-submit-button": "सादर करा", + "articleplaceholder-abouttopic-lua-description": "वर्णन:", + "articleplaceholder-abouttopic-lua-reference": "संदर्भ" +} diff --git a/extensions/ArticlePlaceholder/i18n/ms.json b/extensions/ArticlePlaceholder/i18n/ms.json new file mode 100644 index 0000000..c714a09 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ms.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Kurniasan" + ] + }, + "articleplaceholder-desc": "Menyediakan laman khas berisi maklumat {{WBREPONAME}} berkenaan topik tertentu, beserta undangan mencipta rencana untuk topik terbabit", + "articleplaceholder-abouttopic-create-article-submit-button": "Hantar", + "articleplaceholder-abouttopic-article-exists-error": "Sebuah rencana bernama sama telah wujud", + "articleplaceholder-abouttopic-lua-reference": "Rujukan", + "articleplaceholder-search-header": "Temukan data berkenaan topik ini" +} diff --git a/extensions/ArticlePlaceholder/i18n/oc.json b/extensions/ArticlePlaceholder/i18n/oc.json new file mode 100644 index 0000000..8b433f2 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/oc.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Jfblanc" + ] + }, + "articleplaceholder-desc": "Porgís una pagina especiala d'informacion de {{WBREPONAME}} sus un subjècte determinat, amb invitacion a crear un article sul subjècte.", + "articleplaceholder-abouttopic": "Sul subjècte", + "articleplaceholder-abouttopic-intro": "Aquesta pagina especiala genèra una pagina de contengut sus un subjècte determinat amb de donadas de {{WBREPONAME}}", + "articleplaceholder-abouttopic-entityid": "Picatz un identificador d'entitat per obténer un esquelèta d'article autogenerat", + "articleplaceholder-abouttopic-submit": "borrolhon", + "articleplaceholder-abouttopic-no-entity-error": "Aqueste identificador d'identitat es pas valid.", + "articleplaceholder-abouttopic-create-article": "Crear un article nòu amb lo títol", + "articleplaceholder-abouttopic-create-article-button": "Crear un article", + "articleplaceholder-abouttopic-create-article-submit-button": "Sometre", + "articleplaceholder-abouttopic-article-exists-error": "Un article d'aquel nom ja existís", + "articleplaceholder-abouttopic-lua-entity": "Entitat", + "articleplaceholder-abouttopic-lua-reference": "Referéncia", + "articleplaceholder-abouttopic-lua-qualifier": "Calificador", + "articleplaceholder-abouttopic-lua-identifier": "Identificador", + "articleplaceholder-search-header": "Descobrir de donadas sobratz lo tèma" +} diff --git a/extensions/ArticlePlaceholder/i18n/om.json b/extensions/ArticlePlaceholder/i18n/om.json new file mode 100644 index 0000000..7788414 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/om.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Tumsaa" + ] + }, + "articleplaceholder-abouttopic": "Waa'ee mataduree" +} diff --git a/extensions/ArticlePlaceholder/i18n/pl.json b/extensions/ArticlePlaceholder/i18n/pl.json new file mode 100644 index 0000000..ebcac81 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/pl.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Chrumps" + ] + }, + "articleplaceholder-abouttopic-create-article-button": "Utwórz artykuł", + "articleplaceholder-abouttopic-lua-description": "Opis:", + "articleplaceholder-abouttopic-lua-qualifier": "Kwalifikator", + "articleplaceholder-abouttopic-lua-identifier": "Identyfikator" +} diff --git a/extensions/ArticlePlaceholder/i18n/ps.json b/extensions/ArticlePlaceholder/i18n/ps.json new file mode 100644 index 0000000..384ac75 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ps.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "articleplaceholder-abouttopic": "د موضوع په اړه", + "articleplaceholder-abouttopic-create-article": "په دې سرليک يوه نوې ليکنه ليکل", + "articleplaceholder-abouttopic-create-article-button": "يوه ليکنه ليکل", + "articleplaceholder-abouttopic-create-article-submit-button": "سپارل", + "articleplaceholder-abouttopic-article-exists-error": "په دې نوم يوه ليکنه له پخوا څخه شته.", + "articleplaceholder-abouttopic-lua-description": "څرگندونه:", + "articleplaceholder-abouttopic-lua-reference": "سرچينه", + "articleplaceholder-abouttopic-lua-identifier": "پېژندگر" +} diff --git a/extensions/ArticlePlaceholder/i18n/qqq.json b/extensions/ArticlePlaceholder/i18n/qqq.json new file mode 100644 index 0000000..a9848e7 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/qqq.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Lucie-Aimée Kaffee", + "Liuxinyu970226", + "Raymond" + ] + }, + "articleplaceholder-desc": "{{desc|what=extension|name=ArticlePlaceholder|url=https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder}}\n{{WBREPONAME}} is a variable of the repository name of Wikidata (it has replaced the string 'Wikidata').", + "articleplaceholder-abouttopic": "Title of Special:AboutTopic.", + "articleplaceholder-abouttopic-intro": "Intro paragraph shown on Special:AboutTopic.", + "articleplaceholder-abouttopic-entityid": "Text to encourage the user to enter an entity id.", + "articleplaceholder-abouttopic-submit": "Label on the submit button.\n{{Identical|Craft}}", + "articleplaceholder-abouttopic-no-entity-error": "Error message in case of an invalid entity id.", + "articleplaceholder-abouttopic-create-article": "Text in the popup encouraging the user to create an article with a selectable title", + "articleplaceholder-abouttopic-create-article-button": "Label on create article button", + "articleplaceholder-abouttopic-create-article-submit-button": "Label on submit button\n{{Identical|Submit}}", + "articleplaceholder-abouttopic-article-exists-error": "Error to indicate the given article title already exists", + "articleplaceholder-abouttopic-lua-entity": "Header of the entity section\n{{Identical|Entity}}", + "articleplaceholder-abouttopic-lua-reference": "Header of the reference section\n{{Identical|Reference}}", + "articleplaceholder-abouttopic-lua-qualifier": "Header of the qualifier section\n{{Identical|Qualifier}}", + "articleplaceholder-abouttopic-lua-identifier": "Header of the identifier section\n{{Identical|Identifier}}", + "articleplaceholder-search-header": "Header in the search for the results of Special:AboutTopic generated pages" +} diff --git a/extensions/ArticlePlaceholder/i18n/ru.json b/extensions/ArticlePlaceholder/i18n/ru.json new file mode 100644 index 0000000..872a0f8 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/ru.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Okras" + ] + }, + "articleplaceholder-abouttopic": "О теме", + "articleplaceholder-abouttopic-create-article-button": "Создать статью", + "articleplaceholder-abouttopic-create-article-submit-button": "Отправить", + "articleplaceholder-abouttopic-article-exists-error": "Статья с таким названием уже существует.", + "articleplaceholder-abouttopic-lua-entity": "Сущность", + "articleplaceholder-abouttopic-lua-reference": "Примечание", + "articleplaceholder-abouttopic-lua-qualifier": "Квалификатор", + "articleplaceholder-abouttopic-lua-identifier": "Идентификатор" +} diff --git a/extensions/ArticlePlaceholder/i18n/sd.json b/extensions/ArticlePlaceholder/i18n/sd.json new file mode 100644 index 0000000..462facb --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/sd.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Mehtab ahmed", + "Aursani" + ] + }, + "articleplaceholder-abouttopic": "موضوع بابت", + "articleplaceholder-abouttopic-create-article": "هن عنوان سان ڪو نئون مضمون تخليق ڪريو", + "articleplaceholder-abouttopic-create-article-button": "ڪو مضمون تخليق ڪريو", + "articleplaceholder-abouttopic-create-article-submit-button": "اماڻيو", + "articleplaceholder-abouttopic-article-exists-error": "هن نالي سان اڳ ئي هڪ مضمون موجود آهي", + "articleplaceholder-abouttopic-lua-reference": "حوالو", + "articleplaceholder-search-header": "موضوع تي مواد دريافت ڪريو" +} diff --git a/extensions/ArticlePlaceholder/i18n/sr-ec.json b/extensions/ArticlePlaceholder/i18n/sr-ec.json new file mode 100644 index 0000000..b4d7399 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/sr-ec.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Milicevic01" + ] + }, + "articleplaceholder-abouttopic": "О теми" +} diff --git a/extensions/ArticlePlaceholder/i18n/sr-el.json b/extensions/ArticlePlaceholder/i18n/sr-el.json new file mode 100644 index 0000000..4f53b27 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/sr-el.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Milicevic01" + ] + }, + "articleplaceholder-abouttopic": "O temi" +} diff --git a/extensions/ArticlePlaceholder/i18n/su.json b/extensions/ArticlePlaceholder/i18n/su.json new file mode 100644 index 0000000..6dd841a --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/su.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Kandar" + ] + }, + "articleplaceholder-desc": "Nyadiakeun kaca husus jeung {{WBREPONAME}} émbaran ngeunaan hiji jejer, kalayan uleman pikeun nyieun artikel pikeun éta jejer", + "articleplaceholder-abouttopic": "Ngeunaan Jejer", + "articleplaceholder-abouttopic-submit": "kriya", + "articleplaceholder-abouttopic-create-article": "Jieun artikel maké judul", + "articleplaceholder-abouttopic-create-article-button": "Jieun artikel", + "articleplaceholder-abouttopic-create-article-submit-button": "Kirim", + "articleplaceholder-abouttopic-article-exists-error": "Artikel maké ieu judul geus aya", + "articleplaceholder-abouttopic-lua-entity": "Entitas", + "articleplaceholder-abouttopic-lua-reference": "Rujukan" +} diff --git a/extensions/ArticlePlaceholder/i18n/sv.json b/extensions/ArticlePlaceholder/i18n/sv.json new file mode 100644 index 0000000..3c4485b --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/sv.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "WikiPhoenix", + "Frisko" + ] + }, + "articleplaceholder-abouttopic": "Om ämnet", + "articleplaceholder-abouttopic-no-entity-error": "Detta är inte ett giltigt artikel-ID.", + "articleplaceholder-abouttopic-create-article": "Skapa en ny artikel med titeln", + "articleplaceholder-abouttopic-create-article-button": "Skapa en artikel", + "articleplaceholder-abouttopic-create-article-submit-button": "Skicka", + "articleplaceholder-abouttopic-article-exists-error": "En artikel med detta namn finns redan", + "articleplaceholder-abouttopic-lua-entity": "Entitet", + "articleplaceholder-abouttopic-lua-reference": "Referens" +} diff --git a/extensions/ArticlePlaceholder/i18n/tr.json b/extensions/ArticlePlaceholder/i18n/tr.json new file mode 100644 index 0000000..9b939a4 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/tr.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "HakanIST" + ] + }, + "articleplaceholder-abouttopic": "Konu Hakkında", + "articleplaceholder-abouttopic-lua-identifier": "Tanımlayıcı" +} diff --git a/extensions/ArticlePlaceholder/i18n/tt-cyrl.json b/extensions/ArticlePlaceholder/i18n/tt-cyrl.json new file mode 100644 index 0000000..cda844d --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/tt-cyrl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Ильнар" + ] + }, + "articleplaceholder-abouttopic-lua-reference": "Искәрмә" +} diff --git a/extensions/ArticlePlaceholder/i18n/yi.json b/extensions/ArticlePlaceholder/i18n/yi.json new file mode 100644 index 0000000..135ed8e --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/yi.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "פוילישער" + ] + }, + "articleplaceholder-abouttopic": "וועגן טעמע" +} diff --git a/extensions/ArticlePlaceholder/i18n/zh-hans.json b/extensions/ArticlePlaceholder/i18n/zh-hans.json new file mode 100644 index 0000000..5a15cdc --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/zh-hans.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Liuxinyu970226" + ] + }, + "articleplaceholder-desc": "提供包含有关特定主题的{{WBREPONAME}}信息的特殊页面,并带有邀请为主题创建条目的功能", + "articleplaceholder-abouttopic": "关于话题", + "articleplaceholder-abouttopic-intro": "此特殊页面通过使用{{WBREPONAME}}的信息,生成一段有关某一特定主题内容页面", + "articleplaceholder-abouttopic-entityid": "输入一个实体ID以获取自动生成的条目占位符。", + "articleplaceholder-abouttopic-submit": "工艺", + "articleplaceholder-abouttopic-no-entity-error": "这不是有效的实体ID。", + "articleplaceholder-abouttopic-create-article": "创建一个带标题的新条目", + "articleplaceholder-abouttopic-create-article-button": "创建条目", + "articleplaceholder-abouttopic-create-article-submit-button": "提交", + "articleplaceholder-abouttopic-article-exists-error": "已存在使用此名称的条目", + "articleplaceholder-abouttopic-lua-entity": "实体", + "articleplaceholder-abouttopic-lua-description": "描述:", + "articleplaceholder-abouttopic-lua-reference": "参考文献", + "articleplaceholder-abouttopic-lua-qualifier": "限定符", + "articleplaceholder-abouttopic-lua-identifier": "标识符", + "articleplaceholder-search-header": "发现数据在主题" +} diff --git a/extensions/ArticlePlaceholder/i18n/zh-hant.json b/extensions/ArticlePlaceholder/i18n/zh-hant.json new file mode 100644 index 0000000..4d05cb0 --- /dev/null +++ b/extensions/ArticlePlaceholder/i18n/zh-hant.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Liuxinyu970226" + ] + }, + "articleplaceholder-fancyunicorn-create-article-submit-button": "送出" +} diff --git a/extensions/ArticlePlaceholder/includes/Hooks.php b/extensions/ArticlePlaceholder/includes/Hooks.php new file mode 100644 index 0000000..99d599e --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/Hooks.php @@ -0,0 +1,60 @@ +<?php + +namespace ArticlePlaceholder; + +/** + * File defining the hook handlers for the ArticlePlaceholder extension. + * + * @license GNU GPL v2+ + * @author Lucie-Aimée Kaffee + */ +class Hooks { + + /** + * External Lua libraries for Scribunto + * + * @param string $engine + * @param array &$extraLibraryPaths + * + * @return bool + */ + public static function onScribuntoExternalLibraries( + $engine, + array &$extraLibraries + ) { + if ( $engine === 'lua' ) { + $extraLibraries['mw.ext.articlePlaceholder.entityRenderer'] = array( + 'class' => 'ArticlePlaceholder\Lua\Scribunto_LuaArticlePlaceholderLibrary', + 'deferLoad' => true, + ); + } + return true; + } + + /** + * External Lua library paths for Scribunto + * + * @param string $engine + * @param array &$extraLibraryPaths + * + * @return bool + */ + public static function registerScribuntoExternalLibraryPaths( + $engine, + array &$extraLibraryPaths + ) { + if ( $engine === 'lua' ) { + $extraLibraryPaths[] = __DIR__ . '/Lua'; + } + return true; + } + + /** + * @param array $files + * @return bool + */ + public static function onUnitTestsList( array &$files ) { + $files[] = __DIR__ . '/../tests/phpunit/'; + return true; + } +} diff --git a/extensions/ArticlePlaceholder/includes/Lua/Identifier.lua b/extensions/ArticlePlaceholder/includes/Lua/Identifier.lua new file mode 100644 index 0000000..7be7163 --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/Lua/Identifier.lua @@ -0,0 +1,6 @@ +-- All the identifier properties in one table +-- As in http://tinyurl.com/wikidata-identifier on 21.11.2015 +-- created using https://github.com/frimelle/identifier-to-lua + +local table = {["P212"] = true, ["P213"] = true, ["P214"] = true, ["P218"] = true, ["P219"] = true, ["P220"] = true, ["P221"] = true, ["P227"] = true, ["P229"] = true, ["P230"] = true, ["P232"] = true, ["P233"] = true, ["P236"] = true, ["P238"] = true, ["P239"] = true, ["P243"] = true, ["P244"] = true, ["P245"] = true, ["P247"] = true, ["P267"] = true, ["P268"] = true, ["P269"] = true, ["P270"] = true, ["P271"] = true, ["P278"] = true, ["P303"] = true, ["P305"] = true, ["P345"] = true, ["P349"] = true, ["P350"] = true, ["P351"] = true, ["P356"] = true, ["P359"] = true, ["P380"] = true, ["P381"] = true, ["P396"] = true, ["P409"] = true, ["P424"] = true, ["P426"] = true, ["P434"] = true, ["P435"] = true, ["P436"] = true, ["P454"] = true, ["P455"] = true, ["P474"] = true, ["P477"] = true, ["P480"] = true, ["P481"] = true, ["P492"] = true, ["P496"] = true, ["P497"] = true, ["P498"] = true, ["P502"] = true, ["P508"] = true, ["P535"] = true, ["P536"] = true, ["P549"] = true, ["P586"] = true, ["P592"] = true, ["P593"] = true, ["P594"] = true, ["P595"] = true, ["P597"] = true, ["P599"] = true, ["P604"] = true, ["P605"] = true, ["P617"] = true, ["P627"] = true, ["P632"] = true, ["P633"] = true, ["P635"] = true, ["P638"] = true, ["P640"] = true, ["P646"] = true, ["P648"] = true, ["P649"] = true, ["P650"] = true, ["P651"] = true, ["P661"] = true, ["P677"] = true, ["P679"] = true, ["P685"] = true, ["P686"] = true, ["P687"] = true, ["P691"] = true, ["P701"] = true, ["P704"] = true, ["P705"] = true, ["P709"] = true, ["P717"] = true, ["P718"] = true, ["P721"] = true, ["P722"] = true, ["P723"] = true, ["P727"] = true, ["P745"] = true, ["P757"] = true, ["P759"] = true, ["P760"] = true, ["P761"] = true, ["P762"] = true, ["P763"] = true, ["P764"] = true, ["P781"] = true, ["P791"] = true, ["P809"] = true, ["P815"] = true, ["P818"] = true, ["P819"] = true, ["P827"] = true, ["P829"] = true, ["P830"] = true, ["P836"] = true, ["P839"] = true, ["P842"] = true, ["P843"] = true, ["P844"] = true, ["P845"] = true, ["P846"] = true, ["P850"] = true, ["P858"] = true, ["P860"] = true, ["P861"] = true, ["P863"] = true, ["P864"] = true, ["P865"] = true, ["P866"] = true, ["P867"] = true, ["P882"] = true, ["P889"] = true, ["P893"] = true, ["P894"] = true, ["P897"] = true, ["P902"] = true, ["P905"] = true, ["P906"] = true, ["P907"] = true, ["P909"] = true, ["P911"] = true, ["P932"] = true, ["P933"] = true, ["P938"] = true, ["P939"] = true, ["P946"] = true, ["P947"] = true, ["P949"] = true, ["P950"] = true, ["P951"] = true, ["P954"] = true, ["P957"] = true, ["P959"] = true, ["P960"] = true, ["P961"] = true, ["P962"] = true, ["P966"] = true, ["P980"] = true, ["P998"] = true, ["P999"] = true, ["P1003"] = true, ["P1004"] = true, ["P1005"] = true, ["P1006"] = true, ["P1007"] = true, ["P1014"] = true, ["P1015"] = true, ["P1017"] = true, ["P1022"] = true, ["P1025"] = true, ["P1042"] = true, ["P1045"] = true, ["P1047"] = true, ["P1048"] = true, ["P1051"] = true, ["P1053"] = true, ["P1055"] = true, ["P1058"] = true, ["P1067"] = true, ["P1070"] = true, ["P1077"] = true, ["P1084"] = true, ["P1085"] = true, ["P1133"] = true, ["P1138"] = true, ["P1146"] = true, ["P1150"] = true, ["P1153"] = true, ["P1157"] = true, ["P1159"] = true, ["P1183"] = true, ["P1185"] = true, ["P1186"] = true, ["P1187"] = true, ["P1188"] = true, ["P1203"] = true, ["P1207"] = true, ["P1208"] = true, ["P1212"] = true, ["P1213"] = true, ["P1214"] = true, ["P1222"] = true, ["P1223"] = true, ["P1224"] = true, ["P1225"] = true, ["P1226"] = true, ["P1229"] = true, ["P1230"] = true, ["P1232"] = true, ["P1233"] = true, ["P1236"] = true, ["P1237"] = true, ["P1238"] = true, ["P1241"] = true, ["P1242"] = true, ["P1243"] = true, ["P1245"] = true, ["P1248"] = true, ["P1251"] = true, ["P1252"] = true, ["P1253"] = true, ["P1258"] = true, ["P1260"] = true, ["P1263"] = true, ["P1265"] = true, ["P1266"] = true, ["P1267"] = true, ["P1271"] = true, ["P1273"] = true, ["P1275"] = true, ["P1277"] = true, ["P1280"] = true, ["P1284"] = true, ["P1285"] = true, ["P1286"] = true, ["P1287"] = true, ["P1288"] = true, ["P1293"] = true, ["P1296"] = true, ["P1297"] = true, ["P1307"] = true, ["P1309"] = true, ["P1311"] = true, ["P1315"] = true, ["P1320"] = true, ["P1330"] = true, ["P1331"] = true, ["P1338"] = true, ["P1341"] = true, ["P1364"] = true, ["P1367"] = true, ["P1368"] = true, ["P1369"] = true, ["P1375"] = true, ["P1391"] = true, ["P1394"] = true, ["P1396"] = true, ["P1407"] = true, ["P1409"] = true, ["P1413"] = true, ["P1415"] = true, ["P1417"] = true, ["P1421"] = true, ["P1422"] = true, ["P1428"] = true, ["P1430"] = true, ["P1438"] = true, ["P1439"] = true, ["P1440"] = true, ["P1447"] = true, ["P1459"] = true, ["P1461"] = true, ["P1463"] = true, ["P1466"] = true, ["P1467"] = true, ["P1468"] = true, ["P1469"] = true, ["P1473"] = true, ["P1474"] = true, ["P1483"] = true, ["P1529"] = true, ["P1541"] = true, ["P1551"] = true, ["P1553"] = true, ["P1555"] = true, ["P1556"] = true, ["P1562"] = true, ["P1563"] = true, ["P1564"] = true, ["P1565"] = true, ["P1566"] = true, ["P1567"] = true, ["P1573"] = true, ["P1580"] = true, ["P1583"] = true, ["P1584"] = true, ["P1601"] = true, ["P1602"] = true, ["P1607"] = true, ["P1608"] = true, ["P1609"] = true, ["P1610"] = true, ["P1614"] = true, ["P1616"] = true, ["P1627"] = true, ["P1644"] = true, ["P1648"] = true, ["P1649"] = true, ["P1650"] = true, ["P1651"] = true, ["P1662"] = true, ["P1663"] = true, ["P1665"] = true, ["P1666"] = true, ["P1667"] = true, ["P1669"] = true, ["P1670"] = true, ["P1679"] = true, ["P1695"] = true, ["P1700"] = true, ["P1702"] = true, ["P1707"] = true, ["P1708"] = true, ["P1710"] = true, ["P1711"] = true, ["P1712"] = true, ["P1714"] = true, ["P1715"] = true, ["P1717"] = true, ["P1726"] = true, ["P1727"] = true, ["P1728"] = true, ["P1729"] = true, ["P1730"] = true, ["P1732"] = true, ["P1733"] = true, ["P1738"] = true, ["P1741"] = true, ["P1745"] = true, ["P1749"] = true, ["P1751"] = true, ["P1761"] = true, ["P1763"] = true, ["P1769"] = true, ["P1770"] = true, ["P1771"] = true, ["P1772"] = true, ["P1788"] = true, ["P1794"] = true, ["P1795"] = true, ["P1798"] = true, ["P1799"] = true, ["P1800"] = true, ["P1802"] = true, ["P1804"] = true, ["P1807"] = true, ["P1808"] = true, ["P1816"] = true, ["P1818"] = true, ["P1819"] = true, ["P1822"] = true, ["P1825"] = true, ["P1826"] = true, ["P1828"] = true, ["P1832"] = true, ["P1837"] = true, ["P1838"] = true, ["P1839"] = true, ["P1842"] = true, ["P1847"] = true, ["P1848"] = true, ["P1850"] = true, ["P1866"] = true, ["P1869"] = true, ["P1871"] = true, ["P1874"] = true, ["P1882"] = true, ["P1890"] = true, ["P1895"] = true, ["P1933"] = true, ["P1934"] = true, ["P1935"] = true, ["P1938"] = true, ["P1939"] = true, ["P1940"] = true, ["P1946"] = true, ["P1947"] = true, ["P1948"] = true, ["P1953"] = true, ["P1954"] = true, ["P1969"] = true, ["P1970"] = true, ["P1982"] = true, ["P1983"] = true, ["P1984"] = true, ["P1985"] = true, ["P1986"] = true, ["P1992"] = true, ["P1994"] = true, ["P2002"] = true, ["P2003"] = true, ["P2005"] = true, ["P2013"] = true, ["P2014"] = true, ["P2019"] = true, ["P2020"] = true, ["P2041"] = true, ["P2042"] = true, ["P2070"] = true, ["P2074"] = true, ["P2080"] = true, ["P2081"] = true, ["P2108"] = true, ["P2161"] = true, ["P2163"] = true, ["P2167"] = true, ["P2168"] = true, ["P2174"] = true, ["P2180"] = true, ["P2181"] = true, ["P2182"] = true, ["P2187"] = true, ["P2188"] = true, ["P2189"] = true, ["P2191"] = true, ["P2192"] = true, ["P2193"] = true, ["P2194"] = true, ["P2195"] = true, ["P2206"] = true, ["P2242"] = true, ["P2252"] = true, ["P2272"] = true, ["P2273"] = true, ["P2323"] = true, ["P2327"] = true, ["P2328"] = true, ["P2330"] = true, ["P2331"] = true, } + return table diff --git a/extensions/ArticlePlaceholder/includes/Lua/Scribunto_LuaArticlePlaceholderLibrary.php b/extensions/ArticlePlaceholder/includes/Lua/Scribunto_LuaArticlePlaceholderLibrary.php new file mode 100644 index 0000000..9b27d25 --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/Lua/Scribunto_LuaArticlePlaceholderLibrary.php @@ -0,0 +1,45 @@ +<?php + +namespace ArticlePlaceholder\Lua; + +use RuntimeException; +use Scribunto_LuaLibraryBase; + +/** + * Registers and defines functions needed by the Lua modules + * + * @licence GNU GPL v2+ + * @author Lucie-Aimée Kaffee + */ +class Scribunto_LuaArticlePlaceholderLibrary extends Scribunto_LuaLibraryBase { + + /** + * @return string[] + */ + public function getImageProperty() { + global $wgArticlePlaceholderImageProperty; + if ( + !is_string( $wgArticlePlaceholderImageProperty ) || + $wgArticlePlaceholderImageProperty === '' + ) { + throw new RuntimeException( 'Bad value in $wgArticlePlaceholderImageProperty' ); + } + return array( $wgArticlePlaceholderImageProperty ); + } + + /** + * @return array + */ + public function register() { + // These functions will be exposed to the Lua module. + // They are member functions on a Lua table which is private to the module, thus + // these can't be called from user code, unless explicitly exposed in Lua. + $lib = array( + 'getImageProperty' => array( $this, 'getImageProperty' ), + ); + + return $this->getEngine()->registerInterface( + __DIR__ . '/mw.ext.articlePlaceholder.entityRenderer.lua', $lib, array() + ); + } +} diff --git a/extensions/ArticlePlaceholder/includes/Lua/mw.ext.articlePlaceholder.entityRenderer.lua b/extensions/ArticlePlaceholder/includes/Lua/mw.ext.articlePlaceholder.entityRenderer.lua new file mode 100644 index 0000000..b934ca4 --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/Lua/mw.ext.articlePlaceholder.entityRenderer.lua @@ -0,0 +1,409 @@ +--[[ + @license GNU GPL v2+ + @author Lucie-Aimée Kaffee +]] + +local entityrenderer = {} + +local util = require( 'libraryUtil' ) +local php = mw_interface + +entityrenderer.imageProperty = php.getImageProperty() +local identifierProperties = require( 'Identifier' ) + +local hasReferences = false + +-- Get the datavalue for a given property. +-- @param String propertyId +-- @return String datatype +local getDatatype = function( propertyId ) + local property = mw.wikibase.getEntity( propertyId ) + return property['datatype'] +end + +----------------------------------- Implementation of Renderers ----------------------------------- + +-- Render a label to the language of the local Wiki. +-- @param string entityId +-- @return string label or entityId if no label available +local labelRenderer = function( entityId ) + local label = mw.wikibase.label( entityId ) + if label == nil then + label = entityId + end + return label +end + +-- Returns a table of statements sorted by *something* +-- @param table entity +-- @return table of properties +local statementSorter = function( entity ) + -- @todo sort by *something* + -- @todo limit number of statements + return entity:getProperties() +end + +-- Renders a given table of snaks. +-- @param table snaks +-- @return String result +local snaksRenderer = function( snaks ) + local result = '' + if snaks ~= nil and type( snaks ) == 'table' then + result = mw.wikibase.renderSnaks( snaks ) + end + return result +end + +-- Render a reference. +-- @param table references +-- @return String result +local referenceRenderer = function( references ) + local frame = mw:getCurrentFrame() + local referencesWikitext = {} + local referenceWikitext + + if references ~= nil then + hasReferences = true + local i = 1 + while references[i] do + for propRef, snakRef in pairs( references[i]['snaks'] ) do + referenceWikitext = "'''" .. labelRenderer( propRef ) .. "''': " .. snaksRenderer( snakRef ) + table.insert( referencesWikitext, frame:extensionTag( 'ref', referenceWikitext ) ) + end + i = i + 1 + end + end + + return table.concat( referencesWikitext, "" ) +end + +-- Render a qualifier. +-- @param table qualifierSnak +-- @return String result +local qualifierRenderer = function( qualifierSnak ) + local result = '' + if qualifierSnak ~= nil then + result = result .. '<h4>' .. mw.message.new( 'articleplaceholder-abouttopic-lua-qualifier' ):plain() .. '</h4>' + for key, value in pairs(qualifierSnak) do + result = result .. "<p>'''" .. labelRenderer( key ) .. "''': " + result = result .. snaksRenderer( value ) .. '</p>' + end + end + return result +end + +-- Render the image. +-- @param String propertyId +-- @return String renderedImage +local imageStatementRenderer = function( statement, orientationImage ) + local reference = '' + local qualifier = '' + local image = '' + if statement ~= nil then + for key, value in pairs( statement ) do + if key == 'mainsnak' then + image = mw.wikibase.renderSnak( value ) + elseif key == 'references' then + reference = referenceRenderer( value ) + elseif key == 'qualifiers' then + qualifier = qualifierRenderer( value ) + end + end + end + local result = '[[File:' .. image .. '|thumb|' .. orientationImage .. '|200px|' .. reference .. ']]' + result = result .. qualifier + return result +end + +-- Renders a statement. +-- @param table statement +-- @return string result +local statementRenderer = function( statement ) + local result = '' + local reference = '' + local qualifier = '' + local mainsnak = '' + if statement ~= nil then + for key, value in pairs( statement ) do + if key == 'mainsnak' then + mainsnak = mw.wikibase.renderSnak( value ) + elseif key == 'references' then + reference = referenceRenderer( value ) + elseif key == 'qualifiers' then + qualifier = qualifierRenderer( value ) + end + end + end + result = result .. '<p><span class="articleplaceholder-value">' .. mainsnak .. '</span>' .. reference .. '</p>' .. qualifier + return result +end + +-- Renders the best statements. +-- @param table entity +-- @param String propertyId +-- @return string statement +local bestStatementRenderer = function( entity, propertyId ) + local statement = '' + local bestStatements = entity:getBestStatements( propertyId ) + for _, stat in pairs( bestStatements ) do + if getDatatype( propertyId ) == "commonsMedia" then + statement = statement .. imageStatementRenderer( stat, "center" ) + else + statement = statement .. statementRenderer(stat) + end + end + return statement +end + +-- Render the identifier +-- @return string identifier +local identifierRenderer = function( entity, propertyId ) + return bestStatementRenderer( entity, propertyId ) +end + +-- Render a list of identifier +-- @param table entity +-- @return string identifier +local identifierListRenderer = function( entity ) + local properties = entity:getProperties() + local identifierList = '' + if properties ~= nil then + for _, propertyId in pairs( properties ) do + if identifierProperties[propertyId] then + identifierList = identifierList .. '<div class="articleplaceholder-identifier">' .. '<h2>' .. labelRenderer( propertyId ) .. '</h2>' + identifierList = identifierList .. identifierRenderer( entity, propertyId ) .. '</div>' + end + end + end + if identifierList ~= nil and identifierList ~= '' then + local div = '<div class="articleplaceholder-identifierlist">' + identifierList = div .. '<h1>' .. mw.message.new( 'articleplaceholder-abouttopic-lua-identifier' ):plain() .. '</h1>' .. identifierList + return identifierList .. '</div>' + end + return '' +end + +-- Render a list of statements. +-- @param table entity +-- @return string result +local statementListRenderer = function( entity ) + local result = '' + local properties = statementSorter( entity ) + if properties ~= nil then + for _, propertyId in pairs( properties ) do + if propertyId ~= entityrenderer.imageProperty and not identifierProperties[propertyId] then + result = result .. '<div class="articleplaceholder-statement">' + result = result .. '<h2>' .. labelRenderer( propertyId ) .. '</h2>' + result = result .. bestStatementRenderer( entity, propertyId ) + result = result .. '</div>' + end + end + end + return '<div class="articleplaceholder-statementgroup">' .. result .. '</div>' +end + +-- Render the image. +-- @param String propertyId +-- @return String renderedImage +local topImageRenderer = function( entity, propertyId, orientationImage ) + local renderedImage = '' + if propertyId ~= nil then + local imageName = entity:formatPropertyValues( propertyId ).value + if imageName ~= nil and imageName ~= '' then + renderedImage = '[[File:' .. imageName .. '|thumb|' .. orientationImage .. ']]' + renderedImage = '<div class="articleplaceholder-topimage">' .. renderedImage .. '</div>' + end + end + return renderedImage +end + +-- Render the description. +-- @param String entityId +-- @return String description +local function descriptionRenderer( entityId ) + local description = mw.wikibase.description( entityId ) + + if description ~= nil then + return '<div class="articleplaceholer-description"><p>' .. description .. '</p></div>' + else + return '' + end +end + +-- Render an entity, method to call all renderer +-- @param String entityId +-- @return String result +local renderEntity = function ( entityID ) + local entity = mw.wikibase.getEntityObject( entityID ) + local result = '' + + local description = descriptionRenderer( entityID ) + local image = topImageRenderer( entity, entityrenderer.imageProperty, "right" ) + local identifier = identifierListRenderer( entity ) + local entityResult = statementListRenderer( entity ) + + result = result .. '__NOTOC__' + if description ~= nil then + result = result .. description + end + result = result .. '<div class="articleplaceholder-sidebar">' .. image + result = result .. identifier .. '</div>' + if entityResult ~= '' then + result = result .. entityResult + end + + if hasReferences then + result = result .. '<h1>' .. mw.message.new( 'articleplaceholder-abouttopic-lua-reference' ):plain() .. '</h1>' + end + + return result +end + + +------------------------------------------------------------------------------------------------- + +----------------------------------- Getter und Setter -------------------------------------------- +entityrenderer.getLabelRenderer = function() + return labelRenderer +end + +entityrenderer.setLabelRenderer = function( newLabelRenderer ) + util.checkType( 'setLabelRenderer', 1, newLabelRenderer, 'function' ) + labelRenderer = newLabelRenderer +end + +entityrenderer.getStatementSorter = function() + return statementSorter +end + +entityrenderer.setStatementSorter = function( newStatementSorter ) + util.checkType( 'setStatementSorter', 1, newStatementSorter, 'function' ) + statementSorter = newStatementSorter +end + +entityrenderer.getSnaksRenderer = function() + return snaksRenderer +end + +entityrenderer.setSnaksRenderer = function( newsnaksRenderer ) + util.checkType( 'setSnaksRenderer', 1, newsnaksRenderer, 'function' ) + snaksRenderer = newSnaksRenderer +end + +entityrenderer.getReferenceRenderer = function() + return referenceRenderer +end + +entityrenderer.setReferenceRenderer = function( newReferenceRenderer ) + util.checkType( 'setReferenceRenderer', 1, newReferenceRenderer, 'function' ) + referenceRenderer = newReferenceRenderer +end + +entityrenderer.getQualifierRenderer = function() + return qualifierRenderer +end + +entityrenderer.setQualifierRenderer = function( newQualifierRenderer ) + util.checkType( 'setQualifierRenderer', 1, newQualifierRenderer, 'function' ) + qualifierRenderer = newQualifierRenderer +end + +entityrenderer.getImageStatementRenderer = function() + return imageStatementRenderer +end + +entityrenderer.setImageStatementRenderer = function( newImageStatementRenderer ) + util.checkType( 'setImageStatementRenderer', 1, newImageStatementRenderer, 'function' ) + imageStatementRenderer = newImageStatementRenderer +end + +entityrenderer.getStatementRenderer = function() + return statementRenderer +end + +entityrenderer.setStatementRenderer = function( newStatementRenderer ) + util.checkType( 'setStatementRenderer', 1, newStatementRenderer, 'function' ) + statementRenderer = newStatementRenderer +end + +entityrenderer.getBestStatementRenderer = function() + return bestStatementRenderer +end + +entityrenderer.setBestStatementRenderer = function( newBestStatementRenderer ) + util.checkType( 'setBestStatementRenderer', 1, newBestStatementRenderer, 'function' ) + bestStatementRenderer = newBestStatementRenderer +end + +entityrenderer.getIdentifierRenderer = function() + return identifierRenderer +end + +entityrenderer.setIdentifierRenderer = function( newIdentifierRenderer ) + util.checkType( 'setIdentifierRenderer', 1, newIdentifierRenderer, 'function' ) + identifierRenderer = newIdentifierRenderer +end + +entityrenderer.getIdentifierListRenderer = function() + return identifierListRenderer +end + +entityrenderer.setIdentifierListRenderer = function( newIdentifierListRenderer ) + util.checkType( 'setIdentifierListRenderer', 1, newIdentifierListRenderer, 'function' ) + identifierListRenderer = newIdentifierListRenderer +end + +entityrenderer.getStatementListRenderer = function() + return statementListRenderer +end + +entityrenderer.setStatementListRenderer = function( newStatementListRenderer ) + util.checkType( 'setStatementListRenderer', 1, newStatementListRenderer, 'function' ) + statementListRenderer = newStatementListRenderer +end + +entityrenderer.getTopImageRenderer = function() + return topImageRenderer +end + +entityrenderer.setTopImageRenderer = function( newTopImageRenderer ) + util.checkType( 'setTopImageRenderer', 1, newTopImageRenderer, 'function' ) + topImageRenderer = newTopImageRenderer +end + +entityrenderer.getDescriptionRenderer = function() + return descriptionRenderer +end + +entityrenderer.setDescriptionRenderer = function( newDescriptionRenderer ) + util.checkType( 'setDescriptionRenderer', 1, newDescriptionRenderer, 'function' ) + descriptionRenderer = newDescriptionRenderer +end + +entityrenderer.getRenderEntity = function() + return renderEntity +end + +entityrenderer.setRenderEntity = function( newRenderEntity ) + util.checkType( 'setRenderEntity', 1, newRenderEntity, 'function' ) + renderEntity = newRenderEntity +end + +entityrenderer.getHasReferences = function() + return hasReferences +end + +entityrenderer.setHasReferences = function( newHasReferences ) + util.checkType( 'setHasReferences', 1, newHasReferences, 'boolean' ) + hasReferences = newHasReferences +end + +-------------------------------------------------------------------------------------------------- + +-- render an entity +entityrenderer.render = function(frame) + local entityID = mw.text.trim( frame.args[1] or "" ) + return renderEntity( entityID ) +end + +return entityrenderer diff --git a/extensions/ArticlePlaceholder/includes/SearchHookHandler.php b/extensions/ArticlePlaceholder/includes/SearchHookHandler.php new file mode 100644 index 0000000..daa0a51 --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/SearchHookHandler.php @@ -0,0 +1,158 @@ +<?php + +namespace ArticlePlaceholder; + +use OutputPage; +use SpecialSearch; +use Wikibase\Client\WikibaseClient; +use Wikibase\Lib\Interactors\TermIndexSearchInteractor; +use Wikibase\Lib\Interactors\TermSearchResult; +use Wikibase\TermIndex; +use Wikibase\TermIndexEntry; + +/** + * Adding results from ArticlePlaceholder to search + * + * @author Lucie-Aimée Kaffee + * @license GNU General Public Licence 2.0 or later + */ +class SearchHookHandler { + + /** + * @var TermIndex + */ + private $termIndex; + + /** + * @var TermIndexSearchInteractor + */ + private $termSearchInteractor; + + /** + * @var string + */ + private $languageCode; + + /** + * @param string $language user language + * + * @return self + */ + private static function newFromGlobalState( $language ) { + global $wgLanguageCode; + + $wikibaseClient = WikibaseClient::getDefaultInstance(); + + return new self( + $wikibaseClient->getStore()->getTermIndex(), + $wikibaseClient->newTermSearchInteractor( $language ), + $wgLanguageCode + ); + } + + /** + * @param TermIndex $termIndex + * @param TermIndexSearchInteractor $termSearchInteractor + * @param string $languageCode content language + */ + public function __construct( + TermIndex $termIndex, + TermIndexSearchInteractor $termSearchInteractor, + $languageCode + ) { + $this->termIndex = $termIndex; + $this->termSearchInteractor = $termSearchInteractor; + $this->languageCode = $languageCode; + } + + /** + * @param SpecialSearch $specialSearch + * @param OutputPage $output + * @param string|null $term + * + * @return bool + */ + public static function onSpecialSearchResultsAppend( + SpecialSearch $specialSearch, + OutputPage $output, + $term + ) { + if ( $term === null || $term === '' ) { + return; + } + // user language, not content language + $instance = self::newFromGlobalState( $specialSearch->getLanguage()->getCode() ); + $instance->addToSearch( $specialSearch, $output, $term ); + return true; + } + + /** + * @param SpecialSearch $specialSearch + * @param OutputPage $output + * @param string $term + */ + public function addToSearch( SpecialSearch $specialSearch, OutputPage $output, $term ) { + $searchResult = $this->getSearchResults( $term ); + if ( $searchResult !== null ) { + $output->addWikiText( $this->getSearchHeader() ); + + $output->addWikiText( $searchResult ); + } + } + + /** + * @return string + */ + private function getSearchHeader() { + $header = '==' . wfMessage( 'articleplaceholder-search-header' )->text() . '=='; + return $header; + } + + /** + * @param string $term + * + * @return string + */ + private function getSearchResults( $term ) { + $searchResults = $this->searchEntities( $term ); + $link = 'Special:AboutTopic/'; + $wikitext = null; + foreach ( $searchResults as $searchResult ) { + $wikitext .= '<div class="article-placeholder-searchResult">' + . $this->createResult( $searchResult, $link ) + . '</div>'; + } + return $wikitext; + } + + /** + * @param TermSearchResult $searchResult + * @param string $link + * + * @return string + */ + private function createResult( TermSearchResult $searchResult, $link ) { + $entityId = $searchResult->getEntityId(); + $label = $searchResult->getDisplayLabel()->getText(); + $description = $searchResult->getDisplayDescription()->getText(); + + return '[[' . $link . wfEscapeWikiText( $entityId ) . '|' . wfEscapeWikiText( $label ) + .']]: ' . wfEscapeWikiText( $description ); + } + + /** + * @param string $term + * + * @return TermSearchResult[] + */ + private function searchEntities( $term ) { + $searchResults = $this->termSearchInteractor->searchForEntities( + $term, + $this->languageCode, + 'item', + array( TermIndexEntry::TYPE_LABEL, TermIndexEntry::TYPE_ALIAS ) + ); + return $searchResults; + } + +} diff --git a/extensions/ArticlePlaceholder/includes/Template/aboutTopic-template-module.xml b/extensions/ArticlePlaceholder/includes/Template/aboutTopic-template-module.xml new file mode 100644 index 0000000..cac14d8 --- /dev/null +++ b/extensions/ArticlePlaceholder/includes/Template/aboutTopic-template-module.xml @@ -0,0 +1,95 @@ +<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"> + <siteinfo> + <sitename>hey-hey-wiki</sitename> + <dbname>my_wiki</dbname> + <base>http://localhost/core/index.php/Main_Page</base> + <generator>MediaWiki 1.27alpha</generator> + <case>first-letter</case> + <namespaces> + <namespace key="-2" case="first-letter">Media</namespace> + <namespace key="-1" case="first-letter">Special</namespace> + <namespace key="0" case="first-letter" /> + <namespace key="1" case="first-letter">Talk</namespace> + <namespace key="2" case="first-letter">User</namespace> + <namespace key="3" case="first-letter">User talk</namespace> + <namespace key="4" case="first-letter">Hey-hey-wiki</namespace> + <namespace key="5" case="first-letter">Hey-hey-wiki talk</namespace> + <namespace key="6" case="first-letter">File</namespace> + <namespace key="7" case="first-letter">File talk</namespace> + <namespace key="8" case="first-letter">MediaWiki</namespace> + <namespace key="9" case="first-letter">MediaWiki talk</namespace> + <namespace key="10" case="first-letter">Template</namespace> + <namespace key="11" case="first-letter">Template talk</namespace> + <namespace key="12" case="first-letter">Help</namespace> + <namespace key="13" case="first-letter">Help talk</namespace> + <namespace key="14" case="first-letter">Category</namespace> + <namespace key="15" case="first-letter">Category talk</namespace> + <namespace key="120" case="first-letter">Item</namespace> + <namespace key="121" case="first-letter">Item talk</namespace> + <namespace key="122" case="first-letter">Property</namespace> + <namespace key="123" case="first-letter">Property talk</namespace> + <namespace key="828" case="first-letter">Module</namespace> + <namespace key="829" case="first-letter">Module talk</namespace> + </namespaces> + </siteinfo> + <page> + <title>Template:AboutTopic</title> + <ns>10</ns> + <id>30</id> + <revision> + <id>350</id> + <parentid>349</parentid> + <timestamp>2016-01-21T15:00:18Z</timestamp> + <contributor> + <ip>127.0.0.1</ip> + </contributor> + <model>wikitext</model> + <format>text/x-wiki</format> + <text xml:space="preserve" bytes="260">This template is part of the [https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder ArticlePlaceholder extension]. If you want to adjust it, please consider making your changes upstream. +<onlyinclude>{{#invoke:AboutTopic|showData|{{{1}}}}}</onlyinclude></text> + <sha1>f4z4fq5u00orujc7eknv3zljd19u9vy</sha1> + </revision> + </page> + <page> + <title>Module:AboutTopic</title> + <ns>828</ns> + <id>31</id> + <revision> + <id>354</id> + <parentid>353</parentid> + <timestamp>2016-01-22T21:22:29Z</timestamp> + <contributor> + <ip>127.0.0.1</ip> + </contributor> + <model>Scribunto</model> + <format>text/plain</format> + <text xml:space="preserve" bytes="204">local p = {} + +-- get the label of the local entity +p.showData = function(frame) + entityRenderer = require( 'mw.ext.articlePlaceholder.entityRenderer' ) + return entityRenderer.render( frame ) +end + +return p</text> + <sha1>mx55u3pffzrgm5zr0coh5ww9vqvv8ot</sha1> + </revision> + </page> + <page> + <title>Module:AboutTopic/doc</title> + <ns>828</ns> + <id>38</id> + <revision> + <id>346</id> + <parentid>345</parentid> + <timestamp>2016-01-20T15:02:01Z</timestamp> + <contributor> + <ip>127.0.0.1</ip> + </contributor> + <model>wikitext</model> + <format>text/x-wiki</format> + <text xml:space="preserve" bytes="190">This Module is part of the [https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder ArticlePlaceholder extension]. If you want to adjust it, please consider making your changes upstream.</text> + <sha1>7r1o4e4er1o8eb3pxvaloqapgpucfbw</sha1> + </revision> + </page> +</mediawiki> \ No newline at end of file diff --git a/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.createArticle.js b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.createArticle.js new file mode 100644 index 0000000..e755db7 --- /dev/null +++ b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.createArticle.js @@ -0,0 +1,106 @@ +/** + * @licence GNU GPL v2+ + * + * @author Lucie-Aimée Kaffee + */ + +( function ( $, mw, OO ) { + + var titleInput; + + function onSubmit() { + var titleRaw = titleInput.getValue(), + api = new mw.Api(); + + api.get( { action: 'query', titles: titleRaw } ).done( function ( data ) { + var query = data.query, + pageKeys = Object.keys( query.pages ), + title, + link; + + if ( titleRaw !== titleInput.getValue() ) { + return; + } + + if ( pageKeys[ 0 ] === '-1' ) { + title = mw.Title.newFromUserInput( titleRaw, 0 ); + link = '?title=' + encodeURIComponent( title.getNameText() ) + '&action=edit'; + link = mw.util.wikiScript() + link; + document.location.href = link; + } else { + $( '#mw-article-placeholder-error' ).append( + '<p>' + mw.message( 'articleplaceholder-abouttopic-article-exists-error' ).escaped() + '</p>' + ); + } + } ); + + return false; + } + + function onWikipageContent() { + var dialog, + windowManager, + button, + submitButton, + dialogContent +; + titleInput = new OO.ui.TextInputWidget( { + value: mw.config.get( 'apLabel' ), + multiline: false, + autosize: true + } ); + + submitButton = new OO.ui.ButtonWidget( { + label: mw.message( 'articleplaceholder-abouttopic-create-article-submit-button' ).text() + } ); + + dialogContent = $( '<p>' + mw.message( 'articleplaceholder-abouttopic-create-article' ).escaped() + '</p>' ); + dialogContent.append( titleInput.$element ); + dialogContent.append( submitButton.$element ); + dialogContent.append( '<div id="mw-article-placeholder-error"></div>' ); + + submitButton.on( 'click', onSubmit ); + + titleInput.on( 'change', function () { + $( '#mw-article-placeholder-error' ).empty(); + } ); + + titleInput.on( 'enter', function () { + submitButton.emit( 'click' ); + } ); + + function CreateArticleDialog( config ) { + CreateArticleDialog.super.call( this, config ); // jshint:ignore + } + OO.inheritClass( CreateArticleDialog, OO.ui.Dialog ); + + // Customize the initialize() function: This is where to add content to the dialog body and set up event handlers. + CreateArticleDialog.prototype.initialize = function () { + CreateArticleDialog.super.prototype.initialize.call( this ); // jshint:ignore + this.content = new OO.ui.PanelLayout( { $: this.$, padded: true, expanded: false } ); + this.content.$element.append( dialogContent ); + this.$body.append( this.content.$element ); + }; + + CreateArticleDialog.prototype.getBodyHeight = function () { + return this.content.$element.outerHeight( true ); + }; + + dialog = new CreateArticleDialog( { + size: 'medium' + } ); + windowManager = new OO.ui.WindowManager(); + button = OO.ui.infuse( 'create-article-button' ); + + $( 'body' ).append( windowManager.$element ); + // Add the window to the window manager using the addWindows() method. + windowManager.addWindows( [ dialog ] ); + + button.on( 'click', function () { + windowManager.openWindow( dialog ); + } ); + } + + mw.hook( 'wikipage.content' ).add( onWikipageContent ); + +} )( jQuery, mediaWiki, OO ); diff --git a/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplay.css b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplay.css new file mode 100644 index 0000000..5eb9aa3 --- /dev/null +++ b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplay.css @@ -0,0 +1,41 @@ +.articleplaceholder-statement { + display: inline-block; + border: 1px solid; + vertical-align: top; + padding: 10px; + margin: 20px; + width: 300px; +} + +#bodyContent { + padding-top: 5%; + padding-right: 305px; +} + +#create-article-button { + position: absolute; + top: 0px; + left: 10px; +} + +.articleplaceholder-sidebar { + position: absolute; + right: 0px; + width: 20%; +} + +.articleplaceholder-topimage { + float: right; +} + +.articleplaceholder-identifierlist { + clear: both; +} + +.articleplaceholder-statementgroup { + margin-top: 5%; +} + +.articleplaceholder-value { + font-size: 150%; +} diff --git a/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplaySmall.css b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplaySmall.css new file mode 100644 index 0000000..d7f1084 --- /dev/null +++ b/extensions/ArticlePlaceholder/modules/ext.articleplaceholder.defaultDisplaySmall.css @@ -0,0 +1,10 @@ +#bodyContent { + padding-top: 5%; + padding-right: 305px; +} + +.articleplaceholder-sidebar, .articleplaceholder-statementgroup { + float: none; + position: static; + width: auto; +} diff --git a/extensions/ArticlePlaceholder/package.json b/extensions/ArticlePlaceholder/package.json new file mode 100644 index 0000000..d86af25 --- /dev/null +++ b/extensions/ArticlePlaceholder/package.json @@ -0,0 +1,15 @@ +{ + "name": "articleplaceholder", + "version": "0.0.0", + "scripts": { + "test": "grunt test" + }, + "devDependencies": { + "grunt": "0.4.5", + "grunt-cli": "0.1.13", + "grunt-contrib-jshint": "0.11.2", + "grunt-banana-checker": "0.4.0", + "grunt-jscs": "2.1.0", + "grunt-jsonlint": "1.0.7" + } +} diff --git a/extensions/ArticlePlaceholder/phpcs.xml b/extensions/ArticlePlaceholder/phpcs.xml new file mode 100644 index 0000000..409f3eb --- /dev/null +++ b/extensions/ArticlePlaceholder/phpcs.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<ruleset> + <rule ref="vendor/mediawiki/mediawiki-codesniffer/MediaWiki"/> + <file>.</file> + <arg name="extensions" value="php,php5,inc"/> + <arg name="encoding" value="utf8"/> + <exclude-pattern>vendor</exclude-pattern> + <rule ref="Squiz.Classes.ValidClassName.NotCamelCaps"> + <exclude-pattern>Scribunto_LuaArticlePlaceholderLibrary</exclude-pattern> + </rule> +</ruleset> diff --git a/extensions/ArticlePlaceholder/tests/phpunit/Specials/SpecialAboutTopicTest.php b/extensions/ArticlePlaceholder/tests/phpunit/Specials/SpecialAboutTopicTest.php new file mode 100644 index 0000000..e52d7b6 --- /dev/null +++ b/extensions/ArticlePlaceholder/tests/phpunit/Specials/SpecialAboutTopicTest.php @@ -0,0 +1,56 @@ +<?php + +namespace ArticlePlaceholder\Tests; + +use ArticlePlaceholder\Specials\SpecialAboutTopic; +use Language; +use MediaWikiTestCase; +use Wikibase\Client\Store\TitleFactory; + +/** + * @covers ArticlePlaceholder\Specials\SpecialAboutTopic + * + * @group ArticlePlaceholder + * + * @licence GNU GPL v2+ + * @author Thiemo Mättig + */ +class SpecialAboutTopicTest extends MediaWikiTestCase { + + protected function setUp() { + parent::setUp(); + + $this->setMwGlobals( array( + 'wgContLang' => Language::factory( 'qqx' ) + ) ); + } + + public function testExecute() { + $termLookupFactory = $this->getMockBuilder( + 'Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory' ) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new SpecialAboutTopic( + $this->getMock( 'Wikibase\DataModel\Entity\EntityIdParser' ), + $termLookupFactory, + $this->getMock( 'Wikibase\Lib\Store\SiteLinkLookup' ), + $this->getMock( 'SiteStore' ), + new TitleFactory(), + '', + $this->getMock( 'Wikibase\DataModel\Services\Lookup\EntityLookup' ) + ); + + $instance->execute( '' ); + $output = $instance->getOutput(); + $this->assertSame( '(articleplaceholder-abouttopic)', $output->getPageTitle() ); + + $html = $output->getHTML(); + $this->assertContains( 'id="ap-abouttopic-form1"', $html ); + $this->assertContains( 'id="ap-abouttopic-entityid"', $html ); + $this->assertContains( '(articleplaceholder-abouttopic-intro)', $html ); + $this->assertContains( '(articleplaceholder-abouttopic-entityid)', $html ); + $this->assertContains( '(articleplaceholder-abouttopic-submit)', $html ); + } + +} diff --git a/extensions/ArticlePlaceholder/tests/phpunit/includes/HooksTest.php b/extensions/ArticlePlaceholder/tests/phpunit/includes/HooksTest.php new file mode 100644 index 0000000..925a5cd --- /dev/null +++ b/extensions/ArticlePlaceholder/tests/phpunit/includes/HooksTest.php @@ -0,0 +1,26 @@ +<?php + +namespace ArticlePlaceholder\Tests; + +use ArticlePlaceholder\Hooks; +use PHPUnit_Framework_TestCase; + +/** + * @covers ArticlePlaceholder\Hooks + * + * @group ArticlePlaceholder + * + * @licence GNU GPL v2+ + * @author Thiemo Mättig + */ +class HooksTest extends PHPUnit_Framework_TestCase { + + public function testRegisterScribuntoExternalLibraryPaths() { + $instance = new Hooks(); + $paths = array(); + $this->assertTrue( $instance->registerScribuntoExternalLibraryPaths( 'lua', $paths ) ); + $this->assertArrayHasKey( 0, $paths ); + $this->assertStringEndsWith( '/includes/Lua', $paths[0] ); + } + +} diff --git a/extensions/ArticlePlaceholder/tests/phpunit/includes/SearchHookHandlerTest.php b/extensions/ArticlePlaceholder/tests/phpunit/includes/SearchHookHandlerTest.php new file mode 100644 index 0000000..1fac5e9 --- /dev/null +++ b/extensions/ArticlePlaceholder/tests/phpunit/includes/SearchHookHandlerTest.php @@ -0,0 +1,144 @@ +<?php + +namespace ArticlePlaceholder\Tests; + +use ArticlePlaceholder\SearchHookHandler; +use MediaWikiTestCase; +use OutputPage; +use RequestContext; +use Title; +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Entity\PropertyId; +use Wikibase\LanguageFallbackChainFactory; +use Wikibase\Lib\Interactors\TermIndexSearchInteractor; +use Wikibase\Store\BufferingTermLookup; +use Wikibase\TermIndexEntry; +use Wikibase\Test\MockTermIndex; + +/** + * @group ArticlePlaceholder + * + * @covers SearchHookHandler + * + * @licence GNU GPL v2+ + * @author Lucie-Aimée Kaffee + */ +class SearchHookHandlerTest extends MediaWikiTestCase { + + private function getMockTermIndex() { + $typeLabel = TermIndexEntry::TYPE_LABEL; + $typeAlias = TermIndexEntry::TYPE_ALIAS; + $typeDescription = TermIndexEntry::TYPE_DESCRIPTION; + + return new MockTermIndex( + array( + // Q111 - Has label, description and alias all the same + $this->getTermIndexEntry( 'Unicorn', 'en', $typeLabel, new ItemId( 'Q111' ) ), + $this->getTermIndexEntry( 'Unicorn', 'en', $typeDescription, new ItemId( 'Q111' ) ), + $this->getTermIndexEntry( 'Unicorn', 'en', $typeAlias, new ItemId( 'Q111' ) ), + $this->getTermIndexEntry( 'UNICORN', 'en', $typeAlias, new ItemId( 'Q111' ) ), + // Q333 + $this->getTermIndexEntry( 'Unicorns are great', 'en', $typeLabel, new ItemId( 'Q333' ) ), + // Q555 + $this->getTermIndexEntry( 'Ta', 'en', $typeAlias, new ItemId( 'Q555' ) ), + $this->getTermIndexEntry( 'Taa', 'en', $typeAlias, new ItemId( 'Q555' ) ), + $this->getTermIndexEntry( 'TAAA', 'en-ca', $typeAlias, new ItemId( 'Q555' ) ), + $this->getTermIndexEntry( 'Taa', 'en-ca', $typeAlias, new ItemId( 'Q555' ) ), + // P22 + $this->getTermIndexEntry( 'Lama', 'en-ca', $typeLabel, new PropertyId( 'P22' ) ), + $this->getTermIndexEntry( 'La-description', 'en', $typeDescription, new PropertyId( 'P22' ) ), + // P44 + $this->getTermIndexEntry( 'Lama', 'en', $typeLabel, new PropertyId( 'P44' ) ), + $this->getTermIndexEntry( 'Lama-de-desc', 'de', $typeDescription, new PropertyId( 'P44' ) ), + ) + ); + } + + /** + * @param string $text + * @param string $languageCode + * @param string $termType + * @param EntityId|ItemId|PropertyId $entityId + * + * @returns TermIndexEntry + */ + private function getTermIndexEntry( $text, $languageCode, $termType, EntityId $entityId ) { + return new TermIndexEntry( array( + 'termText' => $text, + 'termLanguage' => $languageCode, + 'termType' => $termType, + 'entityId' => $entityId->getNumericId(), + 'entityType' => $entityId->getEntityType(), + ) ); + } + + private function getMockedTermSearchInteractor( $language ) { + $termSearchInteractor = new TermIndexSearchInteractor( + $this->getMockTermIndex(), + new LanguageFallbackChainFactory, + new BufferingTermLookup( $this->getMockTermIndex() ), + $language + ); + return $termSearchInteractor; + } + + private function getSpecialSearch() { + $mock = $this->getMockBuilder( 'SpecialSearch' ) + ->disableOriginalConstructor() + ->getMock(); + return $mock; + } + + private function getLanguageCode() { + return 'en'; + } + + protected function newSearchHookHandler() { + $language = $this->getLanguageCode(); + $page = new SearchHookHandler( + $this->getMockTermIndex(), + $this->getMockedTermSearchInteractor( $language ), + $language + ); + return $page; + } + + public function provideAddToSearch() { + return array( + array( + 'get term, check if entity with right title is returned', + 'Unicorn', + 'Unicorn' + ), + ); + } + + /** + * @dataProvider provideAddToSearch + */ + public function testAddToSearch( $message, $term, $expected ) { + $specialSearch = $this->getSpecialSearch(); + $output = new OutputPage( new RequestContext() ); + $output->setTitle( Title::makeTitle( 0, 'testOutputSearch' ) ); + + $searchHookHander = $this->newSearchHookHandler(); + $searchHookHander->addToSearch( $specialSearch, $output, $term ); + $html = $output->getHTML(); + $this->assertContains( $expected, $html, $message ); + } + + public function testOnSpecialSearchResultsAppend() { + $specialSearch = $this->getSpecialSearch(); + $output = new OutputPage( new RequestContext() ); + + $result = SearchHookHandler::onSpecialSearchResultsAppend( + $specialSearch, + $output, + '' + ); + + $this->assertNull( $result ); + } + +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index a2de2bc..dcf3250 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1568,5 +1568,39 @@ "issues": "https://phabricator.wikimedia.org/", "irc": "irc://irc.freenode.net/wikidata" } + }, + { + "name": "mediawiki/article-placeholder", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git", + "reference": "d3fff7b3144c9ba020380f08018c225e42ce49d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/d3fff7b3144c9ba020380f08018c225e42ce49d7", + "reference": "d3fff7b3144c9ba020380f08018c225e42ce49d7", + "shasum": "" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.2", + "mediawiki/mediawiki-codesniffer": "0.5.1" + }, + "time": "2016-02-08 12:46:34", + "type": "mediawiki-extension", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Lucie-Aimée Kaffee" + } + ], + "description": "Provides a special page with Wikibase information about a certain topic, with invitation to create an article for the topic", + "homepage": "https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder" } ] -- To view, visit https://gerrit.wikimedia.org/r/269396 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia6cc31c92f6d044c9cccfaf9ec3a3f9805bf2e2e Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikidata Gerrit-Branch: wmf/1.27.0-wmf.13 Gerrit-Owner: Aude <aude.w...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits