summaryrefslogtreecommitdiff
path: root/includes/api
diff options
context:
space:
mode:
Diffstat (limited to 'includes/api')
-rw-r--r--includes/api/ApiBase.php1084
-rw-r--r--includes/api/ApiBlock.php62
-rw-r--r--includes/api/ApiCheckToken.php81
-rw-r--r--includes/api/ApiClearHasMsg.php9
-rw-r--r--includes/api/ApiComparePages.php25
-rw-r--r--includes/api/ApiContinuationManager.php238
-rw-r--r--includes/api/ApiCreateAccount.php48
-rw-r--r--includes/api/ApiDelete.php29
-rw-r--r--includes/api/ApiDisabled.php16
-rw-r--r--includes/api/ApiEditPage.php143
-rw-r--r--includes/api/ApiEmailUser.php19
-rw-r--r--includes/api/ApiErrorFormatter.php303
-rw-r--r--includes/api/ApiExpandTemplates.php85
-rw-r--r--includes/api/ApiFeedContributions.php54
-rw-r--r--includes/api/ApiFeedRecentChanges.php35
-rw-r--r--includes/api/ApiFeedWatchlist.php90
-rw-r--r--includes/api/ApiFileRevert.php22
-rw-r--r--includes/api/ApiFormatBase.php332
-rw-r--r--includes/api/ApiFormatDbg.php11
-rw-r--r--includes/api/ApiFormatDump.php11
-rw-r--r--includes/api/ApiFormatFeedWrapper.php30
-rw-r--r--includes/api/ApiFormatJson.php96
-rw-r--r--includes/api/ApiFormatNone.php4
-rw-r--r--includes/api/ApiFormatPhp.php35
-rw-r--r--includes/api/ApiFormatRaw.php31
-rw-r--r--includes/api/ApiFormatTxt.php11
-rw-r--r--includes/api/ApiFormatWddx.php73
-rw-r--r--includes/api/ApiFormatXml.php302
-rw-r--r--includes/api/ApiFormatYaml.php4
-rw-r--r--includes/api/ApiHelp.php675
-rw-r--r--includes/api/ApiHelpParamValueMessage.php72
-rw-r--r--includes/api/ApiImageRotate.php42
-rw-r--r--includes/api/ApiImport.php35
-rw-r--r--includes/api/ApiLogin.php35
-rw-r--r--includes/api/ApiLogout.php19
-rw-r--r--includes/api/ApiMain.php541
-rw-r--r--includes/api/ApiManageTags.php107
-rw-r--r--includes/api/ApiMessage.php191
-rw-r--r--includes/api/ApiMove.php97
-rw-r--r--includes/api/ApiOpenSearch.php349
-rw-r--r--includes/api/ApiOptions.php37
-rw-r--r--includes/api/ApiPageSet.php337
-rw-r--r--includes/api/ApiParamInfo.php455
-rw-r--r--includes/api/ApiParse.php294
-rw-r--r--includes/api/ApiPatrol.php21
-rw-r--r--includes/api/ApiProtect.php46
-rw-r--r--includes/api/ApiPurge.php39
-rw-r--r--includes/api/ApiQuery.php117
-rw-r--r--includes/api/ApiQueryAllCategories.php42
-rw-r--r--includes/api/ApiQueryAllDeletedRevisions.php427
-rw-r--r--includes/api/ApiQueryAllImages.php99
-rw-r--r--includes/api/ApiQueryAllLinks.php95
-rw-r--r--includes/api/ApiQueryAllMessages.php43
-rw-r--r--includes/api/ApiQueryAllPages.php79
-rw-r--r--includes/api/ApiQueryAllUsers.php273
-rw-r--r--includes/api/ApiQueryBacklinks.php483
-rw-r--r--includes/api/ApiQueryBacklinksprop.php114
-rw-r--r--includes/api/ApiQueryBase.php42
-rw-r--r--includes/api/ApiQueryBlocks.php114
-rw-r--r--includes/api/ApiQueryCategories.php42
-rw-r--r--includes/api/ApiQueryCategoryInfo.php26
-rw-r--r--includes/api/ApiQueryCategoryMembers.php89
-rw-r--r--includes/api/ApiQueryContributors.php37
-rw-r--r--includes/api/ApiQueryDeletedRevisions.php304
-rw-r--r--includes/api/ApiQueryDeletedrevs.php158
-rw-r--r--includes/api/ApiQueryDisabled.php14
-rw-r--r--includes/api/ApiQueryDuplicateFiles.php33
-rw-r--r--includes/api/ApiQueryExtLinksUsage.php60
-rw-r--r--includes/api/ApiQueryExternalLinks.php31
-rw-r--r--includes/api/ApiQueryFileRepoInfo.php27
-rw-r--r--includes/api/ApiQueryFilearchive.php69
-rw-r--r--includes/api/ApiQueryIWBacklinks.php39
-rw-r--r--includes/api/ApiQueryIWLinks.php51
-rw-r--r--includes/api/ApiQueryImageInfo.php121
-rw-r--r--includes/api/ApiQueryImages.php28
-rw-r--r--includes/api/ApiQueryInfo.php122
-rw-r--r--includes/api/ApiQueryLangBacklinks.php40
-rw-r--r--includes/api/ApiQueryLangLinks.php55
-rw-r--r--includes/api/ApiQueryLinks.php43
-rw-r--r--includes/api/ApiQueryLogEvents.php184
-rw-r--r--includes/api/ApiQueryORM.php11
-rw-r--r--includes/api/ApiQueryPagePropNames.php22
-rw-r--r--includes/api/ApiQueryPageProps.php22
-rw-r--r--includes/api/ApiQueryPagesWithProp.php39
-rw-r--r--includes/api/ApiQueryPrefixSearch.php40
-rw-r--r--includes/api/ApiQueryProtectedTitles.php40
-rw-r--r--includes/api/ApiQueryQueryPage.php28
-rw-r--r--includes/api/ApiQueryRandom.php27
-rw-r--r--includes/api/ApiQueryRecentChanges.php122
-rw-r--r--includes/api/ApiQueryRevisions.php616
-rw-r--r--includes/api/ApiQueryRevisionsBase.php477
-rw-r--r--includes/api/ApiQuerySearch.php160
-rw-r--r--includes/api/ApiQuerySiteinfo.php260
-rw-r--r--includes/api/ApiQueryStashImageInfo.php52
-rw-r--r--includes/api/ApiQueryTags.php169
-rw-r--r--includes/api/ApiQueryTokens.php30
-rw-r--r--includes/api/ApiQueryUserContributions.php92
-rw-r--r--includes/api/ApiQueryUserInfo.php89
-rw-r--r--includes/api/ApiQueryUsers.php69
-rw-r--r--includes/api/ApiQueryWatchlist.php122
-rw-r--r--includes/api/ApiQueryWatchlistRaw.php36
-rw-r--r--includes/api/ApiResult.php1553
-rw-r--r--includes/api/ApiRevisionDelete.php36
-rw-r--r--includes/api/ApiRollback.php36
-rw-r--r--includes/api/ApiRsd.php44
-rw-r--r--includes/api/ApiSerializable.php47
-rw-r--r--includes/api/ApiSetNotificationTimestamp.php67
-rw-r--r--includes/api/ApiStashEdit.php412
-rw-r--r--includes/api/ApiTag.php177
-rw-r--r--includes/api/ApiTokens.php39
-rw-r--r--includes/api/ApiUnblock.php24
-rw-r--r--includes/api/ApiUndelete.php36
-rw-r--r--includes/api/ApiUpload.php138
-rw-r--r--includes/api/ApiUserrights.php56
-rw-r--r--includes/api/ApiWatch.php58
-rw-r--r--includes/api/i18n/ar.json28
-rw-r--r--includes/api/i18n/av.json8
-rw-r--r--includes/api/i18n/awa.json11
-rw-r--r--includes/api/i18n/be-tarask.json55
-rw-r--r--includes/api/i18n/bn.json8
-rw-r--r--includes/api/i18n/bs.json16
-rw-r--r--includes/api/i18n/ca.json43
-rw-r--r--includes/api/i18n/ce.json12
-rw-r--r--includes/api/i18n/cs.json223
-rw-r--r--includes/api/i18n/cv.json8
-rw-r--r--includes/api/i18n/de.json433
-rw-r--r--includes/api/i18n/el.json12
-rw-r--r--includes/api/i18n/en-gb.json156
-rw-r--r--includes/api/i18n/en.json1169
-rw-r--r--includes/api/i18n/es.json206
-rw-r--r--includes/api/i18n/eu.json57
-rw-r--r--includes/api/i18n/fa.json240
-rw-r--r--includes/api/i18n/fi.json10
-rw-r--r--includes/api/i18n/fr.json1054
-rw-r--r--includes/api/i18n/frc.json19
-rw-r--r--includes/api/i18n/fy.json15
-rw-r--r--includes/api/i18n/gl.json1030
-rw-r--r--includes/api/i18n/he.json180
-rw-r--r--includes/api/i18n/hsb.json8
-rw-r--r--includes/api/i18n/hu.json17
-rw-r--r--includes/api/i18n/ia.json28
-rw-r--r--includes/api/i18n/it.json31
-rw-r--r--includes/api/i18n/ja.json213
-rw-r--r--includes/api/i18n/jam.json8
-rw-r--r--includes/api/i18n/ko.json36
-rw-r--r--includes/api/i18n/ksh.json311
-rw-r--r--includes/api/i18n/ku-latn.json9
-rw-r--r--includes/api/i18n/lb.json94
-rw-r--r--includes/api/i18n/ln.json8
-rw-r--r--includes/api/i18n/lv.json8
-rw-r--r--includes/api/i18n/lzh.json8
-rw-r--r--includes/api/i18n/mg.json11
-rw-r--r--includes/api/i18n/mk.json398
-rw-r--r--includes/api/i18n/ms.json61
-rw-r--r--includes/api/i18n/nap.json10
-rw-r--r--includes/api/i18n/nb.json24
-rw-r--r--includes/api/i18n/nds.json8
-rw-r--r--includes/api/i18n/nl.json61
-rw-r--r--includes/api/i18n/oc.json17
-rw-r--r--includes/api/i18n/pa.json8
-rw-r--r--includes/api/i18n/pam.json31
-rw-r--r--includes/api/i18n/pl.json117
-rw-r--r--includes/api/i18n/ps.json29
-rw-r--r--includes/api/i18n/pt-br.json14
-rw-r--r--includes/api/i18n/pt.json104
-rw-r--r--includes/api/i18n/qqq.json1069
-rw-r--r--includes/api/i18n/roa-tara.json11
-rw-r--r--includes/api/i18n/ru.json55
-rw-r--r--includes/api/i18n/si.json70
-rw-r--r--includes/api/i18n/sr-ec.json24
-rw-r--r--includes/api/i18n/sr-el.json11
-rw-r--r--includes/api/i18n/sv.json372
-rw-r--r--includes/api/i18n/te.json8
-rw-r--r--includes/api/i18n/tl.json35
-rw-r--r--includes/api/i18n/tr.json40
-rw-r--r--includes/api/i18n/uk.json30
-rw-r--r--includes/api/i18n/vi.json156
-rw-r--r--includes/api/i18n/zh-hans.json782
-rw-r--r--includes/api/i18n/zh-hant.json244
179 files changed, 19056 insertions, 5938 deletions
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index 944e4895..5a1eb995 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -32,9 +32,6 @@
* Module parameters: Derived classes can define getAllowedParams() to specify
* which parameters to expect, how to parse and validate them.
*
- * Profiling: various methods to allow keeping tabs on various tasks and their
- * time costs
- *
* Self-documentation: code to allow the API to document its own state
*
* @ingroup API
@@ -64,6 +61,30 @@ abstract class ApiBase extends ContextSource {
// Boolean, if MIN/MAX are set, enforce (die) these?
// Only applies if TYPE='integer' Use with extreme caution
const PARAM_RANGE_ENFORCE = 9;
+ /// @since 1.25
+ // Specify an alternative i18n message for this help parameter.
+ // Value is $msg for ApiBase::makeMessage()
+ const PARAM_HELP_MSG = 10;
+ /// @since 1.25
+ // Specify additional i18n messages to append to the normal message. Value
+ // is an array of $msg for ApiBase::makeMessage()
+ const PARAM_HELP_MSG_APPEND = 11;
+ /// @since 1.25
+ // Specify additional information tags for the parameter. Value is an array
+ // of arrays, with the first member being the 'tag' for the info and the
+ // remaining members being the values. In the help, this is formatted using
+ // apihelp-{$path}-paraminfo-{$tag}, which is passed $1 = count, $2 =
+ // comma-joined list of values, $3 = module prefix.
+ const PARAM_HELP_MSG_INFO = 12;
+ /// @since 1.25
+ // When PARAM_TYPE is an array, this may be an array mapping those values
+ // to page titles which will be linked in the help.
+ const PARAM_VALUE_LINKS = 13;
+ /// @since 1.25
+ // When PARAM_TYPE is an array, this is an array mapping those values to
+ // $msg for ApiBase::makeMessage(). Any value not having a mapping will use
+ // apihelp-{$path}-paramvalue-{$param}-{$value} is used.
+ const PARAM_HELP_MSG_PER_VALUE = 14;
const LIMIT_BIG1 = 500; // Fast query, std user limit
const LIMIT_BIG2 = 5000; // Fast query, bot/sysop limit
@@ -136,6 +157,9 @@ abstract class ApiBase extends ContextSource {
* If the module may only be used with a certain format module,
* it should override this method to return an instance of that formatter.
* A value of null means the default format will be used.
+ * @note Do not use this just because you don't want to support non-json
+ * formats. This should be used only when there is a fundamental
+ * requirement for a specific format.
* @return mixed Instance of a derived class of ApiFormatBase, or null
*/
public function getCustomPrinter() {
@@ -143,27 +167,64 @@ abstract class ApiBase extends ContextSource {
}
/**
- * Returns the description string for this module
- * @return string|array
+ * Returns usage examples for this module.
+ *
+ * Return value has query strings as keys, with values being either strings
+ * (message key), arrays (message key + parameter), or Message objects.
+ *
+ * Do not call this base class implementation when overriding this method.
+ *
+ * @since 1.25
+ * @return array
*/
- protected function getDescription() {
- return false;
- }
+ protected function getExamplesMessages() {
+ // Fall back to old non-localised method
+ $ret = array();
+
+ $examples = $this->getExamples();
+ if ( $examples ) {
+ if ( !is_array( $examples ) ) {
+ $examples = array( $examples );
+ } elseif ( $examples && ( count( $examples ) & 1 ) == 0 &&
+ array_keys( $examples ) === range( 0, count( $examples ) - 1 ) &&
+ !preg_match( '/^\s*api\.php\?/', $examples[0] )
+ ) {
+ // Fix up the ugly "even numbered elements are description, odd
+ // numbered elemts are the link" format (see doc for self::getExamples)
+ $tmp = array();
+ for ( $i = 0; $i < count( $examples ); $i += 2 ) {
+ $tmp[$examples[$i + 1]] = $examples[$i];
+ }
+ $examples = $tmp;
+ }
- /**
- * Returns usage examples for this module. Return false if no examples are available.
- * @return bool|string|array
- */
- protected function getExamples() {
- return false;
+ foreach ( $examples as $k => $v ) {
+ if ( is_numeric( $k ) ) {
+ $qs = $v;
+ $msg = '';
+ } else {
+ $qs = $k;
+ $msg = self::escapeWikiText( $v );
+ if ( is_array( $msg ) ) {
+ $msg = join( " ", $msg );
+ }
+ }
+
+ $qs = preg_replace( '/^\s*api\.php\?/', '', $qs );
+ $ret[$qs] = $this->msg( 'api-help-fallback-example', array( $msg ) );
+ }
+ }
+
+ return $ret;
}
/**
- * @return bool|string|array Returns a false if the module has no help URL,
- * else returns a (array of) string
+ * Return links to more detailed help pages about the module.
+ * @since 1.25, returning boolean false is deprecated
+ * @return string|array
*/
public function getHelpUrls() {
- return false;
+ return array();
}
/**
@@ -176,22 +237,12 @@ abstract class ApiBase extends ContextSource {
* in the overriding methods. Callers of this method can pass zero or
* more OR-ed flags like GET_VALUES_FOR_HELP.
*
- * @return array|bool
+ * @return array
*/
protected function getAllowedParams( /* $flags = 0 */ ) {
// int $flags is not declared because it causes "Strict standards"
// warning. Most derived classes do not implement it.
- return false;
- }
-
- /**
- * Returns an array of parameter descriptions.
- * Don't call this function directly: use getFinalParamDescription() to
- * allow hooks to modify descriptions as needed.
- * @return array|bool False on no parameter descriptions
- */
- protected function getParamDescription() {
- return false;
+ return array();
}
/**
@@ -227,6 +278,25 @@ abstract class ApiBase extends ContextSource {
}
/**
+ * Indicates whether this module is deprecated
+ * @since 1.25
+ * @return bool
+ */
+ public function isDeprecated() {
+ return false;
+ }
+
+ /**
+ * Indicates whether this module is "internal"
+ * Internal API modules are not (yet) intended for 3rd party use and may be unstable.
+ * @since 1.25
+ * @return bool
+ */
+ public function isInternal() {
+ return false;
+ }
+
+ /**
* Returns the token type this module requires in order to execute.
*
* Modules are strongly encouraged to use the core 'csrf' type unless they
@@ -234,11 +304,9 @@ abstract class ApiBase extends ContextSource {
* core types, you must use the ApiQueryTokensRegisterTypes hook to
* register it.
*
- * Returning a non-falsey value here will cause self::getFinalParams() to
- * return a required string 'token' parameter and
- * self::getFinalParamDescription() to ensure there is standardized
- * documentation for it. Also, self::mustBePosted() must return true when
- * tokens are used.
+ * Returning a non-falsey value here will force the addition of an
+ * appropriate 'token' parameter in self::getFinalParams(). Also,
+ * self::mustBePosted() must return true when tokens are used.
*
* In previous versions of MediaWiki, true was a valid return value.
* Returning true will generate errors indicating that the API module needs
@@ -304,6 +372,87 @@ abstract class ApiBase extends ContextSource {
}
/**
+ * Get the parent of this module
+ * @since 1.25
+ * @return ApiBase|null
+ */
+ public function getParent() {
+ return $this->isMain() ? null : $this->getMain();
+ }
+
+ /**
+ * Returns true if the current request breaks the same-origin policy.
+ *
+ * For example, json with callbacks.
+ *
+ * https://en.wikipedia.org/wiki/Same-origin_policy
+ *
+ * @since 1.25
+ * @return bool
+ */
+ public function lacksSameOriginSecurity() {
+ return $this->getMain()->getRequest()->getVal( 'callback' ) !== null;
+ }
+
+ /**
+ * Get the path to this module
+ *
+ * @since 1.25
+ * @return string
+ */
+ public function getModulePath() {
+ if ( $this->isMain() ) {
+ return 'main';
+ } elseif ( $this->getParent()->isMain() ) {
+ return $this->getModuleName();
+ } else {
+ return $this->getParent()->getModulePath() . '+' . $this->getModuleName();
+ }
+ }
+
+ /**
+ * Get a module from its module path
+ *
+ * @since 1.25
+ * @param string $path
+ * @return ApiBase|null
+ * @throws UsageException
+ */
+ public function getModuleFromPath( $path ) {
+ $module = $this->getMain();
+ if ( $path === 'main' ) {
+ return $module;
+ }
+
+ $parts = explode( '+', $path );
+ if ( count( $parts ) === 1 ) {
+ // In case the '+' was typed into URL, it resolves as a space
+ $parts = explode( ' ', $path );
+ }
+
+ $count = count( $parts );
+ for ( $i = 0; $i < $count; $i++ ) {
+ $parent = $module;
+ $manager = $parent->getModuleManager();
+ if ( $manager === null ) {
+ $errorPath = join( '+', array_slice( $parts, 0, $i ) );
+ $this->dieUsage( "The module \"$errorPath\" has no submodules", 'badmodule' );
+ }
+ $module = $manager->getModule( $parts[$i] );
+
+ if ( $module === null ) {
+ $errorPath = $i ? join( '+', array_slice( $parts, 0, $i ) ) : $parent->getModuleName();
+ $this->dieUsage(
+ "The module \"$errorPath\" does not have a submodule \"{$parts[$i]}\"",
+ 'badmodule'
+ );
+ }
+ }
+
+ return $module;
+ }
+
+ /**
* Get the result object
* @return ApiResult
*/
@@ -318,11 +467,17 @@ abstract class ApiBase extends ContextSource {
}
/**
- * Get the result data array (read-only)
- * @return array
+ * Get the error formatter
+ * @return ApiErrorFormatter
*/
- public function getResultData() {
- return $this->getResult()->getData();
+ public function getErrorFormatter() {
+ // Main module has getErrorFormatter() method overridden
+ // Safety - avoid infinite loop:
+ if ( $this->isMain() ) {
+ ApiBase::dieDebug( __METHOD__, 'base method was called on main module. ' );
+ }
+
+ return $this->getMain()->getErrorFormatter();
}
/**
@@ -331,76 +486,38 @@ abstract class ApiBase extends ContextSource {
*/
protected function getDB() {
if ( !isset( $this->mSlaveDB ) ) {
- $this->profileDBIn();
$this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
- $this->profileDBOut();
}
return $this->mSlaveDB;
}
/**
- * Get final module description, after hooks have had a chance to tweak it as
- * needed.
- *
- * @return array|bool False on no parameters
- */
- public function getFinalDescription() {
- $desc = $this->getDescription();
- wfRunHooks( 'APIGetDescription', array( &$this, &$desc ) );
-
- return $desc;
- }
-
- /**
- * Get final list of parameters, after hooks have had a chance to
- * tweak it as needed.
- *
- * @param int $flags Zero or more flags like GET_VALUES_FOR_HELP
- * @return array|bool False on no parameters
- * @since 1.21 $flags param added
+ * Get the continuation manager
+ * @return ApiContinuationManager|null
*/
- public function getFinalParams( $flags = 0 ) {
- $params = $this->getAllowedParams( $flags );
-
- if ( $this->needsToken() ) {
- $params['token'] = array(
- ApiBase::PARAM_TYPE => 'string',
- ApiBase::PARAM_REQUIRED => true,
- );
+ public function getContinuationManager() {
+ // Main module has getContinuationManager() method overridden
+ // Safety - avoid infinite loop:
+ if ( $this->isMain() ) {
+ ApiBase::dieDebug( __METHOD__, 'base method was called on main module. ' );
}
- wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
-
- return $params;
+ return $this->getMain()->getContinuationManager();
}
/**
- * Get final parameter descriptions, after hooks have had a chance to tweak it as
- * needed.
- *
- * @return array|bool False on no parameter descriptions
+ * Set the continuation manager
+ * @param ApiContinuationManager|null
*/
- public function getFinalParamDescription() {
- $desc = $this->getParamDescription();
-
- $tokenType = $this->needsToken();
- if ( $tokenType ) {
- if ( !isset( $desc['token'] ) ) {
- $desc['token'] = array();
- } elseif ( !is_array( $desc['token'] ) ) {
- // We ignore a plain-string token, because it's probably an
- // extension that is supplying the string for BC.
- $desc['token'] = array();
- }
- array_unshift( $desc['token'],
- "A '$tokenType' token retrieved from action=query&meta=tokens"
- );
+ public function setContinuationManager( $manager ) {
+ // Main module has setContinuationManager() method overridden
+ // Safety - avoid infinite loop:
+ if ( $this->isMain() ) {
+ ApiBase::dieDebug( __METHOD__, 'base method was called on main module. ' );
}
- wfRunHooks( 'APIGetParamDescription', array( &$this, &$desc ) );
-
- return $desc;
+ $this->getMain()->setContinuationManager( $manager );
}
/**@}*/
@@ -782,7 +899,7 @@ abstract class ApiBase extends ContextSource {
$value = $this->getMain()->canApiHighLimits()
? $paramSettings[self::PARAM_MAX2]
: $paramSettings[self::PARAM_MAX];
- $this->getResult()->setParsedLimit( $this->getModuleName(), $value );
+ $this->getResult()->addParsedLimit( $this->getModuleName(), $value );
} else {
$value = intval( $value );
$this->validateLimit(
@@ -974,8 +1091,9 @@ abstract class ApiBase extends ContextSource {
* @param string $token Supplied token
* @param array $params All supplied parameters for the module
* @return bool
+ * @throws MWException
*/
- public final function validateToken( $token, array $params ) {
+ final public function validateToken( $token, array $params ) {
$tokenType = $this->needsToken();
$salts = ApiQueryTokens::getTokenTypeSalts();
if ( !isset( $salts[$tokenType] ) ) {
@@ -1093,6 +1211,55 @@ abstract class ApiBase extends ContextSource {
return $user;
}
+ /**
+ * A subset of wfEscapeWikiText for BC texts
+ *
+ * @since 1.25
+ * @param string|array $v
+ * @return string|array
+ */
+ private static function escapeWikiText( $v ) {
+ if ( is_array( $v ) ) {
+ return array_map( 'self::escapeWikiText', $v );
+ } else {
+ return strtr( $v, array(
+ '__' => '_&#95;', '{' => '&#123;', '}' => '&#125;',
+ '[[Category:' => '[[:Category:',
+ '[[File:' => '[[:File:', '[[Image:' => '[[:Image:',
+ ) );
+ }
+ }
+
+ /**
+ * Create a Message from a string or array
+ *
+ * A string is used as a message key. An array has the message key as the
+ * first value and message parameters as subsequent values.
+ *
+ * @since 1.25
+ * @param string|array|Message $msg
+ * @param IContextSource $context
+ * @param array $params
+ * @return Message|null
+ */
+ public static function makeMessage( $msg, IContextSource $context, array $params = null ) {
+ if ( is_string( $msg ) ) {
+ $msg = wfMessage( $msg );
+ } elseif ( is_array( $msg ) ) {
+ $msg = call_user_func_array( 'wfMessage', $msg );
+ }
+ if ( !$msg instanceof Message ) {
+ return null;
+ }
+
+ $msg->setContext( $context );
+ if ( $params ) {
+ $msg->params( $params );
+ }
+
+ return $msg;
+ }
+
/**@}*/
/************************************************************************//**
@@ -1108,28 +1275,8 @@ abstract class ApiBase extends ContextSource {
* @param string $warning Warning message
*/
public function setWarning( $warning ) {
- $result = $this->getResult();
- $data = $result->getData();
- $moduleName = $this->getModuleName();
- if ( isset( $data['warnings'][$moduleName] ) ) {
- // Don't add duplicate warnings
- $oldWarning = $data['warnings'][$moduleName]['*'];
- $warnPos = strpos( $oldWarning, $warning );
- // If $warning was found in $oldWarning, check if it starts at 0 or after "\n"
- if ( $warnPos !== false && ( $warnPos === 0 || $oldWarning[$warnPos - 1] === "\n" ) ) {
- // Check if $warning is followed by "\n" or the end of the $oldWarning
- $warnPos += strlen( $warning );
- if ( strlen( $oldWarning ) <= $warnPos || $oldWarning[$warnPos] === "\n" ) {
- return;
- }
- }
- // If there is a warning already, append it to the existing one
- $warning = "$oldWarning\n$warning";
- }
- $msg = array();
- ApiResult::setContent( $msg, $warning );
- $result->addValue( 'warnings', $moduleName,
- $msg, ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ $msg = new ApiRawMessage( $warning, 'warning' );
+ $this->getErrorFormatter()->addWarning( $this->getModuleName(), $msg );
}
/**
@@ -1159,7 +1306,6 @@ abstract class ApiBase extends ContextSource {
* @throws UsageException
*/
public function dieUsage( $description, $errorCode, $httpRespCode = 0, $extradata = null ) {
- Profiler::instance()->close();
throw new UsageException(
$description,
$this->encodeParamName( $errorCode ),
@@ -1174,6 +1320,7 @@ abstract class ApiBase extends ContextSource {
* @since 1.23
* @param Status $status
* @return array Array of code and error string
+ * @throws MWException
*/
public function getErrorFromStatus( $status ) {
if ( $status->isGood() ) {
@@ -1530,6 +1677,10 @@ abstract class ApiBase extends ContextSource {
'code' => 'nosuchrcid',
'info' => "There is no change with rcid \"\$1\""
),
+ 'nosuchlogid' => array(
+ 'code' => 'nosuchlogid',
+ 'info' => "There is no log entry with ID \"\$1\""
+ ),
'protect-invalidaction' => array(
'code' => 'protect-invalidaction',
'info' => "Invalid protection type \"\$1\""
@@ -1815,6 +1966,21 @@ abstract class ApiBase extends ContextSource {
throw new MWException( "Internal error in $method: $message" );
}
+ /**
+ * Write logging information for API features to a debug log, for usage
+ * analysis.
+ * @param string $feature Feature being used.
+ */
+ protected function logFeatureUsage( $feature ) {
+ $request = $this->getRequest();
+ $s = '"' . addslashes( $feature ) . '"' .
+ ' "' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) . '"' .
+ ' "' . $request->getIP() . '"' .
+ ' "' . addslashes( $request->getHeader( 'Referer' ) ) . '"' .
+ ' "' . addslashes( $this->getMain()->getUserAgent() ) . '"';
+ wfDebugLog( 'api-feature-usage', $s, 'private' );
+ }
+
/**@}*/
/************************************************************************//**
@@ -1823,10 +1989,424 @@ abstract class ApiBase extends ContextSource {
*/
/**
+ * Return the description message.
+ *
+ * @return string|array|Message
+ */
+ protected function getDescriptionMessage() {
+ return "apihelp-{$this->getModulePath()}-description";
+ }
+
+ /**
+ * Get final module description, after hooks have had a chance to tweak it as
+ * needed.
+ *
+ * @since 1.25, returns Message[] rather than string[]
+ * @return Message[]
+ */
+ public function getFinalDescription() {
+ $desc = $this->getDescription();
+ Hooks::run( 'APIGetDescription', array( &$this, &$desc ) );
+ $desc = self::escapeWikiText( $desc );
+ if ( is_array( $desc ) ) {
+ $desc = join( "\n", $desc );
+ } else {
+ $desc = (string)$desc;
+ }
+
+ $msg = ApiBase::makeMessage( $this->getDescriptionMessage(), $this->getContext(), array(
+ $this->getModulePrefix(),
+ $this->getModuleName(),
+ $this->getModulePath(),
+ ) );
+ if ( !$msg->exists() ) {
+ $msg = $this->msg( 'api-help-fallback-description', $desc );
+ }
+ $msgs = array( $msg );
+
+ Hooks::run( 'APIGetDescriptionMessages', array( $this, &$msgs ) );
+
+ return $msgs;
+ }
+
+ /**
+ * Get final list of parameters, after hooks have had a chance to
+ * tweak it as needed.
+ *
+ * @param int $flags Zero or more flags like GET_VALUES_FOR_HELP
+ * @return array|bool False on no parameters
+ * @since 1.21 $flags param added
+ */
+ public function getFinalParams( $flags = 0 ) {
+ $params = $this->getAllowedParams( $flags );
+ if ( !$params ) {
+ $params = array();
+ }
+
+ if ( $this->needsToken() ) {
+ $params['token'] = array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'api-help-param-token',
+ $this->needsToken(),
+ ),
+ ) + ( isset( $params['token'] ) ? $params['token'] : array() );
+ }
+
+ Hooks::run( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
+
+ return $params;
+ }
+
+ /**
+ * Get final parameter descriptions, after hooks have had a chance to tweak it as
+ * needed.
+ *
+ * @since 1.25, returns array of Message[] rather than array of string[]
+ * @return array Keys are parameter names, values are arrays of Message objects
+ */
+ public function getFinalParamDescription() {
+ $prefix = $this->getModulePrefix();
+ $name = $this->getModuleName();
+ $path = $this->getModulePath();
+
+ $desc = $this->getParamDescription();
+ Hooks::run( 'APIGetParamDescription', array( &$this, &$desc ) );
+
+ if ( !$desc ) {
+ $desc = array();
+ }
+ $desc = self::escapeWikiText( $desc );
+
+ $params = $this->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
+ $msgs = array();
+ foreach ( $params as $param => $settings ) {
+ if ( !is_array( $settings ) ) {
+ $settings = array();
+ }
+
+ $d = isset( $desc[$param] ) ? $desc[$param] : '';
+ if ( is_array( $d ) ) {
+ // Special handling for prop parameters
+ $d = array_map( function ( $line ) {
+ if ( preg_match( '/^\s+(\S+)\s+-\s+(.+)$/', $line, $m ) ) {
+ $line = "\n;{$m[1]}:{$m[2]}";
+ }
+ return $line;
+ }, $d );
+ $d = join( ' ', $d );
+ }
+
+ if ( isset( $settings[ApiBase::PARAM_HELP_MSG] ) ) {
+ $msg = $settings[ApiBase::PARAM_HELP_MSG];
+ } else {
+ $msg = $this->msg( "apihelp-{$path}-param-{$param}" );
+ if ( !$msg->exists() ) {
+ $msg = $this->msg( 'api-help-fallback-parameter', $d );
+ }
+ }
+ $msg = ApiBase::makeMessage( $msg, $this->getContext(),
+ array( $prefix, $param, $name, $path ) );
+ if ( !$msg ) {
+ $this->dieDebug( __METHOD__,
+ 'Value in ApiBase::PARAM_HELP_MSG is not valid' );
+ }
+ $msgs[$param] = array( $msg );
+
+ if ( isset( $settings[ApiBase::PARAM_HELP_MSG_PER_VALUE] ) ) {
+ if ( !is_array( $settings[ApiBase::PARAM_HELP_MSG_PER_VALUE] ) ) {
+ $this->dieDebug( __METHOD__,
+ 'ApiBase::PARAM_HELP_MSG_PER_VALUE is not valid' );
+ }
+ if ( !is_array( $settings[ApiBase::PARAM_TYPE] ) ) {
+ $this->dieDebug( __METHOD__,
+ 'ApiBase::PARAM_HELP_MSG_PER_VALUE may only be used when ' .
+ 'ApiBase::PARAM_TYPE is an array' );
+ }
+
+ $valueMsgs = $settings[ApiBase::PARAM_HELP_MSG_PER_VALUE];
+ foreach ( $settings[ApiBase::PARAM_TYPE] as $value ) {
+ if ( isset( $valueMsgs[$value] ) ) {
+ $msg = $valueMsgs[$value];
+ } else {
+ $msg = "apihelp-{$path}-paramvalue-{$param}-{$value}";
+ }
+ $m = ApiBase::makeMessage( $msg, $this->getContext(),
+ array( $prefix, $param, $name, $path, $value ) );
+ if ( $m ) {
+ $m = new ApiHelpParamValueMessage(
+ $value,
+ array( $m->getKey(), 'api-help-param-no-description' ),
+ $m->getParams()
+ );
+ $msgs[$param][] = $m->setContext( $this->getContext() );
+ } else {
+ $this->dieDebug( __METHOD__,
+ "Value in ApiBase::PARAM_HELP_MSG_PER_VALUE for $value is not valid" );
+ }
+ }
+ }
+
+ if ( isset( $settings[ApiBase::PARAM_HELP_MSG_APPEND] ) ) {
+ if ( !is_array( $settings[ApiBase::PARAM_HELP_MSG_APPEND] ) ) {
+ $this->dieDebug( __METHOD__,
+ 'Value for ApiBase::PARAM_HELP_MSG_APPEND is not an array' );
+ }
+ foreach ( $settings[ApiBase::PARAM_HELP_MSG_APPEND] as $m ) {
+ $m = ApiBase::makeMessage( $m, $this->getContext(),
+ array( $prefix, $param, $name, $path ) );
+ if ( $m ) {
+ $msgs[$param][] = $m;
+ } else {
+ $this->dieDebug( __METHOD__,
+ 'Value in ApiBase::PARAM_HELP_MSG_APPEND is not valid' );
+ }
+ }
+ }
+ }
+
+ Hooks::run( 'APIGetParamDescriptionMessages', array( $this, &$msgs ) );
+
+ return $msgs;
+ }
+
+ /**
+ * Generates the list of flags for the help screen and for action=paraminfo
+ *
+ * Corresponding messages: api-help-flag-deprecated,
+ * api-help-flag-internal, api-help-flag-readrights,
+ * api-help-flag-writerights, api-help-flag-mustbeposted
+ *
+ * @return string[]
+ */
+ protected function getHelpFlags() {
+ $flags = array();
+
+ if ( $this->isDeprecated() ) {
+ $flags[] = 'deprecated';
+ }
+ if ( $this->isInternal() ) {
+ $flags[] = 'internal';
+ }
+ if ( $this->isReadMode() ) {
+ $flags[] = 'readrights';
+ }
+ if ( $this->isWriteMode() ) {
+ $flags[] = 'writerights';
+ }
+ if ( $this->mustBePosted() ) {
+ $flags[] = 'mustbeposted';
+ }
+
+ return $flags;
+ }
+
+ /**
+ * Called from ApiHelp before the pieces are joined together and returned.
+ *
+ * This exists mainly for ApiMain to add the Permissions and Credits
+ * sections. Other modules probably don't need it.
+ *
+ * @param string[] &$help Array of help data
+ * @param array $options Options passed to ApiHelp::getHelp
+ */
+ public function modifyHelp( array &$help, array $options ) {
+ }
+
+ /**@}*/
+
+ /************************************************************************//**
+ * @name Deprecated
+ * @{
+ */
+
+ /// @deprecated since 1.24
+ const PROP_ROOT = 'ROOT';
+ /// @deprecated since 1.24
+ const PROP_LIST = 'LIST';
+ /// @deprecated since 1.24
+ const PROP_TYPE = 0;
+ /// @deprecated since 1.24
+ const PROP_NULLABLE = 1;
+
+ /**
+ * Formerly returned a string that identifies the version of the extending
+ * class. Typically included the class name, the svn revision, timestamp,
+ * and last author. Usually done with SVN's Id keyword
+ *
+ * @deprecated since 1.21, version string is no longer supported
+ * @return string
+ */
+ public function getVersion() {
+ wfDeprecated( __METHOD__, '1.21' );
+ return '';
+ }
+
+ /**
+ * Formerly used to fetch a list of possible properites in the result,
+ * somehow organized with respect to the prop parameter that causes them to
+ * be returned. The specific semantics of the return value was never
+ * specified. Since this was never possible to be accurately updated, it
+ * has been removed.
+ *
+ * @deprecated since 1.24
+ * @return array|bool
+ */
+ protected function getResultProperties() {
+ wfDeprecated( __METHOD__, '1.24' );
+ return false;
+ }
+
+ /**
+ * @see self::getResultProperties()
+ * @deprecated since 1.24
+ * @return array|bool
+ */
+ public function getFinalResultProperties() {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getResultProperties()
+ * @deprecated since 1.24
+ */
+ protected static function addTokenProperties( &$props, $tokenFunctions ) {
+ wfDeprecated( __METHOD__, '1.24' );
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getRequireOnlyOneParameterErrorMessages( $params ) {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getRequireMaxOneParameterErrorMessages( $params ) {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getRequireAtLeastOneParameterErrorMessages( $params ) {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getTitleOrPageIdErrorMessage() {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * This formerly attempted to return a list of all possible errors returned
+ * by the module. However, this was impossible to maintain in many cases
+ * since errors could come from other areas of MediaWiki and in some cases
+ * from arbitrary extension hooks. Since a partial list claiming to be
+ * comprehensive is unlikely to be useful, it was removed.
+ *
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getPossibleErrors() {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function getFinalPossibleErrors() {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * @see self::getPossibleErrors()
+ * @deprecated since 1.24
+ * @return array
+ */
+ public function parseErrors( $errors ) {
+ wfDeprecated( __METHOD__, '1.24' );
+ return array();
+ }
+
+ /**
+ * Returns the description string for this module
+ *
+ * Ignored if an i18n message exists for
+ * "apihelp-{$this->getModulePathString()}-description".
+ *
+ * @deprecated since 1.25
+ * @return Message|string|array
+ */
+ protected function getDescription() {
+ return false;
+ }
+
+ /**
+ * Returns an array of parameter descriptions.
+ *
+ * For each parameter, ignored if an i18n message exists for the parameter.
+ * By default that message is
+ * "apihelp-{$this->getModulePathString()}-param-{$param}", but it may be
+ * overridden using ApiBase::PARAM_HELP_MSG in the data returned by
+ * self::getFinalParams().
+ *
+ * @deprecated since 1.25
+ * @return array|bool False on no parameter descriptions
+ */
+ protected function getParamDescription() {
+ return array();
+ }
+
+ /**
+ * Returns usage examples for this module.
+ *
+ * Return value as an array is either:
+ * - numeric keys with partial URLs ("api.php?" plus a query string) as
+ * values
+ * - sequential numeric keys with even-numbered keys being display-text
+ * and odd-numbered keys being partial urls
+ * - partial URLs as keys with display-text (string or array-to-be-joined)
+ * as values
+ * Return value as a string is the same as an array with a numeric key and
+ * that value, and boolean false means "no examples".
+ *
+ * @deprecated since 1.25, use getExamplesMessages() instead
+ * @return bool|string|array
+ */
+ protected function getExamples() {
+ return false;
+ }
+
+ /**
* Generates help message for this module, or false if there is no description
+ * @deprecated since 1.25
* @return string|bool
*/
public function makeHelpMsg() {
+ wfDeprecated( __METHOD__, '1.25' );
static $lnPrfx = "\n ";
$msg = $this->getFinalDescription();
@@ -1891,6 +2471,7 @@ abstract class ApiBase extends ContextSource {
}
/**
+ * @deprecated since 1.25
* @param string $item
* @return string
*/
@@ -1899,12 +2480,14 @@ abstract class ApiBase extends ContextSource {
}
/**
+ * @deprecated since 1.25
* @param string $prefix Text to split output items
* @param string $title What is being output
* @param string|array $input
* @return string
*/
protected function makeHelpArrayToString( $prefix, $title, $input ) {
+ wfDeprecated( __METHOD__, '1.25' );
if ( $input === false ) {
return '';
}
@@ -1929,9 +2512,11 @@ abstract class ApiBase extends ContextSource {
/**
* Generates the parameter descriptions for this module, to be displayed in the
* module's help.
+ * @deprecated since 1.25
* @return string|bool
*/
public function makeHelpMsgParameters() {
+ wfDeprecated( __METHOD__, '1.25' );
$params = $this->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
if ( $params ) {
@@ -2081,292 +2666,79 @@ abstract class ApiBase extends ContextSource {
return false;
}
- /**@}*/
-
- /************************************************************************//**
- * @name Profiling
- * @{
- */
-
/**
- * Profiling: total module execution time
- */
- private $mTimeIn = 0, $mModuleTime = 0;
-
- /**
- * Get the name of the module as shown in the profiler log
- *
+ * @deprecated since 1.25, always returns empty string
* @param DatabaseBase|bool $db
- *
* @return string
*/
public function getModuleProfileName( $db = false ) {
- if ( $db ) {
- return 'API:' . $this->mModuleName . '-DB';
- }
-
- return 'API:' . $this->mModuleName;
+ wfDeprecated( __METHOD__, '1.25' );
+ return '';
}
/**
- * Start module profiling
+ * @deprecated since 1.25
*/
public function profileIn() {
- if ( $this->mTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called twice without calling profileOut()' );
- }
- $this->mTimeIn = microtime( true );
- wfProfileIn( $this->getModuleProfileName() );
+ // No wfDeprecated() yet because extensions call this and might need to
+ // keep doing so for BC.
}
/**
- * End module profiling
+ * @deprecated since 1.25
*/
public function profileOut() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileIn() first' );
- }
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug(
- __METHOD__,
- 'Must be called after database profiling is done with profileDBOut()'
- );
- }
-
- $this->mModuleTime += microtime( true ) - $this->mTimeIn;
- $this->mTimeIn = 0;
- wfProfileOut( $this->getModuleProfileName() );
+ // No wfDeprecated() yet because extensions call this and might need to
+ // keep doing so for BC.
}
/**
- * When modules crash, sometimes it is needed to do a profileOut() regardless
- * of the profiling state the module was in. This method does such cleanup.
+ * @deprecated since 1.25
*/
public function safeProfileOut() {
- if ( $this->mTimeIn !== 0 ) {
- if ( $this->mDBTimeIn !== 0 ) {
- $this->profileDBOut();
- }
- $this->profileOut();
- }
+ wfDeprecated( __METHOD__, '1.25' );
}
/**
- * Total time the module was executed
+ * @deprecated since 1.25, always returns 0
* @return float
*/
public function getProfileTime() {
- if ( $this->mTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileOut() first' );
- }
-
- return $this->mModuleTime;
+ wfDeprecated( __METHOD__, '1.25' );
+ return 0;
}
/**
- * Profiling: database execution time
- */
- private $mDBTimeIn = 0, $mDBTime = 0;
-
- /**
- * Start module profiling
+ * @deprecated since 1.25
*/
public function profileDBIn() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug(
- __METHOD__,
- 'Must be called while profiling the entire module with profileIn()'
- );
- }
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called twice without calling profileDBOut()' );
- }
- $this->mDBTimeIn = microtime( true );
- wfProfileIn( $this->getModuleProfileName( true ) );
+ wfDeprecated( __METHOD__, '1.25' );
}
/**
- * End database profiling
+ * @deprecated since 1.25
*/
public function profileDBOut() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Must be called while profiling ' .
- 'the entire module with profileIn()' );
- }
- if ( $this->mDBTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileDBIn() first' );
- }
-
- $time = microtime( true ) - $this->mDBTimeIn;
- $this->mDBTimeIn = 0;
-
- $this->mDBTime += $time;
- $this->getMain()->mDBTime += $time;
- wfProfileOut( $this->getModuleProfileName( true ) );
+ wfDeprecated( __METHOD__, '1.25' );
}
/**
- * Total time the module used the database
+ * @deprecated since 1.25, always returns 0
* @return float
*/
public function getProfileDBTime() {
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileDBOut() first' );
- }
-
- return $this->mDBTime;
- }
-
- /**
- * Write logging information for API features to a debug log, for usage
- * analysis.
- * @param string $feature Feature being used.
- */
- protected function logFeatureUsage( $feature ) {
- $request = $this->getRequest();
- $s = '"' . addslashes( $feature ) . '"' .
- ' "' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) . '"' .
- ' "' . $request->getIP() . '"' .
- ' "' . addslashes( $request->getHeader( 'Referer' ) ) . '"' .
- ' "' . addslashes( $request->getHeader( 'User-agent' ) ) . '"';
- wfDebugLog( 'api-feature-usage', $s, 'private' );
- }
-
- /**@}*/
-
- /************************************************************************//**
- * @name Deprecated
- * @{
- */
-
- /// @deprecated since 1.24
- const PROP_ROOT = 'ROOT';
- /// @deprecated since 1.24
- const PROP_LIST = 'LIST';
- /// @deprecated since 1.24
- const PROP_TYPE = 0;
- /// @deprecated since 1.24
- const PROP_NULLABLE = 1;
-
- /**
- * Formerly returned a string that identifies the version of the extending
- * class. Typically included the class name, the svn revision, timestamp,
- * and last author. Usually done with SVN's Id keyword
- *
- * @deprecated since 1.21, version string is no longer supported
- * @return string
- */
- public function getVersion() {
- wfDeprecated( __METHOD__, '1.21' );
- return '';
- }
-
- /**
- * Formerly used to fetch a list of possible properites in the result,
- * somehow organized with respect to the prop parameter that causes them to
- * be returned. The specific semantics of the return value was never
- * specified. Since this was never possible to be accurately updated, it
- * has been removed.
- *
- * @deprecated since 1.24
- * @return array|bool
- */
- protected function getResultProperties() {
- wfDeprecated( __METHOD__, '1.24' );
- return false;
- }
-
- /**
- * @see self::getResultProperties()
- * @deprecated since 1.24
- * @return array|bool
- */
- public function getFinalResultProperties() {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
+ wfDeprecated( __METHOD__, '1.25' );
+ return 0;
}
/**
- * @see self::getResultProperties()
- * @deprecated since 1.24
- */
- protected static function addTokenProperties( &$props, $tokenFunctions ) {
- wfDeprecated( __METHOD__, '1.24' );
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
- * @return array
- */
- public function getRequireOnlyOneParameterErrorMessages( $params ) {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
- * @return array
- */
- public function getRequireMaxOneParameterErrorMessages( $params ) {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
- * @return array
- */
- public function getRequireAtLeastOneParameterErrorMessages( $params ) {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
- * @return array
- */
- public function getTitleOrPageIdErrorMessage() {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * This formerly attempted to return a list of all possible errors returned
- * by the module. However, this was impossible to maintain in many cases
- * since errors could come from other areas of MediaWiki and in some cases
- * from arbitrary extension hooks. Since a partial list claiming to be
- * comprehensive is unlikely to be useful, it was removed.
- *
- * @deprecated since 1.24
- * @return array
- */
- public function getPossibleErrors() {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
- * @return array
- */
- public function getFinalPossibleErrors() {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
- }
-
- /**
- * @see self::getPossibleErrors()
- * @deprecated since 1.24
+ * Get the result data array (read-only)
+ * @deprecated since 1.25, use $this->getResult() methods instead
* @return array
*/
- public function parseErrors( $errors ) {
- wfDeprecated( __METHOD__, '1.24' );
- return array();
+ public function getResultData() {
+ wfDeprecated( __METHOD__, '1.25' );
+ return $this->getResult()->getData();
}
/**@}*/
diff --git a/includes/api/ApiBlock.php b/includes/api/ApiBlock.php
index 07f62c66..4d39ce1b 100644
--- a/includes/api/ApiBlock.php
+++ b/includes/api/ApiBlock.php
@@ -78,7 +78,7 @@ class ApiBlock extends ApiBase {
'other',
$params['reason']
),
- 'Expiry' => $params['expiry'] == 'never' ? 'infinite' : $params['expiry'],
+ 'Expiry' => $params['expiry'],
'HardBlock' => !$params['anononly'],
'CreateAccount' => $params['nocreate'],
'AutoBlock' => $params['autoblock'],
@@ -113,27 +113,13 @@ class ApiBlock extends ApiBase {
}
$res['reason'] = $params['reason'];
- if ( $params['anononly'] ) {
- $res['anononly'] = '';
- }
- if ( $params['nocreate'] ) {
- $res['nocreate'] = '';
- }
- if ( $params['autoblock'] ) {
- $res['autoblock'] = '';
- }
- if ( $params['noemail'] ) {
- $res['noemail'] = '';
- }
- if ( $params['hidename'] ) {
- $res['hidename'] = '';
- }
- if ( $params['allowusertalk'] ) {
- $res['allowusertalk'] = '';
- }
- if ( $params['watchuser'] ) {
- $res['watchuser'] = '';
- }
+ $res['anononly'] = $params['anononly'];
+ $res['nocreate'] = $params['nocreate'];
+ $res['autoblock'] = $params['autoblock'];
+ $res['noemail'] = $params['noemail'];
+ $res['hidename'] = $params['hidename'];
+ $res['allowusertalk'] = $params['allowusertalk'];
+ $res['watchuser'] = $params['watchuser'];
$this->getResult()->addValue( null, $this->getModuleName(), $res );
}
@@ -165,38 +151,16 @@ class ApiBlock extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'user' => 'Username, IP address or IP range you want to block',
- 'expiry' => 'Relative expiry time, e.g. \'5 months\' or \'2 weeks\'. ' .
- 'If set to \'infinite\', \'indefinite\' or \'never\', the block will never expire.',
- 'reason' => 'Reason for block',
- 'anononly' => 'Block anonymous users only (i.e. disable anonymous edits for this IP)',
- 'nocreate' => 'Prevent account creation',
- 'autoblock' => 'Automatically block the last used IP address, and ' .
- 'any subsequent IP addresses they try to login from',
- 'noemail'
- => 'Prevent user from sending email through the wiki. (Requires the "blockemail" right.)',
- 'hidename' => 'Hide the username from the block log. (Requires the "hideuser" right.)',
- 'allowusertalk'
- => 'Allow the user to edit their own talk page (depends on $wgBlockAllowsUTEdit)',
- 'reblock' => 'If the user is already blocked, overwrite the existing block',
- 'watchuser' => 'Watch the user/IP\'s user and talk pages',
- );
- }
-
- public function getDescription() {
- return 'Block a user.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=block&user=123.5.5.12&expiry=3%20days&reason=First%20strike&token=123ABC',
- 'api.php?action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate=&autoblock=&noemail=&token=123ABC'
+ 'action=block&user=192.0.2.5&expiry=3%20days&reason=First%20strike&token=123ABC'
+ => 'apihelp-block-example-ip-simple',
+ 'action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate=&autoblock=&noemail=&token=123ABC'
+ => 'apihelp-block-example-user-complex',
);
}
diff --git a/includes/api/ApiCheckToken.php b/includes/api/ApiCheckToken.php
new file mode 100644
index 00000000..28c6ece7
--- /dev/null
+++ b/includes/api/ApiCheckToken.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Created on Jan 29, 2015
+ *
+ * Copyright © 2015 Brad Jorsch bjorsch@wikimedia.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @since 1.25
+ * @ingroup API
+ */
+class ApiCheckToken extends ApiBase {
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+ $token = $params['token'];
+ $maxage = $params['maxtokenage'];
+ $request = $this->getRequest();
+ $salts = ApiQueryTokens::getTokenTypeSalts();
+ $salt = $salts[$params['type']];
+
+ $res = array();
+
+ if ( $this->getUser()->matchEditToken( $token, $salt, $request, $maxage ) ) {
+ $res['result'] = 'valid';
+ } elseif ( $maxage !== null && $this->getUser()->matchEditToken( $token, $salt, $request ) ) {
+ $res['result'] = 'expired';
+ } else {
+ $res['result'] = 'invalid';
+ }
+
+ $ts = User::getEditTokenTimestamp( $token );
+ if ( $ts !== null ) {
+ $mwts = new MWTimestamp();
+ $mwts->timestamp->setTimestamp( $ts );
+ $res['generated'] = $mwts->getTimestamp( TS_ISO_8601 );
+ }
+
+ $this->getResult()->addValue( null, $this->getModuleName(), $res );
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'type' => array(
+ ApiBase::PARAM_TYPE => array_keys( ApiQueryTokens::getTokenTypeSalts() ),
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'token' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'maxtokenage' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
+ );
+ }
+
+ protected function getExamplesMessages() {
+ return array(
+ 'action=checktoken&type=csrf&token=123ABC'
+ => 'apihelp-checktoken-example-simple',
+ );
+ }
+}
diff --git a/includes/api/ApiClearHasMsg.php b/includes/api/ApiClearHasMsg.php
index 32e20e80..eb471ae6 100644
--- a/includes/api/ApiClearHasMsg.php
+++ b/includes/api/ApiClearHasMsg.php
@@ -42,13 +42,10 @@ class ApiClearHasMsg extends ApiBase {
return false;
}
- public function getDescription() {
- return array( 'Clears the hasmsg flag for current user.' );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=clearhasmsg' => 'Clears the hasmsg flag for current user',
+ 'action=clearhasmsg'
+ => 'apihelp-clearhasmsg-example-1',
);
}
diff --git a/includes/api/ApiComparePages.php b/includes/api/ApiComparePages.php
index 48559268..23009123 100644
--- a/includes/api/ApiComparePages.php
+++ b/includes/api/ApiComparePages.php
@@ -72,7 +72,7 @@ class ApiComparePages extends ApiBase {
);
}
- ApiResult::setContent( $vals, $difftext );
+ ApiResult::setContentValue( $vals, 'body', $difftext );
$this->getResult()->addValue( null, $this->getModuleName(), $vals );
}
@@ -126,27 +126,10 @@ class ApiComparePages extends ApiBase {
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'fromtitle' => 'First title to compare',
- 'fromid' => 'First page ID to compare',
- 'fromrev' => 'First revision to compare',
- 'totitle' => 'Second title to compare',
- 'toid' => 'Second page ID to compare',
- 'torev' => 'Second revision to compare',
- );
- }
-
- public function getDescription() {
- return array(
- 'Get the difference between 2 pages.',
- 'You must pass a revision number or a page title or a page ID id for each part (1 and 2).'
- );
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=compare&fromrev=1&torev=2' => 'Create a diff between revision 1 and 2',
+ 'action=compare&fromrev=1&torev=2'
+ => 'apihelp-compare-example-1',
);
}
}
diff --git a/includes/api/ApiContinuationManager.php b/includes/api/ApiContinuationManager.php
new file mode 100644
index 00000000..354f4e7d
--- /dev/null
+++ b/includes/api/ApiContinuationManager.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * This manages continuation state.
+ * @since 1.25 this is no longer a subclass of ApiBase
+ * @ingroup API
+ */
+class ApiContinuationManager {
+ private $source;
+
+ private $allModules = array();
+ private $generatedModules = array();
+
+ private $continuationData = array();
+ private $generatorContinuationData = array();
+
+ private $generatorParams = array();
+ private $generatorDone = false;
+
+ /**
+ * @param ApiBase $module Module starting the continuation
+ * @param ApiBase[] $allModules Contains ApiBase instances that will be executed
+ * @param array $generatedModules Names of modules that depend on the generator
+ */
+ public function __construct(
+ ApiBase $module, array $allModules = array(), array $generatedModules = array()
+ ) {
+ $this->source = get_class( $module );
+ $request = $module->getRequest();
+
+ $this->generatedModules = $generatedModules
+ ? array_combine( $generatedModules, $generatedModules )
+ : array();
+
+ $skip = array();
+ $continue = $request->getVal( 'continue', '' );
+ if ( $continue !== '' ) {
+ $continue = explode( '||', $continue );
+ if ( count( $continue ) !== 2 ) {
+ throw new UsageException(
+ 'Invalid continue param. You should pass the original value returned by the previous query',
+ 'badcontinue'
+ );
+ }
+ $this->generatorDone = ( $continue[0] === '-' );
+ $skip = explode( '|', $continue[1] );
+ if ( !$this->generatorDone ) {
+ $params = explode( '|', $continue[0] );
+ if ( $params ) {
+ $this->generatorParams = array_intersect_key(
+ $request->getValues(),
+ array_flip( $params )
+ );
+ }
+ } else {
+ // When the generator is complete, don't run any modules that
+ // depend on it.
+ $skip += $this->generatedModules;
+ }
+ }
+
+ foreach ( $allModules as $module ) {
+ $name = $module->getModuleName();
+ if ( in_array( $name, $skip, true ) ) {
+ $this->allModules[$name] = false;
+ // Prevent spurious "unused parameter" warnings
+ $module->extractRequestParams();
+ } else {
+ $this->allModules[$name] = $module;
+ }
+ }
+ }
+
+ /**
+ * Get the class that created this manager
+ * @return string
+ */
+ public function getSource() {
+ return $this->source;
+ }
+
+ /**
+ * Is the generator done?
+ * @return bool
+ */
+ public function isGeneratorDone() {
+ return $this->generatorDone;
+ }
+
+ /**
+ * Get the list of modules that should actually be run
+ * @return ApiBase[]
+ */
+ public function getRunModules() {
+ return array_values( array_filter( $this->allModules ) );
+ }
+
+ /**
+ * Set the continuation parameter for a module
+ * @param ApiBase $module
+ * @param string $paramName
+ * @param string|array $paramValue
+ * @throws UnexpectedValueException
+ */
+ public function addContinueParam( ApiBase $module, $paramName, $paramValue ) {
+ $name = $module->getModuleName();
+ if ( !isset( $this->allModules[$name] ) ) {
+ throw new UnexpectedValueException(
+ "Module '$name' called " . __METHOD__ .
+ ' but was not passed to ' . __CLASS__ . '::__construct'
+ );
+ }
+ if ( !$this->allModules[$name] ) {
+ throw new UnexpectedValueException(
+ "Module '$name' was not supposed to have been executed, but " .
+ 'it was executed anyway'
+ );
+ }
+ $paramName = $module->encodeParamName( $paramName );
+ if ( is_array( $paramValue ) ) {
+ $paramValue = join( '|', $paramValue );
+ }
+ $this->continuationData[$name][$paramName] = $paramValue;
+ }
+
+ /**
+ * Set the continuation parameter for the generator module
+ * @param ApiBase $module
+ * @param string $paramName
+ * @param string|array $paramValue
+ */
+ public function addGeneratorContinueParam( ApiBase $module, $paramName, $paramValue ) {
+ $name = $module->getModuleName();
+ $paramName = $module->encodeParamName( $paramName );
+ if ( is_array( $paramValue ) ) {
+ $paramValue = join( '|', $paramValue );
+ }
+ $this->generatorContinuationData[$name][$paramName] = $paramValue;
+ }
+
+ /**
+ * Fetch raw continuation data
+ * @return array
+ */
+ public function getRawContinuation() {
+ return array_merge_recursive( $this->continuationData, $this->generatorContinuationData );
+ }
+
+ /**
+ * Fetch continuation result data
+ * @return array Array( (array)$data, (bool)$batchcomplete )
+ */
+ public function getContinuation() {
+ $data = array();
+ $batchcomplete = false;
+
+ $finishedModules = array_diff(
+ array_keys( $this->allModules ),
+ array_keys( $this->continuationData )
+ );
+
+ // First, grab the non-generator-using continuation data
+ $continuationData = array_diff_key( $this->continuationData, $this->generatedModules );
+ foreach ( $continuationData as $module => $kvp ) {
+ $data += $kvp;
+ }
+
+ // Next, handle the generator-using continuation data
+ $continuationData = array_intersect_key( $this->continuationData, $this->generatedModules );
+ if ( $continuationData ) {
+ // Some modules are unfinished: include those params, and copy
+ // the generator params.
+ foreach ( $continuationData as $module => $kvp ) {
+ $data += $kvp;
+ }
+ $data += $this->generatorParams;
+ $generatorKeys = join( '|', array_keys( $this->generatorParams ) );
+ } elseif ( $this->generatorContinuationData ) {
+ // All the generator-using modules are complete, but the
+ // generator isn't. Continue the generator and restart the
+ // generator-using modules
+ $generatorParams = array();
+ foreach ( $this->generatorContinuationData as $kvp ) {
+ $generatorParams += $kvp;
+ }
+ $data += $generatorParams;
+ $finishedModules = array_diff( $finishedModules, $this->generatedModules );
+ $generatorKeys = join( '|', array_keys( $generatorParams ) );
+ $batchcomplete = true;
+ } else {
+ // Generator and prop modules are all done. Mark it so.
+ $generatorKeys = '-';
+ $batchcomplete = true;
+ }
+
+ // Set 'continue' if any continuation data is set or if the generator
+ // still needs to run
+ if ( $data || $generatorKeys !== '-' ) {
+ $data['continue'] = $generatorKeys . '||' . join( '|', $finishedModules );
+ }
+
+ return array( $data, $batchcomplete );
+ }
+
+ /**
+ * Store the continuation data into the result
+ * @param ApiResult $result
+ */
+ public function setContinuationIntoResult( ApiResult $result ) {
+ list( $data, $batchcomplete ) = $this->getContinuation();
+ if ( $data ) {
+ $result->addValue( null, 'continue', $data,
+ ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ }
+ if ( $batchcomplete ) {
+ $result->addValue( null, 'batchcomplete', true,
+ ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ }
+ }
+}
diff --git a/includes/api/ApiCreateAccount.php b/includes/api/ApiCreateAccount.php
index 2ce532b9..455540b4 100644
--- a/includes/api/ApiCreateAccount.php
+++ b/includes/api/ApiCreateAccount.php
@@ -29,9 +29,12 @@
*/
class ApiCreateAccount extends ApiBase {
public function execute() {
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
- $this->dieUsage( 'Cannot create account when using a callback', 'aborted' );
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
+ $this->dieUsage(
+ 'Cannot create account when the same-origin policy is not applied', 'aborted'
+ );
}
// $loginForm->addNewaccountInternal will throw exceptions
@@ -83,7 +86,7 @@ class ApiCreateAccount extends ApiBase {
$loginForm = new LoginForm();
$loginForm->setContext( $context );
- wfRunHooks( 'AddNewAccountApiForm', array( $this, $loginForm ) );
+ Hooks::run( 'AddNewAccountApiForm', array( $this, $loginForm ) );
$loginForm->load();
$status = $loginForm->addNewaccountInternal();
@@ -113,7 +116,7 @@ class ApiCreateAccount extends ApiBase {
// Save settings (including confirmation token)
$user->saveSettings();
- wfRunHooks( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
+ Hooks::run( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
if ( $params['mailpassword'] ) {
$logAction = 'byemail';
@@ -149,9 +152,9 @@ class ApiCreateAccount extends ApiBase {
$warnings = $status->getErrorsByType( 'warning' );
if ( $warnings ) {
foreach ( $warnings as &$warning ) {
- $apiResult->setIndexedTagName( $warning['params'], 'param' );
+ ApiResult::setIndexedTagName( $warning['params'], 'param' );
}
- $apiResult->setIndexedTagName( $warnings, 'warning' );
+ ApiResult::setIndexedTagName( $warnings, 'warning' );
$result['warnings'] = $warnings;
}
} else {
@@ -160,15 +163,11 @@ class ApiCreateAccount extends ApiBase {
}
// Give extensions a chance to modify the API result data
- wfRunHooks( 'AddNewAccountApiResult', array( $this, $loginForm, &$result ) );
+ Hooks::run( 'AddNewAccountApiResult', array( $this, $loginForm, &$result ) );
$apiResult->addValue( null, 'createaccount', $result );
}
- public function getDescription() {
- return 'Create a new user account.';
- }
-
public function mustBePosted() {
return true;
}
@@ -204,27 +203,12 @@ class ApiCreateAccount extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'name' => 'Username',
- 'password' => "Password (ignored if {$p}mailpassword is set)",
- 'domain' => 'Domain for external authentication (optional)',
- 'token' => 'Account creation token obtained in first request',
- 'email' => 'Email address of user (optional)',
- 'realname' => 'Real name of user (optional)',
- 'mailpassword' => 'If set to any value, a random password will be emailed to the user',
- 'reason' => 'Optional reason for creating the account to be put in the logs',
- 'language'
- => 'Language code to set as default for the user (optional, defaults to content language)'
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=createaccount&name=testuser&password=test123',
- 'api.php?action=createaccount&name=testmailuser&mailpassword=true&reason=MyReason',
+ 'action=createaccount&name=testuser&password=test123'
+ => 'apihelp-createaccount-example-pass',
+ 'action=createaccount&name=testmailuser&mailpassword=true&reason=MyReason'
+ => 'apihelp-createaccount-example-mail',
);
}
diff --git a/includes/api/ApiDelete.php b/includes/api/ApiDelete.php
index abca8245..d8b57182 100644
--- a/includes/api/ApiDelete.php
+++ b/includes/api/ApiDelete.php
@@ -210,35 +210,16 @@ class ApiDelete extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'title' => "Title of the page you want to delete. Cannot be used together with {$p}pageid",
- 'pageid' => "Page ID of the page you want to delete. Cannot be used together with {$p}title",
- 'reason'
- => 'Reason for the deletion. If not set, an automatically generated reason will be used',
- 'watch' => 'Add the page to your watchlist',
- 'watchlist' => 'Unconditionally add or remove the page from your ' .
- 'watchlist, use preferences or do not change watch',
- 'unwatch' => 'Remove the page from your watchlist',
- 'oldimage' => 'The name of the old image to delete as provided by iiprop=archivename'
- );
- }
-
- public function getDescription() {
- return 'Delete a page.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=delete&title=Main%20Page&token=123ABC' => 'Delete the Main Page',
- 'api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
- => 'Delete the Main Page with the reason "Preparing for move"',
+ 'action=delete&title=Main%20Page&token=123ABC'
+ => 'apihelp-delete-example-simple',
+ 'action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
+ => 'apihelp-delete-example-reason',
);
}
diff --git a/includes/api/ApiDisabled.php b/includes/api/ApiDisabled.php
index 6ea5d202..fc975220 100644
--- a/includes/api/ApiDisabled.php
+++ b/includes/api/ApiDisabled.php
@@ -44,19 +44,7 @@ class ApiDisabled extends ApiBase {
return false;
}
- public function getAllowedParams() {
- return array();
- }
-
- public function getParamDescription() {
- return array();
- }
-
- public function getDescription() {
- return 'This module has been disabled.';
- }
-
- public function getExamples() {
- return array();
+ protected function getDescriptionMessage() {
+ return 'apihelp-disabled-description';
}
}
diff --git a/includes/api/ApiEditPage.php b/includes/api/ApiEditPage.php
index a423b560..54a83915 100644
--- a/includes/api/ApiEditPage.php
+++ b/includes/api/ApiEditPage.php
@@ -28,7 +28,9 @@
* A module that allows for editing and creating pages.
*
* Currently, this wraps around the EditPage class in an ugly way,
- * EditPage.php should be rewritten to provide a cleaner interface
+ * EditPage.php should be rewritten to provide a cleaner interface,
+ * see T20654 if you're inspired to fix this.
+ *
* @ingroup API
*/
class ApiEditPage extends ApiBase {
@@ -48,8 +50,12 @@ class ApiEditPage extends ApiBase {
$apiResult = $this->getResult();
if ( $params['redirect'] ) {
- if ( $params['prependtext'] === null && $params['appendtext'] === null && $params['section'] !== 'new' ) {
- $this->dieUsage( 'You have attempted to edit using the "redirect"-following mode, which must be used in conjuction with section=new, prependtext, or appendtext.', 'redirect-appendonly' );
+ if ( $params['prependtext'] === null && $params['appendtext'] === null
+ && $params['section'] !== 'new'
+ ) {
+ $this->dieUsage( 'You have attempted to edit using the "redirect"-following'
+ . ' mode, which must be used in conjuction with section=new, prependtext'
+ . ', or appendtext.', 'redirect-appendonly' );
}
if ( $titleObj->isRedirect() ) {
$oldTitle = $titleObj;
@@ -76,7 +82,7 @@ class ApiEditPage extends ApiBase {
$titleObj = $newTitle;
}
- $apiResult->setIndexedTagName( $redirValues, 'r' );
+ ApiResult::setIndexedTagName( $redirValues, 'r' );
$apiResult->addValue( null, 'redirects', $redirValues );
// Since the page changed, update $pageObj
@@ -195,9 +201,9 @@ class ApiEditPage extends ApiBase {
list( $params['undo'], $params['undoafter'] ) =
array( $params['undoafter'], $params['undo'] );
}
- $undoafterRev = Revision::newFromID( $params['undoafter'] );
+ $undoafterRev = Revision::newFromId( $params['undoafter'] );
}
- $undoRev = Revision::newFromID( $params['undo'] );
+ $undoRev = Revision::newFromId( $params['undo'] );
if ( is_null( $undoRev ) || $undoRev->isDeleted( Revision::DELETED_TEXT ) ) {
$this->dieUsageMsg( array( 'nosuchrevid', $params['undo'] ) );
}
@@ -252,8 +258,10 @@ class ApiEditPage extends ApiBase {
'format' => $contentFormat,
'model' => $contentHandler->getModelID(),
'wpEditToken' => $params['token'],
- 'wpIgnoreBlankSummary' => '',
- 'wpIgnoreBlankArticle' => true
+ 'wpIgnoreBlankSummary' => true,
+ 'wpIgnoreBlankArticle' => true,
+ 'wpIgnoreSelfRedirect' => true,
+ 'bot' => $params['bot'],
);
if ( !is_null( $params['summary'] ) ) {
@@ -294,10 +302,13 @@ class ApiEditPage extends ApiBase {
if ( !is_null( $params['section'] ) ) {
$section = $params['section'];
if ( !preg_match( '/^((T-)?\d+|new)$/', $section ) ) {
- $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
+ $this->dieUsage( "The section parameter must be a valid section id or 'new'",
+ "invalidsection" );
}
$content = $pageObj->getContent();
- if ( $section !== '0' && $section != 'new' && ( !$content || !$content->getSection( $section ) ) ) {
+ if ( $section !== '0' && $section != 'new'
+ && ( !$content || !$content->getSection( $section ) )
+ ) {
$this->dieUsage( "There is no section {$section}.", 'nosuchsection' );
}
$requestArray['wpSection'] = $params['section'];
@@ -320,6 +331,15 @@ class ApiEditPage extends ApiBase {
$requestArray['wpWatchthis'] = '';
}
+ // Apply change tags
+ if ( count( $params['tags'] ) ) {
+ if ( $user->isAllowed( 'applychangetags' ) ) {
+ $requestArray['wpChangeTags'] = implode( ',', $params['tags'] );
+ } else {
+ $this->dieUsage( 'You don\'t have permission to set change tags.', 'taggingnotallowed' );
+ }
+ }
+
// Pass through anything else we might have been given, to support extensions
// This is kind of a hack but it's the best we can do to make extensions work
$requestArray += $this->getRequest()->getValues();
@@ -381,7 +401,7 @@ class ApiEditPage extends ApiBase {
// Run hooks
// Handle APIEditBeforeSave parameters
$r = array();
- if ( !wfRunHooks( 'APIEditBeforeSave', array( $ep, $content, &$r ) ) ) {
+ if ( !Hooks::run( 'APIEditBeforeSave', array( $ep, $content, &$r ) ) ) {
if ( count( $r ) ) {
$r['result'] = 'Failure';
$apiResult->addValue( null, $this->getModuleName(), $r );
@@ -400,13 +420,20 @@ class ApiEditPage extends ApiBase {
$oldRequest = $wgRequest;
$wgRequest = $req;
- $status = $ep->internalAttemptSave( $result, $user->isAllowed( 'bot' ) && $params['bot'] );
+ $status = $ep->attemptSave( $result );
$wgRequest = $oldRequest;
switch ( $status->value ) {
case EditPage::AS_HOOK_ERROR:
case EditPage::AS_HOOK_ERROR_EXPECTED:
- $this->dieUsageMsg( 'hookaborted' );
+ if ( isset( $status->apiHookResult ) ) {
+ $r = $status->apiHookResult;
+ $r['result'] = 'Failure';
+ $apiResult->addValue( null, $this->getModuleName(), $r );
+ return;
+ } else {
+ $this->dieUsageMsg( 'hookaborted' );
+ }
case EditPage::AS_PARSE_ERROR:
$this->dieUsage( $status->getMessage(), 'parseerror' );
@@ -454,12 +481,14 @@ class ApiEditPage extends ApiBase {
case EditPage::AS_CONFLICT_DETECTED:
$this->dieUsageMsg( 'editconflict' );
- // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
case EditPage::AS_TEXTBOX_EMPTY:
$this->dieUsageMsg( 'emptynewsection' );
+ case EditPage::AS_CHANGE_TAG_ERROR:
+ $this->dieStatus( $status );
+
case EditPage::AS_SUCCESS_NEW_ARTICLE:
- $r['new'] = '';
+ $r['new'] = true;
// fall-through
case EditPage::AS_SUCCESS_UPDATE:
@@ -469,7 +498,7 @@ class ApiEditPage extends ApiBase {
$r['contentmodel'] = $titleObj->getContentModel();
$newRevId = $articleObject->getLatest();
if ( $newRevId == $oldRevId ) {
- $r['nochange'] = '';
+ $r['nochange'] = true;
} else {
$r['oldrevid'] = intval( $oldRevId );
$r['newrevid'] = intval( $newRevId );
@@ -479,6 +508,7 @@ class ApiEditPage extends ApiBase {
break;
case EditPage::AS_SUMMARY_NEEDED:
+ // Shouldn't happen since we set wpIgnoreBlankSummary, but just in case
$this->dieUsageMsg( 'summaryrequired' );
case EditPage::AS_END:
@@ -499,10 +529,6 @@ class ApiEditPage extends ApiBase {
return true;
}
- public function getDescription() {
- return 'Create and edit pages.';
- }
-
public function getAllowedParams() {
return array(
'title' => array(
@@ -517,6 +543,10 @@ class ApiEditPage extends ApiBase {
),
'text' => null,
'summary' => null,
+ 'tags' => array(
+ ApiBase::PARAM_TYPE => ChangeTags::listExplicitlyDefinedTags(),
+ ApiBase::PARAM_ISMULTI => true,
+ ),
'minor' => false,
'notminor' => false,
'bot' => false,
@@ -560,58 +590,11 @@ class ApiEditPage extends ApiBase {
),
'contentmodel' => array(
ApiBase::PARAM_TYPE => ContentHandler::getContentModels(),
- )
- );
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'title' => "Title of the page you want to edit. Cannot be used together with {$p}pageid",
- 'pageid' => "Page ID of the page you want to edit. Cannot be used together with {$p}title",
- 'section' => 'Section number. 0 for the top section, \'new\' for a new section',
- 'sectiontitle' => 'The title for a new section',
- 'text' => 'Page content',
- 'token' => array(
- /* Standard description is automatically prepended */
- 'The token should always be sent as the last parameter, or at ' .
- "least, after the {$p}text parameter"
- ),
- 'summary'
- => "Edit summary. Also section title when {$p}section=new and {$p}sectiontitle is not set",
- 'minor' => 'Minor edit',
- 'notminor' => 'Non-minor edit',
- 'bot' => 'Mark this edit as bot',
- 'basetimestamp' => array(
- 'Timestamp of the base revision (obtained through prop=revisions&rvprop=timestamp).',
- 'Used to detect edit conflicts; leave unset to ignore conflicts'
),
- 'starttimestamp' => array(
- 'Timestamp when you began the editing process, e.g. when the current page content ' .
- 'was loaded for editing.',
- 'Used to detect edit conflicts; leave unset to ignore conflicts'
- ),
- 'recreate' => 'Override any errors about the article having been deleted in the meantime',
- 'createonly' => 'Don\'t edit the page if it exists already',
- 'nocreate' => 'Throw an error if the page doesn\'t exist',
- 'watch' => 'Add the page to your watchlist',
- 'unwatch' => 'Remove the page from your watchlist',
- 'watchlist' => 'Unconditionally add or remove the page from your ' .
- 'watchlist, use preferences or do not change watch',
- 'md5' => array(
- "The MD5 hash of the {$p}text parameter, or the {$p}prependtext " .
- "and {$p}appendtext parameters concatenated.",
- 'If set, the edit won\'t be done unless the hash is correct'
+ 'token' => array(
+ // Standard definition automatically inserted
+ ApiBase::PARAM_HELP_MSG_APPEND => array( 'apihelp-edit-param-token' ),
),
- 'prependtext' => "Add this text to the beginning of the page. Overrides {$p}text",
- 'appendtext' => array( "Add this text to the end of the page. Overrides {$p}text.",
- "Use {$p}section=new to append a new section" ),
- 'undo' => "Undo this revision. Overrides {$p}text, {$p}prependtext and {$p}appendtext",
- 'undoafter' => 'Undo all revisions from undo to this one. If not set, just undo one revision',
- 'redirect' => 'Automatically resolve redirects',
- 'contentformat' => 'Content serialization format used for the input text',
- 'contentmodel' => 'Content model of the new content',
);
}
@@ -619,17 +602,17 @@ class ApiEditPage extends ApiBase {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=edit&title=Test&summary=test%20summary&' .
- 'text=article%20content&basetimestamp=20070824123454&token=%2B\\'
- => 'Edit a page (anonymous user)',
- 'api.php?action=edit&title=Test&summary=NOTOC&minor=&' .
- 'prependtext=__NOTOC__%0A&basetimestamp=20070824123454&token=%2B\\'
- => 'Prepend __NOTOC__ to a page (anonymous user)',
- 'api.php?action=edit&title=Test&undo=13585&undoafter=13579&' .
- 'basetimestamp=20070824123454&token=%2B\\'
- => 'Undo r13579 through r13585 with autosummary (anonymous user)',
+ 'action=edit&title=Test&summary=test%20summary&' .
+ 'text=article%20content&basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
+ => 'apihelp-edit-example-edit',
+ 'action=edit&title=Test&summary=NOTOC&minor=&' .
+ 'prependtext=__NOTOC__%0A&basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
+ => 'apihelp-edit-example-prepend',
+ 'action=edit&title=Test&undo=13585&undoafter=13579&' .
+ 'basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
+ => 'apihelp-edit-example-undo',
);
}
diff --git a/includes/api/ApiEmailUser.php b/includes/api/ApiEmailUser.php
index 9870b2de..15eb475e 100644
--- a/includes/api/ApiEmailUser.php
+++ b/includes/api/ApiEmailUser.php
@@ -102,27 +102,14 @@ class ApiEmailUser extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'target' => 'User to send email to',
- 'subject' => 'Subject header',
- 'text' => 'Mail body',
- 'ccme' => 'Send a copy of this mail to me',
- );
- }
-
- public function getDescription() {
- return 'Email a user.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=emailuser&target=WikiSysop&text=Content&token=123ABC'
- => 'Send an email to the User "WikiSysop" with the text "Content"',
+ 'action=emailuser&target=WikiSysop&text=Content&token=123ABC'
+ => 'apihelp-emailuser-example-email',
);
}
diff --git a/includes/api/ApiErrorFormatter.php b/includes/api/ApiErrorFormatter.php
new file mode 100644
index 00000000..94143291
--- /dev/null
+++ b/includes/api/ApiErrorFormatter.php
@@ -0,0 +1,303 @@
+<?php
+/**
+ * This file contains the ApiErrorFormatter definition, plus implementations of
+ * specific formatters.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Formats errors and warnings for the API, and add them to the associated
+ * ApiResult.
+ * @since 1.25
+ * @ingroup API
+ */
+class ApiErrorFormatter {
+ /** @var Title Dummy title to silence warnings from MessageCache::parse() */
+ private static $dummyTitle = null;
+
+ /** @var ApiResult */
+ protected $result;
+
+ /** @var Language */
+ protected $lang;
+ protected $useDB = false;
+ protected $format = 'none';
+
+ /**
+ * @param ApiResult $result Into which data will be added
+ * @param Language $lang Used for i18n
+ * @param string $format
+ * - text: Error message as wikitext
+ * - html: Error message as HTML
+ * - raw: Raw message key and parameters, no human-readable text
+ * - none: Code and data only, no human-readable text
+ * @param bool $useDB Whether to use local translations for errors and warnings.
+ */
+ public function __construct( ApiResult $result, Language $lang, $format, $useDB = false ) {
+ $this->result = $result;
+ $this->lang = $lang;
+ $this->useDB = $useDB;
+ $this->format = $format;
+ }
+
+ /**
+ * Fetch a dummy title to set on Messages
+ * @return Title
+ */
+ protected function getDummyTitle() {
+ if ( self::$dummyTitle === null ) {
+ self::$dummyTitle = Title::makeTitle( NS_SPECIAL, 'Badtitle/' . __METHOD__ );
+ }
+ return self::$dummyTitle;
+ }
+
+ /**
+ * Add a warning to the result
+ * @param string $moduleName
+ * @param MessageSpecifier|array|string $msg i18n message for the warning
+ * @param string $code Machine-readable code for the warning. Defaults as
+ * for IApiMessage::getApiCode().
+ * @param array $data Machine-readable data for the warning, if any.
+ * Uses IApiMessage::getApiData() if $msg implements that interface.
+ */
+ public function addWarning( $moduleName, $msg, $code = null, $data = null ) {
+ $msg = ApiMessage::create( $msg, $code, $data )
+ ->inLanguage( $this->lang )
+ ->title( $this->getDummyTitle() )
+ ->useDatabase( $this->useDB );
+ $this->addWarningOrError( 'warning', $moduleName, $msg );
+ }
+
+ /**
+ * Add an error to the result
+ * @param string $moduleName
+ * @param MessageSpecifier|array|string $msg i18n message for the error
+ * @param string $code Machine-readable code for the warning. Defaults as
+ * for IApiMessage::getApiCode().
+ * @param array $data Machine-readable data for the warning, if any.
+ * Uses IApiMessage::getApiData() if $msg implements that interface.
+ */
+ public function addError( $moduleName, $msg, $code = null, $data = null ) {
+ $msg = ApiMessage::create( $msg, $code, $data )
+ ->inLanguage( $this->lang )
+ ->title( $this->getDummyTitle() )
+ ->useDatabase( $this->useDB );
+ $this->addWarningOrError( 'error', $moduleName, $msg );
+ }
+
+ /**
+ * Add warnings and errors from a Status object to the result
+ * @param string $moduleName
+ * @param Status $status
+ * @param string[] $types 'warning' and/or 'error'
+ */
+ public function addMessagesFromStatus(
+ $moduleName, Status $status, $types = array( 'warning', 'error' )
+ ) {
+ if ( $status->isGood() || !$status->errors ) {
+ return;
+ }
+
+ $types = (array)$types;
+ foreach ( $status->errors as $error ) {
+ if ( !in_array( $error['type'], $types, true ) ) {
+ continue;
+ }
+
+ if ( $error['type'] === 'error' ) {
+ $tag = 'error';
+ } else {
+ // Assume any unknown type is a warning
+ $tag = 'warning';
+ }
+
+ if ( is_array( $error ) && isset( $error['message'] ) ) {
+ // Normal case
+ if ( $error['message'] instanceof Message ) {
+ $msg = ApiMessage::create( $error['message'], null, array() );
+ } else {
+ $args = isset( $error['params'] ) ? $error['params'] : array();
+ array_unshift( $args, $error['message'] );
+ $error += array( 'params' => array() );
+ $msg = ApiMessage::create( $args, null, array() );
+ }
+ } elseif ( is_array( $error ) ) {
+ // Weird case handled by Message::getErrorMessage
+ $msg = ApiMessage::create( $error, null, array() );
+ } else {
+ // Another weird case handled by Message::getErrorMessage
+ $msg = ApiMessage::create( $error, null, array() );
+ }
+
+ $msg->inLanguage( $this->lang )
+ ->title( $this->getDummyTitle() )
+ ->useDatabase( $this->useDB );
+ $this->addWarningOrError( $tag, $moduleName, $msg );
+ }
+ }
+
+ /**
+ * Format messages from a Status as an array
+ * @param Status $status
+ * @param string $type 'warning' or 'error'
+ * @param string|null $format
+ * @return array
+ */
+ public function arrayFromStatus( Status $status, $type = 'error', $format = null ) {
+ if ( $status->isGood() || !$status->errors ) {
+ return array();
+ }
+
+ $result = new ApiResult( 1e6 );
+ $formatter = new ApiErrorFormatter(
+ $result, $this->lang, $format ?: $this->format, $this->useDB
+ );
+ $formatter->addMessagesFromStatus( 'dummy', $status, array( $type ) );
+ switch ( $type ) {
+ case 'error':
+ return (array)$result->getResultData( array( 'errors', 'dummy' ) );
+ case 'warning':
+ return (array)$result->getResultData( array( 'warnings', 'dummy' ) );
+ }
+ }
+
+ /**
+ * Actually add the warning or error to the result
+ * @param string $tag 'warning' or 'error'
+ * @param string $moduleName
+ * @param ApiMessage|ApiRawMessage $msg
+ */
+ protected function addWarningOrError( $tag, $moduleName, $msg ) {
+ $value = array( 'code' => $msg->getApiCode() );
+ switch ( $this->format ) {
+ case 'wikitext':
+ $value += array(
+ 'text' => $msg->text(),
+ ApiResult::META_CONTENT => 'text',
+ );
+ break;
+
+ case 'html':
+ $value += array(
+ 'html' => $msg->parse(),
+ ApiResult::META_CONTENT => 'html',
+ );
+ break;
+
+ case 'raw':
+ $value += array(
+ 'message' => $msg->getKey(),
+ 'params' => $msg->getParams(),
+ );
+ ApiResult::setIndexedTagName( $value['params'], 'param' );
+ break;
+
+ case 'none':
+ break;
+ }
+ $value += $msg->getApiData();
+
+ $path = array( $tag . 's', $moduleName );
+ $existing = $this->result->getResultData( $path );
+ if ( $existing === null || !in_array( $value, $existing ) ) {
+ $flags = ApiResult::NO_SIZE_CHECK;
+ if ( $existing === null ) {
+ $flags |= ApiResult::ADD_ON_TOP;
+ }
+ $this->result->addValue( $path, null, $value, $flags );
+ $this->result->addIndexedTagName( $path, $tag );
+ }
+ }
+}
+
+/**
+ * Format errors and warnings in the old style, for backwards compatibility.
+ * @since 1.25
+ * @deprecated Only for backwards compatibility, do not use
+ * @ingroup API
+ */
+class ApiErrorFormatter_BackCompat extends ApiErrorFormatter {
+ /**
+ * @param ApiResult $result Into which data will be added
+ */
+ public function __construct( ApiResult $result ) {
+ parent::__construct( $result, Language::factory( 'en' ), 'none', false );
+ }
+
+ public function arrayFromStatus( Status $status, $type = 'error', $format = null ) {
+ if ( $status->isGood() || !$status->errors ) {
+ return array();
+ }
+
+ $result = array();
+ foreach ( $status->getErrorsByType( $type ) as $error ) {
+ if ( $error['message'] instanceof Message ) {
+ $error = array(
+ 'message' => $error['message']->getKey(),
+ 'params' => $error['message']->getParams(),
+ ) + $error;
+ }
+ ApiResult::setIndexedTagName( $error['params'], 'param' );
+ $result[] = $error;
+ }
+ ApiResult::setIndexedTagName( $result, $type );
+
+ return $result;
+ }
+
+ protected function addWarningOrError( $tag, $moduleName, $msg ) {
+ $value = $msg->plain();
+
+ if ( $tag === 'error' ) {
+ // In BC mode, only one error
+ $code = $msg->getApiCode();
+ if ( isset( ApiBase::$messageMap[$code] ) ) {
+ // Backwards compatibility
+ $code = ApiBase::$messageMap[$code]['code'];
+ }
+
+ $value = array(
+ 'code' => $code,
+ 'info' => $value,
+ ) + $msg->getApiData();
+ $this->result->addValue( null, 'error', $value,
+ ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ } else {
+ // Don't add duplicate warnings
+ $tag .= 's';
+ $path = array( $tag, $moduleName );
+ $oldWarning = $this->result->getResultData( array( $tag, $moduleName, $tag ) );
+ if ( $oldWarning !== null ) {
+ $warnPos = strpos( $oldWarning, $value );
+ // If $value was found in $oldWarning, check if it starts at 0 or after "\n"
+ if ( $warnPos !== false && ( $warnPos === 0 || $oldWarning[$warnPos - 1] === "\n" ) ) {
+ // Check if $value is followed by "\n" or the end of the $oldWarning
+ $warnPos += strlen( $value );
+ if ( strlen( $oldWarning ) <= $warnPos || $oldWarning[$warnPos] === "\n" ) {
+ return;
+ }
+ }
+ // If there is a warning already, append it to the existing one
+ $value = "$oldWarning\n$value";
+ }
+ $this->result->addContentValue( $path, $tag, $value,
+ ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ }
+ }
+}
diff --git a/includes/api/ApiExpandTemplates.php b/includes/api/ApiExpandTemplates.php
index 8a3b534d..6d064eb2 100644
--- a/includes/api/ApiExpandTemplates.php
+++ b/includes/api/ApiExpandTemplates.php
@@ -52,10 +52,19 @@ class ApiExpandTemplates extends ApiBase {
$prop = array_flip( $params['prop'] );
}
- // Create title for parser
- $title_obj = Title::newFromText( $params['title'] );
- if ( !$title_obj || $title_obj->isExternal() ) {
- $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ // Get title and revision ID for parser
+ $revid = $params['revid'];
+ if ( $revid !== null ) {
+ $rev = Revision::newFromId( $revid );
+ if ( !$rev ) {
+ $this->dieUsage( "There is no revision ID $revid", 'missingrev' );
+ }
+ $title_obj = $rev->getTitle();
+ } else {
+ $title_obj = Title::newFromText( $params['title'] );
+ if ( !$title_obj || $title_obj->isExternal() ) {
+ $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
+ }
}
$result = $this->getResult();
@@ -75,7 +84,7 @@ class ApiExpandTemplates extends ApiBase {
$this->logFeatureUsage( 'action=expandtemplates&generatexml' );
}
- $wgParser->startExternalParse( $title_obj, $options, OT_PREPROCESS );
+ $wgParser->startExternalParse( $title_obj, $options, Parser::OT_PREPROCESS );
$dom = $wgParser->preprocessToDom( $params['text'] );
if ( is_callable( array( $dom, 'saveXML' ) ) ) {
$xml = $dom->saveXML();
@@ -87,38 +96,45 @@ class ApiExpandTemplates extends ApiBase {
$retval['parsetree'] = $xml;
} else {
// the old way
- $xml_result = array();
- ApiResult::setContent( $xml_result, $xml );
- $result->addValue( null, 'parsetree', $xml_result );
+ $result->addValue( null, 'parsetree', $xml );
+ $result->addValue( null, ApiResult::META_BC_SUBELEMENTS, array( 'parsetree' ) );
}
}
// if they didn't want any output except (probably) the parse tree,
// then don't bother actually fully expanding it
if ( $prop || $params['prop'] === null ) {
- $wgParser->startExternalParse( $title_obj, $options, OT_PREPROCESS );
+ $wgParser->startExternalParse( $title_obj, $options, Parser::OT_PREPROCESS );
$frame = $wgParser->getPreprocessor()->newFrame();
- $wikitext = $wgParser->preprocess( $params['text'], $title_obj, $options, null, $frame );
+ $wikitext = $wgParser->preprocess( $params['text'], $title_obj, $options, $revid, $frame );
if ( $params['prop'] === null ) {
// the old way
- ApiResult::setContent( $retval, $wikitext );
+ ApiResult::setContentValue( $retval, 'wikitext', $wikitext );
} else {
if ( isset( $prop['categories'] ) ) {
$categories = $wgParser->getOutput()->getCategories();
- if ( !empty( $categories ) ) {
+ if ( $categories ) {
$categories_result = array();
foreach ( $categories as $category => $sortkey ) {
$entry = array();
$entry['sortkey'] = $sortkey;
- ApiResult::setContent( $entry, $category );
+ ApiResult::setContentValue( $entry, 'category', $category );
$categories_result[] = $entry;
}
- $result->setIndexedTagName( $categories_result, 'category' );
+ ApiResult::setIndexedTagName( $categories_result, 'category' );
$retval['categories'] = $categories_result;
}
}
- if ( isset( $prop['volatile'] ) && $frame->isVolatile() ) {
- $retval['volatile'] = '';
+ if ( isset( $prop['properties'] ) ) {
+ $properties = $wgParser->getOutput()->getProperties();
+ if ( $properties ) {
+ ApiResult::setArrayType( $properties, 'BCkvp', 'name' );
+ ApiResult::setIndexedTagName( $properties, 'property' );
+ $retval['properties'] = $properties;
+ }
+ }
+ if ( isset( $prop['volatile'] ) ) {
+ $retval['volatile'] = $frame->isVolatile();
}
if ( isset( $prop['ttl'] ) && $frame->getTTL() !== null ) {
$retval['ttl'] = $frame->getTTL();
@@ -128,7 +144,7 @@ class ApiExpandTemplates extends ApiBase {
}
}
}
- $result->setSubelements( $retval, array( 'wikitext', 'parsetree' ) );
+ ApiResult::setSubelementsList( $retval, array( 'wikitext', 'parsetree' ) );
$result->addValue( null, $this->getModuleName(), $retval );
}
@@ -141,10 +157,14 @@ class ApiExpandTemplates extends ApiBase {
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_REQUIRED => true,
),
+ 'revid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
'prop' => array(
ApiBase::PARAM_TYPE => array(
'wikitext',
'categories',
+ 'properties',
'volatile',
'ttl',
'parsetree',
@@ -159,35 +179,10 @@ class ApiExpandTemplates extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'text' => 'Wikitext to convert',
- 'title' => 'Title of page',
- 'prop' => array(
- 'Which pieces of information to get',
- ' wikitext - The expanded wikitext',
- ' categories - Any categories present in the input that are not represented in ' .
- 'the wikitext output',
- ' volatile - Whether the output is volatile and should not be reused ' .
- 'elsewhere within the page',
- ' ttl - The maximum time after which caches of the result should be ' .
- 'invalidated',
- ' parsetree - The XML parse tree of the input',
- 'Note that if no values are selected, the result will contain the wikitext,',
- 'but the output will be in a deprecated format.',
- ),
- 'includecomments' => 'Whether to include HTML comments in the output',
- 'generatexml' => 'Generate XML parse tree (replaced by prop=parsetree)',
- );
- }
-
- public function getDescription() {
- return 'Expands all templates in wikitext.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=expandtemplates&text={{Project:Sandbox}}'
+ 'action=expandtemplates&text={{Project:Sandbox}}'
+ => 'apihelp-expandtemplates-example-simple',
);
}
diff --git a/includes/api/ApiFeedContributions.php b/includes/api/ApiFeedContributions.php
index 374203eb..edda6723 100644
--- a/includes/api/ApiFeedContributions.php
+++ b/includes/api/ApiFeedContributions.php
@@ -95,7 +95,10 @@ class ApiFeedContributions extends ApiBase {
if ( ++$count > $limit ) {
break;
}
- $feedItems[] = $this->feedItem( $row );
+ $item = $this->feedItem( $row );
+ if ( $item !== null ) {
+ $feedItems[] = $item;
+ }
}
}
@@ -103,6 +106,23 @@ class ApiFeedContributions extends ApiBase {
}
protected function feedItem( $row ) {
+ // This hook is the api contributions equivalent to the
+ // ContributionsLineEnding hook. Hook implementers may cancel
+ // the hook to signal the user is not allowed to read this item.
+ $feedItem = null;
+ $hookResult = Hooks::run(
+ 'ApiFeedContributions::feedItem',
+ array( $row, $this->getContext(), &$feedItem )
+ );
+ // Hook returned a valid feed item
+ if ( $feedItem instanceof FeedItem ) {
+ return $feedItem;
+ // Hook was canceled and did not return a valid feed item
+ } elseif ( !$hookResult ) {
+ return null;
+ }
+
+ // Hook completed and did not return a valid feed item
$title = Title::makeTitle( intval( $row->page_namespace ), $row->page_title );
if ( $title && $title->userCan( 'read', $this->getUser() ) ) {
$date = $row->rev_timestamp;
@@ -161,7 +181,7 @@ class ApiFeedContributions extends ApiBase {
public function getAllowedParams() {
$feedFormatNames = array_keys( $this->getConfig()->get( 'FeedClasses' ) );
- return array(
+ $ret = array(
'feedformat' => array(
ApiBase::PARAM_DFLT => 'rss',
ApiBase::PARAM_TYPE => $feedFormatNames
@@ -187,32 +207,22 @@ class ApiFeedContributions extends ApiBase {
'deletedonly' => false,
'toponly' => false,
'newonly' => false,
- 'showsizediff' => false,
+ 'showsizediff' => array(
+ ApiBase::PARAM_DFLT => false,
+ ),
);
- }
- public function getParamDescription() {
- return array(
- 'feedformat' => 'The format of the feed',
- 'user' => 'What users to get the contributions for',
- 'namespace' => 'What namespace to filter the contributions by',
- 'year' => 'From year (and earlier)',
- 'month' => 'From month (and earlier)',
- 'tagfilter' => 'Filter contributions that have these tags',
- 'deletedonly' => 'Show only deleted contributions',
- 'toponly' => 'Only show edits that are latest revisions',
- 'newonly' => 'Only show edits that are page creations',
- 'showsizediff' => 'Show the size difference between revisions. Disabled in Miser Mode',
- );
- }
+ if ( $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['showsizediff'][ApiBase::PARAM_HELP_MSG] = 'api-help-param-disabled-in-miser-mode';
+ }
- public function getDescription() {
- return 'Returns a user contributions feed.';
+ return $ret;
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=feedcontributions&user=Reedy',
+ 'action=feedcontributions&user=Example'
+ => 'apihelp-feedcontributions-example-simple',
);
}
}
diff --git a/includes/api/ApiFeedRecentChanges.php b/includes/api/ApiFeedRecentChanges.php
index 7239a296..d452bbd6 100644
--- a/includes/api/ApiFeedRecentChanges.php
+++ b/includes/api/ApiFeedRecentChanges.php
@@ -171,37 +171,12 @@ class ApiFeedRecentChanges extends ApiBase {
return $ret;
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'feedformat' => 'The format of the feed',
- 'namespace' => 'Namespace to limit the results to',
- 'invert' => 'All namespaces but the selected one',
- 'associated' => 'Include associated (talk or main) namespace',
- 'days' => 'Days to limit the results to',
- 'limit' => 'Maximum number of results to return',
- 'from' => 'Show changes since then',
- 'hideminor' => 'Hide minor changes',
- 'hidebots' => 'Hide changes made by bots',
- 'hideanons' => 'Hide changes made by anonymous users',
- 'hideliu' => 'Hide changes made by registered users',
- 'hidepatrolled' => 'Hide patrolled changes',
- 'hidemyself' => 'Hide changes made by yourself',
- 'tagfilter' => 'Filter by tag',
- 'target' => 'Show only changes on pages linked from this page',
- 'showlinkedto' => 'Show changes on pages linked to the selected page instead',
- 'categories' => 'Show only changes on pages in all of these categories',
- 'categories_any' => 'Show only changes on pages in any of the categories instead',
- );
- }
-
- public function getDescription() {
- return 'Returns a recent changes feed';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=feedrecentchanges',
- 'api.php?action=feedrecentchanges&days=30'
+ 'action=feedrecentchanges'
+ => 'apihelp-feedrecentchanges-example-simple',
+ 'action=feedrecentchanges&days=30'
+ => 'apihelp-feedrecentchanges-example-30days',
);
}
}
diff --git a/includes/api/ApiFeedWatchlist.php b/includes/api/ApiFeedWatchlist.php
index 6aef8fc2..d1beef8a 100644
--- a/includes/api/ApiFeedWatchlist.php
+++ b/includes/api/ApiFeedWatchlist.php
@@ -112,12 +112,16 @@ class ApiFeedWatchlist extends ApiBase {
$module = new ApiMain( $fauxReq );
$module->execute();
- // Get data array
- $data = $module->getResultData();
-
+ $data = $module->getResult()->getResultData( array( 'query', 'watchlist' ) );
$feedItems = array();
- foreach ( (array)$data['query']['watchlist'] as $info ) {
- $feedItems[] = $this->createFeedItem( $info );
+ foreach ( (array)$data as $key => $info ) {
+ if ( ApiResult::isMetadataKey( $key ) ) {
+ continue;
+ }
+ $feedItem = $this->createFeedItem( $info );
+ if ( $feedItem ) {
+ $feedItems[] = $feedItem;
+ }
}
$msg = wfMessage( 'watchlist' )->inContentLanguage()->text();
@@ -166,10 +170,22 @@ class ApiFeedWatchlist extends ApiBase {
private function createFeedItem( $info ) {
$titleStr = $info['title'];
$title = Title::newFromText( $titleStr );
+ $curidParam = array();
+ if ( !$title || $title->isExternal() ) {
+ // Probably a formerly-valid title that's now conflicting with an
+ // interwiki prefix or the like.
+ if ( isset( $info['pageid'] ) ) {
+ $title = Title::newFromId( $info['pageid'] );
+ $curidParam = array( 'curid' => $info['pageid'] );
+ }
+ if ( !$title || $title->isExternal() ) {
+ return null;
+ }
+ }
if ( isset( $info['revid'] ) ) {
$titleUrl = $title->getFullURL( array( 'diff' => $info['revid'] ) );
} else {
- $titleUrl = $title->getFullURL();
+ $titleUrl = $title->getFullURL( $curidParam );
}
$comment = isset( $info['comment'] ) ? $info['comment'] : null;
@@ -219,50 +235,42 @@ class ApiFeedWatchlist extends ApiBase {
),
'linktosections' => false,
);
+
+ $copyParams = array(
+ 'allrev' => 'allrev',
+ 'owner' => 'wlowner',
+ 'token' => 'wltoken',
+ 'show' => 'wlshow',
+ 'type' => 'wltype',
+ 'excludeuser' => 'wlexcludeuser',
+ );
if ( $flags ) {
$wlparams = $this->getWatchlistModule()->getAllowedParams( $flags );
- $ret['allrev'] = $wlparams['allrev'];
- $ret['wlowner'] = $wlparams['owner'];
- $ret['wltoken'] = $wlparams['token'];
- $ret['wlshow'] = $wlparams['show'];
- $ret['wltype'] = $wlparams['type'];
- $ret['wlexcludeuser'] = $wlparams['excludeuser'];
+ foreach ( $copyParams as $from => $to ) {
+ $p = $wlparams[$from];
+ if ( !is_array( $p ) ) {
+ $p = array( ApiBase::PARAM_DFLT => $p );
+ }
+ if ( !isset( $p[ApiBase::PARAM_HELP_MSG] ) ) {
+ $p[ApiBase::PARAM_HELP_MSG] = "apihelp-query+watchlist-param-$from";
+ }
+ $ret[$to] = $p;
+ }
} else {
- $ret['allrev'] = null;
- $ret['wlowner'] = null;
- $ret['wltoken'] = null;
- $ret['wlshow'] = null;
- $ret['wltype'] = null;
- $ret['wlexcludeuser'] = null;
+ foreach ( $copyParams as $from => $to ) {
+ $ret[$to] = null;
+ }
}
return $ret;
}
- public function getParamDescription() {
- $wldescr = $this->getWatchlistModule()->getParamDescription();
-
- return array(
- 'feedformat' => 'The format of the feed',
- 'hours' => 'List pages modified within this many hours from now',
- 'linktosections' => 'Link directly to changed sections if possible',
- 'allrev' => $wldescr['allrev'],
- 'wlowner' => $wldescr['owner'],
- 'wltoken' => $wldescr['token'],
- 'wlshow' => $wldescr['show'],
- 'wltype' => $wldescr['type'],
- 'wlexcludeuser' => $wldescr['excludeuser'],
- );
- }
-
- public function getDescription() {
- return 'Returns a watchlist feed.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=feedwatchlist',
- 'api.php?action=feedwatchlist&allrev=&hours=6'
+ 'action=feedwatchlist'
+ => 'apihelp-feedwatchlist-example-default',
+ 'action=feedwatchlist&allrev=&hours=6'
+ => 'apihelp-feedwatchlist-example-all6hrs',
);
}
diff --git a/includes/api/ApiFileRevert.php b/includes/api/ApiFileRevert.php
index f518e172..5517ee08 100644
--- a/includes/api/ApiFileRevert.php
+++ b/includes/api/ApiFileRevert.php
@@ -61,7 +61,7 @@ class ApiFileRevert extends ApiBase {
} else {
$result = array(
'result' => 'Failure',
- 'errors' => $this->getResult()->convertStatusToArray( $status ),
+ 'errors' => $this->getErrorFormatter()->arrayFromStatus( $status ),
);
}
@@ -135,29 +135,15 @@ class ApiFileRevert extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'filename' => 'Target filename without the File: prefix',
- 'comment' => 'Upload comment',
- 'archivename' => 'Archive name of the revision to revert to',
- );
- }
-
- public function getDescription() {
- return array(
- 'Revert a file to an old version.'
- );
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=filerevert&filename=Wiki.png&comment=Revert&' .
+ 'action=filerevert&filename=Wiki.png&comment=Revert&' .
'archivename=20110305152740!Wiki.png&token=123ABC'
- => 'Revert Wiki.png to the version of 20110305152740',
+ => 'apihelp-filerevert-example-revert',
);
}
}
diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php
index 9165ce88..d078dc45 100644
--- a/includes/api/ApiFormatBase.php
+++ b/includes/api/ApiFormatBase.php
@@ -30,8 +30,9 @@
* @ingroup API
*/
abstract class ApiFormatBase extends ApiBase {
- private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp, $mCleared;
- private $mBufferResult = false, $mBuffer, $mDisabled = false;
+ private $mIsHtml, $mFormat, $mUnescapeAmps, $mHelp;
+ private $mBuffer, $mDisabled = false;
+ protected $mForceDefaultParams = false;
/**
* If $format ends with 'fm', pretty-print the output in HTML.
@@ -48,25 +49,19 @@ abstract class ApiFormatBase extends ApiBase {
$this->mFormat = $format;
}
$this->mFormat = strtoupper( $this->mFormat );
- $this->mCleared = false;
}
/**
* Overriding class returns the MIME type that should be sent to the client.
- * This method is not called if getIsHtml() returns true.
+ *
+ * When getIsHtml() returns true, the return value here is used for syntax
+ * highlighting but the client sees text/html.
+ *
* @return string
*/
abstract public function getMimeType();
/**
- * Whether this formatter needs raw data such as _element tags
- * @return bool
- */
- public function getNeedsRawData() {
- return false;
- }
-
- /**
* Get the internal format name
* @return string
*/
@@ -75,19 +70,6 @@ abstract class ApiFormatBase extends ApiBase {
}
/**
- * Specify whether or not sequences like &amp;quot; should be unescaped
- * to &quot; . This should only be set to true for the help message
- * when rendered in the default (xmlfm) format. This is a temporary
- * special-case fix that should be removed once the help has been
- * reworked to use a fully HTML interface.
- *
- * @param bool $b Whether or not ampersands should be escaped.
- */
- public function setUnescapeAmps( $b ) {
- $this->mUnescapeAmps = $b;
- }
-
- /**
* Returns true when the HTML pretty-printer should be used.
* The default implementation assumes that formats ending with 'fm'
* should be formatted in HTML.
@@ -98,30 +80,27 @@ abstract class ApiFormatBase extends ApiBase {
}
/**
- * Whether this formatter can format the help message in a nice way.
- * By default, this returns the same as getIsHtml().
- * When action=help is set explicitly, the help will always be shown
- * @return bool
- */
- public function getWantsHelp() {
- return $this->getIsHtml();
- }
-
- /**
- * Disable the formatter completely. This causes calls to initPrinter(),
- * printText() and closePrinter() to be ignored.
+ * Disable the formatter.
+ *
+ * This causes calls to initPrinter() and closePrinter() to be ignored.
*/
public function disable() {
$this->mDisabled = true;
}
+ /**
+ * Whether the printer is disabled
+ * @return bool
+ */
public function isDisabled() {
return $this->mDisabled;
}
/**
- * Whether this formatter can handle printing API errors. If this returns
- * false, then on API errors the default printer will be instantiated.
+ * Whether this formatter can handle printing API errors.
+ *
+ * If this returns false, then on API errors the default printer will be
+ * instantiated.
* @since 1.23
* @return bool
*/
@@ -130,24 +109,47 @@ abstract class ApiFormatBase extends ApiBase {
}
/**
- * Initialize the printer function and prepare the output headers, etc.
- * This method must be the first outputting method during execution.
- * A human-targeted notice about available formats is printed for the HTML-based output,
- * except for help screens (caused by either an error in the API parameters,
- * the calling of action=help, or requesting the root script api.php).
- * @param bool $isHelpScreen Whether a help screen is going to be shown
+ * Ignore request parameters, force a default.
+ *
+ * Used as a fallback if errors are being thrown.
+ * @since 1.26
*/
- function initPrinter( $isHelpScreen ) {
+ public function forceDefaultParams() {
+ $this->mForceDefaultParams = true;
+ }
+
+ /**
+ * Overridden to honor $this->forceDefaultParams(), if applicable
+ * @since 1.26
+ */
+ protected function getParameterFromSettings( $paramName, $paramSettings, $parseLimit ) {
+ if ( !$this->mForceDefaultParams ) {
+ return parent::getParameterFromSettings( $paramName, $paramSettings, $parseLimit );
+ }
+
+ if ( !is_array( $paramSettings ) ) {
+ return $paramSettings;
+ } elseif ( isset( $paramSettings[self::PARAM_DFLT] ) ) {
+ return $paramSettings[self::PARAM_DFLT];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Initialize the printer function and prepare the output headers.
+ * @param bool $unused Always false since 1.25
+ */
+ function initPrinter( $unused = false ) {
if ( $this->mDisabled ) {
return;
}
- $isHtml = $this->getIsHtml();
- $mime = $isHtml ? 'text/html' : $this->getMimeType();
- $script = wfScript( 'api' );
+
+ $mime = $this->getIsHtml() ? 'text/html' : $this->getMimeType();
// Some printers (ex. Feed) do their own header settings,
// in which case $mime will be set to null
- if ( is_null( $mime ) ) {
+ if ( $mime === null ) {
return; // skip any initialization
}
@@ -158,91 +160,64 @@ abstract class ApiFormatBase extends ApiBase {
if ( $apiFrameOptions ) {
$this->getMain()->getRequest()->response()->header( "X-Frame-Options: $apiFrameOptions" );
}
-
- if ( $isHtml ) {
-?>
-<!DOCTYPE HTML>
-<html>
-<head>
-<?php
- if ( $this->mUnescapeAmps ) {
-?> <title>MediaWiki API</title>
-<?php
- } else {
-?> <title>MediaWiki API Result</title>
-<?php
- }
-?>
-</head>
-<body>
-<?php
- if ( !$isHelpScreen ) {
-// @codingStandardsIgnoreStart Exclude long line from CodeSniffer checks
-?>
-<br />
-<small>
-You are looking at the HTML representation of the <?php echo $this->mFormat; ?> format.<br />
-HTML is good for debugging, but is unsuitable for application use.<br />
-Specify the format parameter to change the output format.<br />
-To see the non HTML representation of the <?php echo $this->mFormat; ?> format, set format=<?php echo strtolower( $this->mFormat ); ?>.<br />
-See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>, or
-<a href='<?php echo $script; ?>'>API help</a> for more information.
-</small>
-<pre style='white-space: pre-wrap;'>
-<?php
-// @codingStandardsIgnoreEnd
- // don't wrap the contents of the <pre> for help screens
- // because these are actually formatted to rely on
- // the monospaced font for layout purposes
- } else {
-?>
-<pre>
-<?php
- }
- }
}
/**
- * Finish printing. Closes HTML tags.
+ * Finish printing and output buffered data.
*/
public function closePrinter() {
if ( $this->mDisabled ) {
return;
}
- if ( $this->getIsHtml() ) {
-?>
-</pre>
-</body>
-</html>
-<?php
+ $mime = $this->getMimeType();
+ if ( $this->getIsHtml() && $mime !== null ) {
+ $format = $this->getFormat();
+ $result = $this->getBuffer();
+
+ $context = new DerivativeContext( $this->getMain() );
+ $context->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'apioutput' ) );
+ $context->setTitle( SpecialPage::getTitleFor( 'ApiHelp' ) );
+ $out = new OutputPage( $context );
+ $context->setOutput( $out );
+
+ $out->addModules( 'mediawiki.apipretty' );
+ $out->setPageTitle( $context->msg( 'api-format-title' ) );
+
+ $header = $context->msg( 'api-format-prettyprint-header' )
+ ->params( $format, strtolower( $format ) )
+ ->parseAsBlock();
+ $out->addHTML(
+ Html::rawElement( 'div', array( 'class' => 'api-pretty-header' ),
+ ApiHelp::fixHelpLinks( $header )
+ )
+ );
+
+ if ( Hooks::run( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) {
+ $out->addHTML(
+ Html::element( 'pre', array( 'class' => 'api-pretty-content' ), $result )
+ );
+ }
+
+ // API handles its own clickjacking protection.
+ // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
+ $out->allowClickJacking();
+ $out->output();
+ } else {
+ // For non-HTML output, clear all errors that might have been
+ // displayed if display_errors=On
+ ob_clean();
+
+ echo $this->getBuffer();
}
}
/**
- * The main format printing function. Call it to output the result
- * string to the user. This function will automatically output HTML
- * when format name ends in 'fm'.
+ * Append text to the output buffer.
* @param string $text
*/
public function printText( $text ) {
- if ( $this->mDisabled ) {
- return;
- }
- if ( $this->mBufferResult ) {
- $this->mBuffer = $text;
- } elseif ( $this->getIsHtml() ) {
- echo $this->formatHTML( $text );
- } else {
- // For non-HTML output, clear all errors that might have been
- // displayed if display_errors=On
- // Do this only once, of course
- if ( !$this->mCleared ) {
- ob_clean();
- $this->mCleared = true;
- }
- echo $text;
- }
+ $this->mBuffer .= $text;
}
/**
@@ -253,34 +228,89 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
return $this->mBuffer;
}
+ protected function getExamplesMessages() {
+ return array(
+ 'action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName()
+ => array( 'apihelp-format-example-generic', $this->getFormat() )
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Data_formats';
+ }
+
/**
- * Set the flag to buffer the result instead of printing it.
- * @param bool $value
+ * To avoid code duplication with the deprecation of dbg, dump, txt, wddx,
+ * and yaml, this method is added to do the necessary work. It should be
+ * removed when those deprecated formats are removed.
*/
- public function setBufferResult( $value ) {
- $this->mBufferResult = $value;
+ protected function markDeprecated() {
+ $fm = $this->getIsHtml() ? 'fm' : '';
+ $name = $this->getModuleName();
+ $this->logFeatureUsage( "format=$name" );
+ $this->setWarning( "format=$name has been deprecated. Please use format=json$fm instead." );
+ }
+
+ /************************************************************************//**
+ * @name Deprecated
+ * @{
+ */
+
+ /**
+ * Specify whether or not sequences like &amp;quot; should be unescaped
+ * to &quot; . This should only be set to true for the help message
+ * when rendered in the default (xmlfm) format. This is a temporary
+ * special-case fix that should be removed once the help has been
+ * reworked to use a fully HTML interface.
+ *
+ * @deprecated since 1.25
+ * @param bool $b Whether or not ampersands should be escaped.
+ */
+ public function setUnescapeAmps( $b ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ $this->mUnescapeAmps = $b;
+ }
+
+ /**
+ * Whether this formatter can format the help message in a nice way.
+ * By default, this returns the same as getIsHtml().
+ * When action=help is set explicitly, the help will always be shown
+ * @deprecated since 1.25
+ * @return bool
+ */
+ public function getWantsHelp() {
+ wfDeprecated( __METHOD__, '1.25' );
+ return $this->getIsHtml();
}
/**
* Sets whether the pretty-printer should format *bold*
+ * @deprecated since 1.25
* @param bool $help
*/
public function setHelp( $help = true ) {
+ wfDeprecated( __METHOD__, '1.25' );
$this->mHelp = $help;
}
/**
* Pretty-print various elements in HTML format, such as xml tags and
* URLs. This method also escapes characters like <
+ * @deprecated since 1.25
* @param string $text
* @return string
*/
protected function formatHTML( $text ) {
+ wfDeprecated( __METHOD__, '1.25' );
+
// Escape everything first for full coverage
$text = htmlspecialchars( $text );
- // encode all comments or tags as safe blue strings
- $text = str_replace( '&lt;', '<span style="color:blue;">&lt;', $text );
- $text = str_replace( '&gt;', '&gt;</span>', $text );
+
+ if ( $this->mFormat === 'XML' || $this->mFormat === 'WDDX' ) {
+ // encode all comments or tags as safe blue strings
+ $text = str_replace( '&lt;', '<span style="color:blue;">&lt;', $text );
+ $text = str_replace( '&gt;', '&gt;</span>', $text );
+ }
// identify requests to api.php
$text = preg_replace( '#^(\s*)(api\.php\?[^ <\n\t]+)$#m', '\1<a href="\2">\2</a>', $text );
@@ -325,30 +355,42 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
return $text;
}
- public function getExamples() {
- return array(
- 'api.php?action=query&meta=siteinfo&siprop=namespaces&format=' . $this->getModuleName()
- => "Format the query result in the {$this->getModuleName()} format",
- );
- }
-
- public function getHelpUrls() {
- return 'https://www.mediawiki.org/wiki/API:Data_formats';
- }
-
+ /**
+ * @see ApiBase::getDescription
+ * @deprecated since 1.25
+ */
public function getDescription() {
return $this->getIsHtml() ? ' (pretty-print in HTML)' : '';
}
/**
- * To avoid code duplication with the deprecation of dbg, dump, txt, wddx,
- * and yaml, this method is added to do the necessary work. It should be
- * removed when those deprecated formats are removed.
+ * Set the flag to buffer the result instead of printing it.
+ * @deprecated since 1.25, output is always buffered
+ * @param bool $value
*/
- protected function markDeprecated() {
- $fm = $this->getIsHtml() ? 'fm' : '';
- $name = $this->getModuleName();
- $this->logFeatureUsage( "format=$name" );
- $this->setWarning( "format=$name has been deprecated. Please use format=json$fm instead." );
+ public function setBufferResult( $value ) {
}
+
+ /**
+ * Formerly indicated whether the formatter needed metadata from ApiResult.
+ *
+ * ApiResult previously (indirectly) used this to decide whether to add
+ * metadata or to ignore calls to metadata-setting methods, which
+ * unfortunately made several methods that should have been static have to
+ * be dynamic instead. Now ApiResult always stores metadata and formatters
+ * are required to ignore it or filter it out.
+ *
+ * @deprecated since 1.25
+ * @return bool
+ */
+ public function getNeedsRawData() {
+ return false;
+ }
+
+ /**@}*/
}
+
+/**
+ * For really cool vim folding this needs to be at the end:
+ * vim: foldmarker=@{,@} foldmethod=marker
+ */
diff --git a/includes/api/ApiFormatDbg.php b/includes/api/ApiFormatDbg.php
index 5ec518b3..7d359ad4 100644
--- a/includes/api/ApiFormatDbg.php
+++ b/includes/api/ApiFormatDbg.php
@@ -40,10 +40,15 @@ class ApiFormatDbg extends ApiFormatBase {
public function execute() {
$this->markDeprecated();
- $this->printText( var_export( $this->getResultData(), true ) );
+ $data = $this->getResult()->getResultData( null, array(
+ 'BC' => array(),
+ 'Types' => array(),
+ 'Strip' => 'all',
+ ) );
+ $this->printText( var_export( $data, true ) );
}
- public function getDescription() {
- return 'DEPRECATED! Output data in PHP\'s var_export() format' . parent::getDescription();
+ public function isDeprecated() {
+ return true;
}
}
diff --git a/includes/api/ApiFormatDump.php b/includes/api/ApiFormatDump.php
index d4c7cab4..f34e1ae4 100644
--- a/includes/api/ApiFormatDump.php
+++ b/includes/api/ApiFormatDump.php
@@ -40,14 +40,19 @@ class ApiFormatDump extends ApiFormatBase {
public function execute() {
$this->markDeprecated();
+ $data = $this->getResult()->getResultData( null, array(
+ 'BC' => array(),
+ 'Types' => array(),
+ 'Strip' => 'all',
+ ) );
ob_start();
- var_dump( $this->getResultData() );
+ var_dump( $data );
$result = ob_get_contents();
ob_end_clean();
$this->printText( $result );
}
- public function getDescription() {
- return 'DEPRECATED! Output data in PHP\'s var_dump() format' . parent::getDescription();
+ public function isDeprecated() {
+ return true;
}
}
diff --git a/includes/api/ApiFormatFeedWrapper.php b/includes/api/ApiFormatFeedWrapper.php
index 92600067..00747eef 100644
--- a/includes/api/ApiFormatFeedWrapper.php
+++ b/includes/api/ApiFormatFeedWrapper.php
@@ -46,8 +46,8 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
// Disable size checking for this because we can't continue
// cleanly; size checking would cause more problems than it'd
// solve
- $result->addValue( null, '_feed', $feed, ApiResult::NO_SIZE_CHECK );
- $result->addValue( null, '_feeditems', $feedItems, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( null, '_feed', $feed, ApiResult::NO_VALIDATE );
+ $result->addValue( null, '_feeditems', $feedItems, ApiResult::NO_VALIDATE );
}
/**
@@ -82,17 +82,41 @@ class ApiFormatFeedWrapper extends ApiFormatBase {
* $result['_feed'] - an instance of one of the $wgFeedClasses classes
* $result['_feeditems'] - an array of FeedItem instances
*/
+ public function initPrinter( $unused = false ) {
+ parent::initPrinter( $unused );
+
+ if ( $this->isDisabled() ) {
+ return;
+ }
+
+ $data = $this->getResult()->getResultData();
+ if ( isset( $data['_feed'] ) && isset( $data['_feeditems'] ) ) {
+ $data['_feed']->httpHeaders();
+ } else {
+ // Error has occurred, print something useful
+ ApiBase::dieDebug( __METHOD__, 'Invalid feed class/item' );
+ }
+ }
+
+ /**
+ * This class expects the result data to be in a custom format set by self::setResult()
+ * $result['_feed'] - an instance of one of the $wgFeedClasses classes
+ * $result['_feeditems'] - an array of FeedItem instances
+ */
public function execute() {
- $data = $this->getResultData();
+ $data = $this->getResult()->getResultData();
if ( isset( $data['_feed'] ) && isset( $data['_feeditems'] ) ) {
$feed = $data['_feed'];
$items = $data['_feeditems'];
+ // execute() needs to pass strings to $this->printText, not produce output itself.
+ ob_start();
$feed->outHeader();
foreach ( $items as & $item ) {
$feed->outItem( $item );
}
$feed->outFooter();
+ $this->printText( ob_get_clean() );
} else {
// Error has occurred, print something useful
ApiBase::dieDebug( __METHOD__, 'Invalid feed class/item' );
diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php
index d9f9d46a..43877b78 100644
--- a/includes/api/ApiFormatJson.php
+++ b/includes/api/ApiFormatJson.php
@@ -30,39 +30,72 @@
*/
class ApiFormatJson extends ApiFormatBase {
- private $mIsRaw;
+ private $isRaw;
public function __construct( ApiMain $main, $format ) {
parent::__construct( $main, $format );
- $this->mIsRaw = ( $format === 'rawfm' );
+ $this->isRaw = ( $format === 'rawfm' );
}
public function getMimeType() {
$params = $this->extractRequestParams();
// callback:
- if ( $params['callback'] ) {
+ if ( isset( $params['callback'] ) ) {
return 'text/javascript';
}
return 'application/json';
}
+ /**
+ * @deprecated since 1.25
+ */
public function getNeedsRawData() {
- return $this->mIsRaw;
+ return $this->isRaw;
}
+ /**
+ * @deprecated since 1.25
+ */
public function getWantsHelp() {
+ wfDeprecated( __METHOD__, '1.25' );
// Help is always ugly in JSON
return false;
}
public function execute() {
$params = $this->extractRequestParams();
- $json = FormatJson::encode(
- $this->getResultData(),
- $this->getIsHtml(),
- $params['utf8'] ? FormatJson::ALL_OK : FormatJson::XMLMETA_OK
- );
+
+ $opt = 0;
+ if ( $this->isRaw ) {
+ $opt |= FormatJson::ALL_OK;
+ $transform = array();
+ } else {
+ switch ( $params['formatversion'] ) {
+ case 1:
+ $opt |= $params['utf8'] ? FormatJson::ALL_OK : FormatJson::XMLMETA_OK;
+ $transform = array(
+ 'BC' => array(),
+ 'Types' => array( 'AssocAsObject' => true ),
+ 'Strip' => 'all',
+ );
+ break;
+
+ case 2:
+ case 'latest':
+ $opt |= $params['ascii'] ? FormatJson::XMLMETA_OK : FormatJson::ALL_OK;
+ $transform = array(
+ 'Types' => array( 'AssocAsObject' => true ),
+ 'Strip' => 'all',
+ );
+ break;
+
+ default:
+ $this->dieUsage( __METHOD__ . ': Unknown value for \'formatversion\'', 'unknownformatversion' );
+ }
+ }
+ $data = $this->getResult()->getResultData( null, $transform );
+ $json = FormatJson::encode( $data, $this->getIsHtml(), $opt );
// Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
// Flash, but what it does isn't friendly for the API, so we need to
@@ -73,9 +106,8 @@ class ApiFormatJson extends ApiFormatBase {
);
}
- $callback = $params['callback'];
- if ( $callback !== null ) {
- $callback = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", '', $callback );
+ if ( isset( $params['callback'] ) ) {
+ $callback = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", '', $params['callback'] );
# Prepend a comment to try to avoid attacks against content
# sniffers, such as bug 68187.
$this->printText( "/**/$callback($json)" );
@@ -85,26 +117,28 @@ class ApiFormatJson extends ApiFormatBase {
}
public function getAllowedParams() {
- return array(
- 'callback' => null,
- 'utf8' => false,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'callback' => 'If specified, wraps the output into a given function ' .
- 'call. For safety, all user-specific data will be restricted.',
- 'utf8' => 'If specified, encodes most (but not all) non-ASCII ' .
- 'characters as UTF-8 instead of replacing them with hexadecimal escape sequences.',
- );
- }
-
- public function getDescription() {
- if ( $this->mIsRaw ) {
- return 'Output data with the debugging elements in JSON format' . parent::getDescription();
+ if ( $this->isRaw ) {
+ return array();
}
- return 'Output data in JSON format' . parent::getDescription();
+ $ret = array(
+ 'callback' => array(
+ ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback',
+ ),
+ 'utf8' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-utf8',
+ ),
+ 'ascii' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-ascii',
+ ),
+ 'formatversion' => array(
+ ApiBase::PARAM_TYPE => array( 1, 2, 'latest' ),
+ ApiBase::PARAM_DFLT => 1,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-formatversion',
+ ),
+ );
+ return $ret;
}
}
diff --git a/includes/api/ApiFormatNone.php b/includes/api/ApiFormatNone.php
index 78023af3..dc623ac1 100644
--- a/includes/api/ApiFormatNone.php
+++ b/includes/api/ApiFormatNone.php
@@ -36,8 +36,4 @@ class ApiFormatNone extends ApiFormatBase {
public function execute() {
}
-
- public function getDescription() {
- return 'Output nothing' . parent::getDescription();
- }
}
diff --git a/includes/api/ApiFormatPhp.php b/includes/api/ApiFormatPhp.php
index 73ce80ef..d88dd40b 100644
--- a/includes/api/ApiFormatPhp.php
+++ b/includes/api/ApiFormatPhp.php
@@ -35,7 +35,29 @@ class ApiFormatPhp extends ApiFormatBase {
}
public function execute() {
- $text = serialize( $this->getResultData() );
+ $params = $this->extractRequestParams();
+
+ switch ( $params['formatversion'] ) {
+ case 1:
+ $transforms = array(
+ 'BC' => array(),
+ 'Types' => array(),
+ 'Strip' => 'all',
+ );
+ break;
+
+ case 2:
+ case 'latest':
+ $transforms = array(
+ 'Types' => array(),
+ 'Strip' => 'all',
+ );
+ break;
+
+ default:
+ $this->dieUsage( __METHOD__ . ': Unknown value for \'formatversion\'', 'unknownformatversion' );
+ }
+ $text = serialize( $this->getResult()->getResultData( null, $transforms ) );
// Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
// Flash, but what it does isn't friendly for the API. There's nothing
@@ -54,7 +76,14 @@ class ApiFormatPhp extends ApiFormatBase {
$this->printText( $text );
}
- public function getDescription() {
- return 'Output data in serialized PHP format' . parent::getDescription();
+ public function getAllowedParams() {
+ $ret = array(
+ 'formatversion' => array(
+ ApiBase::PARAM_TYPE => array( 1, 2, 'latest' ),
+ ApiBase::PARAM_DFLT => 1,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-php-param-formatversion',
+ ),
+ );
+ return $ret;
}
}
diff --git a/includes/api/ApiFormatRaw.php b/includes/api/ApiFormatRaw.php
index 3f5c8b73..7bb2453d 100644
--- a/includes/api/ApiFormatRaw.php
+++ b/includes/api/ApiFormatRaw.php
@@ -30,20 +30,22 @@
*/
class ApiFormatRaw extends ApiFormatBase {
+ private $errorFallback;
+
/**
* @param ApiMain $main
* @param ApiFormatBase $errorFallback Object to fall back on for errors
*/
public function __construct( ApiMain $main, ApiFormatBase $errorFallback ) {
parent::__construct( $main, 'raw' );
- $this->mErrorFallback = $errorFallback;
+ $this->errorFallback = $errorFallback;
}
public function getMimeType() {
- $data = $this->getResultData();
+ $data = $this->getResult()->getResultData();
if ( isset( $data['error'] ) ) {
- return $this->mErrorFallback->getMimeType();
+ return $this->errorFallback->getMimeType();
}
if ( !isset( $data['mime'] ) ) {
@@ -53,11 +55,28 @@ class ApiFormatRaw extends ApiFormatBase {
return $data['mime'];
}
- public function execute() {
- $data = $this->getResultData();
+ public function initPrinter( $unused = false ) {
+ $data = $this->getResult()->getResultData();
+ if ( isset( $data['error'] ) ) {
+ $this->errorFallback->initPrinter( $unused );
+ } else {
+ parent::initPrinter( $unused );
+ }
+ }
+
+ public function closePrinter() {
+ $data = $this->getResult()->getResultData();
if ( isset( $data['error'] ) ) {
- $this->mErrorFallback->execute();
+ $this->errorFallback->closePrinter();
+ } else {
+ parent::closePrinter();
+ }
+ }
+ public function execute() {
+ $data = $this->getResult()->getResultData();
+ if ( isset( $data['error'] ) ) {
+ $this->errorFallback->execute();
return;
}
diff --git a/includes/api/ApiFormatTxt.php b/includes/api/ApiFormatTxt.php
index c451ed77..e739d5a4 100644
--- a/includes/api/ApiFormatTxt.php
+++ b/includes/api/ApiFormatTxt.php
@@ -40,10 +40,15 @@ class ApiFormatTxt extends ApiFormatBase {
public function execute() {
$this->markDeprecated();
- $this->printText( print_r( $this->getResultData(), true ) );
+ $data = $this->getResult()->getResultData( null, array(
+ 'BC' => array(),
+ 'Types' => array(),
+ 'Strip' => 'all',
+ ) );
+ $this->printText( print_r( $data, true ) );
}
- public function getDescription() {
- return 'DEPRECATED! Output data in PHP\'s print_r() format' . parent::getDescription();
+ public function isDeprecated() {
+ return true;
}
}
diff --git a/includes/api/ApiFormatWddx.php b/includes/api/ApiFormatWddx.php
index ec3dc2d9..c18353fe 100644
--- a/includes/api/ApiFormatWddx.php
+++ b/includes/api/ApiFormatWddx.php
@@ -38,18 +38,30 @@ class ApiFormatWddx extends ApiFormatBase {
public function execute() {
$this->markDeprecated();
+ $data = $this->getResult()->getResultData( null, array(
+ 'BC' => array(),
+ 'Types' => array( 'AssocAsObject' => true ),
+ 'Strip' => 'all',
+ ) );
+
if ( !$this->getIsHtml() && !static::useSlowPrinter() ) {
- $this->printText( wddx_serialize_value( $this->getResultData() ) );
+ $txt = wddx_serialize_value( $data );
+ $txt = str_replace(
+ '<struct><var name=\'php_class_name\'><string>stdClass</string></var>',
+ '<struct>',
+ $txt
+ );
+ $this->printText( $txt );
} else {
// Don't do newlines and indentation if we weren't asked
// for pretty output
$nl = ( $this->getIsHtml() ? "\n" : '' );
- $indstr = ' ';
+ $indstr = ( $this->getIsHtml() ? ' ' : '' );
$this->printText( "<?xml version=\"1.0\"?>$nl" );
$this->printText( "<wddxPacket version=\"1.0\">$nl" );
- $this->printText( "$indstr<header/>$nl" );
+ $this->printText( "$indstr<header />$nl" );
$this->printText( "$indstr<data>$nl" );
- $this->slowWddxPrinter( $this->getResultData(), 4 );
+ $this->slowWddxPrinter( $data, 4 );
$this->printText( "$indstr</data>$nl" );
$this->printText( "</wddxPacket>$nl" );
}
@@ -102,44 +114,49 @@ class ApiFormatWddx extends ApiFormatBase {
$indstr = ( $this->getIsHtml() ? str_repeat( ' ', $indent ) : '' );
$indstr2 = ( $this->getIsHtml() ? str_repeat( ' ', $indent + 2 ) : '' );
$nl = ( $this->getIsHtml() ? "\n" : '' );
+
if ( is_array( $elemValue ) ) {
- // Check whether we've got an associative array (<struct>)
- // or a regular array (<array>)
$cnt = count( $elemValue );
- if ( $cnt == 0 || array_keys( $elemValue ) === range( 0, $cnt - 1 ) ) {
- // Regular array
- $this->printText( $indstr . Xml::element( 'array', array(
- 'length' => $cnt ), null ) . $nl );
- foreach ( $elemValue as $subElemValue ) {
- $this->slowWddxPrinter( $subElemValue, $indent + 2 );
- }
- $this->printText( "$indstr</array>$nl" );
- } else {
- // Associative array (<struct>)
- $this->printText( "$indstr<struct>$nl" );
- foreach ( $elemValue as $subElemName => $subElemValue ) {
- $this->printText( $indstr2 . Xml::element( 'var', array(
- 'name' => $subElemName
- ), null ) . $nl );
- $this->slowWddxPrinter( $subElemValue, $indent + 4 );
- $this->printText( "$indstr2</var>$nl" );
- }
- $this->printText( "$indstr</struct>$nl" );
+ if ( $cnt != 0 && array_keys( $elemValue ) !== range( 0, $cnt - 1 ) ) {
+ $elemValue = (object)$elemValue;
+ }
+ }
+
+ if ( is_array( $elemValue ) ) {
+ // Regular array
+ $this->printText( $indstr . Xml::element( 'array', array(
+ 'length' => count( $elemValue ) ), null ) . $nl );
+ foreach ( $elemValue as $subElemValue ) {
+ $this->slowWddxPrinter( $subElemValue, $indent + 2 );
+ }
+ $this->printText( "$indstr</array>$nl" );
+ } elseif ( is_object( $elemValue ) ) {
+ // Associative array (<struct>)
+ $this->printText( "$indstr<struct>$nl" );
+ foreach ( $elemValue as $subElemName => $subElemValue ) {
+ $this->printText( $indstr2 . Xml::element( 'var', array(
+ 'name' => $subElemName
+ ), null ) . $nl );
+ $this->slowWddxPrinter( $subElemValue, $indent + 4 );
+ $this->printText( "$indstr2</var>$nl" );
}
+ $this->printText( "$indstr</struct>$nl" );
} elseif ( is_int( $elemValue ) || is_float( $elemValue ) ) {
$this->printText( $indstr . Xml::element( 'number', null, $elemValue ) . $nl );
} elseif ( is_string( $elemValue ) ) {
- $this->printText( $indstr . Xml::element( 'string', null, $elemValue ) . $nl );
+ $this->printText( $indstr . Xml::element( 'string', null, $elemValue, false ) . $nl );
} elseif ( is_bool( $elemValue ) ) {
$this->printText( $indstr . Xml::element( 'boolean',
array( 'value' => $elemValue ? 'true' : 'false' ) ) . $nl
);
+ } elseif ( $elemValue === null ) {
+ $this->printText( $indstr . Xml::element( 'null', array() ) . $nl );
} else {
ApiBase::dieDebug( __METHOD__, 'Unknown type ' . gettype( $elemValue ) );
}
}
- public function getDescription() {
- return 'DEPRECATED! Output data in WDDX format' . parent::getDescription();
+ public function isDeprecated() {
+ return true;
}
}
diff --git a/includes/api/ApiFormatXml.php b/includes/api/ApiFormatXml.php
index b3d59379..fa0bac34 100644
--- a/includes/api/ApiFormatXml.php
+++ b/includes/api/ApiFormatXml.php
@@ -39,6 +39,9 @@ class ApiFormatXml extends ApiFormatBase {
return 'text/xml';
}
+ /**
+ * @deprecated since 1.25
+ */
public function getNeedsRawData() {
return true;
}
@@ -56,18 +59,32 @@ class ApiFormatXml extends ApiFormatBase {
if ( !is_null( $this->mXslt ) ) {
$this->addXslt();
}
- if ( $this->mIncludeNamespace ) {
+
+ $result = $this->getResult();
+ if ( $this->mIncludeNamespace && $result->getResultData( 'xmlns' ) === null ) {
// If the result data already contains an 'xmlns' namespace added
// for custom XML output types, it will override the one for the
// generic API results.
// This allows API output of other XML types like Atom, RSS, RSD.
- $data = $this->getResultData() + array( 'xmlns' => self::$namespace );
- } else {
- $data = $this->getResultData();
+ $result->addValue( null, 'xmlns', self::$namespace, ApiResult::NO_SIZE_CHECK );
}
+ $data = $result->getResultData( null, array(
+ 'Custom' => function ( &$data, &$metadata ) {
+ if ( isset( $metadata[ApiResult::META_TYPE] ) ) {
+ // We want to use non-BC for BCassoc to force outputting of _idx.
+ switch( $metadata[ApiResult::META_TYPE] ) {
+ case 'BCassoc':
+ $metadata[ApiResult::META_TYPE] = 'assoc';
+ break;
+ }
+ }
+ },
+ 'BC' => array( 'nobool', 'no*', 'nosub' ),
+ 'Types' => array( 'ArmorKVP' => '_name' ),
+ ) );
$this->printText(
- self::recXmlPrint( $this->mRootElemName,
+ static::recXmlPrint( $this->mRootElemName,
$data,
$this->getIsHtml() ? -2 : null
)
@@ -77,143 +94,185 @@ class ApiFormatXml extends ApiFormatBase {
/**
* This method takes an array and converts it to XML.
*
- * There are several noteworthy cases:
- *
- * If array contains a key '_element', then the code assumes that ALL
- * other keys are not important and replaces them with the
- * value['_element'].
- *
- * @par Example:
- * @verbatim
- * name='root', value = array( '_element'=>'page', 'x', 'y', 'z')
- * @endverbatim
- * creates:
- * @verbatim
- * <root> <page>x</page> <page>y</page> <page>z</page> </root>
- * @endverbatim
- *
- * If any of the array's element key is '*', then the code treats all
- * other key->value pairs as attributes, and the value['*'] as the
- * element's content.
- *
- * @par Example:
- * @verbatim
- * name='root', value = array( '*'=>'text', 'lang'=>'en', 'id'=>10)
- * @endverbatim
- * creates:
- * @verbatim
- * <root lang='en' id='10'>text</root>
- * @endverbatim
- *
- * Finally neither key is found, all keys become element names, and values
- * become element content.
- *
- * @note The method is recursive, so the same rules apply to any
- * sub-arrays.
- *
- * @param string $elemName
- * @param mixed $elemValue
- * @param int $indent
- *
+ * @param string|null $name Tag name
+ * @param mixed $value Tag value (attributes/content/subelements)
+ * @param int|null $indent Indentation
+ * @param array $attributes Additional attributes
* @return string
*/
- public static function recXmlPrint( $elemName, $elemValue, $indent ) {
+ public static function recXmlPrint( $name, $value, $indent, $attributes = array() ) {
$retval = '';
- if ( !is_null( $indent ) ) {
- $indent += 2;
+ if ( $indent !== null ) {
+ if ( $name !== null ) {
+ $indent += 2;
+ }
$indstr = "\n" . str_repeat( ' ', $indent );
} else {
$indstr = '';
}
- $elemName = str_replace( ' ', '_', $elemName );
-
- if ( is_array( $elemValue ) ) {
- if ( isset( $elemValue['*'] ) ) {
- $subElemContent = $elemValue['*'];
- unset( $elemValue['*'] );
- // Add xml:space="preserve" to the
- // element so XML parsers will leave
- // whitespace in the content alone
- $elemValue['xml:space'] = 'preserve';
- } else {
- $subElemContent = null;
+ if ( is_object( $value ) ) {
+ $value = (array)$value;
+ }
+ if ( is_array( $value ) ) {
+ $contentKey = isset( $value[ApiResult::META_CONTENT] )
+ ? $value[ApiResult::META_CONTENT]
+ : '*';
+ $subelementKeys = isset( $value[ApiResult::META_SUBELEMENTS] )
+ ? $value[ApiResult::META_SUBELEMENTS]
+ : array();
+ if ( isset( $value[ApiResult::META_BC_SUBELEMENTS] ) ) {
+ $subelementKeys = array_merge(
+ $subelementKeys, $value[ApiResult::META_BC_SUBELEMENTS]
+ );
}
+ $preserveKeys = isset( $value[ApiResult::META_PRESERVE_KEYS] )
+ ? $value[ApiResult::META_PRESERVE_KEYS]
+ : array();
+ $indexedTagName = isset( $value[ApiResult::META_INDEXED_TAG_NAME] )
+ ? self::mangleName( $value[ApiResult::META_INDEXED_TAG_NAME], $preserveKeys )
+ : '_v';
+ $bcBools = isset( $value[ApiResult::META_BC_BOOLS] )
+ ? $value[ApiResult::META_BC_BOOLS]
+ : array();
+ $indexSubelements = isset( $value[ApiResult::META_TYPE] )
+ ? $value[ApiResult::META_TYPE] !== 'array'
+ : false;
- if ( isset( $elemValue['_element'] ) ) {
- $subElemIndName = $elemValue['_element'];
- unset( $elemValue['_element'] );
- } else {
- $subElemIndName = null;
- }
+ $content = null;
+ $subelements = array();
+ $indexedSubelements = array();
+ foreach ( $value as $k => $v ) {
+ if ( ApiResult::isMetadataKey( $k ) && !in_array( $k, $preserveKeys, true ) ) {
+ continue;
+ }
- if ( isset( $elemValue['_subelements'] ) ) {
- foreach ( $elemValue['_subelements'] as $subElemId ) {
- if ( isset( $elemValue[$subElemId] ) && !is_array( $elemValue[$subElemId] ) ) {
- $elemValue[$subElemId] = array( '*' => $elemValue[$subElemId] );
- }
+ $oldv = $v;
+ if ( is_bool( $v ) && !in_array( $k, $bcBools, true ) ) {
+ $v = $v ? 'true' : 'false';
}
- unset( $elemValue['_subelements'] );
- }
- $indElements = array();
- $subElements = array();
- foreach ( $elemValue as $subElemId => & $subElemValue ) {
- if ( is_int( $subElemId ) ) {
- $indElements[] = $subElemValue;
- unset( $elemValue[$subElemId] );
- } elseif ( is_array( $subElemValue ) ) {
- $subElements[$subElemId] = $subElemValue;
- unset( $elemValue[$subElemId] );
- } elseif ( is_bool( $subElemValue ) ) {
- // treat true as empty string, skip false in xml format
- if ( $subElemValue === true ) {
- $subElemValue = '';
- } else {
- unset( $elemValue[$subElemId] );
+ if ( $name !== null && $k === $contentKey ) {
+ $content = $v;
+ } elseif ( is_int( $k ) ) {
+ $indexedSubelements[$k] = $v;
+ } elseif ( is_array( $v ) || is_object( $v ) ) {
+ $subelements[self::mangleName( $k, $preserveKeys )] = $v;
+ } elseif ( in_array( $k, $subelementKeys, true ) || $name === null ) {
+ $subelements[self::mangleName( $k, $preserveKeys )] = array(
+ 'content' => $v,
+ ApiResult::META_CONTENT => 'content',
+ ApiResult::META_TYPE => 'assoc',
+ );
+ } elseif ( is_bool( $oldv ) ) {
+ if ( $oldv ) {
+ $attributes[self::mangleName( $k, $preserveKeys )] = '';
}
+ } elseif ( $v !== null ) {
+ $attributes[self::mangleName( $k, $preserveKeys )] = $v;
}
}
- if ( is_null( $subElemIndName ) && count( $indElements ) ) {
- ApiBase::dieDebug( __METHOD__, "($elemName, ...) has integer keys " .
- "without _element value. Use ApiResult::setIndexedTagName()." );
- }
-
- if ( count( $subElements ) && count( $indElements ) && !is_null( $subElemContent ) ) {
- ApiBase::dieDebug( __METHOD__, "($elemName, ...) has content and subelements" );
+ if ( $content !== null ) {
+ if ( $subelements || $indexedSubelements ) {
+ $subelements[self::mangleName( $contentKey, $preserveKeys )] = array(
+ 'content' => $content,
+ ApiResult::META_CONTENT => 'content',
+ ApiResult::META_TYPE => 'assoc',
+ );
+ $content = null;
+ } elseif ( is_scalar( $content ) ) {
+ // Add xml:space="preserve" to the element so XML parsers
+ // will leave whitespace in the content alone
+ $attributes += array( 'xml:space' => 'preserve' );
+ }
}
- if ( !is_null( $subElemContent ) ) {
- $retval .= $indstr . Xml::element( $elemName, $elemValue, $subElemContent );
- } elseif ( !count( $indElements ) && !count( $subElements ) ) {
- $retval .= $indstr . Xml::element( $elemName, $elemValue );
+ if ( $content !== null ) {
+ if ( is_scalar( $content ) ) {
+ $retval .= $indstr . Xml::element( $name, $attributes, $content );
+ } else {
+ if ( $name !== null ) {
+ $retval .= $indstr . Xml::element( $name, $attributes, null );
+ }
+ $retval .= static::recXmlPrint( null, $content, $indent );
+ if ( $name !== null ) {
+ $retval .= $indstr . Xml::closeElement( $name );
+ }
+ }
+ } elseif ( !$indexedSubelements && !$subelements ) {
+ if ( $name !== null ) {
+ $retval .= $indstr . Xml::element( $name, $attributes );
+ }
} else {
- $retval .= $indstr . Xml::element( $elemName, $elemValue, null );
-
- foreach ( $subElements as $subElemId => & $subElemValue ) {
- $retval .= self::recXmlPrint( $subElemId, $subElemValue, $indent );
+ if ( $name !== null ) {
+ $retval .= $indstr . Xml::element( $name, $attributes, null );
}
-
- foreach ( $indElements as &$subElemValue ) {
- $retval .= self::recXmlPrint( $subElemIndName, $subElemValue, $indent );
+ foreach ( $subelements as $k => $v ) {
+ $retval .= static::recXmlPrint( $k, $v, $indent );
+ }
+ foreach ( $indexedSubelements as $k => $v ) {
+ $retval .= static::recXmlPrint( $indexedTagName, $v, $indent,
+ $indexSubelements ? array( '_idx' => $k ) : array()
+ );
+ }
+ if ( $name !== null ) {
+ $retval .= $indstr . Xml::closeElement( $name );
}
-
- $retval .= $indstr . Xml::closeElement( $elemName );
}
- } elseif ( !is_object( $elemValue ) ) {
+ } else {
// to make sure null value doesn't produce unclosed element,
- // which is what Xml::element( $elemName, null, null ) returns
- if ( $elemValue === null ) {
- $retval .= $indstr . Xml::element( $elemName );
+ // which is what Xml::element( $name, null, null ) returns
+ if ( $value === null ) {
+ $retval .= $indstr . Xml::element( $name, $attributes );
} else {
- $retval .= $indstr . Xml::element( $elemName, null, $elemValue );
+ $retval .= $indstr . Xml::element( $name, $attributes, $value );
}
}
return $retval;
}
+ /**
+ * Mangle XML-invalid names to be valid in XML
+ * @param string $name
+ * @param array $preserveKeys Names to not mangle
+ * @return string Mangled name
+ */
+ private static function mangleName( $name, $preserveKeys = array() ) {
+ static $nsc = null, $nc = null;
+
+ if ( in_array( $name, $preserveKeys, true ) ) {
+ return $name;
+ }
+
+ if ( $name === '' ) {
+ return '_';
+ }
+
+ if ( $nsc === null ) {
+ // Note we omit ':' from $nsc and $nc because it's reserved for XML
+ // namespacing, and we omit '_' from $nsc (but not $nc) because we
+ // reserve it.
+ $nsc = 'A-Za-z\x{C0}-\x{D6}\x{D8}-\x{F6}\x{F8}-\x{2FF}\x{370}-\x{37D}\x{37F}-\x{1FFF}' .
+ '\x{200C}-\x{200D}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}' .
+ '\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}';
+ $nc = $nsc . '_\-.0-9\x{B7}\x{300}-\x{36F}\x{203F}-\x{2040}';
+ }
+
+ if ( preg_match( "/^[$nsc][$nc]*$/uS", $name ) ) {
+ return $name;
+ }
+
+ return '_' . preg_replace_callback(
+ "/[^$nc]/uS",
+ function ( $m ) {
+ return sprintf( '.%X.', utf8ToCodepoint( $m[0] ) );
+ },
+ str_replace( '.', '.2E.', $name )
+ );
+ }
+
function addXslt() {
$nt = Title::newFromText( $this->mXslt );
if ( is_null( $nt ) || !$nt->exists() ) {
@@ -237,20 +296,13 @@ class ApiFormatXml extends ApiFormatBase {
public function getAllowedParams() {
return array(
- 'xslt' => null,
- 'includexmlnamespace' => false,
+ 'xslt' => array(
+ ApiBase::PARAM_HELP_MSG => 'apihelp-xml-param-xslt',
+ ),
+ 'includexmlnamespace' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-xml-param-includexmlnamespace',
+ ),
);
}
-
- public function getParamDescription() {
- return array(
- 'xslt' => 'If specified, adds <xslt> as stylesheet. This should be a wiki page '
- . 'in the MediaWiki namespace whose page name ends with ".xsl"',
- 'includexmlnamespace' => 'If specified, adds an XML namespace'
- );
- }
-
- public function getDescription() {
- return 'Output data in XML format' . parent::getDescription();
- }
}
diff --git a/includes/api/ApiFormatYaml.php b/includes/api/ApiFormatYaml.php
index 3798f894..c9089a7d 100644
--- a/includes/api/ApiFormatYaml.php
+++ b/includes/api/ApiFormatYaml.php
@@ -40,7 +40,7 @@ class ApiFormatYaml extends ApiFormatJson {
parent::execute();
}
- public function getDescription() {
- return 'DEPRECATED! Output data in YAML format' . ApiFormatBase::getDescription();
+ public function isDeprecated() {
+ return true;
}
}
diff --git a/includes/api/ApiHelp.php b/includes/api/ApiHelp.php
index bcd6c12e..53e8c343 100644
--- a/includes/api/ApiHelp.php
+++ b/includes/api/ApiHelp.php
@@ -2,9 +2,9 @@
/**
*
*
- * Created on Sep 6, 2006
+ * Created on Aug 29, 2014
*
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,102 +25,596 @@
*/
/**
- * This is a simple class to handle action=help
+ * Class to output help for an API module
*
+ * @since 1.25 completely rewritten
* @ingroup API
*/
class ApiHelp extends ApiBase {
- /**
- * Module for displaying help
- */
public function execute() {
- // Get parameters
$params = $this->extractRequestParams();
+ $modules = array();
- if ( !isset( $params['modules'] ) && !isset( $params['querymodules'] ) ) {
- $this->dieUsage( '', 'help' );
+ foreach ( $params['modules'] as $path ) {
+ $modules[] = $this->getModuleFromPath( $path );
}
- $this->getMain()->setHelp();
- $result = $this->getResult();
+ // Get the help
+ $context = new DerivativeContext( $this->getMain()->getContext() );
+ $context->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'apioutput' ) );
+ $context->setLanguage( $this->getMain()->getLanguage() );
+ $context->setTitle( SpecialPage::getTitleFor( 'ApiHelp' ) );
+ $out = new OutputPage( $context );
+ $context->setOutput( $out );
+
+ self::getHelp( $context, $modules, $params );
- if ( is_array( $params['modules'] ) ) {
- $modules = $params['modules'];
+ // Grab the output from the skin
+ ob_start();
+ $context->getOutput()->output();
+ $html = ob_get_clean();
+
+ $result = $this->getResult();
+ if ( $params['wrap'] ) {
+ $data = array(
+ 'mime' => 'text/html',
+ 'help' => $html,
+ );
+ ApiResult::setSubelementsList( $data, 'help' );
+ $result->addValue( null, $this->getModuleName(), $data );
} else {
- $modules = array();
+ $result->reset();
+ $result->addValue( null, 'text', $html, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( null, 'mime', 'text/html', ApiResult::NO_SIZE_CHECK );
+ }
+ }
+
+ /**
+ * Generate help for the specified modules
+ *
+ * Help is placed into the OutputPage object returned by
+ * $context->getOutput().
+ *
+ * Recognized options include:
+ * - headerlevel: (int) Header tag level
+ * - nolead: (bool) Skip the inclusion of api-help-lead
+ * - noheader: (bool) Skip the inclusion of the top-level section headers
+ * - submodules: (bool) Include help for submodules of the current module
+ * - recursivesubmodules: (bool) Include help for submodules recursively
+ * - helptitle: (string) Title to link for additional modules' help. Should contain $1.
+ *
+ * @param IContextSource $context
+ * @param ApiBase[]|ApiBase $modules
+ * @param array $options Formatting options (described above)
+ * @return string
+ */
+ public static function getHelp( IContextSource $context, $modules, array $options ) {
+ global $wgMemc, $wgContLang;
+
+ if ( !is_array( $modules ) ) {
+ $modules = array( $modules );
}
- if ( is_array( $params['querymodules'] ) ) {
- $this->logFeatureUsage( 'action=help&querymodules' );
- $queryModules = $params['querymodules'];
- foreach ( $queryModules as $m ) {
- $modules[] = 'query+' . $m;
+ $out = $context->getOutput();
+ $out->addModules( 'mediawiki.apihelp' );
+ $out->setPageTitle( $context->msg( 'api-help-title' ) );
+
+ $cacheKey = null;
+ if ( count( $modules ) == 1 && $modules[0] instanceof ApiMain &&
+ $options['recursivesubmodules'] && $context->getLanguage() === $wgContLang
+ ) {
+ $cacheHelpTimeout = $context->getConfig()->get( 'APICacheHelpTimeout' );
+ if ( $cacheHelpTimeout > 0 ) {
+ // Get help text from cache if present
+ $cacheKey = wfMemcKey( 'apihelp', $modules[0]->getModulePath(),
+ str_replace( ' ', '_', SpecialVersion::getVersion( 'nodb' ) ) );
+ $cached = $wgMemc->get( $cacheKey );
+ if ( $cached ) {
+ $out->addHTML( $cached );
+ return;
+ }
}
- } else {
- $queryModules = array();
}
+ if ( $out->getHTML() !== '' ) {
+ // Don't save to cache, there's someone else's content in the page
+ // already
+ $cacheKey = null;
+ }
+
+ $options['recursivesubmodules'] = !empty( $options['recursivesubmodules'] );
+ $options['submodules'] = $options['recursivesubmodules'] || !empty( $options['submodules'] );
- $r = array();
- foreach ( $modules as $m ) {
- // sub-modules could be given in the form of "name[+name[+name...]]"
- $subNames = explode( '+', $m );
- if ( count( $subNames ) === 1 ) {
- // In case the '+' was typed into URL, it resolves as a space
- $subNames = explode( ' ', $m );
+ // Prepend lead
+ if ( empty( $options['nolead'] ) ) {
+ $msg = $context->msg( 'api-help-lead' );
+ if ( !$msg->isDisabled() ) {
+ $out->addHTML( $msg->parseAsBlock() );
}
+ }
- $module = $this->getMain();
- $subNamesCount = count( $subNames );
- for ( $i = 0; $i < $subNamesCount; $i++ ) {
- $subs = $module->getModuleManager();
- if ( $subs === null ) {
- $module = null;
- } else {
- $module = $subs->getModule( $subNames[$i] );
- }
+ $haveModules = array();
+ $out->addHTML( self::getHelpInternal( $context, $modules, $options, $haveModules ) );
- if ( $module === null ) {
- if ( count( $subNames ) === 2
- && $i === 1
- && $subNames[0] === 'query'
- && in_array( $subNames[1], $queryModules )
- ) {
- // Legacy: This is one of the renamed 'querymodule=...' parameters,
- // do not use '+' notation in the output, use submodule's name instead.
- $name = $subNames[1];
- } else {
- $name = implode( '+', array_slice( $subNames, 0, $i + 1 ) );
- }
- $r[] = array( 'name' => $name, 'missing' => '' );
- break;
+ $helptitle = isset( $options['helptitle'] ) ? $options['helptitle'] : null;
+ $html = self::fixHelpLinks( $out->getHTML(), $helptitle, $haveModules );
+ $out->clearHTML();
+ $out->addHTML( $html );
+
+ if ( $cacheKey !== null ) {
+ $wgMemc->set( $cacheKey, $out->getHTML(), $cacheHelpTimeout );
+ }
+ }
+
+ /**
+ * Replace Special:ApiHelp links with links to api.php
+ *
+ * @param string $html
+ * @param string|null $helptitle Title to link to rather than api.php, must contain '$1'
+ * @param array $localModules Modules to link within the current page
+ * @return string
+ */
+ public static function fixHelpLinks( $html, $helptitle = null, $localModules = array() ) {
+ $formatter = new HtmlFormatter( $html );
+ $doc = $formatter->getDoc();
+ $xpath = new DOMXPath( $doc );
+ $nodes = $xpath->query( '//a[@href][not(contains(@class,\'apihelp-linktrail\'))]' );
+ foreach ( $nodes as $node ) {
+ $href = $node->getAttribute( 'href' );
+ do {
+ $old = $href;
+ $href = rawurldecode( $href );
+ } while ( $old !== $href );
+ if ( preg_match( '!Special:ApiHelp/([^&/|]+)!', $href, $m ) ) {
+ if ( isset( $localModules[$m[1]] ) ) {
+ $href = '#' . $m[1];
+ } elseif ( $helptitle !== null ) {
+ $href = Title::newFromText( str_replace( '$1', $m[1], $helptitle ) )
+ ->getFullUrl();
} else {
- $type = $subs->getModuleGroup( $subNames[$i] );
+ $href = wfAppendQuery( wfScript( 'api' ), array(
+ 'action' => 'help',
+ 'modules' => $m[1],
+ ) );
}
- }
-
- if ( $module !== null ) {
- $r[] = $this->buildModuleHelp( $module, $type );
+ $node->setAttribute( 'href', $href );
+ $node->removeAttribute( 'title' );
}
}
- $result->setIndexedTagName( $r, 'module' );
- $result->addValue( null, $this->getModuleName(), $r );
+ return $formatter->getText();
}
/**
- * @param ApiBase $module
- * @param string $type What type of request is this? e.g. action, query, list, prop, meta, format
+ * Wrap a message in HTML with a class.
+ *
+ * @param Message $msg
+ * @param string $class
+ * @param string $tag
* @return string
*/
- private function buildModuleHelp( $module, $type ) {
- $msg = ApiMain::makeHelpMsgHeader( $module, $type );
+ private static function wrap( Message $msg, $class, $tag = 'span' ) {
+ return Html::rawElement( $tag, array( 'class' => $class ),
+ $msg->parse()
+ );
+ }
+
+ /**
+ * Recursively-called function to actually construct the help
+ *
+ * @param IContextSource $context
+ * @param ApiBase[] $modules
+ * @param array $options
+ * @param array &$haveModules
+ * @return string
+ */
+ private static function getHelpInternal( IContextSource $context, array $modules,
+ array $options, &$haveModules
+ ) {
+ $out = '';
+
+ $level = min( 6, empty( $options['headerlevel'] ) ? 2 : $options['headerlevel'] );
+ $options['headerlevel'] = $level;
+
+ foreach ( $modules as $module ) {
+ $haveModules[$module->getModulePath()] = true;
+ $module->setContext( $context );
+ $help = array(
+ 'header' => '',
+ 'flags' => '',
+ 'description' => '',
+ 'help-urls' => '',
+ 'parameters' => '',
+ 'examples' => '',
+ 'submodules' => '',
+ );
+
+ if ( empty( $options['noheader'] ) ) {
+ $path = $module->getModulePath();
+ if ( $module->isMain() ) {
+ $header = $context->msg( 'api-help-main-header' )->parse();
+ } else {
+ $name = $module->getModuleName();
+ $header = $module->getParent()->getModuleManager()->getModuleGroup( $name ) .
+ "=$name";
+ if ( $module->getModulePrefix() !== '' ) {
+ $header .= ' ' .
+ $context->msg( 'parentheses', $module->getModulePrefix() )->parse();
+ }
+ }
+ $help['header'] .= Html::element( "h$level",
+ array( 'id' => $path, 'class' => 'apihelp-header' ),
+ $header
+ );
+ }
+
+ $links = array();
+ $any = false;
+ for ( $m = $module; $m !== null; $m = $m->getParent() ) {
+ $name = $m->getModuleName();
+ if ( $name === 'main_int' ) {
+ $name = 'main';
+ }
- $msg2 = $module->makeHelpMsg();
- if ( $msg2 !== false ) {
- $msg .= $msg2;
+ if ( count( $modules ) === 1 && $m === $modules[0] &&
+ !( !empty( $options['submodules'] ) && $m->getModuleManager() )
+ ) {
+ $link = Html::element( 'b', null, $name );
+ } else {
+ $link = SpecialPage::getTitleFor( 'ApiHelp', $m->getModulePath() )->getLocalURL();
+ $link = Html::element( 'a',
+ array( 'href' => $link, 'class' => 'apihelp-linktrail' ),
+ $name
+ );
+ $any = true;
+ }
+ array_unshift( $links, $link );
+ }
+ if ( $any ) {
+ $help['header'] .= self::wrap(
+ $context->msg( 'parentheses' )
+ ->rawParams( $context->getLanguage()->pipeList( $links ) ),
+ 'apihelp-linktrail', 'div'
+ );
+ }
+
+ $flags = $module->getHelpFlags();
+ if ( $flags ) {
+ $help['flags'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-flags' ) );
+ $msg = $context->msg( 'api-help-flags' );
+ if ( !$msg->isDisabled() ) {
+ $help['flags'] .= self::wrap(
+ $msg->numParams( count( $flags ) ), 'apihelp-block-head', 'div'
+ );
+ }
+ $help['flags'] .= Html::openElement( 'ul' );
+ foreach ( $flags as $flag ) {
+ $help['flags'] .= Html::rawElement( 'li', null,
+ self::wrap( $context->msg( "api-help-flag-$flag" ), "apihelp-flag-$flag" )
+ );
+ }
+ $help['flags'] .= Html::closeElement( 'ul' );
+ $help['flags'] .= Html::closeElement( 'div' );
+ }
+
+ foreach ( $module->getFinalDescription() as $msg ) {
+ $msg->setContext( $context );
+ $help['description'] .= $msg->parseAsBlock();
+ }
+
+ $urls = $module->getHelpUrls();
+ if ( $urls ) {
+ $help['help-urls'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-help-urls' )
+ );
+ $msg = $context->msg( 'api-help-help-urls' );
+ if ( !$msg->isDisabled() ) {
+ $help['help-urls'] .= self::wrap(
+ $msg->numParams( count( $urls ) ), 'apihelp-block-head', 'div'
+ );
+ }
+ if ( !is_array( $urls ) ) {
+ $urls = array( $urls );
+ }
+ $help['help-urls'] .= Html::openElement( 'ul' );
+ foreach ( $urls as $url ) {
+ $help['help-urls'] .= Html::rawElement( 'li', null,
+ Html::element( 'a', array( 'href' => $url ), $url )
+ );
+ }
+ $help['help-urls'] .= Html::closeElement( 'ul' );
+ $help['help-urls'] .= Html::closeElement( 'div' );
+ }
+
+ $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
+ $groups = array();
+ if ( $params ) {
+ $help['parameters'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-parameters' )
+ );
+ $msg = $context->msg( 'api-help-parameters' );
+ if ( !$msg->isDisabled() ) {
+ $help['parameters'] .= self::wrap(
+ $msg->numParams( count( $params ) ), 'apihelp-block-head', 'div'
+ );
+ }
+ $help['parameters'] .= Html::openElement( 'dl' );
+
+ $descriptions = $module->getFinalParamDescription();
+
+ foreach ( $params as $name => $settings ) {
+ if ( !is_array( $settings ) ) {
+ $settings = array( ApiBase::PARAM_DFLT => $settings );
+ }
+
+ $help['parameters'] .= Html::element( 'dt', null,
+ $module->encodeParamName( $name ) );
+
+ // Add description
+ $description = array();
+ if ( isset( $descriptions[$name] ) ) {
+ foreach ( $descriptions[$name] as $msg ) {
+ $msg->setContext( $context );
+ $description[] = $msg->parseAsBlock();
+ }
+ }
+
+ // Add usage info
+ $info = array();
+
+ // Required?
+ if ( !empty( $settings[ApiBase::PARAM_REQUIRED] ) ) {
+ $info[] = $context->msg( 'api-help-param-required' )->parse();
+ }
+
+ // Custom info?
+ if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
+ foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
+ $tag = array_shift( $i );
+ $info[] = $context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
+ ->numParams( count( $i ) )
+ ->params( $context->getLanguage()->commaList( $i ) )
+ ->params( $module->getModulePrefix() )
+ ->parse();
+ }
+ }
+
+ // Type documentation
+ if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) {
+ $dflt = isset( $settings[ApiBase::PARAM_DFLT] )
+ ? $settings[ApiBase::PARAM_DFLT]
+ : null;
+ if ( is_bool( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'boolean';
+ } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'string';
+ } elseif ( is_int( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'integer';
+ }
+ }
+ if ( isset( $settings[ApiBase::PARAM_TYPE] ) ) {
+ $type = $settings[ApiBase::PARAM_TYPE];
+ $multi = !empty( $settings[ApiBase::PARAM_ISMULTI] );
+ $hintPipeSeparated = true;
+ $count = ApiBase::LIMIT_SML2 + 1;
+
+ if ( is_array( $type ) ) {
+ $count = count( $type );
+ $links = isset( $settings[ApiBase::PARAM_VALUE_LINKS] )
+ ? $settings[ApiBase::PARAM_VALUE_LINKS]
+ : array();
+ $type = array_map( function ( $v ) use ( $links ) {
+ $ret = wfEscapeWikiText( $v );
+ if ( isset( $links[$v] ) ) {
+ $ret = "[[{$links[$v]}|$ret]]";
+ }
+ return $ret;
+ }, $type );
+ $i = array_search( '', $type, true );
+ if ( $i === false ) {
+ $type = $context->getLanguage()->commaList( $type );
+ } else {
+ unset( $type[$i] );
+ $type = $context->msg( 'api-help-param-list-can-be-empty' )
+ ->numParams( count( $type ) )
+ ->params( $context->getLanguage()->commaList( $type ) )
+ ->parse();
+ }
+ $info[] = $context->msg( 'api-help-param-list' )
+ ->params( $multi ? 2 : 1 )
+ ->params( $type )
+ ->parse();
+ $hintPipeSeparated = false;
+ } else {
+ switch ( $type ) {
+ case 'submodule':
+ $groups[] = $name;
+ $submodules = $module->getModuleManager()->getNames( $name );
+ $count = count( $submodules );
+ sort( $submodules );
+ $prefix = $module->isMain()
+ ? '' : ( $module->getModulePath() . '+' );
+ $submodules = array_map( function ( $name ) use ( $prefix ) {
+ return "[[Special:ApiHelp/{$prefix}{$name}|{$name}]]";
+ }, $submodules );
+ $info[] = $context->msg( 'api-help-param-list' )
+ ->params( $multi ? 2 : 1 )
+ ->params( $context->getLanguage()->commaList( $submodules ) )
+ ->parse();
+ $hintPipeSeparated = false;
+ break;
+
+ case 'namespace':
+ $namespaces = MWNamespace::getValidNamespaces();
+ $count = count( $namespaces );
+ $info[] = $context->msg( 'api-help-param-list' )
+ ->params( $multi ? 2 : 1 )
+ ->params( $context->getLanguage()->commaList( $namespaces ) )
+ ->parse();
+ $hintPipeSeparated = false;
+ break;
+
+ case 'limit':
+ if ( isset( $settings[ApiBase::PARAM_MAX2] ) ) {
+ $info[] = $context->msg( 'api-help-param-limit2' )
+ ->numParams( $settings[ApiBase::PARAM_MAX] )
+ ->numParams( $settings[ApiBase::PARAM_MAX2] )
+ ->parse();
+ } else {
+ $info[] = $context->msg( 'api-help-param-limit' )
+ ->numParams( $settings[ApiBase::PARAM_MAX] )
+ ->parse();
+ }
+ break;
+
+ case 'integer':
+ // Possible messages:
+ // api-help-param-integer-min,
+ // api-help-param-integer-max,
+ // api-help-param-integer-minmax
+ $suffix = '';
+ $min = $max = 0;
+ if ( isset( $settings[ApiBase::PARAM_MIN] ) ) {
+ $suffix .= 'min';
+ $min = $settings[ApiBase::PARAM_MIN];
+ }
+ if ( isset( $settings[ApiBase::PARAM_MAX] ) ) {
+ $suffix .= 'max';
+ $max = $settings[ApiBase::PARAM_MAX];
+ }
+ if ( $suffix !== '' ) {
+ $info[] =
+ $context->msg( "api-help-param-integer-$suffix" )
+ ->params( $multi ? 2 : 1 )
+ ->numParams( $min, $max )
+ ->parse();
+ }
+ break;
+
+ case 'upload':
+ $info[] = $context->msg( 'api-help-param-upload' )
+ ->parse();
+ break;
+ }
+ }
+
+ if ( $multi ) {
+ $extra = array();
+ if ( $hintPipeSeparated ) {
+ $extra[] = $context->msg( 'api-help-param-multi-separate' )->parse();
+ }
+ if ( $count > ApiBase::LIMIT_SML1 ) {
+ $extra[] = $context->msg( 'api-help-param-multi-max' )
+ ->numParams( ApiBase::LIMIT_SML1, ApiBase::LIMIT_SML2 )
+ ->parse();
+ }
+ if ( $extra ) {
+ $info[] = join( ' ', $extra );
+ }
+ }
+ }
+
+ // Add default
+ $default = isset( $settings[ApiBase::PARAM_DFLT] )
+ ? $settings[ApiBase::PARAM_DFLT]
+ : null;
+ if ( $default === '' ) {
+ $info[] = $context->msg( 'api-help-param-default-empty' )
+ ->parse();
+ } elseif ( $default !== null && $default !== false ) {
+ $info[] = $context->msg( 'api-help-param-default' )
+ ->params( wfEscapeWikiText( $default ) )
+ ->parse();
+ }
+
+ if ( !array_filter( $description ) ) {
+ $description = array( self::wrap(
+ $context->msg( 'api-help-param-no-description' ),
+ 'apihelp-empty'
+ ) );
+ }
+
+ // Add "deprecated" flag
+ if ( !empty( $settings[ApiBase::PARAM_DEPRECATED] ) ) {
+ $help['parameters'] .= Html::openElement( 'dd',
+ array( 'class' => 'info' ) );
+ $help['parameters'] .= self::wrap(
+ $context->msg( 'api-help-param-deprecated' ),
+ 'apihelp-deprecated', 'strong'
+ );
+ $help['parameters'] .= Html::closeElement( 'dd' );
+ }
+
+ if ( $description ) {
+ $description = join( '', $description );
+ $description = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $description );
+ $help['parameters'] .= Html::rawElement( 'dd',
+ array( 'class' => 'description' ), $description );
+ }
+
+ foreach ( $info as $i ) {
+ $help['parameters'] .= Html::rawElement( 'dd', array( 'class' => 'info' ), $i );
+ }
+ }
+
+ $help['parameters'] .= Html::closeElement( 'dl' );
+ $help['parameters'] .= Html::closeElement( 'div' );
+ }
+
+ $examples = $module->getExamplesMessages();
+ if ( $examples ) {
+ $help['examples'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-examples' ) );
+ $msg = $context->msg( 'api-help-examples' );
+ if ( !$msg->isDisabled() ) {
+ $help['examples'] .= self::wrap(
+ $msg->numParams( count( $examples ) ), 'apihelp-block-head', 'div'
+ );
+ }
+
+ $help['examples'] .= Html::openElement( 'dl' );
+ foreach ( $examples as $qs => $msg ) {
+ $msg = ApiBase::makeMessage( $msg, $context, array(
+ $module->getModulePrefix(),
+ $module->getModuleName(),
+ $module->getModulePath()
+ ) );
+
+ $link = wfAppendQuery( wfScript( 'api' ), $qs );
+ $help['examples'] .= Html::rawElement( 'dt', null, $msg->parse() );
+ $help['examples'] .= Html::rawElement( 'dd', null,
+ Html::element( 'a', array( 'href' => $link ), "api.php?$qs" )
+ );
+ }
+ $help['examples'] .= Html::closeElement( 'dl' );
+ $help['examples'] .= Html::closeElement( 'div' );
+ }
+
+ if ( $options['submodules'] && $module->getModuleManager() ) {
+ $manager = $module->getModuleManager();
+ $submodules = array();
+ foreach ( $groups as $group ) {
+ $names = $manager->getNames( $group );
+ sort( $names );
+ foreach ( $names as $name ) {
+ $submodules[] = $manager->getModule( $name );
+ }
+ }
+ $help['submodules'] .= self::getHelpInternal( $context, $submodules, array(
+ 'submodules' => $options['recursivesubmodules'],
+ 'headerlevel' => $level + 1,
+ 'noheader' => false,
+ ) + $options, $haveModules );
+ }
+
+ $module->modifyHelp( $help, $options );
+
+ Hooks::run( 'APIHelpModifyOutput', array( $module, &$help, $options ) );
+
+ $out .= join( "\n", $help );
}
- return $msg;
+ return $out;
}
public function shouldCheckMaxlag() {
@@ -131,39 +625,40 @@ class ApiHelp extends ApiBase {
return false;
}
+ public function getCustomPrinter() {
+ $params = $this->extractRequestParams();
+ if ( $params['wrap'] ) {
+ return null;
+ }
+
+ $main = $this->getMain();
+ $errorPrinter = $main->createPrinterByName( $main->getParameter( 'format' ) );
+ return new ApiFormatRaw( $main, $errorPrinter );
+ }
+
public function getAllowedParams() {
return array(
'modules' => array(
- ApiBase::PARAM_ISMULTI => true
- ),
- 'querymodules' => array(
+ ApiBase::PARAM_DFLT => 'main',
ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_DEPRECATED => true
),
+ 'submodules' => false,
+ 'recursivesubmodules' => false,
+ 'wrap' => false,
+ 'toc' => false,
);
}
- public function getParamDescription() {
- return array(
- 'modules' => 'List of module names (value of the action= parameter). ' .
- 'Can specify submodules with a \'+\'',
- 'querymodules' => 'Use modules=query+value instead. List of query ' .
- 'module names (value of prop=, meta= or list= parameter)',
- );
- }
-
- public function getDescription() {
- return 'Display this help screen. Or the help screen for the specified module.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=help' => 'Whole help page',
- 'api.php?action=help&modules=protect' => 'Module (action) help page',
- 'api.php?action=help&modules=query+categorymembers'
- => 'Help for the query/categorymembers module',
- 'api.php?action=help&modules=login|query+info'
- => 'Help for the login and query/info modules',
+ 'action=help'
+ => 'apihelp-help-example-main',
+ 'action=help&recursivesubmodules=1'
+ => 'apihelp-help-example-recursive',
+ 'action=help&modules=help'
+ => 'apihelp-help-example-help',
+ 'action=help&modules=query+info|query+categorymembers'
+ => 'apihelp-help-example-query',
);
}
diff --git a/includes/api/ApiHelpParamValueMessage.php b/includes/api/ApiHelpParamValueMessage.php
new file mode 100644
index 00000000..7cf3d6ed
--- /dev/null
+++ b/includes/api/ApiHelpParamValueMessage.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ *
+ * Created on Dec 22, 2014
+ *
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Message subclass that prepends wikitext for API help.
+ *
+ * This exists so the apihelp-*-paramvalue-*-* messages don't all have to
+ * include markup wikitext while still keeping the
+ * 'APIGetParamDescriptionMessages' hook simple.
+ *
+ * @since 1.25
+ */
+class ApiHelpParamValueMessage extends Message {
+
+ protected $paramValue;
+
+ /**
+ * @see Message::__construct
+ *
+ * @param string $paramValue Parameter value being documented
+ * @param string $text Message to use.
+ * @param array $params Parameters for the message.
+ * @throws InvalidArgumentException
+ */
+ public function __construct( $paramValue, $text, $params = array() ) {
+ parent::__construct( $text, $params );
+ $this->paramValue = $paramValue;
+ }
+
+ /**
+ * Fetch the parameter value
+ * @return string
+ */
+ public function getParamValue() {
+ return $this->paramValue;
+ }
+
+ /**
+ * Fetch the message.
+ * @return string
+ */
+ public function fetchMessage() {
+ if ( $this->message === null ) {
+ $this->message = ";{$this->paramValue}:" . parent::fetchMessage();
+ }
+ return $this->message;
+ }
+
+}
diff --git a/includes/api/ApiImageRotate.php b/includes/api/ApiImageRotate.php
index 20396dd7..865d39fa 100644
--- a/includes/api/ApiImageRotate.php
+++ b/includes/api/ApiImageRotate.php
@@ -42,7 +42,7 @@ class ApiImageRotate extends ApiBase {
$v = $val;
}
if ( $flag !== null ) {
- $v[$flag] = '';
+ $v[$flag] = true;
}
$result[] = $v;
}
@@ -52,7 +52,8 @@ class ApiImageRotate extends ApiBase {
$params = $this->extractRequestParams();
$rotation = $params['rotation'];
- $this->getResult()->beginContinuation( $params['continue'], array(), array() );
+ $continuationManager = new ApiContinuationManager( $this, array(), array() );
+ $this->setContinuationManager( $continuationManager );
$pageSet = $this->getPageSet();
$pageSet->execute();
@@ -70,10 +71,10 @@ class ApiImageRotate extends ApiBase {
$r['id'] = $title->getArticleID();
ApiQueryBase::addTitleInfo( $r, $title );
if ( !$title->exists() ) {
- $r['missing'] = '';
+ $r['missing'] = true;
}
- $file = wfFindFile( $title );
+ $file = wfFindFile( $title, array( 'latest' => true ) );
if ( !$file ) {
$r['result'] = 'Failure';
$r['errormessage'] = 'File does not exist';
@@ -122,7 +123,7 @@ class ApiImageRotate extends ApiBase {
$r['result'] = 'Success';
} else {
$r['result'] = 'Failure';
- $r['errormessage'] = $this->getResult()->convertStatusToArray( $status );
+ $r['errormessage'] = $this->getErrorFormatter()->arrayFromStatus( $status );
}
} else {
$r['result'] = 'Failure';
@@ -131,9 +132,11 @@ class ApiImageRotate extends ApiBase {
$result[] = $r;
}
$apiResult = $this->getResult();
- $apiResult->setIndexedTagName( $result, 'page' );
+ ApiResult::setIndexedTagName( $result, 'page' );
$apiResult->addValue( null, $this->getModuleName(), $result );
- $apiResult->endContinuation();
+
+ $this->setContinuationManager( null );
+ $continuationManager->setContinuationIntoResult( $apiResult );
}
/**
@@ -184,7 +187,9 @@ class ApiImageRotate extends ApiBase {
ApiBase::PARAM_TYPE => array( '90', '180', '270' ),
ApiBase::PARAM_REQUIRED => true
),
- 'continue' => '',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
if ( $flags ) {
$result += $this->getPageSet()->getFinalParams( $flags );
@@ -193,26 +198,17 @@ class ApiImageRotate extends ApiBase {
return $result;
}
- public function getParamDescription() {
- $pageSet = $this->getPageSet();
-
- return $pageSet->getFinalParamDescription() + array(
- 'rotation' => 'Degrees to rotate image clockwise',
- 'continue' => 'When more results are available, use this to continue',
- );
- }
-
- public function getDescription() {
- return 'Rotate one or more images.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=imagerotate&titles=Example.jpg&rotation=90&token=123ABC',
+ 'action=imagerotate&titles=File:Example.jpg&rotation=90&token=123ABC'
+ => 'apihelp-imagerotate-example-simple',
+ 'action=imagerotate&generator=categorymembers&gcmtitle=Category:Flip&gcmtype=file&' .
+ 'rotation=180&token=123ABC'
+ => 'apihelp-imagerotate-example-generator',
);
}
}
diff --git a/includes/api/ApiImport.php b/includes/api/ApiImport.php
index b11348e5..2e87d22d 100644
--- a/includes/api/ApiImport.php
+++ b/includes/api/ApiImport.php
@@ -60,7 +60,7 @@ class ApiImport extends ApiBase {
$this->dieStatus( $source );
}
- $importer = new WikiImporter( $source->value );
+ $importer = new WikiImporter( $source->value, $this->getConfig() );
if ( isset( $params['namespace'] ) ) {
$importer->setTargetNamespace( $params['namespace'] );
}
@@ -79,13 +79,13 @@ class ApiImport extends ApiBase {
try {
$importer->doImport();
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
$this->dieUsageMsg( array( 'import-unknownerror', $e->getMessage() ) );
}
$resultData = $reporter->getData();
$result = $this->getResult();
- $result->setIndexedTagName( $resultData, 'page' );
+ ApiResult::setIndexedTagName( $resultData, 'page' );
$result->addValue( null, $this->getModuleName(), $resultData );
}
@@ -116,36 +116,15 @@ class ApiImport extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'summary' => 'Import summary',
- 'xml' => 'Uploaded XML file',
- 'interwikisource' => 'For interwiki imports: wiki to import from',
- 'interwikipage' => 'For interwiki imports: page to import',
- 'fullhistory' => 'For interwiki imports: import the full history, not just the current version',
- 'templates' => 'For interwiki imports: import all included templates as well',
- 'namespace' => 'For interwiki imports: import to this namespace',
- 'rootpage' => 'Import as subpage of this page',
- );
- }
-
- public function getDescription() {
- return array(
- 'Import a page from another wiki, or an XML file.',
- 'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
- 'sending a file for the "xml" parameter.'
- );
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=import&interwikisource=meta&interwikipage=Help:ParserFunctions&' .
+ 'action=import&interwikisource=meta&interwikipage=Help:ParserFunctions&' .
'namespace=100&fullhistory=&token=123ABC'
- => 'Import [[meta:Help:Parserfunctions]] to namespace 100 with full history',
+ => 'apihelp-import-example-import',
);
}
@@ -176,7 +155,7 @@ class ApiImportReporter extends ImportReporter {
if ( $title === null ) {
# Invalid or non-importable title
$r['title'] = $pageInfo['title'];
- $r['invalid'] = '';
+ $r['invalid'] = true;
} else {
ApiQueryBase::addTitleInfo( $r, $title );
$r['revisions'] = intval( $successCount );
diff --git a/includes/api/ApiLogin.php b/includes/api/ApiLogin.php
index 976f4c12..5480d940 100644
--- a/includes/api/ApiLogin.php
+++ b/includes/api/ApiLogin.php
@@ -46,11 +46,12 @@ class ApiLogin extends ApiBase {
* is reached. The expiry is $this->mLoginThrottle.
*/
public function execute() {
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
$this->getResult()->addValue( null, 'login', array(
'result' => 'Aborted',
- 'reason' => 'Cannot log in when using a callback',
+ 'reason' => 'Cannot log in when the same-origin policy is not applied',
) );
return;
@@ -92,7 +93,7 @@ class ApiLogin extends ApiBase {
// @todo FIXME: Split back and frontend from this hook.
// @todo FIXME: This hook should be placed in the backend
$injected_html = '';
- wfRunHooks( 'UserLoginComplete', array( &$user, &$injected_html ) );
+ Hooks::run( 'UserLoginComplete', array( &$user, &$injected_html ) );
$result['result'] = 'Success';
$result['lguserid'] = intval( $user->getId() );
@@ -184,28 +185,12 @@ class ApiLogin extends ApiBase {
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'name' => 'User Name',
- 'password' => 'Password',
- 'domain' => 'Domain (optional)',
- 'token' => 'Login token obtained in first request',
- );
- }
-
- public function getDescription() {
- return array(
- 'Log in and get the authentication tokens.',
- 'In the event of a successful log-in, a cookie will be attached to your session.',
- 'In the event of a failed log-in, you will not be able to attempt another log-in',
- 'through this method for 5 seconds. This is to prevent password guessing by',
- 'automated password crackers.'
- );
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=login&lgname=user&lgpassword=password'
+ 'action=login&lgname=user&lgpassword=password'
+ => 'apihelp-login-example-gettoken',
+ 'action=login&lgname=user&lgpassword=password&lgtoken=123ABC'
+ => 'apihelp-login-example-login',
);
}
diff --git a/includes/api/ApiLogout.php b/includes/api/ApiLogout.php
index 324f4b2f..bf0ca9c6 100644
--- a/includes/api/ApiLogout.php
+++ b/includes/api/ApiLogout.php
@@ -39,28 +39,17 @@ class ApiLogout extends ApiBase {
// Give extensions to do something after user logout
$injected_html = '';
- wfRunHooks( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
+ Hooks::run( 'UserLogoutComplete', array( &$user, &$injected_html, $oldName ) );
}
public function isReadMode() {
return false;
}
- public function getAllowedParams() {
- return array();
- }
-
- public function getParamDescription() {
- return array();
- }
-
- public function getDescription() {
- return 'Log out and clear session data.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=logout' => 'Log the current user out',
+ 'action=logout'
+ => 'apihelp-logout-example-logout',
);
}
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index 119d7b48..3bf066cf 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -42,7 +42,7 @@ class ApiMain extends ApiBase {
/**
* When no format parameter is given, this format will be used
*/
- const API_DEFAULT_FORMAT = 'xmlfm';
+ const API_DEFAULT_FORMAT = 'jsonfm';
/**
* List of available modules: action name => module class
@@ -54,6 +54,7 @@ class ApiMain extends ApiBase {
'query' => 'ApiQuery',
'expandtemplates' => 'ApiExpandTemplates',
'parse' => 'ApiParse',
+ 'stashedit' => 'ApiStashEdit',
'opensearch' => 'ApiOpenSearch',
'feedcontributions' => 'ApiFeedContributions',
'feedrecentchanges' => 'ApiFeedRecentChanges',
@@ -63,6 +64,7 @@ class ApiMain extends ApiBase {
'rsd' => 'ApiRsd',
'compare' => 'ApiComparePages',
'tokens' => 'ApiTokens',
+ 'checktoken' => 'ApiCheckToken',
// Write modules
'purge' => 'ApiPurge',
@@ -86,6 +88,8 @@ class ApiMain extends ApiBase {
'options' => 'ApiOptions',
'imagerotate' => 'ApiImageRotate',
'revisiondelete' => 'ApiRevisionDelete',
+ 'managetags' => 'ApiManageTags',
+ 'tag' => 'ApiTag',
);
/**
@@ -121,11 +125,11 @@ class ApiMain extends ApiBase {
*/
private static $mRights = array(
'writeapi' => array(
- 'msg' => 'Use of the write API',
+ 'msg' => 'right-writeapi',
'params' => array()
),
'apihighlimits' => array(
- 'msg' => 'Use higher limits in API queries (Slow queries: $1 results; Fast queries: $2 results). The limits for slow queries also apply to multivalue parameters.',
+ 'msg' => 'api-help-right-apihighlimits',
'params' => array( ApiBase::LIMIT_SML2, ApiBase::LIMIT_BIG2 )
)
);
@@ -136,7 +140,7 @@ class ApiMain extends ApiBase {
*/
private $mPrinter;
- private $mModuleMgr, $mResult;
+ private $mModuleMgr, $mResult, $mErrorFormatter, $mContinuationManager;
private $mAction;
private $mEnableWrite;
private $mInternalMode, $mSquidMaxage, $mModule;
@@ -178,15 +182,33 @@ class ApiMain extends ApiBase {
// Remove all modules other than login
global $wgUser;
- if ( $this->getVal( 'callback' ) !== null ) {
- // JSON callback allows cross-site reads.
- // For safety, strip user credentials.
- wfDebug( "API: stripping user credentials for JSON callback\n" );
+ if ( $this->lacksSameOriginSecurity() ) {
+ // If we're in a mode that breaks the same-origin policy, strip
+ // user credentials for security.
+ wfDebug( "API: stripping user credentials when the same-origin policy is not applied\n" );
$wgUser = new User();
$this->getContext()->setUser( $wgUser );
}
}
+ $uselang = $this->getParameter( 'uselang' );
+ if ( $uselang === 'user' ) {
+ // Assume the parent context is going to return the user language
+ // for uselang=user (see T85635).
+ } else {
+ if ( $uselang === 'content' ) {
+ global $wgContLang;
+ $uselang = $wgContLang->getCode();
+ }
+ $code = RequestContext::sanitizeLangCode( $uselang );
+ $this->getContext()->setLanguage( $code );
+ if ( !$this->mInternalMode ) {
+ global $wgLang;
+ $wgLang = $this->getContext()->getLanguage();
+ RequestContext::getMain()->setLanguage( $wgLang );
+ }
+ }
+
$config = $this->getConfig();
$this->mModuleMgr = new ApiModuleManager( $this );
$this->mModuleMgr->addModules( self::$Modules, 'action' );
@@ -194,7 +216,13 @@ class ApiMain extends ApiBase {
$this->mModuleMgr->addModules( self::$Formats, 'format' );
$this->mModuleMgr->addModules( $config->get( 'APIFormatModules' ), 'format' );
- $this->mResult = new ApiResult( $this );
+ Hooks::run( 'ApiMain::moduleManager', array( $this->mModuleMgr ) );
+
+ $this->mResult = new ApiResult( $this->getConfig()->get( 'APIMaxResultSize' ) );
+ $this->mErrorFormatter = new ApiErrorFormatter_BackCompat( $this->mResult );
+ $this->mResult->setErrorFormatter( $this->mErrorFormatter );
+ $this->mResult->setMainForContinuation( $this );
+ $this->mContinuationManager = null;
$this->mEnableWrite = $enableWrite;
$this->mSquidMaxage = -1; // flag for executeActionWithErrorHandling()
@@ -219,6 +247,43 @@ class ApiMain extends ApiBase {
}
/**
+ * Get the ApiErrorFormatter object associated with current request
+ * @return ApiErrorFormatter
+ */
+ public function getErrorFormatter() {
+ return $this->mErrorFormatter;
+ }
+
+ /**
+ * Get the continuation manager
+ * @return ApiContinuationManager|null
+ */
+ public function getContinuationManager() {
+ return $this->mContinuationManager;
+ }
+
+ /**
+ * Set the continuation manager
+ * @param ApiContinuationManager|null
+ */
+ public function setContinuationManager( $manager ) {
+ if ( $manager !== null ) {
+ if ( !$manager instanceof ApiContinuationManager ) {
+ throw new InvalidArgumentException( __METHOD__ . ': Was passed ' .
+ is_object( $manager ) ? get_class( $manager ) : gettype( $manager )
+ );
+ }
+ if ( $this->mContinuationManager !== null ) {
+ throw new UnexpectedValueException(
+ __METHOD__ . ': tried to set manager from ' . $manager->getSource() .
+ ' when a manager is already set from ' . $this->mContinuationManager->getSource()
+ );
+ }
+ }
+ $this->mContinuationManager = $manager;
+ }
+
+ /**
* Get the API module object. Only works after executeAction()
*
* @return ApiBase
@@ -290,6 +355,16 @@ class ApiMain extends ApiBase {
}
}
+ if ( $mode === 'public' && $this->getParameter( 'uselang' ) === 'user' ) {
+ // User language is used for i18n, so we don't want to publicly
+ // cache. Anons are ok, because if they have non-default language
+ // then there's an appropriate Vary header set by whatever set
+ // their non-default language.
+ wfDebug( __METHOD__ . ": downgrading cache mode 'public' to " .
+ "'anon-public-user-private' due to uselang=user\n" );
+ $mode = 'anon-public-user-private';
+ }
+
wfDebug( __METHOD__ . ": setting cache mode $mode\n" );
$this->mCacheMode = $mode;
}
@@ -328,14 +403,11 @@ class ApiMain extends ApiBase {
* Execute api request. Any errors will be handled if the API was called by the remote client.
*/
public function execute() {
- $this->profileIn();
if ( $this->mInternalMode ) {
$this->executeAction();
} else {
$this->executeActionWithErrorHandling();
}
-
- $this->profileOut();
}
/**
@@ -373,10 +445,6 @@ class ApiMain extends ApiBase {
// avoid sending public cache headers for errors.
$this->sendCacheHeaders();
- if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) {
- echo wfReportTime();
- }
-
ob_end_flush();
}
@@ -390,11 +458,17 @@ class ApiMain extends ApiBase {
// Bug 63145: Rollback any open database transactions
if ( !( $e instanceof UsageException ) ) {
// UsageExceptions are intentional, so don't rollback if that's the case
- MWExceptionHandler::rollbackMasterChangesAndLog( $e );
+ try {
+ MWExceptionHandler::rollbackMasterChangesAndLog( $e );
+ } catch ( DBError $e2 ) {
+ // Rollback threw an exception too. Log it, but don't interrupt
+ // our regularly scheduled exception handling.
+ MWExceptionHandler::logException( $e2 );
+ }
}
// Allow extra cleanup and logging
- wfRunHooks( 'ApiMain::onException', array( $this, $e ) );
+ Hooks::run( 'ApiMain::onException', array( $this, $e ) );
// Log it
if ( !( $e instanceof UsageException ) ) {
@@ -421,9 +495,22 @@ class ApiMain extends ApiBase {
// Reset and print just the error message
ob_clean();
- // If the error occurred during printing, do a printer->profileOut()
- $this->mPrinter->safeProfileOut();
- $this->printResult( true );
+ // Printer may not be initialized if the extractRequestParams() fails for the main module
+ $this->createErrorPrinter();
+
+ try {
+ $this->printResult( true );
+ } catch ( UsageException $ex ) {
+ // The error printer itself is failing. Try suppressing its request
+ // parameters and redo.
+ $this->setWarning(
+ 'Error printer failed (will retry without params): ' . $ex->getMessage()
+ );
+ $this->mPrinter = null;
+ $this->createErrorPrinter();
+ $this->mPrinter->forceDefaultParams();
+ $this->printResult( true );
+ }
}
/**
@@ -434,6 +521,7 @@ class ApiMain extends ApiBase {
*
* @since 1.23
* @param Exception $e
+ * @throws Exception
*/
public static function handleApiBeforeMainException( Exception $e ) {
ob_start();
@@ -462,6 +550,8 @@ class ApiMain extends ApiBase {
* If the parameter and the header do match, the header is checked against $wgCrossSiteAJAXdomains
* and $wgCrossSiteAJAXdomainExceptions, and if the origin qualifies, the appropriate CORS
* headers are set.
+ * http://www.w3.org/TR/cors/#resource-requests
+ * http://www.w3.org/TR/cors/#resource-preflight-requests
*
* @return bool False if the caller should abort (403 case), true otherwise (all other cases)
*/
@@ -474,12 +564,14 @@ class ApiMain extends ApiBase {
$request = $this->getRequest();
$response = $request->response();
+
// Origin: header is a space-separated list of origins, check all of them
$originHeader = $request->getHeader( 'Origin' );
if ( $originHeader === false ) {
$origins = array();
} else {
- $origins = explode( ' ', $originHeader );
+ $originHeader = trim( $originHeader );
+ $origins = preg_split( '/\s+/', $originHeader );
}
if ( !in_array( $originParam, $origins ) ) {
@@ -494,18 +586,44 @@ class ApiMain extends ApiBase {
}
$config = $this->getConfig();
- $matchOrigin = self::matchOrigin(
+ $matchOrigin = count( $origins ) === 1 && self::matchOrigin(
$originParam,
$config->get( 'CrossSiteAJAXdomains' ),
$config->get( 'CrossSiteAJAXdomainExceptions' )
);
if ( $matchOrigin ) {
- $response->header( "Access-Control-Allow-Origin: $originParam" );
+ $requestedMethod = $request->getHeader( 'Access-Control-Request-Method' );
+ $preflight = $request->getMethod() === 'OPTIONS' && $requestedMethod !== false;
+ if ( $preflight ) {
+ // This is a CORS preflight request
+ if ( $requestedMethod !== 'POST' && $requestedMethod !== 'GET' ) {
+ // If method is not a case-sensitive match, do not set any additional headers and terminate.
+ return true;
+ }
+ // We allow the actual request to send the following headers
+ $requestedHeaders = $request->getHeader( 'Access-Control-Request-Headers' );
+ if ( $requestedHeaders !== false ) {
+ if ( !self::matchRequestedHeaders( $requestedHeaders ) ) {
+ return true;
+ }
+ $response->header( 'Access-Control-Allow-Headers: ' . $requestedHeaders );
+ }
+
+ // We only allow the actual request to be GET or POST
+ $response->header( 'Access-Control-Allow-Methods: POST, GET' );
+ }
+
+ $response->header( "Access-Control-Allow-Origin: $originHeader" );
$response->header( 'Access-Control-Allow-Credentials: true' );
- $this->getOutput()->addVaryHeader( 'Origin' );
+ $response->header( "Timing-Allow-Origin: $originHeader" ); # http://www.w3.org/TR/resource-timing/#timing-allow-origin
+
+ if ( !$preflight ) {
+ $response->header( 'Access-Control-Expose-Headers: MediaWiki-API-Error, Retry-After, X-Database-Lag' );
+ }
}
+ $this->getOutput()->addVaryHeader( 'Origin' );
return true;
}
@@ -535,6 +653,41 @@ class ApiMain extends ApiBase {
}
/**
+ * Attempt to validate the value of Access-Control-Request-Headers against a list
+ * of headers that we allow the follow up request to send.
+ *
+ * @param string $requestedHeaders Comma seperated list of HTTP headers
+ * @return bool True if all requested headers are in the list of allowed headers
+ */
+ protected static function matchRequestedHeaders( $requestedHeaders ) {
+ if ( trim( $requestedHeaders ) === '' ) {
+ return true;
+ }
+ $requestedHeaders = explode( ',', $requestedHeaders );
+ $allowedAuthorHeaders = array_flip( array(
+ /* simple headers (see spec) */
+ 'accept',
+ 'accept-language',
+ 'content-language',
+ 'content-type',
+ /* non-authorable headers in XHR, which are however requested by some UAs */
+ 'accept-encoding',
+ 'dnt',
+ 'origin',
+ /* MediaWiki whitelist */
+ 'api-user-agent',
+ ) );
+ foreach ( $requestedHeaders as $rHeader ) {
+ $rHeader = strtolower( trim( $rHeader ) );
+ if ( !isset( $allowedAuthorHeaders[$rHeader] ) ) {
+ wfDebugLog( 'api', 'CORS preflight failed on requested header: ' . $rHeader );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Helper function to convert wildcard string into a regex
* '*' => '.*?'
* '?' => '.'
@@ -563,8 +716,24 @@ class ApiMain extends ApiBase {
$out->addVaryHeader( 'X-Forwarded-Proto' );
}
+ // The logic should be:
+ // $this->mCacheControl['max-age'] is set?
+ // Use it, the module knows better than our guess.
+ // !$this->mModule || $this->mModule->isWriteMode(), and mCacheMode is private?
+ // Use 0 because we can guess caching is probably the wrong thing to do.
+ // Use $this->getParameter( 'maxage' ), which already defaults to 0.
+ $maxage = 0;
+ if ( isset( $this->mCacheControl['max-age'] ) ) {
+ $maxage = $this->mCacheControl['max-age'];
+ } elseif ( ( $this->mModule && !$this->mModule->isWriteMode() ) ||
+ $this->mCacheMode !== 'private'
+ ) {
+ $maxage = $this->getParameter( 'maxage' );
+ }
+ $privateCache = 'private, must-revalidate, max-age=' . $maxage;
+
if ( $this->mCacheMode == 'private' ) {
- $response->header( 'Cache-Control: private' );
+ $response->header( "Cache-Control: $privateCache" );
return;
}
@@ -576,14 +745,14 @@ class ApiMain extends ApiBase {
$response->header( $out->getXVO() );
if ( $out->haveCacheVaryCookies() ) {
// Logged in, mark this request private
- $response->header( 'Cache-Control: private' );
+ $response->header( "Cache-Control: $privateCache" );
return;
}
// Logged out, send normal public headers below
} elseif ( session_id() != '' ) {
// Logged in or otherwise has session (e.g. anonymous users who have edited)
// Mark request private
- $response->header( 'Cache-Control: private' );
+ $response->header( "Cache-Control: $privateCache" );
return;
} // else no XVO and anonymous, send public headers below
@@ -607,7 +776,7 @@ class ApiMain extends ApiBase {
// Public cache not requested
// Sending a Vary header in this case is harmless, and protects us
// against conditional calls of setCacheMaxAge().
- $response->header( 'Cache-Control: private' );
+ $response->header( "Cache-Control: $privateCache" );
return;
}
@@ -638,45 +807,39 @@ class ApiMain extends ApiBase {
}
/**
- * Replace the result data with the information about an exception.
- * Returns the error code
- * @param Exception $e
- * @return string
+ * Create the printer for error output
*/
- protected function substituteResultWithError( $e ) {
- $result = $this->getResult();
-
- // Printer may not be initialized if the extractRequestParams() fails for the main module
+ private function createErrorPrinter() {
if ( !isset( $this->mPrinter ) ) {
- // The printer has not been created yet. Try to manually get formatter value.
$value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT );
if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) {
$value = self::API_DEFAULT_FORMAT;
}
-
$this->mPrinter = $this->createPrinterByName( $value );
}
// Printer may not be able to handle errors. This is particularly
// likely if the module returns something for getCustomPrinter().
if ( !$this->mPrinter->canPrintErrors() ) {
- $this->mPrinter->safeProfileOut();
$this->mPrinter = $this->createPrinterByName( self::API_DEFAULT_FORMAT );
}
+ }
- // Update raw mode flag for the selected printer.
- $result->setRawMode( $this->mPrinter->getNeedsRawData() );
-
+ /**
+ * Replace the result data with the information about an exception.
+ * Returns the error code
+ * @param Exception $e
+ * @return string
+ */
+ protected function substituteResultWithError( $e ) {
+ $result = $this->getResult();
$config = $this->getConfig();
if ( $e instanceof UsageException ) {
- // User entered incorrect parameters - print usage screen
+ // User entered incorrect parameters - generate error response
$errMessage = $e->getMessageArray();
-
- // Only print the help message when this is for the developer, not runtime
- if ( $this->mPrinter->getWantsHelp() || $this->mAction == 'help' ) {
- ApiResult::setContent( $errMessage, $this->makeHelpMsg() );
- }
+ $link = wfExpandUrl( wfScript( 'api' ) );
+ ApiResult::setContentValue( $errMessage, 'docref', "See $link for API usage" );
} else {
// Something is seriously wrong
if ( ( $e instanceof DBQueryError ) && !$config->get( 'ShowSQLErrors' ) ) {
@@ -687,17 +850,19 @@ class ApiMain extends ApiBase {
$errMessage = array(
'code' => 'internal_api_error_' . get_class( $e ),
- 'info' => $info,
- );
- ApiResult::setContent(
- $errMessage,
- $config->get( 'ShowExceptionDetails' ) ? "\n\n{$e->getTraceAsString()}\n\n" : ''
+ 'info' => '[' . MWExceptionHandler::getLogId( $e ) . '] ' . $info,
);
+ if ( $config->get( 'ShowExceptionDetails' ) ) {
+ ApiResult::setContentValue(
+ $errMessage,
+ 'trace',
+ MWExceptionHandler::getRedactedTraceAsString( $e )
+ );
+ }
}
// Remember all the warnings to re-add them later
- $oldResult = $result->getData();
- $warnings = isset( $oldResult['warnings'] ) ? $oldResult['warnings'] : null;
+ $warnings = $result->getResultData( array( 'warnings' ) );
$result->reset();
// Re-add the id
@@ -756,6 +921,8 @@ class ApiMain extends ApiBase {
/**
* Set up the module for response
* @return ApiBase The module that will handle this action
+ * @throws MWException
+ * @throws UsageException
*/
protected function setupModule() {
// Instantiate the module requested by the user
@@ -856,7 +1023,7 @@ class ApiMain extends ApiBase {
// Allow extensions to stop execution for arbitrary reasons.
$message = false;
- if ( !wfRunHooks( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
+ if ( !Hooks::run( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
$this->dieUsageMsg( $message );
}
}
@@ -928,10 +1095,8 @@ class ApiMain extends ApiBase {
$this->checkAsserts( $params );
// Execute
- $module->profileIn();
$module->execute();
- wfRunHooks( 'APIAfterExecute', array( &$module ) );
- $module->profileOut();
+ Hooks::run( 'APIAfterExecute', array( &$module ) );
$this->reportUnusedParams();
@@ -1080,23 +1245,10 @@ class ApiMain extends ApiBase {
$this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
}
- $this->getResult()->cleanUpUTF8();
$printer = $this->mPrinter;
- $printer->profileIn();
-
- /**
- * If the help message is requested in the default (xmlfm) format,
- * tell the printer not to escape ampersands so that our links do
- * not break.
- */
- $isHelp = $isError || $this->mAction == 'help';
- $printer->setUnescapeAmps( $isHelp && $printer->getFormat() == 'XML' && $printer->getIsHtml() );
-
- $printer->initPrinter( $isHelp );
-
+ $printer->initPrinter( false );
$printer->execute();
$printer->closePrinter();
- $printer->profileOut();
}
/**
@@ -1113,14 +1265,14 @@ class ApiMain extends ApiBase {
*/
public function getAllowedParams() {
return array(
- 'format' => array(
- ApiBase::PARAM_DFLT => ApiMain::API_DEFAULT_FORMAT,
- ApiBase::PARAM_TYPE => 'submodule',
- ),
'action' => array(
ApiBase::PARAM_DFLT => 'help',
ApiBase::PARAM_TYPE => 'submodule',
),
+ 'format' => array(
+ ApiBase::PARAM_DFLT => ApiMain::API_DEFAULT_FORMAT,
+ ApiBase::PARAM_TYPE => 'submodule',
+ ),
'maxlag' => array(
ApiBase::PARAM_TYPE => 'integer'
),
@@ -1139,126 +1291,136 @@ class ApiMain extends ApiBase {
'servedby' => false,
'curtimestamp' => false,
'origin' => null,
+ 'uselang' => array(
+ ApiBase::PARAM_DFLT => 'user',
+ ),
);
}
- /**
- * See ApiBase for description.
- *
- * @return array
- */
- public function getParamDescription() {
+ /** @see ApiBase::getExamplesMessages() */
+ protected function getExamplesMessages() {
return array(
- 'format' => 'The format of the output',
- 'action' => 'What action you would like to perform. See below for module help',
- 'maxlag' => array(
- 'Maximum lag can be used when MediaWiki is installed on a database replicated cluster.',
- 'To save actions causing any more site replication lag, this parameter can make the client',
- 'wait until the replication lag is less than the specified value.',
- 'In case of a replag error, error code "maxlag" is returned, with the message like',
- '"Waiting for $host: $lag seconds lagged\n".',
- 'See https://www.mediawiki.org/wiki/Manual:Maxlag_parameter for more information',
- ),
- 'smaxage' => 'Set the s-maxage header to this many seconds. Errors are never cached',
- 'maxage' => 'Set the max-age header to this many seconds. Errors are never cached',
- 'assert' => 'Verify the user is logged in if set to "user", or has the bot userright if "bot"',
- 'requestid' => 'Request ID to distinguish requests. This will just be output back to you',
- 'servedby' => 'Include the hostname that served the request in the ' .
- 'results. Unconditionally shown on error',
- 'curtimestamp' => 'Include the current timestamp in the result.',
- 'origin' => array(
- 'When accessing the API using a cross-domain AJAX request (CORS), set this to the',
- 'originating domain. This must be included in any pre-flight request, and',
- 'therefore must be part of the request URI (not the POST body). This must match',
- 'one of the origins in the Origin: header exactly, so it has to be set to ',
- 'something like http://en.wikipedia.org or https://meta.wikimedia.org . If this',
- 'parameter does not match the Origin: header, a 403 response will be returned. If',
- 'this parameter matches the Origin: header and the origin is whitelisted, an',
- 'Access-Control-Allow-Origin header will be set.',
- ),
+ 'action=help'
+ => 'apihelp-help-example-main',
+ 'action=help&recursivesubmodules=1'
+ => 'apihelp-help-example-recursive',
);
}
+ public function modifyHelp( array &$help, array $options ) {
+ // Wish PHP had an "array_insert_before". Instead, we have to manually
+ // reindex the array to get 'permissions' in the right place.
+ $oldHelp = $help;
+ $help = array();
+ foreach ( $oldHelp as $k => $v ) {
+ if ( $k === 'submodules' ) {
+ $help['permissions'] = '';
+ }
+ $help[$k] = $v;
+ }
+ $help['credits'] = '';
+
+ // Fill 'permissions'
+ $help['permissions'] .= Html::openElement( 'div',
+ array( 'class' => 'apihelp-block apihelp-permissions' ) );
+ $m = $this->msg( 'api-help-permissions' );
+ if ( !$m->isDisabled() ) {
+ $help['permissions'] .= Html::rawElement( 'div', array( 'class' => 'apihelp-block-head' ),
+ $m->numParams( count( self::$mRights ) )->parse()
+ );
+ }
+ $help['permissions'] .= Html::openElement( 'dl' );
+ foreach ( self::$mRights as $right => $rightMsg ) {
+ $help['permissions'] .= Html::element( 'dt', null, $right );
+
+ $rightMsg = $this->msg( $rightMsg['msg'], $rightMsg['params'] )->parse();
+ $help['permissions'] .= Html::rawElement( 'dd', null, $rightMsg );
+
+ $groups = array_map( function ( $group ) {
+ return $group == '*' ? 'all' : $group;
+ }, User::getGroupsWithPermission( $right ) );
+
+ $help['permissions'] .= Html::rawElement( 'dd', null,
+ $this->msg( 'api-help-permissions-granted-to' )
+ ->numParams( count( $groups ) )
+ ->params( $this->getLanguage()->commaList( $groups ) )
+ ->parse()
+ );
+ }
+ $help['permissions'] .= Html::closeElement( 'dl' );
+ $help['permissions'] .= Html::closeElement( 'div' );
+
+ // Fill 'credits', if applicable
+ if ( empty( $options['nolead'] ) ) {
+ $help['credits'] .= Html::element( 'h' . min( 6, $options['headerlevel'] + 1 ),
+ array( 'id' => '+credits', 'class' => 'apihelp-header' ),
+ $this->msg( 'api-credits-header' )->parse()
+ );
+ $help['credits'] .= $this->msg( 'api-credits' )->useDatabase( false )->parseAsBlock();
+ }
+ }
+
+ private $mCanApiHighLimits = null;
+
/**
- * See ApiBase for description.
- *
- * @return array
+ * Check whether the current user is allowed to use high limits
+ * @return bool
*/
- public function getDescription() {
- return array(
- '',
- '',
- '**********************************************************************************************',
- '** **',
- '** This is an auto-generated MediaWiki API documentation page **',
- '** **',
- '** Documentation and Examples: **',
- '** https://www.mediawiki.org/wiki/API **',
- '** **',
- '**********************************************************************************************',
- '',
- 'Status: All features shown on this page should be working, but the API',
- ' is still in active development, and may change at any time.',
- ' Make sure to monitor our mailing list for any updates.',
- '',
- 'Erroneous requests: When erroneous requests are sent to the API, a HTTP header will be sent',
- ' with the key "MediaWiki-API-Error" and then both the value of the',
- ' header and the error code sent back will be set to the same value.',
- '',
- ' In the case of an invalid action being passed, these will have a value',
- ' of "unknown_action".',
- '',
- ' For more information see https://www.mediawiki.org' .
- '/wiki/API:Errors_and_warnings',
- '',
- 'Documentation: https://www.mediawiki.org/wiki/API:Main_page',
- 'FAQ https://www.mediawiki.org/wiki/API:FAQ',
- 'Mailing list: https://lists.wikimedia.org/mailman/listinfo/mediawiki-api',
- 'Api Announcements: https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce',
- 'Bugs & Requests: https://bugzilla.wikimedia.org/buglist.cgi?component=API&' .
- 'bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts',
- '',
- '',
- '',
- '',
- '',
- );
+ public function canApiHighLimits() {
+ if ( !isset( $this->mCanApiHighLimits ) ) {
+ $this->mCanApiHighLimits = $this->getUser()->isAllowed( 'apihighlimits' );
+ }
+
+ return $this->mCanApiHighLimits;
}
/**
- * Returns an array of strings with credits for the API
- * @return array
+ * Overrides to return this instance's module manager.
+ * @return ApiModuleManager
*/
- protected function getCredits() {
- return array(
- 'API developers:',
- ' Roan Kattouw (lead developer Sep 2007-2009)',
- ' Victor Vasiliev',
- ' Bryan Tong Minh',
- ' Sam Reed',
- ' Yuri Astrakhan (creator, lead developer Sep 2006-Sep 2007, 2012-2013)',
- ' Brad Jorsch (lead developer 2013-now)',
- '',
- 'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
- 'or file a bug report at https://bugzilla.wikimedia.org/'
+ public function getModuleManager() {
+ return $this->mModuleMgr;
+ }
+
+ /**
+ * Fetches the user agent used for this request
+ *
+ * The value will be the combination of the 'Api-User-Agent' header (if
+ * any) and the standard User-Agent header (if any).
+ *
+ * @return string
+ */
+ public function getUserAgent() {
+ return trim(
+ $this->getRequest()->getHeader( 'Api-user-agent' ) . ' ' .
+ $this->getRequest()->getHeader( 'User-agent' )
);
}
+ /************************************************************************//**
+ * @name Deprecated
+ * @{
+ */
+
/**
* Sets whether the pretty-printer should format *bold* and $italics$
*
+ * @deprecated since 1.25
* @param bool $help
*/
public function setHelp( $help = true ) {
+ wfDeprecated( __METHOD__, '1.25' );
$this->mPrinter->setHelp( $help );
}
/**
* Override the parent to generate help messages for all available modules.
*
+ * @deprecated since 1.25
* @return string
*/
public function makeHelpMsg() {
+ wfDeprecated( __METHOD__, '1.25' );
global $wgMemc;
$this->setHelp();
// Get help text from cache if present
@@ -1281,9 +1443,11 @@ class ApiMain extends ApiBase {
}
/**
+ * @deprecated since 1.25
* @return mixed|string
*/
public function reallyMakeHelpMsg() {
+ wfDeprecated( __METHOD__, '1.25' );
$this->setHelp();
// Use parent to make default message for the main module
@@ -1305,8 +1469,12 @@ class ApiMain extends ApiBase {
$msg .= "\n$astriks Permissions $astriks\n\n";
foreach ( self::$mRights as $right => $rightMsg ) {
+ $rightsMsg = $this->msg( $rightMsg['msg'], $rightMsg['params'] )
+ ->useDatabase( false )
+ ->inLanguage( 'en' )
+ ->text();
$groups = User::getGroupsWithPermission( $right );
- $msg .= "* " . $right . " *\n " . wfMsgReplaceArgs( $rightMsg['msg'], $rightMsg['params'] ) .
+ $msg .= "* " . $right . " *\n $rightsMsg" .
"\nGranted to:\n " . str_replace( '*', 'all', implode( ', ', $groups ) ) . "\n\n";
}
@@ -1321,18 +1489,22 @@ class ApiMain extends ApiBase {
$msg .= "\n";
}
- $msg .= "\n*** Credits: ***\n " . implode( "\n ", $this->getCredits() ) . "\n";
+ $credits = $this->msg( 'api-credits' )->useDatabase( 'false' )->inLanguage( 'en' )->text();
+ $credits = str_replace( "\n", "\n ", $credits );
+ $msg .= "\n*** Credits: ***\n $credits\n";
return $msg;
}
/**
+ * @deprecated since 1.25
* @param ApiBase $module
* @param string $paramName What type of request is this? e.g. action,
* query, list, prop, meta, format
* @return string
*/
public static function makeHelpMsgHeader( $module, $paramName ) {
+ wfDeprecated( __METHOD__, '1.25' );
$modulePrefix = $module->getModulePrefix();
if ( strval( $modulePrefix ) !== '' ) {
$modulePrefix = "($modulePrefix) ";
@@ -1341,20 +1513,6 @@ class ApiMain extends ApiBase {
return "* $paramName={$module->getModuleName()} $modulePrefix*";
}
- private $mCanApiHighLimits = null;
-
- /**
- * Check whether the current user is allowed to use high limits
- * @return bool
- */
- public function canApiHighLimits() {
- if ( !isset( $this->mCanApiHighLimits ) ) {
- $this->mCanApiHighLimits = $this->getUser()->isAllowed( 'apihighlimits' );
- }
-
- return $this->mCanApiHighLimits;
- }
-
/**
* Check whether the user wants us to show version information in the API help
* @return bool
@@ -1367,14 +1525,6 @@ class ApiMain extends ApiBase {
}
/**
- * Overrides to return this instance's module manager.
- * @return ApiModuleManager
- */
- public function getModuleManager() {
- return $this->mModuleMgr;
- }
-
- /**
* Add or overwrite a module in this ApiMain instance. Intended for use by extending
* classes who wish to add their own modules to their lexicon or override the
* behavior of inherent ones.
@@ -1418,11 +1568,13 @@ class ApiMain extends ApiBase {
public function getFormats() {
return $this->getModuleManager()->getNamesWithClasses( 'format' );
}
+
+ /**@}*/
+
}
/**
* This exception will be thrown when dieUsage is called to stop module execution.
- * The exception handling code will print a help screen explaining how this API may be used.
*
* @ingroup API
*/
@@ -1476,3 +1628,8 @@ class UsageException extends MWException {
return "{$this->getCodeString()}: {$this->getMessage()}";
}
}
+
+/**
+ * For really cool vim folding this needs to be at the end:
+ * vim: foldmarker=@{,@} foldmethod=marker
+ */
diff --git a/includes/api/ApiManageTags.php b/includes/api/ApiManageTags.php
new file mode 100644
index 00000000..240d3506
--- /dev/null
+++ b/includes/api/ApiManageTags.php
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup API
+ * @since 1.25
+ */
+class ApiManageTags extends ApiBase {
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ // make sure the user is allowed
+ if ( !$this->getUser()->isAllowed( 'managechangetags' ) ) {
+ $this->dieUsage( "You don't have permission to manage change tags", 'permissiondenied' );
+ }
+
+ $result = $this->getResult();
+ $funcName = "{$params['operation']}TagWithChecks";
+ $status = ChangeTags::$funcName( $params['tag'], $params['reason'],
+ $this->getUser(), $params['ignorewarnings'] );
+
+ if ( !$status->isOK() ) {
+ $this->dieStatus( $status );
+ }
+
+ $ret = array(
+ 'operation' => $params['operation'],
+ 'tag' => $params['tag'],
+ );
+ if ( !$status->isGood() ) {
+ $ret['warnings'] = $this->getErrorFormatter()->arrayFromStatus( $status, 'warning' );
+ }
+ $ret['success'] = $status->value !== null;
+ if ( $ret['success'] ) {
+ $ret['logid'] = $status->value;
+ }
+ $result->addValue( null, $this->getModuleName(), $ret );
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'operation' => array(
+ ApiBase::PARAM_TYPE => array( 'create', 'delete', 'activate', 'deactivate' ),
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'tag' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true,
+ ),
+ 'reason' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ),
+ 'ignorewarnings' => array(
+ ApiBase::PARAM_TYPE => 'boolean',
+ ApiBase::PARAM_DFLT => false,
+ ),
+ );
+ }
+
+ public function needsToken() {
+ return 'csrf';
+ }
+
+ protected function getExamplesMessages() {
+ return array(
+ 'action=managetags&operation=create&tag=spam&reason=For+use+in+edit+patrolling&token=123ABC'
+ => 'apihelp-managetags-example-create',
+ 'action=managetags&operation=delete&tag=vandlaism&reason=Misspelt&token=123ABC'
+ => 'apihelp-managetags-example-delete',
+ 'action=managetags&operation=activate&tag=spam&reason=For+use+in+edit+patrolling&token=123ABC'
+ => 'apihelp-managetags-example-activate',
+ 'action=managetags&operation=deactivate&tag=spam&reason=No+longer+required&token=123ABC'
+ => 'apihelp-managetags-example-deactivate',
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Tag_management';
+ }
+}
diff --git a/includes/api/ApiMessage.php b/includes/api/ApiMessage.php
new file mode 100644
index 00000000..6717c390
--- /dev/null
+++ b/includes/api/ApiMessage.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Defines an interface for messages with additional machine-readable data for
+ * use by the API, and provides concrete implementations of that interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Interface for messages with machine-readable data for use by the API
+ * @since 1.25
+ * @ingroup API
+ */
+interface IApiMessage extends MessageSpecifier {
+ /**
+ * Returns a machine-readable code for use by the API
+ *
+ * The message key is often sufficient, but sometimes there are multiple
+ * messages used for what is really the same underlying condition (e.g.
+ * badaccess-groups and badaccess-group0)
+ * @return string
+ */
+ public function getApiCode();
+
+ /**
+ * Returns additional machine-readable data about the error condition
+ * @return array
+ */
+ public function getApiData();
+
+ /**
+ * Sets the machine-readable code for use by the API
+ * @param string|null $code If null, the message key should be returned by self::getApiCode()
+ * @param array|null $data If non-null, passed to self::setApiData()
+ */
+ public function setApiCode( $code, array $data = null );
+
+ /**
+ * Sets additional machine-readable data about the error condition
+ * @param array $data
+ */
+ public function setApiData( array $data );
+}
+
+/**
+ * Extension of Message implementing IApiMessage
+ * @since 1.25
+ * @ingroup API
+ * @todo: Would be nice to use a Trait here to avoid code duplication
+ */
+class ApiMessage extends Message implements IApiMessage {
+ protected $apiCode = null;
+ protected $apiData = array();
+
+ /**
+ * Create an IApiMessage for the message
+ *
+ * This returns $msg if it's an IApiMessage, calls 'new ApiRawMessage' if
+ * $msg is a RawMessage, or calls 'new ApiMessage' in all other cases.
+ *
+ * @param Message|RawMessage|array|string $msg
+ * @param string|null $code
+ * @param array|null $data
+ * @return ApiMessage
+ */
+ public static function create( $msg, $code = null, array $data = null ) {
+ if ( $msg instanceof IApiMessage ) {
+ return $msg;
+ } elseif ( $msg instanceof RawMessage ) {
+ return new ApiRawMessage( $msg, $code, $data );
+ } else {
+ return new ApiMessage( $msg, $code, $data );
+ }
+ }
+
+ /**
+ * @param Message|string|array $msg
+ * - Message: is cloned
+ * - array: first element is $key, rest are $params to Message::__construct
+ * - string: passed to Message::__construct
+ * @param string|null $code
+ * @param array|null $data
+ * @return ApiMessage
+ */
+ public function __construct( $msg, $code = null, array $data = null ) {
+ if ( $msg instanceof Message ) {
+ foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
+ if ( isset( $msg->$key ) ) {
+ $this->$key = $msg->$key;
+ }
+ }
+ } elseif ( is_array( $msg ) ) {
+ $key = array_shift( $msg );
+ parent::__construct( $key, $msg );
+ } else {
+ parent::__construct( $msg );
+ }
+ $this->apiCode = $code;
+ $this->apiData = (array)$data;
+ }
+
+ public function getApiCode() {
+ return $this->apiCode === null ? $this->getKey() : $this->apiCode;
+ }
+
+ public function setApiCode( $code, array $data = null ) {
+ $this->apiCode = $code;
+ if ( $data !== null ) {
+ $this->setApiData( $data );
+ }
+ }
+
+ public function getApiData() {
+ return $this->apiData;
+ }
+
+ public function setApiData( array $data ) {
+ $this->apiData = $data;
+ }
+}
+
+/**
+ * Extension of RawMessage implementing IApiMessage
+ * @since 1.25
+ * @ingroup API
+ * @todo: Would be nice to use a Trait here to avoid code duplication
+ */
+class ApiRawMessage extends RawMessage implements IApiMessage {
+ protected $apiCode = null;
+ protected $apiData = array();
+
+ /**
+ * @param RawMessage|string|array $msg
+ * - RawMessage: is cloned
+ * - array: first element is $key, rest are $params to RawMessage::__construct
+ * - string: passed to RawMessage::__construct
+ * @param string|null $code
+ * @param array|null $data
+ * @return ApiMessage
+ */
+ public function __construct( $msg, $code = null, array $data = null ) {
+ if ( $msg instanceof RawMessage ) {
+ foreach ( get_class_vars( get_class( $this ) ) as $key => $value ) {
+ if ( isset( $msg->$key ) ) {
+ $this->$key = $msg->$key;
+ }
+ }
+ } elseif ( is_array( $msg ) ) {
+ $key = array_shift( $msg );
+ parent::__construct( $key, $msg );
+ } else {
+ parent::__construct( $msg );
+ }
+ $this->apiCode = $code;
+ $this->apiData = (array)$data;
+ }
+
+ public function getApiCode() {
+ return $this->apiCode === null ? $this->getKey() : $this->apiCode;
+ }
+
+ public function setApiCode( $code, array $data = null ) {
+ $this->apiCode = $code;
+ if ( $data !== null ) {
+ $this->setApiData( $data );
+ }
+ }
+
+ public function getApiData() {
+ return $this->apiData;
+ }
+
+ public function setApiData( array $data ) {
+ $this->apiData = $data;
+ }
+}
diff --git a/includes/api/ApiMove.php b/includes/api/ApiMove.php
index 04e931d2..e42958bf 100644
--- a/includes/api/ApiMove.php
+++ b/includes/api/ApiMove.php
@@ -72,9 +72,9 @@ class ApiMove extends ApiBase {
// Move the page
$toTitleExists = $toTitle->exists();
- $retval = $fromTitle->moveTo( $toTitle, true, $params['reason'], !$params['noredirect'] );
- if ( $retval !== true ) {
- $this->dieUsageMsg( reset( $retval ) );
+ $status = $this->movePage( $fromTitle, $toTitle, $params['reason'], !$params['noredirect'] );
+ if ( !$status->isOK() ) {
+ $this->dieStatus( $status );
}
$r = array(
@@ -83,34 +83,28 @@ class ApiMove extends ApiBase {
'reason' => $params['reason']
);
- if ( $fromTitle->exists() ) {
- //NOTE: we assume that if the old title exists, it's because it was re-created as
- // a redirect to the new title. This is not safe, but what we did before was
- // even worse: we just determined whether a redirect should have been created,
- // and reported that it was created if it should have, without any checks.
- // Also note that isRedirect() is unreliable because of bug 37209.
- $r['redirectcreated'] = '';
- }
+ //NOTE: we assume that if the old title exists, it's because it was re-created as
+ // a redirect to the new title. This is not safe, but what we did before was
+ // even worse: we just determined whether a redirect should have been created,
+ // and reported that it was created if it should have, without any checks.
+ // Also note that isRedirect() is unreliable because of bug 37209.
+ $r['redirectcreated'] = $fromTitle->exists();
- if ( $toTitleExists ) {
- $r['moveoverredirect'] = '';
- }
+ $r['moveoverredirect'] = $toTitleExists;
// Move the talk page
if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() ) {
$toTalkExists = $toTalk->exists();
- $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
- if ( $retval === true ) {
+ $status = $this->movePage( $fromTalk, $toTalk, $params['reason'], !$params['noredirect'] );
+ if ( $status->isOK() ) {
$r['talkfrom'] = $fromTalk->getPrefixedText();
$r['talkto'] = $toTalk->getPrefixedText();
- if ( $toTalkExists ) {
- $r['talkmoveoverredirect'] = '';
- }
+ $r['talkmoveoverredirect'] = $toTalkExists;
} else {
// We're not gonna dieUsage() on failure, since we already changed something
- $parsed = $this->parseMsg( reset( $retval ) );
- $r['talkmove-error-code'] = $parsed['code'];
- $r['talkmove-error-info'] = $parsed['info'];
+ $error = $this->getErrorFromStatus( $status );
+ $r['talkmove-error-code'] = $error[0];
+ $r['talkmove-error-info'] = $error[1];
}
}
@@ -120,12 +114,12 @@ class ApiMove extends ApiBase {
if ( $params['movesubpages'] ) {
$r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle,
$params['reason'], $params['noredirect'] );
- $result->setIndexedTagName( $r['subpages'], 'subpage' );
+ ApiResult::setIndexedTagName( $r['subpages'], 'subpage' );
if ( $params['movetalk'] ) {
$r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk,
$params['reason'], $params['noredirect'] );
- $result->setIndexedTagName( $r['subpages-talk'], 'subpage' );
+ ApiResult::setIndexedTagName( $r['subpages-talk'], 'subpage' );
}
}
@@ -148,6 +142,33 @@ class ApiMove extends ApiBase {
}
/**
+ * @param Title $from
+ * @param Title $to
+ * @param string $reason
+ * @param bool $createRedirect
+ * @return Status
+ */
+ protected function movePage( Title $from, Title $to, $reason, $createRedirect ) {
+ $mp = new MovePage( $from, $to );
+ $valid = $mp->isValidMove();
+ if ( !$valid->isOK() ) {
+ return $valid;
+ }
+
+ $permStatus = $mp->checkPermissions( $this->getUser(), $reason );
+ if ( !$permStatus->isOK() ) {
+ return $permStatus;
+ }
+
+ // Check suppressredirect permission
+ if ( !$this->getUser()->isAllowed( 'suppressredirect' ) ) {
+ $createRedirect = true;
+ }
+
+ return $mp->move( $this->getUser(), $reason, $createRedirect );
+ }
+
+ /**
* @param Title $fromTitle
* @param Title $toTitle
* @param string $reason
@@ -220,37 +241,15 @@ class ApiMove extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'from' => "Title of the page you want to move. Cannot be used together with {$p}fromid",
- 'fromid' => "Page ID of the page you want to move. Cannot be used together with {$p}from",
- 'to' => 'Title you want to rename the page to',
- 'reason' => 'Reason for the move',
- 'movetalk' => 'Move the talk page, if it exists',
- 'movesubpages' => 'Move subpages, if applicable',
- 'noredirect' => 'Don\'t create a redirect',
- 'watch' => 'Add the page and the redirect to your watchlist',
- 'unwatch' => 'Remove the page and the redirect from your watchlist',
- 'watchlist' => 'Unconditionally add or remove the page from your ' .
- 'watchlist, use preferences or do not change watch',
- 'ignorewarnings' => 'Ignore any warnings'
- );
- }
-
- public function getDescription() {
- return 'Move a page.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=move&from=Badtitle&to=Goodtitle&token=123ABC&' .
+ 'action=move&from=Badtitle&to=Goodtitle&token=123ABC&' .
'reason=Misspelled%20title&movetalk=&noredirect='
+ => 'apihelp-move-example-move',
);
}
diff --git a/includes/api/ApiOpenSearch.php b/includes/api/ApiOpenSearch.php
index 7fb045e3..a93b7cc6 100644
--- a/includes/api/ApiOpenSearch.php
+++ b/includes/api/ApiOpenSearch.php
@@ -3,6 +3,8 @@
* Created on Oct 13, 2006
*
* Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ * Copyright © 2008 Brion Vibber <brion@wikimedia.org>
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,21 +29,50 @@
*/
class ApiOpenSearch extends ApiBase {
+ private $format = null;
+ private $fm = null;
+
/**
- * Override built-in handling of format parameter.
- * Only JSON is supported.
+ * Get the output format
*
- * @return ApiFormatBase
+ * @return string
*/
- public function getCustomPrinter() {
- $params = $this->extractRequestParams();
- $format = $params['format'];
- $allowed = array( 'json', 'jsonfm' );
- if ( in_array( $format, $allowed ) ) {
- return $this->getMain()->createPrinterByName( $format );
+ protected function getFormat() {
+ if ( $this->format === null ) {
+ $params = $this->extractRequestParams();
+ $format = $params['format'];
+
+ $allowedParams = $this->getAllowedParams();
+ if ( !in_array( $format, $allowedParams['format'][ApiBase::PARAM_TYPE] ) ) {
+ $format = $allowedParams['format'][ApiBase::PARAM_DFLT];
+ }
+
+ if ( substr( $format, -2 ) === 'fm' ) {
+ $this->format = substr( $format, 0, -2 );
+ $this->fm = 'fm';
+ } else {
+ $this->format = $format;
+ $this->fm = '';
+ }
}
+ return $this->format;
+ }
+
+ public function getCustomPrinter() {
+ switch ( $this->getFormat() ) {
+ case 'json':
+ return new ApiOpenSearchFormatJson(
+ $this->getMain(), $this->fm, $this->getParameter( 'warningsaserror' )
+ );
+
+ case 'xml':
+ $printer = $this->getMain()->createPrinterByName( 'xml' . $this->fm );
+ $printer->setRootElement( 'SearchSuggestion' );
+ return $printer;
- return $this->getMain()->createPrinterByName( $allowed[0] );
+ default:
+ ApiBase::dieDebug( __METHOD__, "Unsupported format '{$this->getFormat()}'" );
+ }
}
public function execute() {
@@ -51,21 +82,188 @@ class ApiOpenSearch extends ApiBase {
$namespaces = $params['namespace'];
$suggest = $params['suggest'];
- // Some script that was loaded regardless of wgEnableOpenSearchSuggest, likely cached.
- if ( $suggest && !$this->getConfig()->get( 'EnableOpenSearchSuggest' ) ) {
- $searches = array();
+ if ( $params['redirects'] === null ) {
+ // Backwards compatibility, don't resolve for JSON.
+ $resolveRedir = $this->getFormat() !== 'json';
} else {
+ $resolveRedir = $params['redirects'] === 'resolve';
+ }
+
+ $results = array();
+
+ if ( !$suggest || $this->getConfig()->get( 'EnableOpenSearchSuggest' ) ) {
// Open search results may be stored for a very long time
$this->getMain()->setCacheMaxAge( $this->getConfig()->get( 'SearchSuggestCacheExpiry' ) );
$this->getMain()->setCacheMode( 'public' );
+ $this->search( $search, $limit, $namespaces, $resolveRedir, $results );
+
+ // Allow hooks to populate extracts and images
+ Hooks::run( 'ApiOpenSearchSuggest', array( &$results ) );
+
+ // Trim extracts, if necessary
+ $length = $this->getConfig()->get( 'OpenSearchDescriptionLength' );
+ foreach ( $results as &$r ) {
+ if ( is_string( $r['extract'] ) && !$r['extract trimmed'] ) {
+ $r['extract'] = self::trimExtract( $r['extract'], $length );
+ }
+ }
+ }
+
+ // Populate result object
+ $this->populateResult( $search, $results );
+ }
- $searcher = new StringPrefixSearch;
- $searches = $searcher->searchWithVariants( $search, $limit, $namespaces );
+ /**
+ * Perform the search
+ *
+ * @param string $search Text to search
+ * @param int $limit Maximum items to return
+ * @param array $namespaces Namespaces to search
+ * @param bool $resolveRedir Whether to resolve redirects
+ * @param array &$results Put results here. Keys have to be integers.
+ */
+ protected function search( $search, $limit, $namespaces, $resolveRedir, &$results ) {
+ // Find matching titles as Title objects
+ $searcher = new TitlePrefixSearch;
+ $titles = $searcher->searchWithVariants( $search, $limit, $namespaces );
+ if ( !$titles ) {
+ return;
}
- // Set top level elements
+
+ // Special pages need unique integer ids in the return list, so we just
+ // assign them negative numbers because those won't clash with the
+ // always positive articleIds that non-special pages get.
+ $nextSpecialPageId = -1;
+
+ if ( $resolveRedir ) {
+ // Query for redirects
+ $redirects = array();
+ $lb = new LinkBatch( $titles );
+ if ( !$lb->isEmpty() ) {
+ $db = $this->getDb();
+ $res = $db->select(
+ array( 'page', 'redirect' ),
+ array( 'page_namespace', 'page_title', 'rd_namespace', 'rd_title' ),
+ array(
+ 'rd_from = page_id',
+ 'rd_interwiki IS NULL OR rd_interwiki = ' . $db->addQuotes( '' ),
+ $lb->constructSet( 'page', $db ),
+ ),
+ __METHOD__
+ );
+ foreach ( $res as $row ) {
+ $redirects[$row->page_namespace][$row->page_title] =
+ array( $row->rd_namespace, $row->rd_title );
+ }
+ }
+
+ // Bypass any redirects
+ $seen = array();
+ foreach ( $titles as $title ) {
+ $ns = $title->getNamespace();
+ $dbkey = $title->getDBkey();
+ $from = null;
+ if ( isset( $redirects[$ns][$dbkey] ) ) {
+ list( $ns, $dbkey ) = $redirects[$ns][$dbkey];
+ $from = $title;
+ $title = Title::makeTitle( $ns, $dbkey );
+ }
+ if ( !isset( $seen[$ns][$dbkey] ) ) {
+ $seen[$ns][$dbkey] = true;
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
+ 'title' => $title,
+ 'redirect from' => $from,
+ 'extract' => false,
+ 'extract trimmed' => false,
+ 'image' => false,
+ 'url' => wfExpandUrl( $title->getFullUrl(), PROTO_CURRENT ),
+ );
+ }
+ }
+ } else {
+ foreach ( $titles as $title ) {
+ $resultId = $title->getArticleId();
+ if ( $resultId === 0 ) {
+ $resultId = $nextSpecialPageId;
+ $nextSpecialPageId -= 1;
+ }
+ $results[$resultId] = array(
+ 'title' => $title,
+ 'redirect from' => null,
+ 'extract' => false,
+ 'extract trimmed' => false,
+ 'image' => false,
+ 'url' => wfExpandUrl( $title->getFullUrl(), PROTO_CURRENT ),
+ );
+ }
+ }
+ }
+
+ /**
+ * @param string $search
+ * @param array &$results
+ */
+ protected function populateResult( $search, &$results ) {
$result = $this->getResult();
- $result->addValue( null, 0, $search );
- $result->addValue( null, 1, $searches );
+
+ switch ( $this->getFormat() ) {
+ case 'json':
+ // http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.1
+ $result->addArrayType( null, 'array' );
+ $result->addValue( null, 0, strval( $search ) );
+ $terms = array();
+ $descriptions = array();
+ $urls = array();
+ foreach ( $results as $r ) {
+ $terms[] = $r['title']->getPrefixedText();
+ $descriptions[] = strval( $r['extract'] );
+ $urls[] = $r['url'];
+ }
+ $result->addValue( null, 1, $terms );
+ $result->addValue( null, 2, $descriptions );
+ $result->addValue( null, 3, $urls );
+ break;
+
+ case 'xml':
+ // http://msdn.microsoft.com/en-us/library/cc891508%28v=vs.85%29.aspx
+ $imageKeys = array(
+ 'source' => true,
+ 'alt' => true,
+ 'width' => true,
+ 'height' => true,
+ 'align' => true,
+ );
+ $items = array();
+ foreach ( $results as $r ) {
+ $item = array(
+ 'Text' => $r['title']->getPrefixedText(),
+ 'Url' => $r['url'],
+ );
+ if ( is_string( $r['extract'] ) && $r['extract'] !== '' ) {
+ $item['Description'] = $r['extract'];
+ }
+ if ( is_array( $r['image'] ) && isset( $r['image']['source'] ) ) {
+ $item['Image'] = array_intersect_key( $r['image'], $imageKeys );
+ }
+ ApiResult::setSubelementsList( $item, array_keys( $item ) );
+ $items[] = $item;
+ }
+ ApiResult::setIndexedTagName( $items, 'Item' );
+ $result->addValue( null, 'version', '2.0' );
+ $result->addValue( null, 'xmlns', 'http://opensearch.org/searchsuggest2' );
+ $result->addValue( null, 'Query', strval( $search ) );
+ $result->addSubelementsList( null, 'Query' );
+ $result->addValue( null, 'Section', $items );
+ break;
+
+ default:
+ ApiBase::dieDebug( __METHOD__, "Unsupported format '{$this->getFormat()}'" );
+ }
}
public function getAllowedParams() {
@@ -84,34 +282,117 @@ class ApiOpenSearch extends ApiBase {
ApiBase::PARAM_ISMULTI => true
),
'suggest' => false,
+ 'redirects' => array(
+ ApiBase::PARAM_TYPE => array( 'return', 'resolve' ),
+ ),
'format' => array(
ApiBase::PARAM_DFLT => 'json',
- ApiBase::PARAM_TYPE => array( 'json', 'jsonfm' ),
- )
+ ApiBase::PARAM_TYPE => array( 'json', 'jsonfm', 'xml', 'xmlfm' ),
+ ),
+ 'warningsaserror' => false,
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'search' => 'Search string',
- 'limit' => 'Maximum amount of results to return',
- 'namespace' => 'Namespaces to search',
- 'suggest' => 'Do nothing if $wgEnableOpenSearchSuggest is false',
- 'format' => 'The format of the output',
+ 'action=opensearch&search=Te'
+ => 'apihelp-opensearch-example-te',
);
}
- public function getDescription() {
- return 'Search the wiki using the OpenSearch protocol.';
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Opensearch';
}
- public function getExamples() {
- return array(
- 'api.php?action=opensearch&search=Te'
- );
+ /**
+ * Trim an extract to a sensible length.
+ *
+ * Adapted from Extension:OpenSearchXml, which adapted it from
+ * Extension:ActiveAbstract.
+ *
+ * @param string $text
+ * @param int $len Target length; actual result will continue to the end of a sentence.
+ * @return string
+ */
+ public static function trimExtract( $text, $length ) {
+ static $regex = null;
+
+ if ( $regex === null ) {
+ $endchars = array(
+ '([^\d])\.\s', '\!\s', '\?\s', // regular ASCII
+ '。', // full-width ideographic full-stop
+ '.', '!', '?', // double-width roman forms
+ '。', // half-width ideographic full stop
+ );
+ $endgroup = implode( '|', $endchars );
+ $end = "(?:$endgroup)";
+ $sentence = ".{{$length},}?$end+";
+ $regex = "/^($sentence)/u";
+ }
+
+ $matches = array();
+ if ( preg_match( $regex, $text, $matches ) ) {
+ return trim( $matches[1] );
+ } else {
+ // Just return the first line
+ $lines = explode( "\n", $text );
+ return trim( $lines[0] );
+ }
}
- public function getHelpUrls() {
- return 'https://www.mediawiki.org/wiki/API:Opensearch';
+ /**
+ * Fetch the template for a type.
+ *
+ * @param string $type MIME type
+ * @return string
+ * @throws MWException
+ */
+ public static function getOpenSearchTemplate( $type ) {
+ global $wgOpenSearchTemplate, $wgCanonicalServer;
+
+ if ( $wgOpenSearchTemplate && $type === 'application/x-suggestions+json' ) {
+ return $wgOpenSearchTemplate;
+ }
+
+ $ns = implode( '|', SearchEngine::defaultNamespaces() );
+ if ( !$ns ) {
+ $ns = "0";
+ }
+
+ switch ( $type ) {
+ case 'application/x-suggestions+json':
+ return $wgCanonicalServer . wfScript( 'api' )
+ . '?action=opensearch&search={searchTerms}&namespace=' . $ns;
+
+ case 'application/x-suggestions+xml':
+ return $wgCanonicalServer . wfScript( 'api' )
+ . '?action=opensearch&format=xml&search={searchTerms}&namespace=' . $ns;
+
+ default:
+ throw new MWException( __METHOD__ . ": Unknown type '$type'" );
+ }
+ }
+}
+
+class ApiOpenSearchFormatJson extends ApiFormatJson {
+ private $warningsAsError = false;
+
+ public function __construct( ApiMain $main, $fm, $warningsAsError ) {
+ parent::__construct( $main, "json$fm" );
+ $this->warningsAsError = $warningsAsError;
+ }
+
+ public function execute() {
+ if ( !$this->getResult()->getResultData( 'error' ) ) {
+ $warnings = $this->getResult()->removeValue( 'warnings', null );
+ if ( $this->warningsAsError && $warnings ) {
+ $this->dieUsage(
+ 'Warnings cannot be represented in OpenSearch JSON format', 'warnings', 0,
+ array( 'warnings' => $warnings )
+ );
+ }
+ }
+
+ parent::execute();
}
}
diff --git a/includes/api/ApiOptions.php b/includes/api/ApiOptions.php
index b01dc3e2..8ef06299 100644
--- a/includes/api/ApiOptions.php
+++ b/includes/api/ApiOptions.php
@@ -153,30 +153,6 @@ class ApiOptions extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'reset' => 'Resets preferences to the site defaults',
- 'resetkinds' => 'List of types of options to reset when the "reset" option is set',
- 'change' => array( 'List of changes, formatted name=value (e.g. skin=vector), ' .
- 'value cannot contain pipe characters. If no value is given (not ',
- 'even an equals sign), e.g., optionname|otheroption|..., the ' .
- 'option will be reset to its default value'
- ),
- 'optionname' => 'A name of a option which should have an optionvalue set',
- 'optionvalue' => 'A value of the option specified by the optionname, ' .
- 'can contain pipe characters',
- );
- }
-
- public function getDescription() {
- return array(
- 'Change preferences of the current user.',
- 'Only options which are registered in core or in one of installed extensions,',
- 'or as options with keys prefixed with \'userjs-\' (intended to be used by user',
- 'scripts), can be set.'
- );
- }
-
public function needsToken() {
return 'csrf';
}
@@ -185,12 +161,15 @@ class ApiOptions extends ApiBase {
return 'https://www.mediawiki.org/wiki/API:Options';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=options&reset=&token=123ABC',
- 'api.php?action=options&change=skin=vector|hideminor=1&token=123ABC',
- 'api.php?action=options&reset=&change=skin=monobook&optionname=nickname&' .
- 'optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC',
+ 'action=options&reset=&token=123ABC'
+ => 'apihelp-options-example-reset',
+ 'action=options&change=skin=vector|hideminor=1&token=123ABC'
+ => 'apihelp-options-example-change',
+ 'action=options&reset=&change=skin=monobook&optionname=nickname&' .
+ 'optionvalue=[[User:Beau|Beau]]%20([[User_talk:Beau|talk]])&token=123ABC'
+ => 'apihelp-options-example-complex',
);
}
}
diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php
index 0f264675..e6f218d6 100644
--- a/includes/api/ApiPageSet.php
+++ b/includes/api/ApiPageSet.php
@@ -53,7 +53,10 @@ class ApiPageSet extends ApiBase {
private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
private $mTitles = array();
+ private $mGoodAndMissingPages = array(); // [ns][dbkey] => page_id or negative when missing
+ private $mGoodPages = array(); // [ns][dbkey] => page_id
private $mGoodTitles = array();
+ private $mMissingPages = array(); // [ns][dbkey] => fake page_id
private $mMissingTitles = array();
private $mInvalidTitles = array();
private $mMissingPageIDs = array();
@@ -65,7 +68,10 @@ class ApiPageSet extends ApiBase {
private $mPendingRedirectIDs = array();
private $mConvertedTitles = array();
private $mGoodRevIDs = array();
+ private $mLiveRevIDs = array();
+ private $mDeletedRevIDs = array();
private $mMissingRevIDs = array();
+ private $mGeneratorData = array(); // [ns][dbkey] => data array
private $mFakePageId = -1;
private $mCacheMode = 'public';
private $mRequestedPageFields = array();
@@ -90,7 +96,7 @@ class ApiPageSet extends ApiBase {
$v = $val;
}
if ( $flag !== null ) {
- $v[$flag] = '';
+ $v[$flag] = true;
}
$result[] = $v;
}
@@ -109,11 +115,9 @@ class ApiPageSet extends ApiBase {
$this->mAllowGenerator = ( $flags & ApiPageSet::DISABLE_GENERATORS ) == 0;
$this->mDefaultNamespace = $defaultNamespace;
- $this->profileIn();
$this->mParams = $this->extractRequestParams();
$this->mResolveRedirects = $this->mParams['redirects'];
$this->mConvertTitles = $this->mParams['converttitles'];
- $this->profileOut();
}
/**
@@ -137,17 +141,12 @@ class ApiPageSet extends ApiBase {
* relevant parameters as used
*/
private function executeInternal( $isDryRun ) {
- $this->profileIn();
-
$generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
if ( isset( $generatorName ) ) {
$dbSource = $this->mDbSource;
- $isQuery = $dbSource instanceof ApiQuery;
- if ( !$isQuery ) {
+ if ( !$dbSource instanceof ApiQuery ) {
// If the parent container of this pageset is not ApiQuery, we must create it to run generator
$dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
- // Enable profiling for query module because it will be used for db sql profiling
- $dbSource->profileIn();
}
$generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
if ( $generator === null ) {
@@ -168,12 +167,9 @@ class ApiPageSet extends ApiBase {
$tmpPageSet->executeInternal( $isDryRun );
// populate this pageset with the generator output
- $this->profileOut();
- $generator->profileIn();
-
if ( !$isDryRun ) {
$generator->executeGenerator( $this );
- wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
+ Hooks::run( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
} else {
// Prevent warnings from being reported on these parameters
$main = $this->getMain();
@@ -181,17 +177,10 @@ class ApiPageSet extends ApiBase {
$main->getVal( $generator->encodeParamName( $paramName ) );
}
}
- $generator->profileOut();
- $this->profileIn();
if ( !$isDryRun ) {
$this->resolvePendingRedirects();
}
-
- if ( !$isQuery ) {
- // If this pageset is not part of the query, we called profileIn() above
- $dbSource->profileOut();
- }
} else {
// Only one of the titles/pageids/revids is allowed at the same time
$dataSource = null;
@@ -235,7 +224,6 @@ class ApiPageSet extends ApiBase {
}
}
}
- $this->profileOut();
}
/**
@@ -309,6 +297,10 @@ class ApiPageSet extends ApiBase {
$pageFlds['page_is_redirect'] = null;
}
+ if ( $this->getConfig()->get( 'ContentHandlerUseDB' ) ) {
+ $pageFlds['page_content_model'] = null;
+ }
+
// only store non-default fields
$this->mRequestedPageFields = array_diff_key( $this->mRequestedPageFields, $pageFlds );
@@ -344,6 +336,14 @@ class ApiPageSet extends ApiBase {
}
/**
+ * Returns an array [ns][dbkey] => page_id for all good titles.
+ * @return array
+ */
+ public function getGoodTitlesByNamespace() {
+ return $this->mGoodPages;
+ }
+
+ /**
* Title objects that were found in the database.
* @return Title[] Array page_id (int) => Title (obj)
*/
@@ -360,6 +360,15 @@ class ApiPageSet extends ApiBase {
}
/**
+ * Returns an array [ns][dbkey] => fake_page_id for all missing titles.
+ * fake_page_id is a unique negative number.
+ * @return array
+ */
+ public function getMissingTitlesByNamespace() {
+ return $this->mMissingPages;
+ }
+
+ /**
* Title objects that were NOT found in the database.
* The array's index will be negative for each item
* @return Title[]
@@ -369,6 +378,22 @@ class ApiPageSet extends ApiBase {
}
/**
+ * Returns an array [ns][dbkey] => page_id for all good and missing titles.
+ * @return array
+ */
+ public function getGoodAndMissingTitlesByNamespace() {
+ return $this->mGoodAndMissingPages;
+ }
+
+ /**
+ * Title objects for good and missing titles.
+ * @return array
+ */
+ public function getGoodAndMissingTitles() {
+ return $this->mGoodTitles + $this->mMissingTitles;
+ }
+
+ /**
* Titles that were deemed invalid by Title::newFromText()
* The array's index will be unique and negative for each item
* @return string[] Array of strings (not Title objects)
@@ -411,10 +436,13 @@ class ApiPageSet extends ApiBase {
if ( $titleTo->hasFragment() ) {
$r['tofragment'] = $titleTo->getFragment();
}
+ if ( $titleTo->isExternal() ) {
+ $r['tointerwiki'] = $titleTo->getInterwiki();
+ }
$values[] = $r;
}
if ( !empty( $values ) && $result ) {
- $result->setIndexedTagName( $values, 'r' );
+ ApiResult::setIndexedTagName( $values, 'r' );
}
return $values;
@@ -445,7 +473,7 @@ class ApiPageSet extends ApiBase {
);
}
if ( !empty( $values ) && $result ) {
- $result->setIndexedTagName( $values, 'n' );
+ ApiResult::setIndexedTagName( $values, 'n' );
}
return $values;
@@ -476,7 +504,7 @@ class ApiPageSet extends ApiBase {
);
}
if ( !empty( $values ) && $result ) {
- $result->setIndexedTagName( $values, 'c' );
+ ApiResult::setIndexedTagName( $values, 'c' );
}
return $values;
@@ -513,7 +541,7 @@ class ApiPageSet extends ApiBase {
$values[] = $item;
}
if ( !empty( $values ) && $result ) {
- $result->setIndexedTagName( $values, 'i' );
+ ApiResult::setIndexedTagName( $values, 'i' );
}
return $values;
@@ -560,7 +588,7 @@ class ApiPageSet extends ApiBase {
}
/**
- * Get the list of revision IDs (requested with the revids= parameter)
+ * Get the list of valid revision IDs (requested with the revids= parameter)
* @return array Array of revID (int) => pageID (int)
*/
public function getRevisionIDs() {
@@ -568,6 +596,22 @@ class ApiPageSet extends ApiBase {
}
/**
+ * Get the list of non-deleted revision IDs (requested with the revids= parameter)
+ * @return array Array of revID (int) => pageID (int)
+ */
+ public function getLiveRevisionIDs() {
+ return $this->mLiveRevIDs;
+ }
+
+ /**
+ * Get the list of revision IDs that were associated with deleted titles.
+ * @return array Array of revID (int) => pageID (int)
+ */
+ public function getDeletedRevisionIDs() {
+ return $this->mDeletedRevIDs;
+ }
+
+ /**
* Revision IDs that were not found in the database
* @return array Array of revision IDs
*/
@@ -589,7 +633,7 @@ class ApiPageSet extends ApiBase {
);
}
if ( !empty( $values ) && $result ) {
- $result->setIndexedTagName( $values, 'rev' );
+ ApiResult::setIndexedTagName( $values, 'rev' );
}
return $values;
@@ -616,9 +660,7 @@ class ApiPageSet extends ApiBase {
* @param array $titles Array of Title objects
*/
public function populateFromTitles( $titles ) {
- $this->profileIn();
$this->initFromTitles( $titles );
- $this->profileOut();
}
/**
@@ -626,20 +668,20 @@ class ApiPageSet extends ApiBase {
* @param array $pageIDs Array of page IDs
*/
public function populateFromPageIDs( $pageIDs ) {
- $this->profileIn();
$this->initFromPageIds( $pageIDs );
- $this->profileOut();
}
/**
* Populate this PageSet from a rowset returned from the database
+ *
+ * Note that the query result must include the columns returned by
+ * $this->getPageTableFields().
+ *
* @param DatabaseBase $db
* @param ResultWrapper $queryResult Query result object
*/
public function populateFromQueryResult( $db, $queryResult ) {
- $this->profileIn();
$this->initFromQueryResult( $queryResult );
- $this->profileOut();
}
/**
@@ -647,9 +689,7 @@ class ApiPageSet extends ApiBase {
* @param array $revIDs Array of revision IDs
*/
public function populateFromRevisionIDs( $revIDs ) {
- $this->profileIn();
$this->initFromRevIDs( $revIDs );
- $this->profileOut();
}
/**
@@ -667,6 +707,8 @@ class ApiPageSet extends ApiBase {
if ( $this->mResolveRedirects && $row->page_is_redirect == '1' ) {
$this->mPendingRedirectIDs[$pageId] = $title;
} else {
+ $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
+ $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
$this->mGoodTitles[$pageId] = $title;
}
@@ -710,10 +752,8 @@ class ApiPageSet extends ApiBase {
$set = $linkBatch->constructSet( 'page', $db );
// Get pageIDs data from the `page` table
- $this->profileDBIn();
$res = $db->select( 'page', $this->getPageTableFields(), $set,
__METHOD__ );
- $this->profileDBOut();
// Hack: get the ns:titles stored in array(ns => array(titles)) format
$this->initFromQueryResult( $res, $linkBatch->data, true ); // process Titles
@@ -744,10 +784,8 @@ class ApiPageSet extends ApiBase {
$db = $this->getDB();
// Get pageIDs data from the `page` table
- $this->profileDBIn();
$res = $db->select( 'page', $this->getPageTableFields(), $set,
__METHOD__ );
- $this->profileDBOut();
}
$this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
@@ -803,6 +841,8 @@ class ApiPageSet extends ApiBase {
foreach ( array_keys( $dbkeys ) as $dbkey ) {
$title = Title::makeTitle( $ns, $dbkey );
$this->mAllPages[$ns][$dbkey] = $this->mFakePageId;
+ $this->mMissingPages[$ns][$dbkey] = $this->mFakePageId;
+ $this->mGoodAndMissingPages[$ns][$dbkey] = $this->mFakePageId;
$this->mMissingTitles[$this->mFakePageId] = $title;
$this->mFakePageId--;
$this->mTitles[] = $title;
@@ -851,22 +891,64 @@ class ApiPageSet extends ApiBase {
$where = array( 'rev_id' => $revids, 'rev_page = page_id' );
// Get pageIDs data from the `page` table
- $this->profileDBIn();
$res = $db->select( $tables, $fields, $where, __METHOD__ );
foreach ( $res as $row ) {
$revid = intval( $row->rev_id );
$pageid = intval( $row->rev_page );
$this->mGoodRevIDs[$revid] = $pageid;
+ $this->mLiveRevIDs[$revid] = $pageid;
$pageids[$pageid] = '';
unset( $remaining[$revid] );
}
- $this->profileDBOut();
}
$this->mMissingRevIDs = array_keys( $remaining );
// Populate all the page information
$this->initFromPageIds( array_keys( $pageids ) );
+
+ // If the user can see deleted revisions, pull out the corresponding
+ // titles from the archive table and include them too. We ignore
+ // ar_page_id because deleted revisions are tied by title, not page_id.
+ if ( !empty( $this->mMissingRevIDs ) && $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+ $remaining = array_flip( $this->mMissingRevIDs );
+ $tables = array( 'archive' );
+ $fields = array( 'ar_rev_id', 'ar_namespace', 'ar_title' );
+ $where = array( 'ar_rev_id' => $this->mMissingRevIDs );
+
+ $res = $db->select( $tables, $fields, $where, __METHOD__ );
+ $titles = array();
+ foreach ( $res as $row ) {
+ $revid = intval( $row->ar_rev_id );
+ $titles[$revid] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+ unset( $remaining[$revid] );
+ }
+
+ $this->initFromTitles( $titles );
+
+ foreach ( $titles as $revid => $title ) {
+ $ns = $title->getNamespace();
+ $dbkey = $title->getDBkey();
+
+ // Handle converted titles
+ if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
+ isset( $this->mConvertedTitles[$title->getPrefixedText()] )
+ ) {
+ $title = Title::newFromText( $this->mConvertedTitles[$title->getPrefixedText()] );
+ $ns = $title->getNamespace();
+ $dbkey = $title->getDBkey();
+ }
+
+ if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
+ $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
+ $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
+ } else {
+ $remaining[$revid] = true;
+ }
+ }
+
+ $this->mMissingRevIDs = array_keys( $remaining );
+ }
}
/**
@@ -896,9 +978,7 @@ class ApiPageSet extends ApiBase {
}
// Get pageIDs data from the `page` table
- $this->profileDBIn();
$res = $db->select( 'page', $pageFlds, $set, __METHOD__ );
- $this->profileDBOut();
// Hack: get the ns:titles stored in array(ns => array(titles)) format
$this->initFromQueryResult( $res, $linkBatch->data, true );
@@ -917,7 +997,6 @@ class ApiPageSet extends ApiBase {
$lb = new LinkBatch();
$db = $this->getDB();
- $this->profileDBIn();
$res = $db->select(
'redirect',
array(
@@ -929,7 +1008,6 @@ class ApiPageSet extends ApiBase {
), array( 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ),
__METHOD__
);
- $this->profileDBOut();
foreach ( $res as $row ) {
$rdfrom = intval( $row->rd_from );
$from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
@@ -940,7 +1018,9 @@ class ApiPageSet extends ApiBase {
$row->rd_interwiki
);
unset( $this->mPendingRedirectIDs[$rdfrom] );
- if ( !$to->isExternal() && !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
+ if ( $to->isExternal() ) {
+ $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
+ } elseif ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
$lb->add( $row->rd_namespace, $row->rd_title );
}
$this->mRedirectTitles[$from] = $to;
@@ -1066,6 +1146,103 @@ class ApiPageSet extends ApiBase {
}
/**
+ * Set data for a title.
+ *
+ * This data may be extracted into an ApiResult using
+ * self::populateGeneratorData. This should generally be limited to
+ * data that is likely to be particularly useful to end users rather than
+ * just being a dump of everything returned in non-generator mode.
+ *
+ * Redirects here will *not* be followed, even if 'redirects' was
+ * specified, since in the case of multiple redirects we can't know which
+ * source's data to use on the target.
+ *
+ * @param Title $title
+ * @param array $data
+ */
+ public function setGeneratorData( Title $title, array $data ) {
+ $ns = $title->getNamespace();
+ $dbkey = $title->getDBkey();
+ $this->mGeneratorData[$ns][$dbkey] = $data;
+ }
+
+ /**
+ * Populate the generator data for all titles in the result
+ *
+ * The page data may be inserted into an ApiResult object or into an
+ * associative array. The $path parameter specifies the path within the
+ * ApiResult or array to find the "pages" node.
+ *
+ * The "pages" node itself must be an associative array mapping the page ID
+ * or fake page ID values returned by this pageset (see
+ * self::getAllTitlesByNamespace() and self::getSpecialTitles()) to
+ * associative arrays of page data. Each of those subarrays will have the
+ * data from self::setGeneratorData() merged in.
+ *
+ * Data that was set by self::setGeneratorData() for pages not in the
+ * "pages" node will be ignored.
+ *
+ * @param ApiResult|array &$result
+ * @param array $path
+ * @return bool Whether the data fit
+ */
+ public function populateGeneratorData( &$result, array $path = array() ) {
+ if ( $result instanceof ApiResult ) {
+ $data = $result->getResultData( $path );
+ if ( $data === null ) {
+ return true;
+ }
+ } else {
+ $data = &$result;
+ foreach ( $path as $key ) {
+ if ( !isset( $data[$key] ) ) {
+ // Path isn't in $result, so nothing to add, so everything
+ // "fits"
+ return true;
+ }
+ $data = &$data[$key];
+ }
+ }
+ foreach ( $this->mGeneratorData as $ns => $dbkeys ) {
+ if ( $ns === -1 ) {
+ $pages = array();
+ foreach ( $this->mSpecialTitles as $id => $title ) {
+ $pages[$title->getDBkey()] = $id;
+ }
+ } else {
+ if ( !isset( $this->mAllPages[$ns] ) ) {
+ // No known titles in the whole namespace. Skip it.
+ continue;
+ }
+ $pages = $this->mAllPages[$ns];
+ }
+ foreach ( $dbkeys as $dbkey => $genData ) {
+ if ( !isset( $pages[$dbkey] ) ) {
+ // Unknown title. Forget it.
+ continue;
+ }
+ $pageId = $pages[$dbkey];
+ if ( !isset( $data[$pageId] ) ) {
+ // $pageId didn't make it into the result. Ignore it.
+ continue;
+ }
+
+ if ( $result instanceof ApiResult ) {
+ $path2 = array_merge( $path, array( $pageId ) );
+ foreach ( $genData as $key => $value ) {
+ if ( !$result->addValue( $path2, $key, $value ) ) {
+ return false;
+ }
+ }
+ } else {
+ $data[$pageId] = array_merge( $data[$pageId], $genData );
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
* Get the database connection (read-only)
* @return DatabaseBase
*/
@@ -1095,26 +1272,51 @@ class ApiPageSet extends ApiBase {
public function getAllowedParams( $flags = 0 ) {
$result = array(
'titles' => array(
- ApiBase::PARAM_ISMULTI => true
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_HELP_MSG => 'api-pageset-param-titles',
),
'pageids' => array(
ApiBase::PARAM_TYPE => 'integer',
- ApiBase::PARAM_ISMULTI => true
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_HELP_MSG => 'api-pageset-param-pageids',
),
'revids' => array(
ApiBase::PARAM_TYPE => 'integer',
- ApiBase::PARAM_ISMULTI => true
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_HELP_MSG => 'api-pageset-param-revids',
+ ),
+ 'generator' => array(
+ ApiBase::PARAM_TYPE => null,
+ ApiBase::PARAM_VALUE_LINKS => array(),
+ ApiBase::PARAM_HELP_MSG => 'api-pageset-param-generator',
+ ),
+ 'redirects' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => $this->mAllowGenerator
+ ? 'api-pageset-param-redirects-generator'
+ : 'api-pageset-param-redirects-nogenerator',
+ ),
+ 'converttitles' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'api-pageset-param-converttitles',
+ new DeferredStringifier(
+ function ( IContextSource $context ) {
+ return $context->getLanguage()
+ ->commaList( LanguageConverter::$languagesWithVariants );
+ },
+ $this
+ )
+ ),
),
- 'redirects' => false,
- 'converttitles' => false,
);
- if ( $this->mAllowGenerator ) {
- if ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
- $result['generator'] = array(
- ApiBase::PARAM_TYPE => $this->getGenerators()
- );
- } else {
- $result['generator'] = null;
+
+ if ( !$this->mAllowGenerator ) {
+ unset( $result['generator'] );
+ } elseif ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
+ foreach ( $this->getGenerators() as $g ) {
+ $result['generator'][ApiBase::PARAM_TYPE][] = $g;
+ $result['generator'][ApiBase::PARAM_VALUE_LINKS][$g] = "Special:ApiHelp/query+$g";
}
}
@@ -1148,23 +1350,4 @@ class ApiPageSet extends ApiBase {
return self::$generators;
}
-
- public function getParamDescription() {
- return array(
- 'titles' => 'A list of titles to work on',
- 'pageids' => 'A list of page IDs to work on',
- 'revids' => 'A list of revision IDs to work on',
- 'generator' => array(
- 'Get the list of pages to work on by executing the specified query module.',
- 'NOTE: generator parameter names must be prefixed with a \'g\', see examples'
- ),
- 'redirects' => 'Automatically resolve redirects',
- 'converttitles' => array(
- 'Convert titles to other variants if necessary. Only works if ' .
- 'the wiki\'s content language supports variant conversion.',
- 'Languages that support variant conversion include ' .
- implode( ', ', LanguageConverter::$languagesWithVariants )
- ),
- );
- }
}
diff --git a/includes/api/ApiParamInfo.php b/includes/api/ApiParamInfo.php
index 067b2f59..4dcaf78e 100644
--- a/includes/api/ApiParamInfo.php
+++ b/includes/api/ApiParamInfo.php
@@ -29,232 +29,329 @@
*/
class ApiParamInfo extends ApiBase {
- /**
- * @var ApiQuery
- */
- protected $queryObj;
+ private $helpFormat;
+ private $context;
public function __construct( ApiMain $main, $action ) {
parent::__construct( $main, $action );
- $this->queryObj = new ApiQuery( $this->getMain(), 'query' );
}
public function execute() {
// Get parameters
$params = $this->extractRequestParams();
- $resultObj = $this->getResult();
+
+ $this->helpFormat = $params['helpformat'];
+ $this->context = new RequestContext;
+ $this->context->setUser( new User ); // anon to avoid caching issues
+ $this->context->setLanguage( $this->getMain()->getLanguage() );
+
+ if ( is_array( $params['modules'] ) ) {
+ $modules = $params['modules'];
+ } else {
+ $modules = array();
+ }
+
+ if ( is_array( $params['querymodules'] ) ) {
+ $this->logFeatureUsage( 'action=paraminfo&querymodules' );
+ $queryModules = $params['querymodules'];
+ foreach ( $queryModules as $m ) {
+ $modules[] = 'query+' . $m;
+ }
+ } else {
+ $queryModules = array();
+ }
+
+ if ( is_array( $params['formatmodules'] ) ) {
+ $this->logFeatureUsage( 'action=paraminfo&formatmodules' );
+ $formatModules = $params['formatmodules'];
+ foreach ( $formatModules as $m ) {
+ $modules[] = $m;
+ }
+ } else {
+ $formatModules = array();
+ }
$res = array();
- $this->addModulesInfo( $params, 'modules', $res, $resultObj );
+ foreach ( $modules as $m ) {
+ try {
+ $module = $this->getModuleFromPath( $m );
+ } catch ( UsageException $ex ) {
+ $this->setWarning( $ex->getMessage() );
+ continue;
+ }
+ $key = 'modules';
+
+ // Back compat
+ $isBCQuery = false;
+ if ( $module->getParent() && $module->getParent()->getModuleName() == 'query' &&
+ in_array( $module->getModuleName(), $queryModules )
+ ) {
+ $isBCQuery = true;
+ $key = 'querymodules';
+ }
+ if ( in_array( $module->getModuleName(), $formatModules ) ) {
+ $key = 'formatmodules';
+ }
- $this->addModulesInfo( $params, 'querymodules', $res, $resultObj );
+ $item = $this->getModuleInfo( $module );
+ if ( $isBCQuery ) {
+ $item['querytype'] = $item['group'];
+ }
+ $res[$key][] = $item;
+ }
+
+ $result = $this->getResult();
+ $result->addValue( array( $this->getModuleName() ), 'helpformat', $this->helpFormat );
+
+ foreach ( $res as $key => $stuff ) {
+ ApiResult::setIndexedTagName( $res[$key], 'module' );
+ }
if ( $params['mainmodule'] ) {
- $res['mainmodule'] = $this->getClassInfo( $this->getMain() );
+ $this->logFeatureUsage( 'action=paraminfo&mainmodule' );
+ $res['mainmodule'] = $this->getModuleInfo( $this->getMain() );
}
if ( $params['pagesetmodule'] ) {
- $pageSet = new ApiPageSet( $this->queryObj );
- $res['pagesetmodule'] = $this->getClassInfo( $pageSet );
+ $this->logFeatureUsage( 'action=paraminfo&pagesetmodule' );
+ $pageSet = new ApiPageSet( $this->getMain()->getModuleManager()->getModule( 'query' ) );
+ $res['pagesetmodule'] = $this->getModuleInfo( $pageSet );
+ unset( $res['pagesetmodule']['name'] );
+ unset( $res['pagesetmodule']['path'] );
+ unset( $res['pagesetmodule']['group'] );
}
- $this->addModulesInfo( $params, 'formatmodules', $res, $resultObj );
-
- $resultObj->addValue( null, $this->getModuleName(), $res );
+ $result->addValue( null, $this->getModuleName(), $res );
}
/**
- * If the type is requested in parameters, adds a section to res with module info.
- * @param array $params User parameters array
- * @param string $type Parameter name
- * @param array $res Store results in this array
- * @param ApiResult $resultObj Results object to set indexed tag.
+ * @param array $res Result array
+ * @param string $key Result key
+ * @param Message[] $msgs
+ * @param bool $joinLists
*/
- private function addModulesInfo( $params, $type, &$res, $resultObj ) {
- if ( !is_array( $params[$type] ) ) {
- return;
- }
- $isQuery = ( $type === 'querymodules' );
- if ( $isQuery ) {
- $mgr = $this->queryObj->getModuleManager();
- } else {
- $mgr = $this->getMain()->getModuleManager();
- }
- $res[$type] = array();
- foreach ( $params[$type] as $mod ) {
- if ( !$mgr->isDefined( $mod ) ) {
- $res[$type][] = array( 'name' => $mod, 'missing' => '' );
- continue;
- }
- $obj = $mgr->getModule( $mod );
- $item = $this->getClassInfo( $obj );
- $item['name'] = $mod;
- if ( $isQuery ) {
- $item['querytype'] = $mgr->getModuleGroup( $mod );
- }
- $res[$type][] = $item;
+ protected function formatHelpMessages( array &$res, $key, array $msgs, $joinLists = false ) {
+ switch ( $this->helpFormat ) {
+ case 'none':
+ break;
+
+ case 'wikitext':
+ $ret = array();
+ foreach ( $msgs as $m ) {
+ $ret[] = $m->setContext( $this->context )->text();
+ }
+ $res[$key] = join( "\n\n", $ret );
+ if ( $joinLists ) {
+ $res[$key] = preg_replace( '!^(([*#:;])[^\n]*)\n\n(?=\2)!m', "$1\n", $res[$key] );
+ }
+ break;
+
+ case 'html':
+ $ret = array();
+ foreach ( $msgs as $m ) {
+ $ret[] = $m->setContext( $this->context )->parseAsBlock();
+ }
+ $ret = join( "\n", $ret );
+ if ( $joinLists ) {
+ $ret = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $ret );
+ }
+ $res[$key] = Parser::stripOuterParagraph( $ret );
+ break;
+
+ case 'raw':
+ $res[$key] = array();
+ foreach ( $msgs as $m ) {
+ $a = array(
+ 'key' => $m->getKey(),
+ 'params' => $m->getParams(),
+ );
+ if ( $m instanceof ApiHelpParamValueMessage ) {
+ $a['forvalue'] = $m->getParamValue();
+ }
+ $res[$key][] = $a;
+ }
+ ApiResult::setIndexedTagName( $res[$key], 'msg' );
+ break;
}
- $resultObj->setIndexedTagName( $res[$type], 'module' );
}
/**
- * @param ApiBase $obj
+ * @param ApiBase $module
* @return ApiResult
*/
- private function getClassInfo( $obj ) {
+ private function getModuleInfo( $module ) {
$result = $this->getResult();
- $retval['classname'] = get_class( $obj );
- $retval['description'] = implode( "\n", (array)$obj->getFinalDescription() );
- $retval['examples'] = '';
-
- // version is deprecated since 1.21, but needs to be returned for v1
- $retval['version'] = '';
- $retval['prefix'] = $obj->getModulePrefix();
-
- if ( $obj->isReadMode() ) {
- $retval['readrights'] = '';
- }
- if ( $obj->isWriteMode() ) {
- $retval['writerights'] = '';
- }
- if ( $obj->mustBePosted() ) {
- $retval['mustbeposted'] = '';
- }
- if ( $obj instanceof ApiQueryGeneratorBase ) {
- $retval['generator'] = '';
+ $ret = array();
+ $path = $module->getModulePath();
+
+ $ret['name'] = $module->getModuleName();
+ $ret['classname'] = get_class( $module );
+ $ret['path'] = $path;
+ if ( !$module->isMain() ) {
+ $ret['group'] = $module->getParent()->getModuleManager()->getModuleGroup(
+ $module->getModuleName()
+ );
}
+ $ret['prefix'] = $module->getModulePrefix();
- $allowedParams = $obj->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
- if ( !is_array( $allowedParams ) ) {
- return $retval;
- }
+ $this->formatHelpMessages( $ret, 'description', $module->getFinalDescription() );
- $retval['helpurls'] = (array)$obj->getHelpUrls();
- if ( isset( $retval['helpurls'][0] ) && $retval['helpurls'][0] === false ) {
- $retval['helpurls'] = array();
+ foreach ( $module->getHelpFlags() as $flag ) {
+ $ret[$flag] = true;
}
- $result->setIndexedTagName( $retval['helpurls'], 'helpurl' );
- $examples = $obj->getExamples();
- $retval['allexamples'] = array();
- if ( $examples !== false ) {
- if ( is_string( $examples ) ) {
- $examples = array( $examples );
- }
- foreach ( $examples as $k => $v ) {
- if ( strlen( $retval['examples'] ) ) {
- $retval['examples'] .= ' ';
- }
- $item = array();
- if ( is_numeric( $k ) ) {
- $retval['examples'] .= $v;
- ApiResult::setContent( $item, $v );
- } else {
- if ( !is_array( $v ) ) {
- $item['description'] = $v;
+ $ret['helpurls'] = (array)$module->getHelpUrls();
+ if ( isset( $ret['helpurls'][0] ) && $ret['helpurls'][0] === false ) {
+ $ret['helpurls'] = array();
+ }
+ ApiResult::setIndexedTagName( $ret['helpurls'], 'helpurl' );
+
+ if ( $this->helpFormat !== 'none' ) {
+ $ret['examples'] = array();
+ $examples = $module->getExamplesMessages();
+ foreach ( $examples as $qs => $msg ) {
+ $item = array(
+ 'query' => $qs
+ );
+ $msg = ApiBase::makeMessage( $msg, $this->context, array(
+ $module->getModulePrefix(),
+ $module->getModuleName(),
+ $module->getModulePath()
+ ) );
+ $this->formatHelpMessages( $item, 'description', array( $msg ) );
+ if ( isset( $item['description'] ) ) {
+ if ( is_array( $item['description'] ) ) {
+ $item['description'] = $item['description'][0];
} else {
- $item['description'] = implode( $v, "\n" );
+ ApiResult::setSubelementsList( $item, 'description' );
}
- $retval['examples'] .= $item['description'] . ' ' . $k;
- ApiResult::setContent( $item, $k );
}
- $retval['allexamples'][] = $item;
+ $ret['examples'][] = $item;
}
+ ApiResult::setIndexedTagName( $ret['examples'], 'example' );
}
- $result->setIndexedTagName( $retval['allexamples'], 'example' );
-
- $retval['parameters'] = array();
- $paramDesc = $obj->getFinalParamDescription();
- foreach ( $allowedParams as $n => $p ) {
- $a = array( 'name' => $n );
- if ( isset( $paramDesc[$n] ) ) {
- $a['description'] = implode( "\n", (array)$paramDesc[$n] );
- }
- //handle shorthand
- if ( !is_array( $p ) ) {
- $p = array(
- ApiBase::PARAM_DFLT => $p,
- );
+ $ret['parameters'] = array();
+ $params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
+ $paramDesc = $module->getFinalParamDescription();
+ foreach ( $params as $name => $settings ) {
+ if ( !is_array( $settings ) ) {
+ $settings = array( ApiBase::PARAM_DFLT => $settings );
}
- //handle missing type
- if ( !isset( $p[ApiBase::PARAM_TYPE] ) ) {
- $dflt = isset( $p[ApiBase::PARAM_DFLT] ) ? $p[ApiBase::PARAM_DFLT] : null;
- if ( is_bool( $dflt ) ) {
- $p[ApiBase::PARAM_TYPE] = 'boolean';
- } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
- $p[ApiBase::PARAM_TYPE] = 'string';
- } elseif ( is_int( $dflt ) ) {
- $p[ApiBase::PARAM_TYPE] = 'integer';
- }
+ $item = array(
+ 'name' => $name
+ );
+ if ( isset( $paramDesc[$name] ) ) {
+ $this->formatHelpMessages( $item, 'description', $paramDesc[$name], true );
}
- if ( isset( $p[ApiBase::PARAM_DEPRECATED] ) && $p[ApiBase::PARAM_DEPRECATED] ) {
- $a['deprecated'] = '';
+ $item['required'] = !empty( $settings[ApiBase::PARAM_REQUIRED] );
+
+ if ( !empty( $settings[ApiBase::PARAM_DEPRECATED] ) ) {
+ $item['deprecated'] = true;
}
- if ( isset( $p[ApiBase::PARAM_REQUIRED] ) && $p[ApiBase::PARAM_REQUIRED] ) {
- $a['required'] = '';
+
+ if ( $name === 'token' && $module->needsToken() ) {
+ $item['tokentype'] = $module->needsToken();
}
- if ( $n === 'token' && $obj->needsToken() ) {
- $a['tokentype'] = $obj->needsToken();
+ if ( !isset( $settings[ApiBase::PARAM_TYPE] ) ) {
+ $dflt = isset( $settings[ApiBase::PARAM_DFLT] )
+ ? $settings[ApiBase::PARAM_DFLT]
+ : null;
+ if ( is_bool( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'boolean';
+ } elseif ( is_string( $dflt ) || is_null( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'string';
+ } elseif ( is_int( $dflt ) ) {
+ $settings[ApiBase::PARAM_TYPE] = 'integer';
+ }
}
- if ( isset( $p[ApiBase::PARAM_DFLT] ) ) {
- $type = $p[ApiBase::PARAM_TYPE];
- if ( $type === 'boolean' ) {
- $a['default'] = ( $p[ApiBase::PARAM_DFLT] ? 'true' : 'false' );
- } elseif ( $type === 'string' ) {
- $a['default'] = strval( $p[ApiBase::PARAM_DFLT] );
- } elseif ( $type === 'integer' ) {
- $a['default'] = intval( $p[ApiBase::PARAM_DFLT] );
- } else {
- $a['default'] = $p[ApiBase::PARAM_DFLT];
+ if ( isset( $settings[ApiBase::PARAM_DFLT] ) ) {
+ switch ( $settings[ApiBase::PARAM_TYPE] ) {
+ case 'boolean':
+ $item['default'] = ( $settings[ApiBase::PARAM_DFLT] ? 'true' : 'false' );
+ break;
+ case 'string':
+ $item['default'] = strval( $settings[ApiBase::PARAM_DFLT] );
+ break;
+ case 'integer':
+ $item['default'] = intval( $settings[ApiBase::PARAM_DFLT] );
+ break;
+ default:
+ $item['default'] = $settings[ApiBase::PARAM_DFLT];
+ break;
}
}
- if ( isset( $p[ApiBase::PARAM_ISMULTI] ) && $p[ApiBase::PARAM_ISMULTI] ) {
- $a['multi'] = '';
- $a['limit'] = $this->getMain()->canApiHighLimits() ?
+
+ $item['multi'] = !empty( $settings[ApiBase::PARAM_ISMULTI] );
+ if ( $item['multi'] ) {
+ $item['limit'] = $this->getMain()->canApiHighLimits() ?
ApiBase::LIMIT_SML2 :
ApiBase::LIMIT_SML1;
- $a['lowlimit'] = ApiBase::LIMIT_SML1;
- $a['highlimit'] = ApiBase::LIMIT_SML2;
+ $item['lowlimit'] = ApiBase::LIMIT_SML1;
+ $item['highlimit'] = ApiBase::LIMIT_SML2;
}
- if ( isset( $p[ApiBase::PARAM_ALLOW_DUPLICATES] ) && $p[ApiBase::PARAM_ALLOW_DUPLICATES] ) {
- $a['allowsduplicates'] = '';
+ if ( !empty( $settings[ApiBase::PARAM_ALLOW_DUPLICATES] ) ) {
+ $item['allowsduplicates'] = true;
}
- if ( isset( $p[ApiBase::PARAM_TYPE] ) ) {
- if ( $p[ApiBase::PARAM_TYPE] === 'submodule' ) {
- $a['type'] = $obj->getModuleManager()->getNames( $n );
- sort( $a['type'] );
- $a['submodules'] = '';
+ if ( isset( $settings[ApiBase::PARAM_TYPE] ) ) {
+ if ( $settings[ApiBase::PARAM_TYPE] === 'submodule' ) {
+ $item['type'] = $module->getModuleManager()->getNames( $name );
+ sort( $item['type'] );
+ $item['submodules'] = true;
} else {
- $a['type'] = $p[ApiBase::PARAM_TYPE];
+ $item['type'] = $settings[ApiBase::PARAM_TYPE];
}
- if ( is_array( $a['type'] ) ) {
+ if ( is_array( $item['type'] ) ) {
// To prevent sparse arrays from being serialized to JSON as objects
- $a['type'] = array_values( $a['type'] );
- $result->setIndexedTagName( $a['type'], 't' );
+ $item['type'] = array_values( $item['type'] );
+ ApiResult::setIndexedTagName( $item['type'], 't' );
}
}
- if ( isset( $p[ApiBase::PARAM_MAX] ) ) {
- $a['max'] = $p[ApiBase::PARAM_MAX];
+ if ( isset( $settings[ApiBase::PARAM_MAX] ) ) {
+ $item['max'] = $settings[ApiBase::PARAM_MAX];
+ }
+ if ( isset( $settings[ApiBase::PARAM_MAX2] ) ) {
+ $item['highmax'] = $settings[ApiBase::PARAM_MAX2];
}
- if ( isset( $p[ApiBase::PARAM_MAX2] ) ) {
- $a['highmax'] = $p[ApiBase::PARAM_MAX2];
+ if ( isset( $settings[ApiBase::PARAM_MIN] ) ) {
+ $item['min'] = $settings[ApiBase::PARAM_MIN];
}
- if ( isset( $p[ApiBase::PARAM_MIN] ) ) {
- $a['min'] = $p[ApiBase::PARAM_MIN];
+
+ if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
+ $item['info'] = array();
+ foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
+ $tag = array_shift( $i );
+ $info = array(
+ 'name' => $tag,
+ );
+ if ( count( $i ) ) {
+ $info['values'] = $i;
+ ApiResult::setIndexedTagName( $info['values'], 'v' );
+ }
+ $this->formatHelpMessages( $info, 'text', array(
+ $this->context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
+ ->numParams( count( $i ) )
+ ->params( $this->context->getLanguage()->commaList( $i ) )
+ ->params( $module->getModulePrefix() )
+ ) );
+ ApiResult::setSubelementsList( $info, 'text' );
+ $item['info'][] = $info;
+ }
+ ApiResult::setIndexedTagName( $item['info'], 'i' );
}
- $retval['parameters'][] = $a;
+
+ $ret['parameters'][] = $item;
}
- $result->setIndexedTagName( $retval['parameters'], 'param' );
+ ApiResult::setIndexedTagName( $ret['parameters'], 'param' );
- return $retval;
+ return $ret;
}
public function isReadMode() {
@@ -262,9 +359,9 @@ class ApiParamInfo extends ApiBase {
}
public function getAllowedParams() {
- $modules = $this->getMain()->getModuleManager()->getNames( 'action' );
- sort( $modules );
- $querymodules = $this->queryObj->getModuleManager()->getNames();
+ // back compat
+ $querymodules = $this->getMain()->getModuleManager()
+ ->getModule( 'query' )->getModuleManager()->getNames();
sort( $querymodules );
$formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' );
sort( $formatmodules );
@@ -272,39 +369,35 @@ class ApiParamInfo extends ApiBase {
return array(
'modules' => array(
ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_TYPE => $modules,
),
+ 'helpformat' => array(
+ ApiBase::PARAM_DFLT => 'none',
+ ApiBase::PARAM_TYPE => array( 'html', 'wikitext', 'raw', 'none' ),
+ ),
+
'querymodules' => array(
+ ApiBase::PARAM_DEPRECATED => true,
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => $querymodules,
),
- 'mainmodule' => false,
- 'pagesetmodule' => false,
+ 'mainmodule' => array(
+ ApiBase::PARAM_DEPRECATED => true,
+ ),
+ 'pagesetmodule' => array(
+ ApiBase::PARAM_DEPRECATED => true,
+ ),
'formatmodules' => array(
+ ApiBase::PARAM_DEPRECATED => true,
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => $formatmodules,
)
);
}
- public function getParamDescription() {
- return array(
- 'modules' => 'List of module names (value of the action= parameter)',
- 'querymodules' => 'List of query module names (value of prop=, meta= or list= parameter)',
- 'mainmodule' => 'Get information about the main (top-level) module as well',
- 'pagesetmodule' => 'Get information about the pageset module ' .
- '(providing titles= and friends) as well',
- 'formatmodules' => 'List of format module names (value of format= parameter)',
- );
- }
-
- public function getDescription() {
- return 'Obtain information about certain API parameters and errors.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=paraminfo&modules=parse&querymodules=allpages|siteinfo'
+ 'action=paraminfo&modules=parse|phpfm|query+allpages|query+siteinfo'
+ => 'apihelp-paraminfo-example-1',
);
}
diff --git a/includes/api/ApiParse.php b/includes/api/ApiParse.php
index 06fdf85b..1b5e2658 100644
--- a/includes/api/ApiParse.php
+++ b/includes/api/ApiParse.php
@@ -70,6 +70,9 @@ class ApiParse extends ApiBase {
if ( isset( $params['section'] ) ) {
$this->section = $params['section'];
+ if ( !preg_match( '/^((T-)?\d+|new)$/', $this->section ) ) {
+ $this->dieUsage( "The section parameter must be a valid section id or 'new'", "invalidsection" );
+ }
} else {
$this->section = false;
}
@@ -79,25 +82,18 @@ class ApiParse extends ApiBase {
// TODO: Does this still need $wgTitle?
global $wgParser, $wgTitle;
- // Currently unnecessary, code to act as a safeguard against any change
- // in current behavior of uselang
- $oldLang = null;
- if ( isset( $params['uselang'] )
- && $params['uselang'] != $this->getContext()->getLanguage()->getCode()
- ) {
- $oldLang = $this->getContext()->getLanguage(); // Backup language
- $this->getContext()->setLanguage( Language::factory( $params['uselang'] ) );
- }
-
$redirValues = null;
// Return result
$result = $this->getResult();
if ( !is_null( $oldid ) || !is_null( $pageid ) || !is_null( $page ) ) {
+ if ( $this->section === 'new' ) {
+ $this->dieUsage( 'section=new cannot be combined with oldid, pageid or page parameters. Please use text', 'params' );
+ }
if ( !is_null( $oldid ) ) {
// Don't use the parser cache
- $rev = Revision::newFromID( $oldid );
+ $rev = Revision::newFromId( $oldid );
if ( !$rev ) {
$this->dieUsage( "There is no revision ID $oldid", 'missingrev' );
}
@@ -128,7 +124,6 @@ class ApiParse extends ApiBase {
} else { // Not $oldid, but $pageid or $page
if ( $params['redirects'] ) {
$reqParams = array(
- 'action' => 'query',
'redirects' => '',
);
if ( !is_null( $pageid ) ) {
@@ -138,14 +133,13 @@ class ApiParse extends ApiBase {
}
$req = new FauxRequest( $reqParams );
$main = new ApiMain( $req );
- $main->execute();
- $data = $main->getResultData();
- $redirValues = isset( $data['query']['redirects'] )
- ? $data['query']['redirects']
- : array();
+ $pageSet = new ApiPageSet( $main );
+ $pageSet->execute();
+ $redirValues = $pageSet->getRedirectTitlesAsResult( $this->getResult() );
+
$to = $page;
- foreach ( (array)$redirValues as $r ) {
- $to = $r['to'];
+ foreach ( $pageSet->getRedirectTitles() as $title ) {
+ $to = $title->getFullText();
}
$pageParams = array( 'title' => $to );
} elseif ( !is_null( $pageid ) ) {
@@ -213,7 +207,14 @@ class ApiParse extends ApiBase {
}
if ( $this->section !== false ) {
- $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
+ if ( $this->section === 'new' ) {
+ // Insert the section title above the content.
+ if ( !is_null( $params['sectiontitle'] ) && $params['sectiontitle'] !== '' ) {
+ $this->content = $this->content->addSectionHeader( $params['sectiontitle'] );
+ }
+ } else {
+ $this->content = $this->getSectionContent( $this->content, $titleObj->getPrefixedText() );
+ }
}
if ( $params['pst'] || $params['onlypst'] ) {
@@ -222,12 +223,19 @@ class ApiParse extends ApiBase {
if ( $params['onlypst'] ) {
// Build a result and bail out
$result_array = array();
- $result_array['text'] = array();
- ApiResult::setContent( $result_array['text'], $this->pstContent->serialize( $format ) );
+ $result_array['text'] = $this->pstContent->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
if ( isset( $prop['wikitext'] ) ) {
- $result_array['wikitext'] = array();
- ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) );
+ $result_array['wikitext'] = $this->content->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
}
+ if ( !is_null( $params['summary'] ) ||
+ ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
+ ) {
+ $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
+ }
+
$result->addValue( null, $this->getModuleName(), $result_array );
return;
@@ -258,16 +266,15 @@ class ApiParse extends ApiBase {
}
if ( isset( $prop['text'] ) ) {
- $result_array['text'] = array();
- ApiResult::setContent( $result_array['text'], $p_result->getText() );
+ $result_array['text'] = $p_result->getText();
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
}
- if ( !is_null( $params['summary'] ) ) {
- $result_array['parsedsummary'] = array();
- ApiResult::setContent(
- $result_array['parsedsummary'],
- Linker::formatComment( $params['summary'], $titleObj )
- );
+ if ( !is_null( $params['summary'] ) ||
+ ( !is_null( $params['sectiontitle'] ) && $this->section === 'new' )
+ ) {
+ $result_array['parsedsummary'] = $this->formatSummary( $titleObj, $params );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
}
if ( isset( $prop['langlinks'] ) ) {
@@ -277,7 +284,7 @@ class ApiParse extends ApiBase {
// Link flags are ignored for now, but may in the future be
// included in the result.
$linkFlags = array();
- wfRunHooks( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
+ Hooks::run( 'LanguageLinks', array( $titleObj, &$langlinks, &$linkFlags ) );
}
} else {
$langlinks = false;
@@ -290,9 +297,8 @@ class ApiParse extends ApiBase {
$result_array['categories'] = $this->formatCategoryLinks( $p_result->getCategories() );
}
if ( isset( $prop['categorieshtml'] ) ) {
- $categoriesHtml = $this->categoriesHtml( $p_result->getCategories() );
- $result_array['categorieshtml'] = array();
- ApiResult::setContent( $result_array['categorieshtml'], $categoriesHtml );
+ $result_array['categorieshtml'] = $this->categoriesHtml( $p_result->getCategories() );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
}
if ( isset( $prop['links'] ) ) {
$result_array['links'] = $this->formatLinks( $p_result->getLinks() );
@@ -332,11 +338,8 @@ class ApiParse extends ApiBase {
}
if ( isset( $prop['headhtml'] ) ) {
- $result_array['headhtml'] = array();
- ApiResult::setContent(
- $result_array['headhtml'],
- $context->getOutput()->headElement( $context->getSkin() )
- );
+ $result_array['headhtml'] = $context->getOutput()->headElement( $context->getSkin() );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
}
}
@@ -347,20 +350,26 @@ class ApiParse extends ApiBase {
$result_array['modulemessages'] = array_values( array_unique( $p_result->getModuleMessages() ) );
}
+ if ( isset( $prop['indicators'] ) ) {
+ $result_array['indicators'] = (array)$p_result->getIndicators();
+ ApiResult::setArrayType( $result_array['indicators'], 'BCkvp', 'name' );
+ }
+
if ( isset( $prop['iwlinks'] ) ) {
$result_array['iwlinks'] = $this->formatIWLinks( $p_result->getInterwikiLinks() );
}
if ( isset( $prop['wikitext'] ) ) {
- $result_array['wikitext'] = array();
- ApiResult::setContent( $result_array['wikitext'], $this->content->serialize( $format ) );
+ $result_array['wikitext'] = $this->content->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
if ( !is_null( $this->pstContent ) ) {
- $result_array['psttext'] = array();
- ApiResult::setContent( $result_array['psttext'], $this->pstContent->serialize( $format ) );
+ $result_array['psttext'] = $this->pstContent->serialize( $format );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'psttext';
}
}
if ( isset( $prop['properties'] ) ) {
- $result_array['properties'] = $this->formatProperties( $p_result->getProperties() );
+ $result_array['properties'] = (array)$p_result->getProperties();
+ ApiResult::setArrayType( $result_array['properties'], 'BCkvp', 'name' );
}
if ( isset( $prop['limitreportdata'] ) ) {
@@ -368,9 +377,8 @@ class ApiParse extends ApiBase {
$this->formatLimitReportData( $p_result->getLimitReportData() );
}
if ( isset( $prop['limitreporthtml'] ) ) {
- $limitreportHtml = EditPage::getPreviewLimitReport( $p_result );
- $result_array['limitreporthtml'] = array();
- ApiResult::setContent( $result_array['limitreporthtml'], $limitreportHtml );
+ $result_array['limitreporthtml'] = EditPage::getPreviewLimitReport( $p_result );
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'limitreporthtml';
}
if ( $params['generatexml'] ) {
@@ -378,15 +386,15 @@ class ApiParse extends ApiBase {
$this->dieUsage( "generatexml is only supported for wikitext content", "notwikitext" );
}
- $wgParser->startExternalParse( $titleObj, $popts, OT_PREPROCESS );
+ $wgParser->startExternalParse( $titleObj, $popts, Parser::OT_PREPROCESS );
$dom = $wgParser->preprocessToDom( $this->content->getNativeData() );
if ( is_callable( array( $dom, 'saveXML' ) ) ) {
$xml = $dom->saveXML();
} else {
$xml = $dom->__toString();
}
- $result_array['parsetree'] = array();
- ApiResult::setContent( $result_array['parsetree'], $xml );
+ $result_array['parsetree'] = $xml;
+ $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
}
$result_mapping = array(
@@ -401,6 +409,7 @@ class ApiParse extends ApiBase {
'sections' => 's',
'headitems' => 'hi',
'modules' => 'm',
+ 'indicators' => 'ind',
'modulescripts' => 'm',
'modulestyles' => 'm',
'modulemessages' => 'm',
@@ -409,10 +418,6 @@ class ApiParse extends ApiBase {
);
$this->setIndexedTagNames( $result_array, $result_mapping );
$result->addValue( null, $this->getModuleName(), $result_array );
-
- if ( !is_null( $oldLang ) ) {
- $this->getContext()->setLanguage( $oldLang ); // Reset language to $oldLang
- }
}
/**
@@ -424,7 +429,6 @@ class ApiParse extends ApiBase {
* @return ParserOptions
*/
protected function makeParserOptions( WikiPage $pageObj, array $params ) {
- wfProfileIn( __METHOD__ );
$popts = $pageObj->makeParserOptions( $this->getContext() );
$popts->enableLimitReport( !$params['disablepp'] );
@@ -432,8 +436,6 @@ class ApiParse extends ApiBase {
$popts->setIsSectionPreview( $params['sectionpreview'] );
$popts->setEditSection( !$params['disableeditsection'] );
- wfProfileOut( __METHOD__ );
-
return $popts;
}
@@ -489,6 +491,30 @@ class ApiParse extends ApiBase {
return $section;
}
+ /**
+ * This mimicks the behavior of EditPage in formatting a summary
+ *
+ * @param Title $title of the page being parsed
+ * @param Array $params the API parameters of the request
+ * @return Content|bool
+ */
+ private function formatSummary( $title, $params ) {
+ global $wgParser;
+ $summary = !is_null( $params['summary'] ) ? $params['summary'] : '';
+ $sectionTitle = !is_null( $params['sectiontitle'] ) ? $params['sectiontitle'] : '';
+
+ if ( $this->section === 'new' && ( $sectionTitle === '' || $summary === '' ) ) {
+ if( $sectionTitle !== '' ) {
+ $summary = $params['sectiontitle'];
+ }
+ if ( $summary !== '' ) {
+ $summary = wfMessage( 'newsectionsummary' )->rawParams( $wgParser->stripSectionName( $summary ) )
+ ->inContentLanguage()->text();
+ }
+ }
+ return Linker::formatComment( $summary, $title, $this->section === 'new' );
+ }
+
private function formatLangLinks( $links ) {
$result = array();
foreach ( $links as $link ) {
@@ -499,7 +525,7 @@ class ApiParse extends ApiBase {
$entry['lang'] = $bits[0];
if ( $title ) {
$entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
- // localised language name in user language (maybe set by uselang=)
+ // localised language name in 'uselang' language
$entry['langname'] = Language::fetchLanguageName(
$title->getInterwiki(),
$this->getLanguage()->getCode()
@@ -508,7 +534,7 @@ class ApiParse extends ApiBase {
// native language name
$entry['autonym'] = Language::fetchLanguageName( $title->getInterwiki() );
}
- ApiResult::setContent( $entry, $bits[1] );
+ ApiResult::setContentValue( $entry, 'title', $bits[1] );
$result[] = $entry;
}
@@ -543,11 +569,11 @@ class ApiParse extends ApiBase {
foreach ( $links as $link => $sortkey ) {
$entry = array();
$entry['sortkey'] = $sortkey;
- ApiResult::setContent( $entry, $link );
+ ApiResult::setContentValue( $entry, 'category', $link );
if ( !isset( $hiddencats[$link] ) ) {
- $entry['missing'] = '';
+ $entry['missing'] = true;
} elseif ( $hiddencats[$link] ) {
- $entry['hidden'] = '';
+ $entry['hidden'] = true;
}
$result[] = $entry;
}
@@ -568,10 +594,8 @@ class ApiParse extends ApiBase {
foreach ( $nslinks as $title => $id ) {
$entry = array();
$entry['ns'] = $ns;
- ApiResult::setContent( $entry, Title::makeTitle( $ns, $title )->getFullText() );
- if ( $id != 0 ) {
- $entry['exists'] = '';
- }
+ ApiResult::setContentValue( $entry, 'title', Title::makeTitle( $ns, $title )->getFullText() );
+ $entry['exists'] = $id != 0;
$result[] = $entry;
}
}
@@ -591,7 +615,7 @@ class ApiParse extends ApiBase {
$entry['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
}
- ApiResult::setContent( $entry, $title->getFullText() );
+ ApiResult::setContentValue( $entry, 'title', $title->getFullText() );
$result[] = $entry;
}
}
@@ -604,19 +628,7 @@ class ApiParse extends ApiBase {
foreach ( $headItems as $tag => $content ) {
$entry = array();
$entry['tag'] = $tag;
- ApiResult::setContent( $entry, $content );
- $result[] = $entry;
- }
-
- return $result;
- }
-
- private function formatProperties( $properties ) {
- $result = array();
- foreach ( $properties as $name => $value ) {
- $entry = array();
- $entry['name'] = $name;
- ApiResult::setContent( $entry, $value );
+ ApiResult::setContentValue( $entry, 'content', $content );
$result[] = $entry;
}
@@ -628,7 +640,7 @@ class ApiParse extends ApiBase {
foreach ( $css as $file => $link ) {
$entry = array();
$entry['file'] = $file;
- ApiResult::setContent( $entry, $link );
+ ApiResult::setContentValue( $entry, 'link', $link );
$result[] = $entry;
}
@@ -645,8 +657,7 @@ class ApiParse extends ApiBase {
if ( !is_array( $value ) ) {
$value = array( $value );
}
- $apiResult->setIndexedTagName( $value, 'param' );
- $apiResult->setIndexedTagName_recursive( $value, 'param' );
+ ApiResult::setIndexedTagNameRecursive( $value, 'param' );
$entry = array_merge( $entry, $value );
$result[] = $entry;
}
@@ -657,7 +668,7 @@ class ApiParse extends ApiBase {
private function setIndexedTagNames( &$array, $mapping ) {
foreach ( $mapping as $key => $name ) {
if ( isset( $array[$key] ) ) {
- $this->getResult()->setIndexedTagName( $array[$key], $name );
+ ApiResult::setIndexedTagName( $array[$key], $name );
}
}
}
@@ -694,6 +705,7 @@ class ApiParse extends ApiBase {
'headitems',
'headhtml',
'modules',
+ 'indicators',
'iwlinks',
'wikitext',
'properties',
@@ -704,11 +716,18 @@ class ApiParse extends ApiBase {
'pst' => false,
'onlypst' => false,
'effectivelanglinks' => false,
- 'uselang' => null,
'section' => null,
+ 'sectiontitle' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ),
'disablepp' => false,
'disableeditsection' => false,
- 'generatexml' => false,
+ 'generatexml' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-parse-param-generatexml', CONTENT_MODEL_WIKITEXT
+ ),
+ ),
'preview' => false,
'sectionpreview' => false,
'disabletoc' => false,
@@ -721,97 +740,16 @@ class ApiParse extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
- $wikitext = CONTENT_MODEL_WIKITEXT;
-
- return array(
- 'text' => "Text to parse. Use {$p}title or {$p}contentmodel to control the content model",
- 'summary' => 'Summary to parse',
- 'redirects' => "If the {$p}page or the {$p}pageid parameter is set to a redirect, resolve it",
- 'title' => "Title of page the text belongs to. " .
- "If omitted, {$p}contentmodel must be specified, and \"API\" will be used as the title",
- 'page' => "Parse the content of this page. Cannot be used together with {$p}text and {$p}title",
- 'pageid' => "Parse the content of this page. Overrides {$p}page",
- 'oldid' => "Parse the content of this revision. Overrides {$p}page and {$p}pageid",
- 'prop' => array(
- 'Which pieces of information to get',
- ' text - Gives the parsed text of the wikitext',
- ' langlinks - Gives the language links in the parsed wikitext',
- ' categories - Gives the categories in the parsed wikitext',
- ' categorieshtml - Gives the HTML version of the categories',
- ' links - Gives the internal links in the parsed wikitext',
- ' templates - Gives the templates in the parsed wikitext',
- ' images - Gives the images in the parsed wikitext',
- ' externallinks - Gives the external links in the parsed wikitext',
- ' sections - Gives the sections in the parsed wikitext',
- ' revid - Adds the revision ID of the parsed page',
- ' displaytitle - Adds the title of the parsed wikitext',
- ' headitems - Gives items to put in the <head> of the page',
- ' headhtml - Gives parsed <head> of the page',
- ' modules - Gives the ResourceLoader modules used on the page',
- ' iwlinks - Gives interwiki links in the parsed wikitext',
- ' wikitext - Gives the original wikitext that was parsed',
- ' properties - Gives various properties defined in the parsed wikitext',
- ' limitreportdata - Gives the limit report in a structured way.',
- " Gives no data, when {$p}disablepp is set.",
- ' limitreporthtml - Gives the HTML version of the limit report.',
- " Gives no data, when {$p}disablepp is set.",
- ),
- 'effectivelanglinks' => array(
- 'Includes language links supplied by extensions',
- '(for use with prop=langlinks)',
- ),
- 'pst' => array(
- 'Do a pre-save transform on the input before parsing it',
- "Only valid when used with {$p}text",
- ),
- 'onlypst' => array(
- 'Do a pre-save transform (PST) on the input, but don\'t parse it',
- 'Returns the same wikitext, after a PST has been applied.',
- "Only valid when used with {$p}text",
- ),
- 'uselang' => 'Which language to parse the request in',
- 'section' => 'Only retrieve the content of this section number',
- 'disablepp' => 'Disable the PP Report from the parser output',
- 'disableeditsection' => 'Disable edit section links from the parser output',
- 'generatexml' => "Generate XML parse tree (requires contentmodel=$wikitext)",
- 'preview' => 'Parse in preview mode',
- 'sectionpreview' => 'Parse in section preview mode (enables preview mode too)',
- 'disabletoc' => 'Disable table of contents in output',
- 'contentformat' => array(
- 'Content serialization format used for the input text',
- "Only valid when used with {$p}text",
- ),
- 'contentmodel' => array(
- "Content model of the input text. If omitted, ${p}title must be specified, " .
- "and default will be the model of the specified ${p}title",
- "Only valid when used with {$p}text",
- ),
- );
- }
-
- public function getDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'Parses content and returns parser output.',
- 'See the various prop-Modules of action=query to get information from the current' .
- 'version of a page.',
- 'There are several ways to specify the text to parse:',
- "1) Specify a page or revision, using {$p}page, {$p}pageid, or {$p}oldid.",
- "2) Specify content explicitly, using {$p}text, {$p}title, and {$p}contentmodel.",
- "3) Specify only a summary to parse. {$p}prop should be given an empty value.",
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=parse&page=Project:Sandbox' => 'Parse a page',
- 'api.php?action=parse&text={{Project:Sandbox}}&contentmodel=wikitext' => 'Parse wikitext',
- 'api.php?action=parse&text={{PAGENAME}}&title=Test'
- => 'Parse wikitext, specifying the page title',
- 'api.php?action=parse&summary=Some+[[link]]&prop=' => 'Parse a summary',
+ 'action=parse&page=Project:Sandbox'
+ => 'apihelp-parse-example-page',
+ 'action=parse&text={{Project:Sandbox}}&contentmodel=wikitext'
+ => 'apihelp-parse-example-text',
+ 'action=parse&text={{PAGENAME}}&title=Test'
+ => 'apihelp-parse-example-texttitle',
+ 'action=parse&summary=Some+[[link]]&prop='
+ => 'apihelp-parse-example-summary',
);
}
diff --git a/includes/api/ApiPatrol.php b/includes/api/ApiPatrol.php
index 8b66781a..779c4188 100644
--- a/includes/api/ApiPatrol.php
+++ b/includes/api/ApiPatrol.php
@@ -38,7 +38,7 @@ class ApiPatrol extends ApiBase {
$this->requireOnlyOneParameter( $params, 'rcid', 'revid' );
if ( isset( $params['rcid'] ) ) {
- $rc = RecentChange::newFromID( $params['rcid'] );
+ $rc = RecentChange::newFromId( $params['rcid'] );
if ( !$rc ) {
$this->dieUsageMsg( array( 'nosuchrcid', $params['rcid'] ) );
}
@@ -86,25 +86,16 @@ class ApiPatrol extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'rcid' => 'Recentchanges ID to patrol',
- 'revid' => 'Revision ID to patrol',
- );
- }
-
- public function getDescription() {
- return 'Patrol a page or revision.';
- }
-
public function needsToken() {
return 'patrol';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=patrol&token=123ABC&rcid=230672766',
- 'api.php?action=patrol&token=123ABC&revid=230672766'
+ 'action=patrol&token=123ABC&rcid=230672766'
+ => 'apihelp-patrol-example-rcid',
+ 'action=patrol&token=123ABC&revid=230672766'
+ => 'apihelp-patrol-example-revid',
);
}
diff --git a/includes/api/ApiProtect.php b/includes/api/ApiProtect.php
index a3d12b7f..ad028375 100644
--- a/includes/api/ApiProtect.php
+++ b/includes/api/ApiProtect.php
@@ -77,7 +77,7 @@ class ApiProtect extends ApiBase {
$this->dieUsageMsg( array( 'protect-invalidlevel', $p[1] ) );
}
- if ( in_array( $expiry[$i], array( 'infinite', 'indefinite', 'infinity', 'never' ) ) ) {
+ if ( wfIsInfinity( $expiry[$i] ) ) {
$expiryarray[$p[0]] = $db->getInfinity();
} else {
$exp = strtotime( $expiry[$i] );
@@ -124,11 +124,11 @@ class ApiProtect extends ApiBase {
'reason' => $params['reason']
);
if ( $cascade ) {
- $res['cascade'] = '';
+ $res['cascade'] = true;
}
$res['protections'] = $resultProtections;
$result = $this->getResult();
- $result->setIndexedTagName( $res['protections'], 'protection' );
+ ApiResult::setIndexedTagName( $res['protections'], 'protection' );
$result->addValue( null, $this->getModuleName(), $res );
}
@@ -175,43 +175,21 @@ class ApiProtect extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'title' => "Title of the page you want to (un)protect. Cannot be used together with {$p}pageid",
- 'pageid' => "ID of the page you want to (un)protect. Cannot be used together with {$p}title",
- 'protections' => 'List of protection levels, formatted action=group (e.g. edit=sysop)',
- 'expiry' => array(
- 'Expiry timestamps. If only one timestamp is ' .
- 'set, it\'ll be used for all protections.',
- 'Use \'infinite\', \'indefinite\', \'infinity\' or \'never\', for a never-expiring protection.'
- ),
- 'reason' => 'Reason for (un)protecting',
- 'cascade' => array(
- 'Enable cascading protection (i.e. protect pages included in this page)',
- 'Ignored if not all protection levels are \'sysop\' or \'protect\''
- ),
- 'watch' => 'If set, add the page being (un)protected to your watchlist',
- 'watchlist' => 'Unconditionally add or remove the page from your ' .
- 'watchlist, use preferences or do not change watch',
- );
- }
-
- public function getDescription() {
- return 'Change the protection level of a page.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=protect&title=Main%20Page&token=123ABC&' .
- 'protections=edit=sysop|move=sysop&cascade=&expiry=20070901163000|never',
- 'api.php?action=protect&title=Main%20Page&token=123ABC&' .
+ 'action=protect&title=Main%20Page&token=123ABC&' .
+ 'protections=edit=sysop|move=sysop&cascade=&expiry=20070901163000|never'
+ => 'apihelp-protect-example-protect',
+ 'action=protect&title=Main%20Page&token=123ABC&' .
'protections=edit=all|move=all&reason=Lifting%20restrictions'
+ => 'apihelp-protect-example-unprotect',
+ 'action=protect&title=Main%20Page&token=123ABC&' .
+ 'protections=&reason=Lifting%20restrictions'
+ => 'apihelp-protect-example-unprotect2',
);
}
diff --git a/includes/api/ApiPurge.php b/includes/api/ApiPurge.php
index 7667b235..a22be498 100644
--- a/includes/api/ApiPurge.php
+++ b/includes/api/ApiPurge.php
@@ -38,7 +38,8 @@ class ApiPurge extends ApiBase {
public function execute() {
$params = $this->extractRequestParams();
- $this->getResult()->beginContinuation( $params['continue'], array(), array() );
+ $continuationManager = new ApiContinuationManager( $this, array(), array() );
+ $this->setContinuationManager( $continuationManager );
$forceLinkUpdate = $params['forcelinkupdate'];
$forceRecursiveLinkUpdate = $params['forcerecursivelinkupdate'];
@@ -52,7 +53,7 @@ class ApiPurge extends ApiBase {
ApiQueryBase::addTitleInfo( $r, $title );
$page = WikiPage::factory( $title );
$page->doPurge(); // Directly purge and skip the UI part of purge().
- $r['purged'] = '';
+ $r['purged'] = true;
if ( $forceLinkUpdate || $forceRecursiveLinkUpdate ) {
if ( !$this->getUser()->pingLimiter( 'linkpurge' ) ) {
@@ -73,7 +74,7 @@ class ApiPurge extends ApiBase {
$title, null, $forceRecursiveLinkUpdate, $p_result );
DataUpdate::runUpdates( $updates );
- $r['linkupdate'] = '';
+ $r['linkupdate'] = true;
if ( $enableParserCache ) {
$pcache = ParserCache::singleton();
@@ -89,7 +90,7 @@ class ApiPurge extends ApiBase {
$result[] = $r;
}
$apiResult = $this->getResult();
- $apiResult->setIndexedTagName( $result, 'page' );
+ ApiResult::setIndexedTagName( $result, 'page' );
$apiResult->addValue( null, $this->getModuleName(), $result );
$values = $pageSet->getNormalizedTitlesAsResult( $apiResult );
@@ -105,7 +106,8 @@ class ApiPurge extends ApiBase {
$apiResult->addValue( null, 'redirects', $values );
}
- $apiResult->endContinuation();
+ $this->setContinuationManager( null );
+ $continuationManager->setContinuationIntoResult( $apiResult );
}
/**
@@ -133,7 +135,9 @@ class ApiPurge extends ApiBase {
$result = array(
'forcelinkupdate' => false,
'forcerecursivelinkupdate' => false,
- 'continue' => '',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
if ( $flags ) {
$result += $this->getPageSet()->getFinalParams( $flags );
@@ -142,25 +146,12 @@ class ApiPurge extends ApiBase {
return $result;
}
- public function getParamDescription() {
- return $this->getPageSet()->getFinalParamDescription()
- + array(
- 'forcelinkupdate' => 'Update the links tables',
- 'forcerecursivelinkupdate' => 'Update the links table, and update ' .
- 'the links tables for any page that uses this page as a template',
- 'continue' => 'When more results are available, use this to continue',
- );
- }
-
- public function getDescription() {
- return array( 'Purge the cache for the given titles.',
- 'Requires a POST request if the user is not logged in.'
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=purge&titles=Main_Page|API' => 'Purge the "Main Page" and the "API" page',
+ 'action=purge&titles=Main_Page|API'
+ => 'apihelp-purge-example-simple',
+ 'action=purge&generator=allpages&gapnamespace=0&gaplimit=10'
+ => 'apihelp-purge-example-generator',
);
}
diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php
index 7c750e41..bfe32052 100644
--- a/includes/api/ApiQuery.php
+++ b/includes/api/ApiQuery.php
@@ -45,6 +45,7 @@ class ApiQuery extends ApiBase {
'categories' => 'ApiQueryCategories',
'categoryinfo' => 'ApiQueryCategoryInfo',
'contributors' => 'ApiQueryContributors',
+ 'deletedrevisions' => 'ApiQueryDeletedRevisions',
'duplicatefiles' => 'ApiQueryDuplicateFiles',
'extlinks' => 'ApiQueryExternalLinks',
'fileusage' => 'ApiQueryBacklinksprop',
@@ -69,6 +70,7 @@ class ApiQuery extends ApiBase {
*/
private static $QueryListModules = array(
'allcategories' => 'ApiQueryAllCategories',
+ 'alldeletedrevisions' => 'ApiQueryAllDeletedRevisions',
'allfileusages' => 'ApiQueryAllLinks',
'allimages' => 'ApiQueryAllImages',
'alllinks' => 'ApiQueryAllLinks',
@@ -141,6 +143,8 @@ class ApiQuery extends ApiBase {
$this->mModuleMgr->addModules( self::$QueryMetaModules, 'meta' );
$this->mModuleMgr->addModules( $config->get( 'APIMetaModules' ), 'meta' );
+ Hooks::run( 'ApiQuery::moduleManager', array( $this->mModuleMgr ) );
+
// Create PageSet that will process titles/pageids/revids/generator
$this->mPageSet = new ApiPageSet( $this );
}
@@ -165,9 +169,7 @@ class ApiQuery extends ApiBase {
*/
public function getNamedDB( $name, $db, $groups ) {
if ( !array_key_exists( $name, $this->mNamedDB ) ) {
- $this->profileDBIn();
$this->mNamedDB[$name] = wfGetDB( $db, $groups );
- $this->profileDBOut();
}
return $this->mNamedDB[$name];
@@ -255,11 +257,11 @@ class ApiQuery extends ApiBase {
$this->instantiateModules( $allModules, 'meta' );
// Filter modules based on continue parameter
- list( $generatorDone, $modules ) = $this->getResult()->beginContinuation(
- $this->mParams['continue'], $allModules, $propModules
- );
+ $continuationManager = new ApiContinuationManager( $this, $allModules, $propModules );
+ $this->setContinuationManager( $continuationManager );
+ $modules = $continuationManager->getRunModules();
- if ( !$generatorDone ) {
+ if ( !$continuationManager->isGeneratorDone() ) {
// Query modules may optimize data requests through the $this->getPageSet()
// object by adding extra fields from the page table.
foreach ( $modules as $module ) {
@@ -281,19 +283,36 @@ class ApiQuery extends ApiBase {
$params = $module->extractRequestParams();
$cacheMode = $this->mergeCacheMode(
$cacheMode, $module->getCacheMode( $params ) );
- $module->profileIn();
$module->execute();
- wfRunHooks( 'APIQueryAfterExecute', array( &$module ) );
- $module->profileOut();
+ Hooks::run( 'APIQueryAfterExecute', array( &$module ) );
}
// Set the cache mode
$this->getMain()->setCacheMode( $cacheMode );
// Write the continuation data into the result
- $this->getResult()->endContinuation(
- $this->mParams['continue'] === null ? 'raw' : 'standard'
- );
+ $this->setContinuationManager( null );
+ if ( $this->mParams['continue'] === null ) {
+ $data = $continuationManager->getRawContinuation();
+ if ( $data ) {
+ $this->getResult()->addValue( null, 'query-continue', $data,
+ ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+ }
+ } else {
+ $continuationManager->setContinuationIntoResult( $this->getResult() );
+ }
+
+ if ( $this->mParams['continue'] === null && !$this->mParams['rawcontinue'] &&
+ $this->getResult()->getResultData( 'query-continue' ) !== null
+ ) {
+ $this->logFeatureUsage( 'action=query&!rawcontinue&!continue' );
+ $this->setWarning(
+ 'Formatting of continuation data will be changing soon. ' .
+ 'To continue using the current formatting, use the \'rawcontinue\' parameter. ' .
+ 'To begin using the new format, pass an empty string for \'continue\' ' .
+ 'in the initial query.'
+ );
+ }
}
/**
@@ -384,18 +403,18 @@ class ApiQuery extends ApiBase {
foreach ( $pageSet->getMissingTitles() as $fakeId => $title ) {
$vals = array();
ApiQueryBase::addTitleInfo( $vals, $title );
- $vals['missing'] = '';
+ $vals['missing'] = true;
$pages[$fakeId] = $vals;
}
// Report any invalid titles
foreach ( $pageSet->getInvalidTitles() as $fakeId => $title ) {
- $pages[$fakeId] = array( 'title' => $title, 'invalid' => '' );
+ $pages[$fakeId] = array( 'title' => $title, 'invalid' => true );
}
// Report any missing page ids
foreach ( $pageSet->getMissingPageIDs() as $pageid ) {
$pages[$pageid] = array(
'pageid' => $pageid,
- 'missing' => ''
+ 'missing' => true
);
}
// Report special pages
@@ -403,15 +422,15 @@ class ApiQuery extends ApiBase {
foreach ( $pageSet->getSpecialTitles() as $fakeId => $title ) {
$vals = array();
ApiQueryBase::addTitleInfo( $vals, $title );
- $vals['special'] = '';
+ $vals['special'] = true;
if ( $title->isSpecialPage() &&
!SpecialPageFactory::exists( $title->getDBkey() )
) {
- $vals['missing'] = '';
+ $vals['missing'] = true;
} elseif ( $title->getNamespace() == NS_MEDIA &&
!wfFindFile( $title )
) {
- $vals['missing'] = '';
+ $vals['missing'] = true;
}
$pages[$fakeId] = $vals;
}
@@ -425,15 +444,18 @@ class ApiQuery extends ApiBase {
}
if ( count( $pages ) ) {
+ $pageSet->populateGeneratorData( $pages );
+ ApiResult::setArrayType( $pages, 'BCarray' );
+
if ( $this->mParams['indexpageids'] ) {
- $pageIDs = array_keys( $pages );
+ $pageIDs = array_keys( ApiResult::stripMetadataNonRecursive( $pages ) );
// json treats all map keys as strings - converting to match
$pageIDs = array_map( 'strval', $pageIDs );
- $result->setIndexedTagName( $pageIDs, 'id' );
+ ApiResult::setIndexedTagName( $pageIDs, 'id' );
$fit = $fit && $result->addValue( 'query', 'pageids', $pageIDs );
}
- $result->setIndexedTagName( $pages, 'page' );
+ ApiResult::setIndexedTagName( $pages, 'page' );
$fit = $fit && $result->addValue( 'query', 'pages', $pages );
}
@@ -462,7 +484,7 @@ class ApiQuery extends ApiBase {
*/
public function setGeneratorContinue( $module, $paramName, $paramValue ) {
wfDeprecated( __METHOD__, '1.24' );
- $this->getResult()->setGeneratorContinueParam( $module, $paramName, $paramValue );
+ $this->getContinuationManager()->addGeneratorContinueParam( $module, $paramName, $paramValue );
return $this->getParameter( 'continue' ) !== null;
}
@@ -504,9 +526,8 @@ class ApiQuery extends ApiBase {
$result->addValue( null, 'text', $exportxml, ApiResult::NO_SIZE_CHECK );
$result->addValue( null, 'mime', 'text/xml', ApiResult::NO_SIZE_CHECK );
} else {
- $r = array();
- ApiResult::setContent( $r, $exportxml );
- $result->addValue( 'query', 'export', $r, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( 'query', 'export', $exportxml, ApiResult::NO_SIZE_CHECK );
+ $result->addValue( 'query', ApiResult::META_BC_SUBELEMENTS, array( 'export' ) );
}
}
@@ -540,9 +561,11 @@ class ApiQuery extends ApiBase {
/**
* Override the parent to generate help messages for all available query modules.
+ * @deprecated since 1.25
* @return string
*/
public function makeHelpMsg() {
+ wfDeprecated( __METHOD__, '1.25' );
// Use parent to make default message for the query module
$msg = parent::makeHelpMsg();
@@ -562,6 +585,7 @@ class ApiQuery extends ApiBase {
/**
* For all modules of a given group, generate help messages and join them together
+ * @deprecated since 1.25
* @param string $group Module group
* @return string
*/
@@ -594,44 +618,13 @@ class ApiQuery extends ApiBase {
return true;
}
- public function getParamDescription() {
- return $this->getPageSet()->getFinalParamDescription() + array(
- 'prop' => 'Which properties to get for the titles/revisions/pageids. ' .
- 'Module help is available below',
- 'list' => 'Which lists to get. Module help is available below',
- 'meta' => 'Which metadata to get about the site. Module help is available below',
- 'indexpageids' => 'Include an additional pageids section listing all returned page IDs',
- 'export' => 'Export the current revisions of all given or generated pages',
- 'exportnowrap' => 'Return the export XML without wrapping it in an ' .
- 'XML result (same format as Special:Export). Can only be used with export',
- 'iwurl' => 'Whether to get the full URL if the title is an interwiki link',
- 'continue' => array(
- 'When present, formats query-continue as key-value pairs that ' .
- 'should simply be merged into the original request.',
- 'This parameter must be set to an empty string in the initial query.',
- 'This parameter is recommended for all new development, and ' .
- 'will be made default in the next API version.'
- ),
- 'rawcontinue' => 'Currently ignored. In the future, \'continue=\' will become the ' .
- 'default and this will be needed to receive the raw query-continue data.',
- );
- }
-
- public function getDescription() {
- return array(
- 'Query API module allows applications to get needed pieces of data ' .
- 'from the MediaWiki databases,',
- 'and is loosely based on the old query.php interface.',
- 'All data modifications will first have to use query to acquire a ' .
- 'token to prevent abuse from malicious sites.'
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=revisions&meta=siteinfo&' .
- 'titles=Main%20Page&rvprop=user|comment&continue=',
- 'api.php?action=query&generator=allpages&gapprefix=API/&prop=revisions&continue=',
+ 'action=query&prop=revisions&meta=siteinfo&' .
+ 'titles=Main%20Page&rvprop=user|comment&continue='
+ => 'apihelp-query-example-revisions',
+ 'action=query&generator=allpages&gapprefix=API/&prop=revisions&continue='
+ => 'apihelp-query-example-allpages',
);
}
diff --git a/includes/api/ApiQueryAllCategories.php b/includes/api/ApiQueryAllCategories.php
index 79fab727..cc0b71af 100644
--- a/includes/api/ApiQueryAllCategories.php
+++ b/includes/api/ApiQueryAllCategories.php
@@ -128,15 +128,15 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
$pages[] = $titleObj;
} else {
$item = array();
- ApiResult::setContent( $item, $titleObj->getText() );
+ ApiResult::setContentValue( $item, 'category', $titleObj->getText() );
if ( isset( $prop['size'] ) ) {
$item['size'] = intval( $row->cat_pages );
$item['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files;
$item['files'] = intval( $row->cat_files );
$item['subcats'] = intval( $row->cat_subcats );
}
- if ( isset( $prop['hidden'] ) && $row->cat_hidden ) {
- $item['hidden'] = '';
+ if ( isset( $prop['hidden'] ) ) {
+ $item['hidden'] = (bool)$row->cat_hidden;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $item );
if ( !$fit ) {
@@ -147,7 +147,7 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'c' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'c' );
} else {
$resultPageSet->populateFromTitles( $pages );
}
@@ -156,7 +156,9 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
public function getAllowedParams() {
return array(
'from' => null,
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'to' => null,
'prefix' => null,
'dir' => array(
@@ -189,32 +191,12 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'from' => 'The category to start enumerating from',
- 'continue' => 'When more results are available, use this to continue',
- 'to' => 'The category to stop enumerating at',
- 'prefix' => 'Search for all category titles that begin with this value',
- 'dir' => 'Direction to sort in',
- 'min' => 'Minimum number of category members',
- 'max' => 'Maximum number of category members',
- 'limit' => 'How many categories to return',
- 'prop' => array(
- 'Which properties to get',
- ' size - Adds number of pages in the category',
- ' hidden - Tags categories that are hidden with __HIDDENCAT__',
- ),
- );
- }
-
- public function getDescription() {
- return 'Enumerate all categories.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=allcategories&acprop=size',
- 'api.php?action=query&generator=allcategories&gacprefix=List&prop=info',
+ 'action=query&list=allcategories&acprop=size'
+ => 'apihelp-query+allcategories-example-size',
+ 'action=query&generator=allcategories&gacprefix=List&prop=info'
+ => 'apihelp-query+allcategories-example-generator',
);
}
diff --git a/includes/api/ApiQueryAllDeletedRevisions.php b/includes/api/ApiQueryAllDeletedRevisions.php
new file mode 100644
index 00000000..4e4d2af7
--- /dev/null
+++ b/includes/api/ApiQueryAllDeletedRevisions.php
@@ -0,0 +1,427 @@
+<?php
+/**
+ * Created on Oct 3, 2014
+ *
+ * Copyright © 2014 Brad Jorsch "bjorsch@wikimedia.org"
+ *
+ * Heavily based on ApiQueryDeletedrevs,
+ * Copyright © 2007 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Query module to enumerate all deleted revisions.
+ *
+ * @ingroup API
+ */
+class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
+
+ public function __construct( ApiQuery $query, $moduleName ) {
+ parent::__construct( $query, $moduleName, 'adr' );
+ }
+
+ /**
+ * @param ApiPageSet $resultPageSet
+ * @return void
+ */
+ protected function run( ApiPageSet $resultPageSet = null ) {
+ $user = $this->getUser();
+ // Before doing anything at all, let's check permissions
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $this->dieUsage(
+ 'You don\'t have permission to view deleted revision information',
+ 'permissiondenied'
+ );
+ }
+
+ $db = $this->getDB();
+ $params = $this->extractRequestParams( false );
+
+ $result = $this->getResult();
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getTitles();
+
+ // This module operates in two modes:
+ // 'user': List deleted revs by a certain user
+ // 'all': List all deleted revs in NS
+ $mode = 'all';
+ if ( !is_null( $params['user'] ) ) {
+ $mode = 'user';
+ }
+
+ if ( $mode == 'user' ) {
+ foreach ( array( 'from', 'to', 'prefix', 'excludeuser' ) as $param ) {
+ if ( !is_null( $params[$param] ) ) {
+ $p = $this->getModulePrefix();
+ $this->dieUsage( "The '{$p}{$param}' parameter cannot be used with '{$p}user'",
+ 'badparams' );
+ }
+ }
+ } else {
+ foreach ( array( 'start', 'end' ) as $param ) {
+ if ( !is_null( $params[$param] ) ) {
+ $p = $this->getModulePrefix();
+ $this->dieUsage( "The '{$p}{$param}' parameter may only be used with '{$p}user'",
+ 'badparams' );
+ }
+ }
+ }
+
+ $this->addTables( 'archive' );
+ if ( $resultPageSet === null ) {
+ $this->parseParameters( $params );
+ $this->addFields( Revision::selectArchiveFields() );
+ $this->addFields( array( 'ar_title', 'ar_namespace' ) );
+ } else {
+ $this->limit = $this->getParameter( 'limit' ) ?: 10;
+ $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_rev_id', 'ar_id' ) );
+ }
+
+ if ( $this->fld_tags ) {
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds(
+ array( 'tag_summary' => array( 'LEFT JOIN', array( 'ar_rev_id=ts_rev_id' ) ) )
+ );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( !is_null( $params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds(
+ array( 'change_tag' => array( 'INNER JOIN', array( 'ar_rev_id=ct_rev_id' ) ) )
+ );
+ $this->addWhereFld( 'ct_tag', $params['tag'] );
+ }
+
+ if ( $this->fetchContent ) {
+ // Modern MediaWiki has the content for deleted revs in the 'text'
+ // table using fields old_text and old_flags. But revisions deleted
+ // pre-1.5 store the content in the 'archive' table directly using
+ // fields ar_text and ar_flags, and no corresponding 'text' row. So
+ // we have to LEFT JOIN and fetch all four fields.
+ $this->addTables( 'text' );
+ $this->addJoinConds(
+ array( 'text' => array( 'LEFT JOIN', array( 'ar_text_id=old_id' ) ) )
+ );
+ $this->addFields( array( 'ar_text', 'ar_flags', 'old_text', 'old_flags' ) );
+
+ // This also means stricter restrictions
+ if ( !$user->isAllowedAny( 'undelete', 'deletedtext' ) ) {
+ $this->dieUsage(
+ 'You don\'t have permission to view deleted revision content',
+ 'permissiondenied'
+ );
+ }
+ }
+
+ $dir = $params['dir'];
+ $miser_ns = null;
+
+ if ( $mode == 'all' ) {
+ if ( $params['namespace'] !== null ) {
+ $namespaces = $params['namespace'];
+ $this->addWhereFld( 'ar_namespace', $namespaces );
+ } else {
+ $namespaces = MWNamespace::getValidNamespaces();
+ }
+
+ // For from/to/prefix, we have to consider the potential
+ // transformations of the title in all specified namespaces.
+ // Generally there will be only one transformation, but wikis with
+ // some namespaces case-sensitive could have two.
+ if ( $params['from'] !== null || $params['to'] !== null ) {
+ $isDirNewer = ( $dir === 'newer' );
+ $after = ( $isDirNewer ? '>=' : '<=' );
+ $before = ( $isDirNewer ? '<=' : '>=' );
+ $where = array();
+ foreach ( $namespaces as $ns ) {
+ $w = array();
+ if ( $params['from'] !== null ) {
+ $w[] = 'ar_title' . $after .
+ $db->addQuotes( $this->titlePartToKey( $params['from'], $ns ) );
+ }
+ if ( $params['to'] !== null ) {
+ $w[] = 'ar_title' . $before .
+ $db->addQuotes( $this->titlePartToKey( $params['to'], $ns ) );
+ }
+ $w = $db->makeList( $w, LIST_AND );
+ $where[$w][] = $ns;
+ }
+ if ( count( $where ) == 1 ) {
+ $where = key( $where );
+ $this->addWhere( $where );
+ } else {
+ $where2 = array();
+ foreach ( $where as $w => $ns ) {
+ $where2[] = $db->makeList( array( $w, 'ar_namespace' => $ns ), LIST_AND );
+ }
+ $this->addWhere( $db->makeList( $where2, LIST_OR ) );
+ }
+ }
+
+ if ( isset( $params['prefix'] ) ) {
+ $where = array();
+ foreach ( $namespaces as $ns ) {
+ $w = 'ar_title' . $db->buildLike(
+ $this->titlePartToKey( $params['prefix'], $ns ),
+ $db->anyString() );
+ $where[$w][] = $ns;
+ }
+ if ( count( $where ) == 1 ) {
+ $where = key( $where );
+ $this->addWhere( $where );
+ } else {
+ $where2 = array();
+ foreach ( $where as $w => $ns ) {
+ $where2[] = $db->makeList( array( $w, 'ar_namespace' => $ns ), LIST_AND );
+ }
+ $this->addWhere( $db->makeList( $where2, LIST_OR ) );
+ }
+ }
+ } else {
+ if ( $this->getConfig()->get( 'MiserMode' ) ) {
+ $miser_ns = $params['namespace'];
+ } else {
+ $this->addWhereFld( 'ar_namespace', $params['namespace'] );
+ }
+ $this->addTimestampWhereRange( 'ar_timestamp', $dir, $params['start'], $params['end'] );
+ }
+
+ if ( !is_null( $params['user'] ) ) {
+ $this->addWhereFld( 'ar_user_text', $params['user'] );
+ } elseif ( !is_null( $params['excludeuser'] ) ) {
+ $this->addWhere( 'ar_user_text != ' .
+ $db->addQuotes( $params['excludeuser'] ) );
+ }
+
+ if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
+ // Paranoia: avoid brute force searches (bug 17342)
+ // (shouldn't be able to get here without 'deletedhistory', but
+ // check it again just in case)
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $bitmask = Revision::DELETED_USER;
+ } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+ $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+ } else {
+ $bitmask = 0;
+ }
+ if ( $bitmask ) {
+ $this->addWhere( $db->bitAnd( 'ar_deleted', $bitmask ) . " != $bitmask" );
+ }
+ }
+
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ $op = ( $dir == 'newer' ? '>' : '<' );
+ if ( $mode == 'all' ) {
+ $this->dieContinueUsageIf( count( $cont ) != 4 );
+ $ns = intval( $cont[0] );
+ $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] );
+ $title = $db->addQuotes( $cont[1] );
+ $ts = $db->addQuotes( $db->timestamp( $cont[2] ) );
+ $ar_id = (int)$cont[3];
+ $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[3] );
+ $this->addWhere( "ar_namespace $op $ns OR " .
+ "(ar_namespace = $ns AND " .
+ "(ar_title $op $title OR " .
+ "(ar_title = $title AND " .
+ "(ar_timestamp $op $ts OR " .
+ "(ar_timestamp = $ts AND " .
+ "ar_id $op= $ar_id)))))" );
+ } else {
+ $this->dieContinueUsageIf( count( $cont ) != 2 );
+ $ts = $db->addQuotes( $db->timestamp( $cont[0] ) );
+ $ar_id = (int)$cont[1];
+ $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[1] );
+ $this->addWhere( "ar_timestamp $op $ts OR " .
+ "(ar_timestamp = $ts AND " .
+ "ar_id $op= $ar_id)" );
+ }
+ }
+
+ $this->addOption( 'LIMIT', $this->limit + 1 );
+
+ $sort = ( $dir == 'newer' ? '' : ' DESC' );
+ $orderby = array();
+ if ( $mode == 'all' ) {
+ // Targeting index name_title_timestamp
+ if ( $params['namespace'] === null || count( array_unique( $params['namespace'] ) ) > 1 ) {
+ $orderby[] = "ar_namespace $sort";
+ }
+ $orderby[] = "ar_title $sort";
+ $orderby[] = "ar_timestamp $sort";
+ $orderby[] = "ar_id $sort";
+ } else {
+ // Targeting index usertext_timestamp
+ // 'user' is always constant.
+ $orderby[] = "ar_timestamp $sort";
+ $orderby[] = "ar_id $sort";
+ }
+ $this->addOption( 'ORDER BY', $orderby );
+
+ $res = $this->select( __METHOD__ );
+ $pageMap = array(); // Maps ns&title to array index
+ $count = 0;
+ $nextIndex = 0;
+ $generated = array();
+ foreach ( $res as $row ) {
+ if ( ++$count > $this->limit ) {
+ // We've had enough
+ if ( $mode == 'all' ) {
+ $this->setContinueEnumParameter( 'continue',
+ "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+ );
+ } else {
+ $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" );
+ }
+ break;
+ }
+
+ // Miser mode namespace check
+ if ( $miser_ns !== null && !in_array( $row->ar_namespace, $miser_ns ) ) {
+ continue;
+ }
+
+ if ( $resultPageSet !== null ) {
+ if ( $params['generatetitles'] ) {
+ $key = "{$row->ar_namespace}:{$row->ar_title}";
+ if ( !isset( $generated[$key] ) ) {
+ $generated[$key] = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+ }
+ } else {
+ $generated[] = $row->ar_rev_id;
+ }
+ } else {
+ $revision = Revision::newFromArchiveRow( $row );
+ $rev = $this->extractRevisionInfo( $revision, $row );
+
+ if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
+ $index = $nextIndex++;
+ $pageMap[$row->ar_namespace][$row->ar_title] = $index;
+ $title = $revision->getTitle();
+ $a = array(
+ 'pageid' => $title->getArticleID(),
+ 'revisions' => array( $rev ),
+ );
+ ApiResult::setIndexedTagName( $a['revisions'], 'rev' );
+ ApiQueryBase::addTitleInfo( $a, $title );
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), $index, $a );
+ } else {
+ $index = $pageMap[$row->ar_namespace][$row->ar_title];
+ $fit = $result->addValue(
+ array( 'query', $this->getModuleName(), $index, 'revisions' ),
+ null, $rev );
+ }
+ if ( !$fit ) {
+ if ( $mode == 'all' ) {
+ $this->setContinueEnumParameter( 'continue',
+ "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+ );
+ } else {
+ $this->setContinueEnumParameter( 'continue', "$row->ar_timestamp|$row->ar_id" );
+ }
+ break;
+ }
+ }
+ }
+
+ if ( $resultPageSet !== null ) {
+ if ( $params['generatetitles'] ) {
+ $resultPageSet->populateFromTitles( $generated );
+ } else {
+ $resultPageSet->populateFromRevisionIDs( $generated );
+ }
+ } else {
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'page' );
+ }
+ }
+
+ public function getAllowedParams() {
+ $ret = parent::getAllowedParams() + array(
+ 'user' => array(
+ ApiBase::PARAM_TYPE => 'user'
+ ),
+ 'namespace' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_TYPE => 'namespace',
+ ApiBase::PARAM_DFLT => null,
+ ),
+ 'start' => array(
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'useronly' ) ),
+ ),
+ 'end' => array(
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'useronly' ) ),
+ ),
+ 'dir' => array(
+ ApiBase::PARAM_TYPE => array(
+ 'newer',
+ 'older'
+ ),
+ ApiBase::PARAM_DFLT => 'older',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+ ),
+ 'from' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'nonuseronly' ) ),
+ ),
+ 'to' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'nonuseronly' ) ),
+ ),
+ 'prefix' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'nonuseronly' ) ),
+ ),
+ 'excludeuser' => array(
+ ApiBase::PARAM_TYPE => 'user',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'nonuseronly' ) ),
+ ),
+ 'tag' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
+ 'generatetitles' => array(
+ ApiBase::PARAM_DFLT => false
+ ),
+ );
+
+ if ( $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['user'][ApiBase::PARAM_HELP_MSG_APPEND] = array(
+ 'apihelp-query+alldeletedrevisions-param-miser-user-namespace',
+ );
+ $ret['namespace'][ApiBase::PARAM_HELP_MSG_APPEND] = array(
+ 'apihelp-query+alldeletedrevisions-param-miser-user-namespace',
+ );
+ }
+
+ return $ret;
+ }
+
+ protected function getExamplesMessages() {
+ return array(
+ 'action=query&list=alldeletedrevisions&adruser=Example&adrlimit=50'
+ => 'apihelp-query+alldeletedrevisions-example-user',
+ 'action=query&list=alldeletedrevisions&adrdir=newer&adrlimit=50'
+ => 'apihelp-query+alldeletedrevisions-example-ns-main',
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Alldeletedrevisions';
+ }
+}
diff --git a/includes/api/ApiQueryAllImages.php b/includes/api/ApiQueryAllImages.php
index 9dc5f69a..381938bd 100644
--- a/includes/api/ApiQueryAllImages.php
+++ b/includes/api/ApiQueryAllImages.php
@@ -232,10 +232,25 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
$this->dieUsage( 'MIME search disabled in Miser Mode', 'mimesearchdisabled' );
}
- list( $major, $minor ) = File::splitMime( $params['mime'] );
-
- $this->addWhereFld( 'img_major_mime', $major );
- $this->addWhereFld( 'img_minor_mime', $minor );
+ $mimeConds = array();
+ foreach ( $params['mime'] as $mime ) {
+ list( $major, $minor ) = File::splitMime( $mime );
+ $mimeConds[] = $db->makeList(
+ array(
+ 'img_major_mime' => $major,
+ 'img_minor_mime' => $minor,
+ ),
+ LIST_AND
+ );
+ }
+ // safeguard against internal_api_error_DBQueryError
+ if ( count( $mimeConds ) > 0 ) {
+ $this->addWhere( $db->makeList( $mimeConds, LIST_OR ) );
+ } else {
+ // no MIME types, no files
+ $this->getResult()->addValue( 'query', $this->getModuleName(), array() );
+ return;
+ }
}
$limit = $params['limit'];
@@ -293,14 +308,14 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'img' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'img' );
} else {
$resultPageSet->populateFromTitles( $titles );
}
}
public function getAllowedParams() {
- return array(
+ $ret = array(
'sort' => array(
ApiBase::PARAM_DFLT => 'name',
ApiBase::PARAM_TYPE => array(
@@ -321,7 +336,9 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
),
'from' => null,
'to' => null,
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'start' => array(
ApiBase::PARAM_TYPE => 'timestamp'
),
@@ -331,7 +348,9 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
'prop' => array(
ApiBase::PARAM_TYPE => ApiQueryImageInfo::getPropertyNames( $this->propertyFilter ),
ApiBase::PARAM_DFLT => 'timestamp|url',
- ApiBase::PARAM_ISMULTI => true
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+imageinfo-param-prop',
+ ApiBase::PARAM_HELP_MSG_PER_VALUE => ApiQueryImageInfo::getPropertyMessages( $this->propertyFilter ),
),
'prefix' => null,
'minsize' => array(
@@ -353,7 +372,10 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
'nobots'
)
),
- 'mime' => null,
+ 'mime' => array(
+ ApiBase::PARAM_DFLT => null,
+ ApiBase::PARAM_ISMULTI => true,
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -362,57 +384,28 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
);
- }
- public function getParamDescription() {
- $p = $this->getModulePrefix();
+ if ( $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['mime'][ApiBase::PARAM_HELP_MSG] = 'api-help-param-disabled-in-miser-mode';
+ }
- return array(
- 'sort' => 'Property to sort by',
- 'dir' => 'The direction in which to list',
- 'from' => "The image title to start enumerating from. Can only be used with {$p}sort=name",
- 'to' => "The image title to stop enumerating at. Can only be used with {$p}sort=name",
- 'continue' => 'When more results are available, use this to continue',
- 'start' => "The timestamp to start enumerating from. Can only be used with {$p}sort=timestamp",
- 'end' => "The timestamp to end enumerating. Can only be used with {$p}sort=timestamp",
- 'prop' => ApiQueryImageInfo::getPropertyDescriptions( $this->propertyFilter ),
- 'prefix' => "Search for all image titles that begin with this " .
- "value. Can only be used with {$p}sort=name",
- 'minsize' => 'Limit to images with at least this many bytes',
- 'maxsize' => 'Limit to images with at most this many bytes',
- 'sha1' => "SHA1 hash of image. Overrides {$p}sha1base36",
- 'sha1base36' => 'SHA1 hash of image in base 36 (used in MediaWiki)',
- 'user' => "Only return files uploaded by this user. Can only be used " .
- "with {$p}sort=timestamp. Cannot be used together with {$p}filterbots",
- 'filterbots' => "How to filter files uploaded by bots. Can only be " .
- "used with {$p}sort=timestamp. Cannot be used together with {$p}user",
- 'mime' => 'What MIME type to search for. e.g. image/jpeg. Disabled in Miser Mode',
- 'limit' => 'How many images in total to return',
- );
+ return $ret;
}
private $propertyFilter = array( 'archivename', 'thumbmime', 'uploadwarning' );
- public function getDescription() {
- return 'Enumerate all images sequentially.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=allimages&aifrom=B' => array(
- 'Simple Use',
- 'Show a list of files starting at the letter "B"',
- ),
- 'api.php?action=query&list=allimages&aiprop=user|timestamp|url&' .
- 'aisort=timestamp&aidir=older' => array(
- 'Simple Use',
- 'Show a list of recently uploaded files similar to Special:NewFiles',
- ),
- 'api.php?action=query&generator=allimages&gailimit=4&' .
- 'gaifrom=T&prop=imageinfo' => array(
- 'Using as Generator',
- 'Show info about 4 files starting at the letter "T"',
- ),
+ 'action=query&list=allimages&aifrom=B'
+ => 'apihelp-query+allimages-example-B',
+ 'action=query&list=allimages&aiprop=user|timestamp|url&' .
+ 'aisort=timestamp&aidir=older'
+ => 'apihelp-query+allimages-example-recent',
+ 'action=query&list=allimages&aimime=image/png|image/gif'
+ => 'apihelp-query+allimages-example-mimetypes',
+ 'action=query&generator=allimages&gailimit=4&' .
+ 'gaifrom=T&prop=imageinfo'
+ => 'apihelp-query+allimages-example-generator',
);
}
diff --git a/includes/api/ApiQueryAllLinks.php b/includes/api/ApiQueryAllLinks.php
index 903dee42..fadecfb4 100644
--- a/includes/api/ApiQueryAllLinks.php
+++ b/includes/api/ApiQueryAllLinks.php
@@ -31,13 +31,12 @@
*/
class ApiQueryAllLinks extends ApiQueryGeneratorBase {
- private $table, $tablePrefix, $indexTag,
- $description, $descriptionWhat, $descriptionTargets, $descriptionLinking;
+ private $table, $tablePrefix, $indexTag;
private $fieldTitle = 'title';
private $dfltNamespace = NS_MAIN;
private $hasNamespace = true;
private $useIndex = null;
- private $props = array(), $propHelp = array();
+ private $props = array();
public function __construct( ApiQuery $query, $moduleName ) {
switch ( $moduleName ) {
@@ -47,10 +46,6 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
$this->tablePrefix = 'pl_';
$this->useIndex = 'pl_namespace';
$this->indexTag = 'l';
- $this->description = 'Enumerate all links that point to a given namespace';
- $this->descriptionWhat = 'link';
- $this->descriptionTargets = 'linked titles';
- $this->descriptionLinking = 'linking';
break;
case 'alltransclusions':
$prefix = 'at';
@@ -59,11 +54,6 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
$this->dfltNamespace = NS_TEMPLATE;
$this->useIndex = 'tl_namespace';
$this->indexTag = 't';
- $this->description =
- 'List all transclusions (pages embedded using {{x}}), including non-existing';
- $this->descriptionWhat = 'transclusion';
- $this->descriptionTargets = 'transcluded titles';
- $this->descriptionLinking = 'transcluding';
break;
case 'allfileusages':
$prefix = 'af';
@@ -73,28 +63,16 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
$this->dfltNamespace = NS_FILE;
$this->hasNamespace = false;
$this->indexTag = 'f';
- $this->description = 'List all file usages, including non-existing';
- $this->descriptionWhat = 'file';
- $this->descriptionTargets = 'file titles';
- $this->descriptionLinking = 'using';
break;
case 'allredirects':
$prefix = 'ar';
$this->table = 'redirect';
$this->tablePrefix = 'rd_';
$this->indexTag = 'r';
- $this->description = 'List all redirects to a namespace';
- $this->descriptionWhat = 'redirect';
- $this->descriptionTargets = 'target pages';
- $this->descriptionLinking = 'redirecting';
$this->props = array(
'fragment' => 'rd_fragment',
'interwiki' => 'rd_interwiki',
);
- $this->propHelp = array(
- ' fragment - Adds the fragment from the redirect, if any',
- ' interwiki - Adds the interwiki prefix from the redirect, if any',
- );
break;
default:
ApiBase::dieDebug( __METHOD__, 'Unknown module name' );
@@ -222,7 +200,9 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['fromid'] = intval( $row->pl_from );
}
@@ -252,7 +232,7 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $this->indexTag );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), $this->indexTag );
} elseif ( $params['unique'] ) {
$resultPageSet->populateFromTitles( $titles );
} else {
@@ -262,7 +242,9 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
public function getAllowedParams() {
$allowedParams = array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'from' => null,
'to' => null,
'prefix' => null,
@@ -300,59 +282,20 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
return $allowedParams;
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
- $what = $this->descriptionWhat;
- $targets = $this->descriptionTargets;
- $linking = $this->descriptionLinking;
- $paramDescription = array(
- 'from' => "The title of the $what to start enumerating from",
- 'to' => "The title of the $what to stop enumerating at",
- 'prefix' => "Search for all $targets that begin with this value",
- 'unique' => array(
- "Only show distinct $targets. Cannot be used with {$p}prop=" .
- join( '|', array_keys( array( 'ids' => 1 ) + $this->props ) ) . '.',
- 'When used as a generator, yields target pages instead of source pages.',
- ),
- 'prop' => array(
- 'What pieces of information to include',
- " ids - Adds the pageid of the $linking page (Cannot be used with {$p}unique)",
- " title - Adds the title of the $what",
- ),
- 'namespace' => 'The namespace to enumerate',
- 'limit' => 'How many total items to return',
- 'continue' => 'When more results are available, use this to continue',
- 'dir' => 'The direction in which to list',
- );
- foreach ( $this->propHelp as $help ) {
- $paramDescription['prop'][] = "$help (Cannot be used with {$p}unique)";
- }
- if ( !$this->hasNamespace ) {
- unset( $paramDescription['namespace'] );
- }
-
- return $paramDescription;
- }
-
- public function getDescription() {
- return $this->description;
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
$p = $this->getModulePrefix();
$name = $this->getModuleName();
- $what = $this->descriptionWhat;
- $targets = $this->descriptionTargets;
+ $path = $this->getModulePath();
return array(
- "api.php?action=query&list={$name}&{$p}from=B&{$p}prop=ids|title"
- => "List $targets with page ids they are from, including missing ones. Start at B",
- "api.php?action=query&list={$name}&{$p}unique=&{$p}from=B"
- => "List unique $targets",
- "api.php?action=query&generator={$name}&g{$p}unique=&g{$p}from=B"
- => "Gets all $targets, marking the missing ones",
- "api.php?action=query&generator={$name}&g{$p}from=B"
- => "Gets pages containing the {$what}s",
+ "action=query&list={$name}&{$p}from=B&{$p}prop=ids|title"
+ => "apihelp-$path-example-B",
+ "action=query&list={$name}&{$p}unique=&{$p}from=B"
+ => "apihelp-$path-example-unique",
+ "action=query&generator={$name}&g{$p}unique=&g{$p}from=B"
+ => "apihelp-$path-example-unique-generator",
+ "action=query&generator={$name}&g{$p}from=B"
+ => "apihelp-$path-example-generator",
);
}
diff --git a/includes/api/ApiQueryAllMessages.php b/includes/api/ApiQueryAllMessages.php
index a75a16fc..44af83d0 100644
--- a/includes/api/ApiQueryAllMessages.php
+++ b/includes/api/ApiQueryAllMessages.php
@@ -146,7 +146,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
$messageIsCustomised = isset( $customisedMessages['pages'][$langObj->ucfirst( $message )] );
if ( $customised === $messageIsCustomised ) {
if ( $customised ) {
- $a['customised'] = '';
+ $a['customised'] = true;
}
} else {
continue;
@@ -156,7 +156,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
$msg = wfMessage( $message, $args )->inLanguage( $langObj );
if ( !$msg->exists() ) {
- $a['missing'] = '';
+ $a['missing'] = true;
} else {
// Check if the parser is enabled:
if ( $params['enableparser'] ) {
@@ -165,12 +165,12 @@ class ApiQueryAllMessages extends ApiQueryBase {
$msgString = $msg->plain();
}
if ( !$params['nocontent'] ) {
- ApiResult::setContent( $a, $msgString );
+ ApiResult::setContentValue( $a, 'content', $msgString );
}
if ( isset( $prop['default'] ) ) {
$default = wfMessage( $message )->inLanguage( $langObj )->useDatabase( false );
if ( !$default->exists() ) {
- $a['defaultmissing'] = '';
+ $a['defaultmissing'] = true;
} elseif ( $default->plain() != $msgString ) {
$a['default'] = $default->plain();
}
@@ -183,7 +183,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
}
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'message' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'message' );
}
public function getCacheMode( $params ) {
@@ -235,35 +235,12 @@ class ApiQueryAllMessages extends ApiQueryBase {
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'messages' => 'Which messages to output. "*" (default) means all messages',
- 'prop' => 'Which properties to get',
- 'enableparser' => array( 'Set to enable parser, will preprocess the wikitext of message',
- 'Will substitute magic words, handle templates etc.' ),
- 'nocontent' => 'If set, do not include the content of the messages in the output.',
- 'includelocal' => array( "Also include local messages, i.e. messages that don't exist in the software but do exist as a MediaWiki: page.",
- "This lists all MediaWiki: pages, so it will also list those that aren't 'really' messages such as Common.js",
- ),
- 'title' => 'Page name to use as context when parsing message (for enableparser option)',
- 'args' => 'Arguments to be substituted into message',
- 'prefix' => 'Return messages with this prefix',
- 'filter' => 'Return only messages with names that contain this string',
- 'customised' => 'Return only messages in this customisation state',
- 'lang' => 'Return messages in this language',
- 'from' => 'Return messages starting at this message',
- 'to' => 'Return messages ending at this message',
- );
- }
-
- public function getDescription() {
- return 'Return messages from this site.';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=query&meta=allmessages&amprefix=ipb-',
- 'api.php?action=query&meta=allmessages&ammessages=august|mainpage&amlang=de',
+ 'action=query&meta=allmessages&amprefix=ipb-'
+ => 'apihelp-query+allmessages-example-ipb',
+ 'action=query&meta=allmessages&ammessages=august|mainpage&amlang=de'
+ => 'apihelp-query+allmessages-example-de',
);
}
diff --git a/includes/api/ApiQueryAllPages.php b/includes/api/ApiQueryAllPages.php
index b7bd65a5..0149ad2f 100644
--- a/includes/api/ApiQueryAllPages.php
+++ b/includes/api/ApiQueryAllPages.php
@@ -168,9 +168,23 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
$this->addTables( 'langlinks' );
$this->addWhere( 'page_id=ll_from' );
$this->addOption( 'STRAIGHT_JOIN' );
- // We have to GROUP BY all selected fields to stop
- // PostgreSQL from whining
- $this->addOption( 'GROUP BY', $selectFields );
+
+ // MySQL filesorts if we use a GROUP BY that works with the rules
+ // in the 1992 SQL standard (it doesn't like having the
+ // constant-in-WHERE page_namespace column in there). Using the
+ // 1999 rules works fine, but that breaks other DBs. Sigh.
+ /// @todo Once we drop support for 1992-rule DBs, we can simplify this.
+ $dbType = $db->getType();
+ if ( $dbType === 'mysql' || $dbType === 'sqlite' ||
+ $dbType === 'postgres' && $db->getServerVersion() >= 9.1
+ ) {
+ // 1999 rules, or screw-the-rules
+ $this->addOption( 'GROUP BY', array( 'page_title', 'page_id' ) );
+ } else {
+ // 1992 rules
+ $this->addOption( 'GROUP BY', $selectFields );
+ }
+
$forceNameTitleIndex = false;
}
@@ -220,14 +234,16 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'p' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'p' );
}
}
public function getAllowedParams() {
return array(
'from' => null,
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'to' => null,
'prefix' => null,
'namespace' => array(
@@ -297,54 +313,15 @@ class ApiQueryAllPages extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'from' => 'The page title to start enumerating from',
- 'continue' => 'When more results are available, use this to continue',
- 'to' => 'The page title to stop enumerating at',
- 'prefix' => 'Search for all page titles that begin with this value',
- 'namespace' => 'The namespace to enumerate',
- 'filterredir' => 'Which pages to list',
- 'dir' => 'The direction in which to list',
- 'minsize' => 'Limit to pages with at least this many bytes',
- 'maxsize' => 'Limit to pages with at most this many bytes',
- 'prtype' => 'Limit to protected pages only',
- 'prlevel' => "The protection level (must be used with {$p}prtype= parameter)",
- 'prfiltercascade'
- => "Filter protections based on cascadingness (ignored when {$p}prtype isn't set)",
- 'filterlanglinks' => array(
- 'Filter based on whether a page has langlinks',
- 'Note that this may not consider langlinks added by extensions.',
- ),
- 'limit' => 'How many total pages to return.',
- 'prexpiry' => array(
- 'Which protection expiry to filter the page on',
- ' indefinite - Get only pages with indefinite protection expiry',
- ' definite - Get only pages with a definite (specific) protection expiry',
- ' all - Get pages with any protections expiry'
- ),
- );
- }
-
- public function getDescription() {
- return 'Enumerate all pages sequentially in a given namespace.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=allpages&apfrom=B' => array(
- 'Simple Use',
- 'Show a list of pages starting at the letter "B"',
- ),
- 'api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info' => array(
- 'Using as Generator',
- 'Show info about 4 pages starting at the letter "T"',
- ),
- 'api.php?action=query&generator=allpages&gaplimit=2&' .
+ 'action=query&list=allpages&apfrom=B'
+ => 'apihelp-query+allpages-example-B',
+ 'action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info'
+ => 'apihelp-query+allpages-example-generator',
+ 'action=query&generator=allpages&gaplimit=2&' .
'gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
- => array( 'Show content of first 2 non-redirect pages beginning at "Re"' )
+ => 'apihelp-query+allpages-example-generator-revisions',
);
}
diff --git a/includes/api/ApiQueryAllUsers.php b/includes/api/ApiQueryAllUsers.php
index affddda7..0cea84f8 100644
--- a/includes/api/ApiQueryAllUsers.php
+++ b/includes/api/ApiQueryAllUsers.php
@@ -48,11 +48,6 @@ class ApiQueryAllUsers extends ApiQueryBase {
$params = $this->extractRequestParams();
$activeUserDays = $this->getConfig()->get( 'ActiveUserDays' );
- if ( $params['activeusers'] ) {
- // Update active user cache
- SpecialActiveUsers::mergeActiveUsers( 600, $activeUserDays );
- }
-
$db = $this->getDB();
$prop = $params['prop'];
@@ -72,7 +67,6 @@ class ApiQueryAllUsers extends ApiQueryBase {
$limit = $params['limit'];
$this->addTables( 'user' );
- $useIndex = true;
$dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
$from = is_null( $params['from'] ) ? null : $this->getCanonicalUserName( $params['from'] );
@@ -82,6 +76,10 @@ class ApiQueryAllUsers extends ApiQueryBase {
# despite the JOIN condition, so manually sort on the correct one.
$userFieldToSort = $params['activeusers'] ? 'qcc_title' : 'user_name';
+ # Some of these subtable joins are going to give us duplicate rows, so
+ # calculate the maximum number of duplicates we might see.
+ $maxDuplicateRows = 1;
+
$this->addWhereRange( $userFieldToSort, $dir, $from, $to );
if ( !is_null( $params['prefix'] ) ) {
@@ -97,7 +95,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
// no group with the given right(s) exists, no need for a query
if ( !count( $groups ) ) {
- $this->getResult()->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), '' );
+ $this->getResult()->addIndexedTagName( array( 'query', $this->getModuleName() ), '' );
return;
}
@@ -116,16 +114,17 @@ class ApiQueryAllUsers extends ApiQueryBase {
}
if ( !is_null( $params['group'] ) && count( $params['group'] ) ) {
- $useIndex = false;
- // Filter only users that belong to a given group
+ // Filter only users that belong to a given group. This might
+ // produce as many rows-per-user as there are groups being checked.
$this->addTables( 'user_groups', 'ug1' );
$this->addJoinConds( array( 'ug1' => array( 'INNER JOIN', array( 'ug1.ug_user=user_id',
'ug1.ug_group' => $params['group'] ) ) ) );
+ $maxDuplicateRows *= count( $params['group'] );
}
if ( !is_null( $params['excludegroup'] ) && count( $params['excludegroup'] ) ) {
- $useIndex = false;
- // Filter only users don't belong to a given group
+ // Filter only users don't belong to a given group. This can only
+ // produce one row-per-user, because we only keep on "no match".
$this->addTables( 'user_groups', 'ug1' );
if ( count( $params['excludegroup'] ) == 1 ) {
@@ -149,22 +148,16 @@ class ApiQueryAllUsers extends ApiQueryBase {
$this->showHiddenUsersAddBlockInfo( $fld_blockinfo );
if ( $fld_groups || $fld_rights ) {
- // Show the groups the given users belong to
- // request more than needed to avoid not getting all rows that belong to one user
- $groupCount = count( User::getAllGroups() );
- $sqlLimit = $limit + $groupCount + 1;
-
- $this->addTables( 'user_groups', 'ug2' );
- $this->addJoinConds( array( 'ug2' => array( 'LEFT JOIN', 'ug2.ug_user=user_id' ) ) );
- $this->addFields( array( 'ug_group2' => 'ug2.ug_group' ) );
- } else {
- $sqlLimit = $limit + 1;
+ $this->addFields( array( 'groups' =>
+ $db->buildGroupConcatField( '|', 'user_groups', 'ug_group', 'ug_user=user_id' )
+ ) );
}
if ( $params['activeusers'] ) {
$activeUserSeconds = $activeUserDays * 86400;
- // Filter query to only include users in the active users cache
+ // Filter query to only include users in the active users cache.
+ // There shouldn't be any duplicate rows in querycachetwo here.
$this->addTables( 'querycachetwo' );
$this->addJoinConds( array( 'querycachetwo' => array(
'INNER JOIN', array(
@@ -190,6 +183,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
) );
}
+ $sqlLimit = $limit + $maxDuplicateRows;
$this->addOption( 'LIMIT', $sqlLimit );
$this->addFields( array(
@@ -199,148 +193,112 @@ class ApiQueryAllUsers extends ApiQueryBase {
$this->addFieldsIf( 'user_editcount', $fld_editcount );
$this->addFieldsIf( 'user_registration', $fld_registration );
- if ( $useIndex ) {
- $this->addOption( 'USE INDEX', array( 'user' => 'user_name' ) );
- }
-
$res = $this->select( __METHOD__ );
-
$count = 0;
- $lastUserData = false;
+ $countDuplicates = 0;
$lastUser = false;
$result = $this->getResult();
-
- // This loop keeps track of the last entry. For each new row, if the
- // new row is for different user then the last, the last entry is added
- // to results. Otherwise, the group of the new row is appended to the
- // last entry. The setContinue... is more complex because of this, and
- // takes into account the higher sql limit to make sure all rows that
- // belong to the same user are received.
-
foreach ( $res as $row ) {
$count++;
- if ( $lastUser !== $row->user_name ) {
- // Save the last pass's user data
- if ( is_array( $lastUserData ) ) {
- if ( $params['activeusers'] && $lastUserData['recentactions'] === 0 ) {
- // activeusers cache was out of date
- $fit = true;
- } else {
- $fit = $result->addValue( array( 'query', $this->getModuleName() ),
- null, $lastUserData );
- }
-
- $lastUserData = null;
-
- if ( !$fit ) {
- $this->setContinueEnumParameter( 'from', $lastUserData['name'] );
- break;
- }
+ if ( $lastUser === $row->user_name ) {
+ // Duplicate row due to one of the needed subtable joins.
+ // Ignore it, but count the number of them to sanely handle
+ // miscalculation of $maxDuplicateRows.
+ $countDuplicates++;
+ if ( $countDuplicates == $maxDuplicateRows ) {
+ ApiBase::dieDebug( __METHOD__, 'Saw more duplicate rows than expected' );
}
+ continue;
+ }
- if ( $count > $limit ) {
- // We've reached the one extra which shows that there are
- // additional pages to be had. Stop here...
- $this->setContinueEnumParameter( 'from', $row->user_name );
- break;
- }
+ $countDuplicates = 0;
+ $lastUser = $row->user_name;
- // Record new user's data
- $lastUser = $row->user_name;
- $lastUserData = array(
- 'userid' => $row->user_id,
- 'name' => $lastUser,
- );
- if ( $fld_blockinfo && !is_null( $row->ipb_by_text ) ) {
- $lastUserData['blockid'] = $row->ipb_id;
- $lastUserData['blockedby'] = $row->ipb_by_text;
- $lastUserData['blockedbyid'] = $row->ipb_by;
- $lastUserData['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
- $lastUserData['blockreason'] = $row->ipb_reason;
- $lastUserData['blockexpiry'] = $row->ipb_expiry;
- }
- if ( $row->ipb_deleted ) {
- $lastUserData['hidden'] = '';
- }
- if ( $fld_editcount ) {
- $lastUserData['editcount'] = intval( $row->user_editcount );
- }
- if ( $params['activeusers'] ) {
- $lastUserData['recentactions'] = intval( $row->recentactions );
- // @todo 'recenteditcount' is set for BC, remove in 1.25
- $lastUserData['recenteditcount'] = $lastUserData['recentactions'];
- }
- if ( $fld_registration ) {
- $lastUserData['registration'] = $row->user_registration ?
- wfTimestamp( TS_ISO_8601, $row->user_registration ) : '';
- }
+ if ( $count > $limit ) {
+ // We've reached the one extra which shows that there are
+ // additional pages to be had. Stop here...
+ $this->setContinueEnumParameter( 'from', $row->user_name );
+ break;
}
- if ( $sqlLimit == $count ) {
- // @todo BUG! database contains group name that User::getAllGroups() does not return
- // Should handle this more gracefully
- ApiBase::dieDebug(
- __METHOD__,
- 'MediaWiki configuration error: The database contains more ' .
- 'user groups than known to User::getAllGroups() function'
- );
+ if ( $count == $sqlLimit ) {
+ // Should never hit this (either the $countDuplicates check or
+ // the $count > $limit check should hit first), but check it
+ // anyway just in case.
+ ApiBase::dieDebug( __METHOD__, 'Saw more duplicate rows than expected' );
}
- $lastUserObj = User::newFromId( $row->user_id );
-
- // Add user's group info
- if ( $fld_groups ) {
- if ( !isset( $lastUserData['groups'] ) ) {
- if ( $lastUserObj ) {
- $lastUserData['groups'] = $lastUserObj->getAutomaticGroups();
- } else {
- // This should not normally happen
- $lastUserData['groups'] = array();
- }
- }
-
- if ( !is_null( $row->ug_group2 ) ) {
- $lastUserData['groups'][] = $row->ug_group2;
- }
-
- $result->setIndexedTagName( $lastUserData['groups'], 'g' );
+ if ( $params['activeusers'] && $row->recentactions === 0 ) {
+ // activeusers cache was out of date
+ continue;
}
- if ( $fld_implicitgroups && !isset( $lastUserData['implicitgroups'] ) && $lastUserObj ) {
- $lastUserData['implicitgroups'] = $lastUserObj->getAutomaticGroups();
- $result->setIndexedTagName( $lastUserData['implicitgroups'], 'g' );
+ $data = array(
+ 'userid' => $row->user_id,
+ 'name' => $row->user_name,
+ );
+
+ if ( $fld_blockinfo && !is_null( $row->ipb_by_text ) ) {
+ $data['blockid'] = $row->ipb_id;
+ $data['blockedby'] = $row->ipb_by_text;
+ $data['blockedbyid'] = $row->ipb_by;
+ $data['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
+ $data['blockreason'] = $row->ipb_reason;
+ $data['blockexpiry'] = $row->ipb_expiry;
+ }
+ if ( $row->ipb_deleted ) {
+ $data['hidden'] = true;
+ }
+ if ( $fld_editcount ) {
+ $data['editcount'] = intval( $row->user_editcount );
+ }
+ if ( $params['activeusers'] ) {
+ $data['recentactions'] = intval( $row->recentactions );
+ // @todo 'recenteditcount' is set for BC, remove in 1.25
+ $data['recenteditcount'] = $data['recentactions'];
}
- if ( $fld_rights ) {
- if ( !isset( $lastUserData['rights'] ) ) {
- if ( $lastUserObj ) {
- $lastUserData['rights'] = User::getGroupPermissions( $lastUserObj->getAutomaticGroups() );
- } else {
- // This should not normally happen
- $lastUserData['rights'] = array();
- }
+ if ( $fld_registration ) {
+ $data['registration'] = $row->user_registration ?
+ wfTimestamp( TS_ISO_8601, $row->user_registration ) : '';
+ }
+
+ if ( $fld_implicitgroups || $fld_groups || $fld_rights ) {
+ $user = User::newFromId( $row->user_id );
+ $implicitGroups = User::newFromId( $row->user_id )->getAutomaticGroups();
+ if ( isset( $row->groups ) && $row->groups !== '' ) {
+ $groups = array_merge( $implicitGroups, explode( '|', $row->groups ) );
+ } else {
+ $groups = $implicitGroups;
}
- if ( !is_null( $row->ug_group2 ) ) {
- $lastUserData['rights'] = array_unique( array_merge( $lastUserData['rights'],
- User::getGroupPermissions( array( $row->ug_group2 ) ) ) );
+ if ( $fld_groups ) {
+ $data['groups'] = $groups;
+ ApiResult::setIndexedTagName( $data['groups'], 'g' );
+ ApiResult::setArrayType( $data['groups'], 'array' );
}
- $result->setIndexedTagName( $lastUserData['rights'], 'r' );
+ if ( $fld_implicitgroups ) {
+ $data['implicitgroups'] = $implicitGroups;
+ ApiResult::setIndexedTagName( $data['implicitgroups'], 'g' );
+ ApiResult::setArrayType( $data['implicitgroups'], 'array' );
+ }
+
+ if ( $fld_rights ) {
+ $data['rights'] = User::getGroupPermissions( $groups );
+ ApiResult::setIndexedTagName( $data['rights'], 'r' );
+ ApiResult::setArrayType( $data['rights'], 'array' );
+ }
}
- }
- if ( is_array( $lastUserData ) &&
- !( $params['activeusers'] && $lastUserData['recentactions'] === 0 )
- ) {
- $fit = $result->addValue( array( 'query', $this->getModuleName() ),
- null, $lastUserData );
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $data );
if ( !$fit ) {
- $this->setContinueEnumParameter( 'from', $lastUserData['name'] );
+ $this->setContinueEnumParameter( 'from', $data['name'] );
+ break;
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'u' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'u' );
}
public function getCacheMode( $params ) {
@@ -392,43 +350,20 @@ class ApiQueryAllUsers extends ApiQueryBase {
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
'witheditsonly' => false,
- 'activeusers' => false,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'from' => 'The user name to start enumerating from',
- 'to' => 'The user name to stop enumerating at',
- 'prefix' => 'Search for all users that begin with this value',
- 'dir' => 'Direction to sort in',
- 'group' => 'Limit users to given group name(s)',
- 'excludegroup' => 'Exclude users in given group name(s)',
- 'rights' => 'Limit users to given right(s) (does not include rights ' .
- 'granted by implicit or auto-promoted groups like *, user, or autoconfirmed)',
- 'prop' => array(
- 'What pieces of information to include.',
- ' blockinfo - Adds the information about a current block on the user',
- ' groups - Lists groups that the user is in. This uses ' .
- 'more server resources and may return fewer results than the limit',
- ' implicitgroups - Lists all the groups the user is automatically in',
- ' rights - Lists rights that the user has',
- ' editcount - Adds the edit count of the user',
- ' registration - Adds the timestamp of when the user registered if available (may be blank)',
+ 'activeusers' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+allusers-param-activeusers',
+ $this->getConfig()->get( 'ActiveUserDays' )
+ ),
),
- 'limit' => 'How many total user names to return',
- 'witheditsonly' => 'Only list users who have made edits',
- 'activeusers' => "Only list users active in the last {$this->getConfig()->get( 'ActiveUserDays' )} days(s)"
);
}
- public function getDescription() {
- return 'Enumerate all registered users.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=allusers&aufrom=Y',
+ 'action=query&list=allusers&aufrom=Y'
+ => 'apihelp-query+allusers-example-Y',
);
}
diff --git a/includes/api/ApiQueryBacklinks.php b/includes/api/ApiQueryBacklinks.php
index c141246d..1df14e0b 100644
--- a/includes/api/ApiQueryBacklinks.php
+++ b/includes/api/ApiQueryBacklinks.php
@@ -39,8 +39,8 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
*/
private $rootTitle;
- private $params, $contID, $redirID, $redirect;
- private $bl_ns, $bl_from, $bl_table, $bl_code, $bl_title, $bl_fields, $hasNS;
+ private $params, $cont, $redirect;
+ private $bl_ns, $bl_from, $bl_from_ns, $bl_table, $bl_code, $bl_title, $bl_fields, $hasNS;
/**
* Maps ns and title to pageid
@@ -84,6 +84,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
parent::__construct( $query, $moduleName, $code );
$this->bl_ns = $prefix . '_namespace';
$this->bl_from = $prefix . '_from';
+ $this->bl_from_ns = $prefix . '_from_namespace';
$this->bl_table = $settings['linktbl'];
$this->bl_code = $code;
$this->helpUrl = $settings['helpurl'];
@@ -119,12 +120,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
* @param ApiPageSet $resultPageSet
* @return void
*/
- private function prepareFirstQuery( $resultPageSet = null ) {
- /* SELECT page_id, page_title, page_namespace, page_is_redirect
- * FROM pagelinks, page WHERE pl_from=page_id
- * AND pl_title='Foo' AND pl_namespace=0
- * LIMIT 11 ORDER BY pl_from
- */
+ private function runFirstQuery( $resultPageSet = null ) {
$this->addTables( array( $this->bl_table, 'page' ) );
$this->addWhere( "{$this->bl_from}=page_id" );
if ( is_null( $resultPageSet ) ) {
@@ -132,18 +128,25 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
} else {
$this->addFields( $resultPageSet->getPageTableFields() );
}
+ $this->addFields( array( 'page_is_redirect', 'from_ns' => 'page_namespace' ) );
- $this->addFields( 'page_is_redirect' );
$this->addWhereFld( $this->bl_title, $this->rootTitle->getDBkey() );
-
if ( $this->hasNS ) {
$this->addWhereFld( $this->bl_ns, $this->rootTitle->getNamespace() );
}
- $this->addWhereFld( 'page_namespace', $this->params['namespace'] );
+ $this->addWhereFld( $this->bl_from_ns, $this->params['namespace'] );
- if ( !is_null( $this->contID ) ) {
+ if ( count( $this->cont ) >= 2 ) {
$op = $this->params['dir'] == 'descending' ? '<' : '>';
- $this->addWhere( "{$this->bl_from}$op={$this->contID}" );
+ if ( count( $this->params['namespace'] ) > 1 ) {
+ $this->addWhere(
+ "{$this->bl_from_ns} $op {$this->cont[0]} OR " .
+ "({$this->bl_from_ns} = {$this->cont[0]} AND " .
+ "{$this->bl_from} $op= {$this->cont[1]})"
+ );
+ } else {
+ $this->addWhere( "{$this->bl_from} $op= {$this->cont[1]}" );
+ }
}
if ( $this->params['filterredir'] == 'redirects' ) {
@@ -156,20 +159,56 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
$this->addOption( 'LIMIT', $this->params['limit'] + 1 );
$sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' );
- $this->addOption( 'ORDER BY', $this->bl_from . $sort );
+ $orderBy = array();
+ if ( count( $this->params['namespace'] ) > 1 ) {
+ $orderBy[] = $this->bl_from_ns . $sort;
+ }
+ $orderBy[] = $this->bl_from . $sort;
+ $this->addOption( 'ORDER BY', $orderBy );
$this->addOption( 'STRAIGHT_JOIN' );
+
+ $res = $this->select( __METHOD__ );
+ $count = 0;
+ foreach ( $res as $row ) {
+ if ( ++$count > $this->params['limit'] ) {
+ // We've reached the one extra which shows that there are
+ // additional pages to be had. Stop here...
+ // Continue string may be overridden at a later step
+ $this->continueStr = "{$row->from_ns}|{$row->page_id}";
+ break;
+ }
+
+ // Fill in continuation fields for later steps
+ if ( count( $this->cont ) < 2 ) {
+ $this->cont[] = $row->from_ns;
+ $this->cont[] = $row->page_id;
+ }
+
+ $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
+ $t = Title::makeTitle( $row->page_namespace, $row->page_title );
+ if ( $row->page_is_redirect ) {
+ $this->redirTitles[] = $t;
+ }
+
+ if ( is_null( $resultPageSet ) ) {
+ $a = array( 'pageid' => intval( $row->page_id ) );
+ ApiQueryBase::addTitleInfo( $a, $t );
+ if ( $row->page_is_redirect ) {
+ $a['redirect'] = true;
+ }
+ // Put all the results in an array first
+ $this->resultArr[$a['pageid']] = $a;
+ } else {
+ $resultPageSet->processDbRow( $row );
+ }
+ }
}
/**
* @param ApiPageSet $resultPageSet
* @return void
*/
- private function prepareSecondQuery( $resultPageSet = null ) {
- /* SELECT page_id, page_title, page_namespace, page_is_redirect, pl_title, pl_namespace
- FROM pagelinks, page WHERE pl_from=page_id
- AND (pl_title='Foo' AND pl_namespace=0) OR (pl_title='Bar' AND pl_namespace=1)
- ORDER BY pl_namespace, pl_title, pl_from LIMIT 11
- */
+ private function runSecondQuery( $resultPageSet = null ) {
$db = $this->getDB();
$this->addTables( array( 'page', $this->bl_table ) );
$this->addWhere( "{$this->bl_from}=page_id" );
@@ -180,7 +219,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
$this->addFields( $resultPageSet->getPageTableFields() );
}
- $this->addFields( $this->bl_title );
+ $this->addFields( array( $this->bl_title, 'from_ns' => 'page_namespace' ) );
if ( $this->hasNS ) {
$this->addFields( $this->bl_ns );
}
@@ -195,30 +234,33 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
$redirDBkey = $t->getDBkey();
$titleWhere[] = "{$this->bl_title} = " . $db->addQuotes( $redirDBkey ) .
( $this->hasNS ? " AND {$this->bl_ns} = {$redirNs}" : '' );
- $allRedirNs[] = $redirNs;
- $allRedirDBkey[] = $redirDBkey;
+ $allRedirNs[$redirNs] = true;
+ $allRedirDBkey[$redirDBkey] = true;
}
$this->addWhere( $db->makeList( $titleWhere, LIST_OR ) );
$this->addWhereFld( 'page_namespace', $this->params['namespace'] );
- if ( !is_null( $this->redirID ) ) {
+ if ( count( $this->cont ) >= 6 ) {
$op = $this->params['dir'] == 'descending' ? '<' : '>';
- /** @var $first Title */
- $first = $this->redirTitles[0];
- $title = $db->addQuotes( $first->getDBkey() );
- $ns = $first->getNamespace();
- $from = $this->redirID;
- if ( $this->hasNS ) {
- $this->addWhere( "{$this->bl_ns} $op $ns OR " .
- "({$this->bl_ns} = $ns AND " .
- "({$this->bl_title} $op $title OR " .
- "({$this->bl_title} = $title AND " .
- "{$this->bl_from} $op= $from)))" );
- } else {
- $this->addWhere( "{$this->bl_title} $op $title OR " .
- "({$this->bl_title} = $title AND " .
- "{$this->bl_from} $op= $from)" );
+
+ $where = "{$this->bl_from} $op= {$this->cont[5]}";
+ // Don't bother with namespace, title, or from_namespace if it's
+ // otherwise constant in the where clause.
+ if ( count( $this->params['namespace'] ) > 1 ) {
+ $where = "{$this->bl_from_ns} $op {$this->cont[4]} OR " .
+ "({$this->bl_from_ns} = {$this->cont[4]} AND ($where))";
+ }
+ if ( count( $allRedirDBkey ) > 1 ) {
+ $title = $db->addQuotes( $this->cont[3] );
+ $where = "{$this->bl_title} $op $title OR " .
+ "({$this->bl_title} = $title AND ($where))";
+ }
+ if ( $this->hasNS && count( $allRedirNs ) > 1 ) {
+ $where = "{$this->bl_ns} $op {$this->cont[2]} OR " .
+ "({$this->bl_ns} = {$this->cont[2]} AND ($where))";
}
+
+ $this->addWhere( $where );
}
if ( $this->params['filterredir'] == 'redirects' ) {
$this->addWhereFld( 'page_is_redirect', 1 );
@@ -229,16 +271,57 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
$this->addOption( 'LIMIT', $this->params['limit'] + 1 );
$orderBy = array();
$sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' );
- // Don't order by namespace/title if it's constant in the WHERE clause
- if ( $this->hasNS && count( array_unique( $allRedirNs ) ) != 1 ) {
+ // Don't order by namespace/title/from_namespace if it's constant in the WHERE clause
+ if ( $this->hasNS && count( $allRedirNs ) > 1 ) {
$orderBy[] = $this->bl_ns . $sort;
}
- if ( count( array_unique( $allRedirDBkey ) ) != 1 ) {
+ if ( count( $allRedirDBkey ) > 1 ) {
$orderBy[] = $this->bl_title . $sort;
}
+ if ( count( $this->params['namespace'] ) > 1 ) {
+ $orderBy[] = $this->bl_from_ns . $sort;
+ }
$orderBy[] = $this->bl_from . $sort;
$this->addOption( 'ORDER BY', $orderBy );
$this->addOption( 'USE INDEX', array( 'page' => 'PRIMARY' ) );
+
+ $res = $this->select( __METHOD__ );
+ $count = 0;
+ foreach ( $res as $row ) {
+ $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE;
+
+ if ( ++$count > $this->params['limit'] ) {
+ // We've reached the one extra which shows that there are
+ // additional pages to be had. Stop here...
+ // Note we must keep the parameters for the first query constant
+ // This may be overridden at a later step
+ $title = $row->{$this->bl_title};
+ $this->continueStr = join( '|', array_slice( $this->cont, 0, 2 ) ) .
+ "|$ns|$title|{$row->from_ns}|{$row->page_id}";
+ break;
+ }
+
+ // Fill in continuation fields for later steps
+ if ( count( $this->cont ) < 6 ) {
+ $this->cont[] = $ns;
+ $this->cont[] = $row->{$this->bl_title};
+ $this->cont[] = $row->from_ns;
+ $this->cont[] = $row->page_id;
+ }
+
+ if ( is_null( $resultPageSet ) ) {
+ $a['pageid'] = intval( $row->page_id );
+ ApiQueryBase::addTitleInfo( $a, Title::makeTitle( $row->page_namespace, $row->page_title ) );
+ if ( $row->page_is_redirect ) {
+ $a['redirect'] = true;
+ }
+ $parentID = $this->pageMap[$ns][$row->{$this->bl_title}];
+ // Put all the results in an array first
+ $this->resultArr[$parentID]['redirlinks'][$row->page_id] = $a;
+ } else {
+ $resultPageSet->processDbRow( $row );
+ }
+ }
}
/**
@@ -255,106 +338,163 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
if ( $this->params['limit'] == 'max' ) {
$this->params['limit'] = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
- $result->setParsedLimit( $this->getModuleName(), $this->params['limit'] );
+ $result->addParsedLimit( $this->getModuleName(), $this->params['limit'] );
} else {
$this->params['limit'] = intval( $this->params['limit'] );
$this->validateLimit( 'limit', $this->params['limit'], 1, $userMax, $botMax );
}
- $this->processContinue();
- $this->prepareFirstQuery( $resultPageSet );
+ $this->rootTitle = $this->getTitleOrPageId( $this->params )->getTitle();
+
+ // only image titles are allowed for the root in imageinfo mode
+ if ( !$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE ) {
+ $this->dieUsage(
+ "The title for {$this->getModuleName()} query must be a file",
+ 'bad_image_title'
+ );
+ }
- $res = $this->select( __METHOD__ . '::firstQuery' );
+ // Parse and validate continuation parameter
+ $this->cont = array();
+ if ( $this->params['continue'] !== null ) {
+ $db = $this->getDB();
+ $cont = explode( '|', $this->params['continue'] );
- $count = 0;
+ switch ( count( $cont ) ) {
+ case 8:
+ // redirect page ID for result adding
+ $this->cont[7] = (int)$cont[7];
+ $this->dieContinueUsageIf( $cont[7] !== (string)$this->cont[7] );
- foreach ( $res as $row ) {
- if ( ++$count > $this->params['limit'] ) {
- // We've reached the one extra which shows that there are
- // additional pages to be had. Stop here...
- // Continue string preserved in case the redirect query doesn't pass the limit
- $this->continueStr = $this->getContinueStr( $row->page_id );
- break;
- }
+ /* Fall through */
- if ( is_null( $resultPageSet ) ) {
- $this->extractRowInfo( $row );
- } else {
- $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
- if ( $row->page_is_redirect ) {
- $this->redirTitles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
- }
+ case 7:
+ // top-level page ID for result adding
+ $this->cont[6] = (int)$cont[6];
+ $this->dieContinueUsageIf( $cont[6] !== (string)$this->cont[6] );
- $resultPageSet->processDbRow( $row );
+ /* Fall through */
+
+ case 6:
+ // ns for 2nd query (even for imageusage)
+ $this->cont[2] = (int)$cont[2];
+ $this->dieContinueUsageIf( $cont[2] !== (string)$this->cont[2] );
+
+ // title for 2nd query
+ $this->cont[3] = $cont[3];
+
+ // from_ns for 2nd query
+ $this->cont[4] = (int)$cont[4];
+ $this->dieContinueUsageIf( $cont[4] !== (string)$this->cont[4] );
+
+ // from_id for 1st query
+ $this->cont[5] = (int)$cont[5];
+ $this->dieContinueUsageIf( $cont[5] !== (string)$this->cont[5] );
+
+ /* Fall through */
+
+ case 2:
+ // from_ns for 1st query
+ $this->cont[0] = (int)$cont[0];
+ $this->dieContinueUsageIf( $cont[0] !== (string)$this->cont[0] );
+
+ // from_id for 1st query
+ $this->cont[1] = (int)$cont[1];
+ $this->dieContinueUsageIf( $cont[1] !== (string)$this->cont[1] );
+
+ break;
+
+ default:
+ $this->dieContinueUsageIf( true );
}
+
+ ksort( $this->cont );
}
+ $this->runFirstQuery( $resultPageSet );
if ( $this->redirect && count( $this->redirTitles ) ) {
$this->resetQueryParams();
- $this->prepareSecondQuery( $resultPageSet );
- $res = $this->select( __METHOD__ . '::secondQuery' );
- $count = 0;
- foreach ( $res as $row ) {
- if ( ++$count > $this->params['limit'] ) {
- // We've reached the one extra which shows that there are
- // additional pages to be had. Stop here...
- // We need to keep the parent page of this redir in
- if ( $this->hasNS ) {
- $parentID = $this->pageMap[$row->{$this->bl_ns}][$row->{$this->bl_title}];
- } else {
- $parentID = $this->pageMap[NS_FILE][$row->{$this->bl_title}];
- }
- $this->continueStr = $this->getContinueRedirStr( $parentID, $row->page_id );
- break;
- }
-
- if ( is_null( $resultPageSet ) ) {
- $this->extractRedirRowInfo( $row );
- } else {
- $resultPageSet->processDbRow( $row );
- }
- }
+ $this->runSecondQuery( $resultPageSet );
}
+
+ // Fill in any missing fields in case it's needed below
+ $this->cont += array( 0, 0, 0, '', 0, 0, 0 );
+
if ( is_null( $resultPageSet ) ) {
// Try to add the result data in one go and pray that it fits
- $fit = $result->addValue( 'query', $this->getModuleName(), array_values( $this->resultArr ) );
+ $code = $this->bl_code;
+ $data = array_map( function ( $arr ) use ( $result, $code ) {
+ if ( isset( $arr['redirlinks'] ) ) {
+ $arr['redirlinks'] = array_values( $arr['redirlinks'] );
+ ApiResult::setIndexedTagName( $arr['redirlinks'], $code );
+ }
+ return $arr;
+ }, array_values( $this->resultArr ) );
+ $fit = $result->addValue( 'query', $this->getModuleName(), $data );
if ( !$fit ) {
// It didn't fit. Add elements one by one until the
// result is full.
+ ksort( $this->resultArr );
+ if ( count( $this->cont ) >= 7 ) {
+ $startAt = $this->cont[6];
+ } else {
+ reset( $this->resultArr );
+ $startAt = key( $this->resultArr );
+ }
+ $idx = 0;
foreach ( $this->resultArr as $pageID => $arr ) {
+ if ( $pageID < $startAt ) {
+ continue;
+ }
+
// Add the basic entry without redirlinks first
$fit = $result->addValue(
array( 'query', $this->getModuleName() ),
- null, array_diff_key( $arr, array( 'redirlinks' => '' ) ) );
+ $idx, array_diff_key( $arr, array( 'redirlinks' => '' ) ) );
if ( !$fit ) {
- $this->continueStr = $this->getContinueStr( $pageID );
+ $this->continueStr = join( '|', array_slice( $this->cont, 0, 6 ) ) .
+ "|$pageID";
break;
}
$hasRedirs = false;
- $redirLinks = isset( $arr['redirlinks'] ) ? $arr['redirlinks'] : array();
- foreach ( (array)$redirLinks as $key => $redir ) {
+ $redirLinks = isset( $arr['redirlinks'] ) ? (array)$arr['redirlinks'] : array();
+ ksort( $redirLinks );
+ if ( count( $this->cont ) >= 8 && $pageID == $startAt ) {
+ $redirStartAt = $this->cont[7];
+ } else {
+ reset( $redirLinks );
+ $redirStartAt = key( $redirLinks );
+ }
+ foreach ( $redirLinks as $key => $redir ) {
+ if ( $key < $redirStartAt ) {
+ continue;
+ }
+
$fit = $result->addValue(
- array( 'query', $this->getModuleName(), $pageID, 'redirlinks' ),
- $key, $redir );
+ array( 'query', $this->getModuleName(), $idx, 'redirlinks' ),
+ null, $redir );
if ( !$fit ) {
- $this->continueStr = $this->getContinueRedirStr( $pageID, $redir['pageid'] );
+ $this->continueStr = join( '|', array_slice( $this->cont, 0, 6 ) ) .
+ "|$pageID|$key";
break;
}
$hasRedirs = true;
}
if ( $hasRedirs ) {
- $result->setIndexedTagName_internal(
- array( 'query', $this->getModuleName(), $pageID, 'redirlinks' ),
+ $result->addIndexedTagName(
+ array( 'query', $this->getModuleName(), $idx, 'redirlinks' ),
$this->bl_code );
}
if ( !$fit ) {
break;
}
+
+ $idx++;
}
}
- $result->setIndexedTagName_internal(
+ $result->addIndexedTagName(
array( 'query', $this->getModuleName() ),
$this->bl_code
);
@@ -364,91 +504,6 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
}
}
- private function extractRowInfo( $row ) {
- $this->pageMap[$row->page_namespace][$row->page_title] = $row->page_id;
- $t = Title::makeTitle( $row->page_namespace, $row->page_title );
- $a = array( 'pageid' => intval( $row->page_id ) );
- ApiQueryBase::addTitleInfo( $a, $t );
- if ( $row->page_is_redirect ) {
- $a['redirect'] = '';
- $this->redirTitles[] = $t;
- }
- // Put all the results in an array first
- $this->resultArr[$a['pageid']] = $a;
- }
-
- private function extractRedirRowInfo( $row ) {
- $a['pageid'] = intval( $row->page_id );
- ApiQueryBase::addTitleInfo( $a, Title::makeTitle( $row->page_namespace, $row->page_title ) );
- if ( $row->page_is_redirect ) {
- $a['redirect'] = '';
- }
- $ns = $this->hasNS ? $row->{$this->bl_ns} : NS_FILE;
- $parentID = $this->pageMap[$ns][$row->{$this->bl_title}];
- // Put all the results in an array first
- $this->resultArr[$parentID]['redirlinks'][] = $a;
- $this->getResult()->setIndexedTagName(
- $this->resultArr[$parentID]['redirlinks'],
- $this->bl_code
- );
- }
-
- protected function processContinue() {
- if ( !is_null( $this->params['continue'] ) ) {
- $this->parseContinueParam();
- } else {
- $this->rootTitle = $this->getTitleOrPageId( $this->params )->getTitle();
- }
-
- // only image titles are allowed for the root in imageinfo mode
- if ( !$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE ) {
- $this->dieUsage(
- "The title for {$this->getModuleName()} query must be an image",
- 'bad_image_title'
- );
- }
- }
-
- protected function parseContinueParam() {
- $continueList = explode( '|', $this->params['continue'] );
- // expected format:
- // ns | key | id1 [| id2]
- // ns+key: root title
- // id1: first-level page ID to continue from
- // id2: second-level page ID to continue from
-
- // null stuff out now so we know what's set and what isn't
- $this->rootTitle = $this->contID = $this->redirID = null;
- $rootNs = intval( $continueList[0] );
- $this->dieContinueUsageIf( $rootNs === 0 && $continueList[0] !== '0' );
-
- $this->rootTitle = Title::makeTitleSafe( $rootNs, $continueList[1] );
- $this->dieContinueUsageIf( !$this->rootTitle );
-
- $contID = intval( $continueList[2] );
- $this->dieContinueUsageIf( $contID === 0 && $continueList[2] !== '0' );
-
- $this->contID = $contID;
- $id2 = isset( $continueList[3] ) ? $continueList[3] : null;
- $redirID = intval( $id2 );
-
- if ( $redirID === 0 && $id2 !== '0' ) {
- // This one isn't required
- return;
- }
- $this->redirID = $redirID;
- }
-
- protected function getContinueStr( $lastPageID ) {
- return $this->rootTitle->getNamespace() .
- '|' . $this->rootTitle->getDBkey() .
- '|' . $lastPageID;
- }
-
- protected function getContinueRedirStr( $lastPageID, $lastRedirID ) {
- return $this->getContinueStr( $lastPageID ) . '|' . $lastRedirID;
- }
-
public function getAllowedParams() {
$retval = array(
'title' => array(
@@ -457,7 +512,9 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
'pageid' => array(
ApiBase::PARAM_TYPE => 'integer',
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'namespace' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => 'namespace'
@@ -493,59 +550,25 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
return $retval;
}
- public function getParamDescription() {
- $retval = array(
- 'title' => "Title to search. Cannot be used together with {$this->bl_code}pageid",
- 'pageid' => "Pageid to search. Cannot be used together with {$this->bl_code}title",
- 'continue' => 'When more results are available, use this to continue',
- 'namespace' => 'The namespace to enumerate',
- 'dir' => 'The direction in which to list',
- );
- if ( $this->getModuleName() != 'embeddedin' ) {
- return array_merge( $retval, array(
- 'redirect' => 'If linking page is a redirect, find all pages ' .
- 'that link to that redirect as well. Maximum limit is halved.',
- 'filterredir' => 'How to filter for redirects. If set to ' .
- "nonredirects when {$this->bl_code}redirect is enabled, " .
- 'this is only applied to the second level',
- 'limit' => 'How many total pages to return. If ' .
- "{$this->bl_code}redirect is enabled, limit applies to each " .
- 'level separately (which means you may get up to 2 * limit results).'
- ) );
- }
-
- return array_merge( $retval, array(
- 'filterredir' => 'How to filter for redirects',
- 'limit' => 'How many total pages to return'
- ) );
- }
-
- public function getDescription() {
- switch ( $this->getModuleName() ) {
- case 'backlinks':
- return 'Find all pages that link to the given page.';
- case 'embeddedin':
- return 'Find all pages that embed (transclude) the given title.';
- case 'imageusage':
- return 'Find all pages that use the given image title.';
- default:
- ApiBase::dieDebug( __METHOD__, 'Unknown module name.' );
- }
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
static $examples = array(
'backlinks' => array(
- 'api.php?action=query&list=backlinks&bltitle=Main%20Page',
- 'api.php?action=query&generator=backlinks&gbltitle=Main%20Page&prop=info'
+ 'action=query&list=backlinks&bltitle=Main%20Page'
+ => 'apihelp-query+backlinks-example-simple',
+ 'action=query&generator=backlinks&gbltitle=Main%20Page&prop=info'
+ => 'apihelp-query+backlinks-example-generator',
),
'embeddedin' => array(
- 'api.php?action=query&list=embeddedin&eititle=Template:Stub',
- 'api.php?action=query&generator=embeddedin&geititle=Template:Stub&prop=info'
+ 'action=query&list=embeddedin&eititle=Template:Stub'
+ => 'apihelp-query+embeddedin-example-simple',
+ 'action=query&generator=embeddedin&geititle=Template:Stub&prop=info'
+ => 'apihelp-query+embeddedin-example-generator',
),
'imageusage' => array(
- 'api.php?action=query&list=imageusage&iutitle=File:Albert%20Einstein%20Head.jpg',
- 'api.php?action=query&generator=imageusage&giutitle=File:Albert%20Einstein%20Head.jpg&prop=info'
+ 'action=query&list=imageusage&iutitle=File:Albert%20Einstein%20Head.jpg'
+ => 'apihelp-query+imageusage-example-simple',
+ 'action=query&generator=imageusage&giutitle=File:Albert%20Einstein%20Head.jpg&prop=info'
+ => 'apihelp-query+imageusage-example-generator',
)
);
diff --git a/includes/api/ApiQueryBacklinksprop.php b/includes/api/ApiQueryBacklinksprop.php
index cd682612..8e271e7b 100644
--- a/includes/api/ApiQueryBacklinksprop.php
+++ b/includes/api/ApiQueryBacklinksprop.php
@@ -40,15 +40,13 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
'code' => 'rd',
'prefix' => 'rd',
'linktable' => 'redirect',
- 'what' => 'redirects to',
- 'description' => 'Returns all redirects to the given pages.',
'props' => array(
- 'fragment' => 'Fragment of each redirect, if any',
+ 'fragment',
),
'showredirects' => false,
'show' => array(
- 'fragment' => 'Only show redirects with a fragment',
- '!fragment' => 'Only show redirects without a fragment',
+ 'fragment',
+ '!fragment',
),
),
'linkshere' => array(
@@ -56,8 +54,6 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
'prefix' => 'pl',
'linktable' => 'pagelinks',
'from_namespace' => true,
- 'what' => 'pages linking to',
- 'description' => 'Find all pages that link to the given pages.',
'showredirects' => true,
),
'transcludedin' => array(
@@ -65,8 +61,6 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
'prefix' => 'tl',
'linktable' => 'templatelinks',
'from_namespace' => true,
- 'what' => 'pages transcluding',
- 'description' => 'Find all pages that transclude the given pages.',
'showredirects' => true,
),
'fileusage' => array(
@@ -75,9 +69,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
'linktable' => 'imagelinks',
'from_namespace' => true,
'to_namespace' => NS_FILE,
- 'what' => 'pages using',
'exampletitle' => 'File:Example.jpg',
- 'description' => 'Find all pages that use the given files.',
'showredirects' => true,
),
);
@@ -106,8 +98,8 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
$emptyString = $db->addQuotes( '' );
$pageSet = $this->getPageSet();
- $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
- $map = $pageSet->getAllTitlesByNamespace();
+ $titles = $pageSet->getGoodAndMissingTitles();
+ $map = $pageSet->getGoodAndMissingTitlesByNamespace();
// Determine our fields to query on
$p = $settings['prefix'];
@@ -295,8 +287,8 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
$vals['fragment'] = $row->rd_fragment;
}
- if ( $fld_redirect && $row->page_is_redirect ) {
- $vals['redirect'] = '';
+ if ( $fld_redirect ) {
+ $vals['redirect'] = (bool)$row->page_is_redirect;
}
$fit = $this->addPageSubItem( $id, $vals );
if ( !$fit ) {
@@ -348,6 +340,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => 'namespace',
),
+ 'show' => null, // Will be filled/removed below
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -355,16 +348,24 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
+ if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['namespace'][ApiBase::PARAM_HELP_MSG_APPEND] = array(
+ 'api-help-param-limited-in-miser-mode',
+ );
+ }
+
if ( !empty( $settings['showredirects'] ) ) {
$ret['prop'][ApiBase::PARAM_TYPE][] = 'redirect';
$ret['prop'][ApiBase::PARAM_DFLT] .= '|redirect';
}
if ( isset( $settings['props'] ) ) {
$ret['prop'][ApiBase::PARAM_TYPE] = array_merge(
- $ret['prop'][ApiBase::PARAM_TYPE], array_keys( $settings['props'] )
+ $ret['prop'][ApiBase::PARAM_TYPE], $settings['props']
);
}
@@ -374,93 +375,32 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
$show[] = '!redirect';
}
if ( isset( $settings['show'] ) ) {
- $show = array_merge( $show, array_keys( $settings['show'] ) );
+ $show = array_merge( $show, $settings['show'] );
}
if ( $show ) {
$ret['show'] = array(
ApiBase::PARAM_TYPE => $show,
ApiBase::PARAM_ISMULTI => true,
);
+ } else {
+ unset( $ret['show'] );
}
return $ret;
}
- public function getParamDescription() {
- $settings = self::$settings[$this->getModuleName()];
- $p = $this->getModulePrefix();
-
- $ret = array(
- 'prop' => array(
- 'Which properties to get:',
- ),
- 'show' => array(
- 'Show only items that meet this criteria.',
- ),
- 'namespace' => 'Only include pages in these namespaces',
- 'limit' => 'How many to return',
- 'continue' => 'When more results are available, use this to continue',
- );
-
- if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
- $ret['namespace'] = array(
- $ret['namespace'],
- "NOTE: Due to \$wgMiserMode, using this may result in fewer than \"{$p}limit\" results",
- 'returned before continuing; in extreme cases, zero results may be returned.',
- );
- if ( isset( $ret['type'] ) ) {
- $ret['namespace'][] = "Note that you can use {$p}type=subcat or {$p}type=file " .
- "instead of {$p}namespace=14 or 6.";
- }
- }
-
- $props = array(
- 'pageid' => 'Adds the ID of page',
- 'title' => 'Adds the title and namespace ID of the page',
- );
- if ( !empty( $settings['showredirects'] ) ) {
- $props['redirect'] = 'Indicate if the page is a redirect';
- }
- if ( isset( $settings['props'] ) ) {
- $props += $settings['props'];
- }
- foreach ( $props as $k => $v ) {
- $ret['props'][] = sprintf( "%-9s - %s", $k, $v );
- }
-
- $show = array();
- if ( !empty( $settings['showredirects'] ) ) {
- $show += array(
- 'redirect' => 'Only show redirects',
- '!redirect' => 'Only show non-redirects',
- );
- }
- if ( isset( $settings['show'] ) ) {
- $show += $settings['show'];
- }
- foreach ( $show as $k => $v ) {
- $ret['show'][] = sprintf( "%-9s - %s", $k, $v );
- }
-
- return $ret;
- }
-
- public function getDescription() {
- return self::$settings[$this->getModuleName()]['description'];
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
$settings = self::$settings[$this->getModuleName()];
$name = $this->getModuleName();
- $what = $settings['what'];
+ $path = $this->getModulePath();
$title = isset( $settings['exampletitle'] ) ? $settings['exampletitle'] : 'Main Page';
$etitle = rawurlencode( $title );
return array(
- "api.php?action=query&prop={$name}&titles={$etitle}"
- => "Get a list of $what [[$title]]",
- "api.php?action=query&generator={$name}&titles={$etitle}&prop=info"
- => "Get information about $what [[$title]]",
+ "action=query&prop={$name}&titles={$etitle}"
+ => "apihelp-$path-example-simple",
+ "action=query&generator={$name}&titles={$etitle}&prop=info"
+ => "apihelp-$path-example-generator",
);
}
diff --git a/includes/api/ApiQueryBase.php b/includes/api/ApiQueryBase.php
index 65e10ab7..a15754ce 100644
--- a/includes/api/ApiQueryBase.php
+++ b/includes/api/ApiQueryBase.php
@@ -70,6 +70,10 @@ abstract class ApiQueryBase extends ApiBase {
/**
* Override this method to request extra fields from the pageSet
* using $pageSet->requestField('fieldName')
+ *
+ * Note this only makes sense for 'prop' modules, as 'list' and 'meta'
+ * modules should not be using the pageset.
+ *
* @param ApiPageSet $pageSet
*/
public function requestExtraData( $pageSet ) {
@@ -91,6 +95,13 @@ abstract class ApiQueryBase extends ApiBase {
}
/**
+ * @see ApiBase::getParent()
+ */
+ public function getParent() {
+ return $this->getQuery();
+ }
+
+ /**
* Get the Query database connection (read-only)
* @return DatabaseBase
*/
@@ -361,12 +372,7 @@ abstract class ApiQueryBase extends ApiBase {
isset( $extraQuery['join_conds'] ) ? (array)$extraQuery['join_conds'] : array()
);
- // getDB has its own profileDBIn/Out calls
- $db = $this->getDB();
-
- $this->profileDBIn();
- $res = $db->select( $tables, $fields, $where, $method, $options, $join_conds );
- $this->profileDBOut();
+ $res = $this->getDB()->select( $tables, $fields, $where, $method, $options, $join_conds );
return $res;
}
@@ -450,7 +456,7 @@ abstract class ApiQueryBase extends ApiBase {
*/
protected function addPageSubItems( $pageId, $data ) {
$result = $this->getResult();
- $result->setIndexedTagName( $data, $this->getModulePrefix() );
+ ApiResult::setIndexedTagName( $data, $this->getModulePrefix() );
return $result->addValue( array( 'query', 'pages', intval( $pageId ) ),
$this->getModuleName(),
@@ -475,7 +481,7 @@ abstract class ApiQueryBase extends ApiBase {
if ( !$fit ) {
return false;
}
- $result->setIndexedTagName_internal( array( 'query', 'pages', $pageId,
+ $result->addIndexedTagName( array( 'query', 'pages', $pageId,
$this->getModuleName() ), $elemname );
return true;
@@ -487,7 +493,7 @@ abstract class ApiQueryBase extends ApiBase {
* @param string|array $paramValue Parameter value
*/
protected function setContinueEnumParameter( $paramName, $paramValue ) {
- $this->getResult()->setContinueParam( $this, $paramName, $paramValue );
+ $this->getContinuationManager()->addContinueParam( $this, $paramName, $paramValue );
}
/**
@@ -502,7 +508,8 @@ abstract class ApiQueryBase extends ApiBase {
*/
public function titlePartToKey( $titlePart, $namespace = NS_MAIN ) {
$t = Title::makeTitleSafe( $namespace, $titlePart . 'x' );
- if ( !$t ) {
+ if ( !$t || $t->hasFragment() ) {
+ // Invalid title (e.g. bad chars) or contained a '#'.
$this->dieUsageMsg( array( 'invalidtitle', $titlePart ) );
}
if ( $namespace != $t->getNamespace() || $t->isExternal() ) {
@@ -578,7 +585,6 @@ abstract class ApiQueryBase extends ApiBase {
protected function checkRowCount() {
wfDeprecated( __METHOD__, '1.24' );
$db = $this->getDB();
- $this->profileDBIn();
$rowcount = $db->estimateRowCount(
$this->tables,
$this->fields,
@@ -586,7 +592,6 @@ abstract class ApiQueryBase extends ApiBase {
__METHOD__,
$this->options
);
- $this->profileDBOut();
if ( $rowcount > $this->getConfig()->get( 'APIMaxDBRows' ) ) {
return false;
@@ -705,13 +710,24 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
*/
protected function setContinueEnumParameter( $paramName, $paramValue ) {
if ( $this->mGeneratorPageSet !== null ) {
- $this->getResult()->setGeneratorContinueParam( $this, $paramName, $paramValue );
+ $this->getContinuationManager()->addGeneratorContinueParam( $this, $paramName, $paramValue );
} else {
parent::setContinueEnumParameter( $paramName, $paramValue );
}
}
/**
+ * @see ApiBase::getHelpFlags()
+ *
+ * Corresponding messages: api-help-flag-generator
+ */
+ protected function getHelpFlags() {
+ $flags = parent::getHelpFlags();
+ $flags[] = 'generator';
+ return $flags;
+ }
+
+ /**
* Execute this module as a generator
* @param ApiPageSet $resultPageSet All output should be appended to this object
*/
diff --git a/includes/api/ApiQueryBlocks.php b/includes/api/ApiQueryBlocks.php
index 33b25fd9..4a7023b7 100644
--- a/includes/api/ApiQueryBlocks.php
+++ b/includes/api/ApiQueryBlocks.php
@@ -31,11 +31,6 @@
*/
class ApiQueryBlocks extends ApiQueryBase {
- /**
- * @var array
- */
- protected $usernames;
-
public function __construct( ApiQuery $query, $moduleName ) {
parent::__construct( $query, $moduleName, 'bk' );
}
@@ -62,12 +57,11 @@ class ApiQueryBlocks extends ApiQueryBase {
$result = $this->getResult();
$this->addTables( 'ipblocks' );
- $this->addFields( array( 'ipb_auto', 'ipb_id' ) );
+ $this->addFields( array( 'ipb_auto', 'ipb_id', 'ipb_timestamp' ) );
$this->addFieldsIf( array( 'ipb_address', 'ipb_user' ), $fld_user || $fld_userid );
$this->addFieldsIf( 'ipb_by_text', $fld_by );
$this->addFieldsIf( 'ipb_by', $fld_byid );
- $this->addFieldsIf( 'ipb_timestamp', $fld_timestamp );
$this->addFieldsIf( 'ipb_expiry', $fld_expiry );
$this->addFieldsIf( 'ipb_reason', $fld_reason );
$this->addFieldsIf( array( 'ipb_range_start', 'ipb_range_end' ), $fld_range );
@@ -102,10 +96,11 @@ class ApiQueryBlocks extends ApiQueryBase {
$this->addWhereFld( 'ipb_id', $params['ids'] );
}
if ( isset( $params['users'] ) ) {
+ $usernames = array();
foreach ( (array)$params['users'] as $u ) {
- $this->prepareUsername( $u );
+ $usernames[] = $this->prepareUsername( $u );
}
- $this->addWhereFld( 'ipb_address', $this->usernames );
+ $this->addWhereFld( 'ipb_address', $usernames );
$this->addWhereFld( 'ipb_auto', 0 );
}
if ( isset( $params['ip'] ) ) {
@@ -192,7 +187,9 @@ class ApiQueryBlocks extends ApiQueryBase {
$this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
break;
}
- $block = array();
+ $block = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_id ) {
$block['id'] = $row->ipb_id;
}
@@ -223,27 +220,13 @@ class ApiQueryBlocks extends ApiQueryBase {
}
if ( $fld_flags ) {
// For clarity, these flags use the same names as their action=block counterparts
- if ( $row->ipb_auto ) {
- $block['automatic'] = '';
- }
- if ( $row->ipb_anon_only ) {
- $block['anononly'] = '';
- }
- if ( $row->ipb_create_account ) {
- $block['nocreate'] = '';
- }
- if ( $row->ipb_enable_autoblock ) {
- $block['autoblock'] = '';
- }
- if ( $row->ipb_block_email ) {
- $block['noemail'] = '';
- }
- if ( $row->ipb_deleted ) {
- $block['hidden'] = '';
- }
- if ( $row->ipb_allow_usertalk ) {
- $block['allowusertalk'] = '';
- }
+ $block['automatic'] = (bool)$row->ipb_auto;
+ $block['anononly'] = (bool)$row->ipb_anon_only;
+ $block['nocreate'] = (bool)$row->ipb_create_account;
+ $block['autoblock'] = (bool)$row->ipb_enable_autoblock;
+ $block['noemail'] = (bool)$row->ipb_block_email;
+ $block['hidden'] = (bool)$row->ipb_deleted;
+ $block['allowusertalk'] = (bool)$row->ipb_allow_usertalk;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
if ( !$fit ) {
@@ -251,7 +234,7 @@ class ApiQueryBlocks extends ApiQueryBase {
break;
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'block' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'block' );
}
protected function prepareUsername( $user ) {
@@ -264,10 +247,12 @@ class ApiQueryBlocks extends ApiQueryBase {
if ( $name === false ) {
$this->dieUsage( "User name {$user} is not valid", 'param_user' );
}
- $this->usernames[] = $name;
+ return $name;
}
public function getAllowedParams() {
+ $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
+
return array(
'start' => array(
ApiBase::PARAM_TYPE => 'timestamp'
@@ -280,7 +265,8 @@ class ApiQueryBlocks extends ApiQueryBase {
'newer',
'older'
),
- ApiBase::PARAM_DFLT => 'older'
+ ApiBase::PARAM_DFLT => 'older',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
'ids' => array(
ApiBase::PARAM_TYPE => 'integer',
@@ -289,7 +275,13 @@ class ApiQueryBlocks extends ApiQueryBase {
'users' => array(
ApiBase::PARAM_ISMULTI => true
),
- 'ip' => null,
+ 'ip' => array(
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+blocks-param-ip',
+ $blockCIDRLimit['IPv4'],
+ $blockCIDRLimit['IPv6'],
+ ),
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -326,56 +318,18 @@ class ApiQueryBlocks extends ApiQueryBase {
),
ApiBase::PARAM_ISMULTI => true
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
- $p = $this->getModulePrefix();
-
- return array(
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to stop enumerating at',
- 'dir' => $this->getDirectionDescription( $p ),
- 'ids' => 'List of block IDs to list (optional)',
- 'users' => 'List of users to search for (optional)',
- 'ip' => array(
- 'Get all blocks applying to this IP or CIDR range, including range blocks.',
- "Cannot be used together with bkusers. CIDR ranges broader than " .
- "IPv4/{$blockCIDRLimit['IPv4']} or IPv6/{$blockCIDRLimit['IPv6']} " .
- "are not accepted"
- ),
- 'limit' => 'The maximum amount of blocks to list',
- 'prop' => array(
- 'Which properties to get',
- ' id - Adds the ID of the block',
- ' user - Adds the username of the blocked user',
- ' userid - Adds the user ID of the blocked user',
- ' by - Adds the username of the blocking user',
- ' byid - Adds the user ID of the blocking user',
- ' timestamp - Adds the timestamp of when the block was given',
- ' expiry - Adds the timestamp of when the block expires',
- ' reason - Adds the reason given for the block',
- ' range - Adds the range of IPs affected by the block',
- ' flags - Tags the ban with (autoblock, anononly, etc)',
- ),
- 'show' => array(
- 'Show only items that meet this criteria.',
- "For example, to see only indefinite blocks on IPs, set {$p}show=ip|!temp"
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return 'List all blocked users and IP addresses.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=blocks',
- 'api.php?action=query&list=blocks&bkusers=Alice|Bob'
+ 'action=query&list=blocks'
+ => 'apihelp-query+blocks-example-simple',
+ 'action=query&list=blocks&bkusers=Alice|Bob'
+ => 'apihelp-query+blocks-example-users',
);
}
diff --git a/includes/api/ApiQueryCategories.php b/includes/api/ApiQueryCategories.php
index 1926dd09..35fa56ef 100644
--- a/includes/api/ApiQueryCategories.php
+++ b/includes/api/ApiQueryCategories.php
@@ -117,8 +117,6 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
}
}
- $this->addOption( 'USE INDEX', array( 'categorylinks' => 'cl_from' ) );
-
$sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
// Don't order by cl_from if it's constant in the WHERE clause
if ( count( $this->getPageSet()->getGoodTitles() ) == 1 ) {
@@ -152,8 +150,8 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
if ( isset( $prop['timestamp'] ) ) {
$vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->cl_timestamp );
}
- if ( isset( $prop['hidden'] ) && !is_null( $row->pp_propname ) ) {
- $vals['hidden'] = '';
+ if ( isset( $prop['hidden'] ) ) {
+ $vals['hidden'] = !is_null( $row->pp_propname );
}
$fit = $this->addPageSubItem( $row->cl_from, $vals );
@@ -202,7 +200,9 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'categories' => array(
ApiBase::PARAM_ISMULTI => true,
),
@@ -216,34 +216,12 @@ class ApiQueryCategories extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'prop' => array(
- 'Which additional properties to get for each category',
- ' sortkey - Adds the sortkey (hexadecimal string) and sortkey prefix',
- ' (human-readable part) for the category',
- ' timestamp - Adds timestamp of when the category was added',
- ' hidden - Tags categories that are hidden with __HIDDENCAT__',
- ),
- 'limit' => 'How many categories to return',
- 'show' => 'Which kind of categories to show',
- 'continue' => 'When more results are available, use this to continue',
- 'categories' => 'Only list these categories. Useful for checking ' .
- 'whether a certain page is in a certain category',
- 'dir' => 'The direction in which to list',
- );
- }
-
- public function getDescription() {
- return 'List all categories the page(s) belong to.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=categories&titles=Albert%20Einstein'
- => 'Get a list of categories [[Albert Einstein]] belongs to',
- 'api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info'
- => 'Get information about all categories used in the [[Albert Einstein]]',
+ 'action=query&prop=categories&titles=Albert%20Einstein'
+ => 'apihelp-query+categories-example-simple',
+ 'action=query&generator=categories&titles=Albert%20Einstein&prop=info'
+ => 'apihelp-query+categories-example-generator',
);
}
diff --git a/includes/api/ApiQueryCategoryInfo.php b/includes/api/ApiQueryCategoryInfo.php
index 6e9f33c1..9f6c6044 100644
--- a/includes/api/ApiQueryCategoryInfo.php
+++ b/includes/api/ApiQueryCategoryInfo.php
@@ -38,14 +38,13 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
public function execute() {
$params = $this->extractRequestParams();
- $alltitles = $this->getPageSet()->getAllTitlesByNamespace();
+ $alltitles = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( empty( $alltitles[NS_CATEGORY] ) ) {
return;
}
$categories = $alltitles[NS_CATEGORY];
- $titles = $this->getPageSet()->getGoodTitles() +
- $this->getPageSet()->getMissingTitles();
+ $titles = $this->getPageSet()->getGoodAndMissingTitles();
$cattitles = array();
foreach ( $categories as $c ) {
/** @var $t Title */
@@ -87,9 +86,7 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
$vals['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files;
$vals['files'] = intval( $row->cat_files );
$vals['subcats'] = intval( $row->cat_subcats );
- if ( $row->cat_hidden ) {
- $vals['hidden'] = '';
- }
+ $vals['hidden'] = (bool)$row->cat_hidden;
$fit = $this->addPageSubItems( $catids[$row->cat_title], $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $row->cat_title );
@@ -104,24 +101,19 @@ class ApiQueryCategoryInfo extends ApiQueryBase {
public function getAllowedParams() {
return array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'continue' => 'When more results are available, use this to continue',
+ 'action=query&prop=categoryinfo&titles=Category:Foo|Category:Bar'
+ => 'apihelp-query+categoryinfo-example-simple',
);
}
- public function getDescription() {
- return 'Returns information about the given categories.';
- }
-
- public function getExamples() {
- return 'api.php?action=query&prop=categoryinfo&titles=Category:Foo|Category:Bar';
- }
-
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/API:Properties#categoryinfo_.2F_ci';
}
diff --git a/includes/api/ApiQueryCategoryMembers.php b/includes/api/ApiQueryCategoryMembers.php
index a88a9cb1..ec0c1d14 100644
--- a/includes/api/ApiQueryCategoryMembers.php
+++ b/includes/api/ApiQueryCategoryMembers.php
@@ -48,6 +48,15 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
}
/**
+ * @param string $hexSortkey
+ * @return bool
+ */
+ private function validateHexSortkey( $hexSortkey ) {
+ // A hex sortkey has an unbound number of 2 letter pairs
+ return preg_match( '/^(?:[a-fA-F0-9]{2})*$/', $hexSortkey );
+ }
+
+ /**
* @param ApiPageSet $resultPageSet
* @return void
*/
@@ -128,6 +137,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
$queryTypes = array_slice( $queryTypes, $contTypeIndex );
// Add a WHERE clause for sortkey and from
+ $this->dieContinueUsageIf( !$this->validateHexSortkey( $cont[1] ) );
// pack( "H*", $foo ) is used to convert hex back to binary
$escSortkey = $this->getDB()->addQuotes( pack( 'H*', $cont[1] ) );
$from = intval( $cont[2] );
@@ -143,6 +153,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
if ( $params['startsortkeyprefix'] !== null ) {
$startsortkey = Collation::singleton()->getSortkey( $params['startsortkeyprefix'] );
} elseif ( $params['starthexsortkey'] !== null ) {
+ if ( !$this->validateHexSortkey( $params['starthexsortkey'] ) ) {
+ $this->dieUsage( 'The starthexsortkey provided is not valid', 'bad_starthexsortkey' );
+ }
$startsortkey = pack( 'H*', $params['starthexsortkey'] );
} else {
$this->logFeatureUsage( 'list=categorymembers&cmstartsortkey' );
@@ -151,6 +164,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
if ( $params['endsortkeyprefix'] !== null ) {
$endsortkey = Collation::singleton()->getSortkey( $params['endsortkeyprefix'] );
} elseif ( $params['endhexsortkey'] !== null ) {
+ if ( !$this->validateHexSortkey( $params['endhexsortkey'] ) ) {
+ $this->dieUsage( 'The endhexsortkey provided is not valid', 'bad_endhexsortkey' );
+ }
$endsortkey = pack( 'H*', $params['endhexsortkey'] );
} else {
$this->logFeatureUsage( 'list=categorymembers&cmendsortkey' );
@@ -230,7 +246,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = intval( $row->page_id );
}
@@ -269,13 +287,13 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal(
+ $result->addIndexedTagName(
array( 'query', $this->getModuleName() ), 'cm' );
}
}
public function getAllowedParams() {
- return array(
+ $ret = array(
'title' => array(
ApiBase::PARAM_TYPE => 'string',
),
@@ -307,7 +325,9 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
'file'
)
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_TYPE => 'limit',
ApiBase::PARAM_DFLT => 10,
@@ -351,67 +371,22 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
ApiBase::PARAM_DEPRECATED => true,
),
);
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
- $desc = array(
- 'title' => "Which category to enumerate (required). Must include " .
- "'Category:' prefix. Cannot be used together with {$p}pageid",
- 'pageid' => "Page ID of the category to enumerate. Cannot be used together with {$p}title",
- 'prop' => array(
- 'What pieces of information to include',
- ' ids - Adds the page ID',
- ' title - Adds the title and namespace ID of the page',
- ' sortkey - Adds the sortkey used for sorting in the category (hexadecimal string)',
- ' sortkeyprefix - Adds the sortkey prefix used for sorting in the ' .
- 'category (human-readable part of the sortkey)',
- ' type - Adds the type that the page has been categorised as (page, subcat or file)',
- ' timestamp - Adds the timestamp of when the page was included',
- ),
- 'namespace' => 'Only include pages in these namespaces',
- 'type' => "What type of category members to include. Ignored when {$p}sort=timestamp is set",
- 'sort' => 'Property to sort by',
- 'dir' => 'In which direction to sort',
- 'start' => "Timestamp to start listing from. Can only be used with {$p}sort=timestamp",
- 'end' => "Timestamp to end listing at. Can only be used with {$p}sort=timestamp",
- 'starthexsortkey' => "Sortkey to start listing from, as returned by prop=sortkey. " .
- "Can only be used with {$p}sort=sortkey",
- 'endhexsortkey' => "Sortkey to end listing from, as returned by prop=sortkey. " .
- "Can only be used with {$p}sort=sortkey",
- 'startsortkeyprefix' => "Sortkey prefix to start listing from. Can " .
- "only be used with {$p}sort=sortkey. Overrides {$p}starthexsortkey",
- 'endsortkeyprefix' => "Sortkey prefix to end listing BEFORE (not at, " .
- "if this value occurs it will not be included!). Can only be used with " .
- "{$p}sort=sortkey. Overrides {$p}endhexsortkey",
- 'startsortkey' => "Use starthexsortkey instead",
- 'endsortkey' => "Use endhexsortkey instead",
- 'continue' => 'For large categories, give the value returned from previous query',
- 'limit' => 'The maximum number of pages to return.',
- );
if ( $this->getConfig()->get( 'MiserMode' ) ) {
- $desc['namespace'] = array(
- $desc['namespace'],
- "NOTE: Due to \$wgMiserMode, using this may result in fewer than \"{$p}limit\" results",
- 'returned before continuing; in extreme cases, zero results may be returned.',
- "Note that you can use {$p}type=subcat or {$p}type=file instead of {$p}namespace=14 or 6.",
+ $ret['namespace'][ApiBase::PARAM_HELP_MSG_APPEND] = array(
+ 'api-help-param-limited-in-miser-mode',
);
}
- return $desc;
- }
-
- public function getDescription() {
- return 'List all pages in a given category.';
+ return $ret;
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=categorymembers&cmtitle=Category:Physics'
- => 'Get first 10 pages in [[Category:Physics]]',
- 'api.php?action=query&generator=categorymembers&gcmtitle=Category:Physics&prop=info'
- => 'Get page info about first 10 pages in [[Category:Physics]]',
+ 'action=query&list=categorymembers&cmtitle=Category:Physics'
+ => 'apihelp-query+categorymembers-example-simple',
+ 'action=query&generator=categorymembers&gcmtitle=Category:Physics&prop=info'
+ => 'apihelp-query+categorymembers-example-generator',
);
}
diff --git a/includes/api/ApiQueryContributors.php b/includes/api/ApiQueryContributors.php
index 55ea4702..7e76db25 100644
--- a/includes/api/ApiQueryContributors.php
+++ b/includes/api/ApiQueryContributors.php
@@ -236,43 +236,16 @@ class ApiQueryContributors extends ApiQueryBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'group' => array(
- 'Limit users to given group name(s)',
- 'Does not include implicit or auto-promoted groups like *, user, or autoconfirmed'
- ),
- 'excludegroup' => array(
- 'Exclude users in given group name(s)',
- 'Does not include implicit or auto-promoted groups like *, user, or autoconfirmed'
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'rights' => array(
- 'Limit users to those having given right(s)',
- 'Does not include rights granted by implicit or auto-promoted groups ' .
- 'like *, user, or autoconfirmed'
- ),
- 'excluderights' => array(
- 'Limit users to those not having given right(s)',
- 'Does not include rights granted by implicit or auto-promoted groups ' .
- 'like *, user, or autoconfirmed'
- ),
- 'limit' => 'How many contributors to return',
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return 'Get the list of logged-in contributors and ' .
- 'the count of anonymous contributors to a page.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=contributors&titles=Main_Page',
+ 'action=query&prop=contributors&titles=Main_Page'
+ => 'apihelp-query+contributors-example-simple',
);
}
diff --git a/includes/api/ApiQueryDeletedRevisions.php b/includes/api/ApiQueryDeletedRevisions.php
new file mode 100644
index 00000000..26ae2668
--- /dev/null
+++ b/includes/api/ApiQueryDeletedRevisions.php
@@ -0,0 +1,304 @@
+<?php
+/**
+ * Created on Oct 3, 2014
+ *
+ * Copyright © 2014 Brad Jorsch "bjorsch@wikimedia.org"
+ *
+ * Heavily based on ApiQueryDeletedrevs,
+ * Copyright © 2007 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Query module to enumerate deleted revisions for pages.
+ *
+ * @ingroup API
+ */
+class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
+
+ public function __construct( ApiQuery $query, $moduleName ) {
+ parent::__construct( $query, $moduleName, 'drv' );
+ }
+
+ protected function run( ApiPageSet $resultPageSet = null ) {
+ $user = $this->getUser();
+ // Before doing anything at all, let's check permissions
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $this->dieUsage(
+ 'You don\'t have permission to view deleted revision information',
+ 'permissiondenied'
+ );
+ }
+
+ $result = $this->getResult();
+ $pageSet = $this->getPageSet();
+ $pageMap = $pageSet->getGoodAndMissingTitlesByNamespace();
+ $pageCount = count( $pageSet->getGoodAndMissingTitles() );
+ $revCount = $pageSet->getRevisionCount();
+ if ( $revCount === 0 && $pageCount === 0 ) {
+ // Nothing to do
+ return;
+ }
+ if ( $revCount !== 0 && count( $pageSet->getDeletedRevisionIDs() ) === 0 ) {
+ // Nothing to do, revisions were supplied but none are deleted
+ return;
+ }
+
+ $params = $this->extractRequestParams( false );
+
+ $db = $this->getDB();
+
+ if ( !is_null( $params['user'] ) && !is_null( $params['excludeuser'] ) ) {
+ $this->dieUsage( 'user and excludeuser cannot be used together', 'badparams' );
+ }
+
+ $this->addTables( 'archive' );
+ if ( $resultPageSet === null ) {
+ $this->parseParameters( $params );
+ $this->addFields( Revision::selectArchiveFields() );
+ $this->addFields( array( 'ar_title', 'ar_namespace' ) );
+ } else {
+ $this->limit = $this->getParameter( 'limit' ) ?: 10;
+ $this->addFields( array( 'ar_title', 'ar_namespace', 'ar_timestamp', 'ar_rev_id', 'ar_id' ) );
+ }
+
+ if ( $this->fld_tags ) {
+ $this->addTables( 'tag_summary' );
+ $this->addJoinConds(
+ array( 'tag_summary' => array( 'LEFT JOIN', array( 'ar_rev_id=ts_rev_id' ) ) )
+ );
+ $this->addFields( 'ts_tags' );
+ }
+
+ if ( !is_null( $params['tag'] ) ) {
+ $this->addTables( 'change_tag' );
+ $this->addJoinConds(
+ array( 'change_tag' => array( 'INNER JOIN', array( 'ar_rev_id=ct_rev_id' ) ) )
+ );
+ $this->addWhereFld( 'ct_tag', $params['tag'] );
+ }
+
+ if ( $this->fetchContent ) {
+ // Modern MediaWiki has the content for deleted revs in the 'text'
+ // table using fields old_text and old_flags. But revisions deleted
+ // pre-1.5 store the content in the 'archive' table directly using
+ // fields ar_text and ar_flags, and no corresponding 'text' row. So
+ // we have to LEFT JOIN and fetch all four fields.
+ $this->addTables( 'text' );
+ $this->addJoinConds(
+ array( 'text' => array( 'LEFT JOIN', array( 'ar_text_id=old_id' ) ) )
+ );
+ $this->addFields( array( 'ar_text', 'ar_flags', 'old_text', 'old_flags' ) );
+
+ // This also means stricter restrictions
+ if ( !$user->isAllowedAny( 'undelete', 'deletedtext' ) ) {
+ $this->dieUsage(
+ 'You don\'t have permission to view deleted revision content',
+ 'permissiondenied'
+ );
+ }
+ }
+
+ $dir = $params['dir'];
+
+ if ( $revCount !== 0 ) {
+ $this->addWhere( array(
+ 'ar_rev_id' => array_keys( $pageSet->getDeletedRevisionIDs() )
+ ) );
+ } else {
+ // We need a custom WHERE clause that matches all titles.
+ $lb = new LinkBatch( $pageSet->getGoodAndMissingTitles() );
+ $where = $lb->constructSet( 'ar', $db );
+ $this->addWhere( $where );
+ }
+
+ if ( !is_null( $params['user'] ) ) {
+ $this->addWhereFld( 'ar_user_text', $params['user'] );
+ } elseif ( !is_null( $params['excludeuser'] ) ) {
+ $this->addWhere( 'ar_user_text != ' .
+ $db->addQuotes( $params['excludeuser'] ) );
+ }
+
+ if ( !is_null( $params['user'] ) || !is_null( $params['excludeuser'] ) ) {
+ // Paranoia: avoid brute force searches (bug 17342)
+ // (shouldn't be able to get here without 'deletedhistory', but
+ // check it again just in case)
+ if ( !$user->isAllowed( 'deletedhistory' ) ) {
+ $bitmask = Revision::DELETED_USER;
+ } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+ $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED;
+ } else {
+ $bitmask = 0;
+ }
+ if ( $bitmask ) {
+ $this->addWhere( $db->bitAnd( 'ar_deleted', $bitmask ) . " != $bitmask" );
+ }
+ }
+
+ if ( !is_null( $params['continue'] ) ) {
+ $cont = explode( '|', $params['continue'] );
+ $op = ( $dir == 'newer' ? '>' : '<' );
+ if ( $revCount !== 0 ) {
+ $this->dieContinueUsageIf( count( $cont ) != 2 );
+ $rev = intval( $cont[0] );
+ $this->dieContinueUsageIf( strval( $rev ) !== $cont[0] );
+ $ar_id = (int)$cont[1];
+ $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[1] );
+ $this->addWhere( "ar_rev_id $op $rev OR " .
+ "(ar_rev_id = $rev AND " .
+ "ar_id $op= $ar_id)" );
+ } else {
+ $this->dieContinueUsageIf( count( $cont ) != 4 );
+ $ns = intval( $cont[0] );
+ $this->dieContinueUsageIf( strval( $ns ) !== $cont[0] );
+ $title = $db->addQuotes( $cont[1] );
+ $ts = $db->addQuotes( $db->timestamp( $cont[2] ) );
+ $ar_id = (int)$cont[3];
+ $this->dieContinueUsageIf( strval( $ar_id ) !== $cont[3] );
+ $this->addWhere( "ar_namespace $op $ns OR " .
+ "(ar_namespace = $ns AND " .
+ "(ar_title $op $title OR " .
+ "(ar_title = $title AND " .
+ "(ar_timestamp $op $ts OR " .
+ "(ar_timestamp = $ts AND " .
+ "ar_id $op= $ar_id)))))" );
+ }
+ }
+
+ $this->addOption( 'LIMIT', $this->limit + 1 );
+
+ if ( $revCount !== 0 ) {
+ // Sort by ar_rev_id when querying by ar_rev_id
+ $this->addWhereRange( 'ar_rev_id', $dir, null, null );
+ } else {
+ // Sort by ns and title in the same order as timestamp for efficiency
+ // But only when not already unique in the query
+ if ( count( $pageMap ) > 1 ) {
+ $this->addWhereRange( 'ar_namespace', $dir, null, null );
+ }
+ $oneTitle = key( reset( $pageMap ) );
+ foreach ( $pageMap as $pages ) {
+ if ( count( $pages ) > 1 || key( $pages ) !== $oneTitle ) {
+ $this->addWhereRange( 'ar_title', $dir, null, null );
+ break;
+ }
+ }
+ $this->addTimestampWhereRange( 'ar_timestamp', $dir, $params['start'], $params['end'] );
+ }
+ // Include in ORDER BY for uniqueness
+ $this->addWhereRange( 'ar_id', $dir, null, null );
+
+ $res = $this->select( __METHOD__ );
+ $count = 0;
+ $generated = array();
+ foreach ( $res as $row ) {
+ if ( ++$count > $this->limit ) {
+ // We've had enough
+ $this->setContinueEnumParameter( 'continue',
+ $revCount
+ ? "$row->ar_rev_id|$row->ar_id"
+ : "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+ );
+ break;
+ }
+
+ if ( $resultPageSet !== null ) {
+ $generated[] = $row->ar_rev_id;
+ } else {
+ if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
+ // Was it converted?
+ $title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
+ $converted = $pageSet->getConvertedTitles();
+ if ( $title && isset( $converted[$title->getPrefixedText()] ) ) {
+ $title = Title::newFromText( $converted[$title->getPrefixedText()] );
+ if ( $title && isset( $pageMap[$title->getNamespace()][$title->getDBkey()] ) ) {
+ $pageMap[$row->ar_namespace][$row->ar_title] =
+ $pageMap[$title->getNamespace()][$title->getDBkey()];
+ }
+ }
+ }
+ if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
+ ApiBase::dieDebug( "Found row in archive (ar_id={$row->ar_id}) that didn't " .
+ "get processed by ApiPageSet" );
+ }
+
+ $fit = $this->addPageSubItem(
+ $pageMap[$row->ar_namespace][$row->ar_title],
+ $this->extractRevisionInfo( Revision::newFromArchiveRow( $row ), $row ),
+ 'rev'
+ );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'continue',
+ $revCount
+ ? "$row->ar_rev_id|$row->ar_id"
+ : "$row->ar_namespace|$row->ar_title|$row->ar_timestamp|$row->ar_id"
+ );
+ break;
+ }
+ }
+ }
+
+ if ( $resultPageSet !== null ) {
+ $resultPageSet->populateFromRevisionIDs( $generated );
+ }
+ }
+
+ public function getAllowedParams() {
+ return parent::getAllowedParams() + array(
+ 'start' => array(
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ),
+ 'end' => array(
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ),
+ 'dir' => array(
+ ApiBase::PARAM_TYPE => array(
+ 'newer',
+ 'older'
+ ),
+ ApiBase::PARAM_DFLT => 'older',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+ ),
+ 'tag' => null,
+ 'user' => array(
+ ApiBase::PARAM_TYPE => 'user'
+ ),
+ 'excludeuser' => array(
+ ApiBase::PARAM_TYPE => 'user'
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
+ );
+ }
+
+ protected function getExamplesMessages() {
+ return array(
+ 'action=query&prop=deletedrevisions&titles=Main%20Page|Talk:Main%20Page&' .
+ 'drvprop=user|comment|content'
+ => 'apihelp-query+deletedrevisions-example-titles',
+ 'action=query&prop=deletedrevisions&revids=123456'
+ => 'apihelp-query+deletedrevisions-example-revids',
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Properties#deletedrevisions_.2F_drv';
+ }
+}
diff --git a/includes/api/ApiQueryDeletedrevs.php b/includes/api/ApiQueryDeletedrevs.php
index 9042696b..72a331f1 100644
--- a/includes/api/ApiQueryDeletedrevs.php
+++ b/includes/api/ApiQueryDeletedrevs.php
@@ -28,6 +28,7 @@
* Query module to enumerate all deleted revisions.
*
* @ingroup API
+ * @deprecated since 1.25
*/
class ApiQueryDeletedrevs extends ApiQueryBase {
@@ -45,6 +46,12 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
);
}
+ $this->setWarning(
+ 'list=deletedrevs has been deprecated. Please use prop=deletedrevisions or ' .
+ 'list=alldeletedrevisions instead.'
+ );
+ $this->logFeatureUsage( 'action=query&list=deletedrevs' );
+
$db = $this->getDB();
$params = $this->extractRequestParams( false );
$prop = array_flip( $params['prop'] );
@@ -68,8 +75,9 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
);
}
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
$fld_token = false;
}
@@ -169,7 +177,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
if ( $limit == 'max' ) {
$limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
- $this->getResult()->setParsedLimit( $this->getModuleName(), $limit );
+ $this->getResult()->addParsedLimit( $this->getModuleName(), $limit );
}
$this->validateLimit( 'limit', $limit, 1, $userMax, $botMax );
@@ -312,7 +320,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
}
if ( $fld_user || $fld_userid ) {
if ( $row->ar_deleted & Revision::DELETED_USER ) {
- $rev['userhidden'] = '';
+ $rev['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_USER, $user ) ) {
@@ -327,7 +335,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
if ( $fld_comment || $fld_parsedcomment ) {
if ( $row->ar_deleted & Revision::DELETED_COMMENT ) {
- $rev['commenthidden'] = '';
+ $rev['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_COMMENT, $user ) ) {
@@ -341,15 +349,15 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
}
}
- if ( $fld_minor && $row->ar_minor_edit == 1 ) {
- $rev['minor'] = '';
+ if ( $fld_minor ) {
+ $rev['minor'] = $row->ar_minor_edit == 1;
}
if ( $fld_len ) {
$rev['len'] = $row->ar_len;
}
if ( $fld_sha1 ) {
if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
- $rev['sha1hidden'] = '';
+ $rev['sha1hidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
@@ -362,15 +370,15 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
}
if ( $fld_content ) {
if ( $row->ar_deleted & Revision::DELETED_TEXT ) {
- $rev['texthidden'] = '';
+ $rev['texthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->ar_deleted, Revision::DELETED_TEXT, $user ) ) {
if ( isset( $row->ar_text ) && !$row->ar_text_id ) {
// Pre-1.5 ar_text row (if condition from Revision::newFromArchiveRow)
- ApiResult::setContent( $rev, Revision::getRevisionText( $row, 'ar_' ) );
+ ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row, 'ar_' ) );
} else {
- ApiResult::setContent( $rev, Revision::getRevisionText( $row ) );
+ ApiResult::setContentValue( $rev, 'text', Revision::getRevisionText( $row ) );
}
}
}
@@ -378,7 +386,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
if ( $fld_tags ) {
if ( $row->ts_tags ) {
$tags = explode( ',', $row->ts_tags );
- $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ ApiResult::setIndexedTagName( $tags, 'tag' );
$rev['tags'] = $tags;
} else {
$rev['tags'] = array();
@@ -386,14 +394,14 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
}
if ( $anyHidden && ( $row->ar_deleted & Revision::DELETED_RESTRICTED ) ) {
- $rev['suppressed'] = '';
+ $rev['suppressed'] = true;
}
if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
$pageID = $newPageID++;
$pageMap[$row->ar_namespace][$row->ar_title] = $pageID;
$a['revisions'] = array( $rev );
- $result->setIndexedTagName( $a['revisions'], 'rev' );
+ ApiResult::setIndexedTagName( $a['revisions'], 'rev' );
$title = Title::makeTitle( $row->ar_namespace, $row->ar_title );
ApiQueryBase::addTitleInfo( $a, $title );
if ( $fld_token ) {
@@ -417,46 +425,56 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
break;
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'page' );
+ }
+
+ public function isDeprecated() {
+ return true;
}
public function getAllowedParams() {
return array(
'start' => array(
- ApiBase::PARAM_TYPE => 'timestamp'
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 1, 2 ) ),
),
'end' => array(
ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 1, 2 ) ),
),
'dir' => array(
ApiBase::PARAM_TYPE => array(
'newer',
'older'
),
- ApiBase::PARAM_DFLT => 'older'
+ ApiBase::PARAM_DFLT => 'older',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 1, 3 ) ),
),
- 'from' => null,
- 'to' => null,
- 'prefix' => null,
- 'continue' => null,
- 'unique' => false,
- 'tag' => null,
- 'user' => array(
- ApiBase::PARAM_TYPE => 'user'
+ 'from' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 3 ) ),
),
- 'excludeuser' => array(
- ApiBase::PARAM_TYPE => 'user'
+ 'to' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 3 ) ),
+ ),
+ 'prefix' => array(
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 3 ) ),
+ ),
+ 'unique' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 3 ) ),
),
'namespace' => array(
ApiBase::PARAM_TYPE => 'namespace',
ApiBase::PARAM_DFLT => NS_MAIN,
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'modes', 3 ) ),
),
- 'limit' => array(
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ 'tag' => null,
+ 'user' => array(
+ ApiBase::PARAM_TYPE => 'user'
+ ),
+ 'excludeuser' => array(
+ ApiBase::PARAM_TYPE => 'user'
),
'prop' => array(
ApiBase::PARAM_DFLT => 'user|comment',
@@ -476,68 +494,30 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
),
ApiBase::PARAM_ISMULTI => true
),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'start' => 'The timestamp to start enumerating from (1, 2)',
- 'end' => 'The timestamp to stop enumerating at (1, 2)',
- 'dir' => $this->getDirectionDescription( $this->getModulePrefix(), ' (1, 3)' ),
- 'from' => 'Start listing at this title (3)',
- 'to' => 'Stop listing at this title (3)',
- 'prefix' => 'Search for all page titles that begin with this value (3)',
- 'limit' => 'The maximum amount of revisions to list',
- 'prop' => array(
- 'Which properties to get',
- ' revid - Adds the revision ID of the deleted revision',
- ' parentid - Adds the revision ID of the previous revision to the page',
- ' user - Adds the user who made the revision',
- ' userid - Adds the user ID whom made the revision',
- ' comment - Adds the comment of the revision',
- ' parsedcomment - Adds the parsed comment of the revision',
- ' minor - Tags if the revision is minor',
- ' len - Adds the length (bytes) of the revision',
- ' sha1 - Adds the SHA-1 (base 16) of the revision',
- ' content - Adds the content of the revision',
- ' token - DEPRECATED! Gives the edit token',
- ' tags - Tags for the revision',
+ 'limit' => array(
+ ApiBase::PARAM_DFLT => 10,
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'namespace' => 'Only list pages in this namespace (3)',
- 'user' => 'Only list revisions by this user',
- 'excludeuser' => 'Don\'t list revisions by this user',
- 'continue' => 'When more results are available, use this to continue',
- 'unique' => 'List only one revision for each page (3)',
- 'tag' => 'Only list revisions tagged with this tag',
- );
- }
-
- public function getDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'List deleted revisions.',
- 'Operates in three modes:',
- ' 1) List deleted revisions for the given title(s), sorted by timestamp.',
- ' 2) List deleted contributions for the given user, sorted by timestamp (no titles specified).',
- ' 3) List all deleted revisions in the given namespace, sorted by title and timestamp',
- " (no titles specified, {$p}user not set).",
- 'Certain parameters only apply to some modes and are ignored in others.',
- 'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.',
);
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&' .
+ 'action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&' .
'drprop=user|comment|content'
- => 'List the last deleted revisions of Main Page and Talk:Main Page, with content (mode 1)',
- 'api.php?action=query&list=deletedrevs&druser=Bob&drlimit=50'
- => 'List the last 50 deleted contributions by Bob (mode 2)',
- 'api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50'
- => 'List the first 50 deleted revisions in the main namespace (mode 3)',
- 'api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=1&drunique='
- => 'List the first 50 deleted pages in the Talk namespace (mode 3):',
+ => 'apihelp-query+deletedrevs-example-mode1',
+ 'action=query&list=deletedrevs&druser=Bob&drlimit=50'
+ => 'apihelp-query+deletedrevs-example-mode2',
+ 'action=query&list=deletedrevs&drdir=newer&drlimit=50'
+ => 'apihelp-query+deletedrevs-example-mode3-main',
+ 'action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=1&drunique='
+ => 'apihelp-query+deletedrevs-example-mode3-talk',
);
}
diff --git a/includes/api/ApiQueryDisabled.php b/includes/api/ApiQueryDisabled.php
index cf0d841e..a6509d41 100644
--- a/includes/api/ApiQueryDisabled.php
+++ b/includes/api/ApiQueryDisabled.php
@@ -44,17 +44,7 @@ class ApiQueryDisabled extends ApiQueryBase {
return array();
}
- public function getParamDescription() {
- return array();
- }
-
- public function getDescription() {
- return array(
- 'This module has been disabled.'
- );
- }
-
- public function getExamples() {
- return array();
+ public function getDescriptionMessage() {
+ return 'apihelp-query+disabled-description';
}
}
diff --git a/includes/api/ApiQueryDuplicateFiles.php b/includes/api/ApiQueryDuplicateFiles.php
index 6d836cd5..4d0bcfed 100644
--- a/includes/api/ApiQueryDuplicateFiles.php
+++ b/includes/api/ApiQueryDuplicateFiles.php
@@ -52,7 +52,7 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
*/
private function run( $resultPageSet = null ) {
$params = $this->extractRequestParams();
- $namespaces = $this->getPageSet()->getAllTitlesByNamespace();
+ $namespaces = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( empty( $namespaces[NS_FILE] ) ) {
return;
}
@@ -137,11 +137,9 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
$r = array(
'name' => $dupName,
'user' => $dupFile->getUser( 'text' ),
- 'timestamp' => wfTimestamp( TS_ISO_8601, $dupFile->getTimestamp() )
+ 'timestamp' => wfTimestamp( TS_ISO_8601, $dupFile->getTimestamp() ),
+ 'shared' => !$dupFile->isLocal(),
);
- if ( !$dupFile->isLocal() ) {
- $r['shared'] = '';
- }
$fit = $this->addPageSubItem( $pageId, $r );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', $image . '|' . $dupName );
@@ -167,7 +165,9 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'dir' => array(
ApiBase::PARAM_DFLT => 'ascending',
ApiBase::PARAM_TYPE => array(
@@ -179,23 +179,12 @@ class ApiQueryDuplicateFiles extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'limit' => 'How many duplicate files to return',
- 'continue' => 'When more results are available, use this to continue',
- 'dir' => 'The direction in which to list',
- 'localonly' => 'Look only for files in the local repository',
- );
- }
-
- public function getDescription() {
- return 'List all files that are duplicates of the given file(s) based on hash values.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&titles=File:Albert_Einstein_Head.jpg&prop=duplicatefiles',
- 'api.php?action=query&generator=allimages&prop=duplicatefiles',
+ 'action=query&titles=File:Albert_Einstein_Head.jpg&prop=duplicatefiles'
+ => 'apihelp-query+duplicatefiles-example-simple',
+ 'action=query&generator=allimages&prop=duplicatefiles'
+ => 'apihelp-query+duplicatefiles-example-generated',
);
}
diff --git a/includes/api/ApiQueryExtLinksUsage.php b/includes/api/ApiQueryExtLinksUsage.php
index faabb920..3f65a19e 100644
--- a/includes/api/ApiQueryExtLinksUsage.php
+++ b/includes/api/ApiQueryExtLinksUsage.php
@@ -112,7 +112,9 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = intval( $row->page_id );
}
@@ -139,13 +141,13 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ),
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ),
$this->getModulePrefix() );
}
}
public function getAllowedParams() {
- return array(
+ $ret = array(
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_DFLT => 'ids|title|url',
@@ -156,7 +158,8 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
)
),
'offset' => array(
- ApiBase::PARAM_TYPE => 'integer'
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
'protocol' => array(
ApiBase::PARAM_TYPE => self::prepareProtocols(),
@@ -176,6 +179,14 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
),
'expandurl' => false,
);
+
+ if ( $this->getConfig()->get( 'MiserMode' ) ) {
+ $ret['namespace'][ApiBase::PARAM_HELP_MSG_APPEND] = array(
+ 'api-help-param-limited-in-miser-mode',
+ );
+ }
+
+ return $ret;
}
public static function prepareProtocols() {
@@ -207,45 +218,10 @@ class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
}
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
- $desc = array(
- 'prop' => array(
- 'What pieces of information to include',
- ' ids - Adds the ID of page',
- ' title - Adds the title and namespace ID of the page',
- ' url - Adds the URL used in the page',
- ),
- 'offset' => 'Used for paging. Use the value returned for "continue"',
- 'protocol' => array(
- "Protocol of the URL. If empty and {$p}query set, the protocol is http.",
- "Leave both this and {$p}query empty to list all external links"
- ),
- 'query' => 'Search string without protocol. See [[Special:LinkSearch]]. ' .
- 'Leave empty to list all external links',
- 'namespace' => 'The page namespace(s) to enumerate.',
- 'limit' => 'How many pages to return.',
- 'expandurl' => 'Expand protocol-relative URLs with the canonical protocol',
- );
-
- if ( $this->getConfig()->get( 'MiserMode' ) ) {
- $desc['namespace'] = array(
- $desc['namespace'],
- "NOTE: Due to \$wgMiserMode, using this may result in fewer than \"{$p}limit\" results",
- 'returned before continuing; in extreme cases, zero results may be returned',
- );
- }
-
- return $desc;
- }
-
- public function getDescription() {
- return 'Enumerate pages that contain a given URL.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=exturlusage&euquery=www.mediawiki.org'
+ 'action=query&list=exturlusage&euquery=www.mediawiki.org'
+ => 'apihelp-query+exturlusage-example-simple',
);
}
diff --git a/includes/api/ApiQueryExternalLinks.php b/includes/api/ApiQueryExternalLinks.php
index 95666354..ec3d9d27 100644
--- a/includes/api/ApiQueryExternalLinks.php
+++ b/includes/api/ApiQueryExternalLinks.php
@@ -91,7 +91,7 @@ class ApiQueryExternalLinks extends ApiQueryBase {
if ( $params['expandurl'] ) {
$to = wfExpandUrl( $to, PROTO_CANONICAL );
}
- ApiResult::setContent( $entry, $to );
+ ApiResult::setContentValue( $entry, 'url', $to );
$fit = $this->addPageSubItem( $row->el_from, $entry );
if ( !$fit ) {
$this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
@@ -114,7 +114,8 @@ class ApiQueryExternalLinks extends ApiQueryBase {
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
'offset' => array(
- ApiBase::PARAM_TYPE => 'integer'
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
'protocol' => array(
ApiBase::PARAM_TYPE => ApiQueryExtLinksUsage::prepareProtocols(),
@@ -125,30 +126,10 @@ class ApiQueryExternalLinks extends ApiQueryBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'limit' => 'How many links to return',
- 'offset' => 'When more results are available, use this to continue',
- 'protocol' => array(
- "Protocol of the URL. If empty and {$p}query set, the protocol is http.",
- "Leave both this and {$p}query empty to list all external links"
- ),
- 'query' => 'Search string without protocol. Useful for checking ' .
- 'whether a certain page contains a certain external url',
- 'expandurl' => 'Expand protocol-relative URLs with the canonical protocol',
- );
- }
-
- public function getDescription() {
- return 'Returns all external URLs (not interwikis) from the given page(s).';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=extlinks&titles=Main%20Page'
- => 'Get a list of external links on the [[Main Page]]',
+ 'action=query&prop=extlinks&titles=Main%20Page'
+ => 'apihelp-query+extlinks-example-simple',
);
}
diff --git a/includes/api/ApiQueryFileRepoInfo.php b/includes/api/ApiQueryFileRepoInfo.php
index d1600efe..9ad7e27e 100644
--- a/includes/api/ApiQueryFileRepoInfo.php
+++ b/includes/api/ApiQueryFileRepoInfo.php
@@ -55,7 +55,9 @@ class ApiQueryFileRepoInfo extends ApiQueryBase {
$repos[] = array_intersect_key( $repoGroup->getLocalRepo()->getInfo(), $props );
$result = $this->getResult();
- $result->setIndexedTagName( $repos, 'repo' );
+ ApiResult::setIndexedTagName( $repos, 'repo' );
+ ApiResult::setArrayTypeRecursive( $repos, 'assoc' );
+ ApiResult::setArrayType( $repos, 'array' );
$result->addValue( array( 'query' ), 'repos', $repos );
}
@@ -89,27 +91,10 @@ class ApiQueryFileRepoInfo extends ApiQueryBase {
) ) );
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'prop' => array(
- 'Which repository properties to get (there may be more available on some wikis):',
- ' apiurl - URL to the repository API - helpful for getting image info from the host.',
- ' name - The key of the repository - used in e.g. ' .
- '$wgForeignFileRepos and imageinfo return values.',
- ' displayname - The human-readable name of the repository wiki.',
- ' rooturl - Root URL for image paths.',
- ' local - Whether that repository is the local one or not.',
- ),
- );
- }
-
- public function getDescription() {
- return 'Return meta information about image repositories configured on the wiki.';
- }
-
- public function getExamples() {
- return array(
- 'api.php?action=query&meta=filerepoinfo&friprop=apiurl|name|displayname',
+ 'action=query&meta=filerepoinfo&friprop=apiurl|name|displayname'
+ => 'apihelp-query+filerepoinfo-example-simple',
);
}
}
diff --git a/includes/api/ApiQueryFilearchive.php b/includes/api/ApiQueryFilearchive.php
index f047d8d4..4d357a7f 100644
--- a/includes/api/ApiQueryFilearchive.php
+++ b/includes/api/ApiQueryFilearchive.php
@@ -193,7 +193,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
$pageCount = ArchivedFile::newFromRow( $row )->pageCount();
if ( $pageCount !== false ) {
- $vals['pagecount'] = $pageCount;
+ $file['pagecount'] = $pageCount;
}
$file['height'] = $row->fa_height;
@@ -218,17 +218,17 @@ class ApiQueryFilearchive extends ApiQueryBase {
}
if ( $row->fa_deleted & File::DELETED_FILE ) {
- $file['filehidden'] = '';
+ $file['filehidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_COMMENT ) {
- $file['commenthidden'] = '';
+ $file['commenthidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_USER ) {
- $file['userhidden'] = '';
+ $file['userhidden'] = true;
}
if ( $row->fa_deleted & File::DELETED_RESTRICTED ) {
// This file is deleted for normal admins
- $file['suppressed'] = '';
+ $file['suppressed'] = true;
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $file );
@@ -240,22 +240,14 @@ class ApiQueryFilearchive extends ApiQueryBase {
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'fa' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'fa' );
}
public function getAllowedParams() {
return array(
'from' => null,
- 'continue' => null,
'to' => null,
'prefix' => null,
- 'limit' => array(
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
'dir' => array(
ApiBase::PARAM_DFLT => 'ascending',
ApiBase::PARAM_TYPE => array(
@@ -283,48 +275,23 @@ class ApiQueryFilearchive extends ApiQueryBase {
'archivename',
),
),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'from' => 'The image title to start enumerating from',
- 'continue' => 'When more results are available, use this to continue',
- 'to' => 'The image title to stop enumerating at',
- 'prefix' => 'Search for all image titles that begin with this value',
- 'dir' => 'The direction in which to list',
- 'limit' => 'How many images to return in total',
- 'sha1' => "SHA1 hash of image. Overrides {$this->getModulePrefix()}sha1base36",
- 'sha1base36' => 'SHA1 hash of image in base 36 (used in MediaWiki)',
- 'prop' => array(
- 'What image information to get:',
- ' sha1 - Adds SHA-1 hash for the image',
- ' timestamp - Adds timestamp for the uploaded version',
- ' user - Adds user who uploaded the image version',
- ' size - Adds the size of the image in bytes and the height, ' .
- 'width and page count (if applicable)',
- ' dimensions - Alias for size',
- ' description - Adds description the image version',
- ' parseddescription - Parse the description on the version',
- ' mime - Adds MIME of the image',
- ' mediatype - Adds the media type of the image',
- ' metadata - Lists Exif metadata for the version of the image',
- ' bitdepth - Adds the bit depth of the version',
- ' archivename - Adds the file name of the archive version for non-latest versions'
+ 'limit' => array(
+ ApiBase::PARAM_DFLT => 10,
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
);
}
- public function getDescription() {
- return 'Enumerate all deleted files sequentially.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=filearchive' => array(
- 'Simple Use',
- 'Show a list of all deleted files',
- ),
+ 'action=query&list=filearchive'
+ => 'apihelp-query+filearchive-example-simple',
);
}
diff --git a/includes/api/ApiQueryIWBacklinks.php b/includes/api/ApiQueryIWBacklinks.php
index b5aa45bf..618387d2 100644
--- a/includes/api/ApiQueryIWBacklinks.php
+++ b/includes/api/ApiQueryIWBacklinks.php
@@ -132,7 +132,7 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
ApiQueryBase::addTitleInfo( $entry, $title );
if ( $row->page_is_redirect ) {
- $entry['redirect'] = '';
+ $entry['redirect'] = true;
}
if ( $iwprefix ) {
@@ -155,7 +155,7 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'iw' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'iw' );
} else {
$resultPageSet->populateFromTitles( $pages );
}
@@ -169,7 +169,9 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
return array(
'prefix' => null,
'title' => null,
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -195,33 +197,12 @@ class ApiQueryIWBacklinks extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'prefix' => 'Prefix for the interwiki',
- 'title' => "Interwiki link to search for. Must be used with {$this->getModulePrefix()}prefix",
- 'continue' => 'When more results are available, use this to continue',
- 'prop' => array(
- 'Which properties to get',
- ' iwprefix - Adds the prefix of the interwiki',
- ' iwtitle - Adds the title of the interwiki',
- ),
- 'limit' => 'How many total pages to return',
- 'dir' => 'The direction in which to list',
- );
- }
-
- public function getDescription() {
- return array( 'Find all pages that link to the given interwiki link.',
- 'Can be used to find all links with a prefix, or',
- 'all links to a title (with a given prefix).',
- 'Using neither parameter is effectively "All IW Links".',
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=iwbacklinks&iwbltitle=Test&iwblprefix=wikibooks',
- 'api.php?action=query&generator=iwbacklinks&giwbltitle=Test&giwblprefix=wikibooks&prop=info'
+ 'action=query&list=iwbacklinks&iwbltitle=Test&iwblprefix=wikibooks'
+ => 'apihelp-query+iwbacklinks-example-simple',
+ 'action=query&generator=iwbacklinks&giwbltitle=Test&giwblprefix=wikibooks&prop=info'
+ => 'apihelp-query+iwbacklinks-example-generator',
);
}
diff --git a/includes/api/ApiQueryIWLinks.php b/includes/api/ApiQueryIWLinks.php
index a185ee24..aca3f700 100644
--- a/includes/api/ApiQueryIWLinks.php
+++ b/includes/api/ApiQueryIWLinks.php
@@ -129,7 +129,7 @@ class ApiQueryIWLinks extends ApiQueryBase {
}
}
- ApiResult::setContent( $entry, $row->iwl_title );
+ ApiResult::setContentValue( $entry, 'title', $row->iwl_title );
$fit = $this->addPageSubItem( $row->iwl_from, $entry );
if ( !$fit ) {
$this->setContinueEnumParameter(
@@ -147,24 +147,12 @@ class ApiQueryIWLinks extends ApiQueryBase {
public function getAllowedParams() {
return array(
- 'url' => array(
- ApiBase::PARAM_DFLT => false,
- ApiBase::PARAM_DEPRECATED => true,
- ),
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => array(
'url',
)
),
- 'limit' => array(
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
- 'continue' => null,
'prefix' => null,
'title' => null,
'dir' => array(
@@ -174,32 +162,27 @@ class ApiQueryIWLinks extends ApiQueryBase {
'descending'
)
),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'prop' => array(
- 'Which additional properties to get for each interlanguage link',
- ' url - Adds the full URL',
+ 'limit' => array(
+ ApiBase::PARAM_DFLT => 10,
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
+ 'url' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_DEPRECATED => true,
),
- 'url' => "Whether to get the full URL (Cannot be used with {$this->getModulePrefix()}prop)",
- 'limit' => 'How many interwiki links to return',
- 'continue' => 'When more results are available, use this to continue',
- 'prefix' => 'Prefix for the interwiki',
- 'title' => "Interwiki link to search for. Must be used with {$this->getModulePrefix()}prefix",
- 'dir' => 'The direction in which to list',
);
}
- public function getDescription() {
- return 'Returns all interwiki links from the given page(s).';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=iwlinks&titles=Main%20Page'
- => 'Get interwiki links from the [[Main Page]]',
+ 'action=query&prop=iwlinks&titles=Main%20Page'
+ => 'apihelp-query+iwlinks-example-simple',
);
}
diff --git a/includes/api/ApiQueryImageInfo.php b/includes/api/ApiQueryImageInfo.php
index 945374b1..94b4bbdb 100644
--- a/includes/api/ApiQueryImageInfo.php
+++ b/includes/api/ApiQueryImageInfo.php
@@ -58,7 +58,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
'revdelUser' => $this->getUser(),
);
- $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
+ $pageIds = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
if ( !empty( $pageIds[NS_FILE] ) ) {
$titles = array_keys( $pageIds[NS_FILE] );
asort( $titles ); // Ensure the order is always the same
@@ -373,7 +373,9 @@ class ApiQueryImageInfo extends ApiQueryBase {
);
}
$version = $opts['version'];
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
// Timestamp is shown even if the file is revdelete'd in interface
// so do same here.
if ( isset( $prop['timestamp'] ) ) {
@@ -397,7 +399,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
if ( $user || $userid ) {
if ( $file->isDeleted( File::DELETED_USER ) ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( $canShowField( File::DELETED_USER ) ) {
@@ -408,7 +410,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
$vals['userid'] = $file->getUser( 'id' );
}
if ( !$file->getUser( 'id' ) ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
@@ -438,7 +440,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
if ( $pcomment || $comment ) {
if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( $canShowField( File::DELETED_COMMENT ) ) {
@@ -469,7 +471,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
}
if ( $file->isDeleted( File::DELETED_FILE ) ) {
- $vals['filehidden'] = '';
+ $vals['filehidden'] = true;
$anyHidden = true;
}
@@ -599,7 +601,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
$retval[] = $r;
}
}
- $result->setIndexedTagName( $retval, 'metadata' );
+ ApiResult::setIndexedTagName( $retval, 'metadata' );
return $retval;
}
@@ -632,7 +634,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_DFLT => 'timestamp|user',
- ApiBase::PARAM_TYPE => self::getPropertyNames()
+ ApiBase::PARAM_TYPE => self::getPropertyNames(),
+ ApiBase::PARAM_HELP_MSG_PER_VALUE => self::getPropertyMessages(),
),
'limit' => array(
ApiBase::PARAM_TYPE => 'limit',
@@ -649,7 +652,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
),
'urlwidth' => array(
ApiBase::PARAM_TYPE => 'integer',
- ApiBase::PARAM_DFLT => -1
+ ApiBase::PARAM_DFLT => -1,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+imageinfo-param-urlwidth',
+ ApiQueryImageInfo::TRANSFORM_LIMIT,
+ ),
),
'urlheight' => array(
ApiBase::PARAM_TYPE => 'integer',
@@ -675,7 +682,9 @@ class ApiQueryImageInfo extends ApiQueryBase {
ApiBase::PARAM_DFLT => '',
ApiBase::PARAM_TYPE => 'string',
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'localonly' => false,
);
}
@@ -684,16 +693,49 @@ class ApiQueryImageInfo extends ApiQueryBase {
* Returns all possible parameters to iiprop
*
* @param array $filter List of properties to filter out
- *
* @return array
*/
public static function getPropertyNames( $filter = array() ) {
- return array_diff( array_keys( self::getProperties() ), $filter );
+ return array_keys( self::getPropertyMessages( $filter ) );
+ }
+
+ /**
+ * Returns messages for all possible parameters to iiprop
+ *
+ * @param array $filter List of properties to filter out
+ * @return array
+ */
+ public static function getPropertyMessages( $filter = array() ) {
+ return array_diff_key(
+ array(
+ 'timestamp' => 'apihelp-query+imageinfo-paramvalue-prop-timestamp',
+ 'user' => 'apihelp-query+imageinfo-paramvalue-prop-user',
+ 'userid' => 'apihelp-query+imageinfo-paramvalue-prop-userid',
+ 'comment' => 'apihelp-query+imageinfo-paramvalue-prop-comment',
+ 'parsedcomment' => 'apihelp-query+imageinfo-paramvalue-prop-parsedcomment',
+ 'canonicaltitle' => 'apihelp-query+imageinfo-paramvalue-prop-canonicaltitle',
+ 'url' => 'apihelp-query+imageinfo-paramvalue-prop-url',
+ 'size' => 'apihelp-query+imageinfo-paramvalue-prop-size',
+ 'dimensions' => 'apihelp-query+imageinfo-paramvalue-prop-dimensions',
+ 'sha1' => 'apihelp-query+imageinfo-paramvalue-prop-sha1',
+ 'mime' => 'apihelp-query+imageinfo-paramvalue-prop-mime',
+ 'thumbmime' => 'apihelp-query+imageinfo-paramvalue-prop-thumbmime',
+ 'mediatype' => 'apihelp-query+imageinfo-paramvalue-prop-mediatype',
+ 'metadata' => 'apihelp-query+imageinfo-paramvalue-prop-metadata',
+ 'commonmetadata' => 'apihelp-query+imageinfo-paramvalue-prop-commonmetadata',
+ 'extmetadata' => 'apihelp-query+imageinfo-paramvalue-prop-extmetadata',
+ 'archivename' => 'apihelp-query+imageinfo-paramvalue-prop-archivename',
+ 'bitdepth' => 'apihelp-query+imageinfo-paramvalue-prop-bitdepth',
+ 'uploadwarning' => 'apihelp-query+imageinfo-paramvalue-prop-uploadwarning',
+ ),
+ array_flip( $filter )
+ );
}
/**
* Returns array key value pairs of properties and their descriptions
*
+ * @deprecated since 1.25
* @param string $modulePrefix
* @return array
*/
@@ -730,6 +772,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
/**
* Returns the descriptions for the properties provided by getPropertyNames()
*
+ * @deprecated since 1.25
* @param array $filter List of properties to filter out
* @param string $modulePrefix
* @return array
@@ -741,55 +784,13 @@ class ApiQueryImageInfo extends ApiQueryBase {
);
}
- /**
- * Return the API documentation for the parameters.
- * @return array Parameter documentation.
- */
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'prop' => self::getPropertyDescriptions( array(), $p ),
- 'urlwidth' => array(
- "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
- 'For performance reasons if this option is used, ' .
- 'no more than ' . self::TRANSFORM_LIMIT . ' scaled images will be returned.'
- ),
- 'urlheight' => "Similar to {$p}urlwidth.",
- 'urlparam' => array(
- "A handler specific parameter string. For example, pdf's ",
- "might use 'page15-100px'."
- ),
- 'limit' => 'How many image revisions to return per image',
- 'start' => 'Timestamp to start listing from',
- 'end' => 'Timestamp to stop listing at',
- 'metadataversion'
- => array( "Version of metadata to use. if 'latest' is specified, use latest version.",
- "Defaults to '1' for backwards compatibility" ),
- 'extmetadatalanguage' => array(
- 'What language to fetch extmetadata in. This affects both which',
- 'translation to fetch, if multiple are available, as well as how things',
- 'like numbers and various values are formatted.'
- ),
- 'extmetadatamultilang'
- =>'If translations for extmetadata property are available, fetch all of them.',
- 'extmetadatafilter'
- => "If specified and non-empty, only these keys will be returned for {$p}prop=extmetadata",
- 'continue' => 'If the query response includes a continue value, ' .
- 'use it here to get another page of results',
- 'localonly' => 'Look only for files in the local repository',
- );
- }
-
- public function getDescription() {
- return 'Returns image information and upload history.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo',
- 'api.php?action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&' .
- 'iiend=20071231235959&iiprop=timestamp|user|url',
+ 'action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo'
+ => 'apihelp-query+imageinfo-example-simple',
+ 'action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&' .
+ 'iiend=2007-12-31T23:59:59Z&iiprop=timestamp|user|url'
+ => 'apihelp-query+imageinfo-example-dated',
);
}
diff --git a/includes/api/ApiQueryImages.php b/includes/api/ApiQueryImages.php
index 9bc3abed..029d945d 100644
--- a/includes/api/ApiQueryImages.php
+++ b/includes/api/ApiQueryImages.php
@@ -146,7 +146,9 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'images' => array(
ApiBase::PARAM_ISMULTI => true,
),
@@ -160,26 +162,12 @@ class ApiQueryImages extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'limit' => 'How many images to return',
- 'continue' => 'When more results are available, use this to continue',
- 'images' => 'Only list these images. Useful for checking whether a ' .
- 'certain page has a certain Image.',
- 'dir' => 'The direction in which to list',
- );
- }
-
- public function getDescription() {
- return 'Returns all images contained on the given page(s).';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=images&titles=Main%20Page'
- => 'Get a list of images used in the [[Main Page]]',
- 'api.php?action=query&generator=images&titles=Main%20Page&prop=info'
- => 'Get information about all images used in the [[Main Page]]',
+ 'action=query&prop=images&titles=Main%20Page'
+ => 'apihelp-query+images-example-simple',
+ 'action=query&generator=images&titles=Main%20Page&prop=info'
+ => 'apihelp-query+images-example-generator',
);
}
diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php
index d7037e3a..66178d4f 100644
--- a/includes/api/ApiQueryInfo.php
+++ b/includes/api/ApiQueryInfo.php
@@ -42,12 +42,14 @@ class ApiQueryInfo extends ApiQueryBase {
private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched,
$pageLatest, $pageLength;
- private $protections, $watched, $watchers, $notificationtimestamps,
+ private $protections, $restrictionTypes, $watched, $watchers, $notificationtimestamps,
$talkids, $subjectids, $displaytitles;
private $showZeroWatchers = false;
private $tokenFunctions;
+ private $countTestedActions = 0;
+
public function __construct( ApiQuery $query, $moduleName ) {
parent::__construct( $query, $moduleName, 'in' );
}
@@ -58,21 +60,21 @@ class ApiQueryInfo extends ApiQueryBase {
*/
public function requestExtraData( $pageSet ) {
$pageSet->requestField( 'page_restrictions' );
- // when resolving redirects, no page will have this field
- if ( !$pageSet->isResolvingRedirects() ) {
- $pageSet->requestField( 'page_is_redirect' );
- }
+ // If the pageset is resolving redirects we won't get page_is_redirect.
+ // But we can't know for sure until the pageset is executed (revids may
+ // turn it off), so request it unconditionally.
+ $pageSet->requestField( 'page_is_redirect' );
$pageSet->requestField( 'page_is_new' );
$config = $this->getConfig();
- if ( !$config->get( 'DisableCounters' ) ) {
- $pageSet->requestField( 'page_counter' );
- }
$pageSet->requestField( 'page_touched' );
$pageSet->requestField( 'page_latest' );
$pageSet->requestField( 'page_len' );
if ( $config->get( 'ContentHandlerUseDB' ) ) {
$pageSet->requestField( 'page_content_model' );
}
+ if ( $config->get( 'PageLanguageUseDB' ) ) {
+ $pageSet->requestField( 'page_lang' );
+ }
}
/**
@@ -88,8 +90,9 @@ class ApiQueryInfo extends ApiQueryBase {
return $this->tokenFunctions;
}
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
return array();
}
@@ -104,7 +107,7 @@ class ApiQueryInfo extends ApiQueryBase {
'import' => array( 'ApiQueryInfo', 'getImportToken' ),
'watch' => array( 'ApiQueryInfo', 'getWatchToken' ),
);
- wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
@@ -328,9 +331,6 @@ class ApiQueryInfo extends ApiQueryBase {
: array();
$this->pageIsNew = $pageSet->getCustomField( 'page_is_new' );
- if ( !$this->getConfig()->get( 'DisableCounters' ) ) {
- $this->pageCounter = $pageSet->getCustomField( 'page_counter' );
- }
$this->pageTouched = $pageSet->getCustomField( 'page_touched' );
$this->pageLatest = $pageSet->getCustomField( 'page_latest' );
$this->pageLength = $pageSet->getCustomField( 'page_len' );
@@ -360,7 +360,7 @@ class ApiQueryInfo extends ApiQueryBase {
/** @var $title Title */
foreach ( $this->everything as $pageid => $title ) {
$pageInfo = $this->extractPageInfo( $pageid, $title );
- $fit = $result->addValue( array(
+ $fit = $pageInfo !== null && $result->addValue( array(
'query',
'pages'
), $pageid, $pageInfo );
@@ -377,7 +377,7 @@ class ApiQueryInfo extends ApiQueryBase {
* Get a result array with information about a title
* @param int $pageid Page ID (negative for missing titles)
* @param Title $title
- * @return array
+ * @return array|null
*/
private function extractPageInfo( $pageid, $title ) {
$pageInfo = array();
@@ -392,16 +392,13 @@ class ApiQueryInfo extends ApiQueryBase {
if ( $titleExists ) {
$pageInfo['touched'] = wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] );
$pageInfo['lastrevid'] = intval( $this->pageLatest[$pageid] );
- $pageInfo['counter'] = $this->getConfig()->get( 'DisableCounters' )
- ? ''
- : intval( $this->pageCounter[$pageid] );
$pageInfo['length'] = intval( $this->pageLength[$pageid] );
if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) {
- $pageInfo['redirect'] = '';
+ $pageInfo['redirect'] = true;
}
if ( $this->pageIsNew[$pageid] ) {
- $pageInfo['new'] = '';
+ $pageInfo['new'] = true;
}
}
@@ -424,11 +421,18 @@ class ApiQueryInfo extends ApiQueryBase {
$pageInfo['protection'] =
$this->protections[$ns][$dbkey];
}
- $this->getResult()->setIndexedTagName( $pageInfo['protection'], 'pr' );
+ ApiResult::setIndexedTagName( $pageInfo['protection'], 'pr' );
+
+ $pageInfo['restrictiontypes'] = array();
+ if ( isset( $this->restrictionTypes[$ns][$dbkey] ) ) {
+ $pageInfo['restrictiontypes'] =
+ $this->restrictionTypes[$ns][$dbkey];
+ }
+ ApiResult::setIndexedTagName( $pageInfo['restrictiontypes'], 'rt' );
}
- if ( $this->fld_watched && isset( $this->watched[$ns][$dbkey] ) ) {
- $pageInfo['watched'] = '';
+ if ( $this->fld_watched ) {
+ $pageInfo['watched'] = isset( $this->watched[$ns][$dbkey] );
}
if ( $this->fld_watchers ) {
@@ -460,8 +464,8 @@ class ApiQueryInfo extends ApiQueryBase {
$pageInfo['editurl'] = wfExpandUrl( $title->getFullURL( 'action=edit' ), PROTO_CURRENT );
$pageInfo['canonicalurl'] = wfExpandUrl( $title->getFullURL(), PROTO_CANONICAL );
}
- if ( $this->fld_readable && $title->userCan( 'read', $this->getUser() ) ) {
- $pageInfo['readable'] = '';
+ if ( $this->fld_readable ) {
+ $pageInfo['readable'] = $title->userCan( 'read', $this->getUser() );
}
if ( $this->fld_preload ) {
@@ -469,7 +473,7 @@ class ApiQueryInfo extends ApiQueryBase {
$pageInfo['preload'] = '';
} else {
$text = null;
- wfRunHooks( 'EditFormPreloadText', array( &$text, &$title ) );
+ Hooks::run( 'EditFormPreloadText', array( &$text, &$title ) );
$pageInfo['preload'] = $text;
}
@@ -483,6 +487,20 @@ class ApiQueryInfo extends ApiQueryBase {
}
}
+ if ( $this->params['testactions'] ) {
+ $limit = $this->getMain()->canApiHighLimits() ? self::LIMIT_SML1 : self::LIMIT_SML2;
+ if ( $this->countTestedActions >= $limit ) {
+ return null; // force a continuation
+ }
+
+ $user = $this->getUser();
+ $pageInfo['actions'] = array();
+ foreach ( $this->params['testactions'] as $action ) {
+ $this->countTestedActions++;
+ $pageInfo['actions'][$action] = $title->userCan( $action, $user );
+ }
+ }
+
return $pageInfo;
}
@@ -512,7 +530,7 @@ class ApiQueryInfo extends ApiQueryBase {
'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 )
);
if ( $row->pr_cascade ) {
- $a['cascade'] = '';
+ $a['cascade'] = true;
}
$this->protections[$title->getNamespace()][$title->getDBkey()][] = $a;
}
@@ -574,7 +592,8 @@ class ApiQueryInfo extends ApiQueryBase {
}
}
- // Cascading protections
+ // Separate good and missing titles into files and other pages
+ // and populate $this->restrictionTypes
$images = $others = array();
foreach ( $this->everything as $title ) {
if ( $title->getNamespace() == NS_FILE ) {
@@ -582,6 +601,9 @@ class ApiQueryInfo extends ApiQueryBase {
} else {
$others[] = $title;
}
+ // Applicable protection types
+ $this->restrictionTypes[$title->getNamespace()][$title->getDBkey()] =
+ array_values( $title->getRestrictionTypes() );
}
if ( count( $others ) ) {
@@ -817,45 +839,31 @@ class ApiQueryInfo extends ApiQueryBase {
'displaytitle',
// If you add more properties here, please consider whether they
// need to be added to getCacheMode()
- ) ),
+ ),
+ ApiBase::PARAM_HELP_MSG_PER_VALUE => array(),
+ ),
+ 'testactions' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_ISMULTI => true,
+ ),
'token' => array(
ApiBase::PARAM_DEPRECATED => true,
ApiBase::PARAM_DFLT => null,
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() )
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'prop' => array(
- 'Which additional properties to get:',
- ' protection - List the protection level of each page',
- ' talkid - The page ID of the talk page for each non-talk page',
- ' watched - List the watched status of each page',
- ' watchers - The number of watchers, if allowed',
- ' notificationtimestamp - The watchlist notification timestamp of each page',
- ' subjectid - The page ID of the parent page for each talk page',
- ' url - Gives a full URL, an edit URL, and the canonical URL for each page',
- ' readable - Whether the user can read this page',
- ' preload - Gives the text returned by EditFormPreloadText',
- ' displaytitle - Gives the way the page title is actually displayed',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'token' => 'Request a token to perform a data-modifying action on a page',
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return 'Get basic page information such as namespace, title, last touched date, ...';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=info&titles=Main%20Page',
- 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
+ 'action=query&prop=info&titles=Main%20Page'
+ => 'apihelp-query+info-example-simple',
+ 'action=query&prop=info&inprop=protection&titles=Main%20Page'
+ => 'apihelp-query+info-example-protection',
);
}
diff --git a/includes/api/ApiQueryLangBacklinks.php b/includes/api/ApiQueryLangBacklinks.php
index 34842c63..7be18b2f 100644
--- a/includes/api/ApiQueryLangBacklinks.php
+++ b/includes/api/ApiQueryLangBacklinks.php
@@ -131,7 +131,7 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
ApiQueryBase::addTitleInfo( $entry, $title );
if ( $row->page_is_redirect ) {
- $entry['redirect'] = '';
+ $entry['redirect'] = true;
}
if ( $lllang ) {
@@ -154,7 +154,7 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'll' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'll' );
} else {
$resultPageSet->populateFromTitles( $pages );
}
@@ -168,7 +168,9 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
return array(
'lang' => null,
'title' => null,
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -194,34 +196,12 @@ class ApiQueryLangBacklinks extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'lang' => 'Language for the language link',
- 'title' => "Language link to search for. Must be used with {$this->getModulePrefix()}lang",
- 'continue' => 'When more results are available, use this to continue',
- 'prop' => array(
- 'Which properties to get',
- ' lllang - Adds the language code of the language link',
- ' lltitle - Adds the title of the language link',
- ),
- 'limit' => 'How many total pages to return',
- 'dir' => 'The direction in which to list',
- );
- }
-
- public function getDescription() {
- return array( 'Find all pages that link to the given language link.',
- 'Can be used to find all links with a language code, or',
- 'all links to a title (with a given language).',
- 'Using neither parameter is effectively "All Language Links".',
- 'Note that this may not consider language links added by extensions.',
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=langbacklinks&lbltitle=Test&lbllang=fr',
- 'api.php?action=query&generator=langbacklinks&glbltitle=Test&glbllang=fr&prop=info'
+ 'action=query&list=langbacklinks&lbltitle=Test&lbllang=fr'
+ => 'apihelp-query+langbacklinks-example-simple',
+ 'action=query&generator=langbacklinks&glbltitle=Test&glbllang=fr&prop=info'
+ => 'apihelp-query+langbacklinks-example-generator',
);
}
diff --git a/includes/api/ApiQueryLangLinks.php b/includes/api/ApiQueryLangLinks.php
index da05f273..5919ee97 100644
--- a/includes/api/ApiQueryLangLinks.php
+++ b/includes/api/ApiQueryLangLinks.php
@@ -124,7 +124,7 @@ class ApiQueryLangLinks extends ApiQueryBase {
if ( isset( $prop['autonym'] ) ) {
$entry['autonym'] = Language::fetchLanguageName( $row->ll_lang );
}
- ApiResult::setContent( $entry, $row->ll_title );
+ ApiResult::setContentValue( $entry, 'title', $row->ll_title );
$fit = $this->addPageSubItem( $row->ll_from, $entry );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "{$row->ll_from}|{$row->ll_lang}" );
@@ -140,18 +140,6 @@ class ApiQueryLangLinks extends ApiQueryBase {
public function getAllowedParams() {
global $wgContLang;
return array(
- 'limit' => array(
- ApiBase::PARAM_DFLT => 10,
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
- 'continue' => null,
- 'url' => array(
- ApiBase::PARAM_DFLT => false,
- ApiBase::PARAM_DEPRECATED => true,
- ),
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => array(
@@ -170,36 +158,27 @@ class ApiQueryLangLinks extends ApiQueryBase {
)
),
'inlanguagecode' => $wgContLang->getCode(),
- );
- }
-
- public function getParamDescription() {
- return array(
- 'limit' => 'How many langlinks to return',
- 'continue' => 'When more results are available, use this to continue',
- 'url' => "Whether to get the full URL (Cannot be used with {$this->getModulePrefix()}prop)",
- 'prop' => array(
- 'Which additional properties to get for each interlanguage link',
- ' url - Adds the full URL',
- ' langname - Adds the localised language name (best effort, use CLDR extension)',
- " Use {$this->getModulePrefix()}inlanguagecode to control the language",
- ' autonym - Adds the native language name',
+ 'limit' => array(
+ ApiBase::PARAM_DFLT => 10,
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
+ 'url' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_DEPRECATED => true,
),
- 'lang' => 'Language code',
- 'title' => "Link to search for. Must be used with {$this->getModulePrefix()}lang",
- 'dir' => 'The direction in which to list',
- 'inlanguagecode' => 'Language code for localised language names',
);
}
- public function getDescription() {
- return 'Returns all interlanguage links from the given page(s).';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=langlinks&titles=Main%20Page&redirects='
- => 'Get interlanguage links from the [[Main Page]]',
+ 'action=query&prop=langlinks&titles=Main%20Page&redirects='
+ => 'apihelp-query+langlinks-example-simple',
);
}
diff --git a/includes/api/ApiQueryLinks.php b/includes/api/ApiQueryLinks.php
index 71329c4d..3bd37144 100644
--- a/includes/api/ApiQueryLinks.php
+++ b/includes/api/ApiQueryLinks.php
@@ -34,26 +34,20 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
const LINKS = 'links';
const TEMPLATES = 'templates';
- private $table, $prefix, $description, $helpUrl;
+ private $table, $prefix, $helpUrl;
public function __construct( ApiQuery $query, $moduleName ) {
switch ( $moduleName ) {
case self::LINKS:
$this->table = 'pagelinks';
$this->prefix = 'pl';
- $this->description = 'link';
$this->titlesParam = 'titles';
- $this->titlesParamDescription = 'Only list links to these titles. Useful ' .
- 'for checking whether a certain page links to a certain title.';
$this->helpUrl = 'https://www.mediawiki.org/wiki/API:Properties#links_.2F_pl';
break;
case self::TEMPLATES:
$this->table = 'templatelinks';
$this->prefix = 'tl';
- $this->description = 'template';
$this->titlesParam = 'templates';
- $this->titlesParamDescription = 'Only list these templates. Useful ' .
- 'for checking whether a certain page uses a certain template.';
$this->helpUrl = 'https://www.mediawiki.org/wiki/API:Properties#templates_.2F_tl';
break;
default:
@@ -197,7 +191,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
$this->titlesParam => array(
ApiBase::PARAM_ISMULTI => true,
),
@@ -211,32 +207,17 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- $desc = $this->description;
-
- return array(
- 'namespace' => "Show {$desc}s in this namespace(s) only",
- 'limit' => "How many {$desc}s to return",
- 'continue' => 'When more results are available, use this to continue',
- $this->titlesParam => $this->titlesParamDescription,
- 'dir' => 'The direction in which to list',
- );
- }
-
- public function getDescription() {
- return "Returns all {$this->description}s from the given page(s).";
- }
-
- public function getExamples() {
- $desc = $this->description;
+ protected function getExamplesMessages() {
$name = $this->getModuleName();
+ $path = $this->getModulePath();
return array(
- "api.php?action=query&prop={$name}&titles=Main%20Page" => "Get {$desc}s from the [[Main Page]]",
- "api.php?action=query&generator={$name}&titles=Main%20Page&prop=info"
- => "Get information about the {$desc} pages in the [[Main Page]]",
- "api.php?action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10"
- => "Get {$desc}s from the Main Page in the User and Template namespaces",
+ "action=query&prop={$name}&titles=Main%20Page"
+ => "apihelp-{$path}-example-simple",
+ "action=query&generator={$name}&titles=Main%20Page&prop=info"
+ => "apihelp-{$path}-example-generator",
+ "action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10"
+ => "apihelp-{$path}-example-namespaces",
);
}
diff --git a/includes/api/ApiQueryLogEvents.php b/includes/api/ApiQueryLogEvents.php
index d9dbb5e6..7b2381f4 100644
--- a/includes/api/ApiQueryLogEvents.php
+++ b/includes/api/ApiQueryLogEvents.php
@@ -230,19 +230,17 @@ class ApiQueryLogEvents extends ApiQueryBase {
}
$vals = $this->extractRowInfo( $row );
- if ( !$vals ) {
- continue;
- }
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
break;
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'item' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'item' );
}
/**
+ * @deprecated since 1.25 Use LogFormatter::formatParametersForApi instead
* @param ApiResult $result
* @param array $vals
* @param string $params
@@ -255,100 +253,23 @@ class ApiQueryLogEvents extends ApiQueryBase {
public static function addLogParams( $result, &$vals, $params, $type,
$action, $ts, $legacy = false
) {
- switch ( $type ) {
- case 'move':
- if ( $legacy ) {
- $targetKey = 0;
- $noredirKey = 1;
- } else {
- $targetKey = '4::target';
- $noredirKey = '5::noredir';
- }
+ wfDeprecated( __METHOD__, '1.25' );
- if ( isset( $params[$targetKey] ) ) {
- $title = Title::newFromText( $params[$targetKey] );
- if ( $title ) {
- $vals2 = array();
- ApiQueryBase::addTitleInfo( $vals2, $title, 'new_' );
- $vals[$type] = $vals2;
- }
- }
- if ( isset( $params[$noredirKey] ) && $params[$noredirKey] ) {
- $vals[$type]['suppressedredirect'] = '';
- }
- $params = null;
- break;
- case 'patrol':
- if ( $legacy ) {
- $cur = 0;
- $prev = 1;
- $auto = 2;
- } else {
- $cur = '4::curid';
- $prev = '5::previd';
- $auto = '6::auto';
- }
- $vals2 = array();
- $vals2['cur'] = $params[$cur];
- $vals2['prev'] = $params[$prev];
- $vals2['auto'] = $params[$auto];
- $vals[$type] = $vals2;
- $params = null;
- break;
- case 'rights':
- $vals2 = array();
- if ( $legacy ) {
- list( $vals2['old'], $vals2['new'] ) = $params;
- } else {
- $vals2['new'] = implode( ', ', $params['5::newgroups'] );
- $vals2['old'] = implode( ', ', $params['4::oldgroups'] );
- }
- $vals[$type] = $vals2;
- $params = null;
- break;
- case 'block':
- if ( $action == 'unblock' ) {
- break;
- }
- $vals2 = array();
- list( $vals2['duration'], $vals2['flags'] ) = $params;
-
- // Indefinite blocks have no expiry time
- if ( SpecialBlock::parseExpiryInput( $params[0] ) !== wfGetDB( DB_SLAVE )->getInfinity() ) {
- $vals2['expiry'] = wfTimestamp( TS_ISO_8601,
- strtotime( $params[0], wfTimestamp( TS_UNIX, $ts ) ) );
- }
- $vals[$type] = $vals2;
- $params = null;
- break;
- case 'upload':
- if ( isset( $params['img_timestamp'] ) ) {
- $params['img_timestamp'] = wfTimestamp( TS_ISO_8601, $params['img_timestamp'] );
- }
- break;
- }
- if ( !is_null( $params ) ) {
- $logParams = array();
- // Keys like "4::paramname" can't be used for output so we change them to "paramname"
- foreach ( $params as $key => $value ) {
- if ( strpos( $key, ':' ) === false ) {
- $logParams[$key] = $value;
- continue;
- }
- $logParam = explode( ':', $key, 3 );
- $logParams[$logParam[2]] = $value;
- }
- $result->setIndexedTagName( $logParams, 'param' );
- $result->setIndexedTagName_recursive( $logParams, 'param' );
- $vals = array_merge( $vals, $logParams );
- }
+ $entry = new ManualLogEntry( $type, $action );
+ $entry->setParameters( $params );
+ $entry->setTimestamp( $ts );
+ $entry->setLegacy( $legacy );
+ $formatter = LogFormatter::newFromEntry( $entry );
+ $vals['params'] = $formatter->formatParametersForApi();
return $vals;
}
private function extractRowInfo( $row ) {
$logEntry = DatabaseLogEntry::newFromRow( $row );
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
$anyHidden = false;
$user = $this->getUser();
@@ -362,7 +283,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
if ( $this->fld_title || $this->fld_ids || $this->fld_details && $row->log_params !== '' ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_ACTION, $user ) ) {
@@ -373,16 +294,8 @@ class ApiQueryLogEvents extends ApiQueryBase {
$vals['pageid'] = intval( $row->page_id );
$vals['logpage'] = intval( $row->log_page );
}
- if ( $this->fld_details && $row->log_params !== '' ) {
- self::addLogParams(
- $this->getResult(),
- $vals,
- $logEntry->getParameters(),
- $logEntry->getType(),
- $logEntry->getSubtype(),
- $logEntry->getTimestamp(),
- $logEntry->isLegacy()
- );
+ if ( $this->fld_details ) {
+ $vals['params'] = LogFormatter::newFromEntry( $logEntry )->formatParametersForApi();
}
}
}
@@ -394,7 +307,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
if ( $this->fld_user || $this->fld_userid ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_USER, $user ) ) {
@@ -406,7 +319,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
}
if ( !$row->log_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
@@ -416,7 +329,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->log_comment ) ) {
if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCan( $row, LogPage::DELETED_COMMENT, $user ) ) {
@@ -433,7 +346,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
if ( $this->fld_tags ) {
if ( $row->ts_tags ) {
$tags = explode( ',', $row->ts_tags );
- $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ ApiResult::setIndexedTagName( $tags, 'tag' );
$vals['tags'] = $tags;
} else {
$vals['tags'] = array();
@@ -441,7 +354,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
}
if ( $anyHidden && LogEventsList::isDeleted( $row, LogPage::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
@@ -473,7 +386,7 @@ class ApiQueryLogEvents extends ApiQueryBase {
public function getAllowedParams( $flags = 0 ) {
$config = $this->getConfig();
- return array(
+ $ret = array(
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_DFLT => 'ids|title|type|user|timestamp|comment|details',
@@ -510,14 +423,15 @@ class ApiQueryLogEvents extends ApiQueryBase {
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
'user' => null,
'title' => null,
'namespace' => array(
ApiBase::PARAM_TYPE => 'namespace'
),
- 'prefix' => null,
+ 'prefix' => array(),
'tag' => null,
'limit' => array(
ApiBase::PARAM_DFLT => 10,
@@ -526,52 +440,22 @@ class ApiQueryLogEvents extends ApiQueryBase {
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'prop' => array(
- 'Which properties to get',
- ' ids - Adds the ID of the log event',
- ' title - Adds the title of the page for the log event',
- ' type - Adds the type of log event',
- ' user - Adds the user responsible for the log event',
- ' userid - Adds the user ID who was responsible for the log event',
- ' timestamp - Adds the timestamp for the event',
- ' comment - Adds the comment of the event',
- ' parsedcomment - Adds the parsed comment of the event',
- ' details - Lists additional details about the event',
- ' tags - Lists tags for the event',
- ),
- 'type' => 'Filter log entries to only this type',
- 'action' => array(
- "Filter log actions to only this action. Overrides {$p}type",
- "Wildcard actions like 'action/*' allows to specify any string for the asterisk"
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to end enumerating',
- 'dir' => $this->getDirectionDescription( $p ),
- 'user' => 'Filter entries to those made by the given user',
- 'title' => 'Filter entries to those related to a page',
- 'namespace' => 'Filter entries to those in the given namespace',
- 'prefix' => 'Filter entries that start with this prefix. Disabled in Miser Mode',
- 'limit' => 'How many total event entries to return',
- 'tag' => 'Only list event entries tagged with this tag',
- 'continue' => 'When more results are available, use this to continue',
);
- }
- public function getDescription() {
- return 'Get events from logs.';
+ if ( $config->get( 'MiserMode' ) ) {
+ $ret['prefix'][ApiBase::PARAM_HELP_MSG] = 'api-help-param-disabled-in-miser-mode';
+ }
+
+ return $ret;
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=logevents'
+ 'action=query&list=logevents'
+ => 'apihelp-query+logevents-example-simple',
);
}
diff --git a/includes/api/ApiQueryORM.php b/includes/api/ApiQueryORM.php
index 469b2972..dc10c91c 100644
--- a/includes/api/ApiQueryORM.php
+++ b/includes/api/ApiQueryORM.php
@@ -205,7 +205,7 @@ abstract class ApiQueryORM extends ApiQueryBase {
* @param array $serializedResults
*/
protected function setIndexedTagNames( array &$serializedResults ) {
- $this->getResult()->setIndexedTagName( $serializedResults, $this->getRowName() );
+ ApiResult::setIndexedTagName( $serializedResults, $this->getRowName() );
}
/**
@@ -233,15 +233,19 @@ abstract class ApiQueryORM extends ApiQueryBase {
ApiBase::PARAM_TYPE => $this->getTable()->getFieldNames(),
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_REQUIRED => true,
+ ApiBase::PARAM_HELP_MSG => 'api-orm-param-props',
),
'limit' => array(
ApiBase::PARAM_DFLT => 20,
ApiBase::PARAM_TYPE => 'limit',
ApiBase::PARAM_MIN => 1,
ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
+ ApiBase::PARAM_HELP_MSG => 'api-orm-param-limit',
+ ),
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'continue' => null,
);
return array_merge( $this->getTable()->getAPIParams(), $params );
@@ -249,6 +253,7 @@ abstract class ApiQueryORM extends ApiQueryBase {
/**
* @see ApiBase::getParamDescription()
+ * @deprecated since 1.25
* @return array
*/
public function getParamDescription() {
diff --git a/includes/api/ApiQueryPagePropNames.php b/includes/api/ApiQueryPagePropNames.php
index 8cd9c6cf..11a29ff9 100644
--- a/includes/api/ApiQueryPagePropNames.php
+++ b/includes/api/ApiQueryPagePropNames.php
@@ -78,12 +78,14 @@ class ApiQueryPagePropNames extends ApiQueryBase {
}
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'p' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'p' );
}
public function getAllowedParams() {
return array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_TYPE => 'limit',
ApiBase::PARAM_DFLT => 10,
@@ -94,20 +96,10 @@ class ApiQueryPagePropNames extends ApiQueryBase {
);
}
- public function getParamDescription() {
- return array(
- 'continue' => 'When more results are available, use this to continue',
- 'limit' => 'The maximum number of pages to return',
- );
- }
-
- public function getDescription() {
- return 'List all page prop names in use on the wiki.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=pagepropnames' => 'Get first 10 prop names',
+ 'action=query&list=pagepropnames'
+ => 'apihelp-query+pagepropnames-example-simple',
);
}
diff --git a/includes/api/ApiQueryPageProps.php b/includes/api/ApiQueryPageProps.php
index e370c39f..dd19bf23 100644
--- a/includes/api/ApiQueryPageProps.php
+++ b/includes/api/ApiQueryPageProps.php
@@ -110,6 +110,7 @@ class ApiQueryPageProps extends ApiQueryBase {
* @return bool True if it fits in the result
*/
private function addPageProps( $result, $page, $props ) {
+ ApiResult::setArrayType( $props, 'assoc' );
$fit = $result->addValue( array( 'query', 'pages', $page ), 'pageprops', $props );
if ( !$fit ) {
@@ -125,28 +126,19 @@ class ApiQueryPageProps extends ApiQueryBase {
public function getAllowedParams() {
return array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
),
);
}
- public function getParamDescription() {
- return array(
- 'continue' => 'When more results are available, use this to continue',
- 'prop' => 'Only list these props. Useful for checking whether a ' .
- 'certain page uses a certain page prop',
- );
- }
-
- public function getDescription() {
- return 'Get various properties defined in the page content.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=pageprops&titles=Category:Foo',
+ 'action=query&prop=pageprops&titles=Category:Foo'
+ => 'apihelp-query+pageprops-example-simple',
);
}
diff --git a/includes/api/ApiQueryPagesWithProp.php b/includes/api/ApiQueryPagesWithProp.php
index b6c85253..7bcaf247 100644
--- a/includes/api/ApiQueryPagesWithProp.php
+++ b/includes/api/ApiQueryPagesWithProp.php
@@ -99,7 +99,9 @@ class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
}
if ( $resultPageSet === null ) {
- $vals = array();
+ $vals = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
if ( $fld_ids ) {
$vals['pageid'] = (int)$row->page_id;
}
@@ -121,7 +123,7 @@ class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
}
if ( $resultPageSet === null ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'page' );
}
}
@@ -140,7 +142,9 @@ class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
'value',
)
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_TYPE => 'limit',
ApiBase::PARAM_DFLT => 10,
@@ -158,31 +162,12 @@ class ApiQueryPagesWithProp extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'propname' => 'Page prop for which to enumerate pages',
- 'prop' => array(
- 'What pieces of information to include',
- ' ids - Adds the page ID',
- ' title - Adds the title and namespace ID of the page',
- ' value - Adds the value of the page prop',
- ),
- 'dir' => 'In which direction to sort',
- 'continue' => 'When more results are available, use this to continue',
- 'limit' => 'The maximum number of pages to return',
- );
- }
-
- public function getDescription() {
- return 'List all pages using a given page prop.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=pageswithprop&pwppropname=displaytitle&pwpprop=ids|title|value'
- => 'Get first 10 pages using {{DISPLAYTITLE:}}',
- 'api.php?action=query&generator=pageswithprop&gpwppropname=notoc&prop=info'
- => 'Get page info about first 10 pages using __NOTOC__',
+ 'action=query&list=pageswithprop&pwppropname=displaytitle&pwpprop=ids|title|value'
+ => 'apihelp-query+pageswithprop-example-simple',
+ 'action=query&generator=pageswithprop&gpwppropname=notoc&prop=info'
+ => 'apihelp-query+pageswithprop-example-generator',
);
}
diff --git a/includes/api/ApiQueryPrefixSearch.php b/includes/api/ApiQueryPrefixSearch.php
index 4abd7f0e..8eb644fc 100644
--- a/includes/api/ApiQueryPrefixSearch.php
+++ b/includes/api/ApiQueryPrefixSearch.php
@@ -43,15 +43,25 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
$search = $params['search'];
$limit = $params['limit'];
$namespaces = $params['namespace'];
+ $offset = $params['offset'];
$searcher = new TitlePrefixSearch;
- $titles = $searcher->searchWithVariants( $search, $limit, $namespaces );
+ $titles = $searcher->searchWithVariants( $search, $limit + 1, $namespaces, $offset );
if ( $resultPageSet ) {
+ if ( count( $titles ) > $limit ) {
+ $this->setContinueEnumParameter( 'offset', $offset + $params['limit'] );
+ array_pop( $titles );
+ }
$resultPageSet->populateFromTitles( $titles );
+ foreach ( $titles as $index => $title ) {
+ $resultPageSet->setGeneratorData( $title, array( 'index' => $index + $offset + 1 ) );
+ }
} else {
$result = $this->getResult();
+ $count = 0;
foreach ( $titles as $title ) {
- if ( !$limit-- ) {
+ if ( ++$count > $limit ) {
+ $this->setContinueEnumParameter( 'offset', $offset + $params['limit'] );
break;
}
$vals = array(
@@ -59,16 +69,17 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
'title' => $title->getPrefixedText(),
);
if ( $title->isSpecialPage() ) {
- $vals['special'] = '';
+ $vals['special'] = true;
} else {
$vals['pageid'] = intval( $title->getArticleId() );
}
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
if ( !$fit ) {
+ $this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
break;
}
}
- $result->setIndexedTagName_internal(
+ $result->addIndexedTagName(
array( 'query', $this->getModuleName() ), $this->getModulePrefix()
);
}
@@ -97,24 +108,17 @@ class ApiQueryPrefixSearch extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX => 100,
ApiBase::PARAM_MAX2 => 200,
),
+ 'offset' => array(
+ ApiBase::PARAM_DFLT => 0,
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
);
}
- public function getParamDescription() {
- return array(
- 'search' => 'Search string',
- 'limit' => 'Maximum amount of results to return',
- 'namespace' => 'Namespaces to search',
- );
- }
-
- public function getDescription() {
- return 'Perform a prefix search for page titles';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=prefixsearch&pssearch=meaning',
+ 'action=query&list=prefixsearch&pssearch=meaning'
+ => 'apihelp-query+prefixsearch-example-simple',
);
}
diff --git a/includes/api/ApiQueryProtectedTitles.php b/includes/api/ApiQueryProtectedTitles.php
index 4c88be7a..fb65e5e2 100644
--- a/includes/api/ApiQueryProtectedTitles.php
+++ b/includes/api/ApiQueryProtectedTitles.php
@@ -156,7 +156,7 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal(
+ $result->addIndexedTagName(
array( 'query', $this->getModuleName() ),
$this->getModulePrefix()
);
@@ -196,7 +196,8 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
'start' => array(
ApiBase::PARAM_TYPE => 'timestamp'
@@ -217,39 +218,18 @@ class ApiQueryProtectedTitles extends ApiQueryGeneratorBase {
'level'
)
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- return array(
- 'namespace' => 'Only list titles in these namespaces',
- 'start' => 'Start listing at this protection timestamp',
- 'end' => 'Stop listing at this protection timestamp',
- 'dir' => $this->getDirectionDescription( $this->getModulePrefix() ),
- 'limit' => 'How many total pages to return',
- 'prop' => array(
- 'Which properties to get',
- ' timestamp - Adds the timestamp of when protection was added',
- ' user - Adds the user that added the protection',
- ' userid - Adds the user id that added the protection',
- ' comment - Adds the comment for the protection',
- ' parsedcomment - Adds the parsed comment for the protection',
- ' expiry - Adds the timestamp of when the protection will be lifted',
- ' level - Adds the protection level',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'level' => 'Only list titles with these protection levels',
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return 'List all titles protected from creation.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=protectedtitles',
+ 'action=query&list=protectedtitles'
+ => 'apihelp-query+protectedtitles-example-simple',
+ 'action=query&generator=protectedtitles&gptnamespace=0&prop=linkshere'
+ => 'apihelp-query+protectedtitles-example-generator',
);
}
diff --git a/includes/api/ApiQueryQueryPage.php b/includes/api/ApiQueryQueryPage.php
index 5ddd9450..650ac8fe 100644
--- a/includes/api/ApiQueryQueryPage.php
+++ b/includes/api/ApiQueryQueryPage.php
@@ -68,9 +68,9 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
$r = array( 'name' => $params['page'] );
if ( $qp->isCached() ) {
if ( !$qp->isCacheable() ) {
- $r['disabled'] = '';
+ $r['disabled'] = true;
} else {
- $r['cached'] = '';
+ $r['cached'] = true;
$ts = $qp->getCachedTimestamp();
if ( $ts ) {
$r['cachedtimestamp'] = wfTimestamp( TS_ISO_8601, $ts );
@@ -119,7 +119,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
}
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal(
+ $result->addIndexedTagName(
array( 'query', $this->getModuleName(), 'results' ),
'page'
);
@@ -144,7 +144,10 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
ApiBase::PARAM_TYPE => array_keys( $this->qpMap ),
ApiBase::PARAM_REQUIRED => true
),
- 'offset' => 0,
+ 'offset' => array(
+ ApiBase::PARAM_DFLT => 0,
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -155,21 +158,10 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
- return array(
- 'page' => 'The name of the special page. Note, this is case sensitive',
- 'offset' => 'When more results are available, use this to continue',
- 'limit' => 'Number of results to return',
- );
- }
-
- public function getDescription() {
- return 'Get a list provided by a QueryPage-based special page.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=querypage&qppage=Ancientpages'
+ 'action=query&list=querypage&qppage=Ancientpages'
+ => 'apihelp-query+querypage-example-ancientpages',
);
}
diff --git a/includes/api/ApiQueryRandom.php b/includes/api/ApiQueryRandom.php
index 530557e6..a2c28443 100644
--- a/includes/api/ApiQueryRandom.php
+++ b/includes/api/ApiQueryRandom.php
@@ -131,7 +131,7 @@ class ApiQueryRandom extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'page' );
}
}
@@ -165,30 +165,15 @@ class ApiQueryRandom extends ApiQueryGeneratorBase {
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'namespace' => 'Return pages in these namespaces only',
- 'limit' => 'Limit how many random pages will be returned',
- 'redirect' => 'Load a random redirect instead of a random page'
+ 'action=query&list=random&rnnamespace=0&rnlimit=2'
+ => 'apihelp-query+random-example-simple',
+ 'action=query&generator=random&grnnamespace=0&grnlimit=2&prop=info'
+ => 'apihelp-query+random-example-generator',
);
}
- public function getDescription() {
- return array(
- 'Get a set of random pages.',
- 'NOTE: Pages are listed in a fixed sequence, only the starting point is random.',
- ' This means that if, for example, "Main Page" is the first random page on',
- ' your list, "List of fictional monkeys" will *always* be second, "List of',
- ' people on stamps of Vanuatu" third, etc.',
- 'NOTE: If the number of pages in the namespace is lower than rnlimit, you will',
- ' get fewer pages. You will not get the same page twice.'
- );
- }
-
- public function getExamples() {
- return 'api.php?action=query&list=random&rnnamespace=0&rnlimit=2';
- }
-
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/API:Random';
}
diff --git a/includes/api/ApiQueryRecentChanges.php b/includes/api/ApiQueryRecentChanges.php
index 6f0c5d34..f6a64785 100644
--- a/includes/api/ApiQueryRecentChanges.php
+++ b/includes/api/ApiQueryRecentChanges.php
@@ -56,15 +56,16 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
return $this->tokenFunctions;
}
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
return array();
}
$this->tokenFunctions = array(
'patrol' => array( 'ApiQueryRecentChanges', 'getPatrolToken' )
);
- wfRunHooks( 'APIQueryRecentChangesTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryRecentChangesTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
@@ -178,7 +179,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
if ( !is_null( $params['type'] ) ) {
try {
$this->addWhereFld( 'rc_type', RecentChange::parseToRCType( $params['type'] ) );
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
ApiBase::dieDebug( __METHOD__, $e->getMessage() );
}
}
@@ -383,9 +384,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
$vals = $this->extractRowInfo( $row );
/* Add that row's data to our final output. */
- if ( !$vals ) {
- continue;
- }
$fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
if ( !$fit ) {
$this->setContinueEnumParameter( 'continue', "$row->rc_timestamp|$row->rc_id" );
@@ -398,7 +396,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
if ( is_null( $resultPageSet ) ) {
/* Format the result */
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'rc' );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'rc' );
} else {
$resultPageSet->populateFromTitles( $titles );
}
@@ -427,7 +425,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
/* Create a new entry in the result for the title. */
if ( $this->fld_title || $this->fld_ids ) {
if ( $type === RC_LOG && ( $row->rc_deleted & LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( $type !== RC_LOG ||
@@ -451,7 +449,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
/* Add user data and 'anon' flag, if user is anonymous. */
if ( $this->fld_user || $this->fld_userid ) {
if ( $row->rc_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_USER, $user ) ) {
@@ -464,22 +462,16 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
}
if ( !$row->rc_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
/* Add flags, such as new, minor, bot. */
if ( $this->fld_flags ) {
- if ( $row->rc_bot ) {
- $vals['bot'] = '';
- }
- if ( $row->rc_type == RC_NEW ) {
- $vals['new'] = '';
- }
- if ( $row->rc_minor ) {
- $vals['minor'] = '';
- }
+ $vals['bot'] = (bool)$row->rc_bot;
+ $vals['new'] = $row->rc_type == RC_NEW;
+ $vals['minor'] = (bool)$row->rc_minor;
}
/* Add sizes of each revision. (Only available on 1.10+) */
@@ -496,7 +488,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
/* Add edit summary / log summary. */
if ( $this->fld_comment || $this->fld_parsedcomment ) {
if ( $row->rc_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
@@ -511,45 +503,32 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
}
if ( $this->fld_redirect ) {
- if ( $row->page_is_redirect ) {
- $vals['redirect'] = '';
- }
+ $vals['redirect'] = (bool)$row->page_is_redirect;
}
/* Add the patrolled flag */
- if ( $this->fld_patrolled && $row->rc_patrolled == 1 ) {
- $vals['patrolled'] = '';
- }
-
- if ( $this->fld_patrolled && ChangesList::isUnpatrolled( $row, $user ) ) {
- $vals['unpatrolled'] = '';
+ if ( $this->fld_patrolled ) {
+ $vals['patrolled'] = $row->rc_patrolled == 1;
+ $vals['unpatrolled'] = ChangesList::isUnpatrolled( $row, $user );
}
if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
if ( $row->rc_deleted & LogPage::DELETED_ACTION ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCanBitfield( $row->rc_deleted, LogPage::DELETED_ACTION, $user ) ) {
$vals['logid'] = intval( $row->rc_logid );
$vals['logtype'] = $row->rc_log_type;
$vals['logaction'] = $row->rc_log_action;
- $logEntry = DatabaseLogEntry::newFromRow( (array)$row );
- ApiQueryLogEvents::addLogParams(
- $this->getResult(),
- $vals,
- $logEntry->getParameters(),
- $logEntry->getType(),
- $logEntry->getSubtype(),
- $logEntry->getTimestamp()
- );
+ $vals['logparams'] = LogFormatter::newFromRow( $row )->formatParametersForApi();
}
}
if ( $this->fld_tags ) {
if ( $row->ts_tags ) {
$tags = explode( ',', $row->ts_tags );
- $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ ApiResult::setIndexedTagName( $tags, 'tag' );
$vals['tags'] = $tags;
} else {
$vals['tags'] = array();
@@ -558,7 +537,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
if ( $this->fld_sha1 && $row->rev_sha1 !== null ) {
if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
- $vals['sha1hidden'] = '';
+ $vals['sha1hidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rev_deleted, Revision::DELETED_TEXT, $user ) ) {
@@ -584,7 +563,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
}
if ( $anyHidden && ( $row->rc_deleted & Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
@@ -625,7 +604,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
'namespace' => array(
ApiBase::PARAM_ISMULTI => true,
@@ -687,6 +667,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
),
'type' => array(
+ ApiBase::PARAM_DFLT => 'edit|new|log',
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => array(
'edit',
@@ -696,57 +677,18 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
)
),
'toponly' => false,
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to end enumerating',
- 'dir' => $this->getDirectionDescription( $p ),
- 'namespace' => 'Filter log entries to only this namespace(s)',
- 'user' => 'Only list changes by this user',
- 'excludeuser' => 'Don\'t list changes by this user',
- 'prop' => array(
- 'Include additional pieces of information',
- ' user - Adds the user responsible for the edit and tags if they are an IP',
- ' userid - Adds the user id responsible for the edit',
- ' comment - Adds the comment for the edit',
- ' parsedcomment - Adds the parsed comment for the edit',
- ' flags - Adds flags for the edit',
- ' timestamp - Adds timestamp of the edit',
- ' title - Adds the page title of the edit',
- ' ids - Adds the page ID, recent changes ID and the new and old revision ID',
- ' sizes - Adds the new and old page length in bytes',
- ' redirect - Tags edit if page is a redirect',
- ' patrolled - Tags patrollable edits as being patrolled or unpatrolled',
- ' loginfo - Adds log information (logid, logtype, etc) to log entries',
- ' tags - Lists tags for the entry',
- ' sha1 - Adds the content checksum for entries associated with a revision',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'token' => 'Which tokens to obtain for each change',
- 'show' => array(
- 'Show only items that meet this criteria.',
- "For example, to see only minor edits done by logged-in users, set {$p}show=minor|!anon"
- ),
- 'type' => 'Which types of changes to show',
- 'limit' => 'How many total changes to return',
- 'tag' => 'Only list changes tagged with this tag',
- 'toponly' => 'Only list changes which are the latest revision',
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return 'Enumerate recent changes.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=recentchanges'
+ 'action=query&list=recentchanges'
+ => 'apihelp-query+recentchanges-example-simple',
+ 'action=query&generator=recentchanges&grcshow=!patrolled&prop=info'
+ => 'apihelp-query+recentchanges-example-generator',
);
}
diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php
index da4ec195..552ca3b4 100644
--- a/includes/api/ApiQueryRevisions.php
+++ b/includes/api/ApiQueryRevisions.php
@@ -32,20 +32,14 @@
*
* @ingroup API
*/
-class ApiQueryRevisions extends ApiQueryBase {
+class ApiQueryRevisions extends ApiQueryRevisionsBase {
- private $diffto, $difftotext, $expandTemplates, $generateXML, $section,
- $token, $parseContent, $contentFormat;
+ private $token = null;
public function __construct( ApiQuery $query, $moduleName ) {
parent::__construct( $query, $moduleName, 'rv' );
}
- private $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
- $fld_size = false, $fld_sha1 = false, $fld_comment = false,
- $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
- $fld_content = false, $fld_tags = false, $fld_contentmodel = false;
-
private $tokenFunctions;
/** @deprecated since 1.24 */
@@ -59,15 +53,16 @@ class ApiQueryRevisions extends ApiQueryBase {
return $this->tokenFunctions;
}
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
return array();
}
$this->tokenFunctions = array(
'rollback' => array( 'ApiQueryRevisions', 'getRollbackToken' )
);
- wfRunHooks( 'APIQueryRevisionsTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryRevisionsTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
@@ -89,7 +84,7 @@ class ApiQueryRevisions extends ApiQueryBase {
array( $title->getPrefixedText(), $rev->getUserText() ) );
}
- public function execute() {
+ protected function run( ApiPageSet $resultPageSet = null ) {
$params = $this->extractRequestParams( false );
// If any of those parameters are used, work in 'enumeration' mode.
@@ -107,6 +102,11 @@ class ApiQueryRevisions extends ApiQueryBase {
// Optimization -- nothing to do
if ( $revCount === 0 && $pageCount === 0 ) {
+ // Nothing to do
+ return;
+ }
+ if ( $revCount > 0 && count( $pageSet->getLiveRevisionIDs() ) === 0 ) {
+ // We're in revisions mode but all given revisions are deleted
return;
}
@@ -127,75 +127,32 @@ class ApiQueryRevisions extends ApiQueryBase {
);
}
- if ( !is_null( $params['difftotext'] ) ) {
- $this->difftotext = $params['difftotext'];
- } elseif ( !is_null( $params['diffto'] ) ) {
- if ( $params['diffto'] == 'cur' ) {
- $params['diffto'] = 0;
- }
- if ( ( !ctype_digit( $params['diffto'] ) || $params['diffto'] < 0 )
- && $params['diffto'] != 'prev' && $params['diffto'] != 'next'
- ) {
- $this->dieUsage(
- 'rvdiffto must be set to a non-negative number, "prev", "next" or "cur"',
- 'diffto'
- );
- }
- // Check whether the revision exists and is readable,
- // DifferenceEngine returns a rather ambiguous empty
- // string if that's not the case
- if ( $params['diffto'] != 0 ) {
- $difftoRev = Revision::newFromID( $params['diffto'] );
- if ( !$difftoRev ) {
- $this->dieUsageMsg( array( 'nosuchrevid', $params['diffto'] ) );
- }
- if ( !$difftoRev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
- $this->setWarning( "Couldn't diff to r{$difftoRev->getID()}: content is hidden" );
- $params['diffto'] = null;
- }
- }
- $this->diffto = $params['diffto'];
+ // In non-enum mode, rvlimit can't be directly used. Use the maximum
+ // allowed value.
+ if ( !$enumRevMode ) {
+ $this->setParsedLimit = false;
+ $params['limit'] = 'max';
}
$db = $this->getDB();
- $this->addTables( 'page' );
- $this->addFields( Revision::selectFields() );
- $this->addWhere( 'page_id = rev_page' );
-
- $prop = array_flip( $params['prop'] );
-
- // Optional fields
- $this->fld_ids = isset( $prop['ids'] );
- // $this->addFieldsIf('rev_text_id', $this->fld_ids); // should this be exposed?
- $this->fld_flags = isset( $prop['flags'] );
- $this->fld_timestamp = isset( $prop['timestamp'] );
- $this->fld_comment = isset( $prop['comment'] );
- $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
- $this->fld_size = isset( $prop['size'] );
- $this->fld_sha1 = isset( $prop['sha1'] );
- $this->fld_contentmodel = isset( $prop['contentmodel'] );
- $this->fld_userid = isset( $prop['userid'] );
- $this->fld_user = isset( $prop['user'] );
- $this->token = $params['token'];
-
- if ( !empty( $params['contentformat'] ) ) {
- $this->contentFormat = $params['contentformat'];
- }
-
- $userMax = ( $this->fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
- $botMax = ( $this->fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
- $limit = $params['limit'];
- if ( $limit == 'max' ) {
- $limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
- $this->getResult()->setParsedLimit( $this->getModuleName(), $limit );
- }
+ $this->addTables( array( 'revision', 'page' ) );
+ $this->addJoinConds(
+ array( 'page' => array( 'INNER JOIN', array( 'page_id = rev_page' ) ) )
+ );
- if ( !is_null( $this->token ) || $pageCount > 0 ) {
- $this->addFields( Revision::selectPageFields() );
+ if ( $resultPageSet === null ) {
+ $this->parseParameters( $params );
+ $this->token = $params['token'];
+ $this->addFields( Revision::selectFields() );
+ if ( $this->token !== null || $pageCount > 0 ) {
+ $this->addFields( Revision::selectPageFields() );
+ }
+ } else {
+ $this->limit = $this->getParameter( 'limit' ) ?: 10;
+ $this->addFields( array( 'rev_id', 'rev_page' ) );
}
- if ( isset( $prop['tags'] ) ) {
- $this->fld_tags = true;
+ if ( $this->fld_tags ) {
$this->addTables( 'tag_summary' );
$this->addJoinConds(
array( 'tag_summary' => array( 'LEFT JOIN', array( 'rev_id=ts_rev_id' ) ) )
@@ -211,7 +168,7 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->addWhereFld( 'ct_tag', $params['tag'] );
}
- if ( isset( $prop['content'] ) || !is_null( $this->diffto ) || !is_null( $this->difftotext ) ) {
+ if ( $this->fetchContent ) {
// For each page we will request, the user must have read rights for that page
$user = $this->getUser();
/** @var $title Title */
@@ -224,28 +181,11 @@ class ApiQueryRevisions extends ApiQueryBase {
}
$this->addTables( 'text' );
- $this->addWhere( 'rev_text_id=old_id' );
+ $this->addJoinConds(
+ array( 'text' => array( 'INNER JOIN', array( 'rev_text_id=old_id' ) ) )
+ );
$this->addFields( 'old_id' );
$this->addFields( Revision::selectTextFields() );
-
- $this->fld_content = isset( $prop['content'] );
-
- $this->expandTemplates = $params['expandtemplates'];
- $this->generateXML = $params['generatexml'];
- $this->parseContent = $params['parse'];
- if ( $this->parseContent ) {
- // Must manually initialize unset limit
- if ( is_null( $limit ) ) {
- $limit = 1;
- }
- // We are only going to parse 1 revision per request
- $this->validateLimit( 'limit', $limit, 1, 1, 1 );
- }
- if ( isset( $params['section'] ) ) {
- $this->section = $params['section'];
- } else {
- $this->section = false;
- }
}
// add user name, if needed
@@ -255,9 +195,6 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->addFields( Revision::selectUserFields() );
}
- // Bug 24166 - API error when using rvprop=tags
- $this->addTables( 'revision' );
-
if ( $enumRevMode ) {
// This is mostly to prevent parameter errors (and optimize SQL?)
if ( !is_null( $params['startid'] ) && !is_null( $params['start'] ) ) {
@@ -300,12 +237,6 @@ class ApiQueryRevisions extends ApiQueryBase {
$params['start'], $params['end'], false );
}
- // must manually initialize unset limit
- if ( is_null( $limit ) ) {
- $limit = 10;
- }
- $this->validateLimit( 'limit', $limit, 1, $userMax, $botMax );
-
// There is only one ID, use it
$ids = array_keys( $pageSet->getGoodTitles() );
$this->addWhereFld( 'rev_page', reset( $ids ) );
@@ -330,11 +261,7 @@ class ApiQueryRevisions extends ApiQueryBase {
}
}
} elseif ( $revCount > 0 ) {
- $max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
- $revs = $pageSet->getRevisionIDs();
- if ( self::truncateArray( $revs, $max ) ) {
- $this->setWarning( "Too many values supplied for parameter 'revids': the limit is $max" );
- }
+ $revs = $pageSet->getLiveRevisionIDs();
// Get all revision IDs
$this->addWhereFld( 'rev_id', array_keys( $revs ) );
@@ -343,19 +270,11 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->addWhere( 'rev_id >= ' . intval( $params['continue'] ) );
}
$this->addOption( 'ORDER BY', 'rev_id' );
-
- // assumption testing -- we should never get more then $revCount rows.
- $limit = $revCount;
} elseif ( $pageCount > 0 ) {
- $max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
$titles = $pageSet->getGoodTitles();
- if ( self::truncateArray( $titles, $max ) ) {
- $this->setWarning( "Too many values supplied for parameter 'titles': the limit is $max" );
- }
// When working in multi-page non-enumeration mode,
// limit to the latest revision only
- $this->addWhere( 'page_id=rev_page' );
$this->addWhere( 'page_latest=rev_id' );
// Get all page IDs
@@ -378,31 +297,20 @@ class ApiQueryRevisions extends ApiQueryBase {
'rev_page',
'rev_id'
) );
-
- // assumption testing -- we should never get more then $pageCount rows.
- $limit = $pageCount;
} else {
ApiBase::dieDebug( __METHOD__, 'param validation?' );
}
- $this->addOption( 'LIMIT', $limit + 1 );
+ $this->addOption( 'LIMIT', $this->limit + 1 );
$count = 0;
+ $generated = array();
$res = $this->select( __METHOD__ );
foreach ( $res as $row ) {
- if ( ++$count > $limit ) {
+ if ( ++$count > $this->limit ) {
// We've reached the one extra which shows that there are
// additional pages to be had. Stop here...
- if ( !$enumRevMode ) {
- ApiBase::dieDebug( __METHOD__, 'Got more rows then expected' ); // bug report
- }
- $this->setContinueEnumParameter( 'continue', intval( $row->rev_id ) );
- break;
- }
-
- $fit = $this->addPageSubItem( $row->rev_page, $this->extractRowInfo( $row ), 'rev' );
- if ( !$fit ) {
if ( $enumRevMode ) {
$this->setContinueEnumParameter( 'continue', intval( $row->rev_id ) );
} elseif ( $revCount > 0 ) {
@@ -413,434 +321,124 @@ class ApiQueryRevisions extends ApiQueryBase {
}
break;
}
- }
- }
-
- private function extractRowInfo( $row ) {
- $revision = new Revision( $row );
- $title = $revision->getTitle();
- $user = $this->getUser();
- $vals = array();
- $anyHidden = false;
-
- if ( $this->fld_ids ) {
- $vals['revid'] = intval( $revision->getId() );
- // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed?
- if ( !is_null( $revision->getParentId() ) ) {
- $vals['parentid'] = intval( $revision->getParentId() );
- }
- }
-
- if ( $this->fld_flags && $revision->isMinor() ) {
- $vals['minor'] = '';
- }
-
- if ( $this->fld_user || $this->fld_userid ) {
- if ( $revision->isDeleted( Revision::DELETED_USER ) ) {
- $vals['userhidden'] = '';
- $anyHidden = true;
- }
- if ( $revision->userCan( Revision::DELETED_USER, $user ) ) {
- if ( $this->fld_user ) {
- $vals['user'] = $revision->getRawUserText();
- }
- $userid = $revision->getRawUser();
- if ( !$userid ) {
- $vals['anon'] = '';
- }
-
- if ( $this->fld_userid ) {
- $vals['userid'] = $userid;
- }
- }
- }
-
- if ( $this->fld_timestamp ) {
- $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $revision->getTimestamp() );
- }
-
- if ( $this->fld_size ) {
- if ( !is_null( $revision->getSize() ) ) {
- $vals['size'] = intval( $revision->getSize() );
- } else {
- $vals['size'] = 0;
- }
- }
-
- if ( $this->fld_sha1 ) {
- if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
- $vals['sha1hidden'] = '';
- $anyHidden = true;
- }
- if ( $revision->userCan( Revision::DELETED_TEXT, $user ) ) {
- if ( $revision->getSha1() != '' ) {
- $vals['sha1'] = wfBaseConvert( $revision->getSha1(), 36, 16, 40 );
- } else {
- $vals['sha1'] = '';
- }
- }
- }
-
- if ( $this->fld_contentmodel ) {
- $vals['contentmodel'] = $revision->getContentModel();
- }
-
- if ( $this->fld_comment || $this->fld_parsedcomment ) {
- if ( $revision->isDeleted( Revision::DELETED_COMMENT ) ) {
- $vals['commenthidden'] = '';
- $anyHidden = true;
- }
- if ( $revision->userCan( Revision::DELETED_COMMENT, $user ) ) {
- $comment = $revision->getRawComment();
-
- if ( $this->fld_comment ) {
- $vals['comment'] = $comment;
- }
-
- if ( $this->fld_parsedcomment ) {
- $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
- }
- }
- }
- if ( $this->fld_tags ) {
- if ( $row->ts_tags ) {
- $tags = explode( ',', $row->ts_tags );
- $this->getResult()->setIndexedTagName( $tags, 'tag' );
- $vals['tags'] = $tags;
+ if ( $resultPageSet !== null ) {
+ $generated[] = $row->rev_id;
} else {
- $vals['tags'] = array();
- }
- }
-
- if ( !is_null( $this->token ) ) {
- $tokenFunctions = $this->getTokenFunctions();
- foreach ( $this->token as $t ) {
- $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision );
- if ( $val === false ) {
- $this->setWarning( "Action '$t' is not allowed for the current user" );
- } else {
- $vals[$t . 'token'] = $val;
- }
- }
- }
-
- $content = null;
- global $wgParser;
- if ( $this->fld_content || !is_null( $this->diffto ) || !is_null( $this->difftotext ) ) {
- $content = $revision->getContent( Revision::FOR_THIS_USER, $this->getUser() );
- // Expand templates after getting section content because
- // template-added sections don't count and Parser::preprocess()
- // will have less input
- if ( $content && $this->section !== false ) {
- $content = $content->getSection( $this->section, false );
- if ( !$content ) {
- $this->dieUsage(
- "There is no section {$this->section} in r" . $revision->getId(),
- 'nosuchsection'
- );
- }
- }
- if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
- $vals['texthidden'] = '';
- $anyHidden = true;
- } elseif ( !$content ) {
- $vals['textmissing'] = '';
- }
- }
- if ( $this->fld_content && $content ) {
- $text = null;
-
- if ( $this->generateXML ) {
- if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
- $t = $content->getNativeData(); # note: don't set $text
-
- $wgParser->startExternalParse(
- $title,
- ParserOptions::newFromContext( $this->getContext() ),
- OT_PREPROCESS
- );
- $dom = $wgParser->preprocessToDom( $t );
- if ( is_callable( array( $dom, 'saveXML' ) ) ) {
- $xml = $dom->saveXML();
- } else {
- $xml = $dom->__toString();
+ $revision = new Revision( $row );
+ $rev = $this->extractRevisionInfo( $revision, $row );
+
+ if ( $this->token !== null ) {
+ $title = $revision->getTitle();
+ $tokenFunctions = $this->getTokenFunctions();
+ foreach ( $this->token as $t ) {
+ $val = call_user_func( $tokenFunctions[$t], $title->getArticleID(), $title, $revision );
+ if ( $val === false ) {
+ $this->setWarning( "Action '$t' is not allowed for the current user" );
+ } else {
+ $rev[$t . 'token'] = $val;
+ }
}
- $vals['parsetree'] = $xml;
- } else {
- $this->setWarning( "Conversion to XML is supported for wikitext only, " .
- $title->getPrefixedDBkey() .
- " uses content model " . $content->getModel() );
- }
- }
-
- if ( $this->expandTemplates && !$this->parseContent ) {
- #XXX: implement template expansion for all content types in ContentHandler?
- if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
- $text = $content->getNativeData();
-
- $text = $wgParser->preprocess(
- $text,
- $title,
- ParserOptions::newFromContext( $this->getContext() )
- );
- } else {
- $this->setWarning( "Template expansion is supported for wikitext only, " .
- $title->getPrefixedDBkey() .
- " uses content model " . $content->getModel() );
-
- $text = false;
}
- }
- if ( $this->parseContent ) {
- $po = $content->getParserOutput(
- $title,
- $revision->getId(),
- ParserOptions::newFromContext( $this->getContext() )
- );
- $text = $po->getText();
- }
-
- if ( $text === null ) {
- $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat();
- $model = $content->getModel();
-
- if ( !$content->isSupportedFormat( $format ) ) {
- $name = $title->getPrefixedDBkey();
-
- $this->dieUsage( "The requested format {$this->contentFormat} is not supported " .
- "for content model $model used by $name", 'badformat' );
- }
-
- $text = $content->serialize( $format );
- // always include format and model.
- // Format is needed to deserialize, model is needed to interpret.
- $vals['contentformat'] = $format;
- $vals['contentmodel'] = $model;
- }
-
- if ( $text !== false ) {
- ApiResult::setContent( $vals, $text );
- }
- }
-
- if ( $content && ( !is_null( $this->diffto ) || !is_null( $this->difftotext ) ) ) {
- static $n = 0; // Number of uncached diffs we've had
-
- if ( $n < $this->getConfig()->get( 'APIMaxUncachedDiffs' ) ) {
- $vals['diff'] = array();
- $context = new DerivativeContext( $this->getContext() );
- $context->setTitle( $title );
- $handler = $revision->getContentHandler();
-
- if ( !is_null( $this->difftotext ) ) {
- $model = $title->getContentModel();
-
- if ( $this->contentFormat
- && !ContentHandler::getForModelID( $model )->isSupportedFormat( $this->contentFormat )
- ) {
-
- $name = $title->getPrefixedDBkey();
-
- $this->dieUsage( "The requested format {$this->contentFormat} is not supported for " .
- "content model $model used by $name", 'badformat' );
+ $fit = $this->addPageSubItem( $row->rev_page, $rev, 'rev' );
+ if ( !$fit ) {
+ if ( $enumRevMode ) {
+ $this->setContinueEnumParameter( 'continue', intval( $row->rev_id ) );
+ } elseif ( $revCount > 0 ) {
+ $this->setContinueEnumParameter( 'continue', intval( $row->rev_id ) );
+ } else {
+ $this->setContinueEnumParameter( 'continue', intval( $row->rev_page ) .
+ '|' . intval( $row->rev_id ) );
}
-
- $difftocontent = ContentHandler::makeContent(
- $this->difftotext,
- $title,
- $model,
- $this->contentFormat
- );
-
- $engine = $handler->createDifferenceEngine( $context );
- $engine->setContent( $content, $difftocontent );
- } else {
- $engine = $handler->createDifferenceEngine( $context, $revision->getID(), $this->diffto );
- $vals['diff']['from'] = $engine->getOldid();
- $vals['diff']['to'] = $engine->getNewid();
- }
- $difftext = $engine->getDiffBody();
- ApiResult::setContent( $vals['diff'], $difftext );
- if ( !$engine->wasCacheHit() ) {
- $n++;
+ break;
}
- } else {
- $vals['diff']['notcached'] = '';
}
}
- if ( $anyHidden && $revision->isDeleted( Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ if ( $resultPageSet !== null ) {
+ $resultPageSet->populateFromRevisionIDs( $generated );
}
-
- return $vals;
}
public function getCacheMode( $params ) {
if ( isset( $params['token'] ) ) {
return 'private';
}
- if ( $this->userCanSeeRevDel() ) {
- return 'private';
- }
- if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
- // formatComment() calls wfMessage() among other things
- return 'anon-public-user-private';
- }
-
- return 'public';
+ return parent::getCacheMode( $params );
}
public function getAllowedParams() {
- return array(
- 'prop' => array(
- ApiBase::PARAM_ISMULTI => true,
- ApiBase::PARAM_DFLT => 'ids|timestamp|flags|comment|user',
- ApiBase::PARAM_TYPE => array(
- 'ids',
- 'flags',
- 'timestamp',
- 'user',
- 'userid',
- 'size',
- 'sha1',
- 'contentmodel',
- 'comment',
- 'parsedcomment',
- 'content',
- 'tags'
- )
- ),
- 'limit' => array(
- ApiBase::PARAM_TYPE => 'limit',
- ApiBase::PARAM_MIN => 1,
- ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
- ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
- ),
+ $ret = parent::getAllowedParams() + array(
'startid' => array(
- ApiBase::PARAM_TYPE => 'integer'
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'endid' => array(
- ApiBase::PARAM_TYPE => 'integer'
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'start' => array(
- ApiBase::PARAM_TYPE => 'timestamp'
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'end' => array(
- ApiBase::PARAM_TYPE => 'timestamp'
+ ApiBase::PARAM_TYPE => 'timestamp',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'dir' => array(
ApiBase::PARAM_DFLT => 'older',
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'user' => array(
- ApiBase::PARAM_TYPE => 'user'
+ ApiBase::PARAM_TYPE => 'user',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'excludeuser' => array(
- ApiBase::PARAM_TYPE => 'user'
+ ApiBase::PARAM_TYPE => 'user',
+ ApiBase::PARAM_HELP_MSG_INFO => array( array( 'singlepageonly' ) ),
),
'tag' => null,
- 'expandtemplates' => false,
- 'generatexml' => false,
- 'parse' => false,
- 'section' => null,
'token' => array(
ApiBase::PARAM_DEPRECATED => true,
ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ),
ApiBase::PARAM_ISMULTI => true
),
- 'continue' => null,
- 'diffto' => null,
- 'difftotext' => null,
- 'contentformat' => array(
- ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
- ApiBase::PARAM_DFLT => null
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
);
- }
- public function getParamDescription() {
- $p = $this->getModulePrefix();
+ $ret['limit'][ApiBase::PARAM_HELP_MSG_INFO] = array( array( 'singlepageonly' ) );
- return array(
- 'prop' => array(
- 'Which properties to get for each revision:',
- ' ids - The ID of the revision',
- ' flags - Revision flags (minor)',
- ' timestamp - The timestamp of the revision',
- ' user - User that made the revision',
- ' userid - User id of revision creator',
- ' size - Length (bytes) of the revision',
- ' sha1 - SHA-1 (base 16) of the revision',
- ' contentmodel - Content model id',
- ' comment - Comment by the user for revision',
- ' parsedcomment - Parsed comment by the user for the revision',
- ' content - Text of the revision',
- ' tags - Tags for the revision',
- ),
- 'limit' => 'Limit how many revisions will be returned (enum)',
- 'startid' => 'From which revision id to start enumeration (enum)',
- 'endid' => 'Stop revision enumeration on this revid (enum)',
- 'start' => 'From which revision timestamp to start enumeration (enum)',
- 'end' => 'Enumerate up to this timestamp (enum)',
- 'dir' => $this->getDirectionDescription( $p, ' (enum)' ),
- 'user' => 'Only include revisions made by user (enum)',
- 'excludeuser' => 'Exclude revisions made by user (enum)',
- 'expandtemplates' => "Expand templates in revision content (requires {$p}prop=content)",
- 'generatexml' => "Generate XML parse tree for revision content (requires {$p}prop=content)",
- 'parse' => array( "Parse revision content (requires {$p}prop=content).",
- 'For performance reasons if this option is used, rvlimit is enforced to 1.' ),
- 'section' => 'Only retrieve the content of this section number',
- 'token' => 'Which tokens to obtain for each revision',
- 'continue' => 'When more results are available, use this to continue',
- 'diffto' => array( 'Revision ID to diff each revision to.',
- 'Use "prev", "next" and "cur" for the previous, next and current revision respectively' ),
- 'difftotext' => array(
- 'Text to diff each revision to. Only diffs a limited number of revisions.',
- "Overrides {$p}diffto. If {$p}section is set, only that section will be",
- 'diffed against this text',
- ),
- 'tag' => 'Only list revisions tagged with this tag',
- 'contentformat' => 'Serialization format used for difftotext and expected for output of content',
- );
- }
-
- public function getDescription() {
- return array(
- 'Get revision information.',
- 'May be used in several ways:',
- ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
- ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.',
- ' 3) Get data about a set of revisions by setting their IDs with revids parameter.',
- 'All parameters marked as (enum) may only be used with a single page (#2).'
- );
+ return $ret;
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'Get data with content for the last revision of titles "API" and "Main Page"',
- ' api.php?action=query&prop=revisions&titles=API|Main%20Page&' .
- 'rvprop=timestamp|user|comment|content',
- 'Get last 5 revisions of the "Main Page"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
- 'rvprop=timestamp|user|comment',
- 'Get first 5 revisions of the "Main Page"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
- 'rvprop=timestamp|user|comment&rvdir=newer',
- 'Get first 5 revisions of the "Main Page" made after 2006-05-01',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
- 'rvprop=timestamp|user|comment&rvdir=newer&rvstart=20060501000000',
- 'Get first 5 revisions of the "Main Page" that were not made made by anonymous user "127.0.0.1"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
- 'rvprop=timestamp|user|comment&rvexcludeuser=127.0.0.1',
- 'Get first 5 revisions of the "Main Page" that were made by the user "MediaWiki default"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
- 'rvprop=timestamp|user|comment&rvuser=MediaWiki%20default',
+ 'action=query&prop=revisions&titles=API|Main%20Page&' .
+ 'rvprop=timestamp|user|comment|content'
+ => 'apihelp-query+revisions-example-content',
+ 'action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
+ 'rvprop=timestamp|user|comment'
+ => 'apihelp-query+revisions-example-last5',
+ 'action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
+ 'rvprop=timestamp|user|comment&rvdir=newer'
+ => 'apihelp-query+revisions-example-first5',
+ 'action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
+ 'rvprop=timestamp|user|comment&rvdir=newer&rvstart=2006-05-01T00:00:00Z'
+ => 'apihelp-query+revisions-example-first5-after',
+ 'action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
+ 'rvprop=timestamp|user|comment&rvexcludeuser=127.0.0.1'
+ => 'apihelp-query+revisions-example-first5-not-localhost',
+ 'action=query&prop=revisions&titles=Main%20Page&rvlimit=5&' .
+ 'rvprop=timestamp|user|comment&rvuser=MediaWiki%20default'
+ => 'apihelp-query+revisions-example-first5-user',
);
}
diff --git a/includes/api/ApiQueryRevisionsBase.php b/includes/api/ApiQueryRevisionsBase.php
new file mode 100644
index 00000000..64f6120a
--- /dev/null
+++ b/includes/api/ApiQueryRevisionsBase.php
@@ -0,0 +1,477 @@
+<?php
+/**
+ *
+ *
+ * Created on Oct 3, 2014 as a split from ApiQueryRevisions
+ *
+ * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * A base class for functions common to producing a list of revisions.
+ *
+ * @ingroup API
+ */
+abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
+
+ protected $limit, $diffto, $difftotext, $expandTemplates, $generateXML, $section,
+ $parseContent, $fetchContent, $contentFormat, $setParsedLimit = true;
+
+ protected $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
+ $fld_size = false, $fld_sha1 = false, $fld_comment = false,
+ $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
+ $fld_content = false, $fld_tags = false, $fld_contentmodel = false;
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator( $resultPageSet ) {
+ $this->run( $resultPageSet );
+ }
+
+ /**
+ * @param ApiPageSet $resultPageSet
+ * @return void
+ */
+ abstract protected function run( ApiPageSet $resultPageSet = null );
+
+ /**
+ * Parse the parameters into the various instance fields.
+ *
+ * @param array $params
+ */
+ protected function parseParameters( $params ) {
+ if ( !is_null( $params['difftotext'] ) ) {
+ $this->difftotext = $params['difftotext'];
+ } elseif ( !is_null( $params['diffto'] ) ) {
+ if ( $params['diffto'] == 'cur' ) {
+ $params['diffto'] = 0;
+ }
+ if ( ( !ctype_digit( $params['diffto'] ) || $params['diffto'] < 0 )
+ && $params['diffto'] != 'prev' && $params['diffto'] != 'next'
+ ) {
+ $p = $this->getModulePrefix();
+ $this->dieUsage(
+ "{$p}diffto must be set to a non-negative number, \"prev\", \"next\" or \"cur\"",
+ 'diffto'
+ );
+ }
+ // Check whether the revision exists and is readable,
+ // DifferenceEngine returns a rather ambiguous empty
+ // string if that's not the case
+ if ( $params['diffto'] != 0 ) {
+ $difftoRev = Revision::newFromId( $params['diffto'] );
+ if ( !$difftoRev ) {
+ $this->dieUsageMsg( array( 'nosuchrevid', $params['diffto'] ) );
+ }
+ if ( !$difftoRev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
+ $this->setWarning( "Couldn't diff to r{$difftoRev->getID()}: content is hidden" );
+ $params['diffto'] = null;
+ }
+ }
+ $this->diffto = $params['diffto'];
+ }
+
+ $prop = array_flip( $params['prop'] );
+
+ $this->fld_ids = isset( $prop['ids'] );
+ $this->fld_flags = isset( $prop['flags'] );
+ $this->fld_timestamp = isset( $prop['timestamp'] );
+ $this->fld_comment = isset( $prop['comment'] );
+ $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
+ $this->fld_size = isset( $prop['size'] );
+ $this->fld_sha1 = isset( $prop['sha1'] );
+ $this->fld_content = isset( $prop['content'] );
+ $this->fld_contentmodel = isset( $prop['contentmodel'] );
+ $this->fld_userid = isset( $prop['userid'] );
+ $this->fld_user = isset( $prop['user'] );
+ $this->fld_tags = isset( $prop['tags'] );
+
+ if ( !empty( $params['contentformat'] ) ) {
+ $this->contentFormat = $params['contentformat'];
+ }
+
+ $this->limit = $params['limit'];
+
+ $this->fetchContent = $this->fld_content || !is_null( $this->diffto )
+ || !is_null( $this->difftotext );
+
+ $smallLimit = false;
+ if ( $this->fetchContent ) {
+ $smallLimit = true;
+ $this->expandTemplates = $params['expandtemplates'];
+ $this->generateXML = $params['generatexml'];
+ $this->parseContent = $params['parse'];
+ if ( $this->parseContent ) {
+ // Must manually initialize unset limit
+ if ( is_null( $this->limit ) ) {
+ $this->limit = 1;
+ }
+ }
+ if ( isset( $params['section'] ) ) {
+ $this->section = $params['section'];
+ } else {
+ $this->section = false;
+ }
+ }
+
+ $userMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
+ $botMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
+ if ( $this->limit == 'max' ) {
+ $this->limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
+ if ( $this->setParsedLimit ) {
+ $this->getResult()->addParsedLimit( $this->getModuleName(), $this->limit );
+ }
+ }
+
+ if ( is_null( $this->limit ) ) {
+ $this->limit = 10;
+ }
+ $this->validateLimit( 'limit', $this->limit, 1, $userMax, $botMax );
+ }
+
+ /**
+ * Extract information from the Revision
+ *
+ * @param Revision $revision
+ * @param object $row Should have a field 'ts_tags' if $this->fld_tags is set
+ * @return array
+ */
+ protected function extractRevisionInfo( Revision $revision, $row ) {
+ $title = $revision->getTitle();
+ $user = $this->getUser();
+ $vals = array();
+ $anyHidden = false;
+
+ if ( $this->fld_ids ) {
+ $vals['revid'] = intval( $revision->getId() );
+ if ( !is_null( $revision->getParentId() ) ) {
+ $vals['parentid'] = intval( $revision->getParentId() );
+ }
+ }
+
+ if ( $this->fld_flags ) {
+ $vals['minor'] = $revision->isMinor();
+ }
+
+ if ( $this->fld_user || $this->fld_userid ) {
+ if ( $revision->isDeleted( Revision::DELETED_USER ) ) {
+ $vals['userhidden'] = true;
+ $anyHidden = true;
+ }
+ if ( $revision->userCan( Revision::DELETED_USER, $user ) ) {
+ if ( $this->fld_user ) {
+ $vals['user'] = $revision->getUserText( Revision::RAW );
+ }
+ $userid = $revision->getUser( Revision::RAW );
+ if ( !$userid ) {
+ $vals['anon'] = true;
+ }
+
+ if ( $this->fld_userid ) {
+ $vals['userid'] = $userid;
+ }
+ }
+ }
+
+ if ( $this->fld_timestamp ) {
+ $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $revision->getTimestamp() );
+ }
+
+ if ( $this->fld_size ) {
+ if ( !is_null( $revision->getSize() ) ) {
+ $vals['size'] = intval( $revision->getSize() );
+ } else {
+ $vals['size'] = 0;
+ }
+ }
+
+ if ( $this->fld_sha1 ) {
+ if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
+ $vals['sha1hidden'] = true;
+ $anyHidden = true;
+ }
+ if ( $revision->userCan( Revision::DELETED_TEXT, $user ) ) {
+ if ( $revision->getSha1() != '' ) {
+ $vals['sha1'] = wfBaseConvert( $revision->getSha1(), 36, 16, 40 );
+ } else {
+ $vals['sha1'] = '';
+ }
+ }
+ }
+
+ if ( $this->fld_contentmodel ) {
+ $vals['contentmodel'] = $revision->getContentModel();
+ }
+
+ if ( $this->fld_comment || $this->fld_parsedcomment ) {
+ if ( $revision->isDeleted( Revision::DELETED_COMMENT ) ) {
+ $vals['commenthidden'] = true;
+ $anyHidden = true;
+ }
+ if ( $revision->userCan( Revision::DELETED_COMMENT, $user ) ) {
+ $comment = $revision->getComment( Revision::RAW );
+
+ if ( $this->fld_comment ) {
+ $vals['comment'] = $comment;
+ }
+
+ if ( $this->fld_parsedcomment ) {
+ $vals['parsedcomment'] = Linker::formatComment( $comment, $title );
+ }
+ }
+ }
+
+ if ( $this->fld_tags ) {
+ if ( $row->ts_tags ) {
+ $tags = explode( ',', $row->ts_tags );
+ ApiResult::setIndexedTagName( $tags, 'tag' );
+ $vals['tags'] = $tags;
+ } else {
+ $vals['tags'] = array();
+ }
+ }
+
+ $content = null;
+ global $wgParser;
+ if ( $this->fetchContent ) {
+ $content = $revision->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+ // Expand templates after getting section content because
+ // template-added sections don't count and Parser::preprocess()
+ // will have less input
+ if ( $content && $this->section !== false ) {
+ $content = $content->getSection( $this->section, false );
+ if ( !$content ) {
+ $this->dieUsage(
+ "There is no section {$this->section} in r" . $revision->getId(),
+ 'nosuchsection'
+ );
+ }
+ }
+ if ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
+ $vals['texthidden'] = true;
+ $anyHidden = true;
+ } elseif ( !$content ) {
+ $vals['textmissing'] = true;
+ }
+ }
+ if ( $this->fld_content && $content ) {
+ $text = null;
+
+ if ( $this->generateXML ) {
+ if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
+ $t = $content->getNativeData(); # note: don't set $text
+
+ $wgParser->startExternalParse(
+ $title,
+ ParserOptions::newFromContext( $this->getContext() ),
+ Parser::OT_PREPROCESS
+ );
+ $dom = $wgParser->preprocessToDom( $t );
+ if ( is_callable( array( $dom, 'saveXML' ) ) ) {
+ $xml = $dom->saveXML();
+ } else {
+ $xml = $dom->__toString();
+ }
+ $vals['parsetree'] = $xml;
+ } else {
+ $vals['badcontentformatforparsetree'] = true;
+ $this->setWarning( "Conversion to XML is supported for wikitext only, " .
+ $title->getPrefixedDBkey() .
+ " uses content model " . $content->getModel() );
+ }
+ }
+
+ if ( $this->expandTemplates && !$this->parseContent ) {
+ #XXX: implement template expansion for all content types in ContentHandler?
+ if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
+ $text = $content->getNativeData();
+
+ $text = $wgParser->preprocess(
+ $text,
+ $title,
+ ParserOptions::newFromContext( $this->getContext() )
+ );
+ } else {
+ $this->setWarning( "Template expansion is supported for wikitext only, " .
+ $title->getPrefixedDBkey() .
+ " uses content model " . $content->getModel() );
+ $vals['badcontentformat'] = true;
+ $text = false;
+ }
+ }
+ if ( $this->parseContent ) {
+ $po = $content->getParserOutput(
+ $title,
+ $revision->getId(),
+ ParserOptions::newFromContext( $this->getContext() )
+ );
+ $text = $po->getText();
+ }
+
+ if ( $text === null ) {
+ $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat();
+ $model = $content->getModel();
+
+ if ( !$content->isSupportedFormat( $format ) ) {
+ $name = $title->getPrefixedDBkey();
+ $this->setWarning( "The requested format {$this->contentFormat} is not " .
+ "supported for content model $model used by $name" );
+ $vals['badcontentformat'] = true;
+ $text = false;
+ } else {
+ $text = $content->serialize( $format );
+ // always include format and model.
+ // Format is needed to deserialize, model is needed to interpret.
+ $vals['contentformat'] = $format;
+ $vals['contentmodel'] = $model;
+ }
+ }
+
+ if ( $text !== false ) {
+ ApiResult::setContentValue( $vals, 'content', $text );
+ }
+ }
+
+ if ( $content && ( !is_null( $this->diffto ) || !is_null( $this->difftotext ) ) ) {
+ static $n = 0; // Number of uncached diffs we've had
+
+ if ( $n < $this->getConfig()->get( 'APIMaxUncachedDiffs' ) ) {
+ $vals['diff'] = array();
+ $context = new DerivativeContext( $this->getContext() );
+ $context->setTitle( $title );
+ $handler = $revision->getContentHandler();
+
+ if ( !is_null( $this->difftotext ) ) {
+ $model = $title->getContentModel();
+
+ if ( $this->contentFormat
+ && !ContentHandler::getForModelID( $model )->isSupportedFormat( $this->contentFormat )
+ ) {
+ $name = $title->getPrefixedDBkey();
+ $this->setWarning( "The requested format {$this->contentFormat} is not " .
+ "supported for content model $model used by $name" );
+ $vals['diff']['badcontentformat'] = true;
+ $engine = null;
+ } else {
+ $difftocontent = ContentHandler::makeContent(
+ $this->difftotext,
+ $title,
+ $model,
+ $this->contentFormat
+ );
+
+ $engine = $handler->createDifferenceEngine( $context );
+ $engine->setContent( $content, $difftocontent );
+ }
+ } else {
+ $engine = $handler->createDifferenceEngine( $context, $revision->getID(), $this->diffto );
+ $vals['diff']['from'] = $engine->getOldid();
+ $vals['diff']['to'] = $engine->getNewid();
+ }
+ if ( $engine ) {
+ $difftext = $engine->getDiffBody();
+ ApiResult::setContentValue( $vals['diff'], 'body', $difftext );
+ if ( !$engine->wasCacheHit() ) {
+ $n++;
+ }
+ }
+ } else {
+ $vals['diff']['notcached'] = true;
+ }
+ }
+
+ if ( $anyHidden && $revision->isDeleted( Revision::DELETED_RESTRICTED ) ) {
+ $vals['suppressed'] = true;
+ }
+
+ return $vals;
+ }
+
+ public function getCacheMode( $params ) {
+ if ( $this->userCanSeeRevDel() ) {
+ return 'private';
+ }
+
+ return 'public';
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'prop' => array(
+ ApiBase::PARAM_ISMULTI => true,
+ ApiBase::PARAM_DFLT => 'ids|timestamp|flags|comment|user',
+ ApiBase::PARAM_TYPE => array(
+ 'ids',
+ 'flags',
+ 'timestamp',
+ 'user',
+ 'userid',
+ 'size',
+ 'sha1',
+ 'contentmodel',
+ 'comment',
+ 'parsedcomment',
+ 'content',
+ 'tags'
+ ),
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-prop',
+ ),
+ 'limit' => array(
+ ApiBase::PARAM_TYPE => 'limit',
+ ApiBase::PARAM_MIN => 1,
+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-limit',
+ ),
+ 'expandtemplates' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-expandtemplates',
+ ),
+ 'generatexml' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-generatexml',
+ ),
+ 'parse' => array(
+ ApiBase::PARAM_DFLT => false,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-parse',
+ ),
+ 'section' => array(
+ ApiBase::PARAM_DFLT => null,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-section',
+ ),
+ 'diffto' => array(
+ ApiBase::PARAM_DFLT => null,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-diffto',
+ ),
+ 'difftotext' => array(
+ ApiBase::PARAM_DFLT => null,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-difftotext',
+ ),
+ 'contentformat' => array(
+ ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
+ ApiBase::PARAM_DFLT => null,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-contentformat',
+ ),
+ );
+ }
+
+}
diff --git a/includes/api/ApiQuerySearch.php b/includes/api/ApiQuerySearch.php
index b7dcd0ed..e29ef8d2 100644
--- a/includes/api/ApiQuerySearch.php
+++ b/includes/api/ApiQuerySearch.php
@@ -116,19 +116,21 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
$this->dieUsage( $matches->getWikiText(), 'search-error' );
}
- $apiResult = $this->getResult();
- // Add search meta data to result
- if ( isset( $searchInfo['totalhits'] ) ) {
- $totalhits = $matches->getTotalHits();
- if ( $totalhits !== null ) {
+ if ( $resultPageSet === null ) {
+ $apiResult = $this->getResult();
+ // Add search meta data to result
+ if ( isset( $searchInfo['totalhits'] ) ) {
+ $totalhits = $matches->getTotalHits();
+ if ( $totalhits !== null ) {
+ $apiResult->addValue( array( 'query', 'searchinfo' ),
+ 'totalhits', $totalhits );
+ }
+ }
+ if ( isset( $searchInfo['suggestion'] ) && $matches->hasSuggestion() ) {
$apiResult->addValue( array( 'query', 'searchinfo' ),
- 'totalhits', $totalhits );
+ 'suggestion', $matches->getSuggestionQuery() );
}
}
- if ( isset( $searchInfo['suggestion'] ) && $matches->hasSuggestion() ) {
- $apiResult->addValue( array( 'query', 'searchinfo' ),
- 'suggestion', $matches->getSuggestionQuery() );
- }
// Add the search results to the result
$terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
@@ -151,7 +153,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
}
$title = $result->getTitle();
- if ( is_null( $resultPageSet ) ) {
+ if ( $resultPageSet === null ) {
$vals = array();
ApiQueryBase::addTitleInfo( $vals, $title );
@@ -168,14 +170,14 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
$vals['timestamp'] = wfTimestamp( TS_ISO_8601, $result->getTimestamp() );
}
if ( isset( $prop['titlesnippet'] ) ) {
- $vals['titlesnippet'] = $result->getTitleSnippet( $terms );
+ $vals['titlesnippet'] = $result->getTitleSnippet();
}
if ( !is_null( $result->getRedirectTitle() ) ) {
if ( isset( $prop['redirecttitle'] ) ) {
- $vals['redirecttitle'] = $result->getRedirectTitle();
+ $vals['redirecttitle'] = $result->getRedirectTitle()->getPrefixedText();
}
if ( isset( $prop['redirectsnippet'] ) ) {
- $vals['redirectsnippet'] = $result->getRedirectSnippet( $terms );
+ $vals['redirectsnippet'] = $result->getRedirectSnippet();
}
}
if ( !is_null( $result->getSectionTitle() ) ) {
@@ -202,56 +204,68 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
}
$hasInterwikiResults = false;
+ $totalhits = null;
if ( $interwiki && $resultPageSet === null && $matches->hasInterwikiResults() ) {
- $matches = $matches->getInterwikiResults();
- $hasInterwikiResults = true;
+ foreach ( $matches->getInterwikiResults() as $matches ) {
+ $matches = $matches->getInterwikiResults();
+ $hasInterwikiResults = true;
- // Include number of results if requested
- if ( isset( $searchInfo['totalhits'] ) ) {
- $totalhits = $matches->getTotalHits();
- if ( $totalhits !== null ) {
- $apiResult->addValue( array( 'query', 'interwikisearchinfo' ),
- 'totalhits', $totalhits );
+ // Include number of results if requested
+ if ( $resultPageSet === null && isset( $searchInfo['totalhits'] ) ) {
+ $totalhits += $matches->getTotalHits();
}
- }
- $result = $matches->next();
- while ( $result ) {
- $title = $result->getTitle();
- $vals = array(
- 'namespace' => $result->getInterwikiNamespaceText(),
- 'title' => $title->getText(),
- 'url' => $title->getFullUrl(),
- );
-
- // Add item to results and see whether it fits
- $fit = $apiResult->addValue(
- array( 'query', 'interwiki' . $this->getModuleName(), $result->getInterwikiPrefix() ),
- null,
- $vals
- );
+ $result = $matches->next();
+ while ( $result ) {
+ $title = $result->getTitle();
+
+ if ( $resultPageSet === null ) {
+ $vals = array(
+ 'namespace' => $result->getInterwikiNamespaceText(),
+ 'title' => $title->getText(),
+ 'url' => $title->getFullUrl(),
+ );
+
+ // Add item to results and see whether it fits
+ $fit = $apiResult->addValue(
+ array( 'query', 'interwiki' . $this->getModuleName(), $result->getInterwikiPrefix() ),
+ null,
+ $vals
+ );
+
+ if ( !$fit ) {
+ // We hit the limit. We can't really provide any meaningful
+ // pagination info so just bail out
+ break;
+ }
+ } else {
+ $titles[] = $title;
+ }
- if ( !$fit ) {
- // We hit the limit. We can't really provide any meaningful
- // pagination info so just bail out
- break;
+ $result = $matches->next();
}
-
- $result = $matches->next();
+ }
+ if ( $totalhits !== null ) {
+ $apiResult->addValue( array( 'query', 'interwikisearchinfo' ),
+ 'totalhits', $totalhits );
}
}
- if ( is_null( $resultPageSet ) ) {
- $apiResult->setIndexedTagName_internal( array(
+ if ( $resultPageSet === null ) {
+ $apiResult->addIndexedTagName( array(
'query', $this->getModuleName()
), 'p' );
if ( $hasInterwikiResults ) {
- $apiResult->setIndexedTagName_internal( array(
+ $apiResult->addIndexedTagName( array(
'query', 'interwiki' . $this->getModuleName()
), 'p' );
}
} else {
$resultPageSet->populateFromTitles( $titles );
+ $offset = $params['offset'] + 1;
+ foreach ( $titles as $index => $title ) {
+ $resultPageSet->setGeneratorData( $title, array( 'index' => $index + $offset ) );
+ }
}
}
@@ -303,7 +317,10 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
),
ApiBase::PARAM_ISMULTI => true,
),
- 'offset' => 0,
+ 'offset' => array(
+ ApiBase::PARAM_DFLT => 0,
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -328,47 +345,14 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
return $params;
}
- public function getParamDescription() {
- $descriptions = array(
- 'search' => 'Search for all page titles (or content) that has this value',
- 'namespace' => 'The namespace(s) to enumerate',
- 'what' => 'Search inside the text or titles',
- 'info' => 'What metadata to return',
- 'prop' => array(
- 'What properties to return',
- ' size - Adds the size of the page in bytes',
- ' wordcount - Adds the word count of the page',
- ' timestamp - Adds the timestamp of when the page was last edited',
- ' score - DEPRECATED and IGNORED',
- ' snippet - Adds a parsed snippet of the page',
- ' titlesnippet - Adds a parsed snippet of the page title',
- ' redirectsnippet - Adds a parsed snippet of the redirect title',
- ' redirecttitle - Adds the title of the matching redirect',
- ' sectionsnippet - Adds a parsed snippet of the matching section title',
- ' sectiontitle - Adds the title of the matching section',
- ' hasrelated - DEPRECATED and IGNORED',
- ),
- 'offset' => 'Use this value to continue paging (return by query)',
- 'limit' => 'How many total pages to return',
- 'interwiki' => 'Include interwiki results in the search, if available'
- );
-
- if ( count( SearchEngine::getSearchTypes() ) > 1 ) {
- $descriptions['backend'] = 'Which search backend to use, if not the default';
- }
-
- return $descriptions;
- }
-
- public function getDescription() {
- return 'Perform a full text search.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=search&srsearch=meaning',
- 'api.php?action=query&list=search&srwhat=text&srsearch=meaning',
- 'api.php?action=query&generator=search&gsrsearch=meaning&prop=info',
+ 'action=query&list=search&srsearch=meaning'
+ => 'apihelp-query+search-example-simple',
+ 'action=query&list=search&srwhat=text&srsearch=meaning'
+ => 'apihelp-query+search-example-text',
+ 'action=query&generator=search&gsrsearch=meaning&prop=info'
+ => 'apihelp-query+search-example-generator',
);
}
diff --git a/includes/api/ApiQuerySiteinfo.php b/includes/api/ApiQuerySiteinfo.php
index 311438fd..b81e993b 100644
--- a/includes/api/ApiQuerySiteinfo.php
+++ b/includes/api/ApiQuerySiteinfo.php
@@ -69,6 +69,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
case 'usergroups':
$fit = $this->appendUserGroups( $p, $params['numberingroup'] );
break;
+ case 'libraries':
+ $fit = $this->appendInstalledLibraries( $p );
+ break;
case 'extensions':
$fit = $this->appendExtensions( $p );
break;
@@ -147,24 +150,17 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$allowFrom = array( '' );
$allowException = true;
if ( !$config->get( 'AllowExternalImages' ) ) {
- if ( $config->get( 'EnableImageWhitelist' ) ) {
- $data['imagewhitelistenabled'] = '';
- }
+ $data['imagewhitelistenabled'] = (bool)$config->get( 'EnableImageWhitelist' );
$allowFrom = $config->get( 'AllowExternalImagesFrom' );
$allowException = !empty( $allowFrom );
}
if ( $allowException ) {
$data['externalimages'] = (array)$allowFrom;
- $this->getResult()->setIndexedTagName( $data['externalimages'], 'prefix' );
- }
-
- if ( !$config->get( 'DisableLangConversion' ) ) {
- $data['langconversion'] = '';
+ ApiResult::setIndexedTagName( $data['externalimages'], 'prefix' );
}
- if ( !$config->get( 'DisableTitleConversion' ) ) {
- $data['titleconversion'] = '';
- }
+ $data['langconversion'] = !$config->get( 'DisableLangConversion' );
+ $data['titleconversion'] = !$config->get( 'DisableTitleConversion' );
if ( $wgContLang->linkPrefixExtension() ) {
$linkPrefixCharset = $wgContLang->linkPrefixCharset();
@@ -177,11 +173,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
$linktrail = $wgContLang->linkTrail();
- if ( $linktrail ) {
- $data['linktrail'] = $linktrail;
- } else {
- $data['linktrail'] = '';
- }
+ $data['linktrail'] = $linktrail ?: '';
+
+ $data['legaltitlechars'] = Title::legalChars();
global $IP;
$git = SpecialVersion::getGitHeadSha1( $IP );
@@ -205,7 +199,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$fallbacks[] = array( 'code' => $code );
}
$data['fallback'] = $fallbacks;
- $this->getResult()->setIndexedTagName( $data['fallback'], 'lang' );
+ ApiResult::setIndexedTagName( $data['fallback'], 'lang' );
if ( $wgContLang->hasVariants() ) {
$variants = array();
@@ -216,21 +210,17 @@ class ApiQuerySiteinfo extends ApiQueryBase {
);
}
$data['variants'] = $variants;
- $this->getResult()->setIndexedTagName( $data['variants'], 'lang' );
+ ApiResult::setIndexedTagName( $data['variants'], 'lang' );
}
- if ( $wgContLang->isRTL() ) {
- $data['rtl'] = '';
- }
+ $data['rtl'] = $wgContLang->isRTL();
$data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
- if ( wfReadOnly() ) {
- $data['readonly'] = '';
+ $data['readonly'] = wfReadOnly();
+ if ( $data['readonly'] ) {
$data['readonlyreason'] = wfReadOnlyReason();
}
- if ( $config->get( 'EnableWriteAPI' ) ) {
- $data['writeapi'] = '';
- }
+ $data['writeapi'] = (bool)$config->get( 'EnableWriteAPI' );
$tz = $config->get( 'Localtimezone' );
$offset = $config->get( 'LocalTZoffset' );
@@ -246,21 +236,22 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data['scriptpath'] = $config->get( 'ScriptPath' );
$data['script'] = $config->get( 'Script' );
$data['variantarticlepath'] = $config->get( 'VariantArticlePath' );
+ $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
$data['server'] = $config->get( 'Server' );
$data['servername'] = $config->get( 'ServerName' );
$data['wikiid'] = wfWikiID();
$data['time'] = wfTimestamp( TS_ISO_8601, time() );
- if ( $config->get( 'MiserMode' ) ) {
- $data['misermode'] = '';
- }
+ $data['misermode'] = (bool)$config->get( 'MiserMode' );
$data['maxuploadsize'] = UploadBase::getMaxUploadSize();
$data['thumblimits'] = $config->get( 'ThumbLimits' );
- $this->getResult()->setIndexedTagName( $data['thumblimits'], 'limit' );
+ ApiResult::setArrayType( $data['thumblimits'], 'BCassoc' );
+ ApiResult::setIndexedTagName( $data['thumblimits'], 'limit' );
$data['imagelimits'] = array();
- $this->getResult()->setIndexedTagName( $data['imagelimits'], 'limit' );
+ ApiResult::setArrayType( $data['imagelimits'], 'BCassoc' );
+ ApiResult::setIndexedTagName( $data['imagelimits'], 'limit' );
foreach ( $config->get( 'ImageLimits' ) as $k => $limit ) {
$data['imagelimits'][$k] = array( 'width' => $limit[0], 'height' => $limit[1] );
}
@@ -272,37 +263,32 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data['favicon'] = wfExpandUrl( $favicon, PROTO_RELATIVE );
}
- wfRunHooks( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
+ Hooks::run( 'APIQuerySiteInfoGeneralInfo', array( $this, &$data ) );
return $this->getResult()->addValue( 'query', $property, $data );
}
protected function appendNamespaces( $property ) {
global $wgContLang;
- $data = array();
+ $data = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
foreach ( $wgContLang->getFormattedNamespaces() as $ns => $title ) {
$data[$ns] = array(
'id' => intval( $ns ),
'case' => MWNamespace::isCapitalized( $ns ) ? 'first-letter' : 'case-sensitive',
);
- ApiResult::setContent( $data[$ns], $title );
+ ApiResult::setContentValue( $data[$ns], 'name', $title );
$canonical = MWNamespace::getCanonicalName( $ns );
- if ( MWNamespace::hasSubpages( $ns ) ) {
- $data[$ns]['subpages'] = '';
- }
+ $data[$ns]['subpages'] = MWNamespace::hasSubpages( $ns );
if ( $canonical ) {
$data[$ns]['canonical'] = strtr( $canonical, '_', ' ' );
}
- if ( MWNamespace::isContent( $ns ) ) {
- $data[$ns]['content'] = '';
- }
-
- if ( MWNamespace::isNonincludable( $ns ) ) {
- $data[$ns]['nonincludable'] = '';
- }
+ $data[$ns]['content'] = MWNamespace::isContent( $ns );
+ $data[$ns]['nonincludable'] = MWNamespace::isNonincludable( $ns );
$contentmodel = MWNamespace::getNamespaceContentModel( $ns );
if ( $contentmodel ) {
@@ -310,7 +296,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
}
- $this->getResult()->setIndexedTagName( $data, 'ns' );
+ ApiResult::setIndexedTagName( $data, 'ns' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -329,13 +315,13 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$item = array(
'id' => intval( $ns )
);
- ApiResult::setContent( $item, strtr( $title, '_', ' ' ) );
+ ApiResult::setContentValue( $item, 'alias', strtr( $title, '_', ' ' ) );
$data[] = $item;
}
sort( $data );
- $this->getResult()->setIndexedTagName( $data, 'ns' );
+ ApiResult::setIndexedTagName( $data, 'ns' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -347,11 +333,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
foreach ( SpecialPageFactory::getNames() as $specialpage ) {
if ( isset( $aliases[$specialpage] ) ) {
$arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
- $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
+ ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
$data[] = $arr;
}
}
- $this->getResult()->setIndexedTagName( $data, 'specialpage' );
+ ApiResult::setIndexedTagName( $data, 'specialpage' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -362,13 +348,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
foreach ( $wgContLang->getMagicWords() as $magicword => $aliases ) {
$caseSensitive = array_shift( $aliases );
$arr = array( 'name' => $magicword, 'aliases' => $aliases );
- if ( $caseSensitive ) {
- $arr['case-sensitive'] = '';
- }
- $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
+ $arr['case-sensitive'] = (bool)$caseSensitive;
+ ApiResult::setIndexedTagName( $arr['aliases'], 'alias' );
$data[] = $arr;
}
- $this->getResult()->setIndexedTagName( $data, 'magicword' );
+ ApiResult::setIndexedTagName( $data, 'magicword' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -397,20 +381,20 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$val = array();
$val['prefix'] = $prefix;
if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
- $val['local'] = '';
+ $val['local'] = true;
}
if ( isset( $row['iw_trans'] ) && $row['iw_trans'] == '1' ) {
- $val['trans'] = '';
+ $val['trans'] = true;
}
if ( isset( $langNames[$prefix] ) ) {
$val['language'] = $langNames[$prefix];
}
if ( in_array( $prefix, $localInterwikis ) ) {
- $val['localinterwiki'] = '';
+ $val['localinterwiki'] = true;
}
if ( in_array( $prefix, $extraLangPrefixes ) ) {
- $val['extralanglink'] = '';
+ $val['extralanglink'] = true;
$linktext = wfMessage( "interlanguage-link-$prefix" );
if ( !$linktext->isDisabled() ) {
@@ -424,20 +408,18 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
$val['url'] = wfExpandUrl( $row['iw_url'], PROTO_CURRENT );
- if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
- $val['protorel'] = '';
- }
- if ( isset( $row['iw_wikiid'] ) ) {
+ $val['protorel'] = substr( $row['iw_url'], 0, 2 ) == '//';
+ if ( isset( $row['iw_wikiid'] ) && $row['iw_wikiid'] !== '' ) {
$val['wikiid'] = $row['iw_wikiid'];
}
- if ( isset( $row['iw_api'] ) ) {
+ if ( isset( $row['iw_api'] ) && $row['iw_api'] !== '' ) {
$val['api'] = $row['iw_api'];
}
$data[] = $val;
}
- $this->getResult()->setIndexedTagName( $data, 'iw' );
+ ApiResult::setIndexedTagName( $data, 'iw' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -472,7 +454,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
$result = $this->getResult();
- $result->setIndexedTagName( $data, 'db' );
+ ApiResult::setIndexedTagName( $data, 'db' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -481,9 +463,6 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data = array();
$data['pages'] = intval( SiteStats::pages() );
$data['articles'] = intval( SiteStats::articles() );
- if ( !$this->getConfig()->get( 'DisableCounters' ) ) {
- $data['views'] = intval( SiteStats::views() );
- }
$data['edits'] = intval( SiteStats::edits() );
$data['images'] = intval( SiteStats::images() );
$data['users'] = intval( SiteStats::users() );
@@ -491,7 +470,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$data['admins'] = intval( SiteStats::numberingroup( 'sysop' ) );
$data['jobs'] = intval( SiteStats::jobs() );
- wfRunHooks( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
+ Hooks::run( 'APIQuerySiteInfoStatisticsInfo', array( &$data ) );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -531,16 +510,16 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$groups = array_intersect( $rights[$group], $allGroups );
if ( $groups ) {
$arr[$type] = $groups;
- $result->setIndexedTagName( $arr[$type], 'group' );
+ ApiResult::setIndexedTagName( $arr[$type], 'group' );
}
}
}
- $result->setIndexedTagName( $arr['rights'], 'permission' );
+ ApiResult::setIndexedTagName( $arr['rights'], 'permission' );
$data[] = $arr;
}
- $result->setIndexedTagName( $data, 'group' );
+ ApiResult::setIndexedTagName( $data, 'group' );
return $result->addValue( 'query', $property, $data );
}
@@ -550,9 +529,39 @@ class ApiQuerySiteinfo extends ApiQueryBase {
foreach ( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) as $ext ) {
$data[] = array( 'ext' => $ext );
}
- $this->getResult()->setIndexedTagName( $data, 'fe' );
+ ApiResult::setIndexedTagName( $data, 'fe' );
+
+ return $this->getResult()->addValue( 'query', $property, $data );
+ }
+
+ protected function appendInstalledLibraries( $property ) {
+ global $IP;
+ $path = "$IP/composer.lock";
+ if ( !file_exists( $path ) ) {
+ // Maybe they're using mediawiki/vendor?
+ $path = "$IP/vendor/composer.lock";
+ if ( !file_exists( $path ) ) {
+ return true;
+ }
+ }
+
+ $data = array();
+ $lock = new ComposerLock( $path );
+ foreach ( $lock->getInstalledDependencies() as $name => $info ) {
+ if ( strpos( $info['type'], 'mediawiki-' ) === 0 ) {
+ // Skip any extensions or skins since they'll be listed
+ // in their proper section
+ continue;
+ }
+ $data[] = array(
+ 'name' => $name,
+ 'version' => $info['version'],
+ );
+ }
+ ApiResult::setIndexedTagName( $data, 'library' );
return $this->getResult()->addValue( 'query', $property, $data );
+
}
protected function appendExtensions( $property ) {
@@ -575,7 +584,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
if ( is_array( $ext['descriptionmsg'] ) ) {
$ret['descriptionmsg'] = $ext['descriptionmsg'][0];
$ret['descriptionmsgparams'] = array_slice( $ext['descriptionmsg'], 1 );
- $this->getResult()->setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
+ ApiResult::setIndexedTagName( $ret['descriptionmsgparams'], 'param' );
} else {
$ret['descriptionmsg'] = $ext['descriptionmsg'];
}
@@ -635,15 +644,21 @@ class ApiQuerySiteinfo extends ApiQueryBase {
}
}
- $this->getResult()->setIndexedTagName( $data, 'ext' );
+ ApiResult::setIndexedTagName( $data, 'ext' );
return $this->getResult()->addValue( 'query', $property, $data );
}
protected function appendRightsInfo( $property ) {
$config = $this->getConfig();
- $title = Title::newFromText( $config->get( 'RightsPage' ) );
- $url = $title ? wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ) : $config->get( 'RightsUrl' );
+ $rightsPage = $config->get( 'RightsPage' );
+ if ( is_string( $rightsPage ) ) {
+ $title = Title::newFromText( $rightsPage );
+ $url = wfExpandUrl( $title, PROTO_CURRENT );
+ } else {
+ $title = false;
+ $url = $config->get( 'RightsUrl' );
+ }
$text = $config->get( 'RightsText' );
if ( !$text && $title ) {
$text = $title->getPrefixedText();
@@ -666,10 +681,10 @@ class ApiQuerySiteinfo extends ApiQueryBase {
'semiprotectedlevels' => $config->get( 'SemiprotectedRestrictionLevels' ),
);
- $this->getResult()->setIndexedTagName( $data['types'], 'type' );
- $this->getResult()->setIndexedTagName( $data['levels'], 'level' );
- $this->getResult()->setIndexedTagName( $data['cascadinglevels'], 'level' );
- $this->getResult()->setIndexedTagName( $data['semiprotectedlevels'], 'level' );
+ ApiResult::setIndexedTagName( $data['types'], 'type' );
+ ApiResult::setIndexedTagName( $data['levels'], 'level' );
+ ApiResult::setIndexedTagName( $data['cascadinglevels'], 'level' );
+ ApiResult::setIndexedTagName( $data['semiprotectedlevels'], 'level' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -683,10 +698,10 @@ class ApiQuerySiteinfo extends ApiQueryBase {
foreach ( $langNames as $code => $name ) {
$lang = array( 'code' => $code );
- ApiResult::setContent( $lang, $name );
+ ApiResult::setContentValue( $lang, 'name', $name );
$data[] = $lang;
}
- $this->getResult()->setIndexedTagName( $data, 'lang' );
+ ApiResult::setIndexedTagName( $data, 'lang' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -707,16 +722,16 @@ class ApiQuerySiteinfo extends ApiQueryBase {
$displayName = $msg->text();
}
$skin = array( 'code' => $name );
- ApiResult::setContent( $skin, $displayName );
+ ApiResult::setContentValue( $skin, 'name', $displayName );
if ( !isset( $allowed[$name] ) ) {
- $skin['unusable'] = '';
+ $skin['unusable'] = true;
}
if ( $name === $default ) {
- $skin['default'] = '';
+ $skin['default'] = true;
}
$data[] = $skin;
}
- $this->getResult()->setIndexedTagName( $data, 'skin' );
+ ApiResult::setIndexedTagName( $data, 'skin' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -725,7 +740,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
global $wgParser;
$wgParser->firstCallInit();
$tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
- $this->getResult()->setIndexedTagName( $tags, 't' );
+ ApiResult::setIndexedTagName( $tags, 't' );
return $this->getResult()->addValue( 'query', $property, $tags );
}
@@ -734,14 +749,14 @@ class ApiQuerySiteinfo extends ApiQueryBase {
global $wgParser;
$wgParser->firstCallInit();
$hooks = $wgParser->getFunctionHooks();
- $this->getResult()->setIndexedTagName( $hooks, 'h' );
+ ApiResult::setIndexedTagName( $hooks, 'h' );
return $this->getResult()->addValue( 'query', $property, $hooks );
}
public function appendVariables( $property ) {
$variables = MagicWord::getVariableIDs();
- $this->getResult()->setIndexedTagName( $variables, 'v' );
+ ApiResult::setIndexedTagName( $variables, 'v' );
return $this->getResult()->addValue( 'query', $property, $variables );
}
@@ -749,13 +764,15 @@ class ApiQuerySiteinfo extends ApiQueryBase {
public function appendProtocols( $property ) {
// Make a copy of the global so we don't try to set the _element key of it - bug 45130
$protocols = array_values( $this->getConfig()->get( 'UrlProtocols' ) );
- $this->getResult()->setIndexedTagName( $protocols, 'p' );
+ ApiResult::setIndexedTagName( $protocols, 'p' );
return $this->getResult()->addValue( 'query', $property, $protocols );
}
public function appendDefaultOptions( $property ) {
- return $this->getResult()->addValue( 'query', $property, User::getDefaultOptions() );
+ $options = User::getDefaultOptions();
+ $options[ApiResult::META_BC_BOOLS] = array_keys( $options );
+ return $this->getResult()->addValue( 'query', $property, $options );
}
private function formatParserTags( $item ) {
@@ -774,11 +791,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
);
- $this->getResult()->setIndexedTagName( $arr['subscribers'], 's' );
+ ApiResult::setIndexedTagName( $arr['subscribers'], 's' );
$data[] = $arr;
}
- $this->getResult()->setIndexedTagName( $data, 'hook' );
+ ApiResult::setIndexedTagName( $data, 'hook' );
return $this->getResult()->addValue( 'query', $property, $data );
}
@@ -811,6 +828,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
'dbrepllag',
'statistics',
'usergroups',
+ 'libraries',
'extensions',
'fileextensions',
'rightsinfo',
@@ -837,54 +855,14 @@ class ApiQuerySiteinfo extends ApiQueryBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'prop' => array(
- 'Which sysinfo properties to get:',
- ' general - Overall system information',
- ' namespaces - List of registered namespaces and their canonical names',
- ' namespacealiases - List of registered namespace aliases',
- ' specialpagealiases - List of special page aliases',
- ' magicwords - List of magic words and their aliases',
- ' statistics - Returns site statistics',
- ' interwikimap - Returns interwiki map ' .
- "(optionally filtered, (optionally localised by using {$p}inlanguagecode))",
- ' dbrepllag - Returns database server with the highest replication lag',
- ' usergroups - Returns user groups and the associated permissions',
- ' extensions - Returns extensions installed on the wiki',
- ' fileextensions - Returns list of file extensions allowed to be uploaded',
- ' rightsinfo - Returns wiki rights (license) information if available',
- ' restrictions - Returns information on available restriction (protection) types',
- ' languages - Returns a list of languages MediaWiki supports ' .
- "(optionally localised by using {$p}inlanguagecode)",
- ' skins - Returns a list of all enabled skins ' .
- "(optionally localised by using {$p}inlanguagecode, otherwise in content language)",
- ' extensiontags - Returns a list of parser extension tags',
- ' functionhooks - Returns a list of parser function hooks',
- ' showhooks - Returns a list of all subscribed hooks (contents of $wgHooks)',
- ' variables - Returns a list of variable IDs',
- ' protocols - Returns a list of protocols that are allowed in external links.',
- ' defaultoptions - Returns the default values for user preferences.',
- ),
- 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
- 'showalldb' => 'List all database servers, not just the one lagging the most',
- 'numberingroup' => 'Lists the number of users in user groups',
- 'inlanguagecode' => 'Language code for localised language names ' .
- '(best effort, use CLDR extension) and skin names',
- );
- }
-
- public function getDescription() {
- return 'Return general information about the site.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics',
- 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
- 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb=',
+ 'action=query&meta=siteinfo&siprop=general|namespaces|namespacealiases|statistics'
+ => 'apihelp-query+siteinfo-example-simple',
+ 'action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local'
+ => 'apihelp-query+siteinfo-example-interwiki',
+ 'action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb='
+ => 'apihelp-query+siteinfo-example-replag',
);
}
diff --git a/includes/api/ApiQueryStashImageInfo.php b/includes/api/ApiQueryStashImageInfo.php
index db928560..11268426 100644
--- a/includes/api/ApiQueryStashImageInfo.php
+++ b/includes/api/ApiQueryStashImageInfo.php
@@ -52,18 +52,16 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
}
try {
- $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
+ $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $this->getUser() );
foreach ( $params['filekey'] as $filekey ) {
$file = $stash->getFile( $filekey );
$finalThumbParam = $this->mergeThumbParams( $file, $scale, $params['urlparam'] );
$imageInfo = ApiQueryImageInfo::getInfo( $file, $prop, $result, $finalThumbParam );
$result->addValue( array( 'query', $this->getModuleName() ), null, $imageInfo );
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), $modulePrefix );
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), $modulePrefix );
}
// @todo Update exception handling here to understand current getFile exceptions
- } catch ( UploadStashNotAvailableException $e ) {
- $this->dieUsage( "Session not available: " . $e->getMessage(), "nosession" );
} catch ( UploadStashFileNotFoundException $e ) {
$this->dieUsage( "File not found: " . $e->getMessage(), "invalidsessiondata" );
} catch ( UploadStashBadPathException $e ) {
@@ -90,50 +88,38 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
'prop' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_DFLT => 'timestamp|url',
- ApiBase::PARAM_TYPE => self::getPropertyNames( $this->propertyFilter )
+ ApiBase::PARAM_TYPE => self::getPropertyNames( $this->propertyFilter ),
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+imageinfo-param-prop',
+ ApiBase::PARAM_HELP_MSG_PER_VALUE => self::getPropertyMessages( $this->propertyFilter )
),
'urlwidth' => array(
ApiBase::PARAM_TYPE => 'integer',
- ApiBase::PARAM_DFLT => -1
+ ApiBase::PARAM_DFLT => -1,
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+imageinfo-param-urlwidth',
+ ApiQueryImageInfo::TRANSFORM_LIMIT,
+ ),
),
'urlheight' => array(
ApiBase::PARAM_TYPE => 'integer',
- ApiBase::PARAM_DFLT => -1
+ ApiBase::PARAM_DFLT => -1,
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+imageinfo-param-urlheight',
),
'urlparam' => array(
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_DFLT => '',
+ ApiBase::PARAM_HELP_MSG => 'apihelp-query+imageinfo-param-urlparam',
),
);
}
- /**
- * Return the API documentation for the parameters.
- * @return array Parameter documentation.
- */
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'prop' => self::getPropertyDescriptions( $this->propertyFilter, $p ),
- 'filekey' => 'Key that identifies a previous upload that was stashed temporarily.',
- 'sessionkey' => 'Alias for filekey, for backward compatibility.',
- 'urlwidth' => "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
- 'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth",
- 'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
- "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
- );
- }
-
- public function getDescription() {
- return 'Returns image information for stashed images.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&prop=stashimageinfo&siifilekey=124sd34rsdf567',
- 'api.php?action=query&prop=stashimageinfo&siifilekey=b34edoe3|bceffd4&' .
- 'siiurlwidth=120&siiprop=url',
+ 'action=query&prop=stashimageinfo&siifilekey=124sd34rsdf567'
+ => 'apihelp-query+stashimageinfo-example-simple',
+ 'action=query&prop=stashimageinfo&siifilekey=b34edoe3|bceffd4&' .
+ 'siiurlwidth=120&siiprop=url'
+ => 'apihelp-query+stashimageinfo-example-params',
);
}
}
diff --git a/includes/api/ApiQueryTags.php b/includes/api/ApiQueryTags.php
index 31845648..45f73b20 100644
--- a/includes/api/ApiQueryTags.php
+++ b/includes/api/ApiQueryTags.php
@@ -31,15 +31,6 @@
*/
class ApiQueryTags extends ApiQueryBase {
- /**
- * @var ApiResult
- */
- private $result;
-
- private $limit;
- private $fld_displayname = false, $fld_description = false,
- $fld_hitcount = false;
-
public function __construct( ApiQuery $query, $moduleName ) {
parent::__construct( $query, $moduleName, 'tg' );
}
@@ -49,84 +40,100 @@ class ApiQueryTags extends ApiQueryBase {
$prop = array_flip( $params['prop'] );
- $this->fld_displayname = isset( $prop['displayname'] );
- $this->fld_description = isset( $prop['description'] );
- $this->fld_hitcount = isset( $prop['hitcount'] );
-
- $this->limit = $params['limit'];
- $this->result = $this->getResult();
+ $fld_displayname = isset( $prop['displayname'] );
+ $fld_description = isset( $prop['description'] );
+ $fld_hitcount = isset( $prop['hitcount'] );
+ $fld_defined = isset( $prop['defined'] );
+ $fld_source = isset( $prop['source'] );
+ $fld_active = isset( $prop['active'] );
+
+ $limit = $params['limit'];
+ $result = $this->getResult();
+
+ $extensionDefinedTags = array_fill_keys( ChangeTags::listExtensionDefinedTags(), 0 );
+ $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
+ $extensionActivatedTags = array_fill_keys( ChangeTags::listExtensionActivatedTags(), 0 );
+
+ $definedTags = array_merge( $extensionDefinedTags, $explicitlyDefinedTags );
+
+ # Fetch defined tags that aren't past the continuation
+ if ( $params['continue'] !== null ) {
+ $cont = $params['continue'];
+ $tags = array_filter( array_keys( $definedTags ), function ( $v ) use ( $cont ) {
+ return $v >= $cont;
+ } );
+ $tags = array_fill_keys( $tags, 0 );
+ } else {
+ $tags = $definedTags;
+ }
+ # Merge in all used tags
$this->addTables( 'change_tag' );
$this->addFields( 'ct_tag' );
-
- $this->addFieldsIf( array( 'hitcount' => 'COUNT(*)' ), $this->fld_hitcount );
-
- $this->addOption( 'LIMIT', $this->limit + 1 );
+ $this->addFields( array( 'hitcount' => $fld_hitcount ? 'COUNT(*)' : '0' ) );
+ $this->addOption( 'LIMIT', $limit + 1 );
$this->addOption( 'GROUP BY', 'ct_tag' );
$this->addWhereRange( 'ct_tag', 'newer', $params['continue'], null );
-
$res = $this->select( __METHOD__ );
-
- $ok = true;
-
foreach ( $res as $row ) {
- if ( !$ok ) {
- break;
- }
- $ok = $this->doTag( $row->ct_tag, $this->fld_hitcount ? $row->hitcount : 0 );
+ $tags[$row->ct_tag] = (int)$row->hitcount;
}
- // include tags with no hits yet
- foreach ( ChangeTags::listDefinedTags() as $tag ) {
- if ( !$ok ) {
+ # Now make sure the array is sorted for proper continuation
+ ksort( $tags );
+
+ $count = 0;
+ foreach ( $tags as $tagName => $hitcount ) {
+ if ( ++$count > $limit ) {
+ $this->setContinueEnumParameter( 'continue', $tagName );
break;
}
- $ok = $this->doTag( $tag, 0 );
- }
-
- $this->result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'tag' );
- }
- private function doTag( $tagName, $hitcount ) {
- static $count = 0;
- static $doneTags = array();
+ $tag = array();
+ $tag['name'] = $tagName;
- if ( in_array( $tagName, $doneTags ) ) {
- return true;
- }
-
- if ( ++$count > $this->limit ) {
- $this->setContinueEnumParameter( 'continue', $tagName );
-
- return false;
- }
+ if ( $fld_displayname ) {
+ $tag['displayname'] = ChangeTags::tagDescription( $tagName );
+ }
- $tag = array();
- $tag['name'] = $tagName;
+ if ( $fld_description ) {
+ $msg = $this->msg( "tag-$tagName-description" );
+ $tag['description'] = $msg->exists() ? $msg->text() : '';
+ }
- if ( $this->fld_displayname ) {
- $tag['displayname'] = ChangeTags::tagDescription( $tagName );
- }
+ if ( $fld_hitcount ) {
+ $tag['hitcount'] = $hitcount;
+ }
- if ( $this->fld_description ) {
- $msg = wfMessage( "tag-$tagName-description" );
- $tag['description'] = $msg->exists() ? $msg->text() : '';
- }
+ $isExtension = isset( $extensionDefinedTags[$tagName] );
+ $isExplicit = isset( $explicitlyDefinedTags[$tagName] );
- if ( $this->fld_hitcount ) {
- $tag['hitcount'] = $hitcount;
- }
+ if ( $fld_defined ) {
+ $tag['defined'] = $isExtension || $isExplicit;
+ }
- $doneTags[] = $tagName;
+ if ( $fld_source ) {
+ $tag['source'] = array();
+ if ( $isExtension ) {
+ $tag['source'][] = 'extension';
+ }
+ if ( $isExplicit ) {
+ $tag['source'][] = 'manual';
+ }
+ }
- $fit = $this->result->addValue( array( 'query', $this->getModuleName() ), null, $tag );
- if ( !$fit ) {
- $this->setContinueEnumParameter( 'continue', $tagName );
+ if ( $fld_active ) {
+ $tag['active'] = $isExplicit || isset( $extensionActivatedTags[$tagName] );
+ }
- return false;
+ $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $tag );
+ if ( !$fit ) {
+ $this->setContinueEnumParameter( 'continue', $tagName );
+ break;
+ }
}
- return true;
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'tag' );
}
public function getCacheMode( $params ) {
@@ -135,7 +142,9 @@ class ApiQueryTags extends ApiQueryBase {
public function getAllowedParams() {
return array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
ApiBase::PARAM_TYPE => 'limit',
@@ -149,34 +158,20 @@ class ApiQueryTags extends ApiQueryBase {
'name',
'displayname',
'description',
- 'hitcount'
+ 'hitcount',
+ 'defined',
+ 'source',
+ 'active',
),
ApiBase::PARAM_ISMULTI => true
)
);
}
- public function getParamDescription() {
- return array(
- 'continue' => 'When more results are available, use this to continue',
- 'limit' => 'The maximum number of tags to list',
- 'prop' => array(
- 'Which properties to get',
- ' name - Adds name of tag',
- ' displayname - Adds system message for the tag',
- ' description - Adds description of the tag',
- ' hitcount - Adds the amount of revisions that have this tag',
- ),
- );
- }
-
- public function getDescription() {
- return 'List change tags.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=tags&tgprop=displayname|description|hitcount'
+ 'action=query&list=tags&tgprop=displayname|description|hitcount|defined'
+ => 'apihelp-query+tags-example-simple',
);
}
diff --git a/includes/api/ApiQueryTokens.php b/includes/api/ApiQueryTokens.php
index ba9c9377..65a08a3b 100644
--- a/includes/api/ApiQueryTokens.php
+++ b/includes/api/ApiQueryTokens.php
@@ -35,10 +35,12 @@ class ApiQueryTokens extends ApiQueryBase {
public function execute() {
$params = $this->extractRequestParams();
- $res = array();
+ $res = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
- if ( $this->getMain()->getRequest()->getVal( 'callback' ) !== null ) {
- $this->setWarning( 'Tokens may not be obtained when using a callback' );
+ if ( $this->lacksSameOriginSecurity() ) {
+ $this->setWarning( 'Tokens may not be obtained when the same-origin policy is not applied' );
return;
}
@@ -55,7 +57,6 @@ class ApiQueryTokens extends ApiQueryBase {
public static function getTokenTypeSalts() {
static $salts = null;
if ( !$salts ) {
- wfProfileIn( __METHOD__ );
$salts = array(
'csrf' => '',
'watch' => 'watch',
@@ -63,9 +64,8 @@ class ApiQueryTokens extends ApiQueryBase {
'rollback' => 'rollback',
'userrights' => 'userrights',
);
- wfRunHooks( 'ApiQueryTokensRegisterTypes', array( &$salts ) );
+ Hooks::run( 'ApiQueryTokensRegisterTypes', array( &$salts ) );
ksort( $salts );
- wfProfileOut( __METHOD__ );
}
return $salts;
@@ -81,20 +81,12 @@ class ApiQueryTokens extends ApiQueryBase {
);
}
- public function getParamDescription() {
- return array(
- 'type' => 'Type of token(s) to request'
- );
- }
-
- public function getDescription() {
- return 'Gets tokens for data-modifying actions.';
- }
-
- protected function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&meta=tokens' => 'Retrieve a csrf token (the default)',
- 'api.php?action=query&meta=tokens&type=watch|patrol' => 'Retrieve a watch token and a patrol token'
+ 'action=query&meta=tokens'
+ => 'apihelp-query+tokens-example-simple',
+ 'action=query&meta=tokens&type=watch|patrol'
+ => 'apihelp-query+tokens-example-types',
);
}
diff --git a/includes/api/ApiQueryUserContributions.php b/includes/api/ApiQueryUserContributions.php
index 4b167b8b..e5ec67d0 100644
--- a/includes/api/ApiQueryUserContributions.php
+++ b/includes/api/ApiQueryUserContributions.php
@@ -120,7 +120,7 @@ class ApiQueryContributions extends ApiQueryBase {
}
}
- $this->getResult()->setIndexedTagName_internal(
+ $this->getResult()->addIndexedTagName(
array( 'query', $this->getModuleName() ),
'item'
);
@@ -335,7 +335,7 @@ class ApiQueryContributions extends ApiQueryBase {
$anyHidden = false;
if ( $row->rev_deleted & Revision::DELETED_TEXT ) {
- $vals['texthidden'] = '';
+ $vals['texthidden'] = true;
$anyHidden = true;
}
@@ -343,7 +343,7 @@ class ApiQueryContributions extends ApiQueryBase {
$vals['userid'] = $row->rev_user;
$vals['user'] = $row->rev_user_text;
if ( $row->rev_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( $this->fld_ids ) {
@@ -367,20 +367,14 @@ class ApiQueryContributions extends ApiQueryBase {
}
if ( $this->fld_flags ) {
- if ( $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id ) ) {
- $vals['new'] = '';
- }
- if ( $row->rev_minor_edit ) {
- $vals['minor'] = '';
- }
- if ( $row->page_latest == $row->rev_id ) {
- $vals['top'] = '';
- }
+ $vals['new'] = $row->rev_parent_id == 0 && !is_null( $row->rev_parent_id );
+ $vals['minor'] = (bool)$row->rev_minor_edit;
+ $vals['top'] = $row->page_latest == $row->rev_id;
}
if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->rev_comment ) ) {
if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
@@ -400,8 +394,8 @@ class ApiQueryContributions extends ApiQueryBase {
}
}
- if ( $this->fld_patrolled && $row->rc_patrolled ) {
- $vals['patrolled'] = '';
+ if ( $this->fld_patrolled ) {
+ $vals['patrolled'] = (bool)$row->rc_patrolled;
}
if ( $this->fld_size && !is_null( $row->rev_len ) ) {
@@ -421,7 +415,7 @@ class ApiQueryContributions extends ApiQueryBase {
if ( $this->fld_tags ) {
if ( $row->ts_tags ) {
$tags = explode( ',', $row->ts_tags );
- $this->getResult()->setIndexedTagName( $tags, 'tag' );
+ ApiResult::setIndexedTagName( $tags, 'tag' );
$vals['tags'] = $tags;
} else {
$vals['tags'] = array();
@@ -429,7 +423,7 @@ class ApiQueryContributions extends ApiQueryBase {
}
if ( $anyHidden && $row->rev_deleted & Revision::DELETED_RESTRICTED ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
@@ -464,7 +458,9 @@ class ApiQueryContributions extends ApiQueryBase {
'end' => array(
ApiBase::PARAM_TYPE => 'timestamp'
),
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'user' => array(
ApiBase::PARAM_ISMULTI => true
),
@@ -474,7 +470,8 @@ class ApiQueryContributions extends ApiQueryBase {
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
'namespace' => array(
ApiBase::PARAM_ISMULTI => true,
@@ -507,7 +504,11 @@ class ApiQueryContributions extends ApiQueryBase {
'!top',
'new',
'!new',
- )
+ ),
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+usercontribs-param-show',
+ $this->getConfig()->get( 'RCMaxAge' )
+ ),
),
'tag' => null,
'toponly' => array(
@@ -517,53 +518,12 @@ class ApiQueryContributions extends ApiQueryBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
- $RCMaxAge = $this->getConfig()->get( 'RCMaxAge' );
-
- return array(
- 'limit' => 'The maximum number of contributions to return',
- 'start' => 'The start timestamp to return from',
- 'end' => 'The end timestamp to return to',
- 'continue' => 'When more results are available, use this to continue',
- 'user' => 'The users to retrieve contributions for',
- 'userprefix' => array(
- "Retrieve contributions for all users whose names begin with this value.",
- "Overrides {$p}user",
- ),
- 'dir' => $this->getDirectionDescription( $p ),
- 'namespace' => 'Only list contributions in these namespaces',
- 'prop' => array(
- 'Include additional pieces of information',
- ' ids - Adds the page ID and revision ID',
- ' title - Adds the title and namespace ID of the page',
- ' timestamp - Adds the timestamp of the edit',
- ' comment - Adds the comment of the edit',
- ' parsedcomment - Adds the parsed comment of the edit',
- ' size - Adds the new size of the edit',
- ' sizediff - Adds the size delta of the edit against its parent',
- ' flags - Adds flags of the edit',
- ' patrolled - Tags patrolled edits',
- ' tags - Lists tags for the edit',
- ),
- 'show' => array(
- "Show only items that meet thse criteria, e.g. non minor edits only: {$p}show=!minor",
- "NOTE: If {$p}show=patrolled or {$p}show=!patrolled is set, revisions older than",
- "\$wgRCMaxAge ($RCMaxAge) won't be shown",
- ),
- 'tag' => 'Only list revisions tagged with this tag',
- 'toponly' => 'Only list changes which are the latest revision',
- );
- }
-
- public function getDescription() {
- return 'Get all edits by a user.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=usercontribs&ucuser=YurikBot',
- 'api.php?action=query&list=usercontribs&ucuserprefix=217.121.114.',
+ 'action=query&list=usercontribs&ucuser=Example'
+ => 'apihelp-query+usercontribs-example-user',
+ 'action=query&list=usercontribs&ucuserprefix=192.0.2.'
+ => 'apihelp-query+usercontribs-example-ipprefix',
);
}
diff --git a/includes/api/ApiQueryUserInfo.php b/includes/api/ApiQueryUserInfo.php
index fd5f47b4..4a7d1e0f 100644
--- a/includes/api/ApiQueryUserInfo.php
+++ b/includes/api/ApiQueryUserInfo.php
@@ -59,7 +59,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
$vals['name'] = $user->getName();
if ( $user->isAnon() ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
if ( isset( $this->prop['blockinfo'] ) ) {
@@ -76,36 +76,40 @@ class ApiQueryUserInfo extends ApiQueryBase {
}
}
- if ( isset( $this->prop['hasmsg'] ) && $user->getNewtalk() ) {
- $vals['messages'] = '';
+ if ( isset( $this->prop['hasmsg'] ) ) {
+ $vals['messages'] = $user->getNewtalk();
}
if ( isset( $this->prop['groups'] ) ) {
$vals['groups'] = $user->getEffectiveGroups();
- $result->setIndexedTagName( $vals['groups'], 'g' ); // even if empty
+ ApiResult::setArrayType( $vals['groups'], 'array' ); // even if empty
+ ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
}
if ( isset( $this->prop['implicitgroups'] ) ) {
$vals['implicitgroups'] = $user->getAutomaticGroups();
- $result->setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
+ ApiResult::setArrayType( $vals['implicitgroups'], 'array' ); // even if empty
+ ApiResult::setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
}
if ( isset( $this->prop['rights'] ) ) {
// User::getRights() may return duplicate values, strip them
$vals['rights'] = array_values( array_unique( $user->getRights() ) );
- $result->setIndexedTagName( $vals['rights'], 'r' ); // even if empty
+ ApiResult::setArrayType( $vals['rights'], 'array' ); // even if empty
+ ApiResult::setIndexedTagName( $vals['rights'], 'r' ); // even if empty
}
if ( isset( $this->prop['changeablegroups'] ) ) {
$vals['changeablegroups'] = $user->changeableGroups();
- $result->setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
- $result->setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
- $result->setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
- $result->setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
+ ApiResult::setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
+ ApiResult::setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
+ ApiResult::setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
+ ApiResult::setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
}
if ( isset( $this->prop['options'] ) ) {
$vals['options'] = $user->getOptions();
+ $vals['options'][ApiResult::META_BC_BOOLS] = array_keys( $vals['options'] );
}
if ( isset( $this->prop['preferencestoken'] ) ) {
@@ -115,7 +119,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
);
}
if ( isset( $this->prop['preferencestoken'] ) &&
- is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) &&
+ !$this->lacksSameOriginSecurity() &&
$user->isAllowed( 'editmyoptions' )
) {
$vals['preferencestoken'] = $user->getEditToken( '', $this->getMain()->getRequest() );
@@ -157,19 +161,19 @@ class ApiQueryUserInfo extends ApiQueryBase {
$acceptLang = array();
foreach ( $langs as $lang => $val ) {
$r = array( 'q' => $val );
- ApiResult::setContent( $r, $lang );
+ ApiResult::setContentValue( $r, 'code', $lang );
$acceptLang[] = $r;
}
- $result->setIndexedTagName( $acceptLang, 'lang' );
+ ApiResult::setIndexedTagName( $acceptLang, 'lang' );
$vals['acceptlang'] = $acceptLang;
}
if ( isset( $this->prop['unreadcount'] ) ) {
$dbr = $this->getQuery()->getNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
- $sql = $dbr->selectSQLText(
+ $count = $dbr->selectRowCount(
'watchlist',
- array( 'dummy' => 1 ),
+ '1',
array(
'wl_user' => $user->getId(),
'wl_notificationtimestamp IS NOT NULL',
@@ -177,12 +181,11 @@ class ApiQueryUserInfo extends ApiQueryBase {
__METHOD__,
array( 'LIMIT' => self::WL_UNREAD_LIMIT )
);
- $count = $dbr->selectField( array( 'c' => "($sql)" ), 'COUNT(*)' );
if ( $count >= self::WL_UNREAD_LIMIT ) {
$vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
} else {
- $vals['unreadcount'] = (int)$count;
+ $vals['unreadcount'] = $count;
}
}
@@ -190,9 +193,13 @@ class ApiQueryUserInfo extends ApiQueryBase {
}
protected function getRateLimits() {
+ $retval = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
+
$user = $this->getUser();
if ( !$user->isPingLimitable() ) {
- return array(); // No limits
+ return $retval; // No limits
}
// Find out which categories we belong to
@@ -212,7 +219,6 @@ class ApiQueryUserInfo extends ApiQueryBase {
$categories = array_merge( $categories, $user->getGroups() );
// Now get the actual limits
- $retval = array();
foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
foreach ( $categories as $cat ) {
if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) ) {
@@ -246,45 +252,22 @@ class ApiQueryUserInfo extends ApiQueryBase {
'acceptlang',
'registrationdate',
'unreadcount',
- )
- )
- );
- }
-
- public function getParamDescription() {
- return array(
- 'prop' => array(
- 'What pieces of information to include',
- ' blockinfo - Tags if the current user is blocked, by whom, and for what reason',
- ' hasmsg - Adds a tag "message" if the current user has pending messages',
- ' groups - Lists all the groups the current user belongs to',
- ' implicitgroups - Lists all the groups the current user is automatically a member of',
- ' rights - Lists all the rights the current user has',
- ' changeablegroups - Lists the groups the current user can add to and remove from',
- ' options - Lists all preferences the current user has set',
- ' preferencestoken - DEPRECATED! Get a token to change current user\'s preferences',
- ' editcount - Adds the current user\'s edit count',
- ' ratelimits - Lists all rate limits applying to the current user',
- ' realname - Adds the user\'s real name',
- ' email - Adds the user\'s email address and email authentication date',
- ' acceptlang - Echoes the Accept-Language header sent by ' .
- 'the client in a structured format',
- ' registrationdate - Adds the user\'s registration date',
- ' unreadcount - Adds the count of unread pages on the user\'s watchlist ' .
- '(maximum ' . ( self::WL_UNREAD_LIMIT - 1 ) . '; returns "' .
- self::WL_UNREAD_LIMIT . '+" if more)',
+ ),
+ ApiBase::PARAM_HELP_MSG => array(
+ 'apihelp-query+userinfo-param-prop',
+ self::WL_UNREAD_LIMIT - 1,
+ self::WL_UNREAD_LIMIT . '+',
+ ),
)
);
}
- public function getDescription() {
- return 'Get information about the current user.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&meta=userinfo',
- 'api.php?action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg',
+ 'action=query&meta=userinfo'
+ => 'apihelp-query+userinfo-example-simple',
+ 'action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg'
+ => 'apihelp-query+userinfo-example-data',
);
}
diff --git a/includes/api/ApiQueryUsers.php b/includes/api/ApiQueryUsers.php
index 2f5e4b4b..f22c2134 100644
--- a/includes/api/ApiQueryUsers.php
+++ b/includes/api/ApiQueryUsers.php
@@ -67,15 +67,16 @@ class ApiQueryUsers extends ApiQueryBase {
return $this->tokenFunctions;
}
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
return array();
}
$this->tokenFunctions = array(
'userrights' => array( 'ApiQueryUsers', 'getUserrightsToken' ),
);
- wfRunHooks( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
+ Hooks::run( 'APIQueryUsersTokens', array( &$this->tokenFunctions ) );
return $this->tokenFunctions;
}
@@ -109,7 +110,7 @@ class ApiQueryUsers extends ApiQueryBase {
foreach ( $users as $u ) {
$n = User::getCanonicalName( $u );
if ( $n === false || $n === '' ) {
- $vals = array( 'name' => $u, 'invalid' => '' );
+ $vals = array( 'name' => $u, 'invalid' => true );
$fit = $result->addValue( array( 'query', $this->getModuleName() ),
null, $vals );
if ( !$fit ) {
@@ -189,7 +190,7 @@ class ApiQueryUsers extends ApiQueryBase {
$data[$name]['rights'] = $user->getRights();
}
if ( $row->ipb_deleted ) {
- $data[$name]['hidden'] = '';
+ $data[$name]['hidden'] = true;
}
if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) {
$data[$name]['blockid'] = $row->ipb_id;
@@ -200,8 +201,8 @@ class ApiQueryUsers extends ApiQueryBase {
$data[$name]['blockexpiry'] = $row->ipb_expiry;
}
- if ( isset( $this->prop['emailable'] ) && $user->canReceiveEmail() ) {
- $data[$name]['emailable'] = '';
+ if ( isset( $this->prop['emailable'] ) ) {
+ $data[$name]['emailable'] = $user->canReceiveEmail();
}
if ( isset( $this->prop['gender'] ) ) {
@@ -236,7 +237,7 @@ class ApiQueryUsers extends ApiQueryBase {
$iwUser = $urPage->fetchUser( $u );
if ( $iwUser instanceof UserRightsProxy ) {
- $data[$u]['interwiki'] = '';
+ $data[$u]['interwiki'] = true;
if ( !is_null( $params['token'] ) ) {
$tokenFunctions = $this->getTokenFunctions();
@@ -251,17 +252,20 @@ class ApiQueryUsers extends ApiQueryBase {
}
}
} else {
- $data[$u]['missing'] = '';
+ $data[$u]['missing'] = true;
}
} else {
if ( isset( $this->prop['groups'] ) && isset( $data[$u]['groups'] ) ) {
- $result->setIndexedTagName( $data[$u]['groups'], 'g' );
+ ApiResult::setArrayType( $data[$u]['groups'], 'array' );
+ ApiResult::setIndexedTagName( $data[$u]['groups'], 'g' );
}
if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) {
- $result->setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
+ ApiResult::setArrayType( $data[$u]['implicitgroups'], 'array' );
+ ApiResult::setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
}
if ( isset( $this->prop['rights'] ) && isset( $data[$u]['rights'] ) ) {
- $result->setIndexedTagName( $data[$u]['rights'], 'r' );
+ ApiResult::setArrayType( $data[$u]['rights'], 'array' );
+ ApiResult::setIndexedTagName( $data[$u]['rights'], 'r' );
}
}
@@ -274,20 +278,7 @@ class ApiQueryUsers extends ApiQueryBase {
}
$done[] = $u;
}
- $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'user' );
- }
-
- /**
- * Gets all the groups that a user is automatically a member of (implicit groups)
- *
- * @deprecated since 1.20; call User::getAutomaticGroups() directly.
- * @param User $user
- * @return array
- */
- public static function getAutoGroups( $user ) {
- wfDeprecated( __METHOD__, '1.20' );
-
- return $user->getAutomaticGroups();
+ $result->addIndexedTagName( array( 'query', $this->getModuleName() ), 'user' );
}
public function getCacheMode( $params ) {
@@ -327,33 +318,13 @@ class ApiQueryUsers extends ApiQueryBase {
);
}
- public function getParamDescription() {
+ protected function getExamplesMessages() {
return array(
- 'prop' => array(
- 'What pieces of information to include',
- ' blockinfo - Tags if the user is blocked, by whom, and for what reason',
- ' groups - Lists all the groups the user(s) belongs to',
- ' implicitgroups - Lists all the groups a user is automatically a member of',
- ' rights - Lists all the rights the user(s) has',
- ' editcount - Adds the user\'s edit count',
- ' registration - Adds the user\'s registration timestamp',
- ' emailable - Tags if the user can and wants to receive ' .
- 'email through [[Special:Emailuser]]',
- ' gender - Tags the gender of the user. Returns "male", "female", or "unknown"',
- ),
- 'users' => 'A list of users to obtain the same information for',
- 'token' => 'Which tokens to obtain for each user',
+ 'action=query&list=users&ususers=Example&usprop=groups|editcount|gender'
+ => 'apihelp-query+users-example-simple',
);
}
- public function getDescription() {
- return 'Get information about a list of users.';
- }
-
- public function getExamples() {
- return 'api.php?action=query&list=users&ususers=brion|TimStarling&usprop=groups|editcount|gender';
- }
-
public function getHelpUrls() {
return 'https://www.mediawiki.org/wiki/API:Users';
}
diff --git a/includes/api/ApiQueryWatchlist.php b/includes/api/ApiQueryWatchlist.php
index efbe05ee..9f7387c7 100644
--- a/includes/api/ApiQueryWatchlist.php
+++ b/includes/api/ApiQueryWatchlist.php
@@ -199,7 +199,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
if ( !is_null( $params['type'] ) ) {
try {
$this->addWhereFld( 'rc_type', RecentChange::parseToRCType( $params['type'] ) );
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
ApiBase::dieDebug( __METHOD__, $e->getMessage() );
}
}
@@ -281,7 +281,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
}
if ( is_null( $resultPageSet ) ) {
- $this->getResult()->setIndexedTagName_internal(
+ $this->getResult()->addIndexedTagName(
array( 'query', $this->getModuleName() ),
'item'
);
@@ -307,7 +307,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
if ( $this->fld_title || $this->fld_ids ) {
// These should already have been filtered out of the query, but just in case.
if ( $type === RC_LOG && ( $row->rc_deleted & LogPage::DELETED_ACTION ) ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( $type !== RC_LOG ||
@@ -327,7 +327,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
/* Add user data and 'anon' flag, if user is anonymous. */
if ( $this->fld_user || $this->fld_userid ) {
if ( $row->rc_deleted & Revision::DELETED_USER ) {
- $vals['userhidden'] = '';
+ $vals['userhidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_USER, $user ) ) {
@@ -342,22 +342,16 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
}
if ( !$row->rc_user ) {
- $vals['anon'] = '';
+ $vals['anon'] = true;
}
}
}
/* Add flags, such as new, minor, bot. */
if ( $this->fld_flags ) {
- if ( $row->rc_bot ) {
- $vals['bot'] = '';
- }
- if ( $row->rc_type == RC_NEW ) {
- $vals['new'] = '';
- }
- if ( $row->rc_minor ) {
- $vals['minor'] = '';
- }
+ $vals['bot'] = (bool)$row->rc_bot;
+ $vals['new'] = $row->rc_type == RC_NEW;
+ $vals['minor'] = (bool)$row->rc_minor;
}
/* Add sizes of each revision. (Only available on 1.10+) */
@@ -380,7 +374,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
/* Add edit summary / log summary. */
if ( $this->fld_comment || $this->fld_parsedcomment ) {
if ( $row->rc_deleted & Revision::DELETED_COMMENT ) {
- $vals['commenthidden'] = '';
+ $vals['commenthidden'] = true;
$anyHidden = true;
}
if ( Revision::userCanBitfield( $row->rc_deleted, Revision::DELETED_COMMENT, $user ) ) {
@@ -395,37 +389,26 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
}
/* Add the patrolled flag */
- if ( $this->fld_patrol && $row->rc_patrolled == 1 ) {
- $vals['patrolled'] = '';
- }
-
- if ( $this->fld_patrol && ChangesList::isUnpatrolled( $row, $user ) ) {
- $vals['unpatrolled'] = '';
+ if ( $this->fld_patrol ) {
+ $vals['patrolled'] = $row->rc_patrolled == 1;
+ $vals['unpatrolled'] = ChangesList::isUnpatrolled( $row, $user );
}
if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
if ( $row->rc_deleted & LogPage::DELETED_ACTION ) {
- $vals['actionhidden'] = '';
+ $vals['actionhidden'] = true;
$anyHidden = true;
}
if ( LogEventsList::userCanBitfield( $row->rc_deleted, LogPage::DELETED_ACTION, $user ) ) {
$vals['logid'] = intval( $row->rc_logid );
$vals['logtype'] = $row->rc_log_type;
$vals['logaction'] = $row->rc_log_action;
- $logEntry = DatabaseLogEntry::newFromRow( (array)$row );
- ApiQueryLogEvents::addLogParams(
- $this->getResult(),
- $vals,
- $logEntry->getParameters(),
- $logEntry->getType(),
- $logEntry->getSubtype(),
- $logEntry->getTimestamp()
- );
+ $vals['logparams'] = LogFormatter::newFromRow( $row )->formatParametersForApi();
}
}
if ( $anyHidden && ( $row->rc_deleted & Revision::DELETED_RESTRICTED ) ) {
- $vals['suppressed'] = '';
+ $vals['suppressed'] = true;
}
return $vals;
@@ -455,7 +438,8 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
ApiBase::PARAM_TYPE => array(
'newer',
'older'
- )
+ ),
+ ApiHelp::PARAM_HELP_MSG => 'api-help-param-direction',
),
'limit' => array(
ApiBase::PARAM_DFLT => 10,
@@ -498,6 +482,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
)
),
'type' => array(
+ ApiBase::PARAM_DFLT => 'edit|new|log',
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => array(
'edit',
@@ -512,67 +497,26 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
'token' => array(
ApiBase::PARAM_TYPE => 'string'
),
- 'continue' => null,
- );
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'allrev' => 'Include multiple revisions of the same page within given timeframe',
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to end enumerating',
- 'namespace' => 'Filter changes to only the given namespace(s)',
- 'user' => 'Only list changes by this user',
- 'excludeuser' => 'Don\'t list changes by this user',
- 'dir' => $this->getDirectionDescription( $p ),
- 'limit' => 'How many total results to return per request',
- 'prop' => array(
- 'Which additional items to get (non-generator mode only).',
- ' ids - Adds revision ids and page ids',
- ' title - Adds title of the page',
- ' flags - Adds flags for the edit',
- ' user - Adds the user who made the edit',
- ' userid - Adds user id of whom made the edit',
- ' comment - Adds comment of the edit',
- ' parsedcomment - Adds parsed comment of the edit',
- ' timestamp - Adds timestamp of the edit',
- ' patrol - Tags edits that are patrolled',
- ' sizes - Adds the old and new lengths of the page',
- ' notificationtimestamp - Adds timestamp of when the user was last notified about the edit',
- ' loginfo - Adds log information where appropriate',
- ),
- 'show' => array(
- 'Show only items that meet this criteria.',
- "For example, to see only minor edits done by logged-in users, set {$p}show=minor|!anon"
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
),
- 'type' => array(
- 'Which types of changes to show',
- ' edit - Regular page edits',
- ' external - External changes',
- ' new - Page creations',
- ' log - Log entries',
- ),
- 'owner' => 'The name of the user whose watchlist you\'d like to access',
- 'token' => 'Give a security token (settable in preferences) to ' .
- 'allow access to another user\'s watchlist',
- 'continue' => 'When more results are available, use this to continue',
);
}
- public function getDescription() {
- return "Get all recent changes to pages in the logged in user's watchlist.";
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=watchlist',
- 'api.php?action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment',
- 'api.php?action=query&list=watchlist&wlallrev=&wlprop=ids|title|timestamp|user|comment',
- 'api.php?action=query&generator=watchlist&prop=info',
- 'api.php?action=query&generator=watchlist&gwlallrev=&prop=revisions&rvprop=timestamp|user',
- 'api.php?action=query&list=watchlist&wlowner=Bob_Smith&wltoken=123ABC'
+ 'action=query&list=watchlist'
+ => 'apihelp-query+watchlist-example-simple',
+ 'action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment'
+ => 'apihelp-query+watchlist-example-props',
+ 'action=query&list=watchlist&wlallrev=&wlprop=ids|title|timestamp|user|comment'
+ => 'apihelp-query+watchlist-example-allrev',
+ 'action=query&generator=watchlist&prop=info'
+ => 'apihelp-query+watchlist-example-generator',
+ 'action=query&generator=watchlist&gwlallrev=&prop=revisions&rvprop=timestamp|user'
+ => 'apihelp-query+watchlist-example-generator-rev',
+ 'action=query&list=watchlist&wlowner=Example&wltoken=123ABC'
+ => 'apihelp-query+watchlist-example-wlowner',
);
}
diff --git a/includes/api/ApiQueryWatchlistRaw.php b/includes/api/ApiQueryWatchlistRaw.php
index 6b2223ac..493c192a 100644
--- a/includes/api/ApiQueryWatchlistRaw.php
+++ b/includes/api/ApiQueryWatchlistRaw.php
@@ -123,7 +123,7 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
}
}
if ( is_null( $resultPageSet ) ) {
- $this->getResult()->setIndexedTagName_internal( $this->getModuleName(), 'wr' );
+ $this->getResult()->addIndexedTagName( $this->getModuleName(), 'wr' );
} else {
$resultPageSet->populateFromTitles( $titles );
}
@@ -131,7 +131,9 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
public function getAllowedParams() {
return array(
- 'continue' => null,
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
'namespace' => array(
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => 'namespace'
@@ -168,35 +170,17 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
'ascending',
'descending'
),
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
),
);
}
- public function getParamDescription() {
- return array(
- 'continue' => 'When more results are available, use this to continue',
- 'namespace' => 'Only list pages in the given namespace(s)',
- 'limit' => 'How many total results to return per request',
- 'prop' => array(
- 'Which additional properties to get (non-generator mode only)',
- ' changed - Adds timestamp of when the user was last notified about the edit',
- ),
- 'show' => 'Only list items that meet these criteria',
- 'owner' => 'The name of the user whose watchlist you\'d like to access',
- 'token' => 'Give a security token (settable in preferences) to allow ' .
- 'access to another user\'s watchlist',
- 'dir' => 'Direction to sort the titles and namespaces in',
- );
- }
-
- public function getDescription() {
- return "Get all pages on the logged in user's watchlist.";
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=query&list=watchlistraw',
- 'api.php?action=query&generator=watchlistraw&gwrshow=changed&prop=revisions',
+ 'action=query&list=watchlistraw'
+ => 'apihelp-query+watchlistraw-example-simple',
+ 'action=query&generator=watchlistraw&gwrshow=changed&prop=info'
+ => 'apihelp-query+watchlistraw-example-generator',
);
}
diff --git a/includes/api/ApiResult.php b/includes/api/ApiResult.php
index 2e80447e..7c573a8f 100644
--- a/includes/api/ApiResult.php
+++ b/includes/api/ApiResult.php
@@ -1,11 +1,5 @@
<?php
/**
- *
- *
- * Created on Sep 4, 2006
- *
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -33,156 +27,266 @@
* Each subarray may either be a dictionary - key-value pairs with unique keys,
* or lists, where the items are added using $data[] = $value notation.
*
- * There are three special key values that change how XML output is generated:
- * '_element' This key sets the tag name for the rest of the elements in the current array.
- * It is only inserted if the formatter returned true for getNeedsRawData()
- * '_subelements' This key causes the specified elements to be returned as subelements rather than attributes.
- * It is only inserted if the formatter returned true for getNeedsRawData()
- * '*' This key has special meaning only to the XML formatter, and is outputted as is
- * for all others. In XML it becomes the content of the current element.
- *
+ * @since 1.25 this is no longer a subclass of ApiBase
* @ingroup API
*/
-class ApiResult extends ApiBase {
+class ApiResult implements ApiSerializable {
/**
- * override existing value in addValue() and setElement()
+ * Override existing value in addValue(), setValue(), and similar functions
* @since 1.21
*/
const OVERRIDE = 1;
/**
- * For addValue() and setElement(), if the value does not exist, add it as the first element.
- * In case the new value has no name (numerical index), all indexes will be renumbered.
+ * For addValue(), setValue() and similar functions, if the value does not
+ * exist, add it as the first element. In case the new value has no name
+ * (numerical index), all indexes will be renumbered.
* @since 1.21
*/
const ADD_ON_TOP = 2;
/**
- * For addValue() and setElement(), do not check size while adding a value
+ * For addValue() and similar functions, do not check size while adding a value
* Don't use this unless you REALLY know what you're doing.
- * Values added while the size checking was disabled will never be counted
+ * Values added while the size checking was disabled will never be counted.
+ * Ignored for setValue() and similar functions.
* @since 1.24
*/
const NO_SIZE_CHECK = 4;
- private $mData, $mIsRawMode, $mSize, $mCheckingSize;
+ /**
+ * For addValue(), setValue() and similar functions, do not validate data.
+ * Also disables size checking. If you think you need to use this, you're
+ * probably wrong.
+ * @since 1.25
+ */
+ const NO_VALIDATE = 12;
- private $continueAllModules = array();
- private $continueGeneratedModules = array();
- private $continuationData = array();
- private $generatorContinuationData = array();
- private $generatorParams = array();
- private $generatorDone = false;
+ /**
+ * Key for the 'indexed tag name' metadata item. Value is string.
+ * @since 1.25
+ */
+ const META_INDEXED_TAG_NAME = '_element';
/**
- * @param ApiMain $main
+ * Key for the 'subelements' metadata item. Value is string[].
+ * @since 1.25
*/
- public function __construct( ApiMain $main ) {
- parent::__construct( $main, 'result' );
- $this->mIsRawMode = false;
- $this->mCheckingSize = true;
- $this->reset();
- }
+ const META_SUBELEMENTS = '_subelements';
/**
- * Clear the current result data.
+ * Key for the 'preserve keys' metadata item. Value is string[].
+ * @since 1.25
*/
- public function reset() {
- $this->mData = array();
- $this->mSize = 0;
- }
+ const META_PRESERVE_KEYS = '_preservekeys';
/**
- * Call this function when special elements such as '_element'
- * are needed by the formatter, for example in XML printing.
- * @since 1.23 $flag parameter added
- * @param bool $flag Set the raw mode flag to this state
+ * Key for the 'content' metadata item. Value is string.
+ * @since 1.25
*/
- public function setRawMode( $flag = true ) {
- $this->mIsRawMode = $flag;
- }
+ const META_CONTENT = '_content';
/**
- * Returns true whether the formatter requested raw data.
- * @return bool
+ * Key for the 'type' metadata item. Value is one of the following strings:
+ * - default: Like 'array' if all (non-metadata) keys are numeric with no
+ * gaps, otherwise like 'assoc'.
+ * - array: Keys are used for ordering, but are not output. In a format
+ * like JSON, outputs as [].
+ * - assoc: In a format like JSON, outputs as {}.
+ * - kvp: For a format like XML where object keys have a restricted
+ * character set, use an alternative output format. For example,
+ * <container><item name="key">value</item></container> rather than
+ * <container key="value" />
+ * - BCarray: Like 'array' normally, 'default' in backwards-compatibility mode.
+ * - BCassoc: Like 'assoc' normally, 'default' in backwards-compatibility mode.
+ * - BCkvp: Like 'kvp' normally. In backwards-compatibility mode, forces
+ * the alternative output format for all formats, for example
+ * [{"name":key,"*":value}] in JSON. META_KVP_KEY_NAME must also be set.
+ * @since 1.25
*/
- public function getIsRawMode() {
- return $this->mIsRawMode;
- }
+ const META_TYPE = '_type';
/**
- * Get the result's internal data array (read-only)
- * @return array
+ * Key (rather than "name" or other default) for when META_TYPE is 'kvp' or
+ * 'BCkvp'. Value is string.
+ * @since 1.25
*/
- public function getData() {
- return $this->mData;
- }
+ const META_KVP_KEY_NAME = '_kvpkeyname';
/**
- * Get the 'real' size of a result item. This means the strlen() of the item,
- * or the sum of the strlen()s of the elements if the item is an array.
- * @param mixed $value
- * @return int
+ * Key for the 'BC bools' metadata item. Value is string[].
+ * Note no setter is provided.
+ * @since 1.25
*/
- public static function size( $value ) {
- $s = 0;
- if ( is_array( $value ) ) {
- foreach ( $value as $v ) {
- $s += self::size( $v );
- }
- } elseif ( !is_object( $value ) ) {
- // Objects can't always be cast to string
- $s = strlen( $value );
+ const META_BC_BOOLS = '_BC_bools';
+
+ /**
+ * Key for the 'BC subelements' metadata item. Value is string[].
+ * Note no setter is provided.
+ * @since 1.25
+ */
+ const META_BC_SUBELEMENTS = '_BC_subelements';
+
+ private $data, $size, $maxSize;
+ private $errorFormatter;
+
+ // Deprecated fields
+ private $isRawMode, $checkingSize, $mainForContinuation;
+
+ /**
+ * @param int|bool $maxSize Maximum result "size", or false for no limit
+ * @since 1.25 Takes an integer|bool rather than an ApiMain
+ */
+ public function __construct( $maxSize ) {
+ if ( $maxSize instanceof ApiMain ) {
+ wfDeprecated( 'ApiMain to ' . __METHOD__, '1.25' );
+ $this->errorFormatter = $maxSize->getErrorFormatter();
+ $this->mainForContinuation = $maxSize;
+ $maxSize = $maxSize->getConfig()->get( 'APIMaxResultSize' );
}
- return $s;
+ $this->maxSize = $maxSize;
+ $this->isRawMode = false;
+ $this->checkingSize = true;
+ $this->reset();
}
/**
- * Get the size of the result, i.e. the amount of bytes in it
- * @return int
+ * Set the error formatter
+ * @since 1.25
+ * @param ApiErrorFormatter $formatter
*/
- public function getSize() {
- return $this->mSize;
+ public function setErrorFormatter( ApiErrorFormatter $formatter ) {
+ $this->errorFormatter = $formatter;
}
/**
- * Disable size checking in addValue(). Don't use this unless you
- * REALLY know what you're doing. Values added while size checking
- * was disabled will not be counted (ever)
- * @deprecated since 1.24, use ApiResult::NO_SIZE_CHECK
+ * Allow for adding one ApiResult into another
+ * @since 1.25
+ * @return mixed
*/
- public function disableSizeCheck() {
- $this->mCheckingSize = false;
+ public function serializeForApiResult() {
+ return $this->data;
}
+ /************************************************************************//**
+ * @name Content
+ * @{
+ */
+
/**
- * Re-enable size checking in addValue()
- * @deprecated since 1.24, use ApiResult::NO_SIZE_CHECK
+ * Clear the current result data.
*/
- public function enableSizeCheck() {
- $this->mCheckingSize = true;
+ public function reset() {
+ $this->data = array(
+ self::META_TYPE => 'assoc', // Usually what's desired
+ );
+ $this->size = 0;
+ }
+
+ /**
+ * Get the result data array
+ *
+ * The returned value should be considered read-only.
+ *
+ * Transformations include:
+ *
+ * Custom: (callable) Applied before other transformations. Signature is
+ * function ( &$data, &$metadata ), return value is ignored. Called for
+ * each nested array.
+ *
+ * BC: (array) This transformation does various adjustments to bring the
+ * output in line with the pre-1.25 result format. The value array is a
+ * list of flags: 'nobool', 'no*', 'nosub'.
+ * - Boolean-valued items are changed to '' if true or removed if false,
+ * unless listed in META_BC_BOOLS. This may be skipped by including
+ * 'nobool' in the value array.
+ * - The tag named by META_CONTENT is renamed to '*', and META_CONTENT is
+ * set to '*'. This may be skipped by including 'no*' in the value
+ * array.
+ * - Tags listed in META_BC_SUBELEMENTS will have their values changed to
+ * array( '*' => $value ). This may be skipped by including 'nosub' in
+ * the value array.
+ * - If META_TYPE is 'BCarray', set it to 'default'
+ * - If META_TYPE is 'BCassoc', set it to 'default'
+ * - If META_TYPE is 'BCkvp', perform the transformation (even if
+ * the Types transformation is not being applied).
+ *
+ * Types: (assoc) Apply transformations based on META_TYPE. The values
+ * array is an associative array with the following possible keys:
+ * - AssocAsObject: (bool) If true, return arrays with META_TYPE 'assoc'
+ * as objects.
+ * - ArmorKVP: (string) If provided, transform arrays with META_TYPE 'kvp'
+ * and 'BCkvp' into arrays of two-element arrays, something like this:
+ * $output = array();
+ * foreach ( $input as $key => $value ) {
+ * $pair = array();
+ * $pair[$META_KVP_KEY_NAME ?: $ArmorKVP_value] = $key;
+ * ApiResult::setContentValue( $pair, 'value', $value );
+ * $output[] = $pair;
+ * }
+ *
+ * Strip: (string) Strips metadata keys from the result.
+ * - 'all': Strip all metadata, recursively
+ * - 'base': Strip metadata at the top-level only.
+ * - 'none': Do not strip metadata.
+ * - 'bc': Like 'all', but leave certain pre-1.25 keys.
+ *
+ * @since 1.25
+ * @param array|string|null $path Path to fetch, see ApiResult::addValue
+ * @param array $transforms See above
+ * @return mixed Result data, or null if not found
+ */
+ public function getResultData( $path = array(), $transforms = array() ) {
+ $path = (array)$path;
+ if ( !$path ) {
+ return self::applyTransformations( $this->data, $transforms );
+ }
+
+ $last = array_pop( $path );
+ $ret = &$this->path( $path, 'dummy' );
+ if ( !isset( $ret[$last] ) ) {
+ return null;
+ } elseif ( is_array( $ret[$last] ) ) {
+ return self::applyTransformations( $ret[$last], $transforms );
+ } else {
+ return $ret[$last];
+ }
+ }
+
+ /**
+ * Get the size of the result, i.e. the amount of bytes in it
+ * @return int
+ */
+ public function getSize() {
+ return $this->size;
}
/**
* Add an output value to the array by name.
+ *
* Verifies that value with the same name has not been added before.
- * @param array $arr To add $value to
- * @param string $name Index of $arr to add $value at
+ *
+ * @since 1.25
+ * @param array &$arr To add $value to
+ * @param string|int|null $name Index of $arr to add $value at,
+ * or null to use the next numeric index.
* @param mixed $value
* @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
- * This parameter used to be boolean, and the value of OVERRIDE=1 was
- * specifically chosen so that it would be backwards compatible with the
- * new method signature.
- *
- * @since 1.21 int $flags replaced boolean $override
*/
- public static function setElement( &$arr, $name, $value, $flags = 0 ) {
- if ( $arr === null || $name === null || $value === null
- || !is_array( $arr ) || is_array( $name )
- ) {
- ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
+ public static function setValue( array &$arr, $name, $value, $flags = 0 ) {
+ if ( !( $flags & ApiResult::NO_VALIDATE ) ) {
+ $value = self::validateValue( $value );
+ }
+
+ if ( $name === null ) {
+ if ( $flags & ApiResult::ADD_ON_TOP ) {
+ array_unshift( $arr, $value );
+ } else {
+ array_push( $arr, $value );
+ }
+ return;
}
$exists = isset( $arr[$name] );
@@ -193,265 +297,968 @@ class ApiResult extends ApiBase {
$arr[$name] = $value;
}
} elseif ( is_array( $arr[$name] ) && is_array( $value ) ) {
- $merged = array_intersect_key( $arr[$name], $value );
- if ( !count( $merged ) ) {
+ $conflicts = array_intersect_key( $arr[$name], $value );
+ if ( !$conflicts ) {
$arr[$name] += $value;
} else {
- ApiBase::dieDebug( __METHOD__, "Attempting to merge element $name" );
+ $keys = join( ', ', array_keys( $conflicts ) );
+ throw new RuntimeException( "Conflicting keys ($keys) when attempting to merge element $name" );
}
} else {
- ApiBase::dieDebug(
- __METHOD__,
- "Attempting to add element $name=$value, existing value is {$arr[$name]}"
- );
+ throw new RuntimeException( "Attempting to add element $name=$value, existing value is {$arr[$name]}" );
}
}
/**
- * Adds a content element to an array.
- * Use this function instead of hardcoding the '*' element.
- * @param array $arr To add the content element to
+ * Validate a value for addition to the result
* @param mixed $value
- * @param string $subElemName When present, content element is created
- * as a sub item of $arr. Use this parameter to create elements in
- * format "<elem>text</elem>" without attributes.
*/
- public static function setContent( &$arr, $value, $subElemName = null ) {
+ private static function validateValue( $value ) {
+ global $wgContLang;
+
+ if ( is_object( $value ) ) {
+ // Note we use is_callable() here instead of instanceof because
+ // ApiSerializable is an informal protocol (see docs there for details).
+ if ( is_callable( array( $value, 'serializeForApiResult' ) ) ) {
+ $oldValue = $value;
+ $value = $value->serializeForApiResult();
+ if ( is_object( $value ) ) {
+ throw new UnexpectedValueException(
+ get_class( $oldValue ) . "::serializeForApiResult() returned an object of class " .
+ get_class( $value )
+ );
+ }
+
+ // Recursive call instead of fall-through so we can throw a
+ // better exception message.
+ try {
+ return self::validateValue( $value );
+ } catch ( Exception $ex ) {
+ throw new UnexpectedValueException(
+ get_class( $oldValue ) . "::serializeForApiResult() returned an invalid value: " .
+ $ex->getMessage(),
+ 0,
+ $ex
+ );
+ }
+ } elseif ( is_callable( array( $value, '__toString' ) ) ) {
+ $value = (string)$value;
+ } else {
+ $value = (array)$value + array( self::META_TYPE => 'assoc' );
+ }
+ }
if ( is_array( $value ) ) {
- ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
+ foreach ( $value as $k => $v ) {
+ $value[$k] = self::validateValue( $v );
+ }
+ } elseif ( is_float( $value ) && !is_finite( $value ) ) {
+ throw new InvalidArgumentException( "Cannot add non-finite floats to ApiResult" );
+ } elseif ( is_string( $value ) ) {
+ $value = $wgContLang->normalize( $value );
+ } elseif ( $value !== null && !is_scalar( $value ) ) {
+ $type = gettype( $value );
+ if ( is_resource( $value ) ) {
+ $type .= '(' . get_resource_type( $value ) . ')';
+ }
+ throw new InvalidArgumentException( "Cannot add $type to ApiResult" );
}
- if ( is_null( $subElemName ) ) {
- ApiResult::setElement( $arr, '*', $value );
- } else {
- if ( !isset( $arr[$subElemName] ) ) {
- $arr[$subElemName] = array();
+
+ return $value;
+ }
+
+ /**
+ * Add value to the output data at the given path.
+ *
+ * Path can be an indexed array, each element specifying the branch at which to add the new
+ * value. Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value.
+ * If $path is null, the value will be inserted at the data root.
+ *
+ * @param array|string|int|null $path
+ * @param string|int|null $name See ApiResult::setValue()
+ * @param mixed $value
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ * This parameter used to be boolean, and the value of OVERRIDE=1 was specifically
+ * chosen so that it would be backwards compatible with the new method signature.
+ * @return bool True if $value fits in the result, false if not
+ * @since 1.21 int $flags replaced boolean $override
+ */
+ public function addValue( $path, $name, $value, $flags = 0 ) {
+ $arr = &$this->path( $path, ( $flags & ApiResult::ADD_ON_TOP ) ? 'prepend' : 'append' );
+
+ if ( $this->checkingSize && !( $flags & ApiResult::NO_SIZE_CHECK ) ) {
+ $newsize = $this->size + self::valueSize( $value );
+ if ( $this->maxSize !== false && $newsize > $this->maxSize ) {
+ /// @todo Add i18n message when replacing calls to ->setWarning()
+ $msg = new ApiRawMessage( 'This result was truncated because it would otherwise ' .
+ ' be larger than the limit of $1 bytes', 'truncatedresult' );
+ $msg->numParams( $this->maxSize );
+ $this->errorFormatter->addWarning( 'result', $msg );
+ return false;
}
- ApiResult::setElement( $arr[$subElemName], '*', $value );
+ $this->size = $newsize;
}
+
+ self::setValue( $arr, $name, $value, $flags );
+ return true;
}
/**
- * Causes the elements with the specified names to be output as
- * subelements rather than attributes.
- * @param array $arr
- * @param array|string $names The element name(s) to be output as subelements
+ * Remove an output value to the array by name.
+ * @param array &$arr To remove $value from
+ * @param string|int $name Index of $arr to remove
+ * @return mixed Old value, or null
*/
- public function setSubelements( &$arr, $names ) {
- // In raw mode, add the '_subelements', otherwise just ignore
- if ( !$this->getIsRawMode() ) {
- return;
+ public static function unsetValue( array &$arr, $name ) {
+ $ret = null;
+ if ( isset( $arr[$name] ) ) {
+ $ret = $arr[$name];
+ unset( $arr[$name] );
}
- if ( $arr === null || $names === null || !is_array( $arr ) ) {
- ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
+ return $ret;
+ }
+
+ /**
+ * Remove value from the output data at the given path.
+ *
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string|int|null $name Index to remove at $path.
+ * If null, $path itself is removed.
+ * @param int $flags Flags used when adding the value
+ * @return mixed Old value, or null
+ */
+ public function removeValue( $path, $name, $flags = 0 ) {
+ $path = (array)$path;
+ if ( $name === null ) {
+ if ( !$path ) {
+ throw new InvalidArgumentException( 'Cannot remove the data root' );
+ }
+ $name = array_pop( $path );
}
- if ( !is_array( $names ) ) {
- $names = array( $names );
+ $ret = self::unsetValue( $this->path( $path, 'dummy' ), $name );
+ if ( $this->checkingSize && !( $flags & ApiResult::NO_SIZE_CHECK ) ) {
+ $newsize = $this->size - self::valueSize( $ret );
+ $this->size = max( $newsize, 0 );
}
- if ( !isset( $arr['_subelements'] ) ) {
- $arr['_subelements'] = $names;
+ return $ret;
+ }
+
+ /**
+ * Add an output value to the array by name and mark as META_CONTENT.
+ *
+ * @since 1.25
+ * @param array &$arr To add $value to
+ * @param string|int $name Index of $arr to add $value at.
+ * @param mixed $value
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ */
+ public static function setContentValue( array &$arr, $name, $value, $flags = 0 ) {
+ if ( $name === null ) {
+ throw new InvalidArgumentException( 'Content value must be named' );
+ }
+ self::setContentField( $arr, $name, $flags );
+ self::setValue( $arr, $name, $value, $flags );
+ }
+
+ /**
+ * Add value to the output data at the given path and mark as META_CONTENT
+ *
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string|int $name See ApiResult::setValue()
+ * @param mixed $value
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ * @return bool True if $value fits in the result, false if not
+ */
+ public function addContentValue( $path, $name, $value, $flags = 0 ) {
+ if ( $name === null ) {
+ throw new InvalidArgumentException( 'Content value must be named' );
+ }
+ $this->addContentField( $path, $name, $flags );
+ $this->addValue( $path, $name, $value, $flags );
+ }
+
+ /**
+ * Add the numeric limit for a limit=max to the result.
+ *
+ * @since 1.25
+ * @param string $moduleName
+ * @param int $limit
+ */
+ public function addParsedLimit( $moduleName, $limit ) {
+ // Add value, allowing overwriting
+ $this->addValue( 'limits', $moduleName, $limit,
+ ApiResult::OVERRIDE | ApiResult::NO_SIZE_CHECK );
+ }
+
+ /**@}*/
+
+ /************************************************************************//**
+ * @name Metadata
+ * @{
+ */
+
+ /**
+ * Set the name of the content field name (META_CONTENT)
+ *
+ * @since 1.25
+ * @param array &$arr
+ * @param string|int $name Name of the field
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ */
+ public static function setContentField( array &$arr, $name, $flags = 0 ) {
+ if ( isset( $arr[self::META_CONTENT] ) &&
+ isset( $arr[$arr[self::META_CONTENT]] ) &&
+ !( $flags & self::OVERRIDE )
+ ) {
+ throw new RuntimeException(
+ "Attempting to set content element as $name when " . $arr[self::META_CONTENT] .
+ " is already set as the content element"
+ );
+ }
+ $arr[self::META_CONTENT] = $name;
+ }
+
+ /**
+ * Set the name of the content field name (META_CONTENT)
+ *
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string|int $name Name of the field
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ */
+ public function addContentField( $path, $name, $flags = 0 ) {
+ $arr = &$this->path( $path, ( $flags & ApiResult::ADD_ON_TOP ) ? 'prepend' : 'append' );
+ self::setContentField( $arr, $name, $flags );
+ }
+
+ /**
+ * Causes the elements with the specified names to be output as
+ * subelements rather than attributes.
+ * @since 1.25 is static
+ * @param array &$arr
+ * @param array|string|int $names The element name(s) to be output as subelements
+ */
+ public static function setSubelementsList( array &$arr, $names ) {
+ if ( !isset( $arr[self::META_SUBELEMENTS] ) ) {
+ $arr[self::META_SUBELEMENTS] = (array)$names;
} else {
- $arr['_subelements'] = array_merge( $arr['_subelements'], $names );
+ $arr[self::META_SUBELEMENTS] = array_merge( $arr[self::META_SUBELEMENTS], (array)$names );
}
}
/**
- * In case the array contains indexed values (in addition to named),
- * give all indexed values the given tag name. This function MUST be
- * called on every array that has numerical indexes.
- * @param array $arr
- * @param string $tag Tag name
+ * Causes the elements with the specified names to be output as
+ * subelements rather than attributes.
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param array|string|int $names The element name(s) to be output as subelements
*/
- public function setIndexedTagName( &$arr, $tag ) {
- // In raw mode, add the '_element', otherwise just ignore
- if ( !$this->getIsRawMode() ) {
- return;
+ public function addSubelementsList( $path, $names ) {
+ $arr = &$this->path( $path );
+ self::setSubelementsList( $arr, $names );
+ }
+
+ /**
+ * Causes the elements with the specified names to be output as
+ * attributes (when possible) rather than as subelements.
+ * @since 1.25
+ * @param array &$arr
+ * @param array|string|int $names The element name(s) to not be output as subelements
+ */
+ public static function unsetSubelementsList( array &$arr, $names ) {
+ if ( isset( $arr[self::META_SUBELEMENTS] ) ) {
+ $arr[self::META_SUBELEMENTS] = array_diff( $arr[self::META_SUBELEMENTS], (array)$names );
}
- if ( $arr === null || $tag === null || !is_array( $arr ) || is_array( $tag ) ) {
- ApiBase::dieDebug( __METHOD__, 'Bad parameter' );
+ }
+
+ /**
+ * Causes the elements with the specified names to be output as
+ * attributes (when possible) rather than as subelements.
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param array|string|int $names The element name(s) to not be output as subelements
+ */
+ public function removeSubelementsList( $path, $names ) {
+ $arr = &$this->path( $path );
+ self::unsetSubelementsList( $arr, $names );
+ }
+
+ /**
+ * Set the tag name for numeric-keyed values in XML format
+ * @since 1.25 is static
+ * @param array &$arr
+ * @param string $tag Tag name
+ */
+ public static function setIndexedTagName( array &$arr, $tag ) {
+ if ( !is_string( $tag ) ) {
+ throw new InvalidArgumentException( 'Bad tag name' );
}
- // Do not use setElement() as it is ok to call this more than once
- $arr['_element'] = $tag;
+ $arr[self::META_INDEXED_TAG_NAME] = $tag;
}
/**
- * Calls setIndexedTagName() on each sub-array of $arr
- * @param array $arr
+ * Set the tag name for numeric-keyed values in XML format
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
* @param string $tag Tag name
*/
- public function setIndexedTagName_recursive( &$arr, $tag ) {
- if ( !is_array( $arr ) ) {
- return;
+ public function addIndexedTagName( $path, $tag ) {
+ $arr = &$this->path( $path );
+ self::setIndexedTagName( $arr, $tag );
+ }
+
+ /**
+ * Set indexed tag name on $arr and all subarrays
+ *
+ * @since 1.25
+ * @param array &$arr
+ * @param string $tag Tag name
+ */
+ public static function setIndexedTagNameRecursive( array &$arr, $tag ) {
+ if ( !is_string( $tag ) ) {
+ throw new InvalidArgumentException( 'Bad tag name' );
}
- foreach ( $arr as &$a ) {
- if ( !is_array( $a ) ) {
- continue;
+ $arr[self::META_INDEXED_TAG_NAME] = $tag;
+ foreach ( $arr as $k => &$v ) {
+ if ( !self::isMetadataKey( $k ) && is_array( $v ) ) {
+ self::setIndexedTagNameRecursive( $v, $tag );
}
- $this->setIndexedTagName( $a, $tag );
- $this->setIndexedTagName_recursive( $a, $tag );
}
}
/**
- * Calls setIndexedTagName() on an array already in the result.
- * Don't specify a path to a value that's not in the result, or
- * you'll get nasty errors.
- * @param array $path Path to the array, like addValue()'s $path
- * @param string $tag
+ * Set indexed tag name on $path and all subarrays
+ *
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string $tag Tag name
*/
- public function setIndexedTagName_internal( $path, $tag ) {
- $data = &$this->mData;
- foreach ( (array)$path as $p ) {
- if ( !isset( $data[$p] ) ) {
- $data[$p] = array();
- }
- $data = &$data[$p];
+ public function addIndexedTagNameRecursive( $path, $tag ) {
+ $arr = &$this->path( $path );
+ self::setIndexedTagNameRecursive( $arr, $tag );
+ }
+
+ /**
+ * Preserve specified keys.
+ *
+ * This prevents XML name mangling and preventing keys from being removed
+ * by self::stripMetadata().
+ *
+ * @since 1.25
+ * @param array &$arr
+ * @param array|string $names The element name(s) to preserve
+ */
+ public static function setPreserveKeysList( array &$arr, $names ) {
+ if ( !isset( $arr[self::META_PRESERVE_KEYS] ) ) {
+ $arr[self::META_PRESERVE_KEYS] = (array)$names;
+ } else {
+ $arr[self::META_PRESERVE_KEYS] = array_merge( $arr[self::META_PRESERVE_KEYS], (array)$names );
}
- if ( is_null( $data ) ) {
- return;
+ }
+
+ /**
+ * Preserve specified keys.
+ * @since 1.25
+ * @see self::setPreserveKeysList()
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param array|string $names The element name(s) to preserve
+ */
+ public function addPreserveKeysList( $path, $names ) {
+ $arr = &$this->path( $path );
+ self::setPreserveKeysList( $arr, $names );
+ }
+
+ /**
+ * Don't preserve specified keys.
+ * @since 1.25
+ * @see self::setPreserveKeysList()
+ * @param array &$arr
+ * @param array|string $names The element name(s) to not preserve
+ */
+ public static function unsetPreserveKeysList( array &$arr, $names ) {
+ if ( isset( $arr[self::META_PRESERVE_KEYS] ) ) {
+ $arr[self::META_PRESERVE_KEYS] = array_diff( $arr[self::META_PRESERVE_KEYS], (array)$names );
}
- $this->setIndexedTagName( $data, $tag );
}
/**
- * Add value to the output data at the given path.
- * Path can be an indexed array, each element specifying the branch at which to add the new
- * value. Setting $path to array('a','b','c') is equivalent to data['a']['b']['c'] = $value.
- * If $path is null, the value will be inserted at the data root.
- * If $name is empty, the $value is added as a next list element data[] = $value.
+ * Don't preserve specified keys.
+ * @since 1.25
+ * @see self::setPreserveKeysList()
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param array|string $names The element name(s) to not preserve
+ */
+ public function removePreserveKeysList( $path, $names ) {
+ $arr = &$this->path( $path );
+ self::unsetPreserveKeysList( $arr, $names );
+ }
+
+ /**
+ * Set the array data type
*
- * @param array|string|null $path
- * @param string $name
- * @param mixed $value
- * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
- * This parameter used to be boolean, and the value of OVERRIDE=1 was specifically
- * chosen so that it would be backwards compatible with the new method signature.
- * @return bool True if $value fits in the result, false if not
+ * @since 1.25
+ * @param array &$arr
+ * @param string $type See ApiResult::META_TYPE
+ * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+ */
+ public static function setArrayType( array &$arr, $type, $kvpKeyName = null ) {
+ if ( !in_array( $type, array( 'default', 'array', 'assoc', 'kvp', 'BCarray', 'BCassoc', 'BCkvp' ), true ) ) {
+ throw new InvalidArgumentException( 'Bad type' );
+ }
+ $arr[self::META_TYPE] = $type;
+ if ( is_string( $kvpKeyName ) ) {
+ $arr[self::META_KVP_KEY_NAME] = $kvpKeyName;
+ }
+ }
+
+ /**
+ * Set the array data type for a path
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string $type See ApiResult::META_TYPE
+ * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+ */
+ public function addArrayType( $path, $tag, $kvpKeyName = null ) {
+ $arr = &$this->path( $path );
+ self::setArrayType( $arr, $tag, $kvpKeyName );
+ }
+
+ /**
+ * Set the array data type recursively
+ * @since 1.25
+ * @param array &$arr
+ * @param string $type See ApiResult::META_TYPE
+ * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+ */
+ public static function setArrayTypeRecursive( array &$arr, $type, $kvpKeyName = null ) {
+ self::setArrayType( $arr, $type, $kvpKeyName );
+ foreach ( $arr as $k => &$v ) {
+ if ( !self::isMetadataKey( $k ) && is_array( $v ) ) {
+ self::setArrayTypeRecursive( $v, $type, $kvpKeyName );
+ }
+ }
+ }
+
+ /**
+ * Set the array data type for a path recursively
+ * @since 1.25
+ * @param array|string|null $path See ApiResult::addValue()
+ * @param string $type See ApiResult::META_TYPE
+ * @param string $kvpKeyName See ApiResult::META_KVP_KEY_NAME
+ */
+ public function addArrayTypeRecursive( $path, $tag, $kvpKeyName = null ) {
+ $arr = &$this->path( $path );
+ self::setArrayTypeRecursive( $arr, $tag, $kvpKeyName );
+ }
+
+ /**@}*/
+
+ /************************************************************************//**
+ * @name Utility
+ * @{
+ */
+
+ /**
+ * Test whether a key should be considered metadata
*
- * @since 1.21 int $flags replaced boolean $override
+ * @param string $key
+ * @return bool
*/
- public function addValue( $path, $name, $value, $flags = 0 ) {
- $data = &$this->mData;
- if ( $this->mCheckingSize && !( $flags & ApiResult::NO_SIZE_CHECK ) ) {
- $newsize = $this->mSize + self::size( $value );
- $maxResultSize = $this->getConfig()->get( 'APIMaxResultSize' );
- if ( $newsize > $maxResultSize ) {
- $this->setWarning(
- "This result was truncated because it would otherwise be larger than the " .
- "limit of {$maxResultSize} bytes" );
+ public static function isMetadataKey( $key ) {
+ return substr( $key, 0, 1 ) === '_';
+ }
- return false;
+ /**
+ * Apply transformations to an array, returning the transformed array.
+ *
+ * @see ApiResult::getResultData()
+ * @since 1.25
+ * @param array $data
+ * @param array $transforms
+ * @return array|object
+ */
+ protected static function applyTransformations( array $dataIn, array $transforms ) {
+ $strip = isset( $transforms['Strip'] ) ? $transforms['Strip'] : 'none';
+ if ( $strip === 'base' ) {
+ $transforms['Strip'] = 'none';
+ }
+ $transformTypes = isset( $transforms['Types'] ) ? $transforms['Types'] : null;
+ if ( $transformTypes !== null && !is_array( $transformTypes ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ':Value for "Types" must be an array' );
+ }
+
+ $metadata = array();
+ $data = self::stripMetadataNonRecursive( $dataIn, $metadata );
+
+ if ( isset( $transforms['Custom'] ) ) {
+ if ( !is_callable( $transforms['Custom'] ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ': Value for "Custom" must be callable' );
}
- $this->mSize = $newsize;
+ call_user_func_array( $transforms['Custom'], array( &$data, &$metadata ) );
}
- $addOnTop = $flags & ApiResult::ADD_ON_TOP;
- if ( $path !== null ) {
- foreach ( (array)$path as $p ) {
- if ( !isset( $data[$p] ) ) {
- if ( $addOnTop ) {
- $data = array( $p => array() ) + $data;
- $addOnTop = false;
- } else {
- $data[$p] = array();
+ if ( ( isset( $transforms['BC'] ) || $transformTypes !== null ) &&
+ isset( $metadata[self::META_TYPE] ) && $metadata[self::META_TYPE] === 'BCkvp' &&
+ !isset( $metadata[self::META_KVP_KEY_NAME] )
+ ) {
+ throw new UnexpectedValueException( 'Type "BCkvp" used without setting ' .
+ 'ApiResult::META_KVP_KEY_NAME metadata item' );
+ }
+
+ // BC transformations
+ $boolKeys = null;
+ $forceKVP = false;
+ if ( isset( $transforms['BC'] ) ) {
+ if ( !is_array( $transforms['BC'] ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ':Value for "BC" must be an array' );
+ }
+ if ( !in_array( 'nobool', $transforms['BC'], true ) ) {
+ $boolKeys = isset( $metadata[self::META_BC_BOOLS] )
+ ? array_flip( $metadata[self::META_BC_BOOLS] )
+ : array();
+ }
+
+ if ( !in_array( 'no*', $transforms['BC'], true ) &&
+ isset( $metadata[self::META_CONTENT] ) && $metadata[self::META_CONTENT] !== '*'
+ ) {
+ $k = $metadata[self::META_CONTENT];
+ $data['*'] = $data[$k];
+ unset( $data[$k] );
+ $metadata[self::META_CONTENT] = '*';
+ }
+
+ if ( !in_array( 'nosub', $transforms['BC'], true ) &&
+ isset( $metadata[self::META_BC_SUBELEMENTS] )
+ ) {
+ foreach ( $metadata[self::META_BC_SUBELEMENTS] as $k ) {
+ if ( isset( $data[$k] ) ) {
+ $data[$k] = array(
+ '*' => $data[$k],
+ self::META_CONTENT => '*',
+ self::META_TYPE => 'assoc',
+ );
}
}
- $data = &$data[$p];
+ }
+
+ if ( isset( $metadata[self::META_TYPE] ) ) {
+ switch ( $metadata[self::META_TYPE] ) {
+ case 'BCarray':
+ case 'BCassoc':
+ $metadata[self::META_TYPE] = 'default';
+ break;
+ case 'BCkvp':
+ $transformTypes['ArmorKVP'] = $metadata[self::META_KVP_KEY_NAME];
+ break;
+ }
}
}
- if ( !$name ) {
- // Add list element
- if ( $addOnTop ) {
- // This element needs to be inserted in the beginning
- // Numerical indexes will be renumbered
- array_unshift( $data, $value );
- } else {
- // Add new value at the end
- $data[] = $value;
+ // Figure out type, do recursive calls, and do boolean transform if necessary
+ $defaultType = 'array';
+ $maxKey = -1;
+ foreach ( $data as $k => &$v ) {
+ $v = is_array( $v ) ? self::applyTransformations( $v, $transforms ) : $v;
+ if ( $boolKeys !== null && is_bool( $v ) && !isset( $boolKeys[$k] ) ) {
+ if ( !$v ) {
+ unset( $data[$k] );
+ continue;
+ }
+ $v = '';
+ }
+ if ( is_string( $k ) ) {
+ $defaultType = 'assoc';
+ } elseif ( $k > $maxKey ) {
+ $maxKey = $k;
}
- } else {
- // Add named element
- self::setElement( $data, $name, $value, $flags );
}
+ unset( $v );
- return true;
+ // Determine which metadata to keep
+ switch ( $strip ) {
+ case 'all':
+ case 'base':
+ $keepMetadata = array();
+ break;
+ case 'none':
+ $keepMetadata = &$metadata;
+ break;
+ case 'bc':
+ $keepMetadata = array_intersect_key( $metadata, array(
+ self::META_INDEXED_TAG_NAME => 1,
+ self::META_SUBELEMENTS => 1,
+ ) );
+ break;
+ default:
+ throw new InvalidArgumentException( __METHOD__ . ': Unknown value for "Strip"' );
+ }
+
+ // Type transformation
+ if ( $transformTypes !== null ) {
+ if ( $defaultType === 'array' && $maxKey !== count( $data ) - 1 ) {
+ $defaultType = 'assoc';
+ }
+
+ // Override type, if provided
+ $type = $defaultType;
+ if ( isset( $metadata[self::META_TYPE] ) && $metadata[self::META_TYPE] !== 'default' ) {
+ $type = $metadata[self::META_TYPE];
+ }
+ if ( ( $type === 'kvp' || $type === 'BCkvp' ) &&
+ empty( $transformTypes['ArmorKVP'] )
+ ) {
+ $type = 'assoc';
+ } elseif ( $type === 'BCarray' ) {
+ $type = 'array';
+ } elseif ( $type === 'BCassoc' ) {
+ $type = 'assoc';
+ }
+
+ // Apply transformation
+ switch ( $type ) {
+ case 'assoc':
+ $metadata[self::META_TYPE] = 'assoc';
+ $data += $keepMetadata;
+ return empty( $transformTypes['AssocAsObject'] ) ? $data : (object)$data;
+
+ case 'array':
+ ksort( $data );
+ $data = array_values( $data );
+ $metadata[self::META_TYPE] = 'array';
+ return $data + $keepMetadata;
+
+ case 'kvp':
+ case 'BCkvp':
+ $key = isset( $metadata[self::META_KVP_KEY_NAME] )
+ ? $metadata[self::META_KVP_KEY_NAME]
+ : $transformTypes['ArmorKVP'];
+ $valKey = isset( $transforms['BC'] ) ? '*' : 'value';
+ $assocAsObject = !empty( $transformTypes['AssocAsObject'] );
+
+ $ret = array();
+ foreach ( $data as $k => $v ) {
+ $item = array(
+ $key => $k,
+ $valKey => $v,
+ );
+ if ( $strip === 'none' ) {
+ $item += array(
+ self::META_PRESERVE_KEYS => array( $key ),
+ self::META_CONTENT => $valKey,
+ self::META_TYPE => 'assoc',
+ );
+ }
+ $ret[] = $assocAsObject ? (object)$item : $item;
+ }
+ $metadata[self::META_TYPE] = 'array';
+
+ return $ret + $keepMetadata;
+
+ default:
+ throw new UnexpectedValueException( "Unknown type '$type'" );
+ }
+ } else {
+ return $data + $keepMetadata;
+ }
}
/**
- * Add a parsed limit=max to the result.
+ * Recursively remove metadata keys from a data array or object
*
- * @param string $moduleName
- * @param int $limit
+ * Note this removes all potential metadata keys, not just the defined
+ * ones.
+ *
+ * @since 1.25
+ * @param array|object $data
+ * @return array|object
*/
- public function setParsedLimit( $moduleName, $limit ) {
- // Add value, allowing overwriting
- $this->addValue( 'limits', $moduleName, $limit, ApiResult::OVERRIDE );
+ public static function stripMetadata( $data ) {
+ if ( is_array( $data ) || is_object( $data ) ) {
+ $isObj = is_object( $data );
+ if ( $isObj ) {
+ $data = (array)$data;
+ }
+ $preserveKeys = isset( $data[self::META_PRESERVE_KEYS] )
+ ? (array)$data[self::META_PRESERVE_KEYS]
+ : array();
+ foreach ( $data as $k => $v ) {
+ if ( self::isMetadataKey( $k ) && !in_array( $k, $preserveKeys, true ) ) {
+ unset( $data[$k] );
+ } elseif ( is_array( $v ) || is_object( $v ) ) {
+ $data[$k] = self::stripMetadata( $v );
+ }
+ }
+ if ( $isObj ) {
+ $data = (object)$data;
+ }
+ }
+ return $data;
}
/**
- * Unset a value previously added to the result set.
- * Fails silently if the value isn't found.
- * For parameters, see addValue()
- * @param array|null $path
- * @param string $name
+ * Remove metadata keys from a data array or object, non-recursive
+ *
+ * Note this removes all potential metadata keys, not just the defined
+ * ones.
+ *
+ * @since 1.25
+ * @param array|object $data
+ * @param array &$metadata Store metadata here, if provided
+ * @return array|object
*/
- public function unsetValue( $path, $name ) {
- $data = &$this->mData;
- if ( $path !== null ) {
- foreach ( (array)$path as $p ) {
- if ( !isset( $data[$p] ) ) {
- return;
+ public static function stripMetadataNonRecursive( $data, &$metadata = null ) {
+ if ( !is_array( $metadata ) ) {
+ $metadata = array();
+ }
+ if ( is_array( $data ) || is_object( $data ) ) {
+ $isObj = is_object( $data );
+ if ( $isObj ) {
+ $data = (array)$data;
+ }
+ $preserveKeys = isset( $data[self::META_PRESERVE_KEYS] )
+ ? (array)$data[self::META_PRESERVE_KEYS]
+ : array();
+ foreach ( $data as $k => $v ) {
+ if ( self::isMetadataKey( $k ) && !in_array( $k, $preserveKeys, true ) ) {
+ $metadata[$k] = $v;
+ unset( $data[$k] );
}
- $data = &$data[$p];
+ }
+ if ( $isObj ) {
+ $data = (object)$data;
}
}
- $this->mSize -= self::size( $data[$name] );
- unset( $data[$name] );
+ return $data;
}
/**
- * Ensure all values in this result are valid UTF-8.
+ * Get the 'real' size of a result item. This means the strlen() of the item,
+ * or the sum of the strlen()s of the elements if the item is an array.
+ * @note Once the deprecated public self::size is removed, we can rename this back to a less awkward name.
+ * @param mixed $value
+ * @return int
*/
- public function cleanUpUTF8() {
- array_walk_recursive( $this->mData, array( 'ApiResult', 'cleanUp_helper' ) );
+ private static function valueSize( $value ) {
+ $s = 0;
+ if ( is_array( $value ) ||
+ is_object( $value ) && !is_callable( array( $value, '__toString' ) )
+ ) {
+ foreach ( $value as $k => $v ) {
+ if ( !self::isMetadataKey( $s ) ) {
+ $s += self::valueSize( $v );
+ }
+ }
+ } elseif ( is_scalar( $value ) ) {
+ $s = strlen( $value );
+ }
+
+ return $s;
}
/**
- * Callback function for cleanUpUTF8()
+ * Return a reference to the internal data at $path
*
- * @param string $s
+ * @param array|string|null $path
+ * @param string $create
+ * If 'append', append empty arrays.
+ * If 'prepend', prepend empty arrays.
+ * If 'dummy', return a dummy array.
+ * Else, raise an error.
+ * @return array
*/
- private static function cleanUp_helper( &$s ) {
- if ( !is_string( $s ) ) {
- return;
+ private function &path( $path, $create = 'append' ) {
+ $path = (array)$path;
+ $ret = &$this->data;
+ foreach ( $path as $i => $k ) {
+ if ( !isset( $ret[$k] ) ) {
+ switch ( $create ) {
+ case 'append':
+ $ret[$k] = array();
+ break;
+ case 'prepend':
+ $ret = array( $k => array() ) + $ret;
+ break;
+ case 'dummy':
+ $tmp = array();
+ return $tmp;
+ default:
+ $fail = join( '.', array_slice( $path, 0, $i + 1 ) );
+ throw new InvalidArgumentException( "Path $fail does not exist" );
+ }
+ }
+ if ( !is_array( $ret[$k] ) ) {
+ $fail = join( '.', array_slice( $path, 0, $i + 1 ) );
+ throw new InvalidArgumentException( "Path $fail is not an array" );
+ }
+ $ret = &$ret[$k];
}
- global $wgContLang;
- $s = $wgContLang->normalize( $s );
+ return $ret;
}
+ /**@}*/
+
+ /************************************************************************//**
+ * @name Deprecated
+ * @{
+ */
+
/**
- * Converts a Status object to an array suitable for addValue
- * @param Status $status
- * @param string $errorType
+ * Call this function when special elements such as '_element'
+ * are needed by the formatter, for example in XML printing.
+ * @deprecated since 1.25, you shouldn't have been using it in the first place
+ * @since 1.23 $flag parameter added
+ * @param bool $flag Set the raw mode flag to this state
+ */
+ public function setRawMode( $flag = true ) {
+ // Can't wfDeprecated() here, since we need to set this flag from
+ // ApiMain for BC with stuff using self::getIsRawMode as
+ // "self::getIsXMLMode".
+ $this->isRawMode = $flag;
+ }
+
+ /**
+ * Returns true whether the formatter requested raw data.
+ * @deprecated since 1.25, you shouldn't have been using it in the first place
+ * @return bool
+ */
+ public function getIsRawMode() {
+ /// @todo: After Wikibase stops calling this, warn
+ return $this->isRawMode;
+ }
+
+ /**
+ * Get the result's internal data array (read-only)
+ * @deprecated since 1.25, use $this->getResultData() instead
* @return array
*/
- public function convertStatusToArray( $status, $errorType = 'error' ) {
- if ( $status->isGood() ) {
- return array();
+ public function getData() {
+ wfDeprecated( __METHOD__, '1.25' );
+ return $this->getResultData( null, array(
+ 'BC' => array(),
+ 'Types' => array(),
+ 'Strip' => $this->isRawMode ? 'bc' : 'all',
+ ) );
+ }
+
+ /**
+ * Disable size checking in addValue(). Don't use this unless you
+ * REALLY know what you're doing. Values added while size checking
+ * was disabled will not be counted (ever)
+ * @deprecated since 1.24, use ApiResult::NO_SIZE_CHECK
+ */
+ public function disableSizeCheck() {
+ wfDeprecated( __METHOD__, '1.24' );
+ $this->checkingSize = false;
+ }
+
+ /**
+ * Re-enable size checking in addValue()
+ * @deprecated since 1.24, use ApiResult::NO_SIZE_CHECK
+ */
+ public function enableSizeCheck() {
+ wfDeprecated( __METHOD__, '1.24' );
+ $this->checkingSize = true;
+ }
+
+ /**
+ * Alias for self::setValue()
+ *
+ * @since 1.21 int $flags replaced boolean $override
+ * @deprecated since 1.25, use self::setValue() instead
+ * @param array $arr To add $value to
+ * @param string $name Index of $arr to add $value at
+ * @param mixed $value
+ * @param int $flags Zero or more OR-ed flags like OVERRIDE | ADD_ON_TOP.
+ * This parameter used to be boolean, and the value of OVERRIDE=1 was
+ * specifically chosen so that it would be backwards compatible with the
+ * new method signature.
+ */
+ public static function setElement( &$arr, $name, $value, $flags = 0 ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ return self::setValue( $arr, $name, $value, $flags );
+ }
+
+ /**
+ * Adds a content element to an array.
+ * Use this function instead of hardcoding the '*' element.
+ * @deprecated since 1.25, use self::setContentValue() instead
+ * @param array $arr To add the content element to
+ * @param mixed $value
+ * @param string $subElemName When present, content element is created
+ * as a sub item of $arr. Use this parameter to create elements in
+ * format "<elem>text</elem>" without attributes.
+ */
+ public static function setContent( &$arr, $value, $subElemName = null ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( is_array( $value ) ) {
+ throw new InvalidArgumentException( __METHOD__ . ': Bad parameter' );
}
+ if ( is_null( $subElemName ) ) {
+ self::setContentValue( $arr, 'content', $value );
+ } else {
+ if ( !isset( $arr[$subElemName] ) ) {
+ $arr[$subElemName] = array();
+ }
+ self::setContentValue( $arr[$subElemName], 'content', $value );
+ }
+ }
- $result = array();
- foreach ( $status->getErrorsByType( $errorType ) as $error ) {
- $this->setIndexedTagName( $error['params'], 'param' );
- $result[] = $error;
+ /**
+ * Set indexed tag name on all subarrays of $arr
+ *
+ * Does not set the tag name for $arr itself.
+ *
+ * @deprecated since 1.25, use self::setIndexedTagNameRecursive() instead
+ * @param array $arr
+ * @param string $tag Tag name
+ */
+ public function setIndexedTagName_recursive( &$arr, $tag ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( !is_array( $arr ) ) {
+ return;
}
- $this->setIndexedTagName( $result, $errorType );
+ if ( !is_string( $tag ) ) {
+ throw new InvalidArgumentException( 'Bad tag name' );
+ }
+ foreach ( $arr as $k => &$v ) {
+ if ( !self::isMetadataKey( $k ) && is_array( $v ) ) {
+ $v[self::META_INDEXED_TAG_NAME] = $tag;
+ $this->setIndexedTagName_recursive( $v, $tag );
+ }
+ }
+ }
- return $result;
+ /**
+ * Alias for self::addIndexedTagName()
+ * @deprecated since 1.25, use $this->addIndexedTagName() instead
+ * @param array $path Path to the array, like addValue()'s $path
+ * @param string $tag
+ */
+ public function setIndexedTagName_internal( $path, $tag ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ $this->addIndexedTagName( $path, $tag );
+ }
+
+ /**
+ * Alias for self::addParsedLimit()
+ * @deprecated since 1.25, use $this->addParsedLimit() instead
+ * @param string $moduleName
+ * @param int $limit
+ */
+ public function setParsedLimit( $moduleName, $limit ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ $this->addParsedLimit( $moduleName, $limit );
}
- public function execute() {
- ApiBase::dieDebug( __METHOD__, 'execute() is not supported on Result object' );
+ /**
+ * Set the ApiMain for use by $this->beginContinuation()
+ * @since 1.25
+ * @deprecated for backwards compatibility only, do not use
+ * @param ApiMain $main
+ */
+ public function setMainForContinuation( ApiMain $main ) {
+ $this->mainForContinuation = $main;
}
/**
@@ -460,172 +1267,148 @@ class ApiResult extends ApiBase {
* This must be balanced by a call to endContinuation().
*
* @since 1.24
- * @param string|null $continue The "continue" parameter, if any
- * @param ApiBase[] $allModules Contains ApiBase instances that will be executed
- * @param array $generatedModules Names of modules that depend on the generator
- * @return array Two elements: a boolean indicating if the generator is done,
- * and an array of modules to actually execute.
+ * @deprecated since 1.25, use ApiContinuationManager instead
+ * @param string|null $continue
+ * @param ApiBase[] $allModules
+ * @param array $generatedModules
+ * @return array
*/
public function beginContinuation(
$continue, array $allModules = array(), array $generatedModules = array()
) {
- $this->continueGeneratedModules = $generatedModules
- ? array_combine( $generatedModules, $generatedModules )
- : array();
- $this->continuationData = array();
- $this->generatorContinuationData = array();
- $this->generatorParams = array();
-
- $skip = array();
- if ( is_string( $continue ) && $continue !== '' ) {
- $continue = explode( '||', $continue );
- $this->dieContinueUsageIf( count( $continue ) !== 2 );
- $this->generatorDone = ( $continue[0] === '-' );
- if ( !$this->generatorDone ) {
- $this->generatorParams = explode( '|', $continue[0] );
- }
- $skip = explode( '|', $continue[1] );
- }
-
- $this->continueAllModules = array();
- $runModules = array();
- foreach ( $allModules as $module ) {
- $name = $module->getModuleName();
- if ( in_array( $name, $skip ) ) {
- $this->continueAllModules[$name] = false;
- // Prevent spurious "unused parameter" warnings
- $module->extractRequestParams();
- } else {
- $this->continueAllModules[$name] = true;
- $runModules[] = $module;
- }
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( $this->mainForContinuation->getContinuationManager() ) {
+ throw new UnexpectedValueException(
+ __METHOD__ . ': Continuation already in progress from ' .
+ $this->mainForContinuation->getContinuationManager()->getSource()
+ );
+ }
+
+ // Ugh. If $continue doesn't match that in the request, temporarily
+ // replace the request when creating the ApiContinuationManager.
+ if ( $continue === null ) {
+ $continue = '';
}
+ if ( $this->mainForContinuation->getVal( 'continue', '' ) !== $continue ) {
+ $oldCtx = $this->mainForContinuation->getContext();
+ $newCtx = new DerivativeContext( $oldCtx );
+ $newCtx->setRequest( new DerivativeRequest(
+ $oldCtx->getRequest(),
+ array( 'continue' => $continue ) + $oldCtx->getRequest()->getValues(),
+ $oldCtx->getRequest()->wasPosted()
+ ) );
+ $this->mainForContinuation->setContext( $newCtx );
+ $reset = new ScopedCallback(
+ array( $this->mainForContinuation, 'setContext' ),
+ array( $oldCtx )
+ );
+ }
+ $manager = new ApiContinuationManager(
+ $this->mainForContinuation, $allModules, $generatedModules
+ );
+ $reset = null;
+
+ $this->mainForContinuation->setContinuationManager( $manager );
return array(
- $this->generatorDone,
- $runModules,
+ $manager->isGeneratorDone(),
+ $manager->getRunModules(),
);
}
/**
- * Set the continuation parameter for a module
- *
* @since 1.24
+ * @deprecated since 1.25, use ApiContinuationManager instead
* @param ApiBase $module
* @param string $paramName
* @param string|array $paramValue
*/
public function setContinueParam( ApiBase $module, $paramName, $paramValue ) {
- $name = $module->getModuleName();
- if ( !isset( $this->continueAllModules[$name] ) ) {
- throw new MWException(
- "Module '$name' called ApiResult::setContinueParam but was not " .
- 'passed to ApiResult::beginContinuation'
- );
- }
- if ( !$this->continueAllModules[$name] ) {
- throw new MWException(
- "Module '$name' was not supposed to have been executed, but " .
- 'it was executed anyway'
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( $this->mainForContinuation->getContinuationManager() ) {
+ $this->mainForContinuation->getContinuationManager()->addContinueParam(
+ $module, $paramName, $paramValue
);
}
- $paramName = $module->encodeParamName( $paramName );
- if ( is_array( $paramValue ) ) {
- $paramValue = join( '|', $paramValue );
- }
- $this->continuationData[$name][$paramName] = $paramValue;
}
/**
- * Set the continuation parameter for the generator module
- *
* @since 1.24
+ * @deprecated since 1.25, use ApiContinuationManager instead
* @param ApiBase $module
* @param string $paramName
* @param string|array $paramValue
*/
public function setGeneratorContinueParam( ApiBase $module, $paramName, $paramValue ) {
- $name = $module->getModuleName();
- $paramName = $module->encodeParamName( $paramName );
- if ( is_array( $paramValue ) ) {
- $paramValue = join( '|', $paramValue );
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( $this->mainForContinuation->getContinuationManager() ) {
+ $this->mainForContinuation->getContinuationManager()->addGeneratorContinueParam(
+ $module, $paramName, $paramValue
+ );
}
- $this->generatorContinuationData[$name][$paramName] = $paramValue;
}
/**
* Close continuation, writing the data into the result
- *
* @since 1.24
+ * @deprecated since 1.25, use ApiContinuationManager instead
* @param string $style 'standard' for the new style since 1.21, 'raw' for
* the style used in 1.20 and earlier.
*/
public function endContinuation( $style = 'standard' ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ if ( !$this->mainForContinuation->getContinuationManager() ) {
+ return;
+ }
+
if ( $style === 'raw' ) {
- $key = 'query-continue';
- $data = array_merge_recursive(
- $this->continuationData, $this->generatorContinuationData
- );
+ $data = $this->mainForContinuation->getContinuationManager()->getRawContinuation();
+ if ( $data ) {
+ $this->addValue( null, 'query-continue', $data, self::ADD_ON_TOP | self::NO_SIZE_CHECK );
+ }
} else {
- $key = 'continue';
- $data = array();
-
- $finishedModules = array_diff(
- array_keys( $this->continueAllModules ),
- array_keys( $this->continuationData )
- );
+ $this->mainForContinuation->getContinuationManager()->setContinuationIntoResult( $this );
+ }
+ }
- // First, grab the non-generator-using continuation data
- $continuationData = array_diff_key(
- $this->continuationData, $this->continueGeneratedModules
- );
- foreach ( $continuationData as $module => $kvp ) {
- $data += $kvp;
- }
+ /**
+ * No-op, this is now checked on insert.
+ * @deprecated since 1.25
+ */
+ public function cleanUpUTF8() {
+ wfDeprecated( __METHOD__, '1.25' );
+ }
- // Next, handle the generator-using continuation data
- $continuationData = array_intersect_key(
- $this->continuationData, $this->continueGeneratedModules
- );
- if ( $continuationData ) {
- // Some modules are unfinished: include those params, and copy
- // the generator params.
- foreach ( $continuationData as $module => $kvp ) {
- $data += $kvp;
- }
- $data += array_intersect_key(
- $this->getMain()->getRequest()->getValues(),
- array_flip( $this->generatorParams )
- );
- } elseif ( $this->generatorContinuationData ) {
- // All the generator-using modules are complete, but the
- // generator isn't. Continue the generator and restart the
- // generator-using modules
- $this->generatorParams = array();
- foreach ( $this->generatorContinuationData as $kvp ) {
- $this->generatorParams = array_merge(
- $this->generatorParams, array_keys( $kvp )
- );
- $data += $kvp;
- }
- $finishedModules = array_diff(
- $finishedModules, $this->continueGeneratedModules
- );
- } else {
- // Generator and prop modules are all done. Mark it so.
- $this->generatorDone = true;
- }
+ /**
+ * Get the 'real' size of a result item. This means the strlen() of the item,
+ * or the sum of the strlen()s of the elements if the item is an array.
+ * @deprecated since 1.25, no external users known and there doesn't seem
+ * to be any case for such use over just checking the return value from the
+ * add/set methods.
+ * @param mixed $value
+ * @return int
+ */
+ public static function size( $value ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ return self::valueSize( $value );
+ }
- // Set 'continue' if any continuation data is set or if the generator
- // still needs to run
- if ( $data || !$this->generatorDone ) {
- $data['continue'] =
- ( $this->generatorDone ? '-' : join( '|', $this->generatorParams ) ) .
- '||' . join( '|', $finishedModules );
- }
- }
- if ( $data ) {
- $this->addValue( null, $key, $data, ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
- }
+ /**
+ * Converts a Status object to an array suitable for addValue
+ * @deprecated since 1.25, use ApiErrorFormatter::arrayFromStatus()
+ * @param Status $status
+ * @param string $errorType
+ * @return array
+ */
+ public function convertStatusToArray( $status, $errorType = 'error' ) {
+ wfDeprecated( __METHOD__, '1.25' );
+ return $this->errorFormatter->arrayFromStatus( $status, $errorType );
}
+
+ /**@}*/
}
+
+/**
+ * For really cool vim folding this needs to be at the end:
+ * vim: foldmarker=@{,@} foldmethod=marker
+ */
diff --git a/includes/api/ApiRevisionDelete.php b/includes/api/ApiRevisionDelete.php
index cbc30704..28962316 100644
--- a/includes/api/ApiRevisionDelete.php
+++ b/includes/api/ApiRevisionDelete.php
@@ -111,7 +111,7 @@ class ApiRevisionDelete extends ApiBase {
// @codingStandardsIgnoreEnd
$data['items'] = array_values( $data['items'] );
- $result->setIndexedTagName( $data['items'], 'i' );
+ ApiResult::setIndexedTagName( $data['items'], 'i' );
$result->addValue( null, $this->getModuleName(), $data );
}
@@ -121,12 +121,12 @@ class ApiRevisionDelete extends ApiBase {
);
$errors = $this->formatStatusMessages( $status->getErrorsByType( 'error' ) );
if ( $errors ) {
- $this->getResult()->setIndexedTagName( $errors, 'e' );
+ ApiResult::setIndexedTagName( $errors, 'e' );
$ret['errors'] = $errors;
}
$warnings = $this->formatStatusMessages( $status->getErrorsByType( 'warning' ) );
if ( $warnings ) {
- $this->getResult()->setIndexedTagName( $warnings, 'w' );
+ ApiResult::setIndexedTagName( $warnings, 'w' );
$ret['warnings'] = $warnings;
}
@@ -146,14 +146,14 @@ class ApiRevisionDelete extends ApiBase {
$message = array( 'message' => $msg->getKey() );
if ( $msg->getParams() ) {
$message['params'] = $msg->getParams();
- $result->setIndexedTagName( $message['params'], 'p' );
+ ApiResult::setIndexedTagName( $message['params'], 'p' );
}
} else {
$message = array( 'message' => $m['message'] );
$msg = wfMessage( $m['message'] );
if ( isset( $m['params'] ) ) {
$message['params'] = $m['params'];
- $result->setIndexedTagName( $message['params'], 'p' );
+ ApiResult::setIndexedTagName( $message['params'], 'p' );
$msg->params( $m['params'] );
}
}
@@ -199,34 +199,18 @@ class ApiRevisionDelete extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'type' => 'Type of revision deletion being performed',
- 'target' => 'Page title for the revision deletion, if required for the type',
- 'ids' => 'Identifiers for the revisions to be deleted',
- 'hide' => 'What to hide for each revision',
- 'show' => 'What to unhide for each revision',
- 'suppress' => 'Whether to suppress data from administrators as well as others',
- 'reason' => 'Reason for the deletion/undeletion',
- );
- }
-
- public function getDescription() {
- return 'Delete/undelete revisions.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=revisiondelete&target=Main%20Page&type=revision&ids=12345&' .
+ 'action=revisiondelete&target=Main%20Page&type=revision&ids=12345&' .
'hide=content&token=123ABC'
- => 'Hide content for revision 12345 on the Main Page',
- 'api.php?action=revisiondelete&type=logging&ids=67890&hide=content|comment|user&' .
+ => 'apihelp-revisiondelete-example-revision',
+ 'action=revisiondelete&type=logging&ids=67890&hide=content|comment|user&' .
'reason=BLP%20violation&token=123ABC'
- => 'Hide all data on log entry 67890 with the reason "BLP violation"',
+ => 'apihelp-revisiondelete-example-log',
);
}
diff --git a/includes/api/ApiRollback.php b/includes/api/ApiRollback.php
index f4d3c541..02e62a03 100644
--- a/includes/api/ApiRollback.php
+++ b/includes/api/ApiRollback.php
@@ -120,31 +120,10 @@ class ApiRollback extends ApiBase {
'nochange'
),
),
- );
- }
-
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'title' => "Title of the page you want to roll back. Cannot be used together with {$p}pageid",
- 'pageid' => "Page ID of the page you want to roll back. Cannot be used together with {$p}title",
- 'user' => 'Name of the user whose edits are to be rolled back.',
'token' => array(
- /* Standard description automatically prepended */
- 'For compatibility, the token used in the web UI is also accepted.'
+ // Standard definition automatically inserted
+ ApiBase::PARAM_HELP_MSG_APPEND => array( 'api-help-param-token-webui' ),
),
- 'summary' => 'Custom edit summary. If empty, default summary will be used',
- 'markbot' => 'Mark the reverted edits and the revert as bot edits',
- 'watchlist' => 'Unconditionally add or remove the page from your watchlist, ' .
- 'use preferences or do not change watch',
- );
- }
-
- public function getDescription() {
- return array(
- 'Undo the last edit to the page. If the last user who edited the page made',
- 'multiple edits in a row, they will all be rolled back.'
);
}
@@ -211,12 +190,13 @@ class ApiRollback extends ApiBase {
return $this->mTitleObj;
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=rollback&title=Main%20Page&user=Catrope&token=123ABC',
- 'api.php?action=rollback&pageid=122&user=Catrope&token=123ABC',
- 'api.php?action=rollback&title=Main%20Page&user=217.121.114.116&' .
- 'token=123ABC&summary=Reverting%20vandalism&markbot=1'
+ 'action=rollback&title=Main%20Page&user=Example&token=123ABC' =>
+ 'apihelp-rollback-example-simple',
+ 'action=rollback&title=Main%20Page&user=192.0.2.5&' .
+ 'token=123ABC&summary=Reverting%20vandalism&markbot=1' =>
+ 'apihelp-rollback-example-summary',
);
}
diff --git a/includes/api/ApiRsd.php b/includes/api/ApiRsd.php
index a2771a0c..d4661125 100644
--- a/includes/api/ApiRsd.php
+++ b/includes/api/ApiRsd.php
@@ -37,12 +37,15 @@ class ApiRsd extends ApiBase {
$result->addValue( null, 'version', '1.0' );
$result->addValue( null, 'xmlns', 'http://archipelago.phrasewise.com/rsd' );
- $service = array( 'apis' => $this->formatRsdApiList() );
- ApiResult::setContent( $service, 'MediaWiki', 'engineName' );
- ApiResult::setContent( $service, 'https://www.mediawiki.org/', 'engineLink' );
- ApiResult::setContent( $service, Title::newMainPage()->getCanonicalURL(), 'homePageLink' );
+ $service = array(
+ 'apis' => $this->formatRsdApiList(),
+ 'engineName' => 'MediaWiki',
+ 'engineLink' => 'https://www.mediawiki.org/',
+ 'homePageLink' => Title::newMainPage()->getCanonicalURL(),
+ );
- $result->setIndexedTagName( $service['apis'], 'api' );
+ ApiResult::setSubelementsList( $service, array( 'engineName', 'engineLink', 'homePageLink' ) );
+ ApiResult::setIndexedTagName( $service['apis'], 'api' );
$result->addValue( null, 'service', $service );
}
@@ -51,21 +54,10 @@ class ApiRsd extends ApiBase {
return new ApiFormatXmlRsd( $this->getMain(), 'xml' );
}
- public function getAllowedParams() {
- return array();
- }
-
- public function getParamDescription() {
- return array();
- }
-
- public function getDescription() {
- return 'Export an RSD (Really Simple Discovery) schema.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=rsd'
+ 'action=rsd'
+ => 'apihelp-rsd-example-simple',
);
}
@@ -110,7 +102,7 @@ class ApiRsd extends ApiBase {
)
),
);
- wfRunHooks( 'ApiRsdServiceApis', array( &$apis ) );
+ Hooks::run( 'ApiRsdServiceApis', array( &$apis ) );
return $apis;
}
@@ -134,7 +126,8 @@ class ApiRsd extends ApiBase {
);
$settings = array();
if ( isset( $info['docs'] ) ) {
- ApiResult::setContent( $settings, $info['docs'], 'docs' );
+ $settings['docs'] = $info['docs'];
+ ApiResult::setSubelementsList( $settings, 'docs' );
}
if ( isset( $info['settings'] ) ) {
foreach ( $info['settings'] as $setting => $val ) {
@@ -144,12 +137,12 @@ class ApiRsd extends ApiBase {
$xmlVal = $val;
}
$setting = array( 'name' => $setting );
- ApiResult::setContent( $setting, $xmlVal );
+ ApiResult::setContentValue( $setting, 'value', $xmlVal );
$settings[] = $setting;
}
}
if ( count( $settings ) ) {
- $this->getResult()->setIndexedTagName( $settings, 'setting' );
+ ApiResult::setIndexedTagName( $settings, 'setting' );
$data['settings'] = $settings;
}
$outputData[] = $data;
@@ -168,4 +161,9 @@ class ApiFormatXmlRsd extends ApiFormatXml {
public function getMimeType() {
return 'application/rsd+xml';
}
+
+ public static function recXmlPrint( $name, $value, $indent, $attributes = array() ) {
+ unset( $attributes['_idx'] );
+ return parent::recXmlPrint( $name, $value, $indent, $attributes );
+ }
}
diff --git a/includes/api/ApiSerializable.php b/includes/api/ApiSerializable.php
new file mode 100644
index 00000000..70e93a6c
--- /dev/null
+++ b/includes/api/ApiSerializable.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Created on Feb 25, 2015
+ *
+ * Copyright © 2015 Brad Jorsch "bjorsch@wikimedia.org"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * This interface allows for overriding the default conversion applied by
+ * ApiResult::validateValue().
+ *
+ * @note This is currently an informal interface; it need not be explicitly
+ * implemented, as long as the method is provided. This allows for extension
+ * code to maintain compatibility with older MediaWiki while still taking
+ * advantage of this where it exists.
+ *
+ * @ingroup API
+ * @since 1.25
+ */
+interface ApiSerializable {
+ /**
+ * Return the value to be added to ApiResult in place of this object.
+ *
+ * The returned value must not be an object, and must pass
+ * all checks done by ApiResult::validateValue().
+ *
+ * @return mixed
+ */
+ public function serializeForApiResult();
+}
diff --git a/includes/api/ApiSetNotificationTimestamp.php b/includes/api/ApiSetNotificationTimestamp.php
index 5d527fc7..86a3f6aa 100644
--- a/includes/api/ApiSetNotificationTimestamp.php
+++ b/includes/api/ApiSetNotificationTimestamp.php
@@ -46,7 +46,8 @@ class ApiSetNotificationTimestamp extends ApiBase {
$params = $this->extractRequestParams();
$this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
- $this->getResult()->beginContinuation( $params['continue'], array(), array() );
+ $continuationManager = new ApiContinuationManager( $this, array(), array() );
+ $this->setContinuationManager( $continuationManager );
$pageSet = $this->getPageSet();
if ( $params['entirewatchlist'] && $pageSet->getDataSource() !== null ) {
@@ -73,7 +74,8 @@ class ApiSetNotificationTimestamp extends ApiBase {
}
$title = reset( $pageSet->getGoodTitles() );
if ( $title ) {
- $timestamp = Revision::getTimestampFromId( $title, $params['torevid'] );
+ $timestamp = Revision::getTimestampFromId(
+ $title, $params['torevid'], Revision::READ_LATEST );
if ( $timestamp ) {
$timestamp = $dbw->timestamp( $timestamp );
} else {
@@ -86,7 +88,8 @@ class ApiSetNotificationTimestamp extends ApiBase {
}
$title = reset( $pageSet->getGoodTitles() );
if ( $title ) {
- $revid = $title->getNextRevisionID( $params['newerthanrevid'] );
+ $revid = $title->getNextRevisionID(
+ $params['newerthanrevid'], Title::GAID_FOR_UPDATE );
if ( $revid ) {
$timestamp = $dbw->timestamp( Revision::getTimestampFromId( $title, $revid ) );
} else {
@@ -112,21 +115,21 @@ class ApiSetNotificationTimestamp extends ApiBase {
foreach ( $pageSet->getInvalidTitles() as $title ) {
$r = array();
$r['title'] = $title;
- $r['invalid'] = '';
+ $r['invalid'] = true;
$result[] = $r;
}
foreach ( $pageSet->getMissingPageIDs() as $p ) {
$page = array();
$page['pageid'] = $p;
- $page['missing'] = '';
- $page['notwatched'] = '';
+ $page['missing'] = true;
+ $page['notwatched'] = true;
$result[] = $page;
}
foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
$rev = array();
$rev['revid'] = $r;
- $rev['missing'] = '';
- $rev['notwatched'] = '';
+ $rev['missing'] = true;
+ $rev['notwatched'] = true;
$result[] = $rev;
}
@@ -160,7 +163,7 @@ class ApiSetNotificationTimestamp extends ApiBase {
'title' => $title->getPrefixedText(),
);
if ( !$title->exists() ) {
- $r['missing'] = '';
+ $r['missing'] = true;
}
if ( isset( $timestamps[$ns] ) && array_key_exists( $dbkey, $timestamps[$ns] ) ) {
$r['notificationtimestamp'] = '';
@@ -168,17 +171,18 @@ class ApiSetNotificationTimestamp extends ApiBase {
$r['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $timestamps[$ns][$dbkey] );
}
} else {
- $r['notwatched'] = '';
+ $r['notwatched'] = true;
}
$result[] = $r;
}
}
- $apiResult->setIndexedTagName( $result, 'page' );
+ ApiResult::setIndexedTagName( $result, 'page' );
}
$apiResult->addValue( null, $this->getModuleName(), $result );
- $apiResult->endContinuation();
+ $this->setContinuationManager( null );
+ $continuationManager->setContinuationIntoResult( $apiResult );
}
/**
@@ -219,7 +223,9 @@ class ApiSetNotificationTimestamp extends ApiBase {
'newerthanrevid' => array(
ApiBase::PARAM_TYPE => 'integer'
),
- 'continue' => '',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
if ( $flags ) {
$result += $this->getPageSet()->getFinalParams( $flags );
@@ -228,34 +234,17 @@ class ApiSetNotificationTimestamp extends ApiBase {
return $result;
}
- public function getParamDescription() {
- return $this->getPageSet()->getFinalParamDescription() + array(
- 'entirewatchlist' => 'Work on all watched pages',
- 'timestamp' => 'Timestamp to which to set the notification timestamp',
- 'torevid' => 'Revision to set the notification timestamp to (one page only)',
- 'newerthanrevid' => 'Revision to set the notification timestamp newer than (one page only)',
- 'continue' => 'When more results are available, use this to continue',
- );
- }
-
- public function getDescription() {
- return array( 'Update the notification timestamp for watched pages.',
- 'This affects the highlighting of changed pages in the watchlist and history,',
- 'and the sending of email when the "Email me when a page on my watchlist is',
- 'changed" preference is enabled.'
- );
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=setnotificationtimestamp&entirewatchlist=&token=123ABC'
- => 'Reset the notification status for the entire watchlist',
- 'api.php?action=setnotificationtimestamp&titles=Main_page&token=123ABC'
- => 'Reset the notification status for "Main page"',
- 'api.php?action=setnotificationtimestamp&titles=Main_page&' .
+ 'action=setnotificationtimestamp&entirewatchlist=&token=123ABC'
+ => 'apihelp-setnotificationtimestamp-example-all',
+ 'action=setnotificationtimestamp&titles=Main_page&token=123ABC'
+ => 'apihelp-setnotificationtimestamp-example-page',
+ 'action=setnotificationtimestamp&titles=Main_page&' .
'timestamp=2012-01-01T00:00:00Z&token=123ABC'
- => 'Set the notification timestamp for "Main page" so all edits ' .
- 'since 1 January 2012 are unviewed',
+ => 'apihelp-setnotificationtimestamp-example-pagetimestamp',
+ 'action=setnotificationtimestamp&generator=allpages&gapnamespace=2&token=123ABC'
+ => 'apihelp-setnotificationtimestamp-example-allpages',
);
}
diff --git a/includes/api/ApiStashEdit.php b/includes/api/ApiStashEdit.php
new file mode 100644
index 00000000..c4b717c7
--- /dev/null
+++ b/includes/api/ApiStashEdit.php
@@ -0,0 +1,412 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Aaron Schulz
+ */
+
+/**
+ * Prepare and edit in shared cache so that it can be reused on edit
+ *
+ * This endpoint can be called via AJAX as the user focuses on the edit
+ * summary box. By the time of submission, the parse may have already
+ * finished, and can be immediately used on page save. Certain parser
+ * functions like {{REVISIONID}} or {{CURRENTTIME}} may cause the cache
+ * to not be used on edit. Template and files used are check for changes
+ * since the output was generated. The cache TTL is also kept low for sanity.
+ *
+ * @ingroup API
+ * @since 1.25
+ */
+class ApiStashEdit extends ApiBase {
+ const ERROR_NONE = 'stashed';
+ const ERROR_PARSE = 'error_parse';
+ const ERROR_CACHE = 'error_cache';
+ const ERROR_UNCACHEABLE = 'uncacheable';
+
+ public function execute() {
+ global $wgMemc;
+
+ $user = $this->getUser();
+ $params = $this->extractRequestParams();
+
+ $page = $this->getTitleOrPageId( $params );
+ $title = $page->getTitle();
+
+ if ( !ContentHandler::getForModelID( $params['contentmodel'] )
+ ->isSupportedFormat( $params['contentformat'] )
+ ) {
+ $this->dieUsage( "Unsupported content model/format", 'badmodelformat' );
+ }
+
+ // Trim and fix newlines so the key SHA1's match (see RequestContext::getText())
+ $text = rtrim( str_replace( "\r\n", "\n", $params['text'] ) );
+ $textContent = ContentHandler::makeContent(
+ $text, $title, $params['contentmodel'], $params['contentformat'] );
+
+ $page = WikiPage::factory( $title );
+ if ( $page->exists() ) {
+ // Page exists: get the merged content with the proposed change
+ $baseRev = Revision::newFromPageId( $page->getId(), $params['baserevid'] );
+ if ( !$baseRev ) {
+ $this->dieUsage( "No revision ID {$params['baserevid']}", 'missingrev' );
+ }
+ $currentRev = $page->getRevision();
+ if ( !$currentRev ) {
+ $this->dieUsage( "No current revision of page ID {$page->getId()}", 'missingrev' );
+ }
+ // Merge in the new version of the section to get the proposed version
+ $editContent = $page->replaceSectionAtRev(
+ $params['section'],
+ $textContent,
+ $params['sectiontitle'],
+ $baseRev->getId()
+ );
+ if ( !$editContent ) {
+ $this->dieUsage( "Could not merge updated section.", 'replacefailed' );
+ }
+ if ( $currentRev->getId() == $baseRev->getId() ) {
+ // Base revision was still the latest; nothing to merge
+ $content = $editContent;
+ } else {
+ // Merge the edit into the current version
+ $baseContent = $baseRev->getContent();
+ $currentContent = $currentRev->getContent();
+ if ( !$baseContent || !$currentContent ) {
+ $this->dieUsage( "Missing content for page ID {$page->getId()}", 'missingrev' );
+ }
+ $handler = ContentHandler::getForModelID( $baseContent->getModel() );
+ $content = $handler->merge3( $baseContent, $editContent, $currentContent );
+ }
+ } else {
+ // New pages: use the user-provided content model
+ $content = $textContent;
+ }
+
+ if ( !$content ) { // merge3() failed
+ $this->getResult()->addValue( null,
+ $this->getModuleName(), array( 'status' => 'editconflict' ) );
+ return;
+ }
+
+ // The user will abort the AJAX request by pressing "save", so ignore that
+ ignore_user_abort( true );
+
+ // Get a key based on the source text, format, and user preferences
+ $key = self::getStashKey( $title, $content, $user );
+ // De-duplicate requests on the same key
+ if ( $user->pingLimiter( 'stashedit' ) ) {
+ $status = 'ratelimited';
+ } elseif ( $wgMemc->lock( $key, 0, 30 ) ) {
+ $unlocker = new ScopedCallback( function() use ( $key ) {
+ global $wgMemc;
+ $wgMemc->unlock( $key );
+ } );
+ $status = self::parseAndStash( $page, $content, $user );
+ } else {
+ $status = 'busy';
+ }
+
+ $this->getResult()->addValue( null, $this->getModuleName(), array( 'status' => $status ) );
+ }
+
+ /**
+ * @param WikiPage $page
+ * @param Content $content
+ * @param User $user
+ * @return integer ApiStashEdit::ERROR_* constant
+ * @since 1.25
+ */
+ public static function parseAndStash( WikiPage $page, Content $content, User $user ) {
+ global $wgMemc;
+
+ $format = $content->getDefaultFormat();
+ $editInfo = $page->prepareContentForEdit( $content, null, $user, $format, false );
+
+ if ( $editInfo && $editInfo->output ) {
+ $key = self::getStashKey( $page->getTitle(), $content, $user );
+
+ list( $stashInfo, $ttl ) = self::buildStashValue(
+ $editInfo->pstContent, $editInfo->output, $editInfo->timestamp
+ );
+
+ if ( $stashInfo ) {
+ $ok = $wgMemc->set( $key, $stashInfo, $ttl );
+ if ( $ok ) {
+ wfDebugLog( 'StashEdit', "Cached parser output for key '$key'." );
+ return self::ERROR_NONE;
+ } else {
+ wfDebugLog( 'StashEdit', "Failed to cache parser output for key '$key'." );
+ return self::ERROR_CACHE;
+ }
+ } else {
+ wfDebugLog( 'StashEdit', "Uncacheable parser output for key '$key'." );
+ return self::ERROR_UNCACHEABLE;
+ }
+ }
+
+ return self::ERROR_PARSE;
+ }
+
+ /**
+ * Attempt to cache PST content and corresponding parser output in passing
+ *
+ * This method can be called when the output was already generated for other
+ * reasons. Parsing should not be done just to call this method, however.
+ * $pstOpts must be that of the user doing the edit preview. If $pOpts does
+ * not match the options of WikiPage::makeParserOptions( 'canonical' ), this
+ * will do nothing. Provided the values are cacheable, they will be stored
+ * in memcached so that final edit submission might make use of them.
+ *
+ * @param Article|WikiPage $page Page title
+ * @param Content $content Proposed page content
+ * @param Content $pstContent The result of preSaveTransform() on $content
+ * @param ParserOutput $pOut The result of getParserOutput() on $pstContent
+ * @param ParserOptions $pstOpts Options for $pstContent (MUST be for prospective author)
+ * @param ParserOptions $pOpts Options for $pOut
+ * @param string $timestamp TS_MW timestamp of parser output generation
+ * @return bool Success
+ */
+ public static function stashEditFromPreview(
+ Page $page, Content $content, Content $pstContent, ParserOutput $pOut,
+ ParserOptions $pstOpts, ParserOptions $pOpts, $timestamp
+ ) {
+ global $wgMemc;
+
+ // getIsPreview() controls parser function behavior that references things
+ // like user/revision that don't exists yet. The user/text should already
+ // be set correctly by callers, just double check the preview flag.
+ if ( !$pOpts->getIsPreview() ) {
+ return false; // sanity
+ } elseif ( $pOpts->getIsSectionPreview() ) {
+ return false; // short-circuit (need the full content)
+ }
+
+ // PST parser options are for the user (handles signatures, etc...)
+ $user = $pstOpts->getUser();
+ // Get a key based on the source text, format, and user preferences
+ $key = self::getStashKey( $page->getTitle(), $content, $user );
+
+ // Parser output options must match cannonical options.
+ // Treat some options as matching that are different but don't matter.
+ $canonicalPOpts = $page->makeParserOptions( 'canonical' );
+ $canonicalPOpts->setIsPreview( true ); // force match
+ $canonicalPOpts->setTimestamp( $pOpts->getTimestamp() ); // force match
+ if ( !$pOpts->matches( $canonicalPOpts ) ) {
+ wfDebugLog( 'StashEdit', "Uncacheable preview output for key '$key' (options)." );
+ return false;
+ }
+
+ // Build a value to cache with a proper TTL
+ list( $stashInfo, $ttl ) = self::buildStashValue( $pstContent, $pOut, $timestamp );
+ if ( !$stashInfo ) {
+ wfDebugLog( 'StashEdit', "Uncacheable parser output for key '$key' (rev/TTL)." );
+ return false;
+ }
+
+ $ok = $wgMemc->set( $key, $stashInfo, $ttl );
+ if ( !$ok ) {
+ wfDebugLog( 'StashEdit', "Failed to cache preview parser output for key '$key'." );
+ } else {
+ wfDebugLog( 'StashEdit', "Cached preview output for key '$key'." );
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Check that a prepared edit is in cache and still up-to-date
+ *
+ * This method blocks if the prepared edit is already being rendered,
+ * waiting until rendering finishes before doing final validity checks.
+ *
+ * The cache is rejected if template or file changes are detected.
+ * Note that foreign template or file transclusions are not checked.
+ *
+ * The result is a map (pstContent,output,timestamp) with fields
+ * extracted directly from WikiPage::prepareContentForEdit().
+ *
+ * @param Title $title
+ * @param Content $content
+ * @param User $user User to get parser options from
+ * @return stdClass|bool Returns false on cache miss
+ */
+ public static function checkCache( Title $title, Content $content, User $user ) {
+ global $wgMemc;
+
+ $key = self::getStashKey( $title, $content, $user );
+ $editInfo = $wgMemc->get( $key );
+ if ( !is_object( $editInfo ) ) {
+ $start = microtime( true );
+ // We ignore user aborts and keep parsing. Block on any prior parsing
+ // so as to use it's results and make use of the time spent parsing.
+ if ( $wgMemc->lock( $key, 30, 30 ) ) {
+ $editInfo = $wgMemc->get( $key );
+ $wgMemc->unlock( $key );
+ }
+ $sec = microtime( true ) - $start;
+ if ( $sec > .01 ) {
+ wfDebugLog( 'StashEdit', "Waited $sec seconds on '$key'." );
+ }
+ }
+
+ if ( !is_object( $editInfo ) || !$editInfo->output ) {
+ wfDebugLog( 'StashEdit', "No cache value for key '$key'." );
+ return false;
+ }
+
+ $time = wfTimestamp( TS_UNIX, $editInfo->output->getTimestamp() );
+ if ( ( time() - $time ) <= 3 ) {
+ wfDebugLog( 'StashEdit', "Timestamp-based cache hit for key '$key'." );
+ return $editInfo; // assume nothing changed
+ }
+
+ $dbr = wfGetDB( DB_SLAVE );
+ // Check that no templates used in the output changed...
+ $cWhr = array(); // conditions to find changes/creations
+ $dWhr = array(); // conditions to find deletions
+ foreach ( $editInfo->output->getTemplateIds() as $ns => $stuff ) {
+ foreach ( $stuff as $dbkey => $revId ) {
+ $cWhr[] = array( 'page_namespace' => $ns, 'page_title' => $dbkey,
+ 'page_latest != ' . intval( $revId ) );
+ $dWhr[] = array( 'page_namespace' => $ns, 'page_title' => $dbkey );
+ }
+ }
+ $change = $dbr->selectField( 'page', '1', $dbr->makeList( $cWhr, LIST_OR ), __METHOD__ );
+ $n = $dbr->selectField( 'page', 'COUNT(*)', $dbr->makeList( $dWhr, LIST_OR ), __METHOD__ );
+ if ( $change || $n != count( $dWhr ) ) {
+ wfDebugLog( 'StashEdit', "Stale cache for key '$key'; template changed." );
+ return false;
+ }
+
+ // Check that no files used in the output changed...
+ $cWhr = array(); // conditions to find changes/creations
+ $dWhr = array(); // conditions to find deletions
+ foreach ( $editInfo->output->getFileSearchOptions() as $name => $options ) {
+ $cWhr[] = array( 'img_name' => $dbkey,
+ 'img_sha1 != ' . $dbr->addQuotes( strval( $options['sha1'] ) ) );
+ $dWhr[] = array( 'img_name' => $dbkey );
+ }
+ $change = $dbr->selectField( 'image', '1', $dbr->makeList( $cWhr, LIST_OR ), __METHOD__ );
+ $n = $dbr->selectField( 'image', 'COUNT(*)', $dbr->makeList( $dWhr, LIST_OR ), __METHOD__ );
+ if ( $change || $n != count( $dWhr ) ) {
+ wfDebugLog( 'StashEdit', "Stale cache for key '$key'; file changed." );
+ return false;
+ }
+
+ wfDebugLog( 'StashEdit', "Cache hit for key '$key'." );
+
+ return $editInfo;
+ }
+
+ /**
+ * Get the temporary prepared edit stash key for a user
+ *
+ * This key can be used for caching prepared edits provided:
+ * - a) The $user was used for PST options
+ * - b) The parser output was made from the PST using cannonical matching options
+ *
+ * @param Title $title
+ * @param Content $content
+ * @param User $user User to get parser options from
+ * @return string
+ */
+ protected static function getStashKey( Title $title, Content $content, User $user ) {
+ $hash = sha1( implode( ':', array(
+ $content->getModel(),
+ $content->getDefaultFormat(),
+ sha1( $content->serialize( $content->getDefaultFormat() ) ),
+ $user->getId() ?: md5( $user->getName() ), // account for user parser options
+ $user->getId() ? $user->getTouched() : '-' // handle preference change races
+ ) ) );
+
+ return wfMemcKey( 'prepared-edit', md5( $title->getPrefixedDBkey() ), $hash );
+ }
+
+ /**
+ * Build a value to store in memcached based on the PST content and parser output
+ *
+ * This makes a simple version of WikiPage::prepareContentForEdit() as stash info
+ *
+ * @param Content $pstContent
+ * @param ParserOutput $parserOutput
+ * @param string $timestamp TS_MW
+ * @return array (stash info array, TTL in seconds) or (null, 0)
+ */
+ protected static function buildStashValue(
+ Content $pstContent, ParserOutput $parserOutput, $timestamp
+ ) {
+ // If an item is renewed, mind the cache TTL determined by config and parser functions
+ $since = time() - wfTimestamp( TS_UNIX, $parserOutput->getTimestamp() );
+ $ttl = min( $parserOutput->getCacheExpiry() - $since, 5 * 60 );
+
+ if ( $ttl > 0 && !$parserOutput->getFlag( 'vary-revision' ) ) {
+ // Only store what is actually needed
+ $stashInfo = (object)array(
+ 'pstContent' => $pstContent,
+ 'output' => $parserOutput,
+ 'timestamp' => $timestamp
+ );
+ return array( $stashInfo, $ttl );
+ }
+
+ return array( null, 0 );
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'title' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'section' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ),
+ 'sectiontitle' => array(
+ ApiBase::PARAM_TYPE => 'string'
+ ),
+ 'text' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'contentmodel' => array(
+ ApiBase::PARAM_TYPE => ContentHandler::getContentModels(),
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'contentformat' => array(
+ ApiBase::PARAM_TYPE => ContentHandler::getAllContentFormats(),
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'baserevid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_REQUIRED => true
+ )
+ );
+ }
+
+ function needsToken() {
+ return 'csrf';
+ }
+
+ function mustBePosted() {
+ return true;
+ }
+
+ function isInternal() {
+ return true;
+ }
+}
diff --git a/includes/api/ApiTag.php b/includes/api/ApiTag.php
new file mode 100644
index 00000000..527c6cb1
--- /dev/null
+++ b/includes/api/ApiTag.php
@@ -0,0 +1,177 @@
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup API
+ * @since 1.25
+ */
+class ApiTag extends ApiBase {
+
+ protected function getAvailableTags() {
+ return ChangeTags::listExplicitlyDefinedTags();
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ // make sure the user is allowed
+ if ( !$this->getUser()->isAllowed( 'changetags' ) ) {
+ $this->dieUsage( "You don't have permission to add or remove change tags from individual edits",
+ 'permissiondenied' );
+ }
+
+ // validate and process each revid, rcid and logid
+ $this->requireAtLeastOneParameter( $params, 'revid', 'rcid', 'logid' );
+ $ret = array();
+ if ( $params['revid'] ) {
+ foreach ( $params['revid'] as $id ) {
+ $ret[] = $this->processIndividual( 'revid', $params, $id );
+ }
+ }
+ if ( $params['rcid'] ) {
+ foreach ( $params['rcid'] as $id ) {
+ $ret[] = $this->processIndividual( 'rcid', $params, $id );
+ }
+ }
+ if ( $params['logid'] ) {
+ foreach ( $params['logid'] as $id ) {
+ $ret[] = $this->processIndividual( 'logid', $params, $id );
+ }
+ }
+
+ ApiResult::setIndexedTagName( $ret, 'result' );
+ $this->getResult()->addValue( null, $this->getModuleName(), $ret );
+ }
+
+ protected static function validateLogId( $logid ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ $result = $dbr->selectField( 'logging', 'log_id', array( 'log_id' => $logid ),
+ __METHOD__ );
+ return (bool)$result;
+ }
+
+ protected function processIndividual( $type, $params, $id ) {
+ $idResult = array( $type => $id );
+
+ // validate the ID
+ $valid = false;
+ switch ( $type ) {
+ case 'rcid':
+ $valid = RecentChange::newFromId( $id );
+ break;
+ case 'revid':
+ $valid = Revision::newFromId( $id );
+ break;
+ case 'logid':
+ $valid = self::validateLogId( $id );
+ break;
+ }
+
+ if ( !$valid ) {
+ $idResult['status'] = 'error';
+ $idResult += $this->parseMsg( array( "nosuch$type", $id ) );
+ return $idResult;
+ }
+
+ $status = ChangeTags::updateTagsWithChecks( $params['add'],
+ $params['remove'],
+ ( $type === 'rcid' ? $id : null ),
+ ( $type === 'revid' ? $id : null ),
+ ( $type === 'logid' ? $id : null ),
+ null,
+ $params['reason'],
+ $this->getUser() );
+
+ if ( !$status->isOK() ) {
+ if ( $status->hasMessage( 'actionthrottledtext' ) ) {
+ $idResult['status'] = 'skipped';
+ } else {
+ $idResult['status'] = 'failure';
+ $idResult['errors'] = $this->getErrorFormatter()->arrayFromStatus( $status, 'error' );
+ }
+ } else {
+ $idResult['status'] = 'success';
+ if ( is_null( $status->value->logId ) ) {
+ $idResult['noop'] = '';
+ } else {
+ $idResult['actionlogid'] = $status->value->logId;
+ $idResult['added'] = $status->value->addedTags;
+ ApiResult::setIndexedTagName( $idResult['added'], 't' );
+ $idResult['removed'] = $status->value->removedTags;
+ ApiResult::setIndexedTagName( $idResult['removed'], 't' );
+ }
+ }
+ return $idResult;
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'rcid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'revid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'logid' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'add' => array(
+ ApiBase::PARAM_TYPE => $this->getAvailableTags(),
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'remove' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_ISMULTI => true,
+ ),
+ 'reason' => array(
+ ApiBase::PARAM_DFLT => '',
+ ),
+ );
+ }
+
+ public function needsToken() {
+ return 'csrf';
+ }
+
+ protected function getExamplesMessages() {
+ return array(
+ 'action=tag&revid=123&add=vandalism&token=123ABC'
+ => 'apihelp-tag-example-rev',
+ 'action=tag&logid=123&remove=spam&reason=Wrongly+applied&token=123ABC'
+ => 'apihelp-tag-example-log',
+ );
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Tag';
+ }
+}
diff --git a/includes/api/ApiTokens.php b/includes/api/ApiTokens.php
index 9287fe6e..4d7fc5a0 100644
--- a/includes/api/ApiTokens.php
+++ b/includes/api/ApiTokens.php
@@ -34,9 +34,12 @@ class ApiTokens extends ApiBase {
$this->setWarning(
"action=tokens has been deprecated. Please use action=query&meta=tokens instead."
);
+ $this->logFeatureUsage( "action=tokens" );
$params = $this->extractRequestParams();
- $res = array();
+ $res = array(
+ ApiResult::META_TYPE => 'assoc',
+ );
$types = $this->getTokenTypes();
foreach ( $params['type'] as $type ) {
@@ -53,8 +56,9 @@ class ApiTokens extends ApiBase {
}
private function getTokenTypes() {
- // If we're in JSON callback mode, no tokens can be obtained
- if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
+ // If we're in a mode that breaks the same-origin policy, no tokens can
+ // be obtained
+ if ( $this->lacksSameOriginSecurity() ) {
return array();
}
@@ -62,20 +66,22 @@ class ApiTokens extends ApiBase {
if ( $types ) {
return $types;
}
- wfProfileIn( __METHOD__ );
$types = array( 'patrol' => array( 'ApiQueryRecentChanges', 'getPatrolToken' ) );
$names = array( 'edit', 'delete', 'protect', 'move', 'block', 'unblock',
'email', 'import', 'watch', 'options' );
foreach ( $names as $name ) {
$types[$name] = array( 'ApiQueryInfo', 'get' . ucfirst( $name ) . 'Token' );
}
- wfRunHooks( 'ApiTokensGetTokenTypes', array( &$types ) );
+ Hooks::run( 'ApiTokensGetTokenTypes', array( &$types ) );
ksort( $types );
- wfProfileOut( __METHOD__ );
return $types;
}
+ public function isDeprecated() {
+ return true;
+ }
+
public function getAllowedParams() {
return array(
'type' => array(
@@ -86,23 +92,12 @@ class ApiTokens extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'type' => 'Type of token(s) to request'
- );
- }
-
- public function getDescription() {
- return array(
- 'This module is deprecated in favor of action=query&meta=tokens.',
- 'Gets tokens for data-modifying actions.'
- );
- }
-
- protected function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=tokens' => 'Retrieve an edit token (the default)',
- 'api.php?action=tokens&type=email|move' => 'Retrieve an email token and a move token'
+ 'action=tokens'
+ => 'apihelp-tokens-example-edit',
+ 'action=tokens&type=email|move'
+ => 'apihelp-tokens-example-emailmove',
);
}
}
diff --git a/includes/api/ApiUnblock.php b/includes/api/ApiUnblock.php
index 2854a825..1af83ba3 100644
--- a/includes/api/ApiUnblock.php
+++ b/includes/api/ApiUnblock.php
@@ -93,30 +93,16 @@ class ApiUnblock extends ApiBase {
);
}
- public function getParamDescription() {
- $p = $this->getModulePrefix();
-
- return array(
- 'id' => "ID of the block you want to unblock (obtained through list=blocks). " .
- "Cannot be used together with {$p}user",
- 'user' => "Username, IP address or IP range you want to unblock. " .
- "Cannot be used together with {$p}id",
- 'reason' => 'Reason for unblock',
- );
- }
-
- public function getDescription() {
- return 'Unblock a user.';
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=unblock&id=105',
- 'api.php?action=unblock&user=Bob&reason=Sorry%20Bob'
+ 'action=unblock&id=105'
+ => 'apihelp-unblock-example-id',
+ 'action=unblock&user=Bob&reason=Sorry%20Bob'
+ => 'apihelp-unblock-example-user',
);
}
diff --git a/includes/api/ApiUndelete.php b/includes/api/ApiUndelete.php
index 07aad9f5..c23e9ff6 100644
--- a/includes/api/ApiUndelete.php
+++ b/includes/api/ApiUndelete.php
@@ -69,7 +69,7 @@ class ApiUndelete extends ApiBase {
}
if ( $retval[1] ) {
- wfRunHooks( 'FileUndeleteComplete',
+ Hooks::run( 'FileUndeleteComplete',
array( $titleObj, $params['fileids'], $this->getUser(), $params['reason'] ) );
}
@@ -117,39 +117,17 @@ class ApiUndelete extends ApiBase {
);
}
- public function getParamDescription() {
- return array(
- 'title' => 'Title of the page you want to restore',
- 'reason' => 'Reason for restoring',
- 'timestamps' => array(
- 'Timestamps of the revisions to restore.',
- 'If both timestamps and fileids are empty, all will be restored.',
- ),
- 'fileids' => array(
- 'IDs of the file revisions to restore.',
- 'If both timestamps and fileids are empty, all will be restored.',
- ),
- 'watchlist' => 'Unconditionally add or remove the page from your ' .
- 'watchlist, use preferences or do not change watch',
- );
- }
-
- public function getDescription() {
- return array(
- 'Restore certain revisions of a deleted page. A list of deleted revisions ',
- '(including timestamps) can be retrieved through list=deletedrevs, and a list',
- 'of deleted file ids can be retrieved through list=filearchive.'
- );
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=undelete&title=Main%20Page&token=123ABC&reason=Restoring%20main%20page',
- 'api.php?action=undelete&title=Main%20Page&token=123ABC&timestamps=20070703220045|20070702194856'
+ 'action=undelete&title=Main%20Page&token=123ABC&reason=Restoring%20main%20page'
+ => 'apihelp-undelete-example-page',
+ 'action=undelete&title=Main%20Page&token=123ABC' .
+ '&timestamps=2007-07-03T22:00:45Z|2007-07-02T19:48:56Z'
+ => 'apihelp-undelete-example-revisions',
);
}
diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php
index 657181b7..74ae05a8 100644
--- a/includes/api/ApiUpload.php
+++ b/includes/api/ApiUpload.php
@@ -64,7 +64,7 @@ class ApiUpload extends ApiBase {
$this->dieUsage( 'No upload module set', 'nomodule' );
}
} catch ( UploadStashException $e ) { // XXX: don't spam exception log
- $this->dieUsage( get_class( $e ) . ": " . $e->getMessage(), 'stasherror' );
+ $this->handleStashException( $e );
}
// First check permission to upload
@@ -112,7 +112,7 @@ class ApiUpload extends ApiBase {
$result['imageinfo'] = $this->mUpload->getImageInfo( $this->getResult() );
}
} catch ( UploadStashException $e ) { // XXX: don't spam exception log
- $this->dieUsage( get_class( $e ) . ": " . $e->getMessage(), 'stasherror' );
+ $this->handleStashException( $e );
}
$this->getResult()->addValue( null, $this->getModuleName(), $result );
@@ -159,7 +159,9 @@ class ApiUpload extends ApiBase {
if ( $warnings && count( $warnings ) > 0 ) {
$result['warnings'] = $warnings;
}
- } catch ( MWException $e ) {
+ } catch ( UploadStashException $e ) {
+ $this->handleStashException( $e );
+ } catch ( Exception $e ) {
$this->dieUsage( $e->getMessage(), 'stashfailed' );
}
@@ -180,7 +182,7 @@ class ApiUpload extends ApiBase {
try {
$result['filekey'] = $this->performStash();
$result['sessionkey'] = $result['filekey']; // backwards compatibility
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
$result['warnings']['stashfailed'] = $e->getMessage();
}
@@ -205,7 +207,9 @@ class ApiUpload extends ApiBase {
if ( $this->mParams['offset'] == 0 ) {
try {
$filekey = $this->performStash();
- } catch ( MWException $e ) {
+ } catch ( UploadStashException $e ) {
+ $this->handleStashException( $e );
+ } catch ( Exception $e ) {
// FIXME: Error handling here is wrong/different from rest of this
$this->dieUsage( $e->getMessage(), 'stashfailed' );
}
@@ -214,7 +218,11 @@ class ApiUpload extends ApiBase {
$status = $this->mUpload->addChunk(
$chunkPath, $chunkSize, $this->mParams['offset'] );
if ( !$status->isGood() ) {
- $this->dieUsage( $status->getWikiText(), 'stashfailed' );
+ $extradata = array(
+ 'offset' => $this->mUpload->getOffset(),
+ );
+
+ $this->dieUsage( $status->getWikiText(), 'stashfailed', 0, $extradata );
return array();
}
@@ -223,11 +231,12 @@ class ApiUpload extends ApiBase {
// Check we added the last chunk:
if ( $this->mParams['offset'] + $chunkSize == $this->mParams['filesize'] ) {
if ( $this->mParams['async'] ) {
- $progress = UploadBase::getSessionStatus( $filekey );
+ $progress = UploadBase::getSessionStatus( $this->getUser(), $filekey );
if ( $progress && $progress['result'] === 'Poll' ) {
$this->dieUsage( "Chunk assembly already in progress.", 'stashfailed' );
}
UploadBase::setSessionStatus(
+ $this->getUser(),
$filekey,
array( 'result' => 'Poll',
'stage' => 'queued', 'status' => Status::newGood() )
@@ -272,16 +281,17 @@ class ApiUpload extends ApiBase {
*/
private function performStash() {
try {
- $stashFile = $this->mUpload->stashFile();
+ $stashFile = $this->mUpload->stashFile( $this->getUser() );
if ( !$stashFile ) {
throw new MWException( 'Invalid stashed file' );
}
$fileKey = $stashFile->getFileKey();
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
$message = 'Stashing temporary file failed: ' . get_class( $e ) . ' ' . $e->getMessage();
wfDebug( __METHOD__ . ' ' . $message . "\n" );
- throw new MWException( $message );
+ $className = get_class( $e );
+ throw new $className( $message );
}
return $fileKey;
@@ -300,7 +310,7 @@ class ApiUpload extends ApiBase {
try {
$data['filekey'] = $this->performStash();
$data['sessionkey'] = $data['filekey'];
- } catch ( MWException $e ) {
+ } catch ( Exception $e ) {
$data['stashfailed'] = $e->getMessage();
}
$data['invalidparameter'] = $parameter;
@@ -327,7 +337,7 @@ class ApiUpload extends ApiBase {
// Status report for "upload to stash"/"upload from stash"
if ( $this->mParams['filekey'] && $this->mParams['checkstatus'] ) {
- $progress = UploadBase::getSessionStatus( $this->mParams['filekey'] );
+ $progress = UploadBase::getSessionStatus( $this->getUser(), $this->mParams['filekey'] );
if ( !$progress ) {
$this->dieUsage( 'No result in status data', 'missingresult' );
} elseif ( !$progress['status']->isGood() ) {
@@ -504,20 +514,20 @@ class ApiUpload extends ApiBase {
'filetype' => $verification['finalExt'],
'allowed' => array_values( array_unique( $this->getConfig()->get( 'FileExtensions' ) ) )
);
- $this->getResult()->setIndexedTagName( $extradata['allowed'], 'ext' );
+ ApiResult::setIndexedTagName( $extradata['allowed'], 'ext' );
$msg = "Filetype not permitted: ";
if ( isset( $verification['blacklistedExt'] ) ) {
$msg .= join( ', ', $verification['blacklistedExt'] );
$extradata['blacklisted'] = array_values( $verification['blacklistedExt'] );
- $this->getResult()->setIndexedTagName( $extradata['blacklisted'], 'ext' );
+ ApiResult::setIndexedTagName( $extradata['blacklisted'], 'ext' );
} else {
$msg .= $verification['finalExt'];
}
$this->dieUsage( $msg, 'filetype-banned', 0, $extradata );
break;
case UploadBase::VERIFICATION_ERROR:
- $this->getResult()->setIndexedTagName( $verification['details'], 'detail' );
+ ApiResult::setIndexedTagName( $verification['details'], 'detail' );
$this->dieUsage( 'This file did not pass file verification', 'verification-error',
0, array( 'details' => $verification['details'] ) );
break;
@@ -549,7 +559,7 @@ class ApiUpload extends ApiBase {
if ( $warnings ) {
// Add indices
$result = $this->getResult();
- $result->setIndexedTagName( $warnings, 'warning' );
+ ApiResult::setIndexedTagName( $warnings, 'warning' );
if ( isset( $warnings['duplicate'] ) ) {
$dupes = array();
@@ -557,7 +567,7 @@ class ApiUpload extends ApiBase {
foreach ( $warnings['duplicate'] as $dupe ) {
$dupes[] = $dupe->getName();
}
- $result->setIndexedTagName( $dupes, 'duplicate' );
+ ApiResult::setIndexedTagName( $dupes, 'duplicate' );
$warnings['duplicate'] = $dupes;
}
@@ -576,6 +586,41 @@ class ApiUpload extends ApiBase {
}
/**
+ * Handles a stash exception, giving a useful error to the user.
+ * @param Exception $e The exception we encountered.
+ */
+ protected function handleStashException( $e ) {
+ $exceptionType = get_class( $e );
+
+ switch ( $exceptionType ) {
+ case 'UploadStashFileNotFoundException':
+ $this->dieUsage( 'Could not find the file in the stash: ' . $e->getMessage(), 'stashedfilenotfound' );
+ break;
+ case 'UploadStashBadPathException':
+ $this->dieUsage( 'File key of improper format or otherwise invalid: ' . $e->getMessage(), 'stashpathinvalid' );
+ break;
+ case 'UploadStashFileException':
+ $this->dieUsage( 'Could not store upload in the stash: ' . $e->getMessage(), 'stashfilestorage' );
+ break;
+ case 'UploadStashZeroLengthFileException':
+ $this->dieUsage( 'File is of zero length, and could not be stored in the stash: ' . $e->getMessage(), 'stashzerolength' );
+ break;
+ case 'UploadStashNotLoggedInException':
+ $this->dieUsage( 'Not logged in: ' . $e->getMessage(), 'stashnotloggedin' );
+ break;
+ case 'UploadStashWrongOwnerException':
+ $this->dieUsage( 'Wrong owner: ' . $e->getMessage(), 'stashwrongowner' );
+ break;
+ case 'UploadStashNoSuchKeyException':
+ $this->dieUsage( 'No such filekey: ' . $e->getMessage(), 'stashnosuchfilekey' );
+ break;
+ default:
+ $this->dieUsage( $exceptionType . ": " . $e->getMessage(), 'stasherror' );
+ break;
+ }
+ }
+
+ /**
* Perform the actual upload. Returns a suitable result array on success;
* dies on failure.
*
@@ -612,11 +657,12 @@ class ApiUpload extends ApiBase {
// No errors, no warnings: do the upload
if ( $this->mParams['async'] ) {
- $progress = UploadBase::getSessionStatus( $this->mParams['filekey'] );
+ $progress = UploadBase::getSessionStatus( $this->getUser(), $this->mParams['filekey'] );
if ( $progress && $progress['result'] === 'Poll' ) {
$this->dieUsage( "Upload from stash already in progress.", 'publishfailed' );
}
UploadBase::setSessionStatus(
+ $this->getUser(),
$this->mParams['filekey'],
array( 'result' => 'Poll', 'stage' => 'queued', 'status' => Status::newGood() )
);
@@ -650,7 +696,7 @@ class ApiUpload extends ApiBase {
);
}
- $this->getResult()->setIndexedTagName( $error, 'error' );
+ ApiResult::setIndexedTagName( $error, 'error' );
$this->dieUsage( 'An internal error occurred', 'internal-error', 0, $error );
}
$result['result'] = 'Success';
@@ -730,59 +776,17 @@ class ApiUpload extends ApiBase {
return $params;
}
- public function getParamDescription() {
- $params = array(
- 'filename' => 'Target filename',
- 'comment' => 'Upload comment. Also used as the initial page text for new ' .
- 'files if "text" is not specified',
- 'text' => 'Initial page text for new files',
- 'watch' => 'Watch the page',
- 'watchlist' => 'Unconditionally add or remove the page from your watchlist, ' .
- 'use preferences or do not change watch',
- 'ignorewarnings' => 'Ignore any warnings',
- 'file' => 'File contents',
- 'url' => 'URL to fetch the file from',
- 'filekey' => 'Key that identifies a previous upload that was stashed temporarily.',
- 'sessionkey' => 'Same as filekey, maintained for backward compatibility.',
- 'stash' => 'If set, the server will not add the file to the repository ' .
- 'and stash it temporarily.',
-
- 'chunk' => 'Chunk contents',
- 'offset' => 'Offset of chunk in bytes',
- 'filesize' => 'Filesize of entire upload',
-
- 'async' => 'Make potentially large file operations asynchronous when possible',
- 'asyncdownload' => 'Make fetching a URL asynchronous',
- 'leavemessage' => 'If asyncdownload is used, leave a message on the user talk page if finished',
- 'statuskey' => 'Fetch the upload status for this file key (upload by URL)',
- 'checkstatus' => 'Only fetch the upload status for the given file key',
- );
-
- return $params;
- }
-
- public function getDescription() {
- return array(
- 'Upload a file, or get the status of pending uploads. Several methods are available:',
- ' * Upload file contents directly, using the "file" parameter',
- ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
- ' * Complete an earlier upload that failed due to warnings, using the "filekey" parameter',
- 'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
- 'sending the "file".',
- );
- }
-
public function needsToken() {
return 'csrf';
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=upload&filename=Wiki.png' .
- '&url=http%3A//upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png&token=123ABC'
- => 'Upload from a URL',
- 'api.php?action=upload&filename=Wiki.png&filekey=filekey&ignorewarnings=1&token=123ABC'
- => 'Complete an upload that failed due to warnings',
+ 'action=upload&filename=Wiki.png' .
+ '&url=http%3A//upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png&token=123ABC'
+ => 'apihelp-upload-example-url',
+ 'action=upload&filename=Wiki.png&filekey=filekey&ignorewarnings=1&token=123ABC'
+ => 'apihelp-upload-example-filekey',
);
}
diff --git a/includes/api/ApiUserrights.php b/includes/api/ApiUserrights.php
index c3ceb345..3ccdde25 100644
--- a/includes/api/ApiUserrights.php
+++ b/includes/api/ApiUserrights.php
@@ -32,12 +32,28 @@ class ApiUserrights extends ApiBase {
private $mUser = null;
+ /**
+ * Get a UserrightsPage object, or subclass.
+ * @return UserrightsPage
+ */
+ protected function getUserRightsPage() {
+ return new UserrightsPage;
+ }
+
+ /**
+ * Get all available groups.
+ * @return array
+ */
+ protected function getAllGroups() {
+ return User::getAllGroups();
+ }
+
public function execute() {
$params = $this->extractRequestParams();
$user = $this->getUrUser( $params );
- $form = new UserrightsPage;
+ $form = $this->getUserRightsPage();
$form->setContext( $this->getContext() );
$r['user'] = $user->getName();
$r['userid'] = $user->getId();
@@ -47,8 +63,8 @@ class ApiUserrights extends ApiBase {
);
$result = $this->getResult();
- $result->setIndexedTagName( $r['added'], 'group' );
- $result->setIndexedTagName( $r['removed'], 'group' );
+ ApiResult::setIndexedTagName( $r['added'], 'group' );
+ ApiResult::setIndexedTagName( $r['removed'], 'group' );
$result->addValue( null, $this->getModuleName(), $r );
}
@@ -65,7 +81,7 @@ class ApiUserrights extends ApiBase {
$user = isset( $params['user'] ) ? $params['user'] : '#' . $params['userid'];
- $form = new UserrightsPage;
+ $form = $this->getUserRightsPage();
$form->setContext( $this->getContext() );
$status = $form->fetchUser( $user );
if ( !$status->isOK() ) {
@@ -94,37 +110,23 @@ class ApiUserrights extends ApiBase {
ApiBase::PARAM_TYPE => 'integer',
),
'add' => array(
- ApiBase::PARAM_TYPE => User::getAllGroups(),
+ ApiBase::PARAM_TYPE => $this->getAllGroups(),
ApiBase::PARAM_ISMULTI => true
),
'remove' => array(
- ApiBase::PARAM_TYPE => User::getAllGroups(),
+ ApiBase::PARAM_TYPE => $this->getAllGroups(),
ApiBase::PARAM_ISMULTI => true
),
'reason' => array(
ApiBase::PARAM_DFLT => ''
- )
- );
- }
-
- public function getParamDescription() {
- return array(
- 'user' => 'User name',
- 'userid' => 'User id',
- 'add' => 'Add the user to these groups',
- 'remove' => 'Remove the user from these groups',
+ ),
'token' => array(
- /* Standard description automatically prepended */
- 'For compatibility, the token used in the web UI is also accepted.'
+ // Standard definition automatically inserted
+ ApiBase::PARAM_HELP_MSG_APPEND => array( 'api-help-param-token-webui' ),
),
- 'reason' => 'Reason for the change',
);
}
- public function getDescription() {
- return 'Add/remove a user to/from groups.';
- }
-
public function needsToken() {
return 'userrights';
}
@@ -133,10 +135,12 @@ class ApiUserrights extends ApiBase {
return $this->getUrUser( $params )->getName();
}
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC',
- 'api.php?action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
+ 'action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
+ => 'apihelp-userrights-example-user',
+ 'action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
+ => 'apihelp-userrights-example-userid',
);
}
diff --git a/includes/api/ApiWatch.php b/includes/api/ApiWatch.php
index e6a660b3..85d051de 100644
--- a/includes/api/ApiWatch.php
+++ b/includes/api/ApiWatch.php
@@ -44,7 +44,8 @@ class ApiWatch extends ApiBase {
$params = $this->extractRequestParams();
- $this->getResult()->beginContinuation( $params['continue'], array(), array() );
+ $continuationManager = new ApiContinuationManager( $this, array(), array() );
+ $this->setContinuationManager( $continuationManager );
$pageSet = $this->getPageSet();
// by default we use pageset to extract the page to work on.
@@ -69,7 +70,7 @@ class ApiWatch extends ApiBase {
$r = $this->watchTitle( $title, $user, $params );
$res[] = $r;
}
- $this->getResult()->setIndexedTagName( $res, 'w' );
+ ApiResult::setIndexedTagName( $res, 'w' );
} else {
// dont allow use of old title parameter with new pageset parameters.
$extraParams = array_keys( array_filter( $pageSet->extractRequestParams(), function ( $x ) {
@@ -92,7 +93,9 @@ class ApiWatch extends ApiBase {
$res = $this->watchTitle( $title, $user, $params, true );
}
$this->getResult()->addValue( null, $this->getModuleName(), $res );
- $this->getResult()->endContinuation();
+
+ $this->setContinuationManager( null );
+ $continuationManager->setContinuationIntoResult( $this->getResult() );
}
private function watchTitle( Title $title, User $user, array $params,
@@ -104,37 +107,22 @@ class ApiWatch extends ApiBase {
$res = array( 'title' => $title->getPrefixedText() );
- // Currently unnecessary, code to act as a safeguard against any change
- // in current behavior of uselang.
- // Copy from ApiParse
- $oldLang = null;
- if ( isset( $params['uselang'] ) &&
- $params['uselang'] != $this->getContext()->getLanguage()->getCode()
- ) {
- $oldLang = $this->getContext()->getLanguage(); // Backup language
- $this->getContext()->setLanguage( Language::factory( $params['uselang'] ) );
- }
-
if ( $params['unwatch'] ) {
$status = UnwatchAction::doUnwatch( $title, $user );
+ $res['unwatched'] = $status->isOK();
if ( $status->isOK() ) {
- $res['unwatched'] = '';
$res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
->title( $title )->parseAsBlock();
}
} else {
$status = WatchAction::doWatch( $title, $user );
+ $res['watched'] = $status->isOK();
if ( $status->isOK() ) {
- $res['watched'] = '';
$res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
->title( $title )->parseAsBlock();
}
}
- if ( !is_null( $oldLang ) ) {
- $this->getContext()->setLanguage( $oldLang ); // Reset language to $oldLang
- }
-
if ( !$status->isOK() ) {
if ( $compatibilityMode ) {
$this->dieStatus( $status );
@@ -176,8 +164,9 @@ class ApiWatch extends ApiBase {
ApiBase::PARAM_DEPRECATED => true
),
'unwatch' => false,
- 'uselang' => null,
- 'continue' => '',
+ 'continue' => array(
+ ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
+ ),
);
if ( $flags ) {
$result += $this->getPageSet()->getFinalParams( $flags );
@@ -186,25 +175,14 @@ class ApiWatch extends ApiBase {
return $result;
}
- public function getParamDescription() {
- $psModule = $this->getPageSet();
-
- return $psModule->getParamDescription() + array(
- 'title' => 'The page to (un)watch. use titles instead',
- 'unwatch' => 'If set the page will be unwatched rather than watched',
- 'uselang' => 'Language to show the message in',
- 'continue' => 'When more results are available, use this to continue',
- );
- }
-
- public function getDescription() {
- return 'Add or remove pages from/to the current user\'s watchlist.';
- }
-
- public function getExamples() {
+ protected function getExamplesMessages() {
return array(
- 'api.php?action=watch&titles=Main_Page' => 'Watch the page "Main Page"',
- 'api.php?action=watch&titles=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
+ 'action=watch&titles=Main_Page&token=123ABC'
+ => 'apihelp-watch-example-watch',
+ 'action=watch&titles=Main_Page&unwatch=&token=123ABC'
+ => 'apihelp-watch-example-unwatch',
+ 'action=watch&generator=allpages&gapnamespace=0&token=123ABC'
+ => 'apihelp-watch-example-generator',
);
}
diff --git a/includes/api/i18n/ar.json b/includes/api/i18n/ar.json
new file mode 100644
index 00000000..aa456f00
--- /dev/null
+++ b/includes/api/i18n/ar.json
@@ -0,0 +1,28 @@
+{
+ "@metadata": {
+ "authors": [
+ "Meno25",
+ "أحمد المحمودي",
+ "Khaled",
+ "Fatz"
+ ]
+ },
+ "apihelp-main-param-format": "صيغة الخرج.",
+ "apihelp-block-description": "منع مستخدم.",
+ "apihelp-block-param-reason": "السبب للمنع.",
+ "apihelp-block-param-nocreate": "امنع إنشاء الحسابات.",
+ "apihelp-compare-param-fromtitle": "العنوان الأول للمقارنة.",
+ "apihelp-compare-param-fromid": "رقم الصفحة الأول للمقارنة.",
+ "apihelp-compare-param-fromrev": "أول مراجعة للمقارنة.",
+ "apihelp-compare-param-totitle": "العنوان الثاني للمقارنة.",
+ "apihelp-compare-param-toid": "رقم الصفحة الثاني للمقارنة.",
+ "apihelp-compare-param-torev": "المراجعة الثانية للمقارنة.",
+ "apihelp-createaccount-param-name": "اسم المستخدم.",
+ "apihelp-delete-description": "حذف صفحة.",
+ "apihelp-delete-param-unwatch": "أزل الصفحة من قائمة مراقبتك.",
+ "apihelp-edit-description": "إنشاء وتعديل الصفحات.",
+ "apihelp-edit-param-watch": "أضف الصفحة إلى لائحة مراقبة المستعمل الحالي",
+ "apihelp-emailuser-description": "مراسلة المستخدم",
+ "apihelp-patrol-example-rcid": "ابحث عن تغيير جديد",
+ "apihelp-query+prefixsearch-param-offset": "عدد النتائج المراد تخطيها."
+}
diff --git a/includes/api/i18n/av.json b/includes/api/i18n/av.json
new file mode 100644
index 00000000..df85c0b6
--- /dev/null
+++ b/includes/api/i18n/av.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Аль-Гимравий"
+ ]
+ },
+ "apihelp-block-param-user": "Нужее блокалда лъезе бокьун вугев гІахьалчиясул цІар, IP-адрес яги IP-адресазул диапазон"
+}
diff --git a/includes/api/i18n/awa.json b/includes/api/i18n/awa.json
new file mode 100644
index 00000000..d0945921
--- /dev/null
+++ b/includes/api/i18n/awa.json
@@ -0,0 +1,11 @@
+{
+ "@metadata": {
+ "authors": [
+ "1AnuraagPandey"
+ ]
+ },
+ "apihelp-block-description": "सदस्य कय अवरोधित करा जाय।",
+ "apihelp-block-param-reason": "ब्लाक करेकै कारण",
+ "apihelp-block-param-nocreate": "खाते बनावेकै रोका जाय",
+ "apihelp-edit-param-minor": "छोट संपादन"
+}
diff --git a/includes/api/i18n/be-tarask.json b/includes/api/i18n/be-tarask.json
new file mode 100644
index 00000000..a09cb5ab
--- /dev/null
+++ b/includes/api/i18n/be-tarask.json
@@ -0,0 +1,55 @@
+{
+ "@metadata": {
+ "authors": [
+ "Red Winged Duck"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Дакумэнтацыя]]\n* [[mw:API:FAQ|Частыя пытаньні]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Сьпіс рассылкі]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-аб’явы]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Памылкі і запыты]\n</div>\n<strong>Статус:</strong> усе магчымасьці на гэтай старонцы павінны працаваць, але API знаходзіцца ў актыўнай распрацоўцы і можа зьмяняцца ў любы момант. Падпісвайцеся на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ рассылку mediawiki-api-announce] дзеля паведамленьняў пра абнаўленьні.\n\n<strong>Памылковыя запыты:</strong> калі да API дасылаюцца памылковыя запыты, HTTP-загаловак будзе дасланы з ключом «MediaWiki-API-Error», а потым значэньне загалоўку і код памылкі будуць выстаўленыя на аднолькавае значэньне. Дзеля дадатковай інфармацыі глядзіце [[mw:API:Errors_and_warnings|API: Памылкі і папярэджаньні]].",
+ "apihelp-main-param-action": "Дзеяньне для выкананьня.",
+ "apihelp-main-param-format": "Фармат вываду.",
+ "apihelp-main-param-maxlag": "Максымальная затрымка можа ўжывацца, калі MediaWiki ўсталяваная ў клястэр з рэплікаванай базай зьвестак. Дзеля захаваньня дзеяньняў, якія выклікаюць затрымку рэплікацыі, гэты парамэтар можа прымусіць кліента чакаць, пакуль затрымка рэплікацыі меншая за яго значэньне. У выпадку доўгай затрымкі, вяртаецца код памылкі <samp>maxlag</samp> з паведамленьнем кшталту <samp>Чаканьне $host: $lag сэкундаў затрымкі</samp>.<br />Глядзіце [[mw:Manual:Maxlag_parameter|Інструкцыя:Парамэтар maxlag]] дзеля дадатковай інфармацыі.",
+ "apihelp-main-param-smaxage": "Выстаўце загаловак <code>s-maxage</code> на зададзеную колькасьць сэкундаў. Памылкі ніколі не кэшуюцца.",
+ "apihelp-main-param-maxage": "Выстаўляе загаловак <code>max-age</code> на зададзеную колькасьць сэкундаў. Памылкі ніколі не кэшуюцца.",
+ "apihelp-main-param-assert": "Упэўніцеся, што ўдзельнік увайшоў у сыстэму, калі зададзена <kbd>user</kbd>, або мае правы робата, калі зададзена <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Любое значэньне, пададзенае тут, будзе ўключанае ў адказ. Можа быць выкарыстанае для адрозьненьня запытаў.",
+ "apihelp-main-param-servedby": "Уключае ў вынік назву сэрвэра, які апрацаваў запыт.",
+ "apihelp-main-param-curtimestamp": "Уключае ў вынік пазнаку актуальнага часу.",
+ "apihelp-main-param-origin": "Пры звароце да API з дапамогай міждамэннага AJAX-запыту (CORS), выстаўце парамэтру значэньне зыходнага дамэну. Ён мусіць быць уключаны ў кожны папярэдні запыт і такім чынам мусіць быць часткай URI-запыту (ня цела POST). Ён мусіць супадаць з адной з крыніц у загалоўку <code>Origin</code>, павінна быць зададзена нешта кшталту <kbd>https://en.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Калі парамэтар не супадае з загалоўкам <code>Origin</code>, будзе вернуты адказ з кодам памылкі 403. Калі парамэтар супадае з загалоўкам <code>Origin</code> і крыніца знаходзіцца ў белым сьпісе, будзе выстаўлены загаловак <code>Access-Control-Allow-Origin</code>.",
+ "apihelp-main-param-uselang": "Мова для выкарыстаньня ў перакладах паведамленьняў. Сьпіс кодаў можа быць атрыманы з <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> з <kbd>siprop=languages</kbd>, або трэба вызначыць <kbd>user</kbd>, каб ужываць наладкі мовы цяперашняга карыстальніка, або вызначыць <kbd>content</kbd>, каб ужываць мову зьместу гэтай вікі.",
+ "apihelp-block-description": "Блякаваньне ўдзельніка.",
+ "apihelp-block-param-user": "Імя ўдзельніка, IP-адрас або IP-дыяпазон, якія вы хочаце заблякаваць.",
+ "apihelp-block-param-expiry": "Час заканчэньня. Можа быць адносным (напрыклад, <kbd>5 months</kbd> або <kbd>2 weeks</kbd>) ці абсалютным (напрыклад, <kbd>2014-09-18T12:34:56Z</kbd>). Калі выстаўлены на <kbd>infinite</kbd>, <kbd>indefinite</kbd> ці <kbd>never</kbd>, блякаваньне будзе бестэрміновым.",
+ "apihelp-block-param-reason": "Прычына блякаваньня.",
+ "apihelp-block-param-anononly": "Заблякаваць толькі ананімных удзельнікаў (напрыклад, забараніць ананімныя праўкі з гэтага IP-адрасу).",
+ "apihelp-block-param-nocreate": "Забарона стварэньня рахункаў.",
+ "apihelp-block-param-autoblock": "Аўтаматычна блякаваць апошні ўжыты IP-адрас, а таксама ўсе наступныя IP-адрасы, зь якіх будуць спробы ўваходу.",
+ "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права <code>blockemail</code>).",
+ "apihelp-block-param-hidename": "Схаваць імя ўдзельніка з журналу блякаваньняў (патрабуе права <code>hideuser</code>).",
+ "apihelp-block-param-allowusertalk": "Дазволіць удзельніку рэдагаваць уласную старонку гутарак (залежыць ад <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Калі ўдзельнік ужо заблякаваны, перапісаць дзейнае блякаваньне.",
+ "apihelp-block-param-watchuser": "Назіраць за старонкай удзельніка або старонкай IP-адрасу, а таксама старонкай гутарак.",
+ "apihelp-block-example-ip-simple": "Заблякаваць IP-адрас <kbd>192.0.2.5</kbd> на тры дні з прычынай <kbd>First strike</kbd>.",
+ "apihelp-block-example-user-complex": "Заблякаваць удзельніка <kbd>Vandal</kbd> назаўсёды з прычынай <kbd>Vandalism</kbd>, а таксама забараніць стварэньне новых рахункаў і адсылку лістоў электроннай поштай.",
+ "apihelp-clearhasmsg-description": "Ачышчае сьцяг <code>hasmsg</code> для актуальнага карыстальніка.",
+ "apihelp-clearhasmsg-example-1": "Ачыстка сьцягу <code>hasmsg</code> для актуальнага карыстальніка",
+ "apihelp-compare-description": "Атрымаць розьніцу паміж 2 старонкамі.\n\nВы мусіце перадаць нумар вэрсіі, назву або ID старонкі для абодвух «from» і «to».",
+ "apihelp-compare-param-fromtitle": "Першая назва для параўнаньня.",
+ "apihelp-compare-param-fromid": "ID першай старонкі для параўнаньня.",
+ "apihelp-compare-param-fromrev": "Першая вэрсія для параўнаньня.",
+ "apihelp-compare-param-totitle": "Другая назва для параўнаньня.",
+ "apihelp-compare-param-toid": "ID другой старонкі для параўнаньня.",
+ "apihelp-compare-param-torev": "Другая вэрсія для параўнаньня.",
+ "apihelp-compare-example-1": "Паказвае розьніцу паміж вэрсіямі 1 і 2",
+ "apihelp-createaccount-description": "Стварэньне новага рахунку ўдзельніка.",
+ "apihelp-createaccount-param-name": "Імя ўдзельніка.",
+ "apihelp-createaccount-param-password": "Пароль (ігнаруецца, калі выстаўлена <var>$1mailpassword</var>).",
+ "apihelp-createaccount-param-domain": "Дамэн для вонкавай аўтэнтыфікацыі (неабавязкова).",
+ "apihelp-createaccount-param-token": "Маркер стварэньня рахунку, атрыманы пры першым запыце.",
+ "apihelp-createaccount-param-email": "Адрас электроннай пошты ўдзельніка (неабавязкова).",
+ "apihelp-createaccount-param-realname": "Сапраўднае імя ўдзельніка (неабавязкова).",
+ "apihelp-createaccount-param-mailpassword": "Калі ўсталяванае любое значэньне, выпадковы пароль будзе дасланы карыстальніку на электронную пошту.",
+ "apihelp-createaccount-param-reason": "Неабавязковая прычына стварэньня рахунку, якая будзе запісаная ў журнал.",
+ "apihelp-createaccount-param-language": "Моўны код, які будзе выстаўлены ўдзельніку па змоўчаньні (неабавязкова, па змоўчаньні мова зьместу).",
+ "apihelp-createaccount-example-pass": "Стварэньне ўдзельніка <kbd>testuser</kbd> з паролем <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Стварэньне ўдзельніка <kbd>testmailuser</kbd> і адпраўка выпадковага паролю электроннай поштай."
+}
diff --git a/includes/api/i18n/bn.json b/includes/api/i18n/bn.json
new file mode 100644
index 00000000..05407ff5
--- /dev/null
+++ b/includes/api/i18n/bn.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Aftabuzzaman"
+ ]
+ },
+ "apihelp-login-example-login": "প্রবেশ"
+}
diff --git a/includes/api/i18n/bs.json b/includes/api/i18n/bs.json
new file mode 100644
index 00000000..420e6ac0
--- /dev/null
+++ b/includes/api/i18n/bs.json
@@ -0,0 +1,16 @@
+{
+ "@metadata": {
+ "authors": [
+ "Palapa"
+ ]
+ },
+ "apihelp-main-param-action": "Koju akciju izvesti.",
+ "apihelp-main-param-format": "Format izlaza.",
+ "apihelp-block-description": "Blokiraj korisnika",
+ "apihelp-block-param-reason": "Razlog za blokadu",
+ "apihelp-block-example-ip-simple": "Blokiraj IP 192.0.2.5 na tri dana sa razlogom \"Prvi napad\"",
+ "apihelp-compare-param-fromtitle": "Prvi naslov za poređenje.",
+ "apihelp-delete-description": "Obriši stranicu.",
+ "apihelp-edit-param-text": "Sadržaj stranice.",
+ "apihelp-edit-param-minor": "Mala izmjena."
+}
diff --git a/includes/api/i18n/ca.json b/includes/api/i18n/ca.json
new file mode 100644
index 00000000..7aa17307
--- /dev/null
+++ b/includes/api/i18n/ca.json
@@ -0,0 +1,43 @@
+{
+ "@metadata": {
+ "authors": [
+ "Toniher",
+ "Macofe",
+ "Xavier Dengra"
+ ]
+ },
+ "apihelp-main-param-format": "El format de la sortida.",
+ "apihelp-block-description": "Bloca un usuari.",
+ "apihelp-block-param-reason": "Raó del blocatge.",
+ "apihelp-block-param-nocreate": "Evita la creació de comptes.",
+ "apihelp-createaccount-description": "Creeu un nou compte d'usuari.",
+ "apihelp-createaccount-param-name": "Nom d'usuari.",
+ "apihelp-createaccount-param-password": "Contrasenya (ignorada si es defineix <var>$1mailpassword</var>)",
+ "apihelp-createaccount-param-email": "Adreça electrònica de l'usuari (opcional).",
+ "apihelp-createaccount-param-realname": "Nom real de l'usuari (opcional).",
+ "apihelp-delete-description": "Suprimeix una pàgina.",
+ "apihelp-disabled-description": "Aquest mòdul ha estat desactivat.",
+ "apihelp-edit-description": "Crea i edita pàgines.",
+ "apihelp-edit-param-text": "Contingut de la pàgina.",
+ "apihelp-edit-param-minor": "Edició menor.",
+ "apihelp-edit-param-createonly": "No editeu aquesta pàgina si ja existeix.",
+ "apihelp-edit-example-edit": "Editeu una pàgina.",
+ "apihelp-emailuser-description": "Envieu un correu electrònic a un usuari.",
+ "apihelp-emailuser-param-target": "Usuari a qui enviar el correu.",
+ "apihelp-emailuser-param-text": "Cos del correu.",
+ "apihelp-emailuser-param-ccme": "Envia'm una còpia d'aquest correu electrònic.",
+ "apihelp-expandtemplates-param-title": "Títol de la pàgina.",
+ "apihelp-feedcontributions-param-deletedonly": "Mostra només les contribucions esborrades.",
+ "apihelp-feedrecentchanges-param-hideminor": "Amaga les edicions menors.",
+ "apihelp-feedrecentchanges-param-hidebots": "Amaga les edicions de bots.",
+ "apihelp-feedrecentchanges-param-hideanons": "Amaga les edicions anònimes.",
+ "apihelp-feedrecentchanges-param-hideliu": "Amaga les edicions d'usuaris registrats.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Amaga les edicions patrullades.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Amaga les meves edicions.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtra segons etiqueta.",
+ "apihelp-feedrecentchanges-param-target": "Mostra només els canvis de les pàgines enllaçades a aquesta pàgina.",
+ "apihelp-feedrecentchanges-example-simple": "Mostra els canvis recents.",
+ "apihelp-help-example-recursive": "Tota l'ajuda en una sola pàgina.",
+ "apihelp-import-param-rootpage": "Importa com a subpàgina d'aquesta pàgina.",
+ "apihelp-login-example-login": "Inicia sessió."
+}
diff --git a/includes/api/i18n/ce.json b/includes/api/i18n/ce.json
new file mode 100644
index 00000000..1d866ba6
--- /dev/null
+++ b/includes/api/i18n/ce.json
@@ -0,0 +1,12 @@
+{
+ "@metadata": {
+ "authors": [
+ "Умар"
+ ]
+ },
+ "apihelp-main-param-action": "Кхочушдан дезарг.",
+ "apihelp-main-param-format": "Гойту формат.",
+ "apihelp-main-param-curtimestamp": "Хилламийн юкъатоха ханна йолу билгало",
+ "apihelp-createaccount-param-name": "Декъашхочун цӀе.",
+ "apihelp-userrights-param-userid": "Декъашхочун ID."
+}
diff --git a/includes/api/i18n/cs.json b/includes/api/i18n/cs.json
new file mode 100644
index 00000000..059eb82e
--- /dev/null
+++ b/includes/api/i18n/cs.json
@@ -0,0 +1,223 @@
+{
+ "@metadata": {
+ "authors": [
+ "Mormegil",
+ "YjM",
+ "Juandev",
+ "Aktron",
+ "Cvanca"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentace]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-mailová konference]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Oznámení k API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Chyby a požadavky]\n</div>\n<strong>Stav:</strong> Všechny funkce uvedené na této stránce by měly fungovat, ale API se stále aktivně vyvíjí a může se kdykoli změnit. Upozornění na změny získáte přihlášením se k [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-mailové konferenci mediawiki-api-announce].\n\n<strong>Chybné požadavky:</strong> Pokud jsou do API zaslány chybné požadavky, bude vrácena HTTP hlavička s klíčem „MediaWiki-API-Error“ a hodnota této hlavičky a chybový kód budou nastaveny na stejnou hodnotu. Více informací najdete [[mw:API:Errors_and_warnings|v dokumentaci]].",
+ "apihelp-main-param-action": "Jaká akce se má provést.",
+ "apihelp-main-param-format": "Formát výstupu.",
+ "apihelp-main-param-maxlag": "Maximální zpoždění lze použít, když je MediaWiki nainstalováno na cluster s replikovanou databází. Abyste se vyhnuli zhoršování už tak špatného replikačního zpoždění, můžete tímto parametrem nechat klienta čekat, dokud replikační zpoždění neklesne pod uvedenou hodnotu. V případě příliš vysokého zpoždění se vrátí chybový kód „<samp>maxlag</samp>“ s hlášením typu „<samp>Waiting for $host: $lag seconds lagged</samp>“.<br />Více informací najdete v [[mw:Manual:Maxlag_parameter|příručce]].",
+ "apihelp-main-param-smaxage": "Nastaví hlavičku <code>s-maxage</code> na uvedený počet sekund. Chyby se nekešují nikdy.",
+ "apihelp-main-param-maxage": "Nastaví hlavičku <code>max-age</code> na uvedený počet sekund. Chyby se nekešují nikdy.",
+ "apihelp-main-param-assert": "Pokud je nastaveno na „<kbd>user</kbd>“, ověří, že je uživatel přihlášen, pokud je nastaveno na „<kbd>bot</kbd>“, ověří, že má oprávnění „bot“.",
+ "apihelp-main-param-requestid": "Libovolná zde uvedená hodnota bude zahrnuta v odpovědi. Lze použít pro rozlišení požadavků.",
+ "apihelp-main-param-servedby": "Zahrnout do odpovědi název hostitele, který požadavek obsloužil.",
+ "apihelp-main-param-curtimestamp": "Zahrnout do odpovědi aktuální časové razítko.",
+ "apihelp-main-param-origin": "Pokud k API přistupujete pomocí mezidoménového AJAXového požadavku (CORS), nastavte tento parametr na doménu původu. Musí být součástí všech předběžných požadavků, takže musí být součástí URI požadavku (nikoli těla POSTu). Hodnota musí přesně odpovídat jednomu z původů v hlavičce Origin:, takže musí být nastavena na něco jako http://en.wikipedia.org nebo https://meta.wikimedia.org. Pokud parametr neodpovídá hlavičce Origin:, bude vrácena odpověď 403. Pokud parametr odpovídá hlavičce Origin: a tento původ je na bílé listině, bude nastavena hlavička Access-Control-Allow-Origin.",
+ "apihelp-main-param-uselang": "Jazyk, který se má použít pro překlad hlášení. Seznam kódů lze načíst z <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> se <kbd>siprop=languages</kbd>, nebo zadejte „<kbd>user</kbd>“ pro použití předvoleného jazyka aktuálního uživatele či „<kbd>content</kbd>“ pro použití jazyka obsahu této wiki.",
+ "apihelp-block-description": "Zablokovat uživatele.",
+ "apihelp-block-param-user": "Uživatelské jméno, IP adresa nebo rozsah IP adres, které chcete zablokovat.",
+ "apihelp-block-param-reason": "Důvod bloku.",
+ "apihelp-block-param-anononly": "Zablokovat pouze anonymní uživatele (tj. zakázat editovat anonymně z této IP).",
+ "apihelp-block-param-nocreate": "Nedovolit registraci nových uživatelů.",
+ "apihelp-block-param-noemail": "Zakázat uživateli posílat e-maily prostřednictvím wiki. (Vyžaduje oprávnění „<code>blockemail</code>“.)",
+ "apihelp-block-param-hidename": "Skrýt uživatelské jméno v knize zablokování. (Vyžaduje oprávnění <code>hideuser</code>.)",
+ "apihelp-block-param-allowusertalk": "Povolit uživateli editovat svou vlastní diskusní stránku (závisí na <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Pokud již uživatel blokován je, přepsat současný blok.",
+ "apihelp-block-param-watchuser": "Sledovat stránku uživatele nebo IP adresy a jejich diskuzní stránky.",
+ "apihelp-block-example-ip-simple": "Na tři dny zablokovat IP adresu <kbd>192.0.2.5</kbd> s odůvodněním <kbd>First strike</kbd>.",
+ "apihelp-block-example-user-complex": "Trvale zablokovat uživatele <kbd>Vandal</kbd> s odůvodněním <kbd>Vandalism</kbd> a zabránit vytváření nových účtů a odesílání e-mailů.",
+ "apihelp-compare-description": "Vrátí rozdíl dvou stránek.\n\nVe „from“ a „to“ musíte zadat číslo revize, název stránky nebo ID stránky.",
+ "apihelp-compare-param-fromtitle": "Název první stránky k porovnání.",
+ "apihelp-compare-param-fromid": "ID první stránky k porovnání.",
+ "apihelp-compare-param-fromrev": "Číslo revize první stránky k porovnání.",
+ "apihelp-compare-param-totitle": "Název druhé stránky k porovnání.",
+ "apihelp-compare-param-toid": "ID druhé stránky k porovnání.",
+ "apihelp-compare-param-torev": "Číslo revize druhé stránky k porovnání.",
+ "apihelp-compare-example-1": "Porovnat revize 1 a 2.",
+ "apihelp-createaccount-description": "Vytvořit nový uživatelský účet.",
+ "apihelp-createaccount-param-name": "Uživatelské jméno.",
+ "apihelp-createaccount-param-password": "Heslo (ignorováno, pokud je nastaveno <var>$1mailpassword</var>).",
+ "apihelp-createaccount-param-domain": "Doména pro externí ověření (volitelné).",
+ "apihelp-createaccount-param-email": "E-mailová adresa uživatele (nepovinné).",
+ "apihelp-createaccount-param-realname": "Skutečné jméno uživatele (nepovinné).",
+ "apihelp-createaccount-param-mailpassword": "Pokud je nastaveno na libovolnou hodnotu, zašle se náhodně vygenerované heslo na e-mail uživatele.",
+ "apihelp-createaccount-param-reason": "Případný důvod pro vytvoření účtu, který se zaznamená do logu.",
+ "apihelp-createaccount-param-language": "Kód jazyka, který se má uživateli nastavit jako výchozí (volitelné, výchozí je jazyk obsahu).",
+ "apihelp-createaccount-example-pass": "Vytvořit uživatele <kbd>testuser</kbd> s heslem <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Vytvořit uživatele <kbd>testmailuser</kbd> a zaslat mu e-mail s náhodně vygenerovaným heslem.",
+ "apihelp-delete-description": "Smazat stránku.",
+ "apihelp-delete-param-title": "Název stránky, která se má smazat. Není možné použít společně s <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "ID stránky, která se má smazat. Není možné použít společně s <var>$1title</var>.",
+ "apihelp-delete-param-watch": "Přidat stránku na seznam sledovaných.",
+ "apihelp-delete-example-simple": "Smazat stránku <kbd>Main Page</kbd>.",
+ "apihelp-disabled-description": "Tento modul byl deaktivován.",
+ "apihelp-edit-description": "Vytvářet a upravovat stránky.",
+ "apihelp-edit-param-sectiontitle": "Název nové sekce.",
+ "apihelp-edit-param-text": "Obsah stránky.",
+ "apihelp-edit-param-minor": "Malá editace.",
+ "apihelp-edit-param-notminor": "Nemalá editace.",
+ "apihelp-edit-param-bot": "Označit tuto editaci jako editaci bota.",
+ "apihelp-edit-param-createonly": "Needitovat stránku, pokud již existuje.",
+ "apihelp-edit-param-nocreate": "Pokud stránka neexistuje, vrátit chybu.",
+ "apihelp-edit-param-watch": "Přidat stránku na seznam sledovaných.",
+ "apihelp-edit-param-unwatch": "Odstranit stránku ze seznamu sledovaných.",
+ "apihelp-edit-param-watchlist": "Bezpodmíněnečně přidat nebo odstranit stránku ze sledovaných stránek aktuálního uživatele, použít nastavení nebo neměnit sledování.",
+ "apihelp-edit-param-redirect": "Automaticky opravit přesměrování.",
+ "apihelp-edit-example-edit": "Upravit stránku.",
+ "apihelp-emailuser-description": "Poslat uživateli e-mail.",
+ "apihelp-emailuser-param-text": "Tělo zprávy.",
+ "apihelp-emailuser-param-ccme": "Odeslat mi kopii této zprávy.",
+ "apihelp-expandtemplates-param-text": "Wikitext k převedení.",
+ "apihelp-feedcontributions-description": "Vrátí kanál příspěvků uživatele.",
+ "apihelp-feedcontributions-param-feedformat": "Formát kanálu.",
+ "apihelp-feedcontributions-param-year": "Od roku (a dříve).",
+ "apihelp-feedcontributions-param-month": "Od měsíce (a dříve)",
+ "apihelp-feedcontributions-param-deletedonly": "Zobrazit pouze smazané příspěvky.",
+ "apihelp-feedrecentchanges-param-namespace": "Jmenný prostor, na který mají být výsledky omezeny.",
+ "apihelp-feedrecentchanges-param-from": "Zobrazit změny od",
+ "apihelp-feedrecentchanges-param-hideminor": "Skrýt drobné změny.",
+ "apihelp-feedrecentchanges-param-hidebots": "Skrýt úpravy provedené roboty.",
+ "apihelp-feedrecentchanges-param-hideanons": "Skrýt změny provedené anonymními uživateli.",
+ "apihelp-feedrecentchanges-param-hideliu": "Skrýt změny provedené registrovanými uživateli.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Skrýt prověřené změny.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Skrýt změny aktuálního uživatele.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtrovat podle značek.",
+ "apihelp-feedrecentchanges-param-target": "Zobrazit jen změny na stránkách odkazovaných z této stránky.",
+ "apihelp-feedrecentchanges-example-simple": "Zobrazit poslední změny.",
+ "apihelp-feedrecentchanges-example-30days": "Zobrazit poslední změny za 30 dní.",
+ "apihelp-filerevert-description": "Revertovat soubor na starší verzi.",
+ "apihelp-filerevert-param-filename": "Cílový název souboru, bez prefixu Soubor:",
+ "apihelp-filerevert-param-comment": "Vložit komentář.",
+ "apihelp-help-description": "Zobrazuje nápovědu k uvedeným modulům.",
+ "apihelp-help-param-modules": "Moduly, pro které se má zobrazit nápověda (hodnoty parametrů action= a format= nebo „main“). Submoduly lze zadávat pomocí „+“.",
+ "apihelp-help-param-submodules": "Zahrnout nápovědu pro podmoduly uvedeného modulu.",
+ "apihelp-help-param-recursivesubmodules": "Zahrnout nápovědu pro podmoduly rekurzivně.",
+ "apihelp-help-param-helpformat": "Formát výstupu nápovědy.",
+ "apihelp-help-param-wrap": "Obalit výstup do standardní struktury API odpovědi.",
+ "apihelp-help-param-toc": "Zahrnout v HTML výstupu tabulku obsahu.",
+ "apihelp-help-example-main": "Nápověda k hlavnímu modulu",
+ "apihelp-help-example-recursive": "Veškerá nápověda na jedné stránce",
+ "apihelp-help-example-help": "Nápověda k samotnému modulu nápovědy",
+ "apihelp-help-example-query": "Nápověda pro dva podmoduly query",
+ "apihelp-imagerotate-description": "Otočit jeden nebo více obrázků.",
+ "apihelp-import-param-summary": "Import shrnutí.",
+ "apihelp-import-param-xml": "Nahraný XML soubor.",
+ "apihelp-import-param-rootpage": "Importovat jako podstránku k této stránce.",
+ "apihelp-login-param-name": "Uživatelské jméno.",
+ "apihelp-login-param-password": "Heslo.",
+ "apihelp-login-param-domain": "Doména (volitelná)",
+ "apihelp-login-example-login": "Přihlášení",
+ "apihelp-logout-example-logout": "Odhlášení aktuálního uživatele.",
+ "apihelp-move-description": "Přesunout stránku.",
+ "apihelp-move-param-reason": "Důvod k přejmenování.",
+ "apihelp-move-param-movetalk": "Přejmenovat diskuzní stránku, pokud existuje.",
+ "apihelp-move-param-movesubpages": "Přejmenovat možné podstránky",
+ "apihelp-move-param-noredirect": "Nevytvářet přesměrování.",
+ "apihelp-move-param-watch": "Přidat stránku a přesměrování do sledovaných stránek aktuálního uživatele.",
+ "apihelp-move-param-unwatch": "Odstranit stránku a přesměrování ze sledovaných stránek současného uživatele.",
+ "apihelp-move-param-ignorewarnings": "Ignorovat všechna varování.",
+ "apihelp-opensearch-param-search": "Hledaný řetězec.",
+ "apihelp-opensearch-param-limit": "Maximální počet vrácených výsledků",
+ "apihelp-opensearch-param-namespace": "Jmenné prostory pro vyhledávání.",
+ "apihelp-opensearch-param-format": "Formát výstupu.",
+ "apihelp-opensearch-example-te": "Najít stránky začínající na „<kbd>Te</kbd>“.",
+ "apihelp-options-example-reset": "Vrátit všechna nastavení.",
+ "apihelp-parse-example-page": "Parsovat stránku.",
+ "apihelp-parse-example-text": "Parsovat wikitext.",
+ "apihelp-patrol-example-revid": "Prověřit revizi.",
+ "apihelp-protect-description": "Změnit úroveň zamčení stránky.",
+ "apihelp-protect-param-reason": "Důvod pro odemčení.",
+ "apihelp-protect-example-protect": "Zamknout stránku.",
+ "apihelp-query+alldeletedrevisions-description": "Seznam všech smazaných revizí od konkrétního uživatele nebo v konkrétním jmenném prostoru.",
+ "apihelp-query+alldeletedrevisions-example-user": "Seznam posledních 50 smazaných editací uživatele <kbd>Příklad<kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Seznam prvních 50 smazaných revizí v hlavním jmenném prostoru.",
+ "apihelp-query+allfileusages-description": "Zobrazit seznam všech použití souboru, včetně neexistujících.",
+ "apihelp-query+allfileusages-example-unique": "Zobrazit seznam unikátních názvů souborů.",
+ "apihelp-query+alllinks-example-generator": "Získat stránky obsahující odkazy.",
+ "apihelp-query+allpages-param-filterredir": "Které stránky uvést na seznam.",
+ "apihelp-query+allpages-param-minsize": "Omezit na stránky s určitým počtem bajtů.",
+ "apihelp-query+allpages-param-prtype": "Omezit jen na zamčené stránky.",
+ "apihelp-query+allpages-example-B": "Zobrazit seznam stránek začínajících na písmeno <kbd>B</kbd>.",
+ "apihelp-query+allredirects-description": "Seznam všech přesměrování pro jmenný prostor.",
+ "apihelp-query+allredirects-example-unique": "Seznam unikátních cílových stránek.",
+ "apihelp-query+allredirects-example-generator": "Získat stránky obsahující přesměrování.",
+ "apihelp-query+alltransclusions-example-unique": "Seznam unikátně vložených titulů.",
+ "apihelp-query+backlinks-example-simple": "Zobrazit odkazy na <kbd>Hlavní stránka</kbd>",
+ "apihelp-query+categorymembers-description": "Seznam všech stránek v dané kategorii.",
+ "apihelp-query+deletedrevisions-param-limit": "Maximální počet revizí pro zobrazení v seznamu.",
+ "apihelp-query+embeddedin-example-simple": "Zobrazit stránky, které obahují <kbd>Template:Stub</kbd>.",
+ "apihelp-query+filearchive-example-simple": "Zobrazit seznam všech smazaných souborů.",
+ "apihelp-query+filerepoinfo-example-simple": "Získat informace o souborových repozitářích.",
+ "apihelp-query+linkshere-example-generator": "Získat informace o stránkách, které odkazují na [[Hlavní Stránka|Hlavní stránku]].",
+ "apihelp-query+recentchanges-example-simple": "Seznam posledních změn.",
+ "apihelp-query+tags-example-simple": "Získat seznam dostupných tagů.",
+ "apihelp-query+usercontribs-example-user": "Zobrazit příspěvky uživatele <kbd>Příklad</kbd>",
+ "apihelp-query+watchlistraw-description": "Získat všechny stránky, které jsou aktuálním uživatelem sledovány.",
+ "apihelp-query+watchlistraw-example-simple": "Seznam sledovaných stránek uživatele.",
+ "apihelp-unblock-param-user": "Uživatel, IP adresa nebo záběr IP adres k odblokování. Nelze použít dohromady s <var>$1id</var>.",
+ "apihelp-watch-example-watch": "Sledovat stránku <kbd>Hlavní stránka</kbd>.",
+ "apihelp-watch-example-generator": "Zobrazit prvních několik stránek z hlavního jmenného prostoru.",
+ "apihelp-format-example-generic": "Výsledek dotazu vypsat ve formátu $1.",
+ "apihelp-dbg-description": "Vypisuje data ve formátu funkce var_export() z PHP.",
+ "apihelp-dbgfm-description": "Vypisuje data ve formátu funkce var_export() z PHP (v čitelné HTML podobě).",
+ "apihelp-dump-description": "Vypisuje data ve formátu funkce var_dump() z PHP.",
+ "apihelp-dumpfm-description": "Vypisuje data ve formátu funkce var_dump() z PHP (v čitelné HTML podobě).",
+ "apihelp-json-description": "Vypisuje data ve formátu JSON.",
+ "apihelp-json-param-callback": "Pokud je uvedeno, obalí výstup do zadaného volání funkce. Z bezpečnostních důvodů budou omezena všechna data specifická pro uživatele.",
+ "apihelp-json-param-utf8": "Pokud je uvedeno, bude většina ne-ASCII znaků (ale ne všechny) kódována v UTF-8 místo nahrazení hexadecimálními escape sekvencemi.",
+ "apihelp-jsonfm-description": "Vypisuje data ve formátu JSON (v čitelné HTML podobě).",
+ "apihelp-none-description": "Nevypisuje nic.",
+ "apihelp-php-description": "Vypisuje data v serializačním formátu PHP.",
+ "apihelp-phpfm-description": "Vypisuje data v serializačním formátu PHP (v čitelné HTML podobě).",
+ "apihelp-rawfm-description": "Vypisuje data s ladicími prvky ve formátu JSON (v čitelné HTML podobě).",
+ "apihelp-txt-description": "Vypisuje data ve formátu funkce print_r() z PHP.",
+ "apihelp-txtfm-description": "Vypisuje data ve formátu funkce print_r() z PHP (v čitelné HTML podobě).",
+ "apihelp-wddx-description": "Vypisuje data ve formátu WDDX.",
+ "apihelp-wddxfm-description": "Vypisuje data ve formátu WDDX (v čitelné HTML podobě).",
+ "apihelp-xml-description": "Vypisuje data ve formátu XML.",
+ "apihelp-xml-param-xslt": "Pokud je uvedeno, přidá stylopis &lt;xslt&gt;. Měla by jím být wikistránka v jmenném prostoru MediaWiki, jejíž název končí na „.xsl“.",
+ "apihelp-xml-param-includexmlnamespace": "Pokud je uvedeno, přidá jmenný prostor XML.",
+ "apihelp-xmlfm-description": "Vypisuje data ve formátu XML (v čitelné HTML podobě).",
+ "apihelp-yaml-description": "Vypisuje data ve formátu YAML.",
+ "apihelp-yamlfm-description": "Vypisuje data ve formátu YAML (v čitelné HTML podobě).",
+ "api-format-title": "Odpověď z MediaWiki API",
+ "api-format-prettyprint-header": "Díváte se na HTML reprezentaci formátu $1. HTML se hodí pro ladění, ale pro aplikační použití je nevhodné.\n\nPro změnu výstupního formátu uveďte parametr format. Abyste viděli ne-HTML reprezentaci formátu $1, nastavte format=$2.\n\nVíce informací najdete v [https://www.mediawiki.org/wiki/Special:MyLanguage/API:Main_page úplné dokumentaci] nebo [[Special:ApiHelp/main|nápovědě k API]].",
+ "api-help-title": "Nápověda k MediaWiki API",
+ "api-help-lead": "Toto je automaticky generovaná dokumentační stránka k MediaWiki API.\n\nDokumentace a příklady: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Hlavní modul",
+ "api-help-flag-deprecated": "Tento modul je zastaralý.",
+ "api-help-flag-internal": "<strong>Tento modul je interní nebo nestabilní.</strong> Jeho funkčnost se může bez předchozího upozornění změnit.",
+ "api-help-flag-readrights": "Tento modul vyžaduje oprávnění ke čtení.",
+ "api-help-flag-writerights": "Tento modul vyžaduje oprávnění k zápisu.",
+ "api-help-flag-mustbeposted": "Tento modul přijímá pouze požadavky POST.",
+ "api-help-flag-generator": "Tento modul lze využívat jako generátor.",
+ "api-help-parameters": "{{PLURAL:$1|Parametr|Parametry}}:",
+ "api-help-param-deprecated": "Zastaralý.",
+ "api-help-param-required": "Tento parametr je povinný.",
+ "api-help-param-list": "{{PLURAL:$1|1=Jedna hodnota|2=Hodnoty (oddělené „{{!}}“)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Musí být prázdné|Může být prázdné nebo $2}}",
+ "api-help-param-limit": "Není dovoleno více než $1.",
+ "api-help-param-limit2": "Není dovoleno více než $1 ($2 pro boty).",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=Hodnota nesmí|2=Hodnoty nesmějí}} být nižší než $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=Hodnota nesmí|2=Hodnoty nesmějí}} být vyšší než $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=Hodnota|2=Hodnoty}} musí ležet mezi $2 a $3.",
+ "api-help-param-upload": "Musí se odeslat POST požadavkem jako načítaný soubor pomocí multipart/form-data.",
+ "api-help-param-multi-separate": "Hodnoty oddělujte pomocí „|“.",
+ "api-help-param-multi-max": "Maximální počet hodnot je {{PLURAL:$1|$1}} (pro boty {{PLURAL:$2|$2}}).",
+ "api-help-param-default": "Implicitní hodnota: $1",
+ "api-help-param-default-empty": "Implicitní hodnota: <span class=\"apihelp-empty\">(prázdné)</span>",
+ "api-help-param-token": "Token typu „$1“ získaný pomocí [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(bez popisu)</span>",
+ "api-help-examples": "{{PLURAL:$1|Příklad|Příklady}}:",
+ "api-help-permissions": "{{PLURAL:$1|Oprávnění}}:",
+ "api-help-permissions-granted-to": "Uděleno {{PLURAL:$1|skupině|skupinám}}: $2",
+ "api-help-right-apihighlimits": "Používání vyšších limitů v API dotazech (pomalé dotazy: $1, rychlé dotazy: $2). Limity pro pomalé dotazy se vztahují i na vícehodnotové parametry.",
+ "api-credits-header": "Zásluhy",
+ "api-credits": "Vývojáři API:\n* Roan Kattouw (hlavní vývojář září 2007–2009)\n* Viktor Vasiljev\n* Bryan Tong Minh\n* Sam Reed\n* Jurij Astrachan (tvůrce, hlavní vývojář září 2006–září 2007)\n* Brad Jorsch (hlavní vývojář od 2013)\n\nSvé komentáře, návrhy či dotazy posílejte na mediawiki-api@lists.wikimedia.org\nnebo založte chybové hlášení na https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/cv.json b/includes/api/i18n/cv.json
new file mode 100644
index 00000000..88f222f8
--- /dev/null
+++ b/includes/api/i18n/cv.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Chuvash2014"
+ ]
+ },
+ "apihelp-login-example-login": "Кĕр"
+}
diff --git a/includes/api/i18n/de.json b/includes/api/i18n/de.json
new file mode 100644
index 00000000..96172040
--- /dev/null
+++ b/includes/api/i18n/de.json
@@ -0,0 +1,433 @@
+{
+ "@metadata": {
+ "authors": [
+ "Florian",
+ "Kghbln",
+ "Metalhead64",
+ "Inkowik",
+ "Umherirrender",
+ "Giftpflanze",
+ "Macofe",
+ "Se4598",
+ "Purodha"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page/de|Dokumentation]]\n* [[mw:API:FAQ/de|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:API:Errors_and_warnings|API: Fehler und Warnungen]].",
+ "apihelp-main-param-action": "Auszuführende Aktion.",
+ "apihelp-main-param-format": "Format der Ausgabe.",
+ "apihelp-main-param-maxlag": "maxlag kann verwendet werden, wenn MediaWiki auf einem datenbankreplizierten Cluster installiert ist. Um weitere Replikationsrückstände zu verhindern, lässt dieser Parameter den Client warten, bis der Replikationsrückstand kleiner als der angegebene Wert (in Sekunden) ist. Bei einem größerem Rückstand wird der Fehlercode <samp>maxlag</samp> zurückgegeben mit einer Nachricht wie <samp>Waiting for $host: $lag seconds lagged</samp>.<br />Siehe [[mw:Manual:Maxlag_parameter|Handbuch: Maxlag parameter]] für weitere Informationen.",
+ "apihelp-main-param-smaxage": "Den <code>s-maxage</code>-Header auf diese Anzahl Sekunden festlegen. Fehler werden niemals gecacht.",
+ "apihelp-main-param-maxage": "Den <code>max-age</code>-Header auf diese Anzahl Sekunden festlegen. Fehler werden niemals gecacht.",
+ "apihelp-main-param-assert": "Sicherstellen, dass der Benutzer eingeloggt ist, wenn auf <kbd>user</kbd> gesetzt, oder Bot ist, wenn auf <kbd>bot</kbd> gesetzt.",
+ "apihelp-main-param-requestid": "Der angegebene Wert wird mit in die Antwort aufgenommen und kann zur Unterscheidung von Anfragen verwendet werden.",
+ "apihelp-main-param-servedby": "Namen des bearbeitenden Hosts mit zurückgeben.",
+ "apihelp-main-param-curtimestamp": "Aktuellen Zeitstempel mit zurückgeben.",
+ "apihelp-main-param-origin": "Beim Zugriff auf die API mittels Cross-Domain-AJAX-Anfrage (CORS) ist dieser Parameter auf die veranlassende Domain zu setzen. Er muss in jedem Pre-Flight-Request angegeben werden und deshalb ein Teil der Anfrage-URI sein (nicht des POST-Bodys). Er muss genau einer der Angaben im <code>Origin</code>-Header entsprechen, d.&nbsp;h. er muss auf etwas wie <kbd>https://de.wikipedia.org</kbd> oder <kbd>https://meta.wikimedia.org</kbd> gesetzt werden. Falls dieser Parameter nicht mit dem <code>Origin</code>-Header übereinstimmt, wird eine 403-Antwort zurückgegeben. Falls dieser Parameter dem <code>Origin</code>-Header entspricht und die Domain auf der Whitelist ist, wird ein <code>Access-Control-Allow-Origin</code>-Header gesetzt.",
+ "apihelp-main-param-uselang": "Zu verwendende Sprache für Nachrichtenübersetzungen. Eine Liste der Codes kann von <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> mit <kbd>siprop=languages</kbd> abgerufen werden. Gib <kbd>user</kbd> zum Verwenden der aktuellen Benutzerspracheinstellung oder <kbd>content</kbd> an, um die Inhaltssprache des Wikis zu verwenden.",
+ "apihelp-block-description": "Einen Benutzer sperren.",
+ "apihelp-block-param-user": "Benutzername, IP-Adresse oder IP-Bereich, der gesperrt werden soll.",
+ "apihelp-block-param-expiry": "Sperrdauer. Kann relativ (z.&nbsp;B. <kbd>5 months</kbd> oder <kbd>2 weeks</kbd>) oder absolut (z.&nbsp;B. <kbd>2014-09-18T12:34:56Z</kbd>) sein. Wenn auf <kbd>infinite</kbd>, <kbd>indefinite</kbd> oder <kbd>never</kbd> gesetzt, ist die Sperre unbegrenzt.",
+ "apihelp-block-param-reason": "Sperrbegründung.",
+ "apihelp-block-param-anononly": "Nur anonyme Benutzer sperren (z.&nbsp;B. anonyme Bearbeitungen für diese IP deaktivieren).",
+ "apihelp-block-param-nocreate": "Benutzerkontenerstellung verhindern.",
+ "apihelp-block-param-autoblock": "Die zuletzt verwendete IP-Adresse automatisch sperren und alle darauffolgenden IP-Adressen, die versuchen sich anzumelden.",
+ "apihelp-block-param-noemail": "Benutzer davon abhalten, E-Mails auf dem Wiki zu versenden (erfordert das <code>blockemail</code>-Recht).",
+ "apihelp-block-param-hidename": "Den Benutzernamen im Sperr-Logbuch verstecken (erfordert das <code>hideuser</code>-Recht).",
+ "apihelp-block-param-allowusertalk": "Dem Benutzer erlauben, seine eigene Diskussionsseite zu bearbeiten (abhängig von <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Falls der Benutzer bereits gesperrt ist, die vorhandene Sperre überschreiben.",
+ "apihelp-block-param-watchuser": "Benutzer- und Diskussionsseiten des Benutzers oder der IP-Adresse beobachten.",
+ "apihelp-block-example-ip-simple": "IP <kbd>192.0.2.5</kbd> für drei Tage mit der Begründung „First strike“ (erste Verwarnung) sperren",
+ "apihelp-block-example-user-complex": "Benutzer <kbd>Vandal</kbd> unbeschränkt sperren mit der Begründung „Vandalism“ (Vandalismus), Erstellung neuer Benutzerkonten sowie Versand von E-Mails verhindern.",
+ "apihelp-checktoken-description": "Überprüft die Gültigkeit eines über <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> erhaltenen Tokens.",
+ "apihelp-checktoken-param-type": "Typ des Tokens, das getestet werden soll.",
+ "apihelp-checktoken-param-token": "Token, das getestet werden soll.",
+ "apihelp-checktoken-param-maxtokenage": "Maximal erlaubtes Alter des Tokens in Sekunden.",
+ "apihelp-checktoken-example-simple": "Überprüft die Gültigkeit des <kbd>csrf</kbd>-Tokens.",
+ "apihelp-clearhasmsg-description": "Löschen des <code>hasmsg</code>-Flags („hat Nachrichten“-Flag) für den aktuellen Benutzer.",
+ "apihelp-clearhasmsg-example-1": "<code>hasmsg</code>-Flags für den aktuellen Benutzer löschen",
+ "apihelp-compare-description": "Abrufen des Unterschieds zwischen zwei Seiten.\n\nDu musst eine Versionsnummer, einen Seitentitel oder eine Seitennummer für „from“ als auch „to“ angeben.",
+ "apihelp-compare-param-fromtitle": "Erster zu vergleichender Titel.",
+ "apihelp-compare-param-fromid": "Erste zu vergleichende Seitennummer.",
+ "apihelp-compare-param-fromrev": "Erste zu vergleichende Version.",
+ "apihelp-compare-param-totitle": "Zweiter zu vergleichender Titel.",
+ "apihelp-compare-param-toid": "Zweite zu vergleichende Seitennummer.",
+ "apihelp-compare-param-torev": "Zweite zu vergleichende Version.",
+ "apihelp-compare-example-1": "Unterschied zwischen Version 1 und 2 abrufen",
+ "apihelp-createaccount-description": "Erstellen eines neuen Benutzerkontos.",
+ "apihelp-createaccount-param-name": "Benutzername.",
+ "apihelp-createaccount-param-password": "Passwort (wird ignoriert, wenn <var>$1mailpassword</var> angegeben ist).",
+ "apihelp-createaccount-param-domain": "Domain für die externe Authentifizierung (optional).",
+ "apihelp-createaccount-param-token": "Der in der ersten Anfrage erhaltene Benutzerkontenerstellungs-Token.",
+ "apihelp-createaccount-param-email": "E-Mail-Adresse des Benutzers (optional).",
+ "apihelp-createaccount-param-realname": "Realname des Benutzers (optional).",
+ "apihelp-createaccount-param-mailpassword": "Wenn ein Wert angegeben wird, wird ein zufälliges Passwort per E-Mail an den Benutzer versandt.",
+ "apihelp-createaccount-param-reason": "Optionale Begründung für die Benutzerkontenerstellung, die in den Logbüchern vermerkt wird.",
+ "apihelp-createaccount-param-language": "Festzulegender standardmäßiger Sprachcode für den Benutzer (optional, Standard ist Inhaltssprache).",
+ "apihelp-createaccount-example-pass": "Benutzer <kbd>testuser</kbd> mit dem Passwort <kbd>test123</kbd> erstellen.",
+ "apihelp-createaccount-example-mail": "Benutzer <kbd>testmailuser</kbd> erstellen und zufällig generiertes Passwort per E-Mail verschicken.",
+ "apihelp-delete-description": "Löschen einer Seite.",
+ "apihelp-delete-param-title": "Titel der Seite, die gelöscht werden soll. Kann nicht zusammen mit <var>$1pageid</var> verwendet werden.",
+ "apihelp-delete-param-pageid": "Seitennummer der Seite, die gelöscht werden soll. Kann nicht zusammen mit <var>$1title</var> verwendet werden.",
+ "apihelp-delete-param-reason": "Löschbegründung. Falls nicht festgelegt, wird eine automatisch generierte Begründung verwendet.",
+ "apihelp-delete-param-watch": "Seite auf die Beobachtungsliste des aktuellen Benutzers setzen.",
+ "apihelp-delete-param-watchlist": "Seite zur Beobachtungsliste des aktuellen Benutzers hinzufügen oder von ihr entfernen, die Standardeinstellungen verwenden oder die Beobachtung nicht ändern.",
+ "apihelp-delete-param-unwatch": "Seite von der Beobachtungsliste entfernen.",
+ "apihelp-delete-param-oldimage": "Name des alten zu löschenden Bildes, wie von [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]] angegeben.",
+ "apihelp-delete-example-simple": "<kbd>Hauptseite</kbd> löschen.",
+ "apihelp-delete-example-reason": "<kbd>Hauptseite</kbd> löschen mit der Begründung <kbd>Vorbereitung für Verschiebung</kbd>.",
+ "apihelp-disabled-description": "Dieses Modul wurde deaktiviert.",
+ "apihelp-edit-description": "Erstellen und Bearbeiten von Seiten.",
+ "apihelp-edit-param-title": "Titel der Seite, die bearbeitet werden soll. Kann nicht zusammen mit <var>$1pageid</var> verwendet werden.",
+ "apihelp-edit-param-pageid": "Seitennummer der Seite, die bearbeitet werden soll. Kann nicht zusammen mit <var>$1title</var> verwendet werden.",
+ "apihelp-edit-param-section": "Abschnittsnummer. <kbd>0</kbd> für die Einleitung, <kbd>new</kbd> für einen neuen Abschnitt.",
+ "apihelp-edit-param-sectiontitle": "Die Überschrift für einen neuen Abschnitt.",
+ "apihelp-edit-param-text": "Seiteninhalt.",
+ "apihelp-edit-param-summary": "Bearbeitungszusammenfassung. Auch Abschnittsüberschrift, wenn $1section=new und $1sectiontitle nicht festgelegt ist.",
+ "apihelp-edit-param-minor": "Kleine Bearbeitung.",
+ "apihelp-edit-param-notminor": "Nicht-kleine Bearbeitung.",
+ "apihelp-edit-param-bot": "Diese Bearbeitung als Bot-Bearbeitung markieren.",
+ "apihelp-edit-param-basetimestamp": "Zeitstempel der Basisversion, wird verwendet zum Aufspüren von Bearbeitungskonflikten. Kann abgerufen werden durch [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "Zeitstempel, an dem der Bearbeitungsprozess begonnen wurde. Er wird zum Aufspüren von Bearbeitungskonflikten verwendet. Ein geeigneter Wert kann mithilfe von <var>[[Special:ApiHelp/main|curtimestamp]]</var> beim Beginn des Bearbeitungsprozesses (z.&nbsp;B. beim Laden des Seiteninhalts zum Bearbeiten) abgerufen werden.",
+ "apihelp-edit-param-recreate": "Keinen Fehler zurückgeben, wenn die Seite in der Zwischenzeit gelöscht wurde.",
+ "apihelp-edit-param-createonly": "Seite nicht bearbeiten, falls sie bereits vorhanden ist.",
+ "apihelp-edit-param-nocreate": "Einen Fehler zurückgeben, falls die Seite nicht vorhanden ist.",
+ "apihelp-edit-param-watch": "Seite der Beobachtungsliste hinzufügen.",
+ "apihelp-edit-param-unwatch": "Seite von der Beobachtungsliste entfernen.",
+ "apihelp-edit-param-watchlist": "Die Seite zur Beobachtungsliste des aktuellen Benutzers hinzufügen oder von ihr entfernen, die Standardeinstellungen verwenden oder die Beobachtung nicht ändern.",
+ "apihelp-edit-param-md5": "Der MD5-Hash des Parameters $1text oder der aneinandergehängten Parameter $1prependtext und $1appendtext. Wenn angegeben, wird die Bearbeitung nicht ausgeführt, wenn der Hash nicht korrekt ist.",
+ "apihelp-edit-param-prependtext": "Diesen Text an den Anfang der Seite setzen. Überschreibt $1text.",
+ "apihelp-edit-param-appendtext": "Diesen Text an das Ende der Seite hinzufügen. Überschreibt $1text.\n\nVerwende statt dieses Parameters $1section=new zum Anhängen eines neuen Abschnitts.",
+ "apihelp-edit-param-undo": "Diese Version rückgängig machen. Überschreibt $1text, $1prependtext und $1appendtext.",
+ "apihelp-edit-param-undoafter": "Alle Versionen von $1undo bis zu dieser rückgängig machen. Falls nicht angegeben, nur eine Version rückgängig machen.",
+ "apihelp-edit-param-redirect": "Weiterleitungen automatisch auflösen.",
+ "apihelp-edit-param-contentformat": "Für den Eingabetext verwendetes Inhaltsserialisierungsformat.",
+ "apihelp-edit-param-contentmodel": "Inhaltsmodell des neuen Inhalts.",
+ "apihelp-edit-param-token": "Der Token sollte immer als letzter Parameter gesendet werden, zumindest aber nach dem $1text-Parameter.",
+ "apihelp-edit-example-edit": "Eine Seite bearbeiten",
+ "apihelp-edit-example-prepend": "<kbd>_&#95;NOTOC_&#95;</kbd> bei einer Seite voranstellen",
+ "apihelp-edit-example-undo": "Versionen 13579 bis 13585 mit automatischer Zusammenfassung rückgängig machen",
+ "apihelp-emailuser-description": "E-Mail an einen Benutzer senden.",
+ "apihelp-emailuser-param-target": "Benutzer, an den die E-Mail gesendet werden soll.",
+ "apihelp-emailuser-param-subject": "Betreffzeile.",
+ "apihelp-emailuser-param-text": "E-Mail-Inhalt.",
+ "apihelp-emailuser-param-ccme": "Eine Kopie dieser E-Mail an mich senden.",
+ "apihelp-emailuser-example-email": "Eine E-Mail an den Benutzer <kbd>WikiSysop</kbd> mit dem Text <kbd>Inhalt</kbd> senden.",
+ "apihelp-expandtemplates-description": "Alle Vorlagen im Wikitext expandieren.",
+ "apihelp-expandtemplates-param-title": "Titel der Seite.",
+ "apihelp-expandtemplates-param-text": "Zu konvertierender Wikitext.",
+ "apihelp-expandtemplates-param-revid": "Versionsnummer, die für die Anzeige von <nowiki>{{REVISIONID}}</nowiki> und ähnlichen Variablen verwendet wird.",
+ "apihelp-expandtemplates-param-includecomments": "Ob HTML-Kommentare in der Ausgabe eingeschlossen werden sollen.",
+ "apihelp-expandtemplates-param-generatexml": "XML-Parserbaum erzeugen (ersetzt durch $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Den Wikitext <kbd><nowiki>{{Project:Spielwiese}}</nowiki></kbd> expandieren.",
+ "apihelp-feedcontributions-description": "Gibt einen Benutzerbeiträge-Feed zurück.",
+ "apihelp-feedcontributions-param-feedformat": "Das Format des Feeds.",
+ "apihelp-feedcontributions-param-user": "Von welchen Benutzern die Beiträge abgerufen werden sollen.",
+ "apihelp-feedcontributions-param-namespace": "Auf welchen Namensraum die Beiträge begrenzt werden sollen.",
+ "apihelp-feedcontributions-param-year": "Von Jahr (und früher).",
+ "apihelp-feedcontributions-param-month": "Von Monat (und früher).",
+ "apihelp-feedcontributions-param-tagfilter": "Beiträge filtern, die diese Markierungen haben.",
+ "apihelp-feedcontributions-param-deletedonly": "Nur gelöschte Beiträge anzeigen.",
+ "apihelp-feedcontributions-param-toponly": "Nur aktuelle Versionen anzeigen.",
+ "apihelp-feedcontributions-param-newonly": "Nur Seitenerstellungen anzeigen.",
+ "apihelp-feedcontributions-param-showsizediff": "Zeigt den Größenunterschied zwischen Versionen an.",
+ "apihelp-feedcontributions-example-simple": "Beiträge für die Benutzer <kbd>Beispiel<kbd> zurückgeben",
+ "apihelp-feedrecentchanges-description": "Gibt einen Letzte-Änderungen-Feed zurück.",
+ "apihelp-feedrecentchanges-param-feedformat": "Das Format des Feeds.",
+ "apihelp-feedrecentchanges-param-namespace": "Namensraum, auf den die Ergebnisse beschränkt werden sollen.",
+ "apihelp-feedrecentchanges-param-invert": "Alle Namensräume außer dem ausgewählten.",
+ "apihelp-feedrecentchanges-param-associated": "Verbundenen Namensraum (Diskussions oder Hauptnamensraum) mit einschließen.",
+ "apihelp-feedrecentchanges-param-days": "Tage, auf die die Ergebnisse beschränkt werden sollen.",
+ "apihelp-feedrecentchanges-param-limit": "Maximale Anzahl zurückzugebender Ergebnisse.",
+ "apihelp-feedrecentchanges-param-from": "Änderungen seit jetzt anzeigen.",
+ "apihelp-feedrecentchanges-param-hideminor": "Kleine Änderungen ausblenden.",
+ "apihelp-feedrecentchanges-param-hidebots": "Änderungen von Bots ausblenden.",
+ "apihelp-feedrecentchanges-param-hideanons": "Änderungen von anonymen Benutzern ausblenden.",
+ "apihelp-feedrecentchanges-param-hideliu": "Änderungen von registrierten Benutzern ausblenden.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Kontrollierte Änderungen ausblenden.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Änderungen des aktuellen Benutzers ausblenden.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Nach Markierung filtern.",
+ "apihelp-feedrecentchanges-param-target": "Nur Änderungen an Seiten anzeigen, die von dieser Seite verlinkt sind.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Zeige Änderungen an Seiten die von der ausgewählten Seite verlinkt sind.",
+ "apihelp-feedrecentchanges-example-simple": "Letzte Änderungen anzeigen",
+ "apihelp-feedrecentchanges-example-30days": "Letzte Änderungen für 30 Tage anzeigen",
+ "apihelp-feedwatchlist-description": "Gibt einen Beobachtungslisten-Feed zurück.",
+ "apihelp-feedwatchlist-param-feedformat": "Das Format des Feeds.",
+ "apihelp-feedwatchlist-param-hours": "Seiten auflisten, die innerhalb dieser Anzahl Stunden ab jetzt geändert wurden.",
+ "apihelp-feedwatchlist-param-linktosections": "Verlinke direkt zum veränderten Abschnitt, wenn möglich.",
+ "apihelp-feedwatchlist-example-default": "Den Beobachtungslisten-Feed anzeigen",
+ "apihelp-feedwatchlist-example-all6hrs": "Zeige alle Änderungen an beobachteten Seiten der letzten 6 Stunden.",
+ "apihelp-filerevert-description": "Eine Datei auf eine alte Version zurücksetzen.",
+ "apihelp-filerevert-param-filename": "Ziel-Datei, ohne das Datei:-Präfix.",
+ "apihelp-filerevert-param-comment": "Hochladekommentar.",
+ "apihelp-filerevert-param-archivename": "Archivname der Version, auf die die Datei zurückgesetzt werden soll.",
+ "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd> auf die Version vom <kbd>2011-03-05T15:27:40Z</kbd> zurücksetzen",
+ "apihelp-help-description": "Hilfe für die angegebenen Module anzeigen.",
+ "apihelp-help-param-modules": "Module, zu denen eine Hilfe angezeigt werden soll (Werte der Parameter <var>action</var> und <var>format</var> oder <kbd>main</kbd>). Kann Submodule mit einem <kbd>+</kbd> angeben.",
+ "apihelp-help-param-submodules": "Hilfe für Submodule des benannten Moduls einschließen.",
+ "apihelp-help-param-recursivesubmodules": "Hilfe für Submodule rekursiv einschließen.",
+ "apihelp-help-param-helpformat": "Format der Hilfe-Ausgabe.",
+ "apihelp-help-param-wrap": "Die Ausgabe in eine Standard-API-Antwort-Struktur einschließen.",
+ "apihelp-help-param-toc": "Ein Inhaltsverzeichnis in der HTML-Ausgabe einschließen.",
+ "apihelp-help-example-main": "Hilfe für das Hauptmodul",
+ "apihelp-help-example-recursive": "Alle Hilfen in einer Seite",
+ "apihelp-help-example-help": "Hilfe für das Hilfemodul selbst",
+ "apihelp-help-example-query": "Hilfe für zwei Abfrage-Submodule",
+ "apihelp-imagerotate-description": "Ein oder mehrere Bilder drehen.",
+ "apihelp-imagerotate-param-rotation": "Anzahl der Grad, um die das Bild im Uhrzeigersinn gedreht werden soll.",
+ "apihelp-imagerotate-example-simple": "<kbd>Datei:Beispiel.png</kbd> um <kbd>90</kbd> Grad drehen.",
+ "apihelp-imagerotate-example-generator": "Alle Bilder in der <kbd>Kategorie:Flip</kbd> um <kbd>180</kbd> Grad drehen.",
+ "apihelp-import-description": "Importiert eine Seite von einem anderen Wiki oder einer XML-Datei.\n\nBitte beachte, dass der HTTP-POST-Vorgang als Dateiupload ausgeführt werden muss (z.B. durch multipart/form-data), um eine Datei über den <var>xml</var>-Parameter zu senden.",
+ "apihelp-import-param-summary": "Import-Zusammenfassung.",
+ "apihelp-import-param-xml": "Hochgeladene XML-Datei.",
+ "apihelp-import-param-interwikisource": "Für Interwiki-Importe: Wiki, von dem importiert werden soll.",
+ "apihelp-import-param-interwikipage": "Für Interwiki-Importe: zu importierende Seite.",
+ "apihelp-import-param-fullhistory": "Für Interwiki-Importe: importiere die komplette Versionsgeschichte, nicht nur die aktuelle Version.",
+ "apihelp-import-param-templates": "Für Interwiki-Importe: importiere auch alle eingebundenen Vorlagen.",
+ "apihelp-import-param-namespace": "Für Interwiki-Importe: importiere in diesen Namensraum.",
+ "apihelp-import-param-rootpage": "Als Unterseite dieser Seite importieren.",
+ "apihelp-import-example-import": "Importiere [[meta:Help:Parserfunctions]] mit der kompletten Versionsgeschichte in den Namensraum 100.",
+ "apihelp-login-description": "Anmelden und Authentifizierungs-Cookies beziehen.\n\nFalls das Anmelden erfolgreich war, werden die benötigten Cookies im Header der HTTP-Antwort des Servers übermittelt. Bei fehlgeschlagenen Anmeldeversuchen können weitere Versuche gedrosselt werden, um automatische Passwortermittlungsattacken zu verhinden.",
+ "apihelp-login-param-name": "Benutzername.",
+ "apihelp-login-param-password": "Passwort.",
+ "apihelp-login-param-domain": "Domain (optional).",
+ "apihelp-login-param-token": "Anmeldetoken, den du in der ersten Anfrage erhalten hast.",
+ "apihelp-login-example-gettoken": "Ruft einen Anmelde-Token ab",
+ "apihelp-login-example-login": "Anmelden",
+ "apihelp-logout-description": "Abmelden und alle Sitzungsdaten löschen.",
+ "apihelp-logout-example-logout": "Meldet den aktuellen Benutzer ab",
+ "apihelp-managetags-description": "Ermöglicht Verwaltungsaufgaben zu Änderungsmarkierungen.",
+ "apihelp-managetags-param-reason": "optionale Begründung für das Erstellen, Löschen, Aktivieren oder Deaktivieren der Markierung.",
+ "apihelp-managetags-param-ignorewarnings": "Warnungen während des Vorgangs ignorieren.",
+ "apihelp-managetags-example-create": "Erstellt eine Markierung namens <kbd>spam</kbd> mit der Begründung <kbd>For use in edit patrolling</kbd> (für die Eingangskontrolle).",
+ "apihelp-managetags-example-delete": "Löscht die <kbd>vandlaism</kbd>-Markierung mit der Begründung <kbd>Misspelt</kbd>.",
+ "apihelp-managetags-example-activate": "Aktiviert eine Markierung namens <kbd>spam</kbd> mit der Begründung <kbd>For use in edit patrolling</kbd> (für die Eingangskontrolle).",
+ "apihelp-managetags-example-deactivate": "Deaktiviert eine Markierung namens <kbd>spam</kbd> mit der Begründung <kbd>No longer required</kbd> (nicht mehr benötigt).",
+ "apihelp-move-description": "Eine Seite verschieben.",
+ "apihelp-move-param-from": "Titel der zu verschiebenden Seite. Kann nicht zusammen mit <var>$1fromid</var> verwendet werden.",
+ "apihelp-move-param-fromid": "Seitenkennung der zu verschiebenden Seite. Kann nicht zusammen mit <var>$1from</var> verwendet werden.",
+ "apihelp-move-param-to": "Titel, zu dem die Seite umbenannt werden soll.",
+ "apihelp-move-param-reason": "Grund für die Umbenennung.",
+ "apihelp-move-param-movetalk": "Verschiebt die Diskussionsseite, falls vorhanden.",
+ "apihelp-move-param-movesubpages": "Unterseiten verschieben, falls möglich.",
+ "apihelp-move-param-noredirect": "Keine Weiterleitung erstellen.",
+ "apihelp-move-param-watch": "Die Seite und die entstandene Weiterleitung zur Beobachtungsliste hinzufügen.",
+ "apihelp-move-param-unwatch": "Die Seite und die entstandene Weiterleitung von der Beobachtungsliste entfernen.",
+ "apihelp-move-param-watchlist": "Die Seite in jedem Fall zur Beobachtungsliste hinzufügen oder davon entfernen, die Voreinstellungen dafür nutzen oder den Beobachtungsstatus nicht ändern.",
+ "apihelp-move-param-ignorewarnings": "Alle Warnungen ignorieren.",
+ "apihelp-move-example-move": "<kbd>Schlechter Titel</kbd> nach <kbd>Guter Titel</kbd> verschieben, ohne eine Weiterleitung zu erstellen.",
+ "apihelp-opensearch-description": "Das Wiki mithilfe des OpenSearch-Protokolls durchsuchen.",
+ "apihelp-opensearch-param-search": "Such-Zeichenfolge.",
+ "apihelp-opensearch-param-limit": "Maximale Anzahl zurückzugebender Ergebnisse.",
+ "apihelp-opensearch-param-namespace": "Zu durchsuchende Namensräume.",
+ "apihelp-opensearch-param-suggest": "Nichts unternehmen, falls <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> falsch ist.",
+ "apihelp-opensearch-param-format": "Das Format der Ausgabe.",
+ "apihelp-opensearch-example-te": "Seiten finden, die mit <kbd>Te</kbd> beginnen.",
+ "apihelp-options-param-reset": "Setzt die Einstellungen auf Websitestandards zurück.",
+ "apihelp-options-example-reset": "Alle Einstellungen zurücksetzen",
+ "apihelp-options-example-change": "Ändert die Einstellungen <kbd>skin</kbd> und <kbd>hideminor</kbd>.",
+ "apihelp-options-example-complex": "Setzt alle Einstellungen zurück, dann <kbd>skin</kbd> und <kbd>nickname</kbd> festlegen.",
+ "apihelp-paraminfo-description": "Ruft Informationen über API-Module ab.",
+ "apihelp-paraminfo-param-helpformat": "Format der Hilfe-Zeichenfolgen.",
+ "apihelp-parse-param-summary": "Zu parsende Zusammenfassung.",
+ "apihelp-parse-param-section": "Gibt nur den Inhalt dieses Abschnittes zurück oder erstellt einen neuen Abschnitt, wenn <kbd>new</kbd> angegeben wird.\n\n<kbd>new</kbd> wird nur ausgewertet, wenn auch <var>text</var> angegeben wurde.",
+ "apihelp-parse-param-sectiontitle": "Überschrift des neuen Abschnittes, wenn <var>section</var> = <kbd>new</kbd> ist.\n\nAnders als beim Bearbeiten der Seite wird der Parameter nicht durch die <var>summary</var> ersetzt, wenn er weggelassen oder leer ist.",
+ "apihelp-parse-param-disableeditsection": "Deaktiviert Abschnittsbearbeitungslinks in der Parserausgabe.",
+ "apihelp-parse-param-preview": "Im Vorschaumodus parsen.",
+ "apihelp-parse-param-disabletoc": "Inhaltsverzeichnis in der Ausgabe deaktivieren.",
+ "apihelp-parse-example-page": "Eine Seite parsen.",
+ "apihelp-parse-example-text": "Wikitext parsen.",
+ "apihelp-parse-example-texttitle": "Parst den Wikitext über die Eingabe des Seitentitels.",
+ "apihelp-parse-example-summary": "Parst eine Zusammenfassung.",
+ "apihelp-patrol-description": "Kontrolliert eine Seite oder Version.",
+ "apihelp-patrol-param-rcid": "Letzte-Änderungen-Kennung, die kontrolliert werden soll.",
+ "apihelp-patrol-param-revid": "Versionskennung, die kontrolliert werden soll.",
+ "apihelp-patrol-example-rcid": "Kontrolliert eine kürzlich getätigte Änderung.",
+ "apihelp-patrol-example-revid": "Kontrolliert eine Version",
+ "apihelp-protect-description": "Ändert den Schutzstatus einer Seite.",
+ "apihelp-protect-param-title": "Titel der Seite, die du (ent-)sperren möchtest. Kann nicht zusammen mit $1pageid verwendet werden.",
+ "apihelp-protect-param-pageid": "Seitenkennung der Seite, die du (ent-)sperren möchtest. Kann nicht zusammen mit $1title verwendet werden.",
+ "apihelp-protect-param-protections": "Liste der Schutzebenen nach dem Format <kbd>Aktion=Ebene</kbd> (z.B. <kbd>edit=sysop</kbd>).\n\n<strong>HINWEIS:</strong> Wenn eine Aktion nicht angegeben wird, wird deren Schutz entfernt.",
+ "apihelp-protect-param-expiry": "Zeitstempel des Schutzablaufs. Wenn nur ein Zeitstempel übergeben wird, ist dieser für alle Seitenschutze gültig. Um eine unendliche Schutzdauer festzulegen, kannst du die Werte <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd> oder <kbd>never</kbd> übergeben.",
+ "apihelp-protect-param-reason": "Grund für den Seitenschutz oder dessen Aufhebung.",
+ "apihelp-protect-param-cascade": "Aktiviert den Kaskadenschutz (alle eingebundenen Seiten werden ebenfalls geschützt). Wenn die übergebenen Schutzebenen keinen Kaskadenschutz unterstützen, wird dieser Parameter ignoriert.",
+ "apihelp-protect-param-watch": "Wenn vorhanden, fügt dieser Parameter die zu (ent-)sperrende Seite der Beobachtungsliste des aktuellen Benutzers hinzu.",
+ "apihelp-protect-param-watchlist": "Die Seite bedingungslos zur Beobachtungsliste des aktuellen Benutzers hinzufügen oder von ihr entfernen, Einstellungen verwenden oder Beobachtung nicht ändern.",
+ "apihelp-protect-example-protect": "Schützt eine Seite",
+ "apihelp-protect-example-unprotect": "Eine Seite entsperren, indem die Einschränkungen durch den Schutz auf <kbd>all</kbd> gestellt werden.",
+ "apihelp-protect-example-unprotect2": "Eine Seite entsperren, indem keine Einschränkungen übergeben werden",
+ "apihelp-purge-description": "Setzt den Cache der angegebenen Seiten zurück.\n\nFalls kein Benutzer angemeldet ist, müssen POST-Anfragen genutzt werden.",
+ "apihelp-purge-param-forcelinkupdate": "Aktualisiert die Linktabellen.",
+ "apihelp-purge-param-forcerecursivelinkupdate": "Aktualisiert die Linktabelle der Seite und alle Linktabellen der Seiten, die sie als Vorlage einbinden.",
+ "apihelp-purge-example-simple": "Purgt die <kbd>Main Page</kbd> und die <kbd>API</kbd>-Seite.",
+ "apihelp-purge-example-generator": "Purgt die ersten 10 Seiten des Hauptnamensraums.",
+ "apihelp-query-description": "Bezieht Daten von und über MediaWiki.\n\nAlle Änderungsvorgänge müssen unter Angabe eines Tokens ablaufen, um Missbrauch durch böswillige Anwendungen vorzubeugen.",
+ "apihelp-query-param-prop": "Zurückzuliefernde Eigenschaften der abgefragten Seiten.",
+ "apihelp-query-param-list": "Welche Listen abgerufen werden sollen.",
+ "apihelp-query-param-meta": "Zurückzugebende Metadaten.",
+ "apihelp-query-param-indexpageids": "Schließt einen zusätzlichen pageids-Abschnitt mit allen zurückgegebenen Seitenkennungen ein.",
+ "apihelp-query-param-export": "Exportiert die aktuellen Versionen der angegebenen oder generierten Seiten.",
+ "apihelp-query-param-exportnowrap": "Gibt den XML-Export zurück, ohne ihn in ein XML-Ergebnis einzuschließen (gleiches Format wie durch [[Special:Export]]). Kann nur zusammen mit $1export genutzt werden.",
+ "apihelp-query-param-iwurl": "Gibt an, ob die komplette URL zurückgegeben werden soll, wenn der Titel ein Interwikilink ist.",
+ "apihelp-query-param-continue": "Falls angegeben, wird query-continue als Schlüssel-Wert-Paar zurückgegeben, das anschließend an die Folgeabfrage gehängt werden kann. Dieser Parameter muss in der ersten Abfrage auf leer gesetzt werden.\n\nDieser Parameter ist für alle Neuentwicklungen empfohlen und wird in der nächsten API-Version Standard.",
+ "apihelp-query-param-rawcontinue": "Momentan unbeachtet. In Zukunft wird <var>$1continue</var> Standard, dieser Parameter wird dann benötigt, um die rohen <samp>query-continue</samp>-Daten zu erhalten.",
+ "apihelp-query-example-revisions": "Bezieht [[Special:ApiHelp/query+siteinfo|Seiteninformationen]] und [[Special:ApiHelp/query+revisions|Versionen]] der <kbd>Main Page</kbd>.",
+ "apihelp-query-example-allpages": "Bezieht Versionen von Seiten, die mit <kbd>API/</kbd> beginnen.",
+ "apihelp-query+allcategories-description": "Alle Kategorien aufzählen.",
+ "apihelp-query+allcategories-param-from": "Kategorie, bei der die Auflistung beginnen soll.",
+ "apihelp-query+allcategories-param-to": "Kategorie, bei der die Auflistung enden soll.",
+ "apihelp-query+allcategories-param-prefix": "Listet alle Kategorien auf, die mit dem angegebenen Wert beginnen.",
+ "apihelp-query+allcategories-param-dir": "Sortierrichtung.",
+ "apihelp-query+allcategories-param-min": "Gibt nur Kategorien zurück, die mindestens die angegebene Anzahl an Einträgen haben.",
+ "apihelp-query+allcategories-param-max": "Gibt nur Kategorien zurück, die höchstens die angegebene Anzahl an Einträgen haben.",
+ "apihelp-query+allcategories-param-limit": "Wie viele Kategorien zurückgegeben werden sollen.",
+ "apihelp-query+allcategories-param-prop": "Zurückzugebende Eigenschaften:\n;size: Ergänzt die Anzahl der Einträge in der Antwort.\n;hidden: Markiert über _&#95;HIDDENCAT_&#95; versteckte Kategorien.",
+ "apihelp-query+allcategories-example-size": "Listet Kategorien mit der Anzahl ihrer Einträge auf.",
+ "apihelp-query+allcategories-example-generator": "Bezieht Informationen über die Kategorieseite selbst für Kategorien, die mit <kbd>List</kbd> beginnen.",
+ "apihelp-query+alldeletedrevisions-description": "Bezieht alle gelöschten Versionen eines Benutzers oder eines Namensraumes.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Darf nur mit <var>$3user</var> verwendet werden.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Kann nicht zusammen mit <var>$3user</var> benutzt werden.",
+ "apihelp-query+alldeletedrevisions-param-start": "Der Zeitstempel, bei dem die Auflistung beginnen soll.",
+ "apihelp-query+alldeletedrevisions-param-end": "Der Zeitstempel, bei dem die Auflistung enden soll.",
+ "apihelp-query+alldeletedrevisions-param-from": "Seitentitel, bei dem die Auflistung beginnen soll.",
+ "apihelp-query+alldeletedrevisions-param-to": "Seitentitel, bei dem die Auflistung enden soll.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Listet alle Seitentitel auf, die mit dem angegebenen Wert beginnen.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Listet nur Versionen auf, die die angegebene Markierung haben.",
+ "apihelp-query+alldeletedrevisions-param-user": "Nur Versionen von diesem Benutzer auflisten.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Schließt Bearbeitungen des angegebenen Benutzers aus.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Nur Seiten in diesem Namensraum auflisten.",
+ "apihelp-query+allfileusages-param-limit": "Wie viele Gesamtobjekte zurückgegeben werden sollen.",
+ "apihelp-query+allfileusages-example-unique": "Einheitliche Dateititel auflisten",
+ "apihelp-query+allfileusages-example-generator": "Seiten abrufen, die die Dateien enthalten",
+ "apihelp-query+allimages-description": "Alle Bilder nacheinander auflisten.",
+ "apihelp-query+allimages-param-sha1": "SHA1-Hash des Bildes. Überschreibt $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "SHA1-Hash des Bildes (Basis 36; verwendet in MediaWiki).",
+ "apihelp-query+allimages-param-limit": "Wie viele Gesamtbilder zurückgegeben werden sollen.",
+ "apihelp-query+allimages-example-recent": "Zeigt eine Liste von kürzlich hochgeladenen Dateien ähnlich zu [[Special:NewFiles]].",
+ "apihelp-query+alllinks-example-unique": "Einheitlich verlinkte Titel auflisten",
+ "apihelp-query+allpages-param-filterredir": "Welche Seiten aufgelistet werden sollen.",
+ "apihelp-query+allredirects-example-unique": "Einzigartige Zielseiten auflisten.",
+ "apihelp-query+allredirects-example-generator": "Seiten abrufen, die die Weiterleitungen enthalten",
+ "apihelp-query+alltransclusions-param-namespace": "Der aufzulistende Namensraum.",
+ "apihelp-query+alltransclusions-example-unique": "Einzigartige eingebundene Titel auflisten.",
+ "apihelp-query+allusers-param-limit": "Wie viele Benutzernamen insgesamt zurückgegeben werden sollen.",
+ "apihelp-query+allusers-example-Y": "Benutzer ab <kbd>Y</kbd> auflisten.",
+ "apihelp-query+backlinks-description": "Alle Seiten finden, die auf die angegebene Seite verlinken.",
+ "apihelp-query+backlinks-example-simple": "Links auf <kbd>Hauptseite</kbd> anzeigen.",
+ "apihelp-query+blocks-example-simple": "Sperren auflisten",
+ "apihelp-query+categorymembers-param-startsortkey": "Stattdessen $1starthexsortkey verwenden.",
+ "apihelp-query+categorymembers-param-endsortkey": "Stattdessen $1endhexsortkey verwenden.",
+ "apihelp-query+contributors-param-limit": "Wie viele Spender zurückgegeben werden sollen.",
+ "apihelp-query+deletedrevisions-param-user": "Nur Versionen von diesem Benutzer auflisten.",
+ "apihelp-query+deletedrevisions-param-limit": "Die Maximalmenge der aufzulistenden Versionen.",
+ "apihelp-query+deletedrevs-param-from": "Auflistung bei diesem Titel beginnen.",
+ "apihelp-query+deletedrevs-param-to": "Auflistung bei diesem Titel beenden.",
+ "apihelp-query+duplicatefiles-param-localonly": "Sucht nur nach Dateien im lokalen Repositorium.",
+ "apihelp-query+duplicatefiles-example-simple": "Sucht nach Duplikaten von [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "Sucht nach Duplikaten aller Dateien.",
+ "apihelp-query+embeddedin-param-namespace": "Der aufzulistende Namensraum.",
+ "apihelp-query+embeddedin-param-filterredir": "Wie Weiterleitungen behandelt werden sollen.",
+ "apihelp-query+embeddedin-param-limit": "Wie viele Seiten insgesamt zurückgegeben werden sollen.",
+ "apihelp-query+extlinks-param-limit": "Wie viele Links zurückgegeben werden sollen.",
+ "apihelp-query+exturlusage-param-limit": "Wie viele Seiten zurückgegeben werden sollen.",
+ "apihelp-query+filearchive-param-from": "Der Bildertitel, bei dem die Auflistung beginnen soll.",
+ "apihelp-query+filearchive-param-to": "Der Bildertitel, bei dem die Auflistung enden soll.",
+ "apihelp-query+filearchive-param-limit": "Wie viele Bilder insgesamt zurückgegeben werden sollen.",
+ "apihelp-query+filearchive-example-simple": "Eine Liste aller gelöschten Dateien auflisten",
+ "apihelp-query+imageinfo-param-limit": "Wie viele Dateiversionen pro Datei zurückgegeben werden sollen.",
+ "apihelp-query+imageinfo-param-start": "Zeitstempel, von dem die Liste beginnen soll.",
+ "apihelp-query+imageinfo-param-end": "Zeitstempel, an dem die Liste enden soll.",
+ "apihelp-query+imageinfo-param-urlheight": "Ähnlich wie $1urlwidth.",
+ "apihelp-query+info-description": "Ruft Basisinformationen über die Seite ab.",
+ "apihelp-query+info-param-testactions": "Überprüft, ob der aktuelle Benutzer gewisse Aktionen auf der Seite ausführen kann.",
+ "apihelp-query+iwbacklinks-param-prefix": "Präfix für das Interwiki.",
+ "apihelp-query+langbacklinks-param-limit": "Wie viele Gesamtseiten zurückgegeben werden sollen.",
+ "apihelp-query+links-example-simple": "Links von der <kbd>Hauptseite</kbd> abrufen",
+ "apihelp-query+linkshere-description": "Alle Seiten finden, die auf die angegebenen Seiten verlinken.",
+ "apihelp-query+logevents-description": "Ereignisse von den Logbüchern abrufen.",
+ "apihelp-query+prefixsearch-param-search": "Such-Zeichenfolge.",
+ "apihelp-query+search-example-simple": "Nach <kbd>meaning</kbd> suchen.",
+ "apihelp-query+search-example-text": "Texte nach <kbd>meaning</kbd> durchsuchen.",
+ "apihelp-query+siteinfo-example-simple": "Websiteinformationen abrufen",
+ "apihelp-query+tags-description": "Änderungs-Tags auflisten.",
+ "apihelp-query+tags-example-simple": "Verfügbare Tags auflisten",
+ "apihelp-query+usercontribs-description": "Alle Bearbeitungen von einem Benutzer abrufen.",
+ "apihelp-query+userinfo-example-simple": "Informationen über den aktuellen Benutzer abrufen",
+ "apihelp-query+users-description": "Informationen über eine Liste von Benutzern abrufen.",
+ "apihelp-rsd-description": "Ein RSD-Schema (Really Simple Discovery) exportieren.",
+ "apihelp-rsd-example-simple": "Das RSD-Schema exportieren",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "An allen beobachteten Seiten arbeiten.",
+ "apihelp-unblock-description": "Einen Benutzer freigeben.",
+ "apihelp-unblock-param-reason": "Grund für die Freigabe.",
+ "apihelp-unblock-example-id": "Sperrkennung #<kbd>105</kbd> freigeben.",
+ "apihelp-undelete-param-reason": "Grund für die Wiederherstellung.",
+ "apihelp-upload-param-filename": "Ziel-Dateiname.",
+ "apihelp-upload-param-watch": "Die Seite beobachten.",
+ "apihelp-upload-param-file": "Dateiinhalte.",
+ "apihelp-upload-param-url": "URL, von der die Datei abgerufen werden soll.",
+ "apihelp-upload-example-url": "Von einer URL hochladen",
+ "apihelp-userrights-param-user": "Benutzername.",
+ "apihelp-userrights-param-userid": "Benutzerkennung.",
+ "apihelp-watch-example-watch": "Die Seite <kbd>Hauptseite</kbd> beobachten.",
+ "apihelp-format-example-generic": "Das Abfrageergebnis im $1-Format formatieren",
+ "apihelp-dbg-description": "Daten im PHP-<code>var_export()</code>-Format ausgeben.",
+ "apihelp-dbgfm-description": "Daten im PHP-<code>var_export()</code>-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-dump-description": "Daten im PHP-<code>var_dump()</code>-Format ausgeben.",
+ "apihelp-dumpfm-description": "Daten im PHP-<code>var_dump()</code>-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-json-description": "Daten im JSON-Format ausgeben.",
+ "apihelp-json-param-callback": "Falls angegeben, wird die Ausgabe in einen angegebenen Funktionsaufruf eingeschlossen. Aus Sicherheitsgründen sind benutzerspezifische Daten beschränkt.",
+ "apihelp-json-param-utf8": "Falls angegeben, kodiert die meisten (aber nicht alle) Nicht-ASCII-Zeichen als UTF-8 anstatt sie mit hexadezimalen Escape-Sequenzen zu ersetzen.",
+ "apihelp-jsonfm-description": "Daten im JSON-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-none-description": "Nichts ausgeben.",
+ "apihelp-php-description": "Daten im serialisierten PHP-Format ausgeben.",
+ "apihelp-phpfm-description": "Daten im serialisierten PHP-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-rawfm-description": "Daten mit den Fehlerbehebungselementen im JSON-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-txt-description": "Daten im PHP-<code>print_r()</code>-Format ausgeben.",
+ "apihelp-txtfm-description": "Daten im PHP-<code>print_r()</code>-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-wddx-description": "Daten im WDDX-Format ausgeben.",
+ "apihelp-wddxfm-description": "Daten im WDDX-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-xml-description": "Daten im XML-Format ausgeben.",
+ "apihelp-xml-param-xslt": "Falls angegeben, fügt die benannte Seite als XSL-Stylesheet hinzu. Der Wert muss ein Titel im Namensraum „{{ns:mediawiki}}“ sein und mit <code>.xsl</code> enden.",
+ "apihelp-xml-param-includexmlnamespace": "Falls angegeben, ergänzt einen XML-Namensraum.",
+ "apihelp-xmlfm-description": "Daten im XML-Format ausgeben (schöngedruckt in HTML).",
+ "apihelp-yaml-description": "Daten im YAML-Format ausgeben.",
+ "apihelp-yamlfm-description": "Daten im YAML-Format ausgeben (schöngedruckt in HTML).",
+ "api-format-title": "MediaWiki-API-Ergebnis",
+ "api-format-prettyprint-header": "Dies ist die HTML-Repräsentation des $1-Formats. HTML ist zur Fehlerbehebung gut, aber unpassend für den Anwendungsgebrauch.\n\nGib den Parameter <var>Format</var> an, um das Ausgabeformat zu ändern. Um die Nicht-HTML-Repräsentation des $1-Formats anzusehen, lege <kbd>format=$2</kbd> fest.\n\nSiehe die [[mw:API|vollständige Dokumentation]] oder die [[Special:ApiHelp/main|API-Hilfe]] für weitere Informationen.",
+ "api-orm-param-props": "Felder an die Anfrage.",
+ "api-orm-param-limit": "Maximale Anzahl zurückgegebender Zeilen.",
+ "api-pageset-param-titles": "Eine Liste der Titel, an denen gearbeitet werden soll.",
+ "api-pageset-param-pageids": "Eine Liste der Seitenkennungen, an denen gearbeitet werden soll.",
+ "api-pageset-param-revids": "Eine Liste der Versionskennungen, an denen gearbeitet werden soll.",
+ "api-help-title": "MediaWiki-API-Hilfe",
+ "api-help-lead": "Dies ist eine automatisch generierte MediaWiki-API-Dokumentationsseite.\n\nDokumentation und Beispiele: https://www.mediawiki.org/wiki/API/de",
+ "api-help-main-header": "Hauptmodul",
+ "api-help-flag-deprecated": "Dieses Modul ist veraltet.",
+ "api-help-flag-internal": "<strong>Dieses Modul ist intern oder instabil.</strong> Seine Operationen werden ohne Kenntnisnahme geändert.",
+ "api-help-flag-readrights": "Dieses Modul erfordert Leserechte.",
+ "api-help-flag-writerights": "Dieses Modul erfordert Schreibrechte.",
+ "api-help-flag-mustbeposted": "Dieses Modul akzeptiert nur POST-Anfragen.",
+ "api-help-flag-generator": "Dieses Modul kann als Generator verwendet werden.",
+ "api-help-parameters": "{{PLURAL:$1|Parameter}}:",
+ "api-help-param-deprecated": "Veraltet.",
+ "api-help-param-required": "Dieser Parameter ist erforderlich.",
+ "api-help-param-list": "{{PLURAL:$1|1=Ein Wert|2=Werte (mit <kbd>{{!}}</kbd> trennen)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Muss leer sein|Kann leer sein oder $2}}",
+ "api-help-param-limit": "Nicht mehr als $1 erlaubt.",
+ "api-help-param-limit2": "Nicht mehr als $1 ($2 für Bots) erlaubt.",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=Der Wert darf|2=Die Werte dürfen}} nicht kleiner sein als $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=Der Wert darf|2=Die Werte dürfen}} nicht größer sein als $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=Der Wert muss|2=Die Werte müssen}} zwischen $2 und $3 sein.",
+ "api-help-param-upload": "Muss als Dateiupload mithilfe eines multipart/form-data-Formular bereitgestellt werden.",
+ "api-help-param-multi-separate": "Werte mit <kbd>|</kbd> trennen.",
+ "api-help-param-multi-max": "Maximale Anzahl der Werte ist {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} für Bots).",
+ "api-help-param-default": "Standard: $1",
+ "api-help-param-default-empty": "Standard: <span class=\"apihelp-empty\">(leer)</span>",
+ "api-help-param-token": "Ein „$1“-Token abgerufen von [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(keine Beschreibung)</span>",
+ "api-help-examples": "{{PLURAL:$1|Beispiel|Beispiele}}:",
+ "api-help-permissions": "{{PLURAL:$1|Berechtigung|Berechtigungen}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Gewährt an}}: $2",
+ "api-help-right-apihighlimits": "Höhere Beschränkungen in API-Anfragen verwenden (langsame Anfragen: $1; schnelle Anfragen: $2). Die Beschränkungen für langsame Anfragen werden auch auf Mehrwertparameter angewandt.",
+ "api-credits-header": "Danksagungen",
+ "api-credits": "API-Entwickler:\n* Roan Kattouw (Hauptentwickler von September 2007 bis 2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (Autor, Hauptentwickler von September 2006 bis September 2007)\n* Brad Jorsch (Hauptentwickler seit 2013)\n\nBitte sende deine Kommentare, Vorschläge und Fragen an mediawiki-api@lists.wikimedia.org\noder reiche einen Fehlerbericht auf https://phabricator.wikimedia.org/ ein."
+}
diff --git a/includes/api/i18n/el.json b/includes/api/i18n/el.json
new file mode 100644
index 00000000..d4d239f4
--- /dev/null
+++ b/includes/api/i18n/el.json
@@ -0,0 +1,12 @@
+{
+ "@metadata": {
+ "authors": [
+ "Glavkos"
+ ]
+ },
+ "apihelp-block-description": "Φραγή χρήστη",
+ "apihelp-block-param-user": "Όνομα χρήστη, διεύθυνση IP ή εύρος διευθύνσεων IP που θέλετε να επιβάλετε φραγή.",
+ "apihelp-block-param-reason": "Λόγος φραγής.",
+ "apihelp-createaccount-param-name": "Όνομα χρήστη.",
+ "apihelp-delete-description": "Διαγραφή σελίδας."
+}
diff --git a/includes/api/i18n/en-gb.json b/includes/api/i18n/en-gb.json
new file mode 100644
index 00000000..929ec7e0
--- /dev/null
+++ b/includes/api/i18n/en-gb.json
@@ -0,0 +1,156 @@
+{
+ "@metadata": {
+ "authors": [
+ "Reedy",
+ "Chase me ladies, I'm the Cavalry"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> All features shown on this page should be working, but the API is still in active development, and may change at any time. Subscribe to [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] for notice of updates.\n\n<strong>Erroneous requests:</strong> When erroneous requests are sent to the API, an HTTP header will be sent with the key \"MediaWiki-API-Error\" and then both the value of the header and the error code sent back will be set to the same value. For more information see [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+ "apihelp-main-param-maxage": "Set the <code>max-age</code> header to this many seconds. Errors are never cached.",
+ "apihelp-main-param-assert": "Verify the user is logged in if set to <kbd>user</kbd>, or has the bot userright if <kbd>bot</kbd>.",
+ "apihelp-block-param-user": "Username, IP address, or IP range to block.",
+ "apihelp-block-param-allowusertalk": "Allow the user to edit their own talk page (depends on <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-watchuser": "Watch the user and talk pages of the user or IP address.",
+ "apihelp-block-example-ip-simple": "Block IP address <kbd>192.0.2.5</kbd> for three days with reason <kbd>First strike</kbd>.",
+ "apihelp-clearhasmsg-description": "Clears the <code>hasmsg</code> flag for the current user.",
+ "apihelp-compare-description": "Get the difference between 2 pages.\n\nA revision number, a page title, or a page ID for both \"from\" and \"to\" must be passed.",
+ "apihelp-createaccount-param-password": "Password (ignored if <var>$1mailpassword</var> is set).",
+ "apihelp-delete-param-title": "Title of the page to delete. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-delete-param-watch": "Add the page to the current user's watchlist.",
+ "apihelp-delete-example-simple": "Delete <kbd>Main Page</kbd>.",
+ "apihelp-delete-example-reason": "Delete <kbd>Main Page</kbd> with the reason <kbd>Preparing for move</kbd>.",
+ "apihelp-edit-param-title": "Title of the page to edit. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-edit-param-watch": "Add the page to the current user's watchlist.",
+ "apihelp-edit-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-edit-param-contentformat": "Content serialisation format used for the input text.",
+ "apihelp-edit-example-prepend": "Prepend <kbd>_&#95;NOTOC_&#95;</kbd> to a page.",
+ "apihelp-expandtemplates-example-simple": "Expand the wikitext <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Hide changes made by the current user.",
+ "apihelp-filerevert-example-revert": "Revert <kbd>Wiki.png</kbd> to the version of <kbd>2011-03-05T15:27:40Z</kbd>.",
+ "apihelp-help-example-main": "Help for the main module.",
+ "apihelp-help-example-query": "Help for two query submodules.",
+ "apihelp-import-description": "Import a page from another wiki, or an XML file.\n\nNote that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when sending a file for the <var>xml</var> parameter.",
+ "apihelp-login-example-gettoken": "Retrieve a login token.",
+ "apihelp-logout-example-logout": "Log the current user out.",
+ "apihelp-move-param-to": "Title to rename the page to.",
+ "apihelp-move-param-reason": "Reason for the rename.",
+ "apihelp-move-example-move": "Move <kbd>Badtitle</kbd> to <kbd>Goodtitle</kbd> without leaving a redirect.",
+ "apihelp-opensearch-example-te": "Find pages beginning with <kbd>Te</kbd>.",
+ "apihelp-options-param-resetkinds": "List of types of options to reset when the <var>$1reset</var> option is set.",
+ "apihelp-options-param-optionvalue": "A value of the option specified by <var>$1optionname</var>, can contain pipe characters.",
+ "apihelp-options-example-change": "Change <kbd>skin</kbd> and <kbd>hideminor</kbd> preferences.",
+ "apihelp-options-example-complex": "Reset all preferences, then set <kbd>skin</kbd> and <kbd>nickname</kbd>.",
+ "apihelp-paraminfo-param-querymodules": "List of query module names (value of <var>prop</var>, <var>meta</var> or <var>list</var> parameter). Use <kbd>$1modules=query+foo</kbd> instead of <kbd>$1querymodules=foo</kbd>.",
+ "apihelp-parse-param-pageid": "Parse the content of this page. Overrides <var>$1page</var>.",
+ "apihelp-parse-param-contentformat": "Content serialisation format used for the input text. Only valid when used with $1text.",
+ "apihelp-patrol-example-rcid": "Patrol a recent change.",
+ "apihelp-patrol-example-revid": "Patrol a revision.",
+ "apihelp-protect-param-protections": "List of protection levels, formatted <kbd>action=level</kbd> (e.g. <kbd>edit=sysop</kbd>).\n\n<strong>Note:</strong> Any actions not listed will have restrictions removed.",
+ "apihelp-protect-param-expiry": "Expiry timestamps. If only one timestamp is set, it will be used for all protections. Use <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, or <kbd>never</kbd>, for a never-expiring protection.",
+ "apihelp-protect-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-protect-example-unprotect2": "Unprotect a page by setting no restrictions.",
+ "apihelp-purge-example-simple": "Purge the <kbd>Main Page</kbd> and the <kbd>API</kbd> page.",
+ "apihelp-query-example-allpages": "Fetch revisions of pages beginning with <kbd>API/</kbd>.",
+ "apihelp-query+allcategories-example-generator": "Retrieve information about the category page for categories beginning <kbd>List</kbd>.",
+ "apihelp-query+allfileusages-example-unique-generator": "Gets all file titles, marking the missing ones.",
+ "apihelp-query+alllinks-param-unique": "Only show distinct linked titles. Cannot be used with <kbd>$1prop=ids</kbd>.\nWhen used as a generator, yields target pages instead of source pages.",
+ "apihelp-query+alllinks-example-B": "List linked titles, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-unique": "List unique linked titles.",
+ "apihelp-query+allmessages-example-ipb": "Show messages starting with <kbd>ipb-</kbd>.",
+ "apihelp-query+allmessages-example-de": "Show messages <kbd>august</kbd> and <kbd>mainpage</kbd> in German.",
+ "apihelp-query+allpages-example-B": "Show a list of pages starting at the letter <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-B": "List target pages, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-generator": "Gets pages containing the redirects.",
+ "apihelp-query+alltransclusions-example-unique": "List unique transcluded titles.",
+ "apihelp-query+alltransclusions-example-generator": "Gets pages containing the transclusions.",
+ "apihelp-query+backlinks-param-pageid": "Page ID to search. Cannot be used together with <var>$1title</var>.",
+ "apihelp-query+backlinks-param-limit": "How many total pages to return. If <var>$1redirect</var> is enabled, limit applies to each level separately (which means up to 2 * <var>$1limit</var> results may be returned).",
+ "apihelp-query+backlinks-example-generator": "Get information about pages linking to <kbd>Main page<kbd>.",
+ "apihelp-query+blocks-param-ip": "Get all blocks applying to this IP or CIDR range, including range blocks.\nThis cannot be used together with <var>$3users</var>. CIDR ranges broader than IPv4/$1 or IPv6/$2 will not be not accepted.",
+ "apihelp-query+blocks-example-simple": "List blocks.",
+ "apihelp-query+blocks-example-users": "List blocks of users <kbd>Alice</kbd> and <kbd>Bob</kbd>.",
+ "apihelp-query+categoryinfo-example-simple": "Get information about <kbd>Category:Foo</kbd> and <kbd>Category:Bar</kbd>.",
+ "apihelp-query+categorymembers-param-pageid": "Page ID of the category to enumerate. Cannot be used together with <var>$1title</var>.",
+ "apihelp-query+categorymembers-param-endhexsortkey": "Sortkey to end listing from, as returned by <kbd>$1prop=sortkey</kbd>. Can only be used with <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+deletedrevs-example-mode2": "List the last 50 deleted contributions by <kbd>Bob</kbd> (mode 2).",
+ "apihelp-query+deletedrevs-example-mode3-main": "List the first 50 deleted revisions in the main namespace (mode 3).",
+ "apihelp-query+deletedrevs-example-mode3-talk": "List the first 50 deleted pages in the {{ns:talk}} namespace (mode 3).",
+ "apihelp-query+duplicatefiles-example-simple": "Look for duplicates of [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "Look for duplicates of all files.",
+ "apihelp-query+extlinks-example-simple": "Get a list of external links on <kbd>Main Page<kbd>.",
+ "apihelp-query+exturlusage-param-protocol": "Protocol of the URL. If empty and <var>$1query</var> set, the protocol is <kbd>http</kbd>. Leave both this and <var>$1query</var> empty to list all external links.",
+ "apihelp-query+filerepoinfo-example-simple": "Get information about file repositories.",
+ "apihelp-query+imageinfo-param-metadataversion": "Version of metadata to use. If <kbd>latest</kbd> is specified, use latest version. Defaults to <kbd>1</kbd> for backwards compatibility.",
+ "apihelp-query+imageinfo-example-simple": "Fetch information about the current version of [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+images-example-simple": "Get a list of files used in the [[Main Page]].",
+ "apihelp-query+imageusage-example-simple": "Show pages using [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageusage-example-generator": "Get information about pages using [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+info-example-protection": "Get general and protection information about the page <kbd>Main Page</kbd>.",
+ "apihelp-query+iwbacklinks-example-simple": "Get pages linking to [[wikibooks:Test]].",
+ "apihelp-query+iwlinks-param-title": "Interwiki link to search for. Must be used with <var>$1prefix</var>.",
+ "apihelp-query+langbacklinks-example-simple": "Get pages linking to [[:fr:Test]].",
+ "apihelp-query+langbacklinks-example-generator": "Get information about pages linking to [[:fr:Test]].",
+ "apihelp-query+langlinks-param-title": "Link to search for. Must be used with <var>$1lang</var>.",
+ "apihelp-query+links-example-simple": "Get links from the page <kbd>Main Page</kbd>",
+ "apihelp-query+links-example-namespaces": "Get links from the page <kbd>Main Page</kbd> in the {{ns:user}} and {{ns:template}} namespaces.",
+ "apihelp-query+linkshere-example-simple": "Get a list of pages linking to the [[Main Page]].",
+ "apihelp-query+linkshere-example-generator": "Get information about pages linking to the [[Main Page]].",
+ "apihelp-query+logevents-example-simple": "List recent log events.",
+ "apihelp-query+pagepropnames-description": "List all page property names in use on the wiki.",
+ "apihelp-query+pageswithprop-description": "List all pages using a given page property.",
+ "apihelp-query+pageswithprop-example-generator": "Get page information about the first 10 pages using <code>_&#95;NOTOC_&#95;</code>.",
+ "apihelp-query+protectedtitles-example-generator": "Find links to protected titles in the main namespace.",
+ "apihelp-query+random-example-simple": "Return two random pages from the main namespace.",
+ "apihelp-query+random-example-generator": "Return page info about two random pages from the main namespace.",
+ "apihelp-query+recentchanges-example-simple": "List recent changes.",
+ "apihelp-query+redirects-example-generator": "Get information about all redirects to the [[Main Page]].",
+ "apihelp-query+revisions-example-first5-not-localhost": "Get first 5 revisions of the <kbd>Main Page</kbd> that were not made by anonymous user <kbd>127.0.0.1</kbd>.",
+ "apihelp-query+revisions+base-param-difftotext": "Text to diff each revision to. Only diffs a limited number of revisions. Overrides <var>$1diffto</var>. If <var>$1section</var> is set, only that section will be diffed against this text",
+ "apihelp-query+revisions+base-param-contentformat": "Serialisation format used for <var>$1difftotext</var> and expected for output of content.",
+ "apihelp-query+search-example-text": "Search texts for <kbd>meaning</kbd>.",
+ "apihelp-query+search-example-generator": "Get page information about the pages returned for a search for <kbd>meaning</kbd>.",
+ "apihelp-query+siteinfo-example-simple": "Fetch site information.",
+ "apihelp-query+siteinfo-example-replag": "Check the current replication lag.",
+ "apihelp-query+stashimageinfo-example-simple": "Returns information for a stashed file.",
+ "apihelp-query+tags-example-simple": "List available tags.",
+ "apihelp-query+templates-example-simple": "Get the templates used on the page <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-generator": "Get information about the template pages used on <kbd>Main Page</kbd>.",
+ "apihelp-query+tokens-example-simple": "Retrieve a csrf token (the default).",
+ "apihelp-query+tokens-example-types": "Retrieve a watch token and a patrol token.",
+ "apihelp-query+transcludedin-example-simple": "Get a list of pages transcluding <kbd>Main Page</kbd>.",
+ "apihelp-query+transcludedin-example-generator": "Get information about pages transcluding <kbd>Main Page</kbd>.",
+ "apihelp-query+usercontribs-example-user": "Show contributions of user <kbd>Example</kbd>.",
+ "apihelp-query+userinfo-example-simple": "Get information about the current user.",
+ "apihelp-query+watchlist-example-simple": "List the top revision for recently changed pages on the watchlist of the current user.",
+ "apihelp-query+watchlist-example-generator": "Fetch page info for recently changed pages on the current user's watchlist.",
+ "apihelp-query+watchlistraw-description": "Get all pages on the current user's watchlist.",
+ "apihelp-query+watchlistraw-example-simple": "List pages on the watchlist of the current user.",
+ "apihelp-query+watchlistraw-example-generator": "Fetch page info for pages on the current user's watchlist.",
+ "apihelp-revisiondelete-example-revision": "Hide content for revision <kbd>12345</kbd> on the page <kbd>Main Page</kbd>.",
+ "apihelp-rollback-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-rollback-example-simple": "Roll back the last edits to page <kbd>Main Page</kbd> by user <kbd>Example</kbd>.",
+ "apihelp-setnotificationtimestamp-example-allpages": "Reset the notification status for pages in the <kbd>{{ns:user}}</kbd> namespace.",
+ "apihelp-unblock-param-id": "ID of the block to unblock (obtained through <kbd>list=blocks</kbd>). Cannot be used together with <var>$1user</var>.",
+ "apihelp-undelete-param-timestamps": "Timestamps of the revisions to restore. If both <var>$1timestamps</var> and <var>$1fileids</var> are empty, all will be restored.",
+ "apihelp-undelete-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-undelete-example-page": "Undelete page <kbd>Main Page</kbd>.",
+ "apihelp-undelete-example-revisions": "Undelete two revisions of page <kbd>Main Page</kbd>.",
+ "apihelp-upload-param-comment": "Upload comment. Also used as the initial page text for new files if <var>$1text</var> is not specified.",
+ "apihelp-upload-example-url": "Upload from a URL.",
+ "apihelp-upload-example-filekey": "Complete an upload that failed due to warnings.",
+ "apihelp-userrights-example-userid": "Add the user with ID <kbd>123</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
+ "apihelp-watch-param-title": "The page to (un)watch. Use <var>$1titles</var> instead.",
+ "apihelp-watch-example-unwatch": "Unwatch the page <kbd>Main Page</kbd>.",
+ "apihelp-dbg-description": "Output data in PHP's <code>var_export()</code> format.",
+ "apihelp-dbgfm-description": "Output data in PHP's <code>var_export()</code> format (pretty-print in HTML).",
+ "apihelp-dump-description": "Output data in PHP's <code>var_dump()</code> format.",
+ "apihelp-php-description": "Output data in serialised PHP format.",
+ "apihelp-phpfm-description": "Output data in serialised PHP format (pretty-print in HTML).",
+ "apihelp-txt-description": "Output data in PHP's <code>print_r()</code> format.",
+ "apihelp-txtfm-description": "Output data in PHP's <code>print_r()</code> format (pretty-print in HTML).",
+ "api-pageset-param-redirects-generator": "Automatically resolve redirects in <var>$1titles</var>, <var>$1pageids</var>, and <var>$1revids</var>, and in pages returned by <var>$1generator</var>.",
+ "api-pageset-param-redirects-nogenerator": "Automatically resolve redirects in <var>$1titles</var>, <var>$1pageids</var>, and <var>$1revids</var>.",
+ "api-help-param-multi-separate": "Separate values with <kbd>|</kbd>.",
+ "api-help-param-disabled-in-miser-mode": "Disabled due to [[mw:Manual:$wgMiserMode|miser mode]].",
+ "api-help-param-limited-in-miser-mode": "<strong>Note:</strong> Due to [[mw:Manual:$wgMiserMode|miser mode]], using this may result in fewer than <var>$1limit</var> results returned before continuing; in extreme cases, zero results may be returned."
+}
diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json
new file mode 100644
index 00000000..36a4d812
--- /dev/null
+++ b/includes/api/i18n/en.json
@@ -0,0 +1,1169 @@
+{
+ "@metadata": {
+ "authors": [
+ "Anomie",
+ "Siebrand"
+ ]
+ },
+
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> All features shown on this page should be working, but the API is still in active development, and may change at any time. Subscribe to [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] for notice of updates.\n\n<strong>Erroneous requests:</strong> When erroneous requests are sent to the API, an HTTP header will be sent with the key \"MediaWiki-API-Error\" and then both the value of the header and the error code sent back will be set to the same value. For more information see [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+ "apihelp-main-param-action": "Which action to perform.",
+ "apihelp-main-param-format": "The format of the output.",
+ "apihelp-main-param-maxlag": "Maximum lag can be used when MediaWiki is installed on a database replicated cluster. To save actions causing any more site replication lag, this parameter can make the client wait until the replication lag is less than the specified value. In case of excessive lag, error code <samp>maxlag</samp> is returned with a message like <samp>Waiting for $host: $lag seconds lagged</samp>.<br />See [[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]] for more information.",
+ "apihelp-main-param-smaxage": "Set the <code>s-maxage</code> header to this many seconds. Errors are never cached.",
+ "apihelp-main-param-maxage": "Set the <code>max-age</code> header to this many seconds. Errors are never cached.",
+ "apihelp-main-param-assert": "Verify the user is logged in if set to <kbd>user</kbd>, or has the bot userright if <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Any value given here will be included in the response. May be used to distinguish requests.",
+ "apihelp-main-param-servedby": "Include the hostname that served the request in the results.",
+ "apihelp-main-param-curtimestamp": "Include the current timestamp in the result.",
+ "apihelp-main-param-origin": "When accessing the API using a cross-domain AJAX request (CORS), set this to the originating domain. This must be included in any pre-flight request, and therefore must be part of the request URI (not the POST body). This must match one of the origins in the <code>Origin</code> header exactly, so it has to be set to something like <kbd>https://en.wikipedia.org</kbd> or <kbd>https://meta.wikimedia.org</kbd>. If this parameter does not match the <code>Origin</code> header, a 403 response will be returned. If this parameter matches the <code>Origin</code> header and the origin is whitelisted, an <code>Access-Control-Allow-Origin</code> header will be set.",
+ "apihelp-main-param-uselang": "Language to use for message translations. A list of codes may be fetched from <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> with <kbd>siprop=languages</kbd>, or specify <kbd>user</kbd> to use the current user's language preference, or specify <kbd>content</kbd> to use this wiki's content language.",
+
+ "apihelp-block-description": "Block a user.",
+ "apihelp-block-param-user": "Username, IP address, or IP range to block.",
+ "apihelp-block-param-expiry": "Expiry time. May be relative (e.g. <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) or absolute (e.g. <kbd>2014-09-18T12:34:56Z</kbd>). If set to <kbd>infinite</kbd>, <kbd>indefinite</kbd>, or <kbd>never</kbd>, the block will never expire.",
+ "apihelp-block-param-reason": "Reason for block.",
+ "apihelp-block-param-anononly": "Block anonymous users only (i.e. disable anonymous edits for this IP address).",
+ "apihelp-block-param-nocreate": "Prevent account creation.",
+ "apihelp-block-param-autoblock": "Automatically block the last used IP address, and any subsequent IP addresses they try to login from.",
+ "apihelp-block-param-noemail": "Prevent user from sending email through the wiki. (Requires the <code>blockemail</code> right).",
+ "apihelp-block-param-hidename": "Hide the username from the block log. (Requires the <code>hideuser</code> right).",
+ "apihelp-block-param-allowusertalk": "Allow the user to edit their own talk page (depends on <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "If the user is already blocked, overwrite the existing block.",
+ "apihelp-block-param-watchuser": "Watch the user's or IP address's user and talk pages.",
+ "apihelp-block-example-ip-simple": "Block IP address <kbd>192.0.2.5</kbd> for three days with reason <kbd>First strike</kbd>.",
+ "apihelp-block-example-user-complex": "Block user <kbd>Vandal</kbd> indefinitely with reason <kbd>Vandalism</kbd>, and prevent new account creation and email sending.",
+
+ "apihelp-checktoken-description": "Check the validity of a token from <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+ "apihelp-checktoken-param-type": "Type of token being tested.",
+ "apihelp-checktoken-param-token": "Token to test.",
+ "apihelp-checktoken-param-maxtokenage": "Maximum allowed age of the token, in seconds.",
+ "apihelp-checktoken-example-simple": "Test the validity of a <kbd>csrf</kbd> token.",
+
+ "apihelp-clearhasmsg-description": "Clears the <code>hasmsg</code> flag for the current user.",
+ "apihelp-clearhasmsg-example-1": "Clear the <code>hasmsg</code> flag for the current user.",
+
+ "apihelp-compare-description": "Get the difference between 2 pages.\n\nA revision number, a page title, or a page ID for both \"from\" and \"to\" must be passed.",
+ "apihelp-compare-param-fromtitle": "First title to compare.",
+ "apihelp-compare-param-fromid": "First page ID to compare.",
+ "apihelp-compare-param-fromrev": "First revision to compare.",
+ "apihelp-compare-param-totitle": "Second title to compare.",
+ "apihelp-compare-param-toid": "Second page ID to compare.",
+ "apihelp-compare-param-torev": "Second revision to compare.",
+ "apihelp-compare-example-1": "Create a diff between revision 1 and 2.",
+
+ "apihelp-createaccount-description": "Create a new user account.",
+ "apihelp-createaccount-param-name": "Username.",
+ "apihelp-createaccount-param-password": "Password (ignored if <var>$1mailpassword</var> is set).",
+ "apihelp-createaccount-param-domain": "Domain for external authentication (optional).",
+ "apihelp-createaccount-param-token": "Account creation token obtained in first request.",
+ "apihelp-createaccount-param-email": "Email address of user (optional).",
+ "apihelp-createaccount-param-realname": "Real name of user (optional).",
+ "apihelp-createaccount-param-mailpassword": "If set to any value, a random password will be emailed to the user.",
+ "apihelp-createaccount-param-reason": "Optional reason for creating the account to be put in the logs.",
+ "apihelp-createaccount-param-language": "Language code to set as default for the user (optional, defaults to content language).",
+ "apihelp-createaccount-example-pass": "Create user <kbd>testuser</kbd> with password <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Create user <kbd>testmailuser</kbd> and email a randomly-generated password.",
+
+ "apihelp-delete-description": "Delete a page.",
+ "apihelp-delete-param-title": "Title of the page to delete. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "Page ID of the page to delete. Cannot be used together with <var>$1title</var>.",
+ "apihelp-delete-param-reason": "Reason for the deletion. If not set, an automatically generated reason will be used.",
+ "apihelp-delete-param-watch": "Add the page to the current user's watchlist.",
+ "apihelp-delete-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-delete-param-unwatch": "Remove the page from the current user's watchlist.",
+ "apihelp-delete-param-oldimage": "The name of the old image to delete as provided by [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+ "apihelp-delete-example-simple": "Delete <kbd>Main Page</kbd>.",
+ "apihelp-delete-example-reason": "Delete <kbd>Main Page</kbd> with the reason <kbd>Preparing for move</kbd>.",
+
+ "apihelp-disabled-description": "This module has been disabled.",
+
+ "apihelp-edit-description": "Create and edit pages.",
+ "apihelp-edit-param-title": "Title of the page to edit. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-edit-param-pageid": "Page ID of the page to edit. Cannot be used together with <var>$1title</var>.",
+ "apihelp-edit-param-section": "Section number. <kbd>0</kbd> for the top section, <kbd>new</kbd> for a new section.",
+ "apihelp-edit-param-sectiontitle": "The title for a new section.",
+ "apihelp-edit-param-text": "Page content.",
+ "apihelp-edit-param-summary": "Edit summary. Also section title when $1section=new and $1sectiontitle is not set.",
+ "apihelp-edit-param-tags": "Change tags to apply to the revision.",
+ "apihelp-edit-param-minor": "Minor edit.",
+ "apihelp-edit-param-notminor": "Non-minor edit.",
+ "apihelp-edit-param-bot": "Mark this edit as bot.",
+ "apihelp-edit-param-basetimestamp": "Timestamp of the base revision, used to detect edit conflicts. May be obtained through [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "Timestamp when the editing process began, used to detect edit conflicts. An appropriate value may be obtained using <var>[[Special:ApiHelp/main|curtimestamp]]</var> when beginning the edit process (e.g. when loading the page content to edit).",
+ "apihelp-edit-param-recreate": "Override any errors about the page having been deleted in the meantime.",
+ "apihelp-edit-param-createonly": "Don't edit the page if it exists already.",
+ "apihelp-edit-param-nocreate": "Throw an error if the page doesn't exist.",
+ "apihelp-edit-param-watch": "Add the page to the current user's watchlist.",
+ "apihelp-edit-param-unwatch": "Remove the page from the current user's watchlist.",
+ "apihelp-edit-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-edit-param-md5": "The MD5 hash of the $1text parameter, or the $1prependtext and $1appendtext parameters concatenated. If set, the edit won't be done unless the hash is correct.",
+ "apihelp-edit-param-prependtext": "Add this text to the beginning of the page. Overrides $1text.",
+ "apihelp-edit-param-appendtext": "Add this text to the end of the page. Overrides $1text.\n\nUse $1section=new to append a new section, rather than this parameter.",
+ "apihelp-edit-param-undo": "Undo this revision. Overrides $1text, $1prependtext and $1appendtext.",
+ "apihelp-edit-param-undoafter": "Undo all revisions from $1undo to this one. If not set, just undo one revision.",
+ "apihelp-edit-param-redirect": "Automatically resolve redirects.",
+ "apihelp-edit-param-contentformat": "Content serialization format used for the input text.",
+ "apihelp-edit-param-contentmodel": "Content model of the new content.",
+ "apihelp-edit-param-token": "The token should always be sent as the last parameter, or at least after the $1text parameter.",
+ "apihelp-edit-example-edit": "Edit a page.",
+ "apihelp-edit-example-prepend": "Prepend <kbd>_&#95;NOTOC_&#95;</kbd> to a page.",
+ "apihelp-edit-example-undo": "Undo revisions 13579 through 13585 with autosummary.",
+
+ "apihelp-emailuser-description": "Email a user.",
+ "apihelp-emailuser-param-target": "User to send email to.",
+ "apihelp-emailuser-param-subject": "Subject header.",
+ "apihelp-emailuser-param-text": "Mail body.",
+ "apihelp-emailuser-param-ccme": "Send a copy of this mail to me.",
+ "apihelp-emailuser-example-email": "Send an email to the User <kbd>WikiSysop</kbd> with the text <kbd>Content</kbd>.",
+
+ "apihelp-expandtemplates-description": "Expands all templates in wikitext.",
+ "apihelp-expandtemplates-param-title": "Title of page.",
+ "apihelp-expandtemplates-param-text": "Wikitext to convert.",
+ "apihelp-expandtemplates-param-revid": "Revision ID, for <nowiki>{{REVISIONID}}</nowiki> and similar variables.",
+ "apihelp-expandtemplates-param-prop": "Which pieces of information to get:\n;wikitext:The expanded wikitext.\n;categories:Any categories present in the input that are not represented in the wikitext output.\n;properties:Page properties defined by expanded magic words in the wikitext.\n;volatile:Whether the output is volatile and should not be reused elsewhere within the page.\n;ttl:The maximum time after which caches of the result should be invalidated.\n;parsetree:The XML parse tree of the input.\nNote that if no values are selected, the result will contain the wikitext, but the output will be in a deprecated format.",
+ "apihelp-expandtemplates-param-includecomments": "Whether to include HTML comments in the output.",
+ "apihelp-expandtemplates-param-generatexml": "Generate XML parse tree (replaced by $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Expand the wikitext <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+
+ "apihelp-feedcontributions-description": "Returns a user contributions feed.",
+ "apihelp-feedcontributions-param-feedformat": "The format of the feed.",
+ "apihelp-feedcontributions-param-user": "What users to get the contributions for.",
+ "apihelp-feedcontributions-param-namespace": "Which namespace to filter the contributions by.",
+ "apihelp-feedcontributions-param-year": "From year (and earlier).",
+ "apihelp-feedcontributions-param-month": "From month (and earlier).",
+ "apihelp-feedcontributions-param-tagfilter": "Filter contributions that have these tags.",
+ "apihelp-feedcontributions-param-deletedonly": "Show only deleted contributions.",
+ "apihelp-feedcontributions-param-toponly": "Only show edits that are latest revisions.",
+ "apihelp-feedcontributions-param-newonly": "Only show edits that are page creations.",
+ "apihelp-feedcontributions-param-showsizediff": "Show the size difference between revisions.",
+ "apihelp-feedcontributions-example-simple": "Return contributions for user <kbd>Example</kbd>.",
+
+ "apihelp-feedrecentchanges-description": "Returns a recent changes feed.",
+ "apihelp-feedrecentchanges-param-feedformat": "The format of the feed.",
+ "apihelp-feedrecentchanges-param-namespace": "Namespace to limit the results to.",
+ "apihelp-feedrecentchanges-param-invert": "All namespaces but the selected one.",
+ "apihelp-feedrecentchanges-param-associated": "Include associated (talk or main) namespace.",
+ "apihelp-feedrecentchanges-param-days": "Days to limit the results to.",
+ "apihelp-feedrecentchanges-param-limit": "Maximum number of results to return.",
+ "apihelp-feedrecentchanges-param-from": "Show changes since then.",
+ "apihelp-feedrecentchanges-param-hideminor": "Hide minor changes.",
+ "apihelp-feedrecentchanges-param-hidebots": "Hide changes made by bots.",
+ "apihelp-feedrecentchanges-param-hideanons": "Hide changes made by anonymous users.",
+ "apihelp-feedrecentchanges-param-hideliu": "Hide changes made by registered users.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Hide patrolled changes.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Hide changes made by the current user.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filter by tag.",
+ "apihelp-feedrecentchanges-param-target": "Show only changes on pages linked from this page.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Show changes on pages linked to the selected page instead.",
+ "apihelp-feedrecentchanges-example-simple": "Show recent changes.",
+ "apihelp-feedrecentchanges-example-30days": "Show recent changes for 30 days.",
+
+ "apihelp-feedwatchlist-description": "Returns a watchlist feed.",
+ "apihelp-feedwatchlist-param-feedformat": "The format of the feed.",
+ "apihelp-feedwatchlist-param-hours": "List pages modified within this many hours from now.",
+ "apihelp-feedwatchlist-param-linktosections": "Link directly to changed sections if possible.",
+ "apihelp-feedwatchlist-example-default": "Show the watchlist feed.",
+ "apihelp-feedwatchlist-example-all6hrs": "Show all changes to watched pages in the past 6 hours.",
+
+ "apihelp-filerevert-description": "Revert a file to an old version.",
+ "apihelp-filerevert-param-filename": "Target filename, without the File: prefix.",
+ "apihelp-filerevert-param-comment": "Upload comment.",
+ "apihelp-filerevert-param-archivename": "Archive name of the revision to revert to.",
+ "apihelp-filerevert-example-revert": "Revert <kbd>Wiki.png</kbd> to the version of <kbd>2011-03-05T15:27:40Z</kbd>.",
+
+ "apihelp-help-description": "Display help for the specified modules.",
+ "apihelp-help-param-modules": "Modules to display help for (values of the <var>action</var> and <var>format</var> parameters, or <kbd>main</kbd>). Can specify submodules with a <kbd>+</kbd>.",
+ "apihelp-help-param-submodules": "Include help for submodules of the named module.",
+ "apihelp-help-param-recursivesubmodules": "Include help for submodules recursively.",
+ "apihelp-help-param-helpformat": "Format of the help output.",
+ "apihelp-help-param-wrap": "Wrap the output in a standard API response structure.",
+ "apihelp-help-param-toc": "Include a table of contents in the HTML output.",
+ "apihelp-help-example-main": "Help for the main module.",
+ "apihelp-help-example-recursive": "All help in one page.",
+ "apihelp-help-example-help": "Help for the help module itself.",
+ "apihelp-help-example-query": "Help for two query submodules.",
+
+ "apihelp-imagerotate-description": "Rotate one or more images.",
+ "apihelp-imagerotate-param-rotation": "Degrees to rotate image clockwise.",
+ "apihelp-imagerotate-example-simple": "Rotate <kbd>File:Example.png</kbd> by <kbd>90</kbd> degrees.",
+ "apihelp-imagerotate-example-generator": "Rotate all images in <kbd>Category:Flip</kbd> by <kbd>180</kbd> degrees.",
+
+ "apihelp-import-description": "Import a page from another wiki, or an XML file.\n\nNote that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when sending a file for the <var>xml</var> parameter.",
+ "apihelp-import-param-summary": "Import summary.",
+ "apihelp-import-param-xml": "Uploaded XML file.",
+ "apihelp-import-param-interwikisource": "For interwiki imports: wiki to import from.",
+ "apihelp-import-param-interwikipage": "For interwiki imports: page to import.",
+ "apihelp-import-param-fullhistory": "For interwiki imports: import the full history, not just the current version.",
+ "apihelp-import-param-templates": "For interwiki imports: import all included templates as well.",
+ "apihelp-import-param-namespace": "For interwiki imports: import to this namespace.",
+ "apihelp-import-param-rootpage": "Import as subpage of this page.",
+ "apihelp-import-example-import": "Import [[meta:Help:Parserfunctions]] to namespace 100 with full history.",
+
+ "apihelp-login-description": "Log in and get authentication cookies.\n\nIn the event of a successful log-in, the needed cookies will be included in the HTTP response headers. In the event of a failed log-in, further attempts may be throttled to limit automated password guessing attacks.",
+ "apihelp-login-param-name": "User name.",
+ "apihelp-login-param-password": "Password.",
+ "apihelp-login-param-domain": "Domain (optional).",
+ "apihelp-login-param-token": "Login token obtained in first request.",
+ "apihelp-login-example-gettoken": "Retrieve a login token.",
+ "apihelp-login-example-login": "Log in.",
+
+ "apihelp-logout-description": "Log out and clear session data.",
+ "apihelp-logout-example-logout": "Log the current user out.",
+
+ "apihelp-managetags-description": "Perform management tasks relating to change tags.",
+ "apihelp-managetags-param-operation": "Which operation to perform:\n;create:Create a new change tag for manual use.\n;delete:Remove a change tag from the database, including removing the tag from all revisions, recent change entries and log entries on which it is used.\n;activate:Activate a change tag, allowing users to apply it manually.\n;deactivate:Deactivate a change tag, preventing users from applying it manually.",
+ "apihelp-managetags-param-tag": "Tag to create, delete, activate or deactivate. For tag creation, the tag must not exist. For tag deletion, the tag must exist. For tag activation, the tag must exist and not be in use by an extension. For tag deactivation, the tag must be currently active and manually defined.",
+ "apihelp-managetags-param-reason": "An optional reason for creating, deleting, activating or deactivating the tag.",
+ "apihelp-managetags-param-ignorewarnings": "Whether to ignore any warnings that are issued during the operation.",
+ "apihelp-managetags-example-create": "Create a tag named <kbd>spam</kbd> with the reason <kbd>For use in edit patrolling</kbd>",
+ "apihelp-managetags-example-delete": "Delete the <kbd>vandlaism</kbd> tag with the reason <kbd>Misspelt</kbd>",
+ "apihelp-managetags-example-activate": "Activate a tag named <kbd>spam</kbd> with the reason <kbd>For use in edit patrolling</kbd>",
+ "apihelp-managetags-example-deactivate": "Deactivate a tag named <kbd>spam</kbd> with the reason <kbd>No longer required</kbd>",
+
+ "apihelp-move-description": "Move a page.",
+ "apihelp-move-param-from": "Title of the page to rename. Cannot be used together with <var>$1fromid</var>.",
+ "apihelp-move-param-fromid": "Page ID of the page to rename. Cannot be used together with <var>$1from</var>.",
+ "apihelp-move-param-to": "Title to rename the page to.",
+ "apihelp-move-param-reason": "Reason for the rename.",
+ "apihelp-move-param-movetalk": "Rename the talk page, if it exists.",
+ "apihelp-move-param-movesubpages": "Rename subpages, if applicable.",
+ "apihelp-move-param-noredirect": "Don't create a redirect.",
+ "apihelp-move-param-watch": "Add the page and the redirect to the current user's watchlist.",
+ "apihelp-move-param-unwatch": "Remove the page and the redirect from the current user's watchlist.",
+ "apihelp-move-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-move-param-ignorewarnings": "Ignore any warnings.",
+ "apihelp-move-example-move": "Move <kbd>Badtitle</kbd> to <kbd>Goodtitle</kbd> without leaving a redirect.",
+
+ "apihelp-opensearch-description": "Search the wiki using the OpenSearch protocol.",
+ "apihelp-opensearch-param-search": "Search string.",
+ "apihelp-opensearch-param-limit": "Maximum number of results to return.",
+ "apihelp-opensearch-param-namespace": "Namespaces to search.",
+ "apihelp-opensearch-param-suggest": "Do nothing if <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> is false.",
+ "apihelp-opensearch-param-redirects": "How to handle redirects:\n;return:Return the redirect itself.\n;resolve:Return the target page. May return fewer than $1limit results.\nFor historical reasons, the default is \"return\" for $1format=json and \"resolve\" for other formats.",
+ "apihelp-opensearch-param-format": "The format of the output.",
+ "apihelp-opensearch-param-warningsaserror": "If warnings are raised with <kbd>format=json</kbd>, return an API error instead of ignoring them.",
+ "apihelp-opensearch-example-te": "Find pages beginning with <kbd>Te</kbd>.",
+
+ "apihelp-options-description": "Change preferences of the current user.\n\nOnly options which are registered in core or in one of installed extensions, or options with keys prefixed with \"userjs-\" (intended to be used by user scripts), can be set.",
+ "apihelp-options-param-reset": "Resets preferences to the site defaults.",
+ "apihelp-options-param-resetkinds": "List of types of options to reset when the <var>$1reset</var> option is set.",
+ "apihelp-options-param-change": "List of changes, formatted name=value (e.g. skin=vector). Value cannot contain pipe characters. If no value is given (not even an equals sign), e.g., optionname|otheroption|..., the option will be reset to its default value.",
+ "apihelp-options-param-optionname": "A name of a option which should be set to the value given by <var>$1optionvalue</var>.",
+ "apihelp-options-param-optionvalue": "A value of the option specified by <var>$1optionname</var>, can contain pipe characters.",
+ "apihelp-options-example-reset": "Reset all preferences.",
+ "apihelp-options-example-change": "Change <kbd>skin</kbd> and <kbd>hideminor</kbd> preferences.",
+ "apihelp-options-example-complex": "Reset all preferences, then set <kbd>skin</kbd> and <kbd>nickname</kbd>.",
+
+ "apihelp-paraminfo-description": "Obtain information about API modules.",
+ "apihelp-paraminfo-param-modules": "List of module names (values of the <var>action</var> and <var>format</var> parameters, or <kbd>main</kbd>). Can specify submodules with a <kbd>+</kbd>.",
+ "apihelp-paraminfo-param-helpformat": "Format of help strings.",
+ "apihelp-paraminfo-param-querymodules": "List of query module names (value of <var>prop</var>, <var>meta</var> or <var>list</var> parameter). Use <kbd>$1modules=query+foo</kbd> instead of <kbd>$1querymodules=foo</kbd>.",
+ "apihelp-paraminfo-param-mainmodule": "Get information about the main (top-level) module as well. Use <kbd>$1modules=main</kbd> instead.",
+ "apihelp-paraminfo-param-pagesetmodule": "Get information about the pageset module (providing titles= and friends) as well.",
+ "apihelp-paraminfo-param-formatmodules": "List of format module names (value of <var>format</var> parameter). Use <var>$1modules</var> instead.",
+ "apihelp-paraminfo-example-1": "Show info for <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, and <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+
+ "apihelp-parse-description": "Parses content and returns parser output.\n\nSee the various prop-modules of <kbd>[[Special:ApiHelp/query|action=query]]</kbd> to get information from the current version of a page.\n\nThere are several ways to specify the text to parse:\n# Specify a page or revision, using <var>$1page</var>, <var>$1pageid</var>, or <var>$1oldid</var>.\n# Specify content explicitly, using <var>$1text</var>, <var>$1title</var>, and <var>$1contentmodel</var>.\n# Specify only a summary to parse. <var>$1prop</var> should be given an empty value.",
+ "apihelp-parse-param-title": "Title of page the text belongs to. If omitted, <var>$1contentmodel</var> must be specified, and [[API]] will be used as the title.",
+ "apihelp-parse-param-text": "Text to parse. Use <var>$1title</var> or <var>$1contentmodel</var> to control the content model.",
+ "apihelp-parse-param-summary": "Summary to parse.",
+ "apihelp-parse-param-page": "Parse the content of this page. Cannot be used together with <var>$1text</var> and <var>$1title</var>.",
+ "apihelp-parse-param-pageid": "Parse the content of this page. Overrides <var>$1page</var>.",
+ "apihelp-parse-param-redirects": "If <var>$1page</var> or <var>$1pageid</var> is set to a redirect, resolve it.",
+ "apihelp-parse-param-oldid": "Parse the content of this revision. Overrides <var>$1page</var> and <var>$1pageid</var>.",
+ "apihelp-parse-param-prop": "Which pieces of information to get:\n;text:Gives the parsed text of the wikitext.\n;langlinks:Gives the language links in the parsed wikitext.\n;categories:Gives the categories in the parsed wikitext.\n;categorieshtml:Gives the HTML version of the categories.\n;links:Gives the internal links in the parsed wikitext.\n;templates:Gives the templates in the parsed wikitext.\n;images:Gives the images in the parsed wikitext.\n;externallinks:Gives the external links in the parsed wikitext.\n;sections:Gives the sections in the parsed wikitext.\n;revid:Adds the revision ID of the parsed page.\n;displaytitle:Adds the title of the parsed wikitext.\n;headitems:Gives items to put in the &lt;head&gt; of the page.\n;headhtml:Gives parsed &lt;head&gt; of the page.\n;modules:Gives the ResourceLoader modules used on the page.\n;indicators:Gives the HTML of page status indicators used on the page.\n;iwlinks:Gives interwiki links in the parsed wikitext.\n;wikitext:Gives the original wikitext that was parsed.\n;properties:Gives various properties defined in the parsed wikitext.\n;limitreportdata:Gives the limit report in a structured way. Gives no data, when $1disablepp is set.\n;limitreporthtml:Gives the HTML version of the limit report. Gives no data, when $1disablepp is set.",
+ "apihelp-parse-param-pst": "Do a pre-save transform on the input before parsing it. Only valid when used with text.",
+ "apihelp-parse-param-onlypst": "Do a pre-save transform (PST) on the input, but don't parse it. Returns the same wikitext, after a PST has been applied. Only valid when used with <var>$1text</var>.",
+ "apihelp-parse-param-effectivelanglinks": "Includes language links supplied by extensions (for use with <kbd>$1prop=langlinks</kbd>).",
+ "apihelp-parse-param-section": "Only retrieve the content of this section number or when <kbd>new</kbd> generate a new section.\n\n<kbd>new</kbd> section is only honored when specifying <var>text</var>.",
+ "apihelp-parse-param-sectiontitle": "New section title when <var>section</var> is <kbd>new</kbd>.\n\nUnlike page editing, this does not fall back to <var>summary</var> when omitted or empty.",
+ "apihelp-parse-param-disablepp": "Disable the PP Report from the parser output.",
+ "apihelp-parse-param-disableeditsection": "Disable edit section links from the parser output.",
+ "apihelp-parse-param-generatexml": "Generate XML parse tree (requires content model <code>$1</code>).",
+ "apihelp-parse-param-preview": "Parse in preview mode.",
+ "apihelp-parse-param-sectionpreview": "Parse in section preview mode (enables preview mode too).",
+ "apihelp-parse-param-disabletoc": "Disable table of contents in output.",
+ "apihelp-parse-param-contentformat": "Content serialization format used for the input text. Only valid when used with $1text.",
+ "apihelp-parse-param-contentmodel": "Content model of the input text. If omitted, $1title must be specified, and default will be the model of the specified title. Only valid when used with $1text.",
+ "apihelp-parse-example-page": "Parse a page.",
+ "apihelp-parse-example-text": "Parse wikitext.",
+ "apihelp-parse-example-texttitle": "Parse wikitext, specifying the page title.",
+ "apihelp-parse-example-summary": "Parse a summary.",
+
+ "apihelp-patrol-description": "Patrol a page or revision.",
+ "apihelp-patrol-param-rcid": "Recentchanges ID to patrol.",
+ "apihelp-patrol-param-revid": "Revision ID to patrol.",
+ "apihelp-patrol-example-rcid": "Patrol a recent change.",
+ "apihelp-patrol-example-revid": "Patrol a revision.",
+
+ "apihelp-protect-description": "Change the protection level of a page.",
+ "apihelp-protect-param-title": "Title of the page to (un)protect. Cannot be used together with $1pageid.",
+ "apihelp-protect-param-pageid": "ID of the page to (un)protect. Cannot be used together with $1title.",
+ "apihelp-protect-param-protections": "List of protection levels, formatted <kbd>action=level</kbd> (e.g. <kbd>edit=sysop</kbd>).\n\n<strong>Note:</strong> Any actions not listed will have restrictions removed.",
+ "apihelp-protect-param-expiry": "Expiry timestamps. If only one timestamp is set, it'll be used for all protections. Use <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, or <kbd>never</kbd>, for a never-expiring protection.",
+ "apihelp-protect-param-reason": "Reason for (un)protecting.",
+ "apihelp-protect-param-cascade": "Enable cascading protection (i.e. protect pages included in this page). Ignored if all protection levels given do not support cascading.",
+ "apihelp-protect-param-watch": "If set, add the page being (un)protected to the current user's watchlist.",
+ "apihelp-protect-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-protect-example-protect": "Protect a page.",
+ "apihelp-protect-example-unprotect": "Unprotect a page by setting restrictions to <kbd>all</kbd>.",
+ "apihelp-protect-example-unprotect2": "Unprotect a page by setting no restrictions.",
+
+ "apihelp-purge-description": "Purge the cache for the given titles.\n\nRequires a POST request if the user is not logged in.",
+ "apihelp-purge-param-forcelinkupdate": "Update the links tables.",
+ "apihelp-purge-param-forcerecursivelinkupdate": "Update the links table, and update the links tables for any page that uses this page as a template.",
+ "apihelp-purge-example-simple": "Purge the <kbd>Main Page</kbd> and the <kbd>API</kbd> page.",
+ "apihelp-purge-example-generator": "Purge the first 10 pages in the main namespace.",
+
+ "apihelp-query-description": "Fetch data from and about MediaWiki.\n\nAll data modifications will first have to use query to acquire a token to prevent abuse from malicious sites.",
+ "apihelp-query-param-prop": "Which properties to get for the queried pages.",
+ "apihelp-query-param-list": "Which lists to get.",
+ "apihelp-query-param-meta": "Which metadata to get.",
+ "apihelp-query-param-indexpageids": "Include an additional pageids section listing all returned page IDs.",
+ "apihelp-query-param-export": "Export the current revisions of all given or generated pages.",
+ "apihelp-query-param-exportnowrap": "Return the export XML without wrapping it in an XML result (same format as [[Special:Export]]). Can only be used with $1export.",
+ "apihelp-query-param-iwurl": "Whether to get the full URL if the title is an interwiki link.",
+ "apihelp-query-param-continue": "When present, formats query-continue as key-value pairs that should simply be merged into the original request. This parameter must be set to an empty string in the initial query.\n\nThis parameter is recommended for all new development, and will be made default in the next API version.",
+ "apihelp-query-param-rawcontinue": "Currently ignored. In the future, <var>$1continue</var> will become the default and this will be needed to receive the raw <samp>query-continue</samp> data.",
+ "apihelp-query-example-revisions": "Fetch [[Special:ApiHelp/query+siteinfo|site info]] and [[Special:ApiHelp/query+revisions|revisions]] of <kbd>Main Page</kbd>.",
+ "apihelp-query-example-allpages": "Fetch revisions of pages beginning with <kbd>API/</kbd>.",
+
+ "apihelp-query+allcategories-description": "Enumerate all categories.",
+ "apihelp-query+allcategories-param-from": "The category to start enumerating from.",
+ "apihelp-query+allcategories-param-to": "The category to stop enumerating at.",
+ "apihelp-query+allcategories-param-prefix": "Search for all category titles that begin with this value.",
+ "apihelp-query+allcategories-param-dir": "Direction to sort in.",
+ "apihelp-query+allcategories-param-min": "Only return categories with at least this many members.",
+ "apihelp-query+allcategories-param-max": "Only return categories with at most this many members.",
+ "apihelp-query+allcategories-param-limit": "How many categories to return.",
+ "apihelp-query+allcategories-param-prop": "Which properties to get:\n;size:Adds number of pages in the category.\n;hidden:Tags categories that are hidden with _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+allcategories-example-size": "List categories with information on the number of pages in each.",
+ "apihelp-query+allcategories-example-generator": "Retrieve info about the category page itself for categories beginning <kbd>List</kbd>.",
+
+ "apihelp-query+alldeletedrevisions-description": "List all deleted revisions by a user or in a namespace.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "May only be used with <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Cannot be used with <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+alldeletedrevisions-param-end": "The timestamp to stop enumerating at.",
+ "apihelp-query+alldeletedrevisions-param-from": "Start listing at this title.",
+ "apihelp-query+alldeletedrevisions-param-to": "Stop listing at this title.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Search for all page titles that begin with this value.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Only list revisions tagged with this tag.",
+ "apihelp-query+alldeletedrevisions-param-user": "Only list revisions by this user.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Don't list revisions by this user.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Only list pages in this namespace.",
+ "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>Note:</strong> Due to [[mw:Manual:$wgMiserMode|miser mode]], using <var>$1user</var> and <var>$1namespace</var> together may result in fewer than <var>$1limit</var> results returned before continuing; in extreme cases, zero results may be returned.",
+ "apihelp-query+alldeletedrevisions-param-generatetitles": "When being used as a generator, generate titles rather than revision IDs.",
+ "apihelp-query+alldeletedrevisions-example-user": "List the last 50 deleted contributions by user <kbd>Example<kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "List the first 50 deleted revisions in the main namespace.",
+
+ "apihelp-query+allfileusages-description": "List all file usages, including non-existing.",
+ "apihelp-query+allfileusages-param-from": "The title of the file to start enumerating from.",
+ "apihelp-query+allfileusages-param-to": "The title of the file to stop enumerating at.",
+ "apihelp-query+allfileusages-param-prefix": "Search for all file titles that begin with this value.",
+ "apihelp-query+allfileusages-param-unique": "Only show distinct file titles. Cannot be used with $1prop=ids.\nWhen used as a generator, yields target pages instead of source pages.",
+ "apihelp-query+allfileusages-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID of the using page (cannot be used with $1unique).\n;title:Adds the title of the file.",
+ "apihelp-query+allfileusages-param-limit": "How many total items to return.",
+ "apihelp-query+allfileusages-param-dir": "The direction in which to list.",
+ "apihelp-query+allfileusages-example-B": "List file titles, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+allfileusages-example-unique": "List unique file titles.",
+ "apihelp-query+allfileusages-example-unique-generator": "Gets all file titles, marking the missing ones.",
+ "apihelp-query+allfileusages-example-generator": "Gets pages containing the files.",
+
+ "apihelp-query+allimages-description": "Enumerate all images sequentially.",
+ "apihelp-query+allimages-param-sort": "Property to sort by.",
+ "apihelp-query+allimages-param-dir": "The direction in which to list.",
+ "apihelp-query+allimages-param-from": "The image title to start enumerating from. Can only be used with $1sort=name.",
+ "apihelp-query+allimages-param-to": "The image title to stop enumerating at. Can only be used with $1sort=name.",
+ "apihelp-query+allimages-param-start": "The timestamp to start enumerating from. Can only be used with $1sort=timestamp.",
+ "apihelp-query+allimages-param-end": "The timestamp to end enumerating. Can only be used with $1sort=timestamp.",
+ "apihelp-query+allimages-param-prefix": "Search for all image titles that begin with this value. Can only be used with $1sort=name.",
+ "apihelp-query+allimages-param-minsize": "Limit to images with at least this many bytes.",
+ "apihelp-query+allimages-param-maxsize": "Limit to images with at most this many bytes.",
+ "apihelp-query+allimages-param-sha1": "SHA1 hash of image. Overrides $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "SHA1 hash of image in base 36 (used in MediaWiki).",
+ "apihelp-query+allimages-param-user": "Only return files uploaded by this user. Can only be used with $1sort=timestamp. Cannot be used together with $1filterbots.",
+ "apihelp-query+allimages-param-filterbots": "How to filter files uploaded by bots. Can only be used with $1sort=timestamp. Cannot be used together with $1user.",
+ "apihelp-query+allimages-param-mime": "What MIME types to search for, e.g. <kbd>image/jpeg</kbd>.",
+ "apihelp-query+allimages-param-limit": "How many images in total to return.",
+ "apihelp-query+allimages-example-B": "Show a list of files starting at the letter <kbd>B</kbd>.",
+ "apihelp-query+allimages-example-recent": "Show a list of recently uploaded files, similar to [[Special:NewFiles]].",
+ "apihelp-query+allimages-example-mimetypes": "Show a list of files with MIME type <kbd>image/png</kbd> or <kbd>image/gif</kbd>",
+ "apihelp-query+allimages-example-generator": "Show info about 4 files starting at the letter <kbd>T</kbd>.",
+
+ "apihelp-query+alllinks-description": "Enumerate all links that point to a given namespace.",
+ "apihelp-query+alllinks-param-from": "The title of the link to start enumerating from.",
+ "apihelp-query+alllinks-param-to": "The title of the link to stop enumerating at.",
+ "apihelp-query+alllinks-param-prefix": "Search for all linked titles that begin with this value.",
+ "apihelp-query+alllinks-param-unique": "Only show distinct linked titles. Cannot be used with <kbd>$1prop=ids</kbd>.\nWhen used as a generator, yields target pages instead of source pages.",
+ "apihelp-query+alllinks-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID of the linking page (cannot be used with <var>$1unique</var>).\n;title:Adds the title of the link.",
+ "apihelp-query+alllinks-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+alllinks-param-limit": "How many total items to return.",
+ "apihelp-query+alllinks-param-dir": "The direction in which to list.",
+ "apihelp-query+alllinks-example-B": "List linked titles, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-unique": "List unique linked titles.",
+ "apihelp-query+alllinks-example-unique-generator": "Gets all linked titles, marking the missing ones.",
+ "apihelp-query+alllinks-example-generator": "Gets pages containing the links.",
+
+ "apihelp-query+allmessages-description": "Return messages from this site.",
+ "apihelp-query+allmessages-param-messages": "Which messages to output. <kbd>*</kbd> (default) means all messages.",
+ "apihelp-query+allmessages-param-prop": "Which properties to get.",
+ "apihelp-query+allmessages-param-enableparser": "Set to enable parser, will preprocess the wikitext of message (substitute magic words, handle templates, etc.).",
+ "apihelp-query+allmessages-param-nocontent": "If set, do not include the content of the messages in the output.",
+ "apihelp-query+allmessages-param-includelocal": "Also include local messages, i.e. messages that don't exist in the software but do exist as a MediaWiki: page.\nThis lists all MediaWiki: pages, so it will also list those that aren't really messages such as [[MediaWiki:Common.js|Common.js]].",
+ "apihelp-query+allmessages-param-args": "Arguments to be substituted into message.",
+ "apihelp-query+allmessages-param-filter": "Return only messages with names that contain this string.",
+ "apihelp-query+allmessages-param-customised": "Return only messages in this customisation state.",
+ "apihelp-query+allmessages-param-lang": "Return messages in this language.",
+ "apihelp-query+allmessages-param-from": "Return messages starting at this message.",
+ "apihelp-query+allmessages-param-to": "Return messages ending at this message.",
+ "apihelp-query+allmessages-param-title": "Page name to use as context when parsing message (for $1enableparser option).",
+ "apihelp-query+allmessages-param-prefix": "Return messages with this prefix.",
+ "apihelp-query+allmessages-example-ipb": "Show messages starting with <kbd>ipb-</kbd>.",
+ "apihelp-query+allmessages-example-de": "Show messages <kbd>august</kbd> and <kbd>mainpage</kbd> in German.",
+
+ "apihelp-query+allpages-description": "Enumerate all pages sequentially in a given namespace.",
+ "apihelp-query+allpages-param-from": "The page title to start enumerating from.",
+ "apihelp-query+allpages-param-to": "The page title to stop enumerating at.",
+ "apihelp-query+allpages-param-prefix": "Search for all page titles that begin with this value.",
+ "apihelp-query+allpages-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+allpages-param-filterredir": "Which pages to list.",
+ "apihelp-query+allpages-param-minsize": "Limit to pages with at least this many bytes.",
+ "apihelp-query+allpages-param-maxsize": "Limit to pages with at most this many bytes.",
+ "apihelp-query+allpages-param-prtype": "Limit to protected pages only.",
+ "apihelp-query+allpages-param-prlevel": "Filter protections based on protection level (must be used with $1prtype= parameter).",
+ "apihelp-query+allpages-param-prfiltercascade": "Filter protections based on cascadingness (ignored when $1prtype isn't set).",
+ "apihelp-query+allpages-param-limit": "How many total pages to return.",
+ "apihelp-query+allpages-param-dir": "The direction in which to list.",
+ "apihelp-query+allpages-param-filterlanglinks": "Filter based on whether a page has langlinks. Note that this may not consider langlinks added by extensions.",
+ "apihelp-query+allpages-param-prexpiry": "Which protection expiry to filter the page on:\n;indefinite:Get only pages with indefinite protection expiry.\n;definite:Get only pages with a definite (specific) protection expiry.\n;all:Get pages with any protections expiry.",
+ "apihelp-query+allpages-example-B": "Show a list of pages starting at the letter <kbd>B</kbd>.",
+ "apihelp-query+allpages-example-generator": "Show info about 4 pages starting at the letter <kbd>T</kbd>.",
+ "apihelp-query+allpages-example-generator-revisions": "Show content of first 2 non-redirect pages beginning at <kbd>Re</kbd>.",
+
+ "apihelp-query+allredirects-description": "List all redirects to a namespace.",
+ "apihelp-query+allredirects-param-from": "The title of the redirect to start enumerating from.",
+ "apihelp-query+allredirects-param-to": "The title of the redirect to stop enumerating at.",
+ "apihelp-query+allredirects-param-prefix": "Search for all target pages that begin with this value.",
+ "apihelp-query+allredirects-param-unique": "Only show distinct target pages. Cannot be used with $1prop=ids|fragment|interwiki.\nWhen used as a generator, yields target pages instead of source pages.",
+ "apihelp-query+allredirects-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID of the redirecting page (cannot be used with <var>$1unique</var>).\n;title:Adds the title of the redirect.\n;fragment:Adds the fragment from the redirect, if any (cannot be used with <var>$1unique</var>).\n;interwiki:Adds the interwiki prefix from the redirect, if any (cannot be used with <var>$1unique</var>).",
+ "apihelp-query+allredirects-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+allredirects-param-limit": "How many total items to return.",
+ "apihelp-query+allredirects-param-dir": "The direction in which to list.",
+ "apihelp-query+allredirects-example-B": "List target pages, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-unique": "List unique target pages.",
+ "apihelp-query+allredirects-example-unique-generator": "Gets all target pages, marking the missing ones.",
+ "apihelp-query+allredirects-example-generator": "Gets pages containing the redirects.",
+
+ "apihelp-query+alltransclusions-description": "List all transclusions (pages embedded using &#123;&#123;x&#125;&#125;), including non-existing.",
+ "apihelp-query+alltransclusions-param-from": "The title of the transclusion to start enumerating from.",
+ "apihelp-query+alltransclusions-param-to": "The title of the transclusion to stop enumerating at.",
+ "apihelp-query+alltransclusions-param-prefix": "Search for all transcluded titles that begin with this value.",
+ "apihelp-query+alltransclusions-param-unique": "Only show distinct transcluded titles. Cannot be used with $1prop=ids.\nWhen used as a generator, yields target pages instead of source pages.",
+ "apihelp-query+alltransclusions-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID of the transcluding page (cannot be used with $1unique).\n;title:Adds the title of the transclusion.",
+ "apihelp-query+alltransclusions-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+alltransclusions-param-limit": "How many total items to return.",
+ "apihelp-query+alltransclusions-param-dir": "The direction in which to list.",
+ "apihelp-query+alltransclusions-example-B": "List transcluded titles, including missing ones, with page IDs they are from, starting at <kbd>B</kbd>.",
+ "apihelp-query+alltransclusions-example-unique": "List unique transcluded titles.",
+ "apihelp-query+alltransclusions-example-unique-generator": "Gets all transcluded titles, marking the missing ones.",
+ "apihelp-query+alltransclusions-example-generator": "Gets pages containing the transclusions.",
+
+ "apihelp-query+allusers-description": "Enumerate all registered users.",
+ "apihelp-query+allusers-param-from": "The user name to start enumerating from.",
+ "apihelp-query+allusers-param-to": "The user name to stop enumerating at.",
+ "apihelp-query+allusers-param-prefix": "Search for all users that begin with this value.",
+ "apihelp-query+allusers-param-dir": "Direction to sort in.",
+ "apihelp-query+allusers-param-group": "Only include users in the given groups.",
+ "apihelp-query+allusers-param-excludegroup": "Exclude users in the given groups.",
+ "apihelp-query+allusers-param-rights": "Only include users with the given rights. Does not include rights granted by implicit or auto-promoted groups like *, user, or autoconfirmed.",
+ "apihelp-query+allusers-param-prop": "Which pieces of information to include:\n;blockinfo:Adds the information about a current block on the user.\n;groups:Lists groups that the user is in. This uses more server resources and may return fewer results than the limit.\n;implicitgroups:Lists all the groups the user is automatically in.\n;rights:Lists rights that the user has.\n;editcount:Adds the edit count of the user.\n;registration:Adds the timestamp of when the user registered if available (may be blank).",
+ "apihelp-query+allusers-param-limit": "How many total user names to return.",
+ "apihelp-query+allusers-param-witheditsonly": "Only list users who have made edits.",
+ "apihelp-query+allusers-param-activeusers": "Only list users active in the last $1 {{PLURAL:$1|day|days}}.",
+ "apihelp-query+allusers-example-Y": "List users starting at <kbd>Y</kbd>.",
+
+ "apihelp-query+backlinks-description": "Find all pages that link to the given page.",
+ "apihelp-query+backlinks-param-title": "Title to search. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-query+backlinks-param-pageid": "Page ID to search. Cannot be used together with <var>$1title</var>.",
+ "apihelp-query+backlinks-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+backlinks-param-dir": "The direction in which to list.",
+ "apihelp-query+backlinks-param-filterredir": "How to filter for redirects. If set to <kbd>nonredirects</kbd> when <var>$1redirect</var> is enabled, this is only applied to the second level.",
+ "apihelp-query+backlinks-param-limit": "How many total pages to return. If <var>$1redirect</var> is enabled, limit applies to each level separately (which means up to 2 * <var>$1limit</var> results may be returned).",
+ "apihelp-query+backlinks-param-redirect": "If linking page is a redirect, find all pages that link to that redirect as well. Maximum limit is halved.",
+ "apihelp-query+backlinks-example-simple": "Show links to <kbd>Main page<kbd>.",
+ "apihelp-query+backlinks-example-generator": "Get information about pages linking to <kbd>Main page<kbd>.",
+
+ "apihelp-query+blocks-description": "List all blocked users and IP addresses.",
+ "apihelp-query+blocks-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+blocks-param-end": "The timestamp to stop enumerating at.",
+ "apihelp-query+blocks-param-ids": "List of block IDs to list (optional).",
+ "apihelp-query+blocks-param-users": "List of users to search for (optional).",
+ "apihelp-query+blocks-param-ip": "Get all blocks applying to this IP or CIDR range, including range blocks.\nCannot be used together with <var>$3users</var>. CIDR ranges broader than IPv4/$1 or IPv6/$2 are not accepted.",
+ "apihelp-query+blocks-param-limit": "The maximum number of blocks to list.",
+ "apihelp-query+blocks-param-prop": "Which properties to get:\n;id:Adds the ID of the block.\n;user:Adds the username of the blocked user.\n;userid:Adds the user ID of the blocked user.\n;by:Adds the username of the blocking user.\n;byid:Adds the user ID of the blocking user.\n;timestamp:Adds the timestamp of when the block was given.\n;expiry:Adds the timestamp of when the block expires.\n;reason:Adds the reason given for the block.\n;range:Adds the range of IP addresses affected by the block.\n;flags:Tags the ban with (autoblock, anononly, etc.).",
+ "apihelp-query+blocks-param-show": "Show only items that meet these criteria.\nFor example, to see only indefinite blocks on IP addresses, set <kbd>$1show=ip|!temp</kbd>.",
+ "apihelp-query+blocks-example-simple": "List blocks.",
+ "apihelp-query+blocks-example-users": "List blocks of users <kbd>Alice</kbd> and <kbd>Bob</kbd>.",
+
+ "apihelp-query+categories-description": "List all categories the pages belong to.",
+ "apihelp-query+categories-param-prop": "Which additional properties to get for each category:\n;sortkey:Adds the sortkey (hexadecimal string) and sortkey prefix (human-readable part) for the category.\n;timestamp:Adds timestamp of when the category was added.\n;hidden:Tags categories that are hidden with _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+categories-param-show": "Which kind of categories to show.",
+ "apihelp-query+categories-param-limit": "How many categories to return.",
+ "apihelp-query+categories-param-categories": "Only list these categories. Useful for checking whether a certain page is in a certain category.",
+ "apihelp-query+categories-param-dir": "The direction in which to list.",
+ "apihelp-query+categories-example-simple": "Get a list of categories the page <kbd>Albert Einstein</kbd> belongs to.",
+ "apihelp-query+categories-example-generator": "Get information about all categories used in the page <kbd>Albert Einstein</kbd>.",
+
+ "apihelp-query+categoryinfo-description": "Returns information about the given categories.",
+ "apihelp-query+categoryinfo-example-simple": "Get information about <kbd>Category:Foo</kbd> and <kbd>Category:Bar</kbd>.",
+
+ "apihelp-query+categorymembers-description": "List all pages in a given category.",
+ "apihelp-query+categorymembers-param-title": "Which category to enumerate (required). Must include the <kbd>{{ns:category}}:</kbd> prefix. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-query+categorymembers-param-pageid": "Page ID of the category to enumerate. Cannot be used together with <var>$1title</var>.",
+ "apihelp-query+categorymembers-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID.\n;title:Adds the title and namespace ID of the page.\n;sortkey:Adds the sortkey used for sorting in the category (hexadecimal string).\n;sortkeyprefix:Adds the sortkey prefix used for sorting in the category (human-readable part of the sortkey).\n;type:Adds the type that the page has been categorised as (page, subcat or file).\n;timestamp:Adds the timestamp of when the page was included.",
+ "apihelp-query+categorymembers-param-namespace": "Only include pages in these namespaces. Note that <kbd>$1type=subcat</kbd> or <kbd>$1type=file</kbd> may be used instead of <kbd>$1namespace=14</kbd> or <kbd>6</kbd>.",
+ "apihelp-query+categorymembers-param-type": "Which type of category members to include. Ignored when <kbd>$1sort=timestamp</kbd> is set.",
+ "apihelp-query+categorymembers-param-limit": "The maximum number of pages to return.",
+ "apihelp-query+categorymembers-param-sort": "Property to sort by.",
+ "apihelp-query+categorymembers-param-dir": "In which direction to sort.",
+ "apihelp-query+categorymembers-param-start": "Timestamp to start listing from. Can only be used with <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-end": "Timestamp to end listing at. Can only be used with <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-starthexsortkey": "Sortkey to start listing from, as returned by <kbd>$1prop=sortkey</kbd>. Can only be used with <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-endhexsortkey": "Sortkey to end listing from, as returned by <kbd>$1prop=sortkey</kbd>. Can only be used with <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-startsortkeyprefix": "Sortkey prefix to start listing from. Can only be used with <kbd>$1sort=sortkey</kbd>. Overrides <var>$1starthexsortkey</var>.",
+ "apihelp-query+categorymembers-param-endsortkeyprefix": "Sortkey prefix to end listing BEFORE (not at, if this value occurs it will not be included!). Can only be used with $1sort=sortkey. Overrides $1endhexsortkey.",
+ "apihelp-query+categorymembers-param-startsortkey": "Use $1starthexsortkey instead.",
+ "apihelp-query+categorymembers-param-endsortkey": "Use $1endhexsortkey instead.",
+ "apihelp-query+categorymembers-example-simple": "Get first 10 pages in <kbd>Category:Physics</kbd>.",
+ "apihelp-query+categorymembers-example-generator": "Get page info about first 10 pages in <kbd>Category:Physics</kbd>.",
+
+ "apihelp-query+contributors-description": "Get the list of logged-in contributors and the count of anonymous contributors to a page.",
+ "apihelp-query+contributors-param-group": "Only include users in the given groups. Does not include implicit or auto-promoted groups like *, user, or autoconfirmed.",
+ "apihelp-query+contributors-param-excludegroup": "Exclude users in the given groups. Does not include implicit or auto-promoted groups like *, user, or autoconfirmed.",
+ "apihelp-query+contributors-param-rights": "Only include users having the given rights. Does not include rights granted by implicit or auto-promoted groups like *, user, or autoconfirmed.",
+ "apihelp-query+contributors-param-excluderights": "Exclude users having the given rights. Does not include rights granted by implicit or auto-promoted groups like *, user, or autoconfirmed.",
+ "apihelp-query+contributors-param-limit": "How many contributors to return.",
+ "apihelp-query+contributors-example-simple": "Show contributors to the page <kbd>Main Page</kbd>.",
+
+ "apihelp-query+deletedrevisions-description": "Get deleted revision information.\n\nMay be used in several ways:\n# Get deleted revisions for a set of pages, by setting titles or pageids. Ordered by title and timestamp.\n# Get data about a set of deleted revisions by setting their IDs with revids. Ordered by revision ID.",
+ "apihelp-query+deletedrevisions-param-start": "The timestamp to start enumerating from. Ignored when processing a list of revision IDs.",
+ "apihelp-query+deletedrevisions-param-end": "The timestamp to stop enumerating at. Ignored when processing a list of revision IDs.",
+ "apihelp-query+deletedrevisions-param-tag": "Only list revisions tagged with this tag.",
+ "apihelp-query+deletedrevisions-param-user": "Only list revisions by this user.",
+ "apihelp-query+deletedrevisions-param-excludeuser": "Don't list revisions by this user.",
+ "apihelp-query+deletedrevisions-param-limit": "The maximum amount of revisions to list.",
+ "apihelp-query+deletedrevisions-param-prop": "Which properties to get:\n;revid:Adds the revision ID of the deleted revision.\n;parentid:Adds the revision ID of the previous revision to the page.\n;user:Adds the user who made the revision.\n;userid:Adds the user ID who made the revision.\n;comment:Adds the comment of the revision.\n;parsedcomment:Adds the parsed comment of the revision.\n;minor:Tags if the revision is minor.\n;len:Adds the length (bytes) of the revision.\n;sha1:Adds the SHA-1 (base 16) of the revision.\n;content:Adds the content of the revision.\n;tags:Tags for the revision.",
+ "apihelp-query+deletedrevisions-example-titles": "List the deleted revisions of the pages <kbd>Main Page</kbd> and <kbd>Talk:Main Page</kbd>, with content.",
+ "apihelp-query+deletedrevisions-example-revids": "List the information for deleted revision <kbd>123456</kbd>.",
+
+ "apihelp-query+deletedrevs-description": "List deleted revisions.\n\nOperates in three modes:\n# List deleted revisions for the given titles, sorted by timestamp.\n# List deleted contributions for the given user, sorted by timestamp (no titles specified).\n# List all deleted revisions in the given namespace, sorted by title and timestamp (no titles specified, $1user not set).\n\nCertain parameters only apply to some modes and are ignored in others.",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Mode|Modes}}: $2",
+ "apihelp-query+deletedrevs-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+deletedrevs-param-end": "The timestamp to stop enumerating at.",
+ "apihelp-query+deletedrevs-param-from": "Start listing at this title.",
+ "apihelp-query+deletedrevs-param-to": "Stop listing at this title.",
+ "apihelp-query+deletedrevs-param-prefix": "Search for all page titles that begin with this value.",
+ "apihelp-query+deletedrevs-param-unique": "List only one revision for each page.",
+ "apihelp-query+deletedrevs-param-tag": "Only list revisions tagged with this tag.",
+ "apihelp-query+deletedrevs-param-user": "Only list revisions by this user.",
+ "apihelp-query+deletedrevs-param-excludeuser": "Don't list revisions by this user.",
+ "apihelp-query+deletedrevs-param-namespace": "Only list pages in this namespace.",
+ "apihelp-query+deletedrevs-param-limit": "The maximum amount of revisions to list.",
+ "apihelp-query+deletedrevs-param-prop": "Which properties to get:\n;revid:Adds the revision ID of the deleted revision.\n;parentid:Adds the revision ID of the previous revision to the page.\n;user:Adds the user who made the revision.\n;userid:Adds the user ID whom made the revision.\n;comment:Adds the comment of the revision.\n;parsedcomment:Adds the parsed comment of the revision.\n;minor:Tags if the revision is minor.\n;len:Adds the length (bytes) of the revision.\n;sha1:Adds the SHA-1 (base 16) of the revision.\n;content:Adds the content of the revision.\n;token:<span class=\"apihelp-deprecated\">Deprecated.</span> Gives the edit token.\n;tags:Tags for the revision.",
+ "apihelp-query+deletedrevs-example-mode1": "List the last deleted revisions of the pages <kbd>Main Page</kbd> and <kbd>Talk:Main Page</kbd>, with content (mode 1).",
+ "apihelp-query+deletedrevs-example-mode2": "List the last 50 deleted contributions by <kbd>Bob</kbd> (mode 2).",
+ "apihelp-query+deletedrevs-example-mode3-main": "List the first 50 deleted revisions in the main namespace (mode 3).",
+ "apihelp-query+deletedrevs-example-mode3-talk": "List the first 50 deleted pages in the {{ns:talk}} namespace (mode 3).",
+
+ "apihelp-query+disabled-description": "This query module has been disabled.",
+
+ "apihelp-query+duplicatefiles-description": "List all files that are duplicates of the given files based on hash values.",
+ "apihelp-query+duplicatefiles-param-limit": "How many duplicate files to return.",
+ "apihelp-query+duplicatefiles-param-dir": "The direction in which to list.",
+ "apihelp-query+duplicatefiles-param-localonly": "Look only for files in the local repository.",
+ "apihelp-query+duplicatefiles-example-simple": "Look for duplicates of [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "Look for duplicates of all files.",
+
+ "apihelp-query+embeddedin-description": "Find all pages that embed (transclude) the given title.",
+ "apihelp-query+embeddedin-param-title": "Title to search. Cannot be used together with $1pageid.",
+ "apihelp-query+embeddedin-param-pageid": "Page ID to search. Cannot be used together with $1title.",
+ "apihelp-query+embeddedin-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+embeddedin-param-dir": "The direction in which to list.",
+ "apihelp-query+embeddedin-param-filterredir": "How to filter for redirects.",
+ "apihelp-query+embeddedin-param-limit": "How many total pages to return.",
+ "apihelp-query+embeddedin-example-simple": "Show pages transcluding <kbd>Template:Stub</kbd>.",
+ "apihelp-query+embeddedin-example-generator": "Get information about pages transcluding <kbd>Template:Stub</kbd>.",
+
+ "apihelp-query+extlinks-description": "Returns all external URLs (not interwikis) from the given pages.",
+ "apihelp-query+extlinks-param-limit": "How many links to return.",
+ "apihelp-query+extlinks-param-protocol": "Protocol of the URL. If empty and <var>$1query</var> is set, the protocol is <kbd>http</kbd>. Leave both this and <var>$1query</var> empty to list all external links.",
+ "apihelp-query+extlinks-param-query": "Search string without protocol. Useful for checking whether a certain page contains a certain external url.",
+ "apihelp-query+extlinks-param-expandurl": "Expand protocol-relative URLs with the canonical protocol.",
+ "apihelp-query+extlinks-example-simple": "Get a list of external links on <kbd>Main Page<kbd>.",
+
+ "apihelp-query+exturlusage-description": "Enumerate pages that contain a given URL.",
+ "apihelp-query+exturlusage-param-prop": "Which pieces of information to include:\n;ids:Adds the ID of page.\n;title:Adds the title and namespace ID of the page.\n;url:Adds the URL used in the page.",
+ "apihelp-query+exturlusage-param-protocol": "Protocol of the URL. If empty and <var>$1query</var> set, the protocol is <kbd>http</kbd>. Leave both this and <var>$1query</var> empty to list all external links.",
+ "apihelp-query+exturlusage-param-query": "Search string without protocol. See [[Special:LinkSearch]]. Leave empty to list all external links.",
+ "apihelp-query+exturlusage-param-namespace": "The page namespaces to enumerate.",
+ "apihelp-query+exturlusage-param-limit": "How many pages to return.",
+ "apihelp-query+exturlusage-param-expandurl": "Expand protocol-relative URLs with the canonical protocol.",
+ "apihelp-query+exturlusage-example-simple": "Show pages linking to <kbd>http://www.mediawiki.org</kbd>.",
+
+ "apihelp-query+filearchive-description": "Enumerate all deleted files sequentially.",
+ "apihelp-query+filearchive-param-from": "The image title to start enumerating from.",
+ "apihelp-query+filearchive-param-to": "The image title to stop enumerating at.",
+ "apihelp-query+filearchive-param-prefix": "Search for all image titles that begin with this value.",
+ "apihelp-query+filearchive-param-limit": "How many images to return in total.",
+ "apihelp-query+filearchive-param-dir": "The direction in which to list.",
+ "apihelp-query+filearchive-param-sha1": "SHA1 hash of image. Overrides $1sha1base36.",
+ "apihelp-query+filearchive-param-sha1base36": "SHA1 hash of image in base 36 (used in MediaWiki).",
+ "apihelp-query+filearchive-param-prop": "Which image information to get:\n;sha1:Adds SHA-1 hash for the image.\n;timestamp:Adds timestamp for the uploaded version.\n;user:Adds user who uploaded the image version.\n;size:Adds the size of the image in bytes and the height, width and page count (if applicable).\n;dimensions:Alias for size.\n;description:Adds description the image version.\n;parseddescription:Parse the description on the version.\n;mime:Adds MIME of the image.\n;mediatype:Adds the media type of the image.\n;metadata:Lists Exif metadata for the version of the image.\n;bitdepth:Adds the bit depth of the version.\n;archivename:Adds the filename of the archive version for non-latest versions.",
+ "apihelp-query+filearchive-example-simple": "Show a list of all deleted files.",
+
+ "apihelp-query+filerepoinfo-description": "Return meta information about image repositories configured on the wiki.",
+ "apihelp-query+filerepoinfo-param-prop": "Which repository properties to get (there may be more available on some wikis):\n;apiurl:URL to the repository API - helpful for getting image info from the host.\n;name:The key of the repository - used in e.g. <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> and [[Special:ApiHelp/query+imageinfo|imageinfo]] return values.\n;displayname:The human-readable name of the repository wiki.\n;rooturl:Root URL for image paths.\n;local:Whether that repository is the local one or not.",
+ "apihelp-query+filerepoinfo-example-simple": "Get information about file repositories.",
+
+ "apihelp-query+fileusage-description": "Find all pages that use the given files.",
+ "apihelp-query+fileusage-param-prop": "Which properties to get:\n;pageid:Page ID of each page.\n;title:Title of each page.\n;redirect:Flag if the page is a redirect.",
+ "apihelp-query+fileusage-param-namespace": "Only include pages in these namespaces.",
+ "apihelp-query+fileusage-param-limit": "How many to return.",
+ "apihelp-query+fileusage-param-show": "Show only items that meet these criteria:\n;redirect:Only show redirects.\n;!redirect:Only show non-redirects.",
+ "apihelp-query+fileusage-example-simple": "Get a list of pages using [[:File:Example.jpg]].",
+ "apihelp-query+fileusage-example-generator": "Get information about pages using [[:File:Example.jpg]].",
+
+ "apihelp-query+imageinfo-description": "Returns file information and upload history.",
+ "apihelp-query+imageinfo-param-prop": "Which file information to get:",
+ "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Adds timestamp for the uploaded version.",
+ "apihelp-query+imageinfo-paramvalue-prop-user":"Adds the user who uploaded each file version.",
+ "apihelp-query+imageinfo-paramvalue-prop-userid":"Add the user ID that uploaded each file version.",
+ "apihelp-query+imageinfo-paramvalue-prop-comment":"Comment on the version.",
+ "apihelp-query+imageinfo-paramvalue-prop-parsedcomment":"Parse the comment on the version.",
+ "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle":"Adds the canonical title of the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-url":"Gives URL to the file and the description page.",
+ "apihelp-query+imageinfo-paramvalue-prop-size":"Adds the size of the file in bytes and the height, width and page count (if applicable).",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions":"Alias for size.",
+ "apihelp-query+imageinfo-paramvalue-prop-sha1":"Adds SHA-1 hash for the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-mime":"Adds MIME type of the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-thumbmime":"Adds MIME type of the image thumbnail (requires url and param $1urlwidth).",
+ "apihelp-query+imageinfo-paramvalue-prop-mediatype":"Adds the media type of the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-metadata":"Lists Exif metadata for the version of the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-commonmetadata":"Lists file format generic metadata for the version of the file.",
+ "apihelp-query+imageinfo-paramvalue-prop-extmetadata":"Lists formatted metadata combined from multiple sources. Results are HTML formatted.",
+ "apihelp-query+imageinfo-paramvalue-prop-archivename":"Adds the filename of the archive version for non-latest versions.",
+ "apihelp-query+imageinfo-paramvalue-prop-bitdepth":"Adds the bit depth of the version.",
+ "apihelp-query+imageinfo-paramvalue-prop-uploadwarning":"Used by the Special:Upload page to get information about an existing file. Not intended for use outside MediaWiki core.",
+ "apihelp-query+imageinfo-param-limit": "How many file revisions to return per file.",
+ "apihelp-query+imageinfo-param-start": "Timestamp to start listing from.",
+ "apihelp-query+imageinfo-param-end": "Timestamp to stop listing at.",
+ "apihelp-query+imageinfo-param-urlwidth": "If $2prop=url is set, a URL to an image scaled to this width will be returned.\nFor performance reasons if this option is used, no more than $1 scaled images will be returned.",
+ "apihelp-query+imageinfo-param-urlheight": "Similar to $1urlwidth.",
+ "apihelp-query+imageinfo-param-metadataversion": "Version of metadata to use. If <kbd>latest</kbd> is specified, use latest version. Defaults to <kbd>1</kbd> for backwards compatibility.",
+ "apihelp-query+imageinfo-param-extmetadatalanguage": "What language to fetch extmetadata in. This affects both which translation to fetch, if multiple are available, as well as how things like numbers and various values are formatted.",
+ "apihelp-query+imageinfo-param-extmetadatamultilang": "If translations for extmetadata property are available, fetch all of them.",
+ "apihelp-query+imageinfo-param-extmetadatafilter": "If specified and non-empty, only these keys will be returned for $1prop=extmetadata.",
+ "apihelp-query+imageinfo-param-urlparam": "A handler specific parameter string. For example, PDFs might use <kbd>page15-100px</kbd>. <var>$1urlwidth</var> must be used and be consistent with <var>$1urlparam</var>.",
+ "apihelp-query+imageinfo-param-localonly": "Look only for files in the local repository.",
+ "apihelp-query+imageinfo-example-simple": "Fetch information about the current version of [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageinfo-example-dated": "Fetch information about versions of [[:File:Test.jpg]] from 2008 and later.",
+
+ "apihelp-query+images-description": "Returns all files contained on the given pages.",
+ "apihelp-query+images-param-limit": "How many files to return.",
+ "apihelp-query+images-param-images": "Only list these files. Useful for checking whether a certain page has a certain file.",
+ "apihelp-query+images-param-dir": "The direction in which to list.",
+ "apihelp-query+images-example-simple": "Get a list of files used in the [[Main Page]].",
+ "apihelp-query+images-example-generator": "Get information about all files used in the [[Main Page]].",
+
+ "apihelp-query+imageusage-description": "Find all pages that use the given image title.",
+ "apihelp-query+imageusage-param-title": "Title to search. Cannot be used together with $1pageid.",
+ "apihelp-query+imageusage-param-pageid": "Page ID to search. Cannot be used together with $1title.",
+ "apihelp-query+imageusage-param-namespace": "The namespace to enumerate.",
+ "apihelp-query+imageusage-param-dir": "The direction in which to list.",
+ "apihelp-query+imageusage-param-filterredir": "How to filter for redirects. If set to nonredirects when $1redirect is enabled, this is only applied to the second level.",
+ "apihelp-query+imageusage-param-limit": "How many total pages to return. If <var>$1redirect</var> is enabled, the limit applies to each level separately (which means up to 2 * <var>$1limit</var> results may be returned).",
+ "apihelp-query+imageusage-param-redirect": "If linking page is a redirect, find all pages that link to that redirect as well. Maximum limit is halved.",
+ "apihelp-query+imageusage-example-simple": "Show pages using [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageusage-example-generator": "Get information about pages using [[:File:Albert Einstein Head.jpg]].",
+
+ "apihelp-query+info-description": "Get basic page information.",
+ "apihelp-query+info-param-prop": "Which additional properties to get:",
+ "apihelp-query+info-paramvalue-prop-protection": "List the protection level of each page.",
+ "apihelp-query+info-paramvalue-prop-talkid": "The page ID of the talk page for each non-talk page.",
+ "apihelp-query+info-paramvalue-prop-watched": "List the watched status of each page.",
+ "apihelp-query+info-paramvalue-prop-watchers": "The number of watchers, if allowed.",
+ "apihelp-query+info-paramvalue-prop-notificationtimestamp": "The watchlist notification timestamp of each page.",
+ "apihelp-query+info-paramvalue-prop-subjectid": "The page ID of the parent page for each talk page.",
+ "apihelp-query+info-paramvalue-prop-url": "Gives a full URL, an edit URL, and the canonical URL for each page.",
+ "apihelp-query+info-paramvalue-prop-readable": "Whether the user can read this page.",
+ "apihelp-query+info-paramvalue-prop-preload": "Gives the text returned by EditFormPreloadText.",
+ "apihelp-query+info-paramvalue-prop-displaytitle": "Gives the way the page title is actually displayed.",
+ "apihelp-query+info-param-testactions": "Test whether the current user can perform certain actions on the page.",
+ "apihelp-query+info-param-token": "Use [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] instead.",
+ "apihelp-query+info-example-simple": "Get information about the page <kbd>Main Page</kbd>.",
+ "apihelp-query+info-example-protection": "Get general and protection information about the page <kbd>Main Page</kbd>.",
+
+ "apihelp-query+iwbacklinks-description": "Find all pages that link to the given interwiki link.\n\nCan be used to find all links with a prefix, or all links to a title (with a given prefix). Using neither parameter is effectively \"all interwiki links\".",
+ "apihelp-query+iwbacklinks-param-prefix": "Prefix for the interwiki.",
+ "apihelp-query+iwbacklinks-param-title": "Interwiki link to search for. Must be used with <var>$1blprefix</var>.",
+ "apihelp-query+iwbacklinks-param-limit": "How many total pages to return.",
+ "apihelp-query+iwbacklinks-param-prop": "Which properties to get:\n;iwprefix:Adds the prefix of the interwiki.\n;iwtitle:Adds the title of the interwiki.",
+ "apihelp-query+iwbacklinks-param-dir": "The direction in which to list.",
+ "apihelp-query+iwbacklinks-example-simple": "Get pages linking to [[wikibooks:Test]].",
+ "apihelp-query+iwbacklinks-example-generator": "Get information about pages linking to [[wikibooks:Test]].",
+
+ "apihelp-query+iwlinks-description": "Returns all interwiki links from the given pages.",
+ "apihelp-query+iwlinks-param-url": "Whether to get the full URL (cannot be used with $1prop).",
+ "apihelp-query+iwlinks-param-prop": "Which additional properties to get for each interlanguage link:\n;url:Adds the full URL.",
+ "apihelp-query+iwlinks-param-limit": "How many interwiki links to return.",
+ "apihelp-query+iwlinks-param-prefix": "Only return interwiki links with this prefix.",
+ "apihelp-query+iwlinks-param-title": "Interwiki link to search for. Must be used with <var>$1prefix</var>.",
+ "apihelp-query+iwlinks-param-dir": "The direction in which to list.",
+ "apihelp-query+iwlinks-example-simple": "Get interwiki links from the page <kbd>Main Page</kbd>.",
+
+ "apihelp-query+langbacklinks-description": "Find all pages that link to the given language link.\n\nCan be used to find all links with a language code, or all links to a title (with a given language). Using neither parameter is effectively \"all language links\".\n\nNote that this may not consider language links added by extensions.",
+ "apihelp-query+langbacklinks-param-lang": "Language for the language link.",
+ "apihelp-query+langbacklinks-param-title": "Language link to search for. Must be used with $1lang.",
+ "apihelp-query+langbacklinks-param-limit": "How many total pages to return.",
+ "apihelp-query+langbacklinks-param-prop": "Which properties to get:\n;lllang:Adds the language code of the language link.\n;lltitle:Adds the title of the language link.",
+ "apihelp-query+langbacklinks-param-dir": "The direction in which to list.",
+ "apihelp-query+langbacklinks-example-simple": "Get pages linking to [[:fr:Test]].",
+ "apihelp-query+langbacklinks-example-generator": "Get information about pages linking to [[:fr:Test]].",
+
+ "apihelp-query+langlinks-description": "Returns all interlanguage links from the given pages.",
+ "apihelp-query+langlinks-param-limit": "How many langlinks to return.",
+ "apihelp-query+langlinks-param-url": "Whether to get the full URL (cannot be used with <var>$1prop</var>).",
+ "apihelp-query+langlinks-param-prop": "Which additional properties to get for each interlanguage link:\n;url:Adds the full URL.\n;langname:Adds the localised language name (best effort). Use <var>$1inlanguagecode</var> to control the language.\n;autonym:Adds the native language name.",
+ "apihelp-query+langlinks-param-lang": "Only return language links with this language code.",
+ "apihelp-query+langlinks-param-title": "Link to search for. Must be used with <var>$1lang</var>.",
+ "apihelp-query+langlinks-param-dir": "The direction in which to list.",
+ "apihelp-query+langlinks-param-inlanguagecode": "Language code for localised language names.",
+ "apihelp-query+langlinks-example-simple": "Get interlanguage links from the page <kbd>Main Page</kbd>.",
+
+ "apihelp-query+links-description": "Returns all links from the given pages.",
+ "apihelp-query+links-param-namespace": "Show links in these namespaces only.",
+ "apihelp-query+links-param-limit": "How many links to return.",
+ "apihelp-query+links-param-titles": "Only list links to these titles. Useful for checking whether a certain page links to a certain title.",
+ "apihelp-query+links-param-dir": "The direction in which to list.",
+ "apihelp-query+links-example-simple": "Get links from the page <kbd>Main Page</kbd>",
+ "apihelp-query+links-example-generator": "Get information about the link pages in the page <kbd>Main Page</kbd>.",
+ "apihelp-query+links-example-namespaces": "Get links from the page <kbd>Main Page</kbd> in the {{ns:user}} and {{ns:template}} namespaces.",
+
+ "apihelp-query+linkshere-description": "Find all pages that link to the given pages.",
+ "apihelp-query+linkshere-param-prop": "Which properties to get:\n;pageid:Page ID of each page.\n;title:Title of each page.\n;redirect:Flag if the page is a redirect.",
+ "apihelp-query+linkshere-param-namespace": "Only include pages in these namespaces.",
+ "apihelp-query+linkshere-param-limit": "How many to return.",
+ "apihelp-query+linkshere-param-show": "Show only items that meet these criteria:\n;redirect:Only show redirects.\n;!redirect:Only show non-redirects.",
+ "apihelp-query+linkshere-example-simple": "Get a list of pages linking to the [[Main Page]].",
+ "apihelp-query+linkshere-example-generator": "Get information about pages linking to the [[Main Page]].",
+
+ "apihelp-query+logevents-description": "Get events from logs.",
+ "apihelp-query+logevents-param-prop": "Which properties to get:\n;ids:Adds the ID of the log event.\n;title:Adds the title of the page for the log event.\n;type:Adds the type of log event.\n;user:Adds the user responsible for the log event.\n;userid:Adds the user ID who was responsible for the log event.\n;timestamp:Adds the timestamp for the event.\n;comment:Adds the comment of the event.\n;parsedcomment:Adds the parsed comment of the event.\n;details:Lists additional details about the event.\n;tags:Lists tags for the event.",
+ "apihelp-query+logevents-param-type": "Filter log entries to only this type.",
+ "apihelp-query+logevents-param-action": "Filter log actions to only this action. Overrides <var>$1type</var>. Wildcard actions like <kbd>action/*</kbd> allows to specify any string for the asterisk.",
+ "apihelp-query+logevents-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+logevents-param-end": "The timestamp to end enumerating.",
+ "apihelp-query+logevents-param-user": "Filter entries to those made by the given user.",
+ "apihelp-query+logevents-param-title": "Filter entries to those related to a page.",
+ "apihelp-query+logevents-param-namespace": "Filter entries to those in the given namespace.",
+ "apihelp-query+logevents-param-prefix": "Filter entries that start with this prefix.",
+ "apihelp-query+logevents-param-tag": "Only list event entries tagged with this tag.",
+ "apihelp-query+logevents-param-limit": "How many total event entries to return.",
+ "apihelp-query+logevents-example-simple": "List recent log events.",
+
+ "apihelp-query+pagepropnames-description": "List all page property names in use on the wiki.",
+ "apihelp-query+pagepropnames-param-limit": "The maximum number of names to return.",
+ "apihelp-query+pagepropnames-example-simple": "Get first 10 property names.",
+
+ "apihelp-query+pageprops-description": "Get various properties defined in the page content.",
+ "apihelp-query+pageprops-param-prop": "Only list these props. Useful for checking whether a certain page uses a certain page prop.",
+ "apihelp-query+pageprops-example-simple": "Get properties for <kbd>Category:Foo</kbd>.",
+
+ "apihelp-query+pageswithprop-description": "List all pages using a given page property.",
+ "apihelp-query+pageswithprop-param-propname": "Page prop for which to enumerate pages.",
+ "apihelp-query+pageswithprop-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID.\n;title:Adds the title and namespace ID of the page.\n;value:Adds the value of the page prop.",
+ "apihelp-query+pageswithprop-param-limit": "The maximum number of pages to return.",
+ "apihelp-query+pageswithprop-param-dir": "In which direction to sort.",
+ "apihelp-query+pageswithprop-example-simple": "List the first 10 pages using <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+ "apihelp-query+pageswithprop-example-generator": "Get page info about first 10 pages using <code>_&#95;NOTOC_&#95;</code>.",
+
+ "apihelp-query+prefixsearch-description": "Perform a prefix search for page titles.",
+ "apihelp-query+prefixsearch-param-search": "Search string.",
+ "apihelp-query+prefixsearch-param-namespace": "Namespaces to search.",
+ "apihelp-query+prefixsearch-param-limit": "Maximum number of results to return.",
+ "apihelp-query+prefixsearch-param-offset": "Number of results to skip.",
+ "apihelp-query+prefixsearch-example-simple": "Search for page titles beginning with <kbd>meaning</kbd>.",
+ "apihelp-query+protectedtitles-description": "List all titles protected from creation.",
+ "apihelp-query+protectedtitles-param-namespace": "Only list titles in these namespaces.",
+ "apihelp-query+protectedtitles-param-level": "Only list titles with these protection levels.",
+ "apihelp-query+protectedtitles-param-limit": "How many total pages to return.",
+ "apihelp-query+protectedtitles-param-start": "Start listing at this protection timestamp.",
+ "apihelp-query+protectedtitles-param-end": "Stop listing at this protection timestamp.",
+ "apihelp-query+protectedtitles-param-prop": "Which properties to get:\n;timestamp:Adds the timestamp of when protection was added.\n;user:Adds the user that added the protection.\n;userid:Adds the user ID that added the protection.\n;comment:Adds the comment for the protection.\n;parsedcomment:Adds the parsed comment for the protection.\n;expiry:Adds the timestamp of when the protection will be lifted.\n;level:Adds the protection level.",
+ "apihelp-query+protectedtitles-example-simple": "List protected titles.",
+ "apihelp-query+protectedtitles-example-generator": "Find links to protected titles in the main namespace.",
+
+ "apihelp-query+querypage-description": "Get a list provided by a QueryPage-based special page.",
+ "apihelp-query+querypage-param-page": "The name of the special page. Note, this is case sensitive.",
+ "apihelp-query+querypage-param-limit": "Number of results to return.",
+ "apihelp-query+querypage-example-ancientpages": "Return results from [[Special:Ancientpages]].",
+
+ "apihelp-query+random-description": "Get a set of random pages.\n\nPages are listed in a fixed sequence, only the starting point is random. This means that if, for example, <samp>Main Page</samp> is the first random page in the list, <samp>List of fictional monkeys</samp> will <em>always</em> be second, <samp>List of people on stamps of Vanuatu</samp> third, etc.\n\nIf the number of pages in the namespace is lower than <var>$1limit</var>, fewer pages will be returned. The same page will not be returned twice.",
+ "apihelp-query+random-param-namespace": "Return pages in these namespaces only.",
+ "apihelp-query+random-param-limit": "Limit how many random pages will be returned.",
+ "apihelp-query+random-param-redirect": "Load a random redirect instead of a random page.",
+ "apihelp-query+random-example-simple": "Return two random pages from the main namespace.",
+ "apihelp-query+random-example-generator": "Return page info about two random pages from the main namespace.",
+
+ "apihelp-query+recentchanges-description": "Enumerate recent changes.",
+ "apihelp-query+recentchanges-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+recentchanges-param-end": "The timestamp to end enumerating.",
+ "apihelp-query+recentchanges-param-namespace": "Filter changes to only these namespaces.",
+ "apihelp-query+recentchanges-param-user": "Only list changes by this user.",
+ "apihelp-query+recentchanges-param-excludeuser": "Don't list changes by this user.",
+ "apihelp-query+recentchanges-param-tag": "Only list changes tagged with this tag.",
+ "apihelp-query+recentchanges-param-prop": "Include additional pieces of information:\n;user:Adds the user responsible for the edit and tags if they are an IP.\n;userid:Adds the user ID responsible for the edit.\n;comment:Adds the comment for the edit.\n;parsedcomment:Adds the parsed comment for the edit.\n;flags:Adds flags for the edit.\n;timestamp:Adds timestamp of the edit.\n;title:Adds the page title of the edit.\n;ids:Adds the page ID, recent changes ID and the new and old revision ID.\n;sizes:Adds the new and old page length in bytes.\n;redirect:Tags edit if page is a redirect.\n;patrolled:Tags patrollable edits as being patrolled or unpatrolled.\n;loginfo:Adds log information (log ID, log type, etc) to log entries.\n;tags:Lists tags for the entry.\n;sha1:Adds the content checksum for entries associated with a revision.",
+ "apihelp-query+recentchanges-param-token": "Use <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> instead.",
+ "apihelp-query+recentchanges-param-show": "Show only items that meet these criteria. For example, to see only minor edits done by logged-in users, set $1show=minor|!anon.",
+ "apihelp-query+recentchanges-param-limit": "How many total changes to return.",
+ "apihelp-query+recentchanges-param-type": "Which types of changes to show.",
+ "apihelp-query+recentchanges-param-toponly": "Only list changes which are the latest revision.",
+ "apihelp-query+recentchanges-example-simple": "List recent changes.",
+ "apihelp-query+recentchanges-example-generator": "Get page info about recent unpatrolled changes.",
+
+ "apihelp-query+redirects-description": "Returns all redirects to the given pages.",
+ "apihelp-query+redirects-param-prop": "Which properties to get:\n;pageid:Page ID of each redirect.\n;title:Title of each redirect.\n;fragment:Fragment of each redirect, if any.",
+ "apihelp-query+redirects-param-namespace": "Only include pages in these namespaces.",
+ "apihelp-query+redirects-param-limit": "How many redirects to return.",
+ "apihelp-query+redirects-param-show": "Show only items that meet these criteria:\n;fragment:Only show redirects with a fragment.\n;!fragment:Only show redirects without a fragment.",
+ "apihelp-query+redirects-example-simple": "Get a list of redirects to the [[Main Page]].",
+ "apihelp-query+redirects-example-generator": "Get information about all redirects to the [[Main Page]].",
+
+ "apihelp-query+revisions-description": "Get revision information.\n\nMay be used in several ways:\n# Get data about a set of pages (last revision), by setting titles or pageids.\n# Get revisions for one given page, by using titles or pageids with start, end, or limit.\n# Get data about a set of revisions by setting their IDs with revids.",
+ "apihelp-query+revisions-paraminfo-singlepageonly": "May only be used with a single page (mode #2).",
+ "apihelp-query+revisions-param-startid": "From which revision ID to start enumeration.",
+ "apihelp-query+revisions-param-endid": "Stop revision enumeration on this revision ID.",
+ "apihelp-query+revisions-param-start": "From which revision timestamp to start enumeration.",
+ "apihelp-query+revisions-param-end": "Enumerate up to this timestamp.",
+ "apihelp-query+revisions-param-user": "Only include revisions made by user.",
+ "apihelp-query+revisions-param-excludeuser": "Exclude revisions made by user.",
+ "apihelp-query+revisions-param-tag": "Only list revisions tagged with this tag.",
+ "apihelp-query+revisions-param-token": "Which tokens to obtain for each revision.",
+ "apihelp-query+revisions-example-content": "Get data with content for the last revision of titles <kbd>API</kbd> and <kbd>Main Page</kbd>.",
+ "apihelp-query+revisions-example-last5": "Get last 5 revisions of the <kbd>Main Page</kbd>.",
+ "apihelp-query+revisions-example-first5": "Get first 5 revisions of the <kbd>Main Page</kbd>.",
+ "apihelp-query+revisions-example-first5-after": "Get first 5 revisions of the <kbd>Main Page</kbd> made after 2006-05-01.",
+ "apihelp-query+revisions-example-first5-not-localhost": "Get first 5 revisions of the <kbd>Main Page</kbd> that were not made by anonymous user <kbd>127.0.0.1</kbd>.",
+ "apihelp-query+revisions-example-first5-user": "Get first 5 revisions of the <kbd>Main Page</kbd> that were made by the user <kbd>MediaWiki default</kbd>.",
+ "apihelp-query+revisions+base-param-prop": "Which properties to get for each revision:\n;ids:The ID of the revision.\n;flags:Revision flags (minor).\n;timestamp:The timestamp of the revision.\n;user:User that made the revision.\n;userid:User ID of the revision creator.\n;size:Length (bytes) of the revision.\n;sha1:SHA-1 (base 16) of the revision.\n;contentmodel:Content model ID of the revision.\n;comment:Comment by the user for the revision.\n;parsedcomment:Parsed comment by the user for the revision.\n;content:Text of the revision.\n;tags:Tags for the revision.",
+ "apihelp-query+revisions+base-param-limit": "Limit how many revisions will be returned.",
+ "apihelp-query+revisions+base-param-expandtemplates": "Expand templates in revision content (requires $1prop=content).",
+ "apihelp-query+revisions+base-param-generatexml": "Generate XML parse tree for revision content (requires $1prop=content).",
+ "apihelp-query+revisions+base-param-parse": "Parse revision content (requires $1prop=content). For performance reasons, if this option is used, $1limit is enforced to 1.",
+ "apihelp-query+revisions+base-param-section": "Only retrieve the content of this section number.",
+ "apihelp-query+revisions+base-param-diffto": "Revision ID to diff each revision to. Use <kbd>prev</kbd>, <kbd>next</kbd> and <kbd>cur</kbd> for the previous, next and current revision respectively.",
+ "apihelp-query+revisions+base-param-difftotext": "Text to diff each revision to. Only diffs a limited number of revisions. Overrides <var>$1diffto</var>. If <var>$1section</var> is set, only that section will be diffed against this text",
+ "apihelp-query+revisions+base-param-contentformat": "Serialization format used for <var>$1difftotext</var> and expected for output of content.",
+
+ "apihelp-query+search-description": "Perform a full text search.",
+ "apihelp-query+search-param-search": "Search for all page titles (or content) that have this value.",
+ "apihelp-query+search-param-namespace": "Search only within these namespaces.",
+ "apihelp-query+search-param-what": "Which type of search to perform.",
+ "apihelp-query+search-param-info": "Which metadata to return.",
+ "apihelp-query+search-param-prop": "Which properties to return:\n;size:Adds the size of the page in bytes.\n;wordcount:Adds the word count of the page.\n;timestamp:Adds the timestamp of when the page was last edited.\n;snippet:Adds a parsed snippet of the page.\n;titlesnippet:Adds a parsed snippet of the page title.\n;redirectsnippet:Adds a parsed snippet of the redirect title.\n;redirecttitle:Adds the title of the matching redirect.\n;sectionsnippet:Adds a parsed snippet of the matching section title.\n;sectiontitle:Adds the title of the matching section.\n;score:<span class=\"apihelp-deprecated\">Deprecated and ignored.</span>\n;hasrelated:<span class=\"apihelp-deprecated\">Deprecated and ignored.</span>",
+ "apihelp-query+search-param-limit": "How many total pages to return.",
+ "apihelp-query+search-param-interwiki": "Include interwiki results in the search, if available.",
+ "apihelp-query+search-param-backend": "Which search backend to use, if not the default.",
+ "apihelp-query+search-example-simple": "Search for <kbd>meaning</kbd>.",
+ "apihelp-query+search-example-text": "Search texts for <kbd>meaning</kbd>.",
+ "apihelp-query+search-example-generator": "Ger page info about the pages returned for a search for <kbd>meaning</kbd>.",
+
+ "apihelp-query+siteinfo-description": "Return general information about the site.",
+ "apihelp-query+siteinfo-param-prop": "Which information to get:\n;general:Overall system information.\n;namespaces:List of registered namespaces and their canonical names.\n;namespacealiases:List of registered namespace aliases.\n;specialpagealiases:List of special page aliases.\n;magicwords:List of magic words and their aliases.\n;statistics:Returns site statistics.\n;interwikimap:Returns interwiki map (optionally filtered, optionally localised by using <var>$1inlanguagecode</var>).\n;dbrepllag:Returns database server with the highest replication lag.\n;usergroups:Returns user groups and the associated permissions.\n;libraries:Returns libraries installed on the wiki.\n;extensions:Returns extensions installed on the wiki.\n;fileextensions:Returns list of file extensions allowed to be uploaded.\n;rightsinfo:Returns wiki rights (license) information if available.\n;restrictions:Returns information on available restriction (protection) types.\n;languages:Returns a list of languages MediaWiki supports (optionally localised by using <var>$1inlanguagecode</var>).\n;skins:Returns a list of all enabled skins (optionally localised by using <var>$1inlanguagecode</var>, otherwise in the content language).\n;extensiontags:Returns a list of parser extension tags.\n;functionhooks:Returns a list of parser function hooks.\n;showhooks:Returns a list of all subscribed hooks (contents of <var>[[mw:Manual:$wgHooks|$wgHooks]]</var>).\n;variables:Returns a list of variable IDs.\n;protocols:Returns a list of protocols that are allowed in external links.\n;defaultoptions:Returns the default values for user preferences.",
+ "apihelp-query+siteinfo-param-filteriw": "Return only local or only nonlocal entries of the interwiki map.",
+ "apihelp-query+siteinfo-param-showalldb": "List all database servers, not just the one lagging the most.",
+ "apihelp-query+siteinfo-param-numberingroup": "Lists the number of users in user groups.",
+ "apihelp-query+siteinfo-param-inlanguagecode": "Language code for localised language names (best effort) and skin names.",
+ "apihelp-query+siteinfo-example-simple": "Fetch site information.",
+ "apihelp-query+siteinfo-example-interwiki": "Fetch a list of local interwiki prefixes.",
+ "apihelp-query+siteinfo-example-replag": "Check the current replication lag.",
+
+ "apihelp-query+stashimageinfo-description": "Returns file information for stashed files.",
+ "apihelp-query+stashimageinfo-param-filekey": "Key that identifies a previous upload that was stashed temporarily.",
+ "apihelp-query+stashimageinfo-param-sessionkey": "Alias for $1filekey, for backward compatibility.",
+ "apihelp-query+stashimageinfo-example-simple": "Returns information for a stashed file.",
+ "apihelp-query+stashimageinfo-example-params": "Returns thumbnails for two stashed files.",
+
+ "apihelp-query+tags-description": "List change tags.",
+ "apihelp-query+tags-param-limit": "The maximum number of tags to list.",
+ "apihelp-query+tags-param-prop": "Which properties to get:\n;name:Adds name of tag.\n;displayname:Adds system message for the tag.\n;description:Adds description of the tag.\n;hitcount:Adds the number of revisions and log entries that have this tag.\n;defined:Indicate whether the tag is defined.\n;source:Gets the sources of the tag, which may include <samp>extension</samp> for extension-defined tags and <samp>manual</samp> for tags that may be applied manually by users.\n;active:Whether the tag is still being applied.",
+ "apihelp-query+tags-example-simple": "List available tags.",
+
+ "apihelp-query+templates-description": "Returns all pages transcluded on the given pages.",
+ "apihelp-query+templates-param-namespace": "Show templates in this namespaces only.",
+ "apihelp-query+templates-param-limit": "How many templates to return.",
+ "apihelp-query+templates-param-templates": "Only list these templates. Useful for checking whether a certain page uses a certain template.",
+ "apihelp-query+templates-param-dir": "The direction in which to list.",
+ "apihelp-query+templates-example-simple": "Get the templates used on the page <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-generator": "Get information about the template pages used on <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-namespaces": "Get pages in the {{ns:user}} and {{ns:template}} namespaces that are transcluded on the page <kbd>Main Page</kbd>.",
+
+ "apihelp-query+tokens-description": "Gets tokens for data-modifying actions.",
+ "apihelp-query+tokens-param-type": "Types of token to request.",
+ "apihelp-query+tokens-example-simple": "Retrieve a csrf token (the default).",
+ "apihelp-query+tokens-example-types": "Retrieve a watch token and a patrol token.",
+
+ "apihelp-query+transcludedin-description": "Find all pages that transclude the given pages.",
+ "apihelp-query+transcludedin-param-prop": "Which properties to get:\n;pageid:Page ID of each page.\n;title:Title of each page.\n;redirect:Flag if the page is a redirect.",
+ "apihelp-query+transcludedin-param-namespace": "Only include pages in these namespaces.",
+ "apihelp-query+transcludedin-param-limit": "How many to return.",
+ "apihelp-query+transcludedin-param-show": "Show only items that meet these criteria:\n;redirect:Only show redirects.\n;!redirect:Only show non-redirects.",
+ "apihelp-query+transcludedin-example-simple": "Get a list of pages transcluding <kbd>Main Page</kbd>.",
+ "apihelp-query+transcludedin-example-generator": "Get information about pages transcluding <kbd>Main Page</kbd>.",
+
+ "apihelp-query+usercontribs-description": "Get all edits by a user.",
+ "apihelp-query+usercontribs-param-limit": "The maximum number of contributions to return.",
+ "apihelp-query+usercontribs-param-start": "The start timestamp to return from.",
+ "apihelp-query+usercontribs-param-end": "The end timestamp to return to.",
+ "apihelp-query+usercontribs-param-user": "The users to retrieve contributions for.",
+ "apihelp-query+usercontribs-param-userprefix": "Retrieve contributions for all users whose names begin with this value. Overrides $1user.",
+ "apihelp-query+usercontribs-param-namespace": "Only list contributions in these namespaces.",
+ "apihelp-query+usercontribs-param-prop": "Include additional pieces of information:\n;ids:Adds the page ID and revision ID.\n;title:Adds the title and namespace ID of the page.\n;timestamp:Adds the timestamp of the edit.\n;comment:Adds the comment of the edit.\n;parsedcomment:Adds the parsed comment of the edit.\n;size:Adds the new size of the edit.\n;sizediff:Adds the size delta of the edit against its parent.\n;flags:Adds flags of the edit.\n;patrolled:Tags patrolled edits.\n;tags:Lists tags for the edit.",
+ "apihelp-query+usercontribs-param-show": "Show only items that meet these criteria, e.g. non minor edits only: <kbd>$2show=!minor</kbd>.\n\nIf <kbd>$2show=patrolled</kbd> or <kbd>$2show=!patrolled</kbd> is set, revisions older than <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|second|seconds}}) won't be shown.",
+ "apihelp-query+usercontribs-param-tag": "Only list revisions tagged with this tag.",
+ "apihelp-query+usercontribs-param-toponly": "Only list changes which are the latest revision.",
+ "apihelp-query+usercontribs-example-user": "Show contributions of user <kbd>Example</kbd>.",
+ "apihelp-query+usercontribs-example-ipprefix": "Show contributions from all IP addresses with prefix <kbd>192.0.2.</kbd>.",
+
+ "apihelp-query+userinfo-description": "Get information about the current user.",
+ "apihelp-query+userinfo-param-prop": "Which pieces of information to include:\n;blockinfo:Tags if the current user is blocked, by whom, and for what reason.\n;hasmsg:Adds a tag <samp>message</samp> if the current user has pending messages.\n;groups:Lists all the groups the current user belongs to.\n;implicitgroups:Lists all the groups the current user is automatically a member of.\n;rights:Lists all the rights the current user has.\n;changeablegroups:Lists the groups the current user can add to and remove from.\n;options:Lists all preferences the current user has set.\n;preferencestoken:<span class=\"apihelp-deprecated\">Deprecated.</span> Get a token to change current user's preferences.\n;editcount:Adds the current user's edit count.\n;ratelimits:Lists all rate limits applying to the current user.\n;realname:Adds the user's real name.\n;email:Adds the user's email address and email authentication date.\n;acceptlang:Echoes the <code>Accept-Language</code> header sent by the client in a structured format.\n;registrationdate:Adds the user's registration date.\n;unreadcount:Adds the count of unread pages on the user's watchlist (maximum $1; returns <samp>$2</samp> if more).",
+ "apihelp-query+userinfo-example-simple": "Get information about the current user.",
+ "apihelp-query+userinfo-example-data": "Get additional information about the current user.",
+
+ "apihelp-query+users-description": "Get information about a list of users.",
+ "apihelp-query+users-param-prop": "Which pieces of information to include:\n;blockinfo:Tags if the user is blocked, by whom, and for what reason.\n;groups:Lists all the groups each user belongs to.\n;implicitgroups:Lists all the groups a user is automatically a member of.\n;rights:Lists all the rights each user has.\n;editcount:Adds the user's edit count.\n;registration:Adds the user's registration timestamp.\n;emailable:Tags if the user can and wants to receive email through [[Special:Emailuser]].\n;gender:Tags the gender of the user. Returns \"male\", \"female\", or \"unknown\".",
+ "apihelp-query+users-param-users": "A list of users to obtain information for.",
+ "apihelp-query+users-param-token": "Use <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> instead.",
+ "apihelp-query+users-example-simple": "Return information for user <kbd>Example</kbd>.",
+
+ "apihelp-query+watchlist-description": "Get recent changes to pages in the current user's watchlist.",
+ "apihelp-query+watchlist-param-allrev": "Include multiple revisions of the same page within given timeframe.",
+ "apihelp-query+watchlist-param-start": "The timestamp to start enumerating from.",
+ "apihelp-query+watchlist-param-end": "The timestamp to end enumerating.",
+ "apihelp-query+watchlist-param-namespace": "Filter changes to only the given namespaces.",
+ "apihelp-query+watchlist-param-user": "Only list changes by this user.",
+ "apihelp-query+watchlist-param-excludeuser": "Don't list changes by this user.",
+ "apihelp-query+watchlist-param-limit": "How many total results to return per request.",
+ "apihelp-query+watchlist-param-prop": "Which additional items to get:\n;ids:Adds revision IDs and page IDs.\n;title:Adds title of the page.\n;flags:Adds flags for the edit.\n;user:Adds the user who made the edit.\n;userid:Adds user ID of whom made the edit.\n;comment:Adds comment of the edit.\n;parsedcomment:Adds parsed comment of the edit.\n;timestamp:Adds timestamp of the edit.\n;patrol:Tags edits that are patrolled.\n;sizes:Adds the old and new lengths of the page.\n;notificationtimestamp:Adds timestamp of when the user was last notified about the edit.\n;loginfo:Adds log information where appropriate.",
+ "apihelp-query+watchlist-param-show": "Show only items that meet these criteria. For example, to see only minor edits done by logged-in users, set $1show=minor|!anon.",
+ "apihelp-query+watchlist-param-type": "Which types of changes to show:\n;edit:Regular page edits.\n;external:External changes.\n;new:Page creations.\n;log:Log entries.",
+ "apihelp-query+watchlist-param-owner": "Used along with $1token to access a different user's watchlist.",
+ "apihelp-query+watchlist-param-token": "A security token (available in the user's [[Special:Preferences#mw-prefsection-watchlist|preferences]]) to allow access to another user's watchlist.",
+ "apihelp-query+watchlist-example-simple": "List the top revision for recently changed pages on the current user's watchlist.",
+ "apihelp-query+watchlist-example-props": "Fetch additional information about the top revision for recently changed pages on the current user's watchlist.",
+ "apihelp-query+watchlist-example-allrev": "Fetch information about all recent changes to pages on the current user's watchlist.",
+ "apihelp-query+watchlist-example-generator": "Fetch page info for recently changed pages on the current user's watchlist.",
+ "apihelp-query+watchlist-example-generator-rev": "Fetch revision info for recent changes to pages on the current user's watchlist.",
+ "apihelp-query+watchlist-example-wlowner": "List the top revision for recently changed pages on the watchlist of user <kbd>Example</kbd>.",
+
+ "apihelp-query+watchlistraw-description": "Get all pages on the current user's watchlist.",
+ "apihelp-query+watchlistraw-param-namespace": "Only list pages in the given namespaces.",
+ "apihelp-query+watchlistraw-param-limit": "How many total results to return per request.",
+ "apihelp-query+watchlistraw-param-prop": "Which additional properties to get:\n;changed:Adds timestamp of when the user was last notified about the edit.",
+ "apihelp-query+watchlistraw-param-show": "Only list items that meet these criteria.",
+ "apihelp-query+watchlistraw-param-owner": "Used along with $1token to access a different user's watchlist.",
+ "apihelp-query+watchlistraw-param-token": "A security token (available in the user's [[Special:Preferences#mw-prefsection-watchlist|preferences]]) to allow access to another user's watchlist.",
+ "apihelp-query+watchlistraw-example-simple": "List pages on the current user's watchlist.",
+ "apihelp-query+watchlistraw-example-generator": "Fetch page info for pages on the current user's watchlist.",
+
+ "apihelp-revisiondelete-description": "Delete and undelete revisions.",
+ "apihelp-revisiondelete-param-type": "Type of revision deletion being performed.",
+ "apihelp-revisiondelete-param-target": "Page title for the revision deletion, if required for the type.",
+ "apihelp-revisiondelete-param-ids": "Identifiers for the revisions to be deleted.",
+ "apihelp-revisiondelete-param-hide": "What to hide for each revision.",
+ "apihelp-revisiondelete-param-show": "What to unhide for each revision.",
+ "apihelp-revisiondelete-param-suppress": "Whether to suppress data from administrators as well as others.",
+ "apihelp-revisiondelete-param-reason": "Reason for the deletion or undeletion.",
+ "apihelp-revisiondelete-example-revision": "Hide content for revision <kbd>12345</kbd> on the page <kbd>Main Page</kbd>.",
+ "apihelp-revisiondelete-example-log": "Hide all data on log entry <kbd>67890</kbd> with the reason <kbd>BLP violation</kbd>.",
+
+ "apihelp-rollback-description": "Undo the last edit to the page.\n\nIf the last user who edited the page made multiple edits in a row, they will all be rolled back.",
+ "apihelp-rollback-param-title": "Title of the page to roll back. Cannot be used together with <var>$1pageid</var>.",
+ "apihelp-rollback-param-pageid": "Page ID of the page to roll back. Cannot be used together with <var>$1title</var>.",
+ "apihelp-rollback-param-user": "Name of the user whose edits are to be rolled back.",
+ "apihelp-rollback-param-summary": "Custom edit summary. If empty, default summary will be used.",
+ "apihelp-rollback-param-markbot": "Mark the reverted edits and the revert as bot edits.",
+ "apihelp-rollback-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-rollback-example-simple": "Roll back the last edits to page <kbd>Main Page</kbd> by user <kbd>Example</kbd>.",
+ "apihelp-rollback-example-summary": "Roll back the last edits to page <kbd>Main Page</kbd> by IP user <kbd>192.0.2.5</kbd> with summary <kbd>Reverting vandalism</kbd>, and mark those edits and the revert as bot edits.",
+
+ "apihelp-rsd-description": "Export an RSD (Really Simple Discovery) schema.",
+ "apihelp-rsd-example-simple": "Export the RSD schema.",
+
+ "apihelp-setnotificationtimestamp-description": "Update the notification timestamp for watched pages.\n\nThis affects the highlighting of changed pages in the watchlist and history, and the sending of email when the \"Email me when a page on my watchlist is changed\" preference is enabled.",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "Work on all watched pages.",
+ "apihelp-setnotificationtimestamp-param-timestamp": "Timestamp to which to set the notification timestamp.",
+ "apihelp-setnotificationtimestamp-param-torevid": "Revision to set the notification timestamp to (one page only).",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "Revision to set the notification timestamp newer than (one page only).",
+ "apihelp-setnotificationtimestamp-example-all": "Reset the notification status for the entire watchlist.",
+ "apihelp-setnotificationtimestamp-example-page": "Reset the notification status for <kbd>Main page</kbd>.",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "Set the notification timestamp for <kbd>Main page</kbd> so all edits since 1 January 2012 are unviewed.",
+ "apihelp-setnotificationtimestamp-example-allpages": "Reset the notification status for pages in the <kbd>{{ns:user}}</kbd> namespace.",
+
+ "apihelp-tag-description": "Add or remove change tags from individual revisions or log entries.",
+ "apihelp-tag-param-rcid": "One or more recent changes IDs from which to add or remove the tag.",
+ "apihelp-tag-param-revid": "One or more revision IDs from which to add or remove the tag.",
+ "apihelp-tag-param-logid": "One or more log entry IDs from which to add or remove the tag.",
+ "apihelp-tag-param-add": "Tags to add. Only manually defined tags can be added.",
+ "apihelp-tag-param-remove": "Tags to remove. Only tags that are either manually defined or completely undefined can be removed.",
+ "apihelp-tag-param-reason": "Reason for the change.",
+ "apihelp-tag-example-rev": "Add the <kbd>vandalism</kbd> tag from revision ID 123 without specifying a reason",
+ "apihelp-tag-example-log": "Remove the <kbd>spam</kbd> tag from log entry ID 123 with the reason <kbd>Wrongly applied</kbd>",
+
+ "apihelp-tokens-description": "Get tokens for data-modifying actions.\n\nThis module is deprecated in favor of [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-tokens-param-type": "Types of token to request.",
+ "apihelp-tokens-example-edit": "Retrieve an edit token (the default).",
+ "apihelp-tokens-example-emailmove": "Retrieve an email token and a move token.",
+
+ "apihelp-unblock-description": "Unblock a user.",
+ "apihelp-unblock-param-id": "ID of the block to unblock (obtained through <kbd>list=blocks</kbd>). Cannot be used together with <var>$1user</var>.",
+ "apihelp-unblock-param-user": "Username, IP address or IP range to unblock. Cannot be used together with <var>$1id</var>.",
+ "apihelp-unblock-param-reason": "Reason for unblock.",
+ "apihelp-unblock-example-id": "Unblock block ID #<kbd>105</kbd>.",
+ "apihelp-unblock-example-user": "Unblock user <kbd>Bob</kbd> with reason <kbd>Sorry Bob</kbd>.",
+
+ "apihelp-undelete-description": "Restore revisions of a deleted page.\n\nA list of deleted revisions (including timestamps) can be retrieved through [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]], and a list of deleted file IDs can be retrieved through [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+ "apihelp-undelete-param-title": "Title of the page to restore.",
+ "apihelp-undelete-param-reason": "Reason for restoring.",
+ "apihelp-undelete-param-timestamps": "Timestamps of the revisions to restore. If both <var>$1timestamps</var> and <var>$1fileids</var> are empty, all will be restored.",
+ "apihelp-undelete-param-fileids": "IDs of the file revisions to restore. If both <var>$1timestamps</var> and <var>$1fileids</var> are empty, all will be restored.",
+ "apihelp-undelete-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-undelete-example-page": "Undelete page <kbd>Main Page</kbd>.",
+ "apihelp-undelete-example-revisions": "Undelete two revisions of page <kbd>Main Page</kbd>.",
+
+ "apihelp-upload-description": "Upload a file, or get the status of pending uploads.\n\nSeveral methods are available:\n* Upload file contents directly, using the <var>$1file</var> parameter.\n* Upload the file in pieces, using the <var>$1filesize</var>, <var>$1chunk</var>, and <var>$1offset</var> parameters.* Have the MediaWiki server fetch a file from a URL, using the <var>$1url</var> parameter.\n* Complete an earlier upload that failed due to warnings, using the <var>$1filekey</var> parameter.\nNote that the HTTP POST must be done as a file upload (i.e. using <code>multipart/form-data</code>) when sending the <var>$1file</var>.",
+ "apihelp-upload-param-filename": "Target filename.",
+ "apihelp-upload-param-comment": "Upload comment. Also used as the initial page text for new files if <var>$1text</var> is not specified.",
+ "apihelp-upload-param-text": "Initial page text for new files.",
+ "apihelp-upload-param-watch": "Watch the page.",
+ "apihelp-upload-param-watchlist": "Unconditionally add or remove the page from the current user's watchlist, use preferences or do not change watch.",
+ "apihelp-upload-param-ignorewarnings": "Ignore any warnings.",
+ "apihelp-upload-param-file": "File contents.",
+ "apihelp-upload-param-url": "URL to fetch the file from.",
+ "apihelp-upload-param-filekey": "Key that identifies a previous upload that was stashed temporarily.",
+ "apihelp-upload-param-sessionkey": "Same as $1filekey, maintained for backward compatibility.",
+ "apihelp-upload-param-stash": "If set, the server will stash the file temporarily instead of adding it to the repository.",
+ "apihelp-upload-param-filesize": "Filesize of entire upload.",
+ "apihelp-upload-param-offset": "Offset of chunk in bytes.",
+ "apihelp-upload-param-chunk": "Chunk contents.",
+ "apihelp-upload-param-async": "Make potentially large file operations asynchronous when possible.",
+ "apihelp-upload-param-asyncdownload": "Make fetching a URL asynchronous.",
+ "apihelp-upload-param-leavemessage": "If asyncdownload is used, leave a message on the user talk page if finished.",
+ "apihelp-upload-param-statuskey": "Fetch the upload status for this file key (upload by URL).",
+ "apihelp-upload-param-checkstatus": "Only fetch the upload status for the given file key.",
+ "apihelp-upload-example-url": "Upload from a URL.",
+ "apihelp-upload-example-filekey": "Complete an upload that failed due to warnings.",
+
+ "apihelp-userrights-description": "Change a user's group membership.",
+ "apihelp-userrights-param-user": "User name.",
+ "apihelp-userrights-param-userid": "User ID.",
+ "apihelp-userrights-param-add": "Add the user to these groups.",
+ "apihelp-userrights-param-remove": "Remove the user from these groups.",
+ "apihelp-userrights-param-reason": "Reason for the change.",
+ "apihelp-userrights-example-user": "Add user <kbd>FooBot</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
+ "apihelp-userrights-example-userid": "Add the user with ID <kbd>123</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
+
+ "apihelp-watch-description": "Add or remove pages from the current user's watchlist.",
+ "apihelp-watch-param-title": "The page to (un)watch. Use <var>$1titles</var> instead.",
+ "apihelp-watch-param-unwatch": "If set the page will be unwatched rather than watched.",
+ "apihelp-watch-example-watch": "Watch the page <kbd>Main Page</kbd>.",
+ "apihelp-watch-example-unwatch": "Unwatch the page <kbd>Main Page</kbd>.",
+ "apihelp-watch-example-generator": "Watch the first few pages in the main namespace.",
+
+ "apihelp-format-example-generic": "Format the query result in the $1 format.",
+ "apihelp-dbg-description": "Output data in PHP's <code>var_export()</code> format.",
+ "apihelp-dbgfm-description": "Output data in PHP's <code>var_export()</code> format (pretty-print in HTML).",
+ "apihelp-dump-description": "Output data in PHP's <code>var_dump()</code> format.",
+ "apihelp-dumpfm-description": "Output data in PHP's <code>var_dump()</code> format (pretty-print in HTML).",
+ "apihelp-json-description": "Output data in JSON format.",
+ "apihelp-json-param-callback": "If specified, wraps the output into a given function call. For safety, all user-specific data will be restricted.",
+ "apihelp-json-param-utf8": "If specified, encodes most (but not all) non-ASCII characters as UTF-8 instead of replacing them with hexadecimal escape sequences. Default when <var>formatversion</var> is not <kbd>1</kbd>.",
+ "apihelp-json-param-ascii": "If specified, encodes all non-ASCII using hexadecimal escape sequences. Default when <var>formatversion</var> is <kbd>1</kbd>.",
+ "apihelp-json-param-formatversion": "Output formatting:\n;1:Backwards-compatible format (XML-style booleans, <samp>*</samp> keys for content nodes, etc.).\n;2:Experimental modern format. Details may change!\n;latest:Use the latest format (currently <kbd>2</kbd>), may change without warning.",
+ "apihelp-jsonfm-description": "Output data in JSON format (pretty-print in HTML).",
+ "apihelp-none-description": "Output nothing.",
+ "apihelp-php-description": "Output data in serialized PHP format.",
+ "apihelp-php-param-formatversion": "Output formatting:\n;1:Backwards-compatible format (XML-style booleans, <samp>*</samp> keys for content nodes, etc.).\n;2:Experimental modern format. Details may change!\n;latest:Use the latest format (currently <kbd>2</kbd>), may change without warning.",
+ "apihelp-phpfm-description": "Output data in serialized PHP format (pretty-print in HTML).",
+ "apihelp-rawfm-description": "Output data with the debugging elements in JSON format (pretty-print in HTML).",
+ "apihelp-txt-description": "Output data in PHP's <code>print_r()</code> format.",
+ "apihelp-txtfm-description": "Output data in PHP's <code>print_r()</code> format (pretty-print in HTML).",
+ "apihelp-wddx-description": "Output data in WDDX format.",
+ "apihelp-wddxfm-description": "Output data in WDDX format (pretty-print in HTML).",
+ "apihelp-xml-description": "Output data in XML format.",
+ "apihelp-xml-param-xslt": "If specified, adds the named page as an XSL stylesheet. The value must be a title in the {{ns:mediawiki}} namespace ending in <code>.xsl</code>.",
+ "apihelp-xml-param-includexmlnamespace": "If specified, adds an XML namespace.",
+ "apihelp-xmlfm-description": "Output data in XML format (pretty-print in HTML).",
+ "apihelp-yaml-description": "Output data in YAML format.",
+ "apihelp-yamlfm-description": "Output data in YAML format (pretty-print in HTML).",
+
+ "api-format-title": "MediaWiki API result",
+ "api-format-prettyprint-header": "This is the HTML representation of the $1 format. HTML is good for debugging, but is unsuitable for application use.\n\nSpecify the <var>format</var> parameter to change the output format. To see the non-HTML representation of the $1 format, set <kbd>format=$2</kbd>.\n\nSee the [[mw:API|complete documentation]], or the [[Special:ApiHelp/main|API help]] for more information.",
+
+ "api-orm-param-props": "Fields to query.",
+ "api-orm-param-limit": "Max amount of rows to return.",
+
+ "api-pageset-param-titles": "A list of titles to work on.",
+ "api-pageset-param-pageids": "A list of page IDs to work on.",
+ "api-pageset-param-revids": "A list of revision IDs to work on.",
+ "api-pageset-param-generator": "Get the list of pages to work on by executing the specified query module.\n\n<strong>Note:</strong> Generator parameter names must be prefixed with a \"g\", see examples.",
+ "api-pageset-param-redirects-generator": "Automatically resolve redirects in <var>$1titles</var>, <var>$1pageids</var>, and <var>$1revids</var>, and in pages returned by <var>$1generator</var>.",
+ "api-pageset-param-redirects-nogenerator": "Automatically resolve redirects in <var>$1titles</var>, <var>$1pageids</var>, and <var>$1revids</var>.",
+ "api-pageset-param-converttitles": "Convert titles to other variants if necessary. Only works if the wiki's content language supports variant conversion. Languages that support variant conversion include $1.",
+
+ "api-help-title": "MediaWiki API help",
+ "api-help-lead": "This is an auto-generated MediaWiki API documentation page.\n\nDocumentation and examples: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Main module",
+ "api-help-fallback-description": "$1",
+ "api-help-fallback-parameter": "$1",
+ "api-help-fallback-example": "$1",
+ "api-help-flags": "",
+ "api-help-flag-deprecated": "This module is deprecated.",
+ "api-help-flag-internal": "<strong>This module is internal or unstable.</strong> Its operation may change without notice.",
+ "api-help-flag-readrights": "This module requires read rights.",
+ "api-help-flag-writerights": "This module requires write rights.",
+ "api-help-flag-mustbeposted": "This module only accepts POST requests.",
+ "api-help-flag-generator": "This module can be used as a generator.",
+ "api-help-help-urls": "",
+ "api-help-parameters": "{{PLURAL:$1|Parameter|Parameters}}:",
+ "api-help-param-deprecated": "Deprecated.",
+ "api-help-param-required": "This parameter is required.",
+ "api-help-param-list": "{{PLURAL:$1|1=One value|2=Values (separate with <kbd>{{!}}</kbd>)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Must be empty|Can be empty, or $2}}",
+ "api-help-param-limit": "No more than $1 allowed.",
+ "api-help-param-limit2": "No more than $1 ($2 for bots) allowed.",
+ "api-help-param-integer-min": "The {{PLURAL:$1|1=value|2=values}} must be no less than $2.",
+ "api-help-param-integer-max": "The {{PLURAL:$1|1=value|2=values}} must be no greater than $3.",
+ "api-help-param-integer-minmax": "The {{PLURAL:$1|1=value|2=values}} must be between $2 and $3.",
+ "api-help-param-upload": "Must be posted as a file upload using multipart/form-data.",
+ "api-help-param-multi-separate": "Separate values with <kbd>|</kbd>.",
+ "api-help-param-multi-max": "Maximum number of values is {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} for bots).",
+ "api-help-param-default": "Default: $1",
+ "api-help-param-default-empty": "Default: <span class=\"apihelp-empty\">(empty)</span>",
+ "api-help-param-token": "A \"$1\" token retrieved from [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "For compatibility, the token used in the web UI is also accepted.",
+ "api-help-param-disabled-in-miser-mode": "Disabled due to [[mw:Manual:$wgMiserMode|miser mode]].",
+ "api-help-param-limited-in-miser-mode": "<strong>Note:</strong> Due to [[mw:Manual:$wgMiserMode|miser mode]], using this may result in fewer than <var>$1limit</var> results returned before continuing; in extreme cases, zero results may be returned.",
+ "api-help-param-direction": "In which direction to enumerate:\n;newer:List oldest first. Note: $1start has to be before $1end.\n;older:List newest first (default). Note: $1start has to be later than $1end.",
+ "api-help-param-continue": "When more results are available, use this to continue.",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(no description)</span>",
+ "api-help-examples": "{{PLURAL:$1|Example|Examples}}:",
+ "api-help-permissions": "{{PLURAL:$1|Permission|Permissions}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Granted to}}: $2",
+ "api-help-right-apihighlimits": "Use higher limits in API queries (slow queries: $1; fast queries: $2). The limits for slow queries also apply to multivalue parameters.",
+
+ "api-credits-header": "Credits",
+ "api-credits": "API developers:\n* Roan Kattouw (lead developer Sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (creator, lead developer Sep 2006–Sep 2007)\n* Brad Jorsch (lead developer 2013–present)\n\nPlease send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org\nor file a bug report at https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/es.json b/includes/api/i18n/es.json
new file mode 100644
index 00000000..d0974772
--- /dev/null
+++ b/includes/api/i18n/es.json
@@ -0,0 +1,206 @@
+{
+ "@metadata": {
+ "authors": [
+ "Macofe",
+ "Effy",
+ "Alan",
+ "Fitoschido",
+ "JasterTDC",
+ "Edslov"
+ ]
+ },
+ "apihelp-main-param-action": "Qué acción se realizará.",
+ "apihelp-main-param-format": "El formato de la salida.",
+ "apihelp-main-param-curtimestamp": "Incluir la marca de tiempo actual en el resultado.",
+ "apihelp-block-description": "Bloquear usuario",
+ "apihelp-block-param-user": "El nombre de usuario, dirección IP o intervalo de IP que quieres bloquear.",
+ "apihelp-block-param-reason": "Razón para el bloqueo.",
+ "apihelp-block-param-anononly": "Bloquear solo usuarios anónimos (es decir, desactivar ediciones anónimas de esta dirección IP).",
+ "apihelp-block-param-nocreate": "Prevenir la creación de cuentas.",
+ "apihelp-block-param-reblock": "Si la cuenta ya está bloqueada, sobrescribir el bloqueo existente.",
+ "apihelp-block-param-watchuser": "Vigilar las páginas de usuario y de discusión del usuario o de la dirección IP.",
+ "apihelp-compare-param-fromtitle": "Primer título para comparar",
+ "apihelp-createaccount-description": "Crear una nueva cuenta de usuario.",
+ "apihelp-createaccount-param-name": "Nombre de usuario.",
+ "apihelp-createaccount-param-email": "Dirección de correo electrónico del usuario (opcional).",
+ "apihelp-createaccount-param-realname": "Nombre verdadero del usuario (opcional).",
+ "apihelp-createaccount-example-pass": "Crear usuario <kbd>testuser</kbd> con la contraseña <kbd>test123</kbd>.",
+ "apihelp-delete-description": "Borrar una página.",
+ "apihelp-delete-param-watch": "Añadir esta página a la lista de seguimiento del usuario actual.",
+ "apihelp-delete-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
+ "apihelp-delete-example-simple": "Borrar la <kbd>Página principal</kbd>",
+ "apihelp-disabled-description": "Se desactivó este módulo.",
+ "apihelp-edit-description": "Crear y editar páginas.",
+ "apihelp-edit-param-sectiontitle": "El título de una sección nueva.",
+ "apihelp-edit-param-text": "Contenido de la página.",
+ "apihelp-edit-param-minor": "Edición menor.",
+ "apihelp-edit-param-notminor": "Edición no menor.",
+ "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
+ "apihelp-edit-param-createonly": "No editar la página si ya existe.",
+ "apihelp-edit-param-nocreate": "Producir un error si la página no existe.",
+ "apihelp-edit-param-watch": "Añadir la página a la lista de seguimiento del usuario actual.",
+ "apihelp-edit-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
+ "apihelp-edit-example-edit": "Editar una página",
+ "apihelp-edit-example-prepend": "Anteponer <kbd>_&#95;NOTOC_&#95;</kbd> a una página.",
+ "apihelp-edit-example-undo": "Deshacer intervalo de revisiones 13579-13585 con resumen automático",
+ "apihelp-emailuser-description": "Enviar un mensaje de correo electrónico a un usuario.",
+ "apihelp-emailuser-param-target": "Cuenta de usuario destinatario.",
+ "apihelp-emailuser-param-subject": "Encabezamiento de asunto.",
+ "apihelp-emailuser-param-text": "Cuerpo del mensaje.",
+ "apihelp-emailuser-param-ccme": "Enviarme una copia de este mensaje.",
+ "apihelp-expandtemplates-param-title": "Título de la página.",
+ "apihelp-expandtemplates-param-text": "Sintaxis wiki que se convertirá.",
+ "apihelp-feedcontributions-description": "Devuelve el canal de contribuciones de un usuario.",
+ "apihelp-feedcontributions-param-feedformat": "El formato del canal.",
+ "apihelp-feedcontributions-param-year": "A partir del año (y anteriores).",
+ "apihelp-feedcontributions-param-month": "A partir del mes (y anteriores).",
+ "apihelp-feedcontributions-param-tagfilter": "Filtrar las contribuciones que tienen estas etiquetas.",
+ "apihelp-feedcontributions-param-deletedonly": "Mostrar solo las contribuciones borradas.",
+ "apihelp-feedcontributions-param-toponly": "Mostrar solo ediciones que son últimas revisiones.",
+ "apihelp-feedcontributions-param-newonly": "Mostrar solo ediciones que son creaciones de páginas.",
+ "apihelp-feedcontributions-param-showsizediff": "Mostrar la diferencia de tamaño entre revisiones.",
+ "apihelp-feedcontributions-example-simple": "Devolver las contribuciones del usuario <kbd>Ejemplo</kbd>.",
+ "apihelp-feedrecentchanges-description": "Devuelve un canal de cambios recientes.",
+ "apihelp-feedrecentchanges-param-feedformat": "El formato del canal.",
+ "apihelp-feedrecentchanges-param-invert": "Todos los espacios de nombres menos el que está seleccionado.",
+ "apihelp-feedrecentchanges-param-associated": "Incluir el espacio de nombres asociado (discusión o principal).",
+ "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados que devolver.",
+ "apihelp-feedrecentchanges-param-from": "Mostrar los cambios realizados a partir de entonces.",
+ "apihelp-feedrecentchanges-param-hideminor": "Ocultar cambios menores.",
+ "apihelp-feedrecentchanges-param-hidebots": "Ocultar los cambios realizados por bots.",
+ "apihelp-feedrecentchanges-param-hideanons": "Ocultar los cambios realizados por usuarios anónimos.",
+ "apihelp-feedrecentchanges-param-hideliu": "Ocultar los cambios realizados por usuarios registrados.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar los cambios patrullados.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Ocultar los cambios realizados por el usuario actual.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiquetas.",
+ "apihelp-feedrecentchanges-param-target": "Mostrar solo los cambios en las páginas enlazadas en esta.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar los cambios en páginas enlazadas con la página seleccionada.",
+ "apihelp-feedrecentchanges-example-simple": "Mostrar los cambios recientes",
+ "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días",
+ "apihelp-feedwatchlist-description": "Devuelve el canal de una lista de seguimiento.",
+ "apihelp-feedwatchlist-param-feedformat": "El formato del canal.",
+ "apihelp-feedwatchlist-param-linktosections": "Enlazar directamente a las secciones cambiadas de ser posible.",
+ "apihelp-feedwatchlist-example-default": "Mostrar el canal de la lista de seguimiento.",
+ "apihelp-feedwatchlist-example-all6hrs": "Mostrar todos los cambios en páginas vigiladas en las últimas 6 horas.",
+ "apihelp-filerevert-description": "Revertir el archivo a una versión anterior.",
+ "apihelp-filerevert-param-filename": "Nombre de archivo final, sin el prefijo Archivo:",
+ "apihelp-filerevert-param-comment": "Comentario de carga.",
+ "apihelp-help-description": "Mostrar la ayuda para los módulos especificados.",
+ "apihelp-help-example-main": "Ayuda del módulo principal",
+ "apihelp-help-example-recursive": "Toda la ayuda en una página",
+ "apihelp-help-example-help": "Ayuda del módulo de ayuda en sí",
+ "apihelp-imagerotate-description": "Girar una o más imágenes.",
+ "apihelp-imagerotate-param-rotation": "Grados que rotar una imagen en sentido horario.",
+ "apihelp-imagerotate-example-simple": "Rotar <kbd>File:Ejemplo.png</kbd> <kbd>90</kbd> grados.",
+ "apihelp-imagerotate-example-generator": "Rotar todas las imágenes en la <kbd>Categoría:Girar</kbd> <kbd>180</kbd> grados.",
+ "apihelp-import-param-summary": "Resumen de importación.",
+ "apihelp-import-param-xml": "Se cargó el archivo XML.",
+ "apihelp-import-param-rootpage": "Importar como subpágina de esta página.",
+ "apihelp-login-param-name": "Nombre de usuario.",
+ "apihelp-login-param-password": "Contraseña.",
+ "apihelp-login-param-domain": "Dominio (opcional).",
+ "apihelp-login-example-login": "Acceder",
+ "apihelp-logout-description": "Salir y vaciar los datos de la sesión.",
+ "apihelp-logout-example-logout": "Cerrar la sesión del usuario actual",
+ "apihelp-managetags-param-reason": "Un motivo opcional para crear, eliminar, activar o desactivar la etiqueta.",
+ "apihelp-managetags-example-delete": "Eliminar la etiqueta <kbd>vandlaismo</kbd> con el motivo <kbd>mal deletreado</kbd>",
+ "apihelp-move-description": "Mover una página.",
+ "apihelp-move-param-reason": "Motivo del cambio de nombre.",
+ "apihelp-move-param-movetalk": "Renombrar la página de discusión si existe.",
+ "apihelp-move-param-movesubpages": "Renombrar las subpáginas si procede.",
+ "apihelp-move-param-noredirect": "No crear una redirección.",
+ "apihelp-move-param-watch": "Añadir la página y su redirección a la lista de seguimiento del usuario actual.",
+ "apihelp-move-param-unwatch": "Eliminar la página y la redirección de la lista de seguimiento del usuario.",
+ "apihelp-move-param-ignorewarnings": "Ignorar cualquier aviso.",
+ "apihelp-opensearch-description": "Buscar en el wiki mediante el protocolo OpenSearch.",
+ "apihelp-opensearch-param-search": "Buscar cadena.",
+ "apihelp-options-example-reset": "Restablecer todas las preferencias",
+ "apihelp-paraminfo-description": "Obtener información acerca de los módulos de la API.",
+ "apihelp-paraminfo-param-helpformat": "Formato de las cadenas de ayuda.",
+ "apihelp-patrol-example-rcid": "Patrullar un cambio reciente",
+ "apihelp-patrol-example-revid": "Patrullar una revisión",
+ "apihelp-protect-param-reason": "Motivo de la (des)protección.",
+ "apihelp-protect-example-protect": "Proteger una página",
+ "apihelp-query+allcategories-description": "Enumerar todas las categorías.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Solo puede usarse con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "No puede ser utilizado con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-from": "Empezar a listar en este título.",
+ "apihelp-query+alldeletedrevisions-param-to": "Terminar de listar en este título.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Buscar todos los títulos de las páginas que comiencen con este valor.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Listar solo las revisiones con esta etiqueta.",
+ "apihelp-query+alldeletedrevisions-param-user": "Listar solo las revisiones de este usuario.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "No listar las revisiones de este usuario.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Listar solo las páginas en este espacio de nombres.",
+ "apihelp-query+alldeletedrevisions-example-user": "Listar las últimas 50 contribuciones borradas del usuario <kbd>Ejemplo<kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Listar las primeras 50 revisiones borradas en el espacio de nombres principal.",
+ "apihelp-query+allfileusages-description": "Listar todos los usos del archivo, incluyendo los que no existen.",
+ "apihelp-query+allimages-param-sha1": "Suma SHA1 de la imagen. Invalida $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "Suma SHA1 de la imagen en base 36 (usada en MediaWiki).",
+ "apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
+ "apihelp-query+allpages-example-B": "Mostrar una lista de páginas que empiecen con la letra <kbd>B</kbd>.",
+ "apihelp-query+allusers-param-activeusers": "Solo listar usuarios activos en {{PLURAL:$1|el último día|los $1 últimos días}}.",
+ "apihelp-query+backlinks-param-pageid": "Identificador de página que buscar. No puede usarse junto con <var>$1title</var>",
+ "apihelp-query+backlinks-example-simple": "Mostrar enlaces a la <kbd>Portada<kbd>.",
+ "apihelp-query+blocks-example-simple": "Listar bloques.",
+ "apihelp-query+categoryinfo-example-simple": "Obtener información acerca de <kbd>Category:Foo</kbd> y <kbd>Category:Bar</kbd>",
+ "apihelp-query+categorymembers-example-generator": "Obtener información sobre las primeras 10 páginas de la <kbd>Categoría:Física</kbd>",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
+ "apihelp-query+deletedrevs-example-mode3-talk": "Listar las primeras 50 páginas en el espacio de nombres {{ns:talk}} (modo 3).",
+ "apihelp-query+duplicatefiles-example-simple": "Buscar duplicados de [[:File:Alber Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los ficheros.",
+ "apihelp-query+exturlusage-example-simple": "Mostrar páginas que enlacen con <kbd>http://www.mediawiki.org</kbd>.",
+ "apihelp-query+filerepoinfo-example-simple": "Obtener información acerca de los repositorios de archivos.",
+ "apihelp-query+images-description": "Devuelve todos los archivos contenidos en las páginas dadas.",
+ "apihelp-query+images-example-simple": "Obtener una lista de los archivos usados en la [[Main Page|Portada]].",
+ "apihelp-query+imageusage-example-simple": "Mostrar las páginas que usan [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageusage-example-generator": "Obtener información sobre las páginas que empleen [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+info-example-protection": "Obtén información general y protección acerca de la página <kb>Página principal</kbd>.",
+ "apihelp-query+iwbacklinks-example-simple": "Obtener las páginas enlazadas a [[wikibooks:Test]]",
+ "apihelp-query+langbacklinks-example-simple": "Obtener las páginas enlazadas a [[:fr:Test]]",
+ "apihelp-query+linkshere-example-generator": "Obtener información acerca de las páginas enlazadas a la [[Main Page|Portada]].",
+ "apihelp-query+protectedtitles-example-generator": "Encuentra enlaces a títulos protegidos en el espacio de nombres principal.",
+ "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
+ "apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
+ "apihelp-query+revisions-example-last5": "Mostrar las últimas 5 revisiones de la <kbd>Portada</kbd>.",
+ "apihelp-query+search-param-info": "Qué metadatos devolver.",
+ "apihelp-query+search-example-text": "Buscar <kbd>meaning</kbd> en los textos.",
+ "apihelp-query+siteinfo-example-simple": "Obtener información del sitio.",
+ "apihelp-query+usercontribs-example-user": "Mostrar contribuciones del usuario <kbd>Ejemplo</kbd>.",
+ "apihelp-query+usercontribs-example-ipprefix": "Mostrar las contribuciones de todas las direcciones IP con el prefijo <kbd>192.0.2.</kbd>.",
+ "apihelp-query+userinfo-description": "Obtener información sobre el usuario actual.",
+ "apihelp-query+watchlist-param-excludeuser": "No listar cambios de este usuario.",
+ "apihelp-query+watchlistraw-param-show": "Sólo listar los elementos que cumplen estos criterios.",
+ "apihelp-query+watchlistraw-example-simple": "Listar las páginas de la lista de seguimiento del usuario actual.",
+ "apihelp-unblock-example-user": "Desbloquear al usuario <kbd>Bob</kbd> con el motivo <kbd>Lo siento, Bob</kbd>",
+ "apihelp-undelete-example-revisions": "Restaurar dos revisiones de la página <kbd>Portada</kbd>.",
+ "apihelp-upload-param-watch": "Vigilar la página.",
+ "apihelp-upload-param-ignorewarnings": "Ignorar las advertencias.",
+ "apihelp-upload-example-url": "Subir desde una URL.",
+ "apihelp-userrights-param-user": "Nombre de usuario.",
+ "apihelp-userrights-param-add": "Agregar el usuario a estos grupos.",
+ "apihelp-userrights-param-remove": "Eliminar el usuario de estos grupos.",
+ "apihelp-userrights-param-reason": "Motivo del cambio.",
+ "apihelp-userrights-example-user": "Agregar al usuario <kbd>FooBot</kbd> al grupo <kbd>bot</kbd> y eliminarlo de los grupos <kbd>sysop</kbd> y <kbd>burócrata</kbd>.",
+ "apihelp-watch-example-watch": "Vigilar la página <kbd>Portada</kbd>.",
+ "apihelp-watch-example-unwatch": "Dejar de vigilar la <kbd>Portada</kbd>.",
+ "api-help-main-header": "Módulo principal",
+ "api-help-flag-deprecated": "Este módulo está en desuso.",
+ "api-help-flag-readrights": "Este módulo requiere permisos de lectura.",
+ "api-help-flag-writerights": "Este módulo requiere permisos de escritura.",
+ "api-help-flag-mustbeposted": "Este módulo solo acepta solicitudes POST.",
+ "api-help-flag-generator": "Este módulo puede utilizarse como un generador.",
+ "api-help-parameters": "{{PLURAL:$1|Parámetro|Parámetros}}:",
+ "api-help-param-deprecated": "En desuso.",
+ "api-help-param-required": "Este parámetro es obligatorio.",
+ "api-help-param-list": "{{PLURAL:$1|1=Un valor|2=Valores (separados por <kbd>{{!}}</kbd>)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Debe estar vacío|Puede estar vacío, o $2}}",
+ "api-help-param-multi-separate": "Separar los valores con <kbd>|</kbd>.",
+ "api-help-param-default": "Predeterminado: $1",
+ "api-help-param-default-empty": "Predeterminado: <span class=\"apihelp-empty\">(vacío)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(sin descripción)</span>",
+ "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:",
+ "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Concedido a|Concedidos a}}: $2",
+ "api-credits-header": "Créditos",
+ "api-credits": "Desarrolladores de la API:\n* Roan Kattouw (desarrollador principal sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (creador, desarrollador principal sep 2006–sep 2007)\n* Brad Jorsch (desarrollador principal 2013–actualidad)\n\nEnvía comentarios, sugerencias y preguntas a mediawiki-api@lists.wikimedia.org\no reporta un error en https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/eu.json b/includes/api/i18n/eu.json
new file mode 100644
index 00000000..574bd2fe
--- /dev/null
+++ b/includes/api/i18n/eu.json
@@ -0,0 +1,57 @@
+{
+ "@metadata": {
+ "authors": [
+ "Subi"
+ ]
+ },
+ "apihelp-block-description": "Blokeatu erabiltzaile bat.",
+ "apihelp-createaccount-description": "Erabiltzaile kontu berria sortu.",
+ "apihelp-createaccount-param-email": "Erabiltzailearen helbide elektronikoa (aukerakoa).",
+ "apihelp-createaccount-param-realname": "Erabiltzailearen benetako izena (aukerakoa).",
+ "apihelp-delete-description": "Orrialde bat ezabatu.",
+ "apihelp-edit-description": "Orrialdeak sortu eta aldatu.",
+ "apihelp-edit-param-minor": "Aldaketa txikia.",
+ "apihelp-edit-example-edit": "Orrialde bat aldatu",
+ "apihelp-expandtemplates-param-title": "Orrialdearen izenburua.",
+ "apihelp-feedcontributions-param-year": "Urtetik aurrera (eta lehenagotik)",
+ "apihelp-feedcontributions-param-month": "Hilabetetik aurrera (eta lehenagotik)",
+ "apihelp-feedrecentchanges-param-hideminor": "Ezkutatu aldaketa txikiak.",
+ "apihelp-feedrecentchanges-param-hidebots": "Ezkutatu botek egindako aldaketak.",
+ "apihelp-feedrecentchanges-param-hideanons": "Ezkutatu erabiltzaile anonimoek egindako aldaketak.",
+ "apihelp-feedrecentchanges-param-hideliu": "Ezkutatu izena emandako erabiltzaileek egindako aldaketak.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Ezkutatu zainpeko aldaketak.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Ezkutatu zuk egindako aldaketak.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Iragazi etiketen arabera.",
+ "apihelp-feedrecentchanges-example-simple": "Erakutsi aldaketa berriak",
+ "apihelp-feedrecentchanges-example-30days": "Erakutsi aldaketa berriak 30 egunez",
+ "apihelp-imagerotate-description": "Irudi bat edo gehiago biratu.",
+ "apihelp-login-param-password": "Pasahitza.",
+ "apihelp-login-param-domain": "Domeinua (hautazkoa).",
+ "apihelp-login-example-login": "Saioa hasi",
+ "apihelp-move-description": "Orrialde bat mugitu",
+ "apihelp-protect-example-protect": "Orrialde bat babestu",
+ "apihelp-query+allusers-param-witheditsonly": "Bakarrik zerrendatu aldaketak egin dituzten erabiltzaileak.",
+ "apihelp-query+allusers-param-activeusers": "Bakarrik zerrendatu azken {{PLURAL:$1|eguneko|$1 egunetako}} erabiltzaile aktiboak.",
+ "apihelp-query+imageinfo-param-urlheight": "$1urlwidth-en antzekoa.",
+ "apihelp-query+imageusage-example-simple": "Erakutsi [[:File:Albert Einstein Head.jpg]] darabilten orriak",
+ "apihelp-query+prefixsearch-param-search": "Bilatu katea.",
+ "apihelp-query+protectedtitles-example-simple": "Zerrendatu babestutako izenburuak",
+ "apihelp-query+recentchanges-example-simple": "Zerrendatu aldaketa berriak.",
+ "apihelp-upload-example-url": "Igo URL batetik.",
+ "apihelp-userrights-param-reason": "Aldaketarako arrazoia.",
+ "api-help-main-header": "Modulu nagusia",
+ "api-help-flag-deprecated": "Modulu hau zaharkitua dago.",
+ "api-help-parameters": "{{PLURAL:$1|Parametroa|Parametroak}}:",
+ "api-help-param-deprecated": "Zaharkitua.",
+ "api-help-param-required": "Parametro hau beharrezkoa da.",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Hutsik egon behar du|Hutsik egon daiteke edo $2}}",
+ "api-help-param-limit": "Ez dira $1 baino gehiago onartzen.",
+ "api-help-param-limit2": "Ez dira $1 ($2 botentzat) baino gehiago onartzen.",
+ "api-help-param-default": "Lehenetsia: $1",
+ "api-help-param-default-empty": "Lehenetsia: <span class=\"apihelp-empty\">(hutsik)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(deskribapenik gabe)</span>",
+ "api-help-examples": "{{PLURAL:$1|Adibidea|Adibideak}}:",
+ "api-help-permissions": "{{PLURAL:$1|Baimena|Baimenak}}:",
+ "api-credits-header": "Kredituak",
+ "api-credits": "API garatzaileak:\n* Roan Kattouw (garatzaile nagusia, 2007ko ira.–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (sortzailea, garatzaile nagusia, 2006ko ira.–2007ko ira.)\n* Brad Jorsch (garatzaile nagusia 2013–gaur egun)\n\nMesedez, bidal iezazkiguzu zure iruzkinak, iradokizunak eta galderak mediawiki-api@lists.wikimedia.org helbidera edo bete ezazu errore-txostena https://phabricator.wikimedia.org/ helbidean."
+}
diff --git a/includes/api/i18n/fa.json b/includes/api/i18n/fa.json
new file mode 100644
index 00000000..d792fd6e
--- /dev/null
+++ b/includes/api/i18n/fa.json
@@ -0,0 +1,240 @@
+{
+ "@metadata": {
+ "authors": [
+ "Alirezaaa",
+ "Arash.pt",
+ "Fatemi127",
+ "Reza1615",
+ "KhabarNegar",
+ "Sahehco",
+ "Signal89",
+ "Mjbmr"
+ ]
+ },
+ "apihelp-main-param-action": "کدام عملیات را انجام دهد.",
+ "apihelp-main-param-format": "فرمت خروجی.",
+ "apihelp-main-param-curtimestamp": "برچسب زمان کنونی را در نتیجه قرار دهید.",
+ "apihelp-block-description": "بستن کاربر",
+ "apihelp-block-param-user": "نام کاربری، آدرس آی پی یا محدوده آی پی موردنظر شما برای بستن.",
+ "apihelp-block-param-reason": "دلیل بسته‌شدن",
+ "apihelp-block-param-anononly": "فقط بستن کاربران ناشناس (مانند غیرفعال‌کردن ویرایش‌های ناشناس این آی‌پی).",
+ "apihelp-block-param-nocreate": "جلوگیری از ایجاد حساب.",
+ "apihelp-block-param-autoblock": "به طور خودکار آخرین نشانی آی‌پی استفاده‌شده، و هر نشانی پس از آن که سعی می‌کند از آن داخل شود را ببند.",
+ "apihelp-block-param-noemail": "از کاربر در برابر ارسال ایمیل از طریق ویکی جلوگیری شود. (نیازمند دسترسی <code>blockemail</code> است).",
+ "apihelp-block-param-hidename": "نام کاربری را از سیاههٔ بستن پنهان کن. (نیازمند دسترسی <code>hideuser</code> است).",
+ "apihelp-block-param-allowusertalk": "به کاربر برای ویرایش صفحه بحث‌شان اجازه دهید (بسته به <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "اگر کاربر پیش از این مسدود شده‌است، مسدود موجود را بازنویسی کن.",
+ "apihelp-block-param-watchuser": "صفحه‌های کاربر و بحث کاربر نشانی آی‌پی یا کاربر را پی‌گیری کنید.",
+ "apihelp-block-example-ip-simple": "آی‌پی <kbd>۱۹۲٫۰٫۲٫۵</kbd> را برای سه روز همراه دلیل <kbd>برخورد اول</kbd> ببندید",
+ "apihelp-clearhasmsg-description": "پرچم <code>hasmsg</code> را برای کاربر جاری پاک کن.",
+ "apihelp-clearhasmsg-example-1": "پاک‌کردن پرچم <code>hasmsg</code> برای کاربر جاری",
+ "apihelp-compare-description": "تفاوت بین ۲ صفحه را بیابید.\n\nشما باید یک شماره بازبینی، یک عنوان صفحه، یا یک شناسه صفحه برای هر دو «از» و «به» مشخص کنید.",
+ "apihelp-compare-param-fromtitle": "عنوان اول برای مقایسه.",
+ "apihelp-compare-param-fromid": "شناسه صفحه اول برای مقایسه.",
+ "apihelp-compare-param-fromrev": "نسخه اول برای مقایسه.",
+ "apihelp-compare-param-totitle": "عنوان دوم برای مقایسه.",
+ "apihelp-compare-param-toid": "شناسه صفحه دوم برای مقایسه.",
+ "apihelp-compare-param-torev": "نسخه دوم برای مقایسه.",
+ "apihelp-compare-example-1": "ایجاد تفاوت بین نسخه 1 و 2",
+ "apihelp-createaccount-description": "ایجاد حساب کاربری",
+ "apihelp-createaccount-param-name": "نام کاربری.",
+ "apihelp-createaccount-param-password": "رمز عبور (نادیده گرفته می‌شود اگر <var>$1mailpassword</var> تنظیم شده‌باشد).",
+ "apihelp-createaccount-param-domain": "دامنه برای احراز هویت خارجی (اختیاری).",
+ "apihelp-createaccount-param-email": "آدرس ایمیل کاربر (اختیاری)",
+ "apihelp-createaccount-param-realname": "نام واقعی کاربر (اختیاری).",
+ "apihelp-createaccount-param-mailpassword": "اگر به هر مقداری تنظیم شود، یک رمز عبور تصادفی به کاربر ایمیل خواهد شد.",
+ "apihelp-createaccount-param-reason": "دلیل اختیاری برای ایجاد حساب کاربری جهت قرارگرفتن در سیاهه‌ها.",
+ "apihelp-createaccount-example-pass": "ایجاد کاربر <kbd>testuser</kbd> همراه رمز عبور <kbd>test123</kbd>",
+ "apihelp-createaccount-example-mail": "ایجاد کاربر <kbd>testmailuser</kbd> و ارسال یک رمز عبور تصادفی به ای‌میل.",
+ "apihelp-delete-description": "حذف صفحه",
+ "apihelp-delete-param-title": "عنوان صفحه‌ای که قصد حذفش را دارید. نمی‌تواند در کنار <var>$1pageid</var> استفاده شود.",
+ "apihelp-delete-param-pageid": "شناسه صفحه‌ای که قصد حذفش را دارید. نمی‌تواند در کنار <var>$1title</var> استفاده شود.",
+ "apihelp-delete-param-reason": "دلیل برای حذف. اگر تنظیم نشود، یک دلیل خودکار ساخته‌شده استفاده می‌شود.",
+ "apihelp-delete-param-watch": "افزودن صفحه به فهرست پی‌گیری کاربر فعلی",
+ "apihelp-delete-param-unwatch": "صفحه را از پی‌گیری‌تان حذف کنید.",
+ "apihelp-delete-example-simple": "حذف <kbd>صفحهٔ اصلی</kbd>",
+ "apihelp-delete-example-reason": "حذف <kbd>صفحهٔ اصلی</kbd> همراه دلیل <kbd>آماده‌سازی برای انتقال</kbd>",
+ "apihelp-disabled-description": "این پودمان غیرفعال شده است.",
+ "apihelp-edit-description": "ایجاد و ویرایش صفحه",
+ "apihelp-edit-param-title": "عنوان صفحه‌ای که قصد ویرایشش را دارید. نمی‌تواند در کنار <var>$1pageid</var> استفاده شود.",
+ "apihelp-edit-param-pageid": "شناسه صفحهٔ صفحه‌ای که می‌خواهید ویرایشش کنید. نمی‌تواند در کنار <var>$1title</var> استفاده شود.",
+ "apihelp-edit-param-section": "شماره بخش. <kbd>۰</kbd> برای بخش بالا، «<kbd>تازه</kbd>» برای یک بخش تازه.",
+ "apihelp-edit-param-sectiontitle": "عنوان برای بخش جدید.",
+ "apihelp-edit-param-text": "محتوای صفحه.",
+ "apihelp-edit-param-summary": "خلاصه را ویرایش کنید. همچنین عنوان بخش را زمانی که $1section=تازه و $1sectiontitle تنظیم نشده‌است.",
+ "apihelp-edit-param-minor": "ویرایش جزئی.",
+ "apihelp-edit-param-notminor": "ویرایش غیر جزئی.",
+ "apihelp-edit-param-bot": "علامت زدن این ویرایش به عنوان ویرایش ربات.",
+ "apihelp-edit-param-createonly": "اگر صفحه موجود بود، ویرایش نکن.",
+ "apihelp-edit-param-nocreate": "رها کردن خطا در صورتی که صفحه وجود ندارد.",
+ "apihelp-edit-param-watch": "افزودن صفحه به فهرست پی‌گیری شما",
+ "apihelp-edit-param-unwatch": "حذف صفحه از فهرست پی‌گیری شما",
+ "apihelp-edit-param-prependtext": "این متن را به ابتدای صفحه اضافه کنید. $1text را لغو می‌کند.",
+ "apihelp-edit-param-undo": "این بازبینی را برگردانید. $1text، $1prependtext و $1appendtext را باطل می‌کند.",
+ "apihelp-edit-param-undoafter": "همه بازبینی‌ها را از $1undo تا این یکی برگردانید. اگر تنظیم نشد، فقط یک بازبینی را برگردانید.",
+ "apihelp-edit-param-redirect": "اصلاح خودکار تغییرمسیرها.",
+ "apihelp-edit-example-edit": "ویرایش صفحه",
+ "apihelp-emailuser-description": "ایمیل به کاربر",
+ "apihelp-emailuser-param-target": "کاربر برای ارسال ایمیل به وی.",
+ "apihelp-emailuser-param-subject": "موضوع هدر.",
+ "apihelp-emailuser-param-text": "متن رایانه.",
+ "apihelp-emailuser-param-ccme": "ارسال یک نسخه از رایانه به شما.",
+ "apihelp-expandtemplates-description": "گسترش همه الگوها در ویکی نبشته",
+ "apihelp-expandtemplates-param-title": "عنوان صفحه",
+ "apihelp-expandtemplates-param-text": "تبدیل برای ویکی‌متن.",
+ "apihelp-feedcontributions-description": "خوراک مشارکت‌های یک کاربر را برمی‌گرداند.",
+ "apihelp-feedcontributions-param-feedformat": "فرمت خوراک.",
+ "apihelp-feedcontributions-param-namespace": "فیلتر شدن مشارکتها براساس فضای نام.",
+ "apihelp-feedcontributions-param-year": "از سال (و پیش از آن).",
+ "apihelp-feedcontributions-param-month": "از ماه (و پیش از آن).",
+ "apihelp-feedcontributions-param-tagfilter": "فیلتر کردن مشارکتها براساس این برچسب‌ها.",
+ "apihelp-feedcontributions-param-deletedonly": "فقط مشارکت‌های حذف شده نمایش داده شود.",
+ "apihelp-feedcontributions-param-toponly": "فقط ویرایش‌هایی که آخرین نسخه‌اند نمایش داده شود.",
+ "apihelp-feedcontributions-param-newonly": "فقط نمایش ویرایش‌هایی که تولید‌های صفحه هستند.",
+ "apihelp-feedcontributions-param-showsizediff": "نمایش تفاوت حجم تغییرات بین نسخه‌ها.",
+ "apihelp-feedcontributions-example-simple": "مشارکت‌های [[کاربر:نمونه]] را برگردان",
+ "apihelp-feedrecentchanges-description": "خوراک تغییرات اخیر را برمی‌گرداند.",
+ "apihelp-feedrecentchanges-param-feedformat": "فرمت خوراک.",
+ "apihelp-feedrecentchanges-param-namespace": "فضای نام برای محدودکردن نتایج به.",
+ "apihelp-feedrecentchanges-param-invert": "همهٔ فضاهای نام به جز انتخاب‌شده‌ها.",
+ "apihelp-feedrecentchanges-param-associated": "فضای نام مرتبط (بحث یا اصلی) را شامل می‌شود.",
+ "apihelp-feedrecentchanges-param-days": "روز برای محدود کردن نتایج.",
+ "apihelp-feedrecentchanges-param-limit": "حداکثر تعداد نتایج خروجی.",
+ "apihelp-feedrecentchanges-param-from": "نمایش تغییرات پس از آن.",
+ "apihelp-feedrecentchanges-param-hideminor": "پنهان کردن تغییرات جزئی.",
+ "apihelp-feedrecentchanges-param-hidebots": "پنهان کردن تغییرات انجام شده توسط ربات‌ها.",
+ "apihelp-feedrecentchanges-param-hideanons": "پنهان کردن ویرایش‌های کاربران ناشناس.",
+ "apihelp-feedrecentchanges-param-hideliu": "پنهان کردن ویرایش‌های کاربران ثبت‌نام کرده.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "پنهان کردن ویرایش گشت‌زن‌ها.",
+ "apihelp-feedrecentchanges-param-hidemyself": "پنهان کردن ویرایش‌های کاربر فعلی.",
+ "apihelp-feedrecentchanges-param-tagfilter": "فیلتر کردن براساس برچسب",
+ "apihelp-feedrecentchanges-param-target": "فقط نمایش ویرایش‌هایی که پیوند دارند به این صفحه.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "نمایش ویرایش‌ها بر روی صفحات پیوند داده شده به صفحات انتخاب شده.",
+ "apihelp-feedrecentchanges-example-simple": "نمایش تغییرات اخیر",
+ "apihelp-feedrecentchanges-example-30days": "نمایش تغییرات اخیر در 30 روز اخیر",
+ "apihelp-feedwatchlist-description": "برگرداندن فهرست پیگیری‌های خوراک.",
+ "apihelp-feedwatchlist-param-feedformat": "فرمت خوراک.",
+ "apihelp-feedwatchlist-param-linktosections": "اگر ممکن است به طور مستقیم به بخش‌های تغییریافته پیوند دهید.",
+ "apihelp-feedwatchlist-example-default": "نمایش خوراک فهرست پی‌گیری",
+ "apihelp-feedwatchlist-example-all6hrs": "همهٔ تغییرات ۶ ساعت گذشته در صفحه‌های پی‌گیری را نمایش دهید",
+ "apihelp-filerevert-description": "واگردانی فایل به یک نسخه قدیمی",
+ "apihelp-filerevert-param-filename": "نام پروندهٔ مقصد، بدون پیشوند پرونده:.",
+ "apihelp-filerevert-param-comment": "ارسال دیدگاه.",
+ "apihelp-filerevert-param-archivename": "نام بایگانی بازبینی برای برگرداندن.",
+ "apihelp-filerevert-example-revert": "برگرداندن <kbd>Wiki.png</kbd> به نسخهٔ <kbd>2011-03-05T15:27:40Z</kbd>",
+ "apihelp-help-description": "راهنما برای پودمان‌های مشخص‌شده را نمایش دهید.",
+ "apihelp-help-param-helpformat": "قالب‌بندی خروجی راهنما.",
+ "apihelp-help-example-main": "راهنما برای پودمان اصلی",
+ "apihelp-help-example-recursive": "همهٔ راهنما در یک صفحه",
+ "apihelp-help-example-help": "راهنما برای خود ماژول راهنما",
+ "apihelp-help-example-query": "راهنما برای دو زیر پودمان کوئری",
+ "apihelp-imagerotate-description": "چرخاندن یک یا چند تصویر",
+ "apihelp-imagerotate-param-rotation": "درجه برای چرخاندن تصویر در جهت ساعت‌گرد.",
+ "apihelp-imagerotate-example-simple": "چرخاندن <kbd>۹۰</kbd> درجه برای <kbd>File:Example.png</kbd>",
+ "apihelp-imagerotate-example-generator": "چرخاندن <kbd>۱۸۰</kbd> درجه برای همهٔ تصاویر موجود در <kbd>Category:Flip</kbd>",
+ "apihelp-import-param-summary": "خلاصه درون‌ریزی.",
+ "apihelp-import-param-xml": "پرونده XML بارگذاری شد.",
+ "apihelp-import-param-interwikisource": "برای درون‌ریز میان‌ویکی: ویکی برای درون‌ریزی از.",
+ "apihelp-import-param-interwikipage": "برای درون‌ریز میان‌ویکی: صفحه برای درون‌ریزی.",
+ "apihelp-import-param-fullhistory": "برای درون‌ریزی میان‌ویکی: درون‌ریزی تاریخچهٔ کامل، نه فقط نسخهٔ موجود.",
+ "apihelp-import-param-templates": "برای درون ریزی میان‌ویکی: همچنین درون‌ریزی الگوهای مورد استفاده.",
+ "apihelp-import-param-namespace": "برای درون‌ریزی میان‌ویکی: درون‌ریزی به این فضای نام.",
+ "apihelp-import-param-rootpage": "درون‌ریزی به عنوان زیر صفحهٔ این صفحه.",
+ "apihelp-login-param-name": "نام کاربری.",
+ "apihelp-login-param-password": "گذرواژه.",
+ "apihelp-login-param-domain": "دامنه (اختیاری)",
+ "apihelp-login-example-gettoken": "دریافت توکن ورود",
+ "apihelp-login-example-login": "ورود",
+ "apihelp-logout-description": "خروج به همراه پاک نمودن اطلاعات این نشست",
+ "apihelp-logout-example-logout": "خروج کاربر فعلی",
+ "apihelp-move-description": "انتقال صفحه",
+ "apihelp-move-param-to": "عنوانی که قصد دارید صفحه را به آن نام تغییر دهید.",
+ "apihelp-move-param-reason": "دلیل انتقال",
+ "apihelp-move-param-movetalk": "صفحهٔ بحث را تغییرنام دهید، اگر وجوددارد.",
+ "apihelp-move-param-movesubpages": "زیرصفحه را تغییرنام دهید، اگر شدنی است.",
+ "apihelp-move-param-noredirect": "عدم ساخت تغییرمسیر.",
+ "apihelp-move-param-watch": "صفحه و تغییرمسیر را به پی‌گیری کاربر کنونی بیافزایید.",
+ "apihelp-move-param-unwatch": "صفحه و تغییرمسیر را از پی‌گیری کاربر کنونی حذف کنید.",
+ "apihelp-move-param-ignorewarnings": "چشم‌پوشی از همهٔ هشدارها.",
+ "apihelp-opensearch-description": "جستجو در ویکی بااستفاده از پروتکل اوپن‌سرچ.",
+ "apihelp-opensearch-param-search": "جستجوی رشته.",
+ "apihelp-opensearch-param-limit": "حداکثر تعداد نتایج برای بازگرداندن.",
+ "apihelp-opensearch-param-namespace": "فضاهای نامی برای جستجو",
+ "apihelp-opensearch-param-suggest": "کاری نکنید اگر <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> false است.",
+ "apihelp-opensearch-param-format": "فرمت خروجی.",
+ "apihelp-opensearch-example-te": "یافتن صفحه‌هایی که با <kbd>ته</kbd> آغاز می‌شوند",
+ "apihelp-options-example-reset": "بازنشانی همه تنظیمات.",
+ "apihelp-paraminfo-param-helpformat": "ساختار راهنمای رشته‌ها",
+ "apihelp-parse-example-page": "تجزیه یک صفحه.",
+ "apihelp-parse-example-text": "تجزیه متن ویکی.",
+ "apihelp-parse-example-summary": "تجزیه خلاصه.",
+ "apihelp-patrol-description": "گشت‌زنی یک صفحه یا نسخهٔ ویرایشی.",
+ "apihelp-patrol-example-rcid": "گشت‌زنی یک تغییر اخیر",
+ "apihelp-patrol-example-revid": "گشت‌زدن یک نسخه",
+ "apihelp-protect-description": "تغییر سطح محافظت صفحه",
+ "apihelp-protect-param-reason": "دلیل برای (عدم) حفاظت.",
+ "apihelp-protect-example-protect": "محافظت از صفحه",
+ "apihelp-protect-example-unprotect": "خارج ساختن صفحه از حفاظت با تغییر سطح حفاظتی به <kbd>همگان</kbd>.",
+ "apihelp-protect-example-unprotect2": "خارج ساختن صفحه از حفاظت با قراردادن هیچ‌گونه محدودیت‌حفاظتی",
+ "apihelp-purge-param-forcelinkupdate": "به‌روزرسانی جداول پیوندها.",
+ "apihelp-purge-param-forcerecursivelinkupdate": "جدول پیوندها را به‌روز رسانی کنید، و جدول‌های پیوندهای هر صفحه‌ای را که از این صفحه به عنوان الگو استفاده می‌کند به‌روز رسانی کنید.",
+ "apihelp-query-param-list": "کدام فهرست‌ها دریافت شود.",
+ "apihelp-query-param-meta": "کدام فراداده‌ها دریافت شود.",
+ "apihelp-query+allcategories-param-prefix": "عنوان همهٔ رده‌ها را که با این مقدار آغاز می‌شود جستجو کنید.",
+ "apihelp-query+allcategories-param-limit": "میزان رده‌ها برای بازگرداندن.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "نمی‌تواند همراه <var>$3user</var> به کار رود.",
+ "apihelp-query+allfileusages-param-limit": "تعداد آیتم‌ها برای بازگرداندن.",
+ "apihelp-query+allfileusages-param-dir": "جهتی که باید فهرست شود.",
+ "apihelp-query+allfileusages-example-unique": "فهرست پرونده‌های با عنوان یکتا",
+ "apihelp-query+allfileusages-example-unique-generator": "گرفتن عنوان همهٔ پرونده‌ها، برچسب زدن موارد گم شده",
+ "apihelp-query+allfileusages-example-generator": "گرفتن صفحاتی که دارای پرونده هستند",
+ "apihelp-query+allimages-description": "متوالی شمردن همهٔ تصاویر.",
+ "apihelp-query+allimages-param-sort": "خصوصیت برای مرتب‌سازی بر پایه آن",
+ "apihelp-query+allimages-param-dir": "جهتی که باید فهرست شود.",
+ "apihelp-query+allimages-param-minsize": "محدودکردن به صفحه‌هایی که دست کم این تعداد بایت دارند.",
+ "apihelp-query+allimages-param-maxsize": "محدودکردن به صفحه‌هایی که حداکثر این تعداد بایت دارند.",
+ "apihelp-query+alllinks-param-namespace": "فضای نامی که باید شمرده شود.",
+ "apihelp-query+alllinks-param-limit": "تعداد آیتم‌ها برای بازگرداندن.",
+ "apihelp-query+alllinks-param-dir": "جهتی که باید فهرست شود.",
+ "apihelp-query+allpages-param-filterredir": "صفحه‌هایی که باید فهرست شوند.",
+ "apihelp-query+allpages-param-minsize": "محدودکردن به صفحه‌هایی که همراه دست کم این تعداد بایت است.",
+ "apihelp-query+allpages-param-limit": "میزان کل صفحه‌ها برای بازگرداندن.",
+ "apihelp-query+allredirects-param-limit": "تعداد آیتم‌ها برای بازگرداندن.",
+ "apihelp-query+backlinks-example-simple": "نمایش پیوندها به <kbd>صفحهٔ اصلی<kbd>",
+ "apihelp-query+blocks-example-simple": "فهرست بسته‌شده‌ها",
+ "apihelp-query+categories-param-show": "کدام نوع رده‌ها نمایش داده‌شود.",
+ "apihelp-query+categories-param-limit": "چه میزان رده بازگردانده شود.",
+ "apihelp-query+categories-param-categories": "فقط این رده‌ها فهرست شود. کاربردی برای بررسی وجود یک صفحهٔ مشخص در یک ردهٔ مشخص.",
+ "apihelp-query+categorymembers-description": "فهرست‌کردن همهٔ صفحه‌ها در یک ردهٔ مشخص‌شده.",
+ "apihelp-query+categorymembers-param-sort": "خصوصیت برای مرتب‌سازی",
+ "apihelp-query+categorymembers-param-dir": "جهت مرتب شدن",
+ "apihelp-query+categorymembers-param-startsortkey": "جایش از $1starthexsortkey استفاده کنید.",
+ "apihelp-query+imageinfo-param-urlheight": "مشابه $1urlwidth.",
+ "apihelp-query+info-description": "دریافت اطلاعات سادهٔ صفحه.",
+ "apihelp-query+iwbacklinks-param-prefix": "پیشوند میان‌ویکی.",
+ "apihelp-query+iwbacklinks-param-title": "پیوند میان‌ویکی برای جستجو. باید همراه <var>$1blprefix</var> استفاده شود.",
+ "apihelp-query+iwbacklinks-param-limit": "تعداد صفحه‌ها برای بازگرداندن.",
+ "apihelp-query+linkshere-param-limit": "تعداد برای بازگرداندن.",
+ "apihelp-query+logevents-description": "دریافت رویدادها از سیاهه‌ها.",
+ "apihelp-query+prefixsearch-param-search": "جستجوی رشته",
+ "apihelp-query+prefixsearch-param-namespace": "فضاهای نامی برای جستجو",
+ "apihelp-query+prefixsearch-param-limit": "حداکثر تعداد نتایج برای بازگرداندن.",
+ "apihelp-query+prefixsearch-param-offset": "تعداد نتایج برای رها کردن.",
+ "apihelp-query+protectedtitles-param-namespace": "فقط عنوان‌ها در این فضاهای نام را فهرست کنید.",
+ "apihelp-query+protectedtitles-param-level": "فقط عنوان‌ها در این سطح‌های حفاظت را فهرست کنید.",
+ "apihelp-query+protectedtitles-param-limit": "تعداد صفحه‌ها برای بازگرداندن.",
+ "apihelp-query+protectedtitles-param-start": "آغاز فهرست‌کردن از این برچسب زمانی حفاظت.",
+ "apihelp-query+protectedtitles-param-end": "متوقف‌کردن فهرست‌کردن در این برچسب زمانی حفاظت.",
+ "apihelp-query+random-param-namespace": "بازگرداندن صفحه‌های فقط در این فضاهای نام.",
+ "apihelp-query+random-param-limit": "محدود کنید چه تعداد صفحه بازگردانده خواهد شد.",
+ "apihelp-query+random-param-redirect": "یک تغییرمسیر تصادفی جای یک صفحه تصادفی بارگیری کنید.",
+ "apihelp-query+random-example-simple": "بازگرداندن تو صفحهٔ تصادفی از فضای نام اصلی",
+ "apihelp-query+random-example-generator": "بازگرداندن اطلاعات صفحه دربارهٔ دو صفحهٔ تصادفی از فضای نام اصلی",
+ "apihelp-query+recentchanges-param-start": "برچسب زمانی برای آغاز شمارش از.",
+ "apihelp-query+recentchanges-param-end": "برچسب زمانی برای پایان شمارش.",
+ "apihelp-query+redirects-param-limit": "تعداد تغییرمسیرها برای بازگرداندن.",
+ "apihelp-upload-param-ignorewarnings": "چشم‌پوشی از همهٔ هشدارها.",
+ "apihelp-userrights-param-user": "نام کاربری.",
+ "api-help-param-deprecated": "توصیه.",
+ "api-credits-header": "اعتبار"
+}
diff --git a/includes/api/i18n/fi.json b/includes/api/i18n/fi.json
new file mode 100644
index 00000000..b1a7e8c4
--- /dev/null
+++ b/includes/api/i18n/fi.json
@@ -0,0 +1,10 @@
+{
+ "@metadata": {
+ "authors": [
+ "Nike",
+ "MrTapsa"
+ ]
+ },
+ "apihelp-query+linkshere-param-show": "Näytä vain kohteet, jotka täyttävät nämä kriteerit:\n;redirect:Näytä vain uudelleenohjaukset.\n;!redirect:Näytä vain ei-uudelleenohjaukset",
+ "apihelp-upload-param-stash": "Mikäli valittu, palvelin säilöö tiedoston väliaikaisesti tallentamisen sijaan."
+}
diff --git a/includes/api/i18n/fr.json b/includes/api/i18n/fr.json
new file mode 100644
index 00000000..114e36c2
--- /dev/null
+++ b/includes/api/i18n/fr.json
@@ -0,0 +1,1054 @@
+{
+ "@metadata": {
+ "authors": [
+ "Gomoko",
+ "Windes",
+ "Orlodrim",
+ "McDutchie",
+ "Element303",
+ "Macofe",
+ "Linedwell",
+ "Nicolapps",
+ "Raulel",
+ "Arkanosis",
+ "Ltrlg"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong> Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un en-tête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet en-tête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+ "apihelp-main-param-action": "Quelle action effectuer.",
+ "apihelp-main-param-format": "Le format de sortie.",
+ "apihelp-main-param-maxlag": "La latence maximale peut être utilisée quand MédiaWiki est installé sur un cluster de base de données répliqué. Pour éviter des actions provoquant un supplément de latence de réplication de site, ce paramètre peut faire attendre le client jusqu’à ce que la latence de réplication soit inférieure à une valeur spécifiée. En cas de latence excessive, le code d’erreur <samp>maxlag</samp> est renvoyé avec un message tel que <samp>Attente de $host : $lag secondes de délai</samp>.<br />Voyez [[mw:Manual:Maxlag_parameter|Manuel: Maxlag parameter]] pour plus d’information.",
+ "apihelp-main-param-smaxage": "Fixer l’entête <code>s-maxage</code> à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.",
+ "apihelp-main-param-maxage": "Fixer l’entête <code>max-age</code> à ce nombre de secondes. Les erreurs ne sont jamais mises en cache.",
+ "apihelp-main-param-assert": "Vérifier si l’utilisateur est connecté si positionné à <kbd>user</kbd>, ou a le droit utilisateur robot si positionné à <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Toute valeur fournie ici sera incluse dans la réponse. Peut être utilisé pour distinguer des demandes.",
+ "apihelp-main-param-servedby": "Inclure le nom d’hôte qui a renvoyé la requête dans les résultats.",
+ "apihelp-main-param-curtimestamp": "Inclure l’horodatage actuel dans le résultat.",
+ "apihelp-main-param-origin": "En accédant à l’API en utilisant une requête AJAX inter-domaines (CORS), mettre le domaine d’origine dans ce paramètre. Il doit être inclus dans toute requête de pre-flight, et doit donc faire partie de l’URI de la requête (pas du corps du POST). Il doit correspondre exactement à une des origines dans l’entête <code>Origin</code> header, donc il doit être fixé avec quelque chose comme <kbd>https://en.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Si ce paramètre ne correspond pas à l’entête <code>Origin</code>, une réponse 403 sera renvoyée. Si ce paramètre correspond à l’entête <code>Origin</code> et que l’origine est en liste blanche, un entête <code>Access-Control-Allow-Origin</code> sera positionné.",
+ "apihelp-main-param-uselang": "Langue à utiliser pour les traductions de message. Une liste de codes peut être analysée depuis <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> avec <kbd>siprop=languages</kbd>, ou en spécifiant <kbd>user</kbd> pour utiliser la préférence de langue de l’utilisateur actuel, ou en spécifiant <kbd>content</kbd> pour utiliser le langage du contenu de ce wiki.",
+ "apihelp-block-description": "Bloquer un utilisateur.",
+ "apihelp-block-param-user": "Nom d’utilisateur, adresse IP ou plage d’adresses IP que vous voulez bloquer.",
+ "apihelp-block-param-expiry": "Durée d’expiration. Peut être relative (par ex. <kbd>5 months</kbd> ou <kbd>2 weeks</kbd>) ou absolue (par ex. <kbd>2014-09-18T12:34:56Z</kbd>). Si elle est mise à <kbd>infinite</kbd>, <kbd>indefinite</kbd> ou <kbd>never</kbd>, le blocage n’expirera jamais.",
+ "apihelp-block-param-reason": "Motif du blocage.",
+ "apihelp-block-param-anononly": "Bloquer uniquement les utilisateurs anonymes (c’est-à-dire désactiver les modifications anonymes pour cette adresse IP).",
+ "apihelp-block-param-nocreate": "Empêcher la création de compte.",
+ "apihelp-block-param-autoblock": "Bloquer automatiquement la dernière adresse IP utilisée, et toute les adresses IP subséquentes depuis lesquelles ils ont essayé de se connecter.",
+ "apihelp-block-param-noemail": "Empêcher l’utilisateur d’envoyer des courriels via le wiki (nécessite le doit <code>blockemail</code>).",
+ "apihelp-block-param-hidename": "Masque le nom de l’utilisateur dans le journal des blocages (nécessite le droit <code>hideuser</code>).",
+ "apihelp-block-param-allowusertalk": "Autoriser les utilisateurs à modifier leur propre page de discussion (dépend de <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Si l’utilisateur est déjà bloqué, écraser le blocage existant.",
+ "apihelp-block-param-watchuser": "Surveiller les pages utilisateur et de discussion de l’utilisateur ou de l’adresse IP.",
+ "apihelp-block-example-ip-simple": "Bloquer l’adresse IP <kbd>192.0.2.5</kbd> pour trois jours avec le motif <kbd>Premier avertissement</kbd>.",
+ "apihelp-block-example-user-complex": "Bloquer indéfiniment l’utilisateur <kbd>Vandale</kbd> avec le motif <kbd>Vandalisme</kbd>, et empêcher la création de nouveau compte et l'envoi de courriel.",
+ "apihelp-checktoken-description": "Vérifier la validité d'un jeton de <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+ "apihelp-checktoken-param-type": "Type de jeton testé",
+ "apihelp-checktoken-param-token": "Jeton à tester.",
+ "apihelp-checktoken-param-maxtokenage": "Temps maximum autorisé pour le jeton, en secondes",
+ "apihelp-checktoken-example-simple": "Tester la validité d'un jeton de <kbd>csrf</kbd>.",
+ "apihelp-clearhasmsg-description": "Efface le drapeau <code>hasmsg</code> pour l’utilisateur courant.",
+ "apihelp-clearhasmsg-example-1": "Effacer le drapeau <code>hasmsg</code> pour l’utilisateur courant",
+ "apihelp-compare-description": "Obtenir la différence entre 2 pages.\n\nVous devez passer un numéro de révision, un titre de page, ou un ID de page, à la fois pour « from » et « to ».",
+ "apihelp-compare-param-fromtitle": "Premier titre à comparer.",
+ "apihelp-compare-param-fromid": "ID de la première page à comparer.",
+ "apihelp-compare-param-fromrev": "Première révision à comparer.",
+ "apihelp-compare-param-totitle": "Second titre à comparer.",
+ "apihelp-compare-param-toid": "ID de la seconde page à comparer.",
+ "apihelp-compare-param-torev": "Seconde révision à comparer.",
+ "apihelp-compare-example-1": "Créer une différence entre les révisions 1 et 2",
+ "apihelp-createaccount-description": "Créer un nouveau compte utilisateur.",
+ "apihelp-createaccount-param-name": "Nom d’utilisateur.",
+ "apihelp-createaccount-param-password": "Mot de passe (ignoré si <var>$1mailpassword</var> est défini).",
+ "apihelp-createaccount-param-domain": "Domaine pour l’authentification externe (facultatif).",
+ "apihelp-createaccount-param-token": "Jeton de création de compte obtenu à la première requête.",
+ "apihelp-createaccount-param-email": "Adresse de courriel de l’utilisateur (facultatif).",
+ "apihelp-createaccount-param-realname": "Vrai nom de l’utilisateur (facultatif).",
+ "apihelp-createaccount-param-mailpassword": "S’il est fixé à une valeur quelconque, un mot de passe aléatoire sera envoyé par courriel à l’utilisateur.",
+ "apihelp-createaccount-param-reason": "Motif facultatif de création du compte à mettre dans les journaux.",
+ "apihelp-createaccount-param-language": "Code de langue à mettre par défaut pour l’utilisateur (facultatif, par défaut langue du contenu).",
+ "apihelp-createaccount-example-pass": "Créer l’utilisateur <kbd>testuser</kbd> avec le mot de passe <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Créer l’utilisateur <kbd>testmailuser</kbd> et envoyer par courriel un mot de passe généré aléatoirement.",
+ "apihelp-delete-description": "Supprimer une page.",
+ "apihelp-delete-param-title": "Titre de la page que vous voulez supprimer. Impossible de l’utiliser avec <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "ID de la page que vous voulez supprimer. Impossible à utiliser avec <var>$1title</var>.",
+ "apihelp-delete-param-reason": "Motif de suppression. Si non défini, un motif généré automatiquement sera utilisé.",
+ "apihelp-delete-param-watch": "Ajouter la page à la liste de suivi de l’utilisateur actuel.",
+ "apihelp-delete-param-watchlist": "Ajouter ou supprimer sans distinction la page de la liste de suivi de l'utilisateur actuel, utiliser les préférences ou ne rien changer au suivi.",
+ "apihelp-delete-param-unwatch": "Supprimer la page de la liste de suivi de l'utilisateur actuel.",
+ "apihelp-delete-param-oldimage": "Le nom de l’ancienne image à supprimer tel que fourni par [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+ "apihelp-delete-example-simple": "Supprimer <kbd>Page principale</kbd>.",
+ "apihelp-delete-example-reason": "Supprimer <kbd>Page principale</kbd> avec le motif <kbd>Préparation au déplacement</kbd>",
+ "apihelp-disabled-description": "Ce module a été désactivé.",
+ "apihelp-edit-description": "Créer et modifier les pages.",
+ "apihelp-edit-param-title": "Titre de la page que vous voulez modifier. Impossible de l’utiliser avec <var>$1pageid</var>.",
+ "apihelp-edit-param-pageid": "ID de la page que vous voulez modifier. Impossible à utiliser avec <var>$1title</var>.",
+ "apihelp-edit-param-section": "Numéro de section. <kbd>0</kbd> pour la section de tête, <kbd>new</kbd> pour une nouvelle section.",
+ "apihelp-edit-param-sectiontitle": "Le titre pour une nouvelle section.",
+ "apihelp-edit-param-text": "Contenu de la page.",
+ "apihelp-edit-param-summary": "Modifier le résumé. Également le titre de la section quand $1section=new et $1sectiontitle n’est pas défini.",
+ "apihelp-edit-param-minor": "Modification mineure.",
+ "apihelp-edit-param-notminor": "Modification non mineure.",
+ "apihelp-edit-param-bot": "Marquer cette modification comme robot.",
+ "apihelp-edit-param-basetimestamp": "Horodatage de la révision de base, utilisé pour détecter les conflits de modification. Peut être obtenu via [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "L'horodatage, lorsque le processus d'édition est démarré, est utilisé pour détecter les conflits de modification. Une valeur appropriée peut être obtenue en utilisant <var>[[Special:ApiHelp/main|curtimestamp]]</var> lors du démarrage du processus d'édition (par ex. en chargeant le contenu de la page à modifier).",
+ "apihelp-edit-param-recreate": "Ignorer toutes les erreurs concernant la page \nqui a été supprimée entre-temps.",
+ "apihelp-edit-param-createonly": "Ne pas modifier la page si elle existe déjà.",
+ "apihelp-edit-param-nocreate": "Lever une erreur si la page n’existe pas.",
+ "apihelp-edit-param-watch": "Ajouter la page à la liste de suivi de l'utilisateur actuel.",
+ "apihelp-edit-param-unwatch": "Supprimer la page de la liste de suivi de l'utilisateur actuel.",
+ "apihelp-edit-param-watchlist": "Ajouter ou supprimer sans condition la page de votre liste de suivi, utiliser les préférences ou ne pas changer le suivi.",
+ "apihelp-edit-param-md5": "Le hachage MD5 du paramètre $1text, ou les paramètres $1prependtext et $1appendtext concaténés. Si défini, la modification ne sera pas effectuée à moins que le hachage ne soit correct.",
+ "apihelp-edit-param-prependtext": "Ajouter ce texte au début de la page. Écrase $1text.",
+ "apihelp-edit-param-appendtext": "Ajouter ce texte à la fin de la page. Écrase $1text.\n\nUtiliser $1section=new pour ajouter une nouvelle section, plutôt que ce paramètre.",
+ "apihelp-edit-param-undo": "Annuler cette révision. Écrase $1text, $1prependtext et $1appendtext.",
+ "apihelp-edit-param-undoafter": "Annuler toutes les révisions depuis $1undo jusqu’à celle-ci. Si non défini, annuler uniquement une révision.",
+ "apihelp-edit-param-redirect": "Résoudre automatiquement les redirections.",
+ "apihelp-edit-param-contentformat": "Format de sérialisation du contenu utilisé pour le texte d’entrée.",
+ "apihelp-edit-param-contentmodel": "Modèle de contenu du nouveau contenu.",
+ "apihelp-edit-param-token": "Le jeton doit toujours être envoyé en tant que dernier paramètre, ou au moins après le paramètre $1text.",
+ "apihelp-edit-example-edit": "Modifier une page",
+ "apihelp-edit-example-prepend": "Préfixer une page par <kbd>_&#95;NOTOC_&#95;</kbd>",
+ "apihelp-edit-example-undo": "Annuler les révisions 13579 à 13585 avec résumé automatique",
+ "apihelp-emailuser-description": "Envoyer un courriel à un utilisateur.",
+ "apihelp-emailuser-param-target": "Utilisateur à qui envoyer le courriel.",
+ "apihelp-emailuser-param-subject": "Entête du sujet.",
+ "apihelp-emailuser-param-text": "Corps du courriel.",
+ "apihelp-emailuser-param-ccme": "M’envoyer une copie de ce courriel.",
+ "apihelp-emailuser-example-email": "Envoyer un courriel à l’utilisateur <kbd>WikiSysop</kbd> avec le texte <kbd>Contenu</kbd>.",
+ "apihelp-expandtemplates-description": "Développe tous les modèles en wikitexte.",
+ "apihelp-expandtemplates-param-title": "Titre de la page.",
+ "apihelp-expandtemplates-param-text": "Wikitexte à convertir.",
+ "apihelp-expandtemplates-param-revid": "ID de révision, pour <nowiki>{{REVISIONID}}</nowiki> et les variables semblables.",
+ "apihelp-expandtemplates-param-prop": "Quelles informations récupérer :\n;wikitext:Le wikitexte développé.\n;categories:Toutes les catégories présentes dans l’entrée qui ne sont pas représentées dans le wikitexte de sortie.\n;properties:Propriétés de page définies en développant les mots magiques dans le wikitexte.\n;volatile:Si la sortie est volatile et ne devrait pas être réutilisée ailleurs dans la page.\n;ttl:Le délai maximal après lequel les caches du résultat devraient être invalidés.\n;parsetree:L’arbre d’analyse XML de l’entrée.\nNoter que si aucune valeur n’est sélectionnée, le résultat contiendra le wikitexte, mais la sortie sera dans un format obsolète.",
+ "apihelp-expandtemplates-param-includecomments": "S’il faut inclure les commentaires HTML dans la sortie.",
+ "apihelp-expandtemplates-param-generatexml": "Générer l’arbre d’analyse XML (remplacé par $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Développe le wikitexte <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+ "apihelp-feedcontributions-description": "Renvoie le fil des contributions d’un utilisateur.",
+ "apihelp-feedcontributions-param-feedformat": "Le format du flux.",
+ "apihelp-feedcontributions-param-user": "Pour quels utilisateurs récupérer les contributions.",
+ "apihelp-feedcontributions-param-namespace": "Par quels espaces de nom filtrer les contributions.",
+ "apihelp-feedcontributions-param-year": "Depuis l’année (et plus récent).",
+ "apihelp-feedcontributions-param-month": "Depuis le mois (et plus récent).",
+ "apihelp-feedcontributions-param-tagfilter": "Filtrer les contributions qui ont ces balises.",
+ "apihelp-feedcontributions-param-deletedonly": "Afficher uniquement les contributions supprimées.",
+ "apihelp-feedcontributions-param-toponly": "Afficher uniquement les modifications qui sont les dernières révisions.",
+ "apihelp-feedcontributions-param-newonly": "Afficher uniquement les modifications qui sont des créations de page.",
+ "apihelp-feedcontributions-param-showsizediff": "Afficher la différence de taille entre les révisions.",
+ "apihelp-feedcontributions-example-simple": "Renvoyer les contributions de l'utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-feedrecentchanges-description": "Renvoie un fil de modifications récentes.",
+ "apihelp-feedrecentchanges-param-feedformat": "Le format du flux.",
+ "apihelp-feedrecentchanges-param-namespace": "Espace de noms auquel limiter les résultats.",
+ "apihelp-feedrecentchanges-param-invert": "Tous les espaces de nom sauf le sélectionné.",
+ "apihelp-feedrecentchanges-param-associated": "Inclure l’espace de noms associé (discussion ou principal).",
+ "apihelp-feedrecentchanges-param-days": "Jours auxquels limiter le résultat.",
+ "apihelp-feedrecentchanges-param-limit": "Nombre maximal de résultats à renvoyer.",
+ "apihelp-feedrecentchanges-param-from": "Afficher les modifications depuis lors.",
+ "apihelp-feedrecentchanges-param-hideminor": "Masquer les modifications mineures.",
+ "apihelp-feedrecentchanges-param-hidebots": "Masquer les modifications faites par des robots.",
+ "apihelp-feedrecentchanges-param-hideanons": "Masquer les modifications faites par des utilisateurs anonymes.",
+ "apihelp-feedrecentchanges-param-hideliu": "Masquer les modifications faites par des utilisateurs enregistrés.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Masquer les modifications contrôlées.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Masquer les modifications faites par l'utilisateur actuel.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtrer par balise.",
+ "apihelp-feedrecentchanges-param-target": "Afficher uniquement les modifications sur les pages liées depuis cette page.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Afficher les modifications plutôt sur les pages liées vers la page sélectionnée.",
+ "apihelp-feedrecentchanges-example-simple": "Afficher les modifications récentes",
+ "apihelp-feedrecentchanges-example-30days": "Afficher les modifications récentes sur 30 jours",
+ "apihelp-feedwatchlist-description": "Renvoie un flux de liste de suivi.",
+ "apihelp-feedwatchlist-param-feedformat": "Le format du flux.",
+ "apihelp-feedwatchlist-param-hours": "Lister les pages modifiées lors de ce nombre d’heures depuis maintenant.",
+ "apihelp-feedwatchlist-param-linktosections": "Lier directement pour modifier les sections si possible.",
+ "apihelp-feedwatchlist-example-default": "Afficher le flux de la liste de suivi",
+ "apihelp-feedwatchlist-example-all6hrs": "Afficher toutes les modifications sur les pages suivies dans les dernières 6 heures",
+ "apihelp-filerevert-description": "Rétablir un fichier dans une ancienne version.",
+ "apihelp-filerevert-param-filename": "Nom de fichier cible, sans le préfixe File:.",
+ "apihelp-filerevert-param-comment": "Télécharger le commentaire.",
+ "apihelp-filerevert-param-archivename": "Nom d’archive de la révision à rétablir.",
+ "apihelp-filerevert-example-revert": "Rétablir <kbd>Wiki.png</kbd> dans la version du <kbd>2011-03-05T15:27:40Z</kbd>",
+ "apihelp-help-description": "Afficher l’aide pour les modules spécifiés.",
+ "apihelp-help-param-modules": "Modules pour lesquels afficher l’aide (valeurs des paramètres <var>action</var> et <var>format</var>, ou <kbd>main</kbd>). Les sous-modules peuvent être spécifiés avec un <kbd>+</kbd>.",
+ "apihelp-help-param-submodules": "Inclure l’aide pour les sous-modules du module nommé.",
+ "apihelp-help-param-recursivesubmodules": "Inclure l’aide pour les sous-modules de façon récursive.",
+ "apihelp-help-param-helpformat": "Format de sortie de l’aide.",
+ "apihelp-help-param-wrap": "Inclut la sortie dans une structure de réponse API standard.",
+ "apihelp-help-param-toc": "Inclure une table des matières dans la sortir HTML.",
+ "apihelp-help-example-main": "Aide pour le module principal",
+ "apihelp-help-example-recursive": "Toute l’aide sur une page",
+ "apihelp-help-example-help": "Aide pour le module d’aide lui-même",
+ "apihelp-help-example-query": "Aide pour deux sous-modules de recherche",
+ "apihelp-imagerotate-description": "Faire pivoter une ou plusieurs images.",
+ "apihelp-imagerotate-param-rotation": "Degrés de rotation de l’image dans le sens des aiguilles d’une montre.",
+ "apihelp-imagerotate-example-simple": "Faire pivoter <kbd>File:Example.png</kbd> de <kbd>90</kbd> degrés.",
+ "apihelp-imagerotate-example-generator": "Faire pivoter toutes les images de <kbd>Category:Flip</kbd> de <kbd>180</kbd> degrés.",
+ "apihelp-import-description": "Importer une page depuis un autre wiki, ou un fichier XML.\n\nNoter que le POST HTTP doit être effectué comme un import de fichier (c’est-à-dire en utilisant multipart/form-data) lors de l’envoi d’un fichier pour le paramètre <var>xml</var>.",
+ "apihelp-import-param-summary": "Importer le résumé.",
+ "apihelp-import-param-xml": "Fichier XML téléchargé.",
+ "apihelp-import-param-interwikisource": "Pour les importations interwiki : wiki depuis lequel importer.",
+ "apihelp-import-param-interwikipage": "Pour les importations interwiki : page à importer.",
+ "apihelp-import-param-fullhistory": "Pour les importations interwiki : importer tout l’historique, et pas seulement la version courante.",
+ "apihelp-import-param-templates": "Pour les importations interwiki : importer aussi tous les modèles inclus.",
+ "apihelp-import-param-namespace": "Pour les importations interwiki : importer vers cet espace de noms.",
+ "apihelp-import-param-rootpage": "Importer comme une sous-page de cette page.",
+ "apihelp-import-example-import": "Importer [[meta:Help:Parserfunctions]] vers l’espace de noms 100 avec tout l’historique.",
+ "apihelp-login-description": "Se connecter et obtenir les cookies d’authentification.\n\nDans le cas d’une connexion réussie, les cookies nécessaires seront inclus dans les entêtes de la réponse HTTP. Dans le cas d’une connexion en échec, les essais ultérieurs pourront être réduits afin de limiter les attaques automatisées de découverte du mot de passe.",
+ "apihelp-login-param-name": "Nom d’utilisateur.",
+ "apihelp-login-param-password": "Mot de passe.",
+ "apihelp-login-param-domain": "Domaine (facultatif).",
+ "apihelp-login-param-token": "Jeton de connexion obtenu à la première requête.",
+ "apihelp-login-example-gettoken": "Récupérer un jeton de connexion",
+ "apihelp-login-example-login": "Se connecter",
+ "apihelp-logout-description": "Se déconnecter et effacer les données de session.",
+ "apihelp-logout-example-logout": "Déconnecter l’utilisateur actuel.",
+ "apihelp-managetags-description": "Effectuer des tâches de gestion relatives à la modification des balises.",
+ "apihelp-managetags-param-operation": "Quelle opération effectuer :\n;create:Créer une nouvelle balise de modification pour un usage manuel.\n;delete:Supprimer une balise de modification de la base de données, y compris la suppression de la marque de toutes les révisions, entrées de modification récente et entrées de journal dans lesquelles elle serait utilisée.\n;activate:Activer une balise de modification, permettant aux utilisateurs de l’appliquer manuellement.\n;deactivate:Désactiver une balise de modification, empêchant les utilisateurs de l’appliquer manuellement.",
+ "apihelp-managetags-param-tag": "Balise à créer, supprimer, activer ou désactiver. Pour la création de balise, elle ne doit pas exister. Pour la suppression de balise, elle doit exister. Pour l’activation de balise, elle doit exister et ne pas être utilisée par une extension. Pour la désactivation de balise, elle doit être actuellement active et définie manuellement.",
+ "apihelp-managetags-param-reason": "Un motif facultatif pour créer, supprimer, activer ou désactiver la balise.",
+ "apihelp-managetags-param-ignorewarnings": "S’il faut ignorer tout avertissement qui se produirait au cours de l’opération.",
+ "apihelp-managetags-example-create": "Créer une balise nommée <kbd>pourriel</kbd> avec le motif <kbd>À utiliser lors de la revue des modifications</kbd>",
+ "apihelp-managetags-example-delete": "Supprimer la balise <kbd>vandlaisme</kbd> avec le motif <kbd>Mal épelé</kbd>",
+ "apihelp-managetags-example-activate": "Activer une balise nommée <kbd>pourriel</kbd> avec le motif <kbd>À utiliser dans la revue des modifications</kbd>",
+ "apihelp-managetags-example-deactivate": "Désactiver une balise nommée <kbd>pourriel</kbd> avec le motif <kbd>Plus nécessaire</kbd>",
+ "apihelp-move-description": "Déplacer une page.",
+ "apihelp-move-param-from": "Titre de la page à renommer. Impossible de l’utiliser avec <var>$1fromid</var>.",
+ "apihelp-move-param-fromid": "ID de la page à renommer. Impossible à utiliser avec <var>$1from</var>.",
+ "apihelp-move-param-to": "Titre de la page renommée.",
+ "apihelp-move-param-reason": "Motif du renommage.",
+ "apihelp-move-param-movetalk": "Renommer la page de discussion, si elle existe.",
+ "apihelp-move-param-movesubpages": "Renommer les sous-pages, le cas échéant.",
+ "apihelp-move-param-noredirect": "Ne pas créer une redirection.",
+ "apihelp-move-param-watch": "Ajouter une page et la redirection à liste de suivi de l'utilisateur actuel.",
+ "apihelp-move-param-unwatch": "Supprimer la page et la redirection de la liste de suivi de l'utilisateur actuel.",
+ "apihelp-move-param-watchlist": "Ajouter ou supprimer sans condition la page de la liste de suivi de l'utilisateur actuel, utiliser les préférences ou ne pas changer le suivi.",
+ "apihelp-move-param-ignorewarnings": "Ignorer tous les avertissements.",
+ "apihelp-move-example-move": "Déplacer <kbd>Mauvais titre</kbd> en <kbd>Bon titre</kbd> sans garder de redirection.",
+ "apihelp-opensearch-description": "Rechercher dans le wiki en utilisant le protocole OpenSearch.",
+ "apihelp-opensearch-param-search": "Chaîne de recherche.",
+ "apihelp-opensearch-param-limit": "Nombre maximal de résultats à renvoyer.",
+ "apihelp-opensearch-param-namespace": "Espaces de nom à rechercher.",
+ "apihelp-opensearch-param-suggest": "Ne rien faire si <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> vaut faux.",
+ "apihelp-opensearch-param-redirects": "Comment gérer les redirections :\n;return:Renvoie la redirection elle-même.\n;resolve:Renvoie la page cible. Peut renvoyer moins de $1limit résultats.\nPour des raisons historiques, la valeur par défaut est « return » pour $1format=json et « resolve » pour les autres formats.",
+ "apihelp-opensearch-param-format": "Le format de sortie.",
+ "apihelp-opensearch-example-te": "Trouver les pages commençant par <kbd>Te</kbd>.",
+ "apihelp-options-description": "Modifier les préférences de l’utilisateur courant.\n\nSeules les options enregistrées dans le cœur ou dans l’une des extensions installées, ou les options avec une clé préfixée par « userjs- » (devant être utilisées dans les scripts utilisateur), peuvent être définies.",
+ "apihelp-options-param-reset": "Réinitialise les préférences aux valeurs par défaut du site.",
+ "apihelp-options-param-resetkinds": "Liste des types d’option à réinitialiser quand l’option <var>$1reset</var> est définie.",
+ "apihelp-options-param-change": "Liste des modifications, au format nom=valeur (par ex. skin=vector). La valeur ne peut pas contenir de caractère barre verticale. Si aucune valeur n’est fournie (pas même un signe égal), par ex., nomoption|autreoption|…, l’option sera réinitialisée à sa valeur par défaut.",
+ "apihelp-options-param-optionname": "Un nom d’option qui doit être fixé à la valeur fournie par <var>$1optionvalue</var>.",
+ "apihelp-options-param-optionvalue": "La valeur d’une option spécifiée par <var>$1optionname</var> peut contenir des caractères barre verticale.",
+ "apihelp-options-example-reset": "Réinitialiser toutes les préférences",
+ "apihelp-options-example-change": "Modifier les préférences <kbd>skin</kbd> et <kbd>hideminor</kbd>.",
+ "apihelp-options-example-complex": "Réinitialiser toutes les préférences, puis définir <kbd>skin</kbd> et <kbd>nickname</kbd>.",
+ "apihelp-paraminfo-description": "Obtenir des informations sur les modules de l’API.",
+ "apihelp-paraminfo-param-modules": "Liste des noms de module (valeurs des paramètres <var>action</var> et <var>format</var>, ou <kbd>main</kbd>). Peut spécifier des sous-modules avec un <kbd>+</kbd>.",
+ "apihelp-paraminfo-param-helpformat": "Format des chaînes d’aide.",
+ "apihelp-paraminfo-param-querymodules": "Liste des noms de module de requêtage (valeur des paramètres <var>prop</var>, <var>meta</var> ou <var>list</var>=). Utiliser <kbd>$1modules=query+foo</kbd> au lieu de <kbd>$1querymodules=foo</kbd>.",
+ "apihelp-paraminfo-param-mainmodule": "Obtenir aussi des informations sur le module principal (niveau supérieur). Utiliser plutôt <kbd>$1modules=main</kbd>.",
+ "apihelp-paraminfo-param-pagesetmodule": "Obtenir aussi des informations sur le module pageset (en fournissant titles= et ses amis).",
+ "apihelp-paraminfo-param-formatmodules": "Liste des noms de module de mise en forme (valeur du paramètre <var>format</var>). Utiliser plutôt <var>$1modules</var>.",
+ "apihelp-paraminfo-example-1": "Afficher les informations pour <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd> et <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+ "apihelp-parse-description": "Analyse le contenu et renvoie le résultat de l’analyseur.\n\nVoyez les différents modules prop de <kbd>[[Special:ApiHelp/query|action=query]]</kbd> pour avoir de l’information sur la version actuelle d’une page.\n\nIl y a plusieurs moyens de spécifier le texte à analyser :\n# Spécifier une page ou une révision, en utilisant <var>$1page</var>, <var>$1pageid</var> ou <var>$1oldid</var>.\n# Spécifier explicitement un contenu, en utilisant <var>$1text</var>, <var>$1title</var> et <var>$1contentmodel</var>\n# Spécifier uniquement un résumé à analyser. <var>$1prop</var> doit recevoir une valeur vide.",
+ "apihelp-parse-param-title": "Titre de la page à laquelle appartient le texte. Si omis, <var>$1contentmodel</var> doit être spécifié, et [[API]] sera utilisé comme titre.",
+ "apihelp-parse-param-text": "Texte à analyser. utiliser <var>$1title</var> ou <var>$1contentmodel</var> pour contrôler le modèle de contenu.",
+ "apihelp-parse-param-summary": "Résumé à analyser.",
+ "apihelp-parse-param-page": "Analyser le contenu de cette page. Impossible à utiliser avec <var>$1text</var> et <var>$1title</var>.",
+ "apihelp-parse-param-pageid": "Analyser le contenu de cette page. Écrase <var>$1page</var>.",
+ "apihelp-parse-param-redirects": "Si le paramètre <var>$1page</var> ou <var>$1pageid</var> est positionné sur une redirection, la résoudre.",
+ "apihelp-parse-param-oldid": "Analyser le contenu de cette révision. Écrase <var>$1page</var> et <var>$1pageid</var>.",
+ "apihelp-parse-param-prop": "Quelles informations obtenir :\n;text:Fournit le texte analysé du wikitexte.\n;langlinks:Fournit les liens de langue dans le wikitexte analysé.\n;categories:Fournit les catégories dans le wikitexte analysé.\n;categorieshtml:Fournit la version HTML des catégories.\n;links:Fournit les liens internes dans le wikitexte analysé.\n;templates:Fournit les modèles dans le wikitexte analysé.\n;images:Fournit les images dans le wikitexte analysé.\n;externallinks:Fournit les liens externes dans le wikitexte analysé.\n;sections:Fournit les sections dans le wikitexte analysé.\n;revid:Ajoute l’ID de révision de la page analysée.\n;displaytitle:Ajoute le titre du wikitexte analysé.\n;headitems:Fournit les éléments à mettre dans le &lt;head&gt; de la page.\n;headhtml:Fournit le &lt;head&gt; analysé de la page.\n;modules:Fournit les modules ResourceLoader utilisés sur la page.\n;indicators:Fournit le HTML des indicateurs d’état de la page utilisés dans la page.\n;iwlinks:Fournit les liens interwiki dans le wikitexte analysé.\n;wikitext:Fournit le wikitexte d’origine qui a été analysé.\n;properties:Fournit différentes propriétés définies dans le wikitexte analysé.\n;limitreportdata:Fournit le rapport de limite de façon structurée. Ne fournit aucune donnée, quand $1disablepp est activé.\n;limitreporthtml:Fournit la version HTML du rapport de limite. Ne fournit aucune donnée, quand $1disablepp est activé.",
+ "apihelp-parse-param-pst": "Faire une transformation avant enregistrement de l’entrée avant de l’analyser. Valide uniquement quand utilisé avec du texte.",
+ "apihelp-parse-param-onlypst": "Faire une transformation avant enregistrement (PST) de l’entrée, mais ne pas l’analyser. Renvoie le même wikitexte, après que la PST a été appliquée. Valide uniquement quand utilisé avec <var>$1text</var>.",
+ "apihelp-parse-param-effectivelanglinks": "Inclut les liens de langue fournis par les extensions (à utiliser avec <kbd>$1prop=langlinks</kbd>).",
+ "apihelp-parse-param-section": "Récupérer uniquement le contenu de ce numéro de section ou quand <kbd>nouveau</kbd> génère une nouvelle section.\n\nLa <kbd>nouvelle</kbd> section est mise à l’honneur uniquement quand <var>text</var> est spécifié.",
+ "apihelp-parse-param-sectiontitle": "Nouveau titre de section quand <var>section</var> vaut <kbd>nouveau</kbd>.\n\nÀ la différence de la modification de page, cela ne revient pas à <var>summary</var> quand il est omis ou vide.",
+ "apihelp-parse-param-disablepp": "Désactiver le rapport PP de la sortie de l’analyseur.",
+ "apihelp-parse-param-disableeditsection": "Désactiver les liens de modification de section de la sortie de l’analyseur.",
+ "apihelp-parse-param-generatexml": "Générer un arbre d’analyse XML (nécessite le modèle de contenu <code>$1</code>).",
+ "apihelp-parse-param-preview": "Analyser en mode aperçu.",
+ "apihelp-parse-param-sectionpreview": "Analyser en mode aperçu de section (active aussi le mode aperçu).",
+ "apihelp-parse-param-disabletoc": "Désactiver la table des matières dans la sortie.",
+ "apihelp-parse-param-contentformat": "Format de sérialisation du contenu utilisé pour le texte d’entrée. Valide uniquement si utilisé avec $1text.",
+ "apihelp-parse-param-contentmodel": "Modèle de contenu du texte d’entrée. Si omis, $1title doit être spécifié, et la valeur par défaut sera le modèle du titre spécifié. Valide uniquement quand utilisé avec $1text.",
+ "apihelp-parse-example-page": "Analyser une page.",
+ "apihelp-parse-example-text": "Analyser le wikitexte.",
+ "apihelp-parse-example-texttitle": "Analyser du wikitexte, en spécifiant le titre de la page.",
+ "apihelp-parse-example-summary": "Analyser un résumé.",
+ "apihelp-patrol-description": "Patrouiller une page ou une révision.",
+ "apihelp-patrol-param-rcid": "ID de modification récente à patrouiller.",
+ "apihelp-patrol-param-revid": "ID de révision à patrouiller.",
+ "apihelp-patrol-example-rcid": "Patrouiller une modification récente",
+ "apihelp-patrol-example-revid": "Patrouiller une révision",
+ "apihelp-protect-description": "Modifier le niveau de protection d’une page.",
+ "apihelp-protect-param-title": "Titre de la page à (dé)protéger. Impossible à utiliser avec $1pageid.",
+ "apihelp-protect-param-pageid": "ID de la page à (dé)protéger. Impossible à utiliser avec $1title.",
+ "apihelp-protect-param-protections": "Liste des niveaux de protection, au format <kbd>action=niveau</kbd> (par ex. <kbd>edit=sysop</kbd>).\n\n<strong>NOTE :<strong> Toutes les actions non listées auront leur restrictions supprimées.",
+ "apihelp-protect-param-expiry": "Horodatages d’expiration. Si un seul horodatage est fourni, il sera utilisé pour toutes les protections. Utiliser <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd> ou <kbd>never</kbd> pour une protection sans expiration.",
+ "apihelp-protect-param-reason": "Motif de (dé)protection.",
+ "apihelp-protect-param-cascade": "Activer la protection en cascade (c’est-à-dire protéger les pages incluses dans cette page). Ignoré si tous les niveaux de protection fournis ne supportent pas la mise en cascade.",
+ "apihelp-protect-param-watch": "Si activé, ajouter la page (dé)protégée à la liste de suivi de l'utilisateur actuel.",
+ "apihelp-protect-param-watchlist": "Ajouter ou supprimer sans condition la page de la liste de suivi de l'utilisateur actuel, utiliser les préférences ou ne pas modifier le suivi.",
+ "apihelp-protect-example-protect": "Protéger une page",
+ "apihelp-protect-example-unprotect": "Enlever la protection d’une page en mettant les restrictions à <kbd>all</kbd>.",
+ "apihelp-protect-example-unprotect2": "Enlever la protection de la page en ne mettant aucune restriction",
+ "apihelp-purge-description": "Vider le cache des titres fournis.\n\nNécessite une requête POST si l’utilisateur n’est pas connecté.",
+ "apihelp-purge-param-forcelinkupdate": "Mettre à jour les tables de liens.",
+ "apihelp-purge-param-forcerecursivelinkupdate": "Mettre à jour la table des liens, et mettre à jour les tables de liens pour toute page qui utilise cette page comme modèle",
+ "apihelp-purge-example-simple": "Purger les pages <kbd>Page principale</kbd> et <kbd>API</kbd>.",
+ "apihelp-purge-example-generator": "Purger les 10 premières pages de l’espace de noms principal",
+ "apihelp-query-description": "Extraire des données de et sur MédiaWiki.\n\nToutes les modifications de données devront d’abord utiliser une requête pour obtenir un jeton, afin d’éviter les abus de la part de sites malveillants.",
+ "apihelp-query-param-prop": "Quelles propriétés obtenir des pages demandées.",
+ "apihelp-query-param-list": "Quelles listes obtenir.",
+ "apihelp-query-param-meta": "Quelles métadonnées obtenir.",
+ "apihelp-query-param-indexpageids": "Inclure une section pageids supplémentaire listant tous les IDs de page renvoyés.",
+ "apihelp-query-param-export": "Exporter les révisions actuelles de toutes les pages fournies ou générées.",
+ "apihelp-query-param-exportnowrap": "Renvoyer le XML exporté sans l’inclure dans un résultat XML (même format que [[Special:Export]]). Utilisable uniquement avec $1export.",
+ "apihelp-query-param-iwurl": "S’il faut obtenir l’URL complète si le titre est un lien interwiki.",
+ "apihelp-query-param-continue": "Quand il est présent, met en forme query-continue sous forme de paires clé-valeur qui devrait simplement être fusionné dans la requête d’origine. Ce paramètre doit être fixé à une chaîne vide dans la requête initiale.\n\nCe paramètre est recommandé pour tout nouveau développement, et sera mis par défaut dans la prochaine version de l’API.",
+ "apihelp-query-param-rawcontinue": "Actuellement ignoré. Plus tard, <var>$1continue</var> deviendra la valeur par défaut et sera nécessaire pour recevoir les données brutes de <samp>query-continue</samp>.",
+ "apihelp-query-example-revisions": "Récupérer [[Special:ApiHelp/query+siteinfo|l’info du site]] et [[Special:ApiHelp/query+revisions|les révisions]] de <kbd>Page principale</kbd>.",
+ "apihelp-query-example-allpages": "Récupérer les révisions des pages commençant par <kbd>API/</kbd>.",
+ "apihelp-query+allcategories-description": "Énumérer toutes les catégories.",
+ "apihelp-query+allcategories-param-from": "La catégorie depuis laquelle démarrer l’énumération.",
+ "apihelp-query+allcategories-param-to": "La catégorie à laquelle terminer l’énumération.",
+ "apihelp-query+allcategories-param-prefix": "Rechercher tous les titres de catégorie qui commencent avec cette valeur.",
+ "apihelp-query+allcategories-param-dir": "Direction dans laquelle trier.",
+ "apihelp-query+allcategories-param-min": "Renvoyer uniquement les catégories avec au moins ce nombre de membres.",
+ "apihelp-query+allcategories-param-max": "Renvoyer uniquement les catégories avec au plus ce nombre de membres.",
+ "apihelp-query+allcategories-param-limit": "Combien de catégories renvoyer.",
+ "apihelp-query+allcategories-param-prop": "Quelles propriétés récupérer :\n;size:Ajoute le nombre de pages dans la catégorie.\n;hidden:Marque les catégories qui sont cachées avec _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+allcategories-example-size": "Lister les catégories avec l’information sur le nombre de pages dans chacune",
+ "apihelp-query+allcategories-example-generator": "Récupérer l’information sur la page de catégorie elle-même pour les catégories commençant par <kbd>List</kbd>.",
+ "apihelp-query+alldeletedrevisions-description": "Lister toutes les révisions supprimées par un utilisateur ou dans un espace de noms.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Utilisable uniquement avec <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Impossible à utiliser avec <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+alldeletedrevisions-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+alldeletedrevisions-param-from": "Démarrer la liste à ce titre.",
+ "apihelp-query+alldeletedrevisions-param-to": "Arrêter la liste à ce titre.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Rechercher tous les titres de page commençant par cette valeur.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Lister uniquement les révisions marquées avec cette balise.",
+ "apihelp-query+alldeletedrevisions-param-user": "Lister uniquement les révisions par cet utilisateur.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Ne pas lister les révisions par cet utilisateur.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Lister uniquement les pages dans cet espace de noms.",
+ "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>REMARQUE :</strong> Du fait du [[mw:Manual:$wgMiserMode|mode minimal]], utiliser <var>$1user</var> et <var>$1namespace</var> ensemble peut aboutir à moins de résultats renvoyés que <var>$1limit</var> avant de continuer ; dans les cas extrêmes, zéro résultats peuvent être renvoyés.",
+ "apihelp-query+alldeletedrevisions-param-generatetitles": "Utilisé comme générateur, générer des titres plutôt que des IDs de révision.",
+ "apihelp-query+alldeletedrevisions-example-user": "Lister les 50 dernières contributions supprimées par l'utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Lister les 50 premières révisions supprimées dans l’espace de noms principal.",
+ "apihelp-query+allfileusages-description": "Lister toutes les utilisations de fichier, y compris ceux n’existant pas.",
+ "apihelp-query+allfileusages-param-from": "Le titre du fichier depuis lequel commencer l’énumération.",
+ "apihelp-query+allfileusages-param-to": "Le titre du fichier auquel arrêter l’énumération.",
+ "apihelp-query+allfileusages-param-prefix": "Rechercher tous les fichiers dont le titre commence par cette valeur.",
+ "apihelp-query+allfileusages-param-unique": "Afficher uniquement les titres de fichier distincts. Impossible à utiliser avec $1prop=ids.\nQuand utilisé comme générateur, produit les pages cibles au lieu des sources.",
+ "apihelp-query+allfileusages-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page utilisatrice (impossible à utiliser avec $1unique).\n;title:Ajoute le titre du fichier.",
+ "apihelp-query+allfileusages-param-limit": "Combien d’éléments renvoyer au total.",
+ "apihelp-query+allfileusages-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+allfileusages-example-B": "Lister les titres de fichier, y compris les manquants, avec les IDs de page d’où ils proviennent, en commençant à <kbd>B</kbd>.",
+ "apihelp-query+allfileusages-example-unique": "Lister les titres de fichier uniques",
+ "apihelp-query+allfileusages-example-unique-generator": "Obtient tous les titres de fichier, en marquant les manquants",
+ "apihelp-query+allfileusages-example-generator": "Obtient les pages contenant les fichiers",
+ "apihelp-query+allimages-description": "Énumérer toutes les images séquentiellement.",
+ "apihelp-query+allimages-param-sort": "Propriété par laquelle trier.",
+ "apihelp-query+allimages-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+allimages-param-from": "Le titre de l’image depuis laquelle démarrer l’énumération. Ne peut être utilisé qu’avec $1sort=name.",
+ "apihelp-query+allimages-param-to": "Le titre de l’image auquel arrêter l’énumération. Ne peut être utilisé qu’avec $1sort=name.",
+ "apihelp-query+allimages-param-start": "L’horodatage depuis lequel énumérer. Ne peut être utilisé qu’avec $1sort=timestamp.",
+ "apihelp-query+allimages-param-end": "L’horodatage de fin de l’énumération. Ne peut être utilisé qu’avec $1sort=timestamp.",
+ "apihelp-query+allimages-param-prefix": "Rechercher toutes les images dont le titre commence par cette valeur. Utilisable uniquement avec $1sort=name.",
+ "apihelp-query+allimages-param-minsize": "Restreindre aux images avec au moins ce nombre d’octets.",
+ "apihelp-query+allimages-param-maxsize": "Restreindre aux images avec au plus ce nombre d’octets.",
+ "apihelp-query+allimages-param-sha1": "Hachage SHA1 de l’image. Écrase $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "Hachage SHA1 de l’image en base 36 (utilisé dans MédiaWiki).",
+ "apihelp-query+allimages-param-user": "Renvoyer seulement les fichiers téléchargés par cet utilisateur. Utilisable uniquement avec $1sort=timestamp. Impossible à utiliser avec $1filterbots.",
+ "apihelp-query+allimages-param-filterbots": "Comment filtrer les fichiers téléchargés par des robots. Peut être utilisé uniquement avec $1sort=timestamp. Impossible à utiliser avec $1user.",
+ "apihelp-query+allimages-param-mime": "Quels types MIME rechercher, par ex. <kbd>image/jpeg</kbd>.",
+ "apihelp-query+allimages-param-limit": "Combien d’images renvoyer au total.",
+ "apihelp-query+allimages-example-B": "Afficher une liste des fichiers commençant par la lettre <kbd>B</kbd>.",
+ "apihelp-query+allimages-example-recent": "Afficher une liste des fichiers récemment téléchargés semblable à [[Special:NewFiles]]",
+ "apihelp-query+allimages-example-mimetypes": "Afficher une liste de fichiers avec le type MIME <kbd>image/png</kbd> ou <kbd>image/gif</kbd>",
+ "apihelp-query+allimages-example-generator": "Afficher l’information sur 4 fichiers commençant par la lettre <kbd>T</kbd>.",
+ "apihelp-query+alllinks-description": "Énumérer tous les liens pointant vers un espace de noms donné.",
+ "apihelp-query+alllinks-param-from": "Le titre du lien auquel démarrer l’énumération.",
+ "apihelp-query+alllinks-param-to": "Le titre du lien auquel arrêter l’énumération.",
+ "apihelp-query+alllinks-param-prefix": "Rechercher tous les titres liés commençant par cette valeur.",
+ "apihelp-query+alllinks-param-unique": "Afficher uniquement les titres liés distincts. Impossible à utiliser avec <kbd>$1prop=ids</kbd>.\nUtilisé avec un générateur, produit les pages cible au lieu des pages source.",
+ "apihelp-query+alllinks-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page de liaison (impossible à utiliser avec <var>$1unique</var>).\n;title:Ajoute le titre du lien.",
+ "apihelp-query+alllinks-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+alllinks-param-limit": "Combien d’éléments renvoyer au total.",
+ "apihelp-query+alllinks-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+alllinks-example-B": "Lister les titres liés, y compris les manquants, avec les IDs des pages d’où ils proviennent, en démarrant à <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-unique": "Lister les titres liés uniques",
+ "apihelp-query+alllinks-example-unique-generator": "Obtient tous les titres liés, en marquant les manquants",
+ "apihelp-query+alllinks-example-generator": "Obtient les pages contenant les liens",
+ "apihelp-query+allmessages-description": "Renvoyer les messages depuis ce site.",
+ "apihelp-query+allmessages-param-messages": "Quels messages sortir. <kbd>*</kbd> (par défaut) signifie tous les messages.",
+ "apihelp-query+allmessages-param-prop": "Quelles propriétés obtenir.",
+ "apihelp-query+allmessages-param-enableparser": "Si positionné pour activer l’analyseur, traitera en avance le wikitexte du message (substitution des mots magiques, gestion des modèles, etc.).",
+ "apihelp-query+allmessages-param-nocontent": "Si positionné, ne pas inclure le contenu des messages dans la sortie.",
+ "apihelp-query+allmessages-param-includelocal": "Inclure aussi les messages locaux, c’est-à-dire les messages qui n’existent pas dans le logiciel mais sous forme d’une page MediaWiki:.\nCela liste toutes les pages MediaWiki:, donc aussi celles qui ne sont pas vraiment des messages, telles que [[MediaWiki:Common.js|Common.js]].",
+ "apihelp-query+allmessages-param-args": "Arguments à substituer dans le message.",
+ "apihelp-query+allmessages-param-filter": "Renvoyer uniquement les messages avec des noms contenant cette chaîne.",
+ "apihelp-query+allmessages-param-customised": "Renvoyer uniquement les messages dans cet état de personnalisation.",
+ "apihelp-query+allmessages-param-lang": "Renvoyer les messages dans cette langue.",
+ "apihelp-query+allmessages-param-from": "Renvoyer les messages commençant à ce message.",
+ "apihelp-query+allmessages-param-to": "Renvoyer les messages en terminant à ce message.",
+ "apihelp-query+allmessages-param-title": "Nom de page à utiliser comme contexte en analysant le message (pour l’option $1enableparser).",
+ "apihelp-query+allmessages-param-prefix": "Renvoyer les messages avec ce préfixe.",
+ "apihelp-query+allmessages-example-ipb": "Afficher les messages commençant par <kbd>ipb-</kbd>.",
+ "apihelp-query+allmessages-example-de": "Afficher les messages <kbd>august</kbd> et <kbd>mainpage</kbd> en allemand.",
+ "apihelp-query+allpages-description": "Énumérer toutes les pages séquentiellement dans un espace de noms donné.",
+ "apihelp-query+allpages-param-from": "Le titre de la page depuis lequel commencer l’énumération.",
+ "apihelp-query+allpages-param-to": "Le titre de la page auquel stopper l’énumération.",
+ "apihelp-query+allpages-param-prefix": "Rechercher tous les titres de page qui commencent par cette valeur.",
+ "apihelp-query+allpages-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+allpages-param-filterredir": "Quelles pages lister.",
+ "apihelp-query+allpages-param-minsize": "Limiter aux pages avec au moins ce nombre d’octets.",
+ "apihelp-query+allpages-param-maxsize": "Limiter aux pages avec au plus ce nombre d’octets.",
+ "apihelp-query+allpages-param-prtype": "Limiter aux pages protégées uniquement.",
+ "apihelp-query+allpages-param-prlevel": "Filtrer les protections basées sur le niveau de protection (doit être utilisé avec le paramètre $1prtype=).",
+ "apihelp-query+allpages-param-prfiltercascade": "Filtrer les protections d’après leur cascade (ignoré si $1prtype n’est pas positionné).",
+ "apihelp-query+allpages-param-limit": "Combien de pages renvoyer au total.",
+ "apihelp-query+allpages-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+allpages-param-filterlanglinks": "Filtrer si une page a des liens de langue. Noter que cela ne prend pas en compte les liens de langue ajoutés par des extensions.",
+ "apihelp-query+allpages-param-prexpiry": "Quelle expiration de protection sur laquelle filtrer la page :\n;indefinite:N’obtenir que les pages avec une expiration de protection infinie.\n;definite:N’obtenir que les pages avec une expiration de protection définie (spécifique).\n;all:Obtenir toutes les pages avec une expiration de protection.",
+ "apihelp-query+allpages-example-B": "Afficher une liste des pages commençant par la lettre <kbd>B</kbd>.",
+ "apihelp-query+allpages-example-generator": "Afficher l’information sur 4 pages commençant par la lettre <kbd>T</kbd>.",
+ "apihelp-query+allpages-example-generator-revisions": "Afficher le contenu des 2 premières pages hors redirections commençant par <kbd>Re</kbd>.",
+ "apihelp-query+allredirects-description": "Lister toutes les redirections vers un espace de noms.",
+ "apihelp-query+allredirects-param-from": "Le titre de la redirection auquel démarrer l’énumération.",
+ "apihelp-query+allredirects-param-to": "Le titre de la redirection auquel arrêter l’énumération.",
+ "apihelp-query+allredirects-param-prefix": "Rechercher toutes les pages cible commençant par cette valeur.",
+ "apihelp-query+allredirects-param-unique": "Afficher uniquement les pages cibles distinctes. Impossible à utiliser avec $1prop=ids|fragment|interwiki.\nUtilisé avec un générateur, produit les pages cible au lieu des pages source.",
+ "apihelp-query+allredirects-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page de redirection (impossible à utiliser avec <var>$1unique</var>).\n;title:Ajoute le titre de la redirection.\n;fragment:Ajoute le fragment de la redirection, s’il y en a un (impossible à utiliser avec <var>$1unique</var>).\n;interwiki:Ajoute le préfixe interwiki de la redirection, s’il y en a un (impossible à utiliser avec <var>$1unique</var>).",
+ "apihelp-query+allredirects-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+allredirects-param-limit": "Combien d’éléments renvoyer au total.",
+ "apihelp-query+allredirects-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+allredirects-example-B": "Lister les pages cible, y compris les manquantes, avec les IDs de page d’où ils proviennent, en commençant à <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-unique": "Lister les pages cible unique",
+ "apihelp-query+allredirects-example-unique-generator": "Obtient toutes les pages cible, en marquant les manquantes",
+ "apihelp-query+allredirects-example-generator": "Obtient les pages contenant les redirections",
+ "apihelp-query+alltransclusions-description": "Lister toutes les transclusions (pages intégrées en utilisant &#123;&#123;x&#125;&#125;), y compris les inexistantes.",
+ "apihelp-query+alltransclusions-param-from": "Le titre de la transclusion depuis lequel commencer l’énumération.",
+ "apihelp-query+alltransclusions-param-to": "Le titre de la transclusion auquel arrêter l’énumération.",
+ "apihelp-query+alltransclusions-param-prefix": "Rechercher tous les titres inclus qui commencent par cette valeur.",
+ "apihelp-query+alltransclusions-param-unique": "Afficher uniquement les titres inclus. Impossible à utiliser avec $1prop=ids.\nUtilisé avec un générateur, produit les pages cible plutôt que les pages source.",
+ "apihelp-query+alltransclusions-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page incluse (impossible à utiliser avec $1unique).\n;title:Ajoute le titre de la transclusion.",
+ "apihelp-query+alltransclusions-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+alltransclusions-param-limit": "Combien d’éléments renvoyer au total.",
+ "apihelp-query+alltransclusions-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+alltransclusions-example-B": "Lister les titres inclus, y compris les manquants, avec les IDs des pages d’où ils viennent, en commençant à <kbd>B</kbd>.",
+ "apihelp-query+alltransclusions-example-unique": "Lister les titres inclus uniques",
+ "apihelp-query+alltransclusions-example-unique-generator": "Obtient tous les titres inclus, en marquant les manquants",
+ "apihelp-query+alltransclusions-example-generator": "Obtient les pages contenant des transclusions",
+ "apihelp-query+allusers-description": "Énumérer tous les utilisateurs enregistrés.",
+ "apihelp-query+allusers-param-from": "Le nom d’utilisateur auquel démarrer l’énumération.",
+ "apihelp-query+allusers-param-to": "Le nom d’utilisateur auquel stopper l’énumération.",
+ "apihelp-query+allusers-param-prefix": "Rechercher tous les utilisateurs commençant par cette valeur.",
+ "apihelp-query+allusers-param-dir": "Direction du tri.",
+ "apihelp-query+allusers-param-group": "Inclure uniquement les utilisateurs dans les groupes donnés.",
+ "apihelp-query+allusers-param-excludegroup": "Exclure les utilisateurs dans les groupes donnés.",
+ "apihelp-query+allusers-param-rights": "Inclure uniquement les utilisateurs avec les droits indiqués. Ne comprend pas les droits accordés par des groupes implicites ou auto-promus comme *, user ou autoconfirmed.",
+ "apihelp-query+allusers-param-prop": "Quelles informations inclure :\n;blockinfo:Ajoute l’information sur le bloc actuel d’un utilisateur.\n;groups:Liste des groupes auxquels appartient l’utilisateur. Cela utilise beaucoup de ressources du serveur et peut renvoyer moins de résultats que la limite.\n;implicitgroups:Liste tous les groupes auxquels l’utilisateur est affecté automatiquement.\n;rights:Liste les droits qu’à l’utilisateur.\n;editcount:Ajoute le compteur de modifications de l’utilisateur.\n;registration:Ajoute l’horodatage de l’inscription de l’utilisateur, s’il est disponible (peut être vide).",
+ "apihelp-query+allusers-param-limit": "Combien de noms d’utilisateur renvoyer au total.",
+ "apihelp-query+allusers-param-witheditsonly": "Ne lister que les utilisateurs qui ont fait des modifications.",
+ "apihelp-query+allusers-param-activeusers": "Lister uniquement les utilisateurs actifs durant {{PLURAL:$1|le dernier jour|les $1 derniers jours}}.",
+ "apihelp-query+allusers-example-Y": "Lister les utilisateurs en commençant à <kbd>Y</kbd>.",
+ "apihelp-query+backlinks-description": "Trouver toutes les pages qui ont un lien vers la page donnée.",
+ "apihelp-query+backlinks-param-title": "Titre à rechercher. Impossible à utiliser avec <var>$1pageid</var>.",
+ "apihelp-query+backlinks-param-pageid": "ID de la page à chercher. Impossible à utiliser avec <var>$1title</var>.",
+ "apihelp-query+backlinks-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+backlinks-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+backlinks-param-filterredir": "Comment filtrer les redirections. Si positionné à <kbd>nonredirects</kbd> quand <var>$1redirect</var> est activé, cela ne s’applique qu’au second niveau.",
+ "apihelp-query+backlinks-param-limit": "Combien de pages renvoyer au total. Si $1redirect est activé, la limite s’applique à chaque niveau séparément (ce qui signifie jusqu’à 2 * limite résultats peut être retourné).",
+ "apihelp-query+backlinks-param-redirect": "Si le lien vers une page est une redirection, trouver toutes les pages qui ont un lien vers cette redirection aussi. La limite maximale est divisée par deux.",
+ "apihelp-query+backlinks-example-simple": "Afficher les liens vers <kbd>Main page<kbd>.",
+ "apihelp-query+backlinks-example-generator": "Obtenir des informations sur les pages ayant un lien vers <kbd>Main page<kbd>.",
+ "apihelp-query+blocks-description": "Lister tous les utilisateurs et les adresses IP bloqués.",
+ "apihelp-query+blocks-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+blocks-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+blocks-param-ids": "Liste des IDs de bloc à lister (facultatif).",
+ "apihelp-query+blocks-param-users": "Liste des utilisateurs à rechercher (facultatif).",
+ "apihelp-query+blocks-param-ip": "Obtenir tous les blocs s’appliquant à cette adresse IP ou à cette plage CIDR, y compris les blocs de plage.\nImpossible à utiliser avec <var>$3users</var>. Les plages CIDR plus larges que IPv4/$1 ou IPv6/$2 ne sont pas acceptées.",
+ "apihelp-query+blocks-param-limit": "Le nombre maximal de blocs à lister.",
+ "apihelp-query+blocks-param-prop": "Quelles propriétés obtenir :\n;id:Ajoute l’ID du blocage.\n;user:Ajoute le nom de l’utilisateur bloqué.\n;userid:Ajoute l’ID de l’utilisateur bloqué.\n;by:Ajoute le nom de l’utilisateur ayant bloqué.\n;byid:Ajoute l’ID de l’utilisateur ayant bloqué.\n;timestamp:Ajoute l’horodatage du blocage.\n;expiry:Ajoute l’horodatage d’expiration du blocage.\n;reason:Ajoute le motif du blocage.\n;range:Ajoute la plage d’adresses IP affectée par le blocage.\n;flags:Marque le bannissement avec (autoblock, anononly, etc.).",
+ "apihelp-query+blocks-param-show": "Afficher uniquement les éléments correspondant à ces critères.\nPar exemple, pour voir uniquement les blocages infinis sur les adresses IP, mettre <kbd>$1show=ip|!temp</kbd>.",
+ "apihelp-query+blocks-example-simple": "Lister les blocages",
+ "apihelp-query+blocks-example-users": "Lister les blocages des utilisateurs <kbd>Alice</kbd> et <kbd>Bob</kbd>.",
+ "apihelp-query+categories-description": "Lister toutes les catégories auxquelles les pages appartiennent.",
+ "apihelp-query+categories-param-prop": "Quelles propriétés supplémentaires obtenir de chaque catégorie :\n;sortkey:Ajoute la clé de tri (chaîne hexadécimale) et son préfixe (partie lisible) de la catégorie.\n;timestamp:Ajoute l’horodatage de l’ajout de la catégorie.\n;hidden:Marque les catégories cachées avec _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+categories-param-show": "Quelle sorte de catégories afficher.",
+ "apihelp-query+categories-param-limit": "Combien de catégories renvoyer.",
+ "apihelp-query+categories-param-categories": "Lister uniquement ces catégories. Utile pour vérifier si une certaine page est dans une certaine catégorie.",
+ "apihelp-query+categories-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+categories-example-simple": "Obtenir une liste des catégories auxquelles appartient la page <kbd>Albert Einstein</kbd>.",
+ "apihelp-query+categories-example-generator": "Obtenir des informations sur toutes les catégories utilisées dans la page <kbd>Albert Einstein</kbd>.",
+ "apihelp-query+categoryinfo-description": "Renvoie les informations sur les catégories données.",
+ "apihelp-query+categoryinfo-example-simple": "Obtenir des informations sur <kbd>Category:Foo</kbd> et <kbd>Category:Bar</kbd>.",
+ "apihelp-query+categorymembers-description": "Lister toutes les pages d’une catégorie donnée.",
+ "apihelp-query+categorymembers-param-title": "Quelle catégorie énumérer (obligatoire). Doit comprendre le préfixe <kbd>{{ns:category}}:</kbd>. Impossible à utiliser avec <var>$1pageid</var>.",
+ "apihelp-query+categorymembers-param-pageid": "ID de la page de la catégorie à énumérer. Impossible à utiliser avec <var>$1title</var>.",
+ "apihelp-query+categorymembers-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page.\n;title:Ajoute le titre et l’ID de l’espace de noms de la page.\n;sortkey:Ajoute la clé de tri utilisée pour trier dans la catégorie (chaîne hexadécimale).\n;sortkeyprefix:Ajoute le préfixe de la clé de tri utilisé pour trier dans la catégorie (partie lisible de la clé de tri).\n;type:Ajoute le type dans lequel a été catégorisée la page (page, sous-catégorie ou fichier).\n;timestamp:Ajoute l’horodatage de l’inclusion de la page.",
+ "apihelp-query+categorymembers-param-namespace": "Inclure uniquement les pages dans ces espaces de nom. Remarquez que <kbd>$1type=subcat</kbd> ou <kbd>$1type=file</kbd> peuvent être utilisés à la place de <kbd>$1namespace=14</kbd> ou <kbd>6</kbd>.",
+ "apihelp-query+categorymembers-param-type": "Quel type de membres de la catégorie inclure. Ignoré quand <kbd>$1sort=timestamp</kbd> est positionné.",
+ "apihelp-query+categorymembers-param-limit": "Le nombre maximal de pages à renvoyer.",
+ "apihelp-query+categorymembers-param-sort": "Propriété par laquelle trier.",
+ "apihelp-query+categorymembers-param-dir": "Dans quelle direction trier.",
+ "apihelp-query+categorymembers-param-start": "Horodatage auquel démarrer la liste. Peut être utilisé uniquement avec <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-end": "Horodatage auquel terminer la liste. Peut être utilisé uniquement avec <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-starthexsortkey": "Clé de tri à laquelle démarrer le listage, telle que renvoyée par <kbd>$1prop=sortkey</kbd>. Utilisable uniquement avec <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-endhexsortkey": "Clé de tri à laquelle arrêter le listage, telle que renvoyée par <kbd>$1prop=sortkey</kbd>. Utilisable uniquement avec <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-startsortkeyprefix": "Préfixe de la clé de tri à laquelle démarrer le listage. Utilisable uniquement avec <kbd>$1sort=sortkey</kbd>. Écrase <var>$1starthexsortkey</var>.",
+ "apihelp-query+categorymembers-param-endsortkeyprefix": "Préfixe de la clé de tri AVANT laquelle se termine le listage (et non pas à, si cette valeur existe elle ne sera pas incluse !). Utilisable uniquement avec $1sort=sortkey. Écrase $1endhexsortkey.",
+ "apihelp-query+categorymembers-param-startsortkey": "Utiliser plutôt $1starthexsortkey.",
+ "apihelp-query+categorymembers-param-endsortkey": "Utiliser plutôt $1endhexsortkey.",
+ "apihelp-query+categorymembers-example-simple": "Obtenir les 10 premières pages de <kbd>Category:Physics</kbd>.",
+ "apihelp-query+categorymembers-example-generator": "Obtenir l’information sur les 10 premières pages de <kbd>Category:Physics</kbd>.",
+ "apihelp-query+contributors-description": "Obtenir la liste des contributeurs connectés et le nombre de contributeurs anonymes d’une page.",
+ "apihelp-query+contributors-param-group": "Inclure uniquement les utilisateurs dans les groupes donnés. Ne pas inclure les groupes implicites ou auto-promus comme *, user ou autoconfirmed.",
+ "apihelp-query+contributors-param-excludegroup": "Exclure les utilisateurs des groupes donnés. Ne pas inclure les groupes implicites ou auto-promus comme *, user ou autoconfirmed.",
+ "apihelp-query+contributors-param-rights": "Inclure uniquement les utilisateurs ayant les droits donnés. Ne pas inclure les droits accordés par les groupes implicites ou auto-promus comme *, user ou autoconfirmed.",
+ "apihelp-query+contributors-param-excluderights": "Exclure les utilisateurs ayant les droits donnés. Ne pas inclure les droits accordés par les groupes implicites ou auto-promus comme *, user ou autoconfirmed.",
+ "apihelp-query+contributors-param-limit": "Combien de contributeurs renvoyer.",
+ "apihelp-query+contributors-example-simple": "Afficher les contributeurs dans la <kbd>Main Page</kbd>.",
+ "apihelp-query+deletedrevisions-description": "Obtenir des informations sur la révision supprimée.\n\nPeut être utilisé de différentes manières :\n# Obtenir les révisions supprimées pour un ensemble de pages, en donnant les titres ou les ids de page. Ordonné par titre et horodatage.\n# Obtenir des données sur un ensemble de révisions supprimées en donnant leurs IDs et leurs ids de révision. Ordonné par ID de révision.",
+ "apihelp-query+deletedrevisions-param-start": "L’horodatage auquel démarrer l’énumération. Ignoré lors du traitement d’une liste d’IDs de révisions.",
+ "apihelp-query+deletedrevisions-param-end": "L’horodatage auquel arrêter l’énumération. Ignoré lors du traitement d’une liste d’IDs de révisions.",
+ "apihelp-query+deletedrevisions-param-tag": "Lister uniquement les révisions marquées par cette balise.",
+ "apihelp-query+deletedrevisions-param-user": "Lister uniquement les révisions faites par cet utilisateur.",
+ "apihelp-query+deletedrevisions-param-excludeuser": "Ne pas lister les révisions faites par cet utilisateur.",
+ "apihelp-query+deletedrevisions-param-limit": "Le nombre maximal de révisions à lister.",
+ "apihelp-query+deletedrevisions-param-prop": "Quelles propriétés obtenir :\n;revid:Ajoute l’ID de la révision supprimée.\n;parentid:Ajoute l’ID de la révision précédente de la page.\n;user:Ajoute l’utilisateur ayant fait la révision.\n;userid:Ajoute l’ID de l’utilisateur ayant fait la révision.\n;comment:Ajoute le commentaire de la révision.\n;parsedcomment:Ajoute le commentaire analysé de la révision.\n;minor:Marque si une révision est mineure.\n;len:Ajoute la taille (en octets) de la révision.\n;sha1:Ajoute le SHA-1 (base 16) de la révision.\n;content:Ajoute le contenu de la révision.\n;tags:Balises pour la révision.",
+ "apihelp-query+deletedrevisions-example-titles": "Lister les révisions supprimées des pages <kbd>Main Page</kbd> et <kbd>Talk:Main Page</kbd>, avec leur contenu.",
+ "apihelp-query+deletedrevisions-example-revids": "Lister les informations pour la révision supprimée <kbd>123456</kbd>.",
+ "apihelp-query+deletedrevs-description": "Lister les révisions supprimées.\n\nOpère selon trois modes :\n# Lister les révisions supprimées pour les titres donnés, triées par horodatage.\n# Lister les contributions supprimées pour l’utilisateur donné, triées par horodatage (pas de titres spécifiés).\n# Lister toutes les révisions supprimées dans l’espace de noms donné, triées par titre et horodatage (aucun titre spécifié, $1user non positionné).\n\nCertains paramètres ne s’appliquent qu’à certains modes et sont ignorés dans les autres.",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Mode|Modes}} : $2",
+ "apihelp-query+deletedrevs-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+deletedrevs-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+deletedrevs-param-from": "Démarrer la liste à ce titre.",
+ "apihelp-query+deletedrevs-param-to": "Arrêter la liste à ce titre.",
+ "apihelp-query+deletedrevs-param-prefix": "Rechercher tous les titres de page commençant par cette valeur.",
+ "apihelp-query+deletedrevs-param-unique": "Lister uniquement une révision pour chaque page.",
+ "apihelp-query+deletedrevs-param-tag": "Lister uniquement les révisions marquées par cette balise.",
+ "apihelp-query+deletedrevs-param-user": "Lister uniquement les révisions par cet utilisateur.",
+ "apihelp-query+deletedrevs-param-excludeuser": "Ne pas lister les révisions par cet utilisateur.",
+ "apihelp-query+deletedrevs-param-namespace": "Lister uniquement les pages dans cet espace de noms.",
+ "apihelp-query+deletedrevs-param-limit": "Le nombre maximal de révisions à lister.",
+ "apihelp-query+deletedrevs-param-prop": "Quelles propriétés obtenir :\n;revid:Ajoute l’ID de la révision supprimée.\n;parentid:Ajoute l’ID de la révision précédente de la page.\n;user:Ajoute l’utilisateur ayant fait la révision.\n;userid:Ajoute l’ID de l’utilisateur qui a fait la révision.\n;comment:Ajoute le commentaire de la révision.\n;parsedcomment:Ajoute le commentaire analysé de la révision.\n;minor:Marque si la révision est mineure.\n;len:Ajoute la longueur (en octets) de la révision.\n;sha1:Ajoute le SHA-1 (base 16) de la révision.\n;content:Ajoute le contenu de la révision.\n;token:<span class=\"apihelp-deprecated\">Obsolète.</span> Fournit le jeton de modification.\n;tags:Balises pour la révision.",
+ "apihelp-query+deletedrevs-example-mode1": "Lister les dernières révisions supprimées de des pages <kbd>Main Page</kbd> et <kbd>Talk:Main Page</kbd>, avec le contenu (mode 1).",
+ "apihelp-query+deletedrevs-example-mode2": "Lister les 50 dernières contributions de <kbd>Bob</kbd> supprimées (mode 2).",
+ "apihelp-query+deletedrevs-example-mode3-main": "Lister les 50 premières révisions supprimées dans l’espace de noms principal (mode 3)",
+ "apihelp-query+deletedrevs-example-mode3-talk": "Lister les 50 premières pages supprimées dans l’espace de noms {{ns:talk}} (mode 3).",
+ "apihelp-query+disabled-description": "Ce module de requête a été désactivé.",
+ "apihelp-query+duplicatefiles-description": "Lister tous les fichiers qui sont des doublons des fichiers donnés d’après leurs valeurs de hachage.",
+ "apihelp-query+duplicatefiles-param-limit": "Combien de fichiers dupliqués à renvoyer.",
+ "apihelp-query+duplicatefiles-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+duplicatefiles-param-localonly": "Rechercher les fichiers uniquement dans le référentiel local.",
+ "apihelp-query+duplicatefiles-example-simple": "Rechercher les doublons de [[:File:Albert Einstein Head.jpg]]",
+ "apihelp-query+duplicatefiles-example-generated": "Rechercher les doublons de tous les fichiers",
+ "apihelp-query+embeddedin-description": "Trouver toutes les pages qui incluent (par transclusion) le titre donné.",
+ "apihelp-query+embeddedin-param-title": "Titre à rechercher. Impossible à utiliser avec $1pageid.",
+ "apihelp-query+embeddedin-param-pageid": "ID de la page à rechercher. Impossible à utiliser avec $1title.",
+ "apihelp-query+embeddedin-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+embeddedin-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+embeddedin-param-filterredir": "Comment filtrer les redirections.",
+ "apihelp-query+embeddedin-param-limit": "Combien de pages renvoyer au total.",
+ "apihelp-query+embeddedin-example-simple": "Afficher les pages incluant <kbd>Template:Stub</kbd>.",
+ "apihelp-query+embeddedin-example-generator": "Obteir des informations sur les pages incluant <kbd>Template:Stub</kbd>.",
+ "apihelp-query+extlinks-description": "Renvoyer toutes les URLs externes (non interwikis) des pages données.",
+ "apihelp-query+extlinks-param-limit": "Combien de liens renvoyer.",
+ "apihelp-query+extlinks-param-protocol": "Protocole de l’URL. Si vide et <var>$1query</var> est positionné, le protocole est <kbd>http</kbd>. Laisser à la fois ceci et <var>$1query</var> vide pour lister tous les liens externes.",
+ "apihelp-query+extlinks-param-query": "Rechercher une chaîne sans protocole. Utile pour vérifier si une certaine page contient une certaine URL externe.",
+ "apihelp-query+extlinks-param-expandurl": "Étendre les URLs relatives au protocole avec le protocole canonique.",
+ "apihelp-query+extlinks-example-simple": "Obtenir une liste des liens externes de <kbd>Main Page<kbd>.",
+ "apihelp-query+exturlusage-description": "Énumérer les pages contenant une URL donnée.",
+ "apihelp-query+exturlusage-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page.\n;title:Ajoute le titre et l’ID de l’espace de noms de la page.\n;url:Ajoute l’URL utilisée dans la page.",
+ "apihelp-query+exturlusage-param-protocol": "Protocole de l’URL. Si vide et que <var>$1query</var> est rempli, le protocole est <kbd>http</kbd>. Le laisser avec <var>$1query</var> vide pour lister tous les liens externes.",
+ "apihelp-query+exturlusage-param-query": "Rechercher une chaîne sans protocole. Voyez [[Special:LinkSearch]]. Le laisser vide liste tous les liens externes.",
+ "apihelp-query+exturlusage-param-namespace": "Les espaces de nom à énumérer.",
+ "apihelp-query+exturlusage-param-limit": "Combien de pages renvoyer.",
+ "apihelp-query+exturlusage-param-expandurl": "Étendre les URLs relatives au protocole avec le protocole canonique.",
+ "apihelp-query+exturlusage-example-simple": "Afficher les pages avec un lien vers <kbd>http://www.mediawiki.org</kbd>.",
+ "apihelp-query+filearchive-description": "Énumérer séquentiellement tous les fichiers supprimés.",
+ "apihelp-query+filearchive-param-from": "Le titre de l’image auquel démarrer l’énumération.",
+ "apihelp-query+filearchive-param-to": "Le titre de l’image auquel arrêter l’énumération.",
+ "apihelp-query+filearchive-param-prefix": "Rechercher tous les titres d’image qui commencent par cette valeur.",
+ "apihelp-query+filearchive-param-limit": "Combien d’images renvoyer au total.",
+ "apihelp-query+filearchive-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+filearchive-param-sha1": "Hachage SHA1 de l’image. Écrase $1sha1base36.",
+ "apihelp-query+filearchive-param-sha1base36": "Hachage SHA1 de l’image en base 36 (utilisé dans MédiaWiki).",
+ "apihelp-query+filearchive-param-prop": "Quelle information obtenir sur l’image :\n;sha1:Ajoute le hachage SHA-1 pour l’image.\n;timestamp:Ajoute l÷’horodatage pour la version téléchargée.\n;user:Ajoute l’utilisateur qui a téléchargé la version de l’image.\n;size:Ajoute la taille de l’image en octets et la hauteur, la largeur et le nombre de page (si c’est applicable).\n;dimensions:Alias pour la taille.\n;description:Ajoute la description de la version de l’image.\n;parseddescription:Analyser la description de la version.\n;mime:Ajoute le MIME de l’image.\n;mediatype:Ajoute le type de média de l’image.\n;metadata:Liste les métadonnées Exif pour la version de l’image.\n;bitdepth:Ajoute la profondeur de bit de la version.\n;archivename:Ajoute le nom de fichier de la version d’archive pour les versions autres que la dernière.",
+ "apihelp-query+filearchive-example-simple": "Afficher une liste de tous les fichiers supprimés",
+ "apihelp-query+filerepoinfo-description": "Renvoyer les méta-informations sur les référentiels d’image configurés dans le wiki.",
+ "apihelp-query+filerepoinfo-param-prop": "Quelles propriétés du référentiel récupérer (il peut y en avoir plus de disponibles sur certains wikis) :\n;apiurl:URL de l’API du référentiel - utile pour obtenir les infos de l’image depuis l’hôte.\n;name:La clé du référentiel - utilisé par ex. dans les valeurs de retour de <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> et [[Special:ApiHelp/query+imageinfo|imageinfo]].\n;displayname:Le nom lisible du wiki référentiel.\n;rooturl:URL racine des chemins d’image.\n;local:Si ce référentiel est le référentiel local ou non.",
+ "apihelp-query+filerepoinfo-example-simple": "Obtenir l’information sur les référentiels de fichier",
+ "apihelp-query+fileusage-description": "Trouver toutes les pages qui utilisent les fichiers donnés.",
+ "apihelp-query+fileusage-param-prop": "Quelles propriétés obtenir :\n;pageid:ID de chaque page.\n;title:Titre de chaque page.\n;redirect:Marque si la page est une redirection.",
+ "apihelp-query+fileusage-param-namespace": "Inclure uniquement les pages dans ces espaces de nom.",
+ "apihelp-query+fileusage-param-limit": "Combien renvoyer.",
+ "apihelp-query+fileusage-param-show": "Afficher uniquement les éléments qui correspondent à ces critères :\n;redirect:Afficher uniquement les redirections.\n;!redirect:Afficher uniquement les non-redirections.",
+ "apihelp-query+fileusage-example-simple": "Obtenir une liste des pages utilisant [[:File:Example.jpg]]",
+ "apihelp-query+fileusage-example-generator": "Obtenir l’information sur les pages utilisant [[:File:Example.jpg]]",
+ "apihelp-query+imageinfo-description": "Renvoyer l’information de fichier et l’historique de téléchargement.",
+ "apihelp-query+imageinfo-param-prop": "Quelles informations obtenir du fichier :\n;timestamp:Ajoute l’horodatage de la version téléchargée.\n;user:Ajoute l’utilisateur qui a téléchargé chaque version du fichier.\n;userid:Ajoute l’ID de l’utilisateur qui a téléchargé chaque version du fichier.\n;comment:Commentaire sur la version.\n;parsedcomment:Analyser le commentaire sur cette version.\n;canonicaltitle:Ajoute le titre canonique du fichier.\n;url:Fournit l’URL du fichier et la page de description.\n;size:Ajoute la taille du fichier en octets et la hauteur, la largeur et le nombre de pages (si applicable).\n;dimensions:Alias pour la taille.\n;sha1:Ajoute le hachage SHA-1 pour le fichier.\n;mime:Ajoute le type MIME du fichier.\n;thumbmime:Ajoute le type MIME de la vignette de l’image (nécessite l’URL et le paramètre $1urlwidth).\n;mediatype:Ajoute le type de média du fichier.\n;metadata:Liste les métadonnées Exif de la version du fichier.\n;commonmetadata:Liste les métadonnées génériques du format du fichier pour la version du fichier.\n;extmetadata:Liste les métadonnées mises en forme combinées depuis différentes sources. Les résultats sont au format HTML.\n;archivename:Ajoute le nom de fichier de la version d’archive pour les versions autres que la dernière.\n;bitdepth:Ajoute la profondeur de bit de la version.\n;uploadwarning:Utilisé par la page Special:Upload pour obtenir de l’information sur un fichier existant. Non prévu pour être utilisé en dehors du cœur de MédiaWiki.",
+ "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Ajoute l’horodatage à la version téléchargée.",
+ "apihelp-query+imageinfo-paramvalue-prop-user": "Ajoute l’utilisateur qui a téléchargé chaque version du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-userid": "Ajouter l’ID de l’utilisateur qui a téléchargé chaque version du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "Commentaire sur la version.",
+ "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Analyser le commentaire de la version.",
+ "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Ajoute le titre canonique du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-url": "Fournit l’URL du fichier et de la page de description.",
+ "apihelp-query+imageinfo-paramvalue-prop-size": "Ajoute la taille du fichier en octets et sa hauteur, largeur et compteur de page (le cas échéant).",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias pour la taille.",
+ "apihelp-query+imageinfo-paramvalue-prop-sha1": "Ajoute le hachage SH1-1 du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-mime": "Ajoute le type MIME du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "Ajoute le type MIME de la vignette de l’image (nécessite l’URL et le paramètre $1urlwidth).",
+ "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Ajoute le type de média du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-metadata": "Liste les métadonnées Exif de la version du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-commonmetadata": "Liste les métadonnées génériques du format du fichier pour la version du fichier.",
+ "apihelp-query+imageinfo-paramvalue-prop-extmetadata": "Liste les métadonnées mises en forme combinées depuis diverses sources. Les résultats sont au format HTML.",
+ "apihelp-query+imageinfo-paramvalue-prop-archivename": "Ajoute le nom de fichier de la version d’archive pour les versions autres que la dernière.",
+ "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "Ajoute la profondeur de bits de la version.",
+ "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "Utilisé par la page Special:Upload pour obtenir de l’information sur un fichier existant. Non prévu pour être utilisé en dehors du cœur de MédiaWiki.",
+ "apihelp-query+imageinfo-param-limit": "Combien de révision de fichier renvoyer par fichier.",
+ "apihelp-query+imageinfo-param-start": "Horodatage auquel démarrer la liste.",
+ "apihelp-query+imageinfo-param-end": "Horodatage auquel arrêter la liste.",
+ "apihelp-query+imageinfo-param-urlwidth": "Si $2prop=url est défini, une URL vers une image à l’échelle de cette largeur sera renvoyée.\nPour des raisons de performance si cette option est utilisée, pas plus de $1 images mises à l’échelle seront renvoyées.",
+ "apihelp-query+imageinfo-param-urlheight": "Similaire à $1urlwidth.",
+ "apihelp-query+imageinfo-param-metadataversion": "Version de métadonnées à utiliser. Si <kbd>latest</kbd> est spécifié, utiliser la dernière version. Par défaut à <kbd>1</kbd> pour la compatibilité ascendante.",
+ "apihelp-query+imageinfo-param-extmetadatalanguage": "Quelle langue pour analyser extmetadata. Cela affecte à la fois quelle traduction analyser, s’il y en a plusieurs, et comment les choses comme les nombres et d’autres valeurs sont mises en forme.",
+ "apihelp-query+imageinfo-param-extmetadatamultilang": "Si des traductions pour la propriété extmetadata sont disponibles, les analyser toutes.",
+ "apihelp-query+imageinfo-param-extmetadatafilter": "Si spécifié et non vide, seules ces clés seront renvoyées pour $1prop=extmetadata.",
+ "apihelp-query+imageinfo-param-urlparam": "Une chaîne de paramètre spécifique à l’analyseur. Par exemple, les PDFs peuvent utiliser <kbd>page15-100px</kbd>. <var>$1urlwidth</var> doit être utilisé et être cohérent avec <var>$1urlparam</var>.",
+ "apihelp-query+imageinfo-param-localonly": "Rechercher les fichiers uniquement dans le référentiel local.",
+ "apihelp-query+imageinfo-example-simple": "Analyser les informations sur la version actuelle de [[:File:Albert Einstein Head.jpg]]",
+ "apihelp-query+imageinfo-example-dated": "Analyser les informations sur les versions de [[:File:Test.jpg]] depuis 2008",
+ "apihelp-query+images-description": "Renvoie tous les fichiers contenus dans les pages fournies.",
+ "apihelp-query+images-param-limit": "Combien de fichiers renvoyer.",
+ "apihelp-query+images-param-images": "Lister uniquement ces fichiers. Utile pour vérifier si une page donnée contient un fichier donné.",
+ "apihelp-query+images-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+images-example-simple": "Obtenir une liste des fichiers utilisés dans [[Main Page]]",
+ "apihelp-query+images-example-generator": "Obtenir des informations sur tous les fichiers utilisés dans [[Main Page]]",
+ "apihelp-query+imageusage-description": "Trouver toutes les pages qui utilisent le titre de l’image donné.",
+ "apihelp-query+imageusage-param-title": "Titre à rechercher. Impossible à utiliser avec $1pageid.",
+ "apihelp-query+imageusage-param-pageid": "ID de la page à rechercher. Impossible à utiliser avec $1title.",
+ "apihelp-query+imageusage-param-namespace": "L’espace de noms à énumérer.",
+ "apihelp-query+imageusage-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+imageusage-param-filterredir": "Comment filtrer les redirections. Si mis à nonredirects quand $1redirect est activé, cela ne s’appliquera qu’au second niveau.",
+ "apihelp-query+imageusage-param-limit": "Combien de pages renvoyer au total. Si <var>$1redirect</var> est activé, la limite s’applique à chaque niveau séparément (ce qui veut dire que jusqu’à 2 * <var>$1limit</var> résultats peuvent être renvoyés).",
+ "apihelp-query+imageusage-param-redirect": "Si le lien vers une page est une redirection, trouver toutes les pages qui ont aussi un lien vers cette redirection. La limite maximale est divisée par deux.",
+ "apihelp-query+imageusage-example-simple": "Afficher les pages utilisant [[:File:Albert Einstein Head.jpg]]",
+ "apihelp-query+imageusage-example-generator": "Obtenir des informations sur les pages utilisant [[:File:Albert Einstein Head.jpg]]",
+ "apihelp-query+info-description": "Obtenir les informations de base sur la page.",
+ "apihelp-query+info-param-prop": "Quelles propriétés supplémentaires récupérer :\n;protection:Liste de niveau de protection de chaque page.\n;talkid:L’ID de la page de discussion pour chaque page qui n’est pas une page de discussion.\n;watched:Liste de l’état de suivi de chaque page.\n;watchers:Le nombre d’observateurs, si c&est autorisé.\n;notificationtimestamp:L’horodatage de notification de la liste de suivi de chaque page.\n;subjectid:L’ID de la page parente de chaque page de discussion.\n;url:Fournit une URL complète, une URL de modification, et l’URL canonique pour chaque page.\n;readable:Si l’utilisateur peut lire cette page.\n;preload:Fournit le texte renvoyé par EditFormPreloadText.\n;displaytitle:Fournit la manière dont le titre de la page est vraiment affiché.",
+ "apihelp-query+info-paramvalue-prop-protection": "Lister le niveau de protection de chaque page.",
+ "apihelp-query+info-paramvalue-prop-talkid": "L’ID de la page de discussion de chaque page qui n’est pas de discussion.",
+ "apihelp-query+info-paramvalue-prop-watched": "Lister l’état de suivi de chaque page.",
+ "apihelp-query+info-paramvalue-prop-watchers": "Le nombre d’observateurs, si c’est autorisé.",
+ "apihelp-query+info-paramvalue-prop-notificationtimestamp": "L’horodatage de notification de la liste de suivi de chaque page.",
+ "apihelp-query+info-paramvalue-prop-subjectid": "L’ID de page de la page parent de chaque page de discussion.",
+ "apihelp-query+info-paramvalue-prop-url": "Fournit une URL complète, une URL de modification, et l’URL canonique de chaque page.",
+ "apihelp-query+info-paramvalue-prop-readable": "Si l’utilisateur peut lire cette page.",
+ "apihelp-query+info-paramvalue-prop-preload": "Fournit le texte renvoyé par EditFormPreloadText.",
+ "apihelp-query+info-paramvalue-prop-displaytitle": "Fournit la manière dont le titre de la page est réellement affiché.",
+ "apihelp-query+info-param-testactions": "Tester si l’utilisateur actuel peut effectuer certaines actions sur la page.",
+ "apihelp-query+info-param-token": "Utiliser plutôt [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-query+info-example-simple": "Obtenir des informations sur la page <kbd>Main Page</kbd>.",
+ "apihelp-query+info-example-protection": "Obtenir des informations générale et de protection sur la page <kbd>Main Page</kbd>.",
+ "apihelp-query+iwbacklinks-description": "Trouver toutes les pages qui ont un lien vers le lien interwiki indiqué.\n\nPeut être utilisé pour trouver tous les liens avec un préfixe, ou tous les liens vers un titre (avec un préfixe donné). N’utiliser aucun paramètre revient en pratique à « tous les liens interwiki ».",
+ "apihelp-query+iwbacklinks-param-prefix": "Préfixe pour l’interwiki.",
+ "apihelp-query+iwbacklinks-param-title": "Lien interwiki à rechercher. Doit être utilisé avec <var>$1blprefix</var>.",
+ "apihelp-query+iwbacklinks-param-limit": "Combien de pages renvoyer.",
+ "apihelp-query+iwbacklinks-param-prop": "Quelles propriétés obtenir :\n;iwprefix:Ajoute le préfixe de l’interwiki.\n;iwtitle:Ajoute le titre de l’interwiki.",
+ "apihelp-query+iwbacklinks-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+iwbacklinks-example-simple": "Obtenir les pages ayant un lien vers [[wikibooks:Test]]",
+ "apihelp-query+iwbacklinks-example-generator": "Obtenir des informations sur les pages ayant un lien vers [[wikibooks:Test]]",
+ "apihelp-query+iwlinks-description": "Renvoie tous les liens interwiki des pages indiquées.",
+ "apihelp-query+iwlinks-param-url": "S&il faut obtenir l’URL complète (impossible à utiliser avec $1prop).",
+ "apihelp-query+iwlinks-param-prop": "Quelles propriétés supplémentaires obtenir pour chaque lien interlangue :\n;url:Ajoute l’URL complète.",
+ "apihelp-query+iwlinks-param-limit": "Combien de liens interwiki renvoyer.",
+ "apihelp-query+iwlinks-param-prefix": "Renvoyer uniquement les liens interwiki avec ce préfixe.",
+ "apihelp-query+iwlinks-param-title": "Lien interwiki à rechercher. Doit être utilisé avec <var>$1prefix</var>.",
+ "apihelp-query+iwlinks-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+iwlinks-example-simple": "Obtenir les liens interwiki de la page <kbd>Main Page</kbd>.",
+ "apihelp-query+langbacklinks-description": "Trouver toutes les pages qui ont un lien vers le lien de langue indiqué.\n\nPeut être utilisé pour trouver tous les liens avec un code de langue, ou tous les liens vers un titre (avec une langue donnée). N’utiliser aucun paramètre revient à « tous les liens de langue ».\n\nNotez que cela peut ne pas prendre en compte les liens de langue ajoutés par les extensions.",
+ "apihelp-query+langbacklinks-param-lang": "Langue pour le lien de langue.",
+ "apihelp-query+langbacklinks-param-title": "Lien interlangue à rechercher. Doit être utilisé avec $1lang.",
+ "apihelp-query+langbacklinks-param-limit": "Combien de pages renvoyer au total.",
+ "apihelp-query+langbacklinks-param-prop": "Quelles propriétés obtenir :\n;lllang:Ajoute le code de langue du lien de langue.\n;lltitle:Ajoute le titre du lien de langue.",
+ "apihelp-query+langbacklinks-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+langbacklinks-example-simple": "Obtenir les pages avec un lien avec [[:fr:Test]]",
+ "apihelp-query+langbacklinks-example-generator": "Obtenir des informations sur les pages ayant un lien vers [[:fr:Test]]",
+ "apihelp-query+langlinks-description": "Renvoie tous les liens interlangue des pages fournies.",
+ "apihelp-query+langlinks-param-limit": "Combien de liens interlangue renvoyer.",
+ "apihelp-query+langlinks-param-url": "S’il faut récupérer l’URL complète (impossible à utiliser avec <var>$1prop</var>).",
+ "apihelp-query+langlinks-param-prop": "Quelles propriétés supplémentaires obtenir pour chaque lien interlangue :\n;url:Ajoute l’URL complète.\n;langname:Ajoute le nom localisé de la langue (au mieux). Utiliser <var>$1inlanguagecode</var> pour contrôler la langue.\n;autonym:Ajoute le nom natif de la langue.",
+ "apihelp-query+langlinks-param-lang": "Renvoyer uniquement les liens interlangue avec ce code de langue.",
+ "apihelp-query+langlinks-param-title": "Lien à rechercher. Doit être utilisé avec <var>$1lang</var>.",
+ "apihelp-query+langlinks-param-dir": "La direction dans laquelle énumérer.",
+ "apihelp-query+langlinks-param-inlanguagecode": "Code de langue pour les noms de langue localisés.",
+ "apihelp-query+langlinks-example-simple": "Obtenir les liens interlangue de la page <kbd>Main Page</kbd>.",
+ "apihelp-query+links-description": "Renvoie tous les liens des pages fournies.",
+ "apihelp-query+links-param-namespace": "Afficher les liens uniquement dans ces espaces de nom.",
+ "apihelp-query+links-param-limit": "Combien de liens renvoyer.",
+ "apihelp-query+links-param-titles": "Lister uniquement les liens vers ces titres. Utile pour vérifier si une certaine page a un lien vers un titre donné.",
+ "apihelp-query+links-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+links-example-simple": "Obtenir les liens de la page <kbd>Main Page</kbd>",
+ "apihelp-query+links-example-generator": "Obtenir des informations sur tous les liens de page dans <kbd>Main Page</kbd>.",
+ "apihelp-query+links-example-namespaces": "Obtenir les liens de la page <kbd>Accueil</kbd> dans les espaces de nom {{ns:user}} et {{ns:template}}.",
+ "apihelp-query+linkshere-description": "Trouver toutes les pages ayant un lien vers les pages données.",
+ "apihelp-query+linkshere-param-prop": "Quelles propriétés obtenir :\n;pageid:ID de chaque page.\n;title:Titre de chaque page.\n;redirect:Indique si la page est une redirection.",
+ "apihelp-query+linkshere-param-namespace": "Inclure uniquement les pages dans ces espaces de nom.",
+ "apihelp-query+linkshere-param-limit": "Combien de résultats renvoyer.",
+ "apihelp-query+linkshere-param-show": "Afficher uniquement les éléments qui correspondent à ces critères :\n;redirect:Afficher uniquement les redirections.\n;!redirect:Afficher uniquement les non-redirections.",
+ "apihelp-query+linkshere-example-simple": "Obtenir une liste des pages liées à [[Main Page]]",
+ "apihelp-query+linkshere-example-generator": "Obtenir des informations sur les pages liées à [[Main Page]]",
+ "apihelp-query+logevents-description": "Obtenir des événements des journaux.",
+ "apihelp-query+logevents-param-prop": "Quelles propriétés obtenir :\n;ids:Ajoute l’ID de l’événement.\n;title:Ajoute le titre de la page pour l’événement.\n;type:Ajoute le type de l’événement.\n;user:Ajoute l’utilisateur responsable de l’événement.\n;userid:Ajoute l’ID de l’utilisateur responsable de l’événement.\n;timestamp:Ajoute l’horodatage de l’événement.\n;comment:Ajoute le commentaire de l’événement.\n;parsedcomment:Ajoute le commentaire analysé de l’événement.\n;details:Liste les détails supplémentaires sur l’événement.\n;tags:Liste les balises de l’événement.",
+ "apihelp-query+logevents-param-type": "Filtrer les entrées du journal à ce seul type.",
+ "apihelp-query+logevents-param-action": "Filtrer les actions du journal à cette seule action. Écrase <var>$1type</var>. Des actions avec une astérisque de la forme <var>$1type</var> sont autorisées pour spécifier n’importe quelle chaîne à la place de l’astérisque.",
+ "apihelp-query+logevents-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+logevents-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+logevents-param-user": "Restreindre aux entrées générées par l’utilisateur spécifié.",
+ "apihelp-query+logevents-param-title": "Restreindre aux entrées associées à une page donnée.",
+ "apihelp-query+logevents-param-namespace": "Restreindre aux entrées dans l’espace de nom spécifié.",
+ "apihelp-query+logevents-param-prefix": "Restreindre aux entrées commençant par ce préfixe.",
+ "apihelp-query+logevents-param-tag": "Lister seulement les entrées ayant cette balise.",
+ "apihelp-query+logevents-param-limit": "Combien d'entrées renvoyer au total.",
+ "apihelp-query+logevents-example-simple": "Liste les entrées de journal récentes.",
+ "apihelp-query+pagepropnames-description": "Lister les noms de toutes les propriétés de page utilisées sur le wiki.",
+ "apihelp-query+pagepropnames-param-limit": "Le nombre maximal de noms à renvoyer.",
+ "apihelp-query+pagepropnames-example-simple": "Obtenir les 10 premiers noms de propriété.",
+ "apihelp-query+pageprops-description": "Obtenir diverses propriétés définies dans le contenu de la page.",
+ "apihelp-query+pageprops-param-prop": "Lister uniquement ces propriétés. Utile pour vérifier si une certaine page utilise une certaine propriété de page.",
+ "apihelp-query+pageprops-example-simple": "Obtenir les propriétés de <kbd>Category:Foo</kbd>.",
+ "apihelp-query+pageswithprop-description": "Lister toutes les pages utilisant une propriété de page donnée.",
+ "apihelp-query+pageswithprop-param-propname": "Propriété de page pour laquelle énumérer les pages.",
+ "apihelp-query+pageswithprop-param-prop": "Quelles informations inclure :\n;ids:Ajoute l’ID de la page.\n;title:Ajoute le titre et l’ID de l’espace de noms de la page.\n;value:Ajoute la valeur de la propriété de page.",
+ "apihelp-query+pageswithprop-param-limit": "Le nombre maximal de pages à renvoyer.",
+ "apihelp-query+pageswithprop-param-dir": "Dans quelle direction trier.",
+ "apihelp-query+pageswithprop-example-simple": "Lister les 10 premières pages en utilisant <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+ "apihelp-query+pageswithprop-example-generator": "Obtenir des informations sur les 10 premières pages utilisant <code>_&#95;NOTOC_&#95;</code>.",
+ "apihelp-query+prefixsearch-description": "Effectuer une recherche de préfixe sur les titres de page.",
+ "apihelp-query+prefixsearch-param-search": "Chaîne de recherche.",
+ "apihelp-query+prefixsearch-param-namespace": "Espaces de nom à rechercher.",
+ "apihelp-query+prefixsearch-param-limit": "Nombre maximal de résultats à renvoyer.",
+ "apihelp-query+prefixsearch-param-offset": "Nombre de résultats à sauter.",
+ "apihelp-query+prefixsearch-example-simple": "Rechercher les titres de page commençant par <kbd>meaning</kbd>.",
+ "apihelp-query+protectedtitles-description": "Lister tous les titres protégés en création.",
+ "apihelp-query+protectedtitles-param-namespace": "Lister uniquement les titres dans ces espaces de nom.",
+ "apihelp-query+protectedtitles-param-level": "Lister uniquement les titres avec ces niveaux de protection.",
+ "apihelp-query+protectedtitles-param-limit": "Combien de pages renvoyer au total.",
+ "apihelp-query+protectedtitles-param-start": "Démarrer la liste à cet horodatage de protection.",
+ "apihelp-query+protectedtitles-param-end": "Arrêter la liste à cet horodatage de protection.",
+ "apihelp-query+protectedtitles-param-prop": "Quelles propriétés obtenir :\n;timestamp:Ajoute l’horodatage de l’ajout de la protection.\n;user:Ajoute l’utilisateur ayant ajouté la protection.\n;userid:Ajoute l’ID de l’utilisateur ayant ajouté la protection.\n;comment:Ajoute le commentaire de la protection.\n;parsedcomment:Ajoute le commentaire analysé de la protection.\n;expiry:Ajoute l’horodatage de levée de la protection.\n;level:Ajoute le niveau de protection.",
+ "apihelp-query+protectedtitles-example-simple": "Lister les titres protégés",
+ "apihelp-query+protectedtitles-example-generator": "Trouver les liens vers les titres protégés dans l’espace de noms principal",
+ "apihelp-query+querypage-description": "Obtenir une liste fournie par une page spéciale basée sur QueryPage",
+ "apihelp-query+querypage-param-page": "Le nom de la page spéciale. Remarque, ce nom est sensible à la casse.",
+ "apihelp-query+querypage-param-limit": "Nombre de résultats à renvoyer.",
+ "apihelp-query+querypage-example-ancientpages": "Renvoyer les résultats de [[Special:Ancientpages]].",
+ "apihelp-query+random-description": "Obtenir un ensemble de pages au hasard.\n\nLes pages sont listées dans un ordre prédéterminé, seul le point de départ est aléatoire. Par exemple, cela signifie que si la première page dans la liste est <samp>Accueil</samp>, la seconde sera <em>toujours</em> <samp>Liste des singes de fiction</samp>, la troisième <samp>Liste de personnes figurant sur les timbres de Vanuatu</samp>, etc.\n\nSi le nombre de page dans l’espace de nom est inférieur à <var>$1limit</var>, moins de pages seront renvoyées. La même page ne sera jamais renvoyée deux fois.",
+ "apihelp-query+random-param-namespace": "Renvoyer seulement des pages de ces espaces de noms.",
+ "apihelp-query+random-param-limit": "Limite sur le nombre de pages aléatoires renvoyées.",
+ "apihelp-query+random-param-redirect": "Charger une redirection aléatoire plutôt qu’une page aléatoire.",
+ "apihelp-query+random-example-simple": "Obtenir deux pages aléatoires de l’espace principal",
+ "apihelp-query+random-example-generator": "Renvoyer les informations de la page sur deux pages au hasard de l’espace de noms principal",
+ "apihelp-query+recentchanges-description": "Énumérer les modifications récentes.",
+ "apihelp-query+recentchanges-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+recentchanges-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+recentchanges-param-namespace": "Filtrer les modifications uniquement sur ces espaces de nom.",
+ "apihelp-query+recentchanges-param-user": "Lister uniquement les modifications par cet utilisateur.",
+ "apihelp-query+recentchanges-param-excludeuser": "Ne pas lister les modifications par cet utilisateur.",
+ "apihelp-query+recentchanges-param-tag": "Lister uniquement les modifications marquées avec cette balise.",
+ "apihelp-query+recentchanges-param-prop": "Inclure des informations supplémentaires :\n;user:Ajoute l’utilisateur responsable de la modification et marque si c’est une adresse IP.\n;userid:Ajoute l’ID de l’utilisateur responsable de la modification.\n;comment:Ajoute le commentaire de la modification.\n;parsedcomment:Ajoute le commentaire analysé pour la modification.\n;flags:Ajoute les balises de la modification.\n;timestamp:Ajoute l’horodatage de la modification.\n;title:Ajoute le titre de la page modifiée.\n;ids:Ajoute l’ID de la page, l’ID des modifications récentes et l’ID de l’ancienne et la nouvelle révisions.\n;sizes:Ajoute l’ancienne et la nouvelle tailles de la page en octets.\n;redirect:Marque la modification si la page est une redirection.\n;patrolled:Marque les modifications patrouillables comme patrouillées ou non.\n;loginfo:Ajoute les informations du journal (Id du journal, type de trace, etc.) aux entrées du journal.\n;tags:Liste les balises de l’entrée.\n;sha1:Ajoute la somme de contrôle du contenu pour les entrées associées à une révision.",
+ "apihelp-query+recentchanges-param-token": "Utiliser plutôt <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+ "apihelp-query+recentchanges-param-show": "Afficher uniquement les éléments correspondant à ces critères. Par exemple, pour voir uniquement les modifications mineures par des utilisateurs connectés, mettre $1show=minor|!anon.",
+ "apihelp-query+recentchanges-param-limit": "Combien de modifications renvoyer au total.",
+ "apihelp-query+recentchanges-param-type": "Quels types de modification afficher.",
+ "apihelp-query+recentchanges-param-toponly": "Lister uniquement les modifications qui sont de la dernière révision.",
+ "apihelp-query+recentchanges-example-simple": "Lister les modifications récentes",
+ "apihelp-query+recentchanges-example-generator": "Obtenir l’information de page sur les modifications récentes non patrouillées",
+ "apihelp-query+redirects-description": "Renvoie toutes les redirections vers les pages données.",
+ "apihelp-query+redirects-param-prop": "Quelles propriétés récupérer :\n;pageid:ID de page de chaque redirection.\n;title:Titre de chaque redirection.\n;fragment:Fragment de chaque redirection, s’il y en a un.",
+ "apihelp-query+redirects-param-namespace": "Inclure uniquement les pages dans ces espaces de nom.",
+ "apihelp-query+redirects-param-limit": "Combien de redirections renvoyer.",
+ "apihelp-query+redirects-param-show": "Afficher uniquement les éléments correspondant à ces critères :\n;fragment:Afficher uniquement les redirections avec un fragment.\n;!fragment:Afficher uniquement les redirections sans fragment.",
+ "apihelp-query+redirects-example-simple": "Obtenir une liste des redirections vers [[Main Page]]",
+ "apihelp-query+redirects-example-generator": "Obtenir des informations sur toutes les redirections vers [[Main Page]]",
+ "apihelp-query+revisions-description": "Obtenir des informations sur la révision.\n\nPeut être utilisé de différentes manières :\n# Obtenir des données sur un ensemble de pages (dernière révision), en mettant les titres ou les ids de page.\n# Obtenir les révisions d’une page donnée, en utilisant les titres ou les ids de page avec début, fin ou limite.\n# Obtenir des données sur un ensemble de révisions en donnant leurs IDs et leurs ids de révision.",
+ "apihelp-query+revisions-paraminfo-singlepageonly": "Utilisable uniquement avec une seule page (mode #2).",
+ "apihelp-query+revisions-param-startid": "À quel ID de révision démarrer l’énumération.",
+ "apihelp-query+revisions-param-endid": "Arrêter l’énumération des révisions à cet ID.",
+ "apihelp-query+revisions-param-start": "À quel horodatage de révision démarrer l’énumération.",
+ "apihelp-query+revisions-param-end": "Énumérer jusqu’à cet horodatage.",
+ "apihelp-query+revisions-param-user": "Inclure uniquement les révisions faites par l’utilisateur.",
+ "apihelp-query+revisions-param-excludeuser": "Exclure les révisions faites par l’utilisateur.",
+ "apihelp-query+revisions-param-tag": "Lister uniquement les révisions marquées avec cette balise.",
+ "apihelp-query+revisions-param-token": "Quels jetons obtenir pour chaque révision.",
+ "apihelp-query+revisions-example-content": "Obtenir des données avec le contenu pour la dernière révision des titres <kbd>API</kbd> et <kbd>Page principale</kbd>.",
+ "apihelp-query+revisions-example-last5": "Obtenir les 5 dernières révisions de la <kbd>Main Page</kbd>.",
+ "apihelp-query+revisions-example-first5": "Obtenir les 5 premières révisions de la <kbd>Page principale</kbd>.",
+ "apihelp-query+revisions-example-first5-after": "Obtenir les 5 premières révisions de la <kbd>Page principale</kbd> faites après le 01/05/2006.",
+ "apihelp-query+revisions-example-first5-not-localhost": "Obtenir les 5 premières révisions de la <kbd>Page principale</kbd> qui n’ont pas été faites par l’utilisateur anonyme <kbd>127.0.0.1</kbd>.",
+ "apihelp-query+revisions-example-first5-user": "Obtenir les 5 premières révisions de la <kbd>Page principale</kbd> qui ont été faites par l’utilisateur <kbd>MédiaWiki par défaut</kbd>.",
+ "apihelp-query+revisions+base-param-prop": "Quelles propriétés obtenir pour chaque révision :\n;ids:L’ID de la révision.\n;flags:Marques de la révision (mineure).\n;timestamp:L’horodatage de la révision.\n;user:Utilisateur ayant fait la révision.\n;userid:ID de l’utilisateur ayant créé la révision.\n;size:Taille (en octets) de la révision.\n;sha1:SHA-1 (base 16) de la révision.\n;contentmodel:ID du modèle de contenu de la révision.\n;comment:Commentaire par l’utilisateur de la révision.\n;parsedcomment:Commentaire analysé par l’utilisateur de la révision.\n;content:Texte de la révision.\n;tags:Balises de la révision.",
+ "apihelp-query+revisions+base-param-limit": "Limiter le nombre de révisions retournées.",
+ "apihelp-query+revisions+base-param-expandtemplates": "Développer les modèles dans le contenu de la révision (nécessite $1prop=content).",
+ "apihelp-query+revisions+base-param-generatexml": "Générer l’arbre d’analyse XML pour le contenu de la révision (nécessite $1prop=content).",
+ "apihelp-query+revisions+base-param-parse": "Analyser le contenu de la révision (nécessite $1prop=content). Pour des raisons de performance, si cette option est utilisée, $1limit est forcé à 1.",
+ "apihelp-query+revisions+base-param-section": "Récupérer uniquement le contenu de ce numéro de section.",
+ "apihelp-query+revisions+base-param-diffto": "ID de révision à comparer à chaque révision. Utiliser <kbd>prev</kbd>, <kbd>next</kbd> et <kbd>cur</kbd> pour la version précédente, suivante et actuelle respectivement.",
+ "apihelp-query+revisions+base-param-difftotext": "Texte auquel comparer chaque révision. Compare uniquement un nombre limité de révisions. Écrase <var>$1diffto</var>. Si <var>$1section</var> est positionné, seule cette section sera comparée avec ce texte",
+ "apihelp-query+revisions+base-param-contentformat": "Format de sérialisation utilisé pour <var>$1difftotext</var> et attendu pour la sortie du contenu.",
+ "apihelp-query+search-description": "Effectuer une recherche en texte intégral.",
+ "apihelp-query+search-param-search": "Rechercher les titres (ou le contenu) de toutes les pages ayant cette valeur.",
+ "apihelp-query+search-param-namespace": "Rechercher uniquement dans ces espaces de nom.",
+ "apihelp-query+search-param-what": "Quel type de recherche effectuer.",
+ "apihelp-query+search-param-info": "Quelles métadonnées renvoyer.",
+ "apihelp-query+search-param-prop": "Quelles propriétés renvoyer :\n;size:Ajoute la taille de la page en octets.\n;wordcount:Ajoute le nombre de mots de la page.\n;timestamp:Ajoute l’horodatage de la dernière modification de la page.\n;snippet:Ajoute un extrait analysé de la page.\n;titlesnippet:Ajoute un extrait analysé du titre de la page.\n;redirectsnippet:Ajoute un extrait analysé du titre de la redirection.\n;redirecttitle:Ajoute le titre de la redirection correspondante.\n;sectionsnippet:Ajoute un extrait analysé du titre de la section correspondante.\n;sectiontitle:Ajoute le titre de la section correspondante.\n;score:<span class=\"apihelp-deprecated\">Obsolète et ignoré.</span>\n;hasrelated:<span class=\"apihelp-deprecated\">Obsolète et ignoré.</span>",
+ "apihelp-query+search-param-limit": "Combien de pages renvoyer au total.",
+ "apihelp-query+search-param-interwiki": "Inclure les résultats interwiki dans la recherche, s’ils sont disponibles.",
+ "apihelp-query+search-param-backend": "Quel serveur de recherche utiliser, si ce n’est pas celui par défaut.",
+ "apihelp-query+search-example-simple": "Rechercher <kbd>signification </kbd>.",
+ "apihelp-query+search-example-text": "Rechercher des textes pour <kbd>signification</kbd>.",
+ "apihelp-query+search-example-generator": "Obtenir les informations sur les pages renvoyées par une recherche de <kbd>signification</kbd>.",
+ "apihelp-query+siteinfo-description": "Renvoyer les informations générales sur le site.",
+ "apihelp-query+siteinfo-param-prop": "Quelles informations obtenir :\n;general:Information globale du système.\n;namespaces:Liste des espaces de nom déclarés et leur nom canonique.\n;namespacealiases:Liste des alias des espaces de nom déclarés.\n;specialpagealiases:Liste des alias des pages spéciales.\n;magicwords:Liste des mots magiques et leurs alias.\n;statistics:Renvoie les statistiques du site.\n;interwikimap:Renvoie la correspondance interwiki (éventuellement filtrée, éventuellement localisée en utilisant <var>$1inlanguagecode</var>).\n;dbrepllag:Renvoie le serveur de base de donnée avec la plus grande latence de réplication.\n;usergroups:Renvoie les groupes utilisateur et les droits associés.\n;libraries:Renvoie les bibliothèques installées sur le wiki.\n;extensions:Renvoie les extensions installées sur le wiki.\n;fileextensions:Renvoie la liste des extensions de fichier autorisées au téléchargement.\n;rightsinfo:Renvoie l’information sur les droits du wiki (sa licence), si elle est disponible.\n;restrictions:Renvoie l’information sur les types de restriction disponibles (protection).\n;languages:Renvoie une liste des langues que supporte MédiaWiki (éventuellement localisé en utilisant <var>$1inlanguagecode</var>).\n;skins:Renvoie une liste de tous les habillages activés (éventuellement localisé en utilisant <var>$1inlanguagecode</var>, sinon dans la langue du contenu).\n;extensiontags:Renvoie une liste des balises d’extension de l’analyseur.\n;functionhooks:Renvoie une liste des accroches de fonction de l’analyseur.\n;showhooks:Renvoie une liste de toutes les accroches souscrites (contenu de <var>[[mw:Manual:$wgHooks|$wgHooks]]</var>).\n;variables:Renvoie une liste des IDs de variable.\n;protocols:Renvoie une liste des protocoles qui sont autorisés dans les liens externes.\n;defaultoptions:Renvoie les valeurs par défaut pour les préférences utilisateur.",
+ "apihelp-query+siteinfo-param-filteriw": "Renvoyer uniquement les entrées locales ou uniquement les non locales de la correspondance interwiki.",
+ "apihelp-query+siteinfo-param-showalldb": "Lister tous les serveurs de base de données, pas seulement celui avec la plus grande latence.",
+ "apihelp-query+siteinfo-param-numberingroup": "Liste le nombre d’utilisateurs dans les groupes.",
+ "apihelp-query+siteinfo-param-inlanguagecode": "Code de langue pour les noms de langue localisés (du mieux possible) et les noms d’habillage.",
+ "apihelp-query+siteinfo-example-simple": "Extraire les informations du site",
+ "apihelp-query+siteinfo-example-interwiki": "Extraire une liste des préfixes interwiki locaux",
+ "apihelp-query+siteinfo-example-replag": "Vérifier la latence de réplication actuelle",
+ "apihelp-query+stashimageinfo-description": "Renvoie les informations de fichier des fichiers mis en réserve.",
+ "apihelp-query+stashimageinfo-param-filekey": "Clé qui identifie un téléchargement précédent qui a été temporairement mis en réserve.",
+ "apihelp-query+stashimageinfo-param-sessionkey": "Alias pour $1filekey, pour la compatibilité descendante.",
+ "apihelp-query+stashimageinfo-example-simple": "Renvoie les informations sur un fichier mis en réserve.",
+ "apihelp-query+stashimageinfo-example-params": "Renvoie les vignettes pour deux fichiers mis en réserve",
+ "apihelp-query+tags-description": "Lister les balises de modification.",
+ "apihelp-query+tags-param-limit": "Le nombre maximal de balises à lister.",
+ "apihelp-query+tags-param-prop": "Quelles propriétés récupérer :\n;name:Ajoute le nom de la balise.\n;displayname:Ajoute le message système pour la balise.\n;description:Ajoute la description de la balise.\n;hitcount:Ajoute le nombre de révisions et d’entrées du journal qui ont cette balise.\n;defined:Indique si la balise est définie.\n;source:Obtient les sources de la balise, ce qui comprend <samp>extension</samp> pour les balises définies par une extension et <samp>manual</samp> pour les balises pouvant être appliquées manuellement par les utilisateurs.\n;active:Si la balise est encore appliquée.",
+ "apihelp-query+tags-example-simple": "Lister les balises disponibles",
+ "apihelp-query+templates-description": "Renvoie toutes les pages incluses dans les pages fournies.",
+ "apihelp-query+templates-param-namespace": "Afficher les modèles uniquement dans ces espaces de nom.",
+ "apihelp-query+templates-param-limit": "Combien de modèles renvoyer.",
+ "apihelp-query+templates-param-templates": "Lister uniquement ces modèles. Utile pour vérifier si une certaine page utilise un modèle donné.",
+ "apihelp-query+templates-param-dir": "La direction dans laquelle lister.",
+ "apihelp-query+templates-example-simple": "Obtenir les modèles utilisés sur la page <kbd>Accueil</kbd>.",
+ "apihelp-query+templates-example-generator": "Obtenir des informations sur les pages modèle utilisé sur <kbd>Main Page</kbd>.",
+ "apihelp-query+templates-example-namespaces": "Obtenir les pages des espaces de nom {{ns:user}} et {{ns:template}} qui sont inclues dans la page <kdb>Main Page<kdb>.",
+ "apihelp-query+tokens-description": "Récupère les jetons pour les actions de modification de données.",
+ "apihelp-query+tokens-param-type": "Types de jeton à demander.",
+ "apihelp-query+tokens-example-simple": "Récupérer un jeton csrf (par défaut)",
+ "apihelp-query+tokens-example-types": "Récupérer un jeton de suivi et un de patrouille",
+ "apihelp-query+transcludedin-description": "Trouver toutes les pages qui incluent les pages données.",
+ "apihelp-query+transcludedin-param-prop": "Quelles propriétés obtenir :\n;pageid:ID de page de chaque page.\n;title:Titre de chaque page.\n;redirect:Marque si cette page est une redirection.",
+ "apihelp-query+transcludedin-param-namespace": "Inclure uniquement les pages dans ces espaces de nom.",
+ "apihelp-query+transcludedin-param-limit": "Combien en renvoyer.",
+ "apihelp-query+transcludedin-param-show": "Afficher uniquement les éléments qui correspondent à ces critères:\n;redirect:Afficher uniquement les redirections.\n;!redirect:Afficher uniquement les non-redirections.",
+ "apihelp-query+transcludedin-example-simple": "Obtenir une liste des pages incluant <kbd>Main Page</kbd>.",
+ "apihelp-query+transcludedin-example-generator": "Obtenir des informations sur les pages incluant <kbd>Main Page</kbd>.",
+ "apihelp-query+usercontribs-description": "Obtenir toutes les modifications par un utilisateur.",
+ "apihelp-query+usercontribs-param-limit": "Le nombre maximal de contributions à renvoyer.",
+ "apihelp-query+usercontribs-param-start": "L’horodatage auquel démarrer le retour.",
+ "apihelp-query+usercontribs-param-end": "L’horodatage auquel arrêter le retour.",
+ "apihelp-query+usercontribs-param-user": "Les utilisateurs pour lesquels récupérer les contributions.",
+ "apihelp-query+usercontribs-param-userprefix": "Récupérer les contributions pour tous les utilisateurs dont les noms commencent par cette valeur. Écrase $1user.",
+ "apihelp-query+usercontribs-param-namespace": "Lister uniquement les contributions dans ces espaces de nom.",
+ "apihelp-query+usercontribs-param-prop": "Inclure des informations supplémentaires:\n;ids:Ajoute l’ID de page et l’ID de révision.\n;title:Ajoute le titre et l’ID d’espace de noms de la page.\n;timestamp:Ajoute l’horodatage de la modification.\n;comment:Ajoute le commentaire de la modification.\n;parsedcomment:Ajoute le commentaire analysé de la modification.\n;size:Ajoute la nouvelle taille de la modification.\n;sizediff:Ajoute le delta de taille de la modification par rapport à son parent.\n;flags:Ajoute les marques de la modification.\n;patrolled:Marque les modifications patrouillées.\n;tags:Liste les balises de la modification.",
+ "apihelp-query+usercontribs-param-show": "Afficher uniquement les éléments correspondant à ces critères, par ex. les modifications non mineures uniquement : <kbd>$2show=!minor</kbd>.\n\nSi <kbd>$2show=patrolled</kbd> ou <kbd>$2show=!patrolled</kbd> est positionné, les révisions plus anciennes que <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|seconde|secondes}}) ne seront pas affichées.",
+ "apihelp-query+usercontribs-param-tag": "Lister uniquement les révisions marquées avec cette balise.",
+ "apihelp-query+usercontribs-param-toponly": "Lister uniquement les modifications qui sont la dernière révision.",
+ "apihelp-query+usercontribs-example-user": "Afficher les contributions de l'utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-query+usercontribs-example-ipprefix": "Afficher les contributions de toutes les adresses IP avec le préfixe <kbd>192.0.2.</kbd>.",
+ "apihelp-query+userinfo-description": "Obtenir de l’information sur l’utilisateur courant.",
+ "apihelp-query+userinfo-param-prop": "Quelles informations inclure :\n;blockinfo:Marque si l’utilisateur actuel est bloqué, par qui, et pour quelle raison.\n;hasmsg:Ajoute une balise <samp>message</samp> si l’utilisateur actuel a des messages en cours.\n;groups:Liste tous les groupes auxquels appartient l’utilisateur actuel.\n;implicitgroups:Liste tous les groupes dont l’utilisateur actuel est automatiquement membre.\n;rights:Liste tous les droits qu’a l’utilisateur actuel.\n;changeablegroups:Liste les groupes pour lesquels l’utilisateur actuel peut ajouter ou supprimer.\n;options:Liste toutes les préférences qu’a défini l’utilisateur actuel.\n;preferencestoken:<span class=\"apihelp-deprecated\">Obsolete.</span> Obtient un jeton pour modifier les préférences de l’utilisateur actuel.\n;editcount:Ajoute le compteur de modifications de l’utilisateur actuel.\n;ratelimits:Liste toutes les limites de débit s’appliquant à l’utilisateur actuel.\n;realname:Ajoute le vrai nom de l’utilisateur actuel.\n;email:Ajoute l’adresse de courriel de l’utilisateur et sa date d’authentification.\n;acceptlang:Renvoie en écho l’entête <code>Accept-Language</code> envoyé par le client dans un format structuré.\n;registrationdate:Ajoute la date d’inscription de l’utilisateur.\n;unreadcount:Ajoute le compteur de pages non lues de la liste de suivi de l’utilisateur (au maximum $1 ; renvoie <samp>$2</samp> s’il y en a plus).",
+ "apihelp-query+userinfo-example-simple": "Obtenir de l’information sur l’utilisateur actuel",
+ "apihelp-query+userinfo-example-data": "Obtenir des informations supplémentaires sur l’utilisateur actuel",
+ "apihelp-query+users-description": "Obtenir des information sur une liste d’utilisateurs",
+ "apihelp-query+users-param-prop": "Quelles informations inclure :\n;blockinfo:Marque si l’utilisateur est bloqué, par qui, et pour quelle raison.\n;groups:Liste tous les groupes auquel appartient chaque utilisateur.\n;implicitgroups:Liste tous les groupes dont un utilisateur est automatiquement membre.\n;rights:Liste tous les droits qu’a un utilisateur.\n;editcount:Ajoute le compteur de modifications de l’utilisateur.\n;registration:Ajoute l’horodatage d’inscription de l’utilisateur.\n;emailable:Marque si l’utilisateur peut et veut recevoir des courriels via [[Special:Emailuser]].\n;gender:Marque le sexe de l’utilisateur. Renvoie « male », « female », ou « unknown ».",
+ "apihelp-query+users-param-users": "Une liste des utilisateurs sur lesquels obtenir de l’information.",
+ "apihelp-query+users-param-token": "Utiliser plutôt <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+ "apihelp-query+users-example-simple": "Renvoyer des informations pour l'utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-query+watchlist-description": "Obtenir les modifications récentes des pages dans la liste de suivi de l’utilisateur actuel.",
+ "apihelp-query+watchlist-param-allrev": "Inclure les multiples révisions de la même page dans l’intervalle de temps fourni.",
+ "apihelp-query+watchlist-param-start": "L’horodatage auquel démarrer l’énumération.",
+ "apihelp-query+watchlist-param-end": "L’horodatage auquel arrêter l’énumération.",
+ "apihelp-query+watchlist-param-namespace": "Filtrer les modifications aux seuls espaces de nom fournis.",
+ "apihelp-query+watchlist-param-user": "Lister uniquement les modifications par cet utilisateur.",
+ "apihelp-query+watchlist-param-excludeuser": "Ne pas lister les modifications faites par cet utilisateur.",
+ "apihelp-query+watchlist-param-limit": "Combien de résultats au total renvoyer par demande.",
+ "apihelp-query+watchlist-param-prop": "Quels éléments supplémentaires obtenir :\n;ids:Ajoute les IDs de révision et de page.\n;title:Ajoute le titre de la page.\n;flags:Ajoute les marques de la modification.\n;user:Ajoute l’utilisateur ayant fait la modification.\n;userid:Ajoute l’ID de l’utilisateur ayant fait la modification.\n;comment:Ajoute le commentaire de la modification.\n;parsedcomment:Ajoute le commentaire analysé de la modification.\n;timestamp:Ajoute l’horodatage de la modification.\n;patrol:Marque les modifications patrouillées.\n;sizes:Ajoute les ancienne et nouvelle tailles de la page.\n;notificationtimestamp:Ajoute l’horodatage de quand l’utilisateur a été notifié de la modification la dernière fois.\n;loginfo:Ajoute l’information du journal quand c’est approprié.",
+ "apihelp-query+watchlist-param-show": "Afficher uniquement les éléments qui correspondent à ces critères. Par exemple, pour voir uniquement les modifications mineures faites par des utilisateurs connectés, mettre $1show=minor|!anon.",
+ "apihelp-query+watchlist-param-type": "Quels types de modification afficher :\n;edit:Modifications de page normale.\n;external:Modifications externes.\n;new:Créations de page.\n;log:Entrées du journal.",
+ "apihelp-query+watchlist-param-owner": "Utilisé avec $1token pour accéder à la liste de suivi d’un autre utilisateur.",
+ "apihelp-query+watchlist-param-token": "Un jeton de sécurité (disponible dans les [[Special:Preferences#mw-prefsection-watchlist|préférences]] de l’utilsiateur) pour autoriser l’accès à la liste de suivi d&un autre utilisateur.",
+ "apihelp-query+watchlist-example-simple": "Lister la révision de tête des pages récemment modifiées dans la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlist-example-props": "Chercher des informations supplémentaires sur la révision de tête des pages récemment modifiées de la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlist-example-allrev": "Chercher les informations sur toutes les modifications récentes des pages de la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlist-example-generator": "Chercher l’information de la page sur les pages récemment modifiées de la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlist-example-generator-rev": "Chercher l’information de la révision pour les modifications récentes des pages de la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlist-example-wlowner": "Lister la révision de tête des pages récemment modifiées de la liste de suivi de l'utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-query+watchlistraw-description": "Obtenir toutes les pages de la liste de suivi de l’utilisateur actuel.",
+ "apihelp-query+watchlistraw-param-namespace": "Lister uniquement les pages dans les espaces de nom fournis.",
+ "apihelp-query+watchlistraw-param-limit": "Combien de résultats renvoyer au total par requête.",
+ "apihelp-query+watchlistraw-param-prop": "Quelles propriétés supplémentaires obtenir :\n;changed:Ajoute l’horodatage de la dernière notification de l’utilisateur à propos de la modification.",
+ "apihelp-query+watchlistraw-param-show": "Lister uniquement les éléments correspondant à ces critères.",
+ "apihelp-query+watchlistraw-param-owner": "Utilisé avec $1token pour accéder à la liste de suivi d’un autre utilisateur.",
+ "apihelp-query+watchlistraw-param-token": "Un jeton de sécurité (disponible dans les [[Special:Preferences#mw-prefsection-watchlist|préférences]] de l’utilisateur) pour permettre l’accès à la liste de suivi d’un autre utilisateur.",
+ "apihelp-query+watchlistraw-example-simple": "Lister les pages dans la liste de suivi de l’utilisateur actuel",
+ "apihelp-query+watchlistraw-example-generator": "Chercher l’information sur les pages de la liste de suivi de l’utilisateur actuel",
+ "apihelp-revisiondelete-description": "Supprimer et annuler la suppression des révisions.",
+ "apihelp-revisiondelete-param-type": "Type de suppression de révision en cours de traitement.",
+ "apihelp-revisiondelete-param-target": "Titre de page pour la suppression de révision, s’il est nécessaire pour le type.",
+ "apihelp-revisiondelete-param-ids": "Identifiants pour les révisions à supprimer.",
+ "apihelp-revisiondelete-param-hide": "Quoi masquer pour chaque révision.",
+ "apihelp-revisiondelete-param-show": "Quoi démasquer pour chaque révision",
+ "apihelp-revisiondelete-param-suppress": "S’il faut supprimer les données aux administrateurs comme aux autres.",
+ "apihelp-revisiondelete-param-reason": "Motif de suppression ou d’annulation de suppression.",
+ "apihelp-revisiondelete-example-revision": "Masquer le contenu de la révision <kbd>12345</kbd> de la page <kbd>Main Page</kbd>",
+ "apihelp-revisiondelete-example-log": "Masquer toutes les données de l’entrée de journal <kbd>67890</kbd> avec le motif <kbd>Violation de Biographie de Personne Vivante</kbd>.",
+ "apihelp-rollback-description": "Annuler la dernière modification de la page.\n\nSi le dernier utilisateur à avoir modifié la page a fait plusieurs modifications sur une ligne, elles seront toutes annulées.",
+ "apihelp-rollback-param-title": "Titre de la page à restaurer. Impossible à utiliser avec <var>$1pageid</var>.",
+ "apihelp-rollback-param-pageid": "ID de la page à restaurer. Impossible à utiliser avec <var>$1title</var>.",
+ "apihelp-rollback-param-user": "Nom de l’utilisateur dont les modifications doivent être annulées.",
+ "apihelp-rollback-param-summary": "Personnaliser le résumé de la modification. S’il est vide, le résumé par défaut sera utilisé.",
+ "apihelp-rollback-param-markbot": "Marquer les modifications annulées et les modifications annulées comme robot.",
+ "apihelp-rollback-param-watchlist": "Ajouter ou supprimer la page de la liste de suivi de l’utilisateur actuel sans condition, utiliser les préférences ou ne pas modifier le suivi.",
+ "apihelp-rollback-example-simple": "Annuler les dernières modifications à [<kbd>Main Page</kbd> par l’utilisateur <kbd>Exemple</kbd>.",
+ "apihelp-rollback-example-summary": "Annuler les dernières modifications de la page <kbd>Main Page</kbd> par l’utilisateur à l’adresse IP <kbd>192.0.2.5</kbd> avec le résumé <kbd>Annulation de vandalisme<kbd>, et marquer ces modifications et l’annulation comme modifications de robots.",
+ "apihelp-rsd-description": "Exporter un schéma RSD (Découverte Très Simple).",
+ "apihelp-rsd-example-simple": "Exporter le schéma RSD",
+ "apihelp-setnotificationtimestamp-description": "Mettre à jour l’horodatage de notification pour les pages suivies.\n\nCela affecte la mise en évidence des pages modifiées dans la liste de suivi et l’historique, et l’envoi de courriel quand la préférence « M’envoyer un courriel quand une page de ma liste de suivi est modifiée » est activée.",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "Travailler sur toutes les pages suivies.",
+ "apihelp-setnotificationtimestamp-param-timestamp": "Horodatage auquel dater la notification.",
+ "apihelp-setnotificationtimestamp-param-torevid": "Révision pour laquelle fixer l’horodatage de notification (une page uniquement).",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "Révision pour fixer l’horodatage de notification plus récent (une page uniquement).",
+ "apihelp-setnotificationtimestamp-example-all": "Réinitialiser l’état de notification pour toute la liste de suivi",
+ "apihelp-setnotificationtimestamp-example-page": "Réinitialiser l’état de notification pour la <kbd>Page principale<kbd>.",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "Fixer l’horodatage de notification pour <kbd>Page principale</kbd> afin que toutes les modifications depuis le 1 janvier 2012 soient non vues",
+ "apihelp-setnotificationtimestamp-example-allpages": "Réinitialiser l’état de notification sur les pages dans l’espace de noms <kbd>{{ns:user}}</kbd>.",
+ "apihelp-tokens-description": "Obtenir les jetons pour les actions modifiant les données.\n\nCe module est obsolète, remplacé par [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-tokens-param-type": "Types de jeton à demander.",
+ "apihelp-tokens-example-edit": "Récupérer un jeton de modification (par défaut).",
+ "apihelp-tokens-example-emailmove": "Récupérer un jeton de courriel et un jeton de déplacement.",
+ "apihelp-unblock-description": "Débloquer un utilisateur.",
+ "apihelp-unblock-param-id": "ID du blocage à lever (obtenu via <kbd>list=blocks</kbd>). Impossible à utiliser avec <var>$1user</var>.",
+ "apihelp-unblock-param-user": "Nom d’utilisateur, adresse IP ou plage d’adresse IP à débloquer. Impossible à utiliser avec <var>$1id</var>.",
+ "apihelp-unblock-param-reason": "Motif de déblocage.",
+ "apihelp-unblock-example-id": "Lever le blocage d’ID #<kbd>105</kbd>.",
+ "apihelp-unblock-example-user": "Débloquer l’utilisateur <kbd>Bob</kbd> avec le motif <kbd>Désolé Bob</kbd>.",
+ "apihelp-undelete-description": "Restaurer les révisions d’une page supprimée.\n\nUne liste des révisions supprimées (avec les horodatages) peut être récupérée via [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]], et une liste d’IDs de fichier supprimé peut être récupérée via [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+ "apihelp-undelete-param-title": "Titre de la page à restaurer.",
+ "apihelp-undelete-param-reason": "Motif de restauration.",
+ "apihelp-undelete-param-timestamps": "Horodatages des révisions à restaurer. Si <var>$1timestamps</var> et <var>$1fileids</var> sont vides, toutes seront restaurées.",
+ "apihelp-undelete-param-fileids": "IDs des révisions de fichier à restaurer. Si <var>$1timestamps</var> et <var>$1fileids</var> sont vides, toutes seront restaurées.",
+ "apihelp-undelete-param-watchlist": "Ajouter ou supprimer la page de la liste de suivi de l’utilisateur actuel sans condition, utiliser les préférences ou ne pas modifier le suivi.",
+ "apihelp-undelete-example-page": "Annuler la suppression de la page <kbd>Main Page</kbd>.",
+ "apihelp-undelete-example-revisions": "Annuler la suppression de deux révisions de la page <kbd>Main Page</kbd>.",
+ "apihelp-upload-description": "Télécharger un fichier, ou obtenir l’état des téléchargements en cours.\n\nPlusieurs méthodes sont disponibles :\n* Télécharger directement le contenu du fichier, en utilisant le paramètre <var>$1file</var>.\n* Télécharger le fichier par morceaux, en utilsiant les paramètres <var>$1filesize</var>, <var>$1chunk</var>, and <var>$1offset</var>.* Pour que le serveur MédiaWiki cherche un fichier depuis une URL, utiliser le paramètre <var>$1url</var>.\n* Terminer un téléchargement précédent qui a échoué à cause d’avertissements, en utilisant le paramètre <var>$1filekey</var>.\nNoter que le POST HTTP doit être fait comme un téléchargement de fichier (par ex. en utilisant <code>multipart/form-data</code>) en envoyant le <code>multipart/form-data</code>.",
+ "apihelp-upload-param-filename": "Nom de fichier cible.",
+ "apihelp-upload-param-comment": "Télécharger le commentaire. Utilisé aussi comme texte de la page initiale pour les nouveaux fichiers si <var>$1text</var> n’est pas spécifié.",
+ "apihelp-upload-param-text": "Texte de page initiale pour les nouveaux fichiers.",
+ "apihelp-upload-param-watch": "Suivre la page.",
+ "apihelp-upload-param-watchlist": "Ajouter ou supprimer sans condition la page de la liste de suivi de l’utilisateur actuel, utiliser les préférences ou ne pas changer le suivi.",
+ "apihelp-upload-param-ignorewarnings": "Ignorer tous les avertissements.",
+ "apihelp-upload-param-file": "Contenu du fichier.",
+ "apihelp-upload-param-url": "URL où chercher le fichier.",
+ "apihelp-upload-param-filekey": "Clé identifiant un téléchargement précédent temporairement mis en attente.",
+ "apihelp-upload-param-sessionkey": "Comme $1filekey, conservé pour des raisons de compatibilité descendante.",
+ "apihelp-upload-param-stash": "Si positionné, le serveur conservera temporairement le fichier au lieu de l’ajouter au dépôt.",
+ "apihelp-upload-param-filesize": "Taille du fichier de tout le téléchargement.",
+ "apihelp-upload-param-offset": "Décalage du bloc en octets.",
+ "apihelp-upload-param-chunk": "Partie du contenu.",
+ "apihelp-upload-param-async": "Faire de façon asynchrone les grosses opérations sur les fichiers quand c’est possible.",
+ "apihelp-upload-param-asyncdownload": "Faire de façon asynchrone la recherche d’une URL.",
+ "apihelp-upload-param-leavemessage": "Si asyncdownload est utilisé, laisser un message sur la page de discussion de l’utilisateur quand c’est terminé.",
+ "apihelp-upload-param-statuskey": "Récupérer l’état de téléchargement pour cette clé de fichier (téléchargé par URL).",
+ "apihelp-upload-param-checkstatus": "Récupérer uniquement l’état de téléchargement pour la clé de fichier donnée.",
+ "apihelp-upload-example-url": "Télécharger depuis une URL",
+ "apihelp-upload-example-filekey": "Terminer un téléchargement qui a échoué à cause d’avertissements",
+ "apihelp-userrights-description": "Modifier l’appartenance d’un utilisateur à un groupe.",
+ "apihelp-userrights-param-user": "Nom d’utilisateur.",
+ "apihelp-userrights-param-userid": "ID de l’utilisateur.",
+ "apihelp-userrights-param-add": "Ajouter l’utilisateur à ces groupes.",
+ "apihelp-userrights-param-remove": "Supprimer l’utilisateur de ces groupes.",
+ "apihelp-userrights-param-reason": "Motif pour la modification.",
+ "apihelp-userrights-example-user": "Ajouter l’utilisateur <kbd>FooBot</kbd> au groupe <kbd>robot</kbd>, et le supprimer des groupes <kbd>sysop</kbd> et <kbd>bureaucrate</kbd>.",
+ "apihelp-userrights-example-userid": "Ajouter l’utilisateur d’ID <kbd>123</kbd> au groupe <kbd>robot</kbd>, et le supprimer des groupes <kbd>sysop</kbd> et <kbd>bureaucrate</kbd>.",
+ "apihelp-watch-description": "Ajouter ou supprimer des pages de la liste de suivi de l’utilisateur actuel.",
+ "apihelp-watch-param-title": "La page à (ne plus) suivre. Utiliser plutôt <var>$1titles</var>.",
+ "apihelp-watch-param-unwatch": "Si défini, la page ne sera plus suivie plutôt que suivie.",
+ "apihelp-watch-example-watch": "Suivre la page <kbd>Page principale</kbd>.",
+ "apihelp-watch-example-unwatch": "Ne plus suivre la page <kbd>Page principale</kbd>.",
+ "apihelp-watch-example-generator": "Suivre les quelques premières pages de l’espace de nom principal",
+ "apihelp-format-example-generic": "Mettre en forme le résultat de la requête dans le format $1",
+ "apihelp-dbg-description": "Extraire les données au format de <code>var_export()</code> de PHP.",
+ "apihelp-dbgfm-description": "Extraire les données au format de <code>var_export()</code> de PHP (affiché proprement en HTML).",
+ "apihelp-dump-description": "Extraire les données au format de <code>var_dump()</code> de PHP.",
+ "apihelp-dumpfm-description": "Extraire les données au format de <code>var_dump()</code> de PHP (affiché proprement en HTML).",
+ "apihelp-json-description": "Extraire les données au format JSON.",
+ "apihelp-json-param-callback": "Si spécifié, inclut la sortie dans l’appel d’une fonction fournie. Pour plus de sûreté, toutes les données spécifiques à l’utilisateur seront restreintes.",
+ "apihelp-json-param-utf8": "Si spécifié, encode la plupart (mais pas tous) des caractères non ASCII en URF-8 au lieu de les remplacer par leur séquence d’échappement hexadécimale.",
+ "apihelp-jsonfm-description": "Extraire les données au format JSON (affiché proprement en HTML).",
+ "apihelp-none-description": "Ne rien extraire.",
+ "apihelp-php-description": "Extraire les données au format sérialisé de PHP.",
+ "apihelp-phpfm-description": "Extraire les données au format sérialisé de PHP (affiché proprement en HTML).",
+ "apihelp-rawfm-description": "Extraire les données avec les éléments de débogage au format JSON (affiché proprement en HTML).",
+ "apihelp-txt-description": "Extraire les données au format de <code>print_r()</code> de PHP.",
+ "apihelp-txtfm-description": "Extraire les données au format de <code>print_r()</code> de PHP (affiché proprement en HTML).",
+ "apihelp-wddx-description": "Extraire les données au format WDDX.",
+ "apihelp-wddxfm-description": "Extraire les données au format WDDX (affiché proprement en HTML).",
+ "apihelp-xml-description": "Extraire les données au format XML.",
+ "apihelp-xml-param-xslt": "Si spécifié, ajoute la page nommée comme une feuille de style XSL. La valeur doit être un titre dans l’espace de noms {{ns:mediawiki}} se terminant par <code>.xsl</code>.",
+ "apihelp-xml-param-includexmlnamespace": "Si spécifié, ajoute un espace de noms XML.",
+ "apihelp-xmlfm-description": "Extraire les données au format XML (affiché proprement en HTML).",
+ "apihelp-yaml-description": "Extraire les données au format YAML.",
+ "apihelp-yamlfm-description": "Extraire les données YAML (affiché proprement en HTML).",
+ "api-format-title": "Résultat de l’API de MédiaWiki",
+ "api-format-prettyprint-header": "Voici la représentation HTML du format $1. HTML est utile pour le débogage, mais inapproprié pour être utilisé dans une application.\n\nSpécifiez le paramètre <var>format</var> pour modifier le format de sortie. Pour voir la représentation non HTML du format $1, mettez <kbd>format=$2</kbd>.\n\nVoyez la [[mw:API|documentation complète]], ou l’[[Special:ApiHelp/main|aide de l’API]] pour plus d’information.",
+ "api-orm-param-props": "Champs à rechercher.",
+ "api-orm-param-limit": "Nombre maximal de lignes à renvoyer.",
+ "api-pageset-param-titles": "Une liste des titres sur lesquels travailler.",
+ "api-pageset-param-pageids": "Une liste des IDs de page sur lesquelles travailler.",
+ "api-pageset-param-revids": "Une liste des IDs de révision sur lesquelles travailler.",
+ "api-pageset-param-generator": "Obtenir la liste des pages sur lesquelles travailler en exécutant le module de recherche spécifié.\n\n<strong>NOTE :<strong> les noms de paramètre du générateur doivent être préfixés avec un « g », voir les exemples.",
+ "api-pageset-param-redirects-generator": "Résoudre automatiquement les redirections dans <var>$1titles</var>, <var>$1pageids</var> et <var>$1revids</var>, et dans les pages renvoyées par <var>$1generator</var>.",
+ "api-pageset-param-redirects-nogenerator": "Résoudre automatiquement les redirections dans <var>$1titles</var>, <var>$1pageids</var> et <var>$1revids</var>.",
+ "api-pageset-param-converttitles": "Convertir les titres dans d’autres variantes si nécessaire. Fonctionne uniquement si la langue de contenu du wiki supporte la conversion en variantes. Les langues qui supportent la conversion en variante incluent $1.",
+ "api-help-title": "Aide de l’API de MediaWiki",
+ "api-help-lead": "Ceci est une page d’aide de l’API de MédiaWiki générée automatiquement.\n\nDocumentation et exemples : https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Module principal",
+ "api-help-flag-deprecated": "Ce module est obsolète.",
+ "api-help-flag-internal": "<strong>Ce module est interne ou instable.</strong> Son fonctionnement peut être modifié sans préavis.",
+ "api-help-flag-readrights": "Ce module nécessite des droits de lecture.",
+ "api-help-flag-writerights": "Ce module nécessite des droits d’écriture.",
+ "api-help-flag-mustbeposted": "Ce module n’accepte que les requêtes POST.",
+ "api-help-flag-generator": "Ce module peut être utilisé comme générateur.",
+ "api-help-parameters": "{{PLURAL:$1|Paramètre|Paramètres}} :",
+ "api-help-param-deprecated": "Obsolète.",
+ "api-help-param-required": "Ce paramètre est obligatoire.",
+ "api-help-param-list": "{{PLURAL:$1|1=Une valeur|2=Valeurs (séparées par <kbd>{{!}}</kbd>)}} : $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Doit être vide|Peut être vide, ou $2}}",
+ "api-help-param-limit": "Pas plus de $1 autorisé.",
+ "api-help-param-limit2": "Pas plus de $1 autorisé ($2 pour les robots).",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=La valeur doit être inférieure|2=Les valeurs doivent être inférieures}} à $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=La valeur ne doit pas être supérieure|2=Les valeurs ne doivent pas être supérieures}} à $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=La valeur doit|2=Les valeurs doivent}} être entre $2 et $3.",
+ "api-help-param-upload": "Doit être envoyé comme un fichier importé utilisant multipart/form-data.",
+ "api-help-param-multi-separate": "Valeurs séparées par <kbd>|</kbd>.",
+ "api-help-param-multi-max": "Le nombre maximal de valeurs est {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} pour les robots).",
+ "api-help-param-default": "Par défaut : $1",
+ "api-help-param-default-empty": "Par défaut : <span class=\"apihelp-empty\">(vide)</span>",
+ "api-help-param-token": "Un jeton « $1 » récupéré par [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "Pour rester compatible, le jeton utilisé dans l’IHM web est aussi accepté.",
+ "api-help-param-disabled-in-miser-mode": "Désactivé à cause du [[mw:Manual:$wgMiserMode|mode minimal]].",
+ "api-help-param-limited-in-miser-mode": "<strong>NOTE :</strong> Du fait du [[mw:Manual:$wgMiserMode|mode minimal]], utiliser cela peut aboutir à moins de résultats que <var>$1limit</var> renvoyés avant de continuer ; dans les cas extrêmes, zéro résultats peuvent être renvoyés.",
+ "api-help-param-direction": "Dans quelle direction énumérer :\n;newer:Lister les plus anciens en premier. Note : $1start doit être avant $1end.\n;older:Lister les nouveaux en premier (par défaut). Note : $1start doit être postérieur à $1end.",
+ "api-help-param-continue": "Quand plus de résultats sont disponibles, utiliser cela pour continuer.",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(aucune description)</span>",
+ "api-help-examples": "{{PLURAL:$1|Exemple|Exemples}} :",
+ "api-help-permissions": "{{PLURAL:$1|Droit|Droits}} :",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Accordé à}} : $2",
+ "api-help-right-apihighlimits": "Utiliser des valeurs plus hautes dans les requêtes de l’API (requêtes lentes : $1 ; requêtes rapides : $2). Les limites pour les requêtes lentes s’appliquent aussi aux paramètres multivalués.",
+ "api-credits-header": "Remerciements",
+ "api-credits": "Développeurs de l’API :\n* Roan Kattouw (développeur en chef Sept. 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (créateur, développeur en chef Sept. 2006–Sept. 2007)\n* Brad Jorsch (développeur en chef depuis 2013)\n\nVeuillez envoyer vos commentaires, suggestions et questions à mediawiki-api@lists.wikimedia.org\nou remplir un rapport de bogue sur https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/frc.json b/includes/api/i18n/frc.json
new file mode 100644
index 00000000..05d5db2d
--- /dev/null
+++ b/includes/api/i18n/frc.json
@@ -0,0 +1,19 @@
+{
+ "@metadata": {
+ "authors": [
+ "Hangmanwa7id"
+ ]
+ },
+ "apihelp-block-description": "Bloquer un useur.",
+ "apihelp-createaccount-param-name": "Nom d'useur.",
+ "apihelp-createaccount-param-password": "Mot de passe (ignoré si <var>$1mailpassword</var> est défini).",
+ "apihelp-createaccount-param-domain": "Domaine pour l’authentification externe (optional).",
+ "apihelp-delete-description": "Effacer une page.",
+ "apihelp-delete-param-title": "Titre de la page que tu veux effacer. Impossible de l’user avec $1pageid.",
+ "apihelp-delete-example-simple": "Effacer la Page principale",
+ "apihelp-emailuser-description": "Emailer un useur.",
+ "apihelp-expandtemplates-param-title": "Titre de la page.",
+ "apihelp-login-param-name": "Nom d’useur.",
+ "apihelp-login-param-password": "Mot de passe.",
+ "apihelp-login-param-domain": "Domaine (optional)."
+}
diff --git a/includes/api/i18n/fy.json b/includes/api/i18n/fy.json
new file mode 100644
index 00000000..05482cfe
--- /dev/null
+++ b/includes/api/i18n/fy.json
@@ -0,0 +1,15 @@
+{
+ "@metadata": {
+ "authors": [
+ "Robin0van0der0vliet"
+ ]
+ },
+ "apihelp-createaccount-param-name": "Brûkersnamme.",
+ "apihelp-login-param-name": "Brûkersnamme.",
+ "apihelp-login-param-password": "Wachtwurd.",
+ "apihelp-userrights-param-user": "Brûkersnamme.",
+ "api-help-param-default": "Standert: $1",
+ "api-help-param-default-empty": "Standert: <span class=\"apihelp-empty\">(leech)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(gjin beskriuwing)</span>",
+ "api-help-examples": "{{PLURAL:$1|Foarbyld|Foarbylden}}:"
+}
diff --git a/includes/api/i18n/gl.json b/includes/api/i18n/gl.json
new file mode 100644
index 00000000..065ced32
--- /dev/null
+++ b/includes/api/i18n/gl.json
@@ -0,0 +1,1030 @@
+{
+ "@metadata": {
+ "authors": [
+ "Elisardojm",
+ "Agremon",
+ "Chairego apc",
+ "VaiPolaSombra",
+ "Banjo",
+ "Fisterraeomar"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte [[mw:API:Errors_and_warnings|API: Erros e avisos]].",
+ "apihelp-main-param-action": "Que acción se realizará.",
+ "apihelp-main-param-format": "O formato de saída.",
+ "apihelp-main-param-maxlag": "O retardo máximo pode usarse cando MediaWiki está instalada nun cluster de base de datos replicadas. Para gardar accións que causen calquera retardo máis de replicación do sitio, este parámetro pode facer que o cliente espere ata que o retardo de replicación sexa menor que o valor especificado. No caso de retardo excesivo, é devolto o código de erro <samp>maxlag</samp> cunha mensaxe como <samp>esperando por $host: $lag segundos de retardo</samp>.<br />Para máis información, ver [[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]].",
+ "apihelp-main-param-smaxage": "Fixar a cabeceira <code>s-maxage</code> a esos segundos. Os erros nunca se gardan na caché.",
+ "apihelp-main-param-maxage": "Fixar a cabeceira <code>max-age</code> a esos segundos. Os erros nunca se gardan na caché.",
+ "apihelp-main-param-assert": "Verificar se o usuario está conectado como <kbd>usuario</kbd> ou ten a marca de <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Calquera valor dado aquí será incluído na resposta. Pode usarse para distingir peticións.",
+ "apihelp-main-param-servedby": "Inclúa o nome do servidor que servía a solicitude nos resultados.",
+ "apihelp-main-param-curtimestamp": "Incluir a marca de tempo actual no resultado.",
+ "apihelp-main-param-origin": "Cando se accede á API usando unha petición AJAX entre-dominios (CORS), inicializar o parámetro co dominio orixe. Isto debe incluírse en calquera petición pre-flight, e polo tanto debe ser parte da petición URI (non do corpo POST). Debe coincidir exactamente cunha das orixes na cabeceira <code>Origin</code>, polo que ten que ser fixado a algo como <kbd>https://en.wikipedia.org</kbd> ou <kbd>https://meta.wikimedia.org</kbd>. Se este parámetro non coincide coa cabeceira <code>Origin</code>, devolverase unha resposta 403. Se este parámetro coincide coa cabeceira <code>Origin</code> e a orixe está na lista branca, porase unha cabeceira <code>Access-Control-Allow-Origin</code>.",
+ "apihelp-main-param-uselang": "Linga a usar para a tradución de mensaxes. Pode consultarse unha lista de códigos en <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> con <kbd>siprop=languages</kbd>, ou especificando <kbd>user</kbd> coa preferencia de lingua do usuario actual, ou especificando <kbd>content</kbd> para usar a lingua do contido desta wiki.",
+ "apihelp-block-description": "Bloquear un usuario.",
+ "apihelp-block-param-user": "Nome de usuario, dirección ou rango de IPs que quere bloquear.",
+ "apihelp-block-param-expiry": "Tempo de caducidade. Pode ser relativo (p. ex.<kbd>5 meses</kbd> ou <kbd>2 semanas</kbd>) ou absoluto (p. ex. 2014-09-18T12:34:56Z</kbd>). Se se pon kbd>infinite</kbd>, <kbd>indefinite</kbd>, ou <kbd>never</kbd>, o bloqueo nunca caducará.",
+ "apihelp-block-param-reason": "Motivo para o bloqueo.",
+ "apihelp-block-param-anononly": "Bloquear só usuarios anónimos (é dicir, desactivar edicións anónimas desta dirección IP).",
+ "apihelp-block-param-nocreate": "Previr a creación de contas.",
+ "apihelp-block-param-autoblock": "Bloquear automaticamente o último enderezo IP utilizado, e calquera outro enderezo desde o que intente conectarse.",
+ "apihelp-block-param-noemail": "Impide que o usuario envíe correos electrónicos a través da wiki. (Require o permiso <code>blockemail</code>).",
+ "apihelp-block-param-hidename": "Ocultar o nome de usuario do rexistro de bloqueos. (Precisa do permiso <code>hideuser</code>).",
+ "apihelp-block-param-allowusertalk": "Permitir que o usuario edite a súa propia páxina de conversa (depende de <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Se o usuario xa está bloqueado, sobreescribir o bloqueo existente.",
+ "apihelp-block-param-watchuser": "Vixiar a páxina de usuario ou direccións IP e a de conversa deste usuario",
+ "apihelp-block-example-ip-simple": "Bloquear dirección IP <kbd>192.0.2.5</kbd> durante tres días coa razón <kbd>Primeiro aviso</kbd>.",
+ "apihelp-block-example-user-complex": "Bloquear indefinidamente ó usuario <kbd>Vándalo</kbd> coa razón <kbd>Vandalismo</kbd>, e impedir a creación de novas contas e envío de correos electrónicos.",
+ "apihelp-checktoken-description": "Verificar a validez dun identificador de <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
+ "apihelp-checktoken-param-type": "Tipo de identificador a probar.",
+ "apihelp-checktoken-param-token": "Símbolo a testar",
+ "apihelp-checktoken-param-maxtokenage": "Tempo máximo autorizado para o identificador, en segundos.",
+ "apihelp-checktoken-example-simple": "Verificar a validez de un identificador <kbd>csrf</kbd>.",
+ "apihelp-clearhasmsg-description": "Limpar a bandeira <code>hasmsg</code> para o usuario actual",
+ "apihelp-clearhasmsg-example-1": "Limpar a bandeira <code>hasmsg</code> para o usuario actual",
+ "apihelp-compare-description": "Obter as diferencias entre dúas páxinas.\n\nDebe indicar un número de revisión, un título de páxina, ou un ID de páxina tanto para \"from\" como para \"to\".",
+ "apihelp-compare-param-fromtitle": "Primeiro título para comparar.",
+ "apihelp-compare-param-fromid": "Identificador da primeira páxina a comparar.",
+ "apihelp-compare-param-fromrev": "Primeira revisión a comparar.",
+ "apihelp-compare-param-totitle": "Segundo título para comparar.",
+ "apihelp-compare-param-toid": "Identificador da segunda páxina a comparar.",
+ "apihelp-compare-param-torev": "Segunda revisión a comparar.",
+ "apihelp-compare-example-1": "Mostrar diferencias entre a revisión 1 e a 2",
+ "apihelp-createaccount-description": "Crear unha nova conta de usuario.",
+ "apihelp-createaccount-param-name": "Nome de usuario.",
+ "apihelp-createaccount-param-password": "Contrasinal (ignorado se <var>$1mailpassword</var> está activo)",
+ "apihelp-createaccount-param-domain": "Dominio para autenticación externa (opcional)",
+ "apihelp-createaccount-param-token": "Símbolo de creación de conta obtido á primeira.",
+ "apihelp-createaccount-param-email": "Enderezo de correo eletrónico do usuario (opcional).",
+ "apihelp-createaccount-param-realname": "Nome real do usuario (opcional).",
+ "apihelp-createaccount-param-mailpassword": "Se se establece calquera valor, enviarase un contrasinal aleatorio ao usuario.",
+ "apihelp-createaccount-param-reason": "Razón opcional de creación da conta para gardar nos rexistros.",
+ "apihelp-createaccount-param-language": "Código de lingua para usar como defecto polo usuario (de xeito opcional, usarase a lingua por defecto)",
+ "apihelp-createaccount-example-pass": "Crear usuario <kbd>testuser</kbd> con contrasinal <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Crear usuario <kbd>testmailuser</kbd>\"testmailuser\" e enviar por correo electrónico un contrasinal xenerado de forma aleatoria.",
+ "apihelp-delete-description": "Borrar a páxina.",
+ "apihelp-delete-param-title": "Título da páxina a eliminar. Non pode usarse xunto con <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "Identificador da páxina a eliminar. Non pode usarse xunto con <var>$1title</var>.",
+ "apihelp-delete-param-reason": "Razón para o borrado. Se non se indica, usarase unha razón xenerada automaticamente.",
+ "apihelp-delete-param-watch": "Engadir esta páxina á lista de vixilancia do usuario actual.",
+ "apihelp-delete-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-delete-param-unwatch": "Eliminar esta páxina da lista de vixilancia do usuario actual.",
+ "apihelp-delete-param-oldimage": "Nome da imaxe antiga a borrar como se proporciona en [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+ "apihelp-delete-example-simple": "Borrar <kbd>Main Page</kbd>.",
+ "apihelp-delete-example-reason": "Eliminar <kbd>Main Page</kbd> coa razón <kbd>Preparing for move</kbd>.",
+ "apihelp-disabled-description": "Este módulo foi desactivado.",
+ "apihelp-edit-description": "Crear e editar páxinas.",
+ "apihelp-edit-param-title": "Título da páxina que quere editar. Non pode usarse xunto con <var>$1pageid</var>.",
+ "apihelp-edit-param-pageid": "Identificador da páxina que quere editar. Non pode usarse xunto con <var>$1title</var>.",
+ "apihelp-edit-param-section": "Número de selección. O <kbd>0</kbd> é para a sección superior, <kbd>new</kbd> para unha sección nova.",
+ "apihelp-edit-param-sectiontitle": "Título para unha nova sección.",
+ "apihelp-edit-param-text": "Contido da páxina.",
+ "apihelp-edit-param-summary": "Resumo de edición. Tamén título de sección cando $1section=new e $1sectiontitle non está definido.",
+ "apihelp-edit-param-minor": "Edición pequena.",
+ "apihelp-edit-param-notminor": "Edición non pequena.",
+ "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
+ "apihelp-edit-param-basetimestamp": "Selo de tempo da revisión de base, usado para detectar conflitos de edición. Pode obterse con [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "Selo de tempo do comezo do proceso de edición, usado para detectar conflitos de edición. Pode obterse un valor axeitado usando <var>[[Special:ApiHelp/main|curtimestamp]]</var> cando se comeza o proceso de edición (p.ex. cando se carga o contido da páxina a editar).",
+ "apihelp-edit-param-recreate": "Ignorar todos os erros da páxina mentres está a ser borrada.",
+ "apihelp-edit-param-createonly": "Non editar a páxina se xa existe.",
+ "apihelp-edit-param-nocreate": "Amosar un mensaxe de erro se a páxina non existe",
+ "apihelp-edit-param-watch": "Engadir esta páxina á lista de vixilancia do usuario actual.",
+ "apihelp-edit-param-unwatch": "Eliminar esta páxina da lista de vixilancia do usuario actual.",
+ "apihelp-edit-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-edit-param-md5": "A función hash MD5 do parámetro $1text, ou dos parámetros $1prependtext e $1appendtext concatenados. Se está definida, non se fará a edición ata que a función hash sexa correcta.",
+ "apihelp-edit-param-prependtext": "Engadir este texto ao comezo da páxina. Sobreescribirase $1text.",
+ "apihelp-edit-param-appendtext": "Engadir este texto no final da páxina. Ignorar $1text.\n\nUse $1section=new para engadir unha nova sección, máis que este parámetro.",
+ "apihelp-edit-param-undo": "Desfacer esta revisión. Ignorar $1text, $1prependtext e $1appendtext.",
+ "apihelp-edit-param-undoafter": "Desfacer tódalas revisións dende $1undo ata esta. Se non está definido, só desfacer unha revisión.",
+ "apihelp-edit-param-redirect": "Resolver redireccións automáticamente",
+ "apihelp-edit-param-contentformat": "Formato de serialización de contido utilizado para o texto de entrada.",
+ "apihelp-edit-param-contentmodel": "Modelo de contido para o novo contido.",
+ "apihelp-edit-param-token": "O identificador debería enviarse empre como o último parámetro, ou polo menos despois do parámetro $1text.",
+ "apihelp-edit-example-edit": "Editar a páxina",
+ "apihelp-edit-example-prepend": "Antepor <kbd>_&#95;NOTOC_&#95;</kbd> a unha páxina.",
+ "apihelp-edit-example-undo": "Desfacer revisións 13579 a 13585 con resumo automático.",
+ "apihelp-emailuser-description": "Enviar un correo electrónico a un usuario.",
+ "apihelp-emailuser-param-target": "Usuario ó que lle mandar correo electrónico.",
+ "apihelp-emailuser-param-subject": "Asunto.",
+ "apihelp-emailuser-param-text": "Corpo do correo.",
+ "apihelp-emailuser-param-ccme": "Enviarme unha copia deste correo.",
+ "apihelp-emailuser-example-email": "Enviar un correo electrónico ó usuario <kbd>Administrador da wiki</kbd> co texto <kbd>Contido</kbd>.",
+ "apihelp-expandtemplates-description": "Expandir tódolos modelos en wikitexto.",
+ "apihelp-expandtemplates-param-title": "Título da páxina.",
+ "apihelp-expandtemplates-param-text": "Sintaxis wiki a converter.",
+ "apihelp-expandtemplates-param-revid": "ID de revisión, para <nowiki>{{REVISIONID}}</nowiki> e variables similares.",
+ "apihelp-expandtemplates-param-prop": "Pezas de información a retornar:\n;wikitext:O texto wiki expandido.\n;categories:Calquer categoría presente na entrada que non estea representada na saída do texto wiki\n;properties:Propiedades da páxina definidas por palabras máxicas expandidas no texto wiki\n;volatile:Definir se a saída é volátil e se non debe usarse noutra parte da páxina.\n;ttl:Tempo máximo a partir do cal os cachés do resultado deben invalidarse.\n;parsetree:O análise sintáctico en árbore do XML de entrada.\nTeña en conta que se non se selecciona ningún valor o resultado conterá o texto wiki, pero a saída estará nun formato desprezado.",
+ "apihelp-expandtemplates-param-includecomments": "Cando queria incluír comentarios HTML na saída.",
+ "apihelp-expandtemplates-param-generatexml": "Xenerar árbore de análise XML (reemprazado por $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Expandir o wikitexto <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>.",
+ "apihelp-feedcontributions-description": "Devolve a lista de contribucións dun usuario.",
+ "apihelp-feedcontributions-param-feedformat": "O formato de alimentación.",
+ "apihelp-feedcontributions-param-user": "Para que usuarios recuperar as contribucións.",
+ "apihelp-feedcontributions-param-namespace": "Que espazo de nomes filtrar polas contribucións.",
+ "apihelp-feedcontributions-param-year": "Desde o ano (e anteriores).",
+ "apihelp-feedcontributions-param-month": "Desde o mes de (e anteriores).",
+ "apihelp-feedcontributions-param-tagfilter": "Filtrar as contribucións que teñan estas etiquetas.",
+ "apihelp-feedcontributions-param-deletedonly": "Mostrar só as contribuciones eliminadas.",
+ "apihelp-feedcontributions-param-toponly": "Mostrar só as edicións que que son as ultimas revisións.",
+ "apihelp-feedcontributions-param-newonly": "Mostrar só as edicións que crearon páxinas.",
+ "apihelp-feedcontributions-param-showsizediff": "Mostrar diferenza de tamaño entre edicións.",
+ "apihelp-feedcontributions-example-simple": "Mostrar as contribucións do usuario <kbd>Example</kbd>.",
+ "apihelp-feedrecentchanges-description": "Devolve un ficheiro de cambios recentes.",
+ "apihelp-feedrecentchanges-param-feedformat": "O formato da saída.",
+ "apihelp-feedrecentchanges-param-namespace": "Espazo de nomes ó que limitar os resultados.",
+ "apihelp-feedrecentchanges-param-invert": "Tódolos nomes de espazos agás o seleccionado",
+ "apihelp-feedrecentchanges-param-associated": "Incluir o espazo de nomes asociado (conversa ou principal).",
+ "apihelp-feedrecentchanges-param-days": "Días a limitar os resultados",
+ "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados a visualizar.",
+ "apihelp-feedrecentchanges-param-from": "Mostrar modificacións desde entón.",
+ "apihelp-feedrecentchanges-param-hideminor": "Ocultar cambios menores.",
+ "apihelp-feedrecentchanges-param-hidebots": "Ocultar cambios feitos por bots.",
+ "apihelp-feedrecentchanges-param-hideanons": "Ocultar os cambios realizados por usuarios anónimos.",
+ "apihelp-feedrecentchanges-param-hideliu": "Ocultar os cambios realizados por usuarios rexistrados.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar os cambios patrullados.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Ocultar os cambios realizados polo usuario actual.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiqueta.",
+ "apihelp-feedrecentchanges-param-target": "Mostrar só os cambios nas páxinas ligadas a esta.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar os cambios nas páxinas ligadas coa páxina seleccionada.",
+ "apihelp-feedrecentchanges-example-simple": "Mostrar os cambios recentes",
+ "apihelp-feedrecentchanges-example-30days": "Mostrar os cambios recentes limitados a 30 días",
+ "apihelp-feedwatchlist-description": "Devolve o fluxo dunha lista de vixiancia.",
+ "apihelp-feedwatchlist-param-feedformat": "O formato da saída.",
+ "apihelp-feedwatchlist-param-hours": "Lista as páxinas modificadas desde estas horas ata agora.",
+ "apihelp-feedwatchlist-param-linktosections": "Ligar directamente ás seccións modificadas se é posible.",
+ "apihelp-feedwatchlist-example-default": "Mostar o fluxo da lista de vixiancia.",
+ "apihelp-feedwatchlist-example-all6hrs": "Amosar tódolos cambios feitos ás páxinas vixiadas nas últimas 6 horas.",
+ "apihelp-filerevert-description": "Revertir o ficheiro a unha versión anterior.",
+ "apihelp-filerevert-param-filename": "Nome de ficheiro final, sen o prefixo Ficheiro:",
+ "apihelp-filerevert-param-comment": "Comentario de carga.",
+ "apihelp-filerevert-param-archivename": "Nome de ficheiro da revisión á que reverter.",
+ "apihelp-filerevert-example-revert": "Reverter <kbd>Wiki.png</kbd> á versión do <kbd>2011-03-05T15:27:40Z</kbd>.",
+ "apihelp-help-description": "Mostrar axuda para os módulos indicados.",
+ "apihelp-help-param-modules": "Módulos para mostar axuda (valores dos parámetros <var>acción</var> e <var>formato</var>, ou <kbd>principal</kbd>). Pode especificar submódulos con un <kbd>+</kbd>.",
+ "apihelp-help-param-submodules": "Incluír axuda para os submódulos do módulo nomeado.",
+ "apihelp-help-param-recursivesubmodules": "Incluír axuda para os submódulos de forma recursiva.",
+ "apihelp-help-param-helpformat": "Formato de saída da axuda.",
+ "apihelp-help-param-wrap": "Incluír a saída nunha estrutura de resposta API estándar.",
+ "apihelp-help-param-toc": "Incluír unha táboa de contidos na saída por HTML",
+ "apihelp-help-example-main": "Axuda para o módulo principal",
+ "apihelp-help-example-recursive": "Toda a axuda nunha páxina",
+ "apihelp-help-example-help": "Axuda do módulo de axuda en si",
+ "apihelp-help-example-query": "Axuda para dous submódulos de consulta.",
+ "apihelp-imagerotate-description": "Xirar unha ou máis imaxes.",
+ "apihelp-imagerotate-param-rotation": "Graos a rotar a imaxe no sentido do reloxio.",
+ "apihelp-imagerotate-example-simple": "Rotar <kbd>File:Example.png</kbd> <kbd>90</kbd> graos.",
+ "apihelp-imagerotate-example-generator": "Rotar tódalas imaxes en <kbd>Category:Flip</kbd> <kbd>180</kbd> graos",
+ "apihelp-import-description": "Importar unha páxina doutra wiki, ou nun ficheiro XML.\n\nDecátese de que o POST HTTP debe facerse como unha carga de ficheiro (p. ex. usando multipart/form-data) cando se envíe un ficheiro para o parámetro <var>xml</var>.",
+ "apihelp-import-param-summary": "Resume de importación.",
+ "apihelp-import-param-xml": "Subido ficheiro XML.",
+ "apihelp-import-param-interwikisource": "Para importacións interwiki: wiki da que importar.",
+ "apihelp-import-param-interwikipage": "Para importacións interwiki: páxina a importar.",
+ "apihelp-import-param-fullhistory": "Para importacións interwiki: importar o historial completo, non só a versión actual.",
+ "apihelp-import-param-templates": "Para importacións interwiki: importar tódolos modelos incluídos.",
+ "apihelp-import-param-namespace": "Para importacións interwiki: importar a este espazo de nomes.",
+ "apihelp-import-param-rootpage": "Importar como subpáxina desta páxina.",
+ "apihelp-import-example-import": "Importar [[meta:Help:Parserfunctions]] ó espazo de nomes 100 con todo o historial.",
+ "apihelp-login-description": "No caso dunha conexión correcta, as cookies necesarias incluiranse nas cabeceiras HTTP de resposta. No caso dunha conexión fallida, os intentos posteriores poden ser reducidos para limitar ataques automaticos de roubo de contrasinais.",
+ "apihelp-login-param-name": "Nome de usuario.",
+ "apihelp-login-param-password": "Contrasinal",
+ "apihelp-login-param-domain": "Dominio (opcional).",
+ "apihelp-login-param-token": "Identificador de conexión obtido na primeira petición.",
+ "apihelp-login-example-gettoken": "Recuperar un identificador de conexión.",
+ "apihelp-login-example-login": "Identificarse",
+ "apihelp-logout-description": "Terminar e limpar datos de sesión.",
+ "apihelp-logout-example-logout": "Cerrar a sesión do usuario actual",
+ "apihelp-managetags-description": "Realizar tarefas de xestión relacionadas coa modificación de etiquetas.",
+ "apihelp-managetags-param-operation": "Que operación realizar:\n;create:Crear unha nova etiqueta de modificación para uso manual.\n;delete:Borar unha etiqueta de modificación da base de datos, incluíndo o borrado da etiqueta de todas as revisións, entradas de cambios recentes e entradas de rexistro onde estea a usarse.\n;activate:Activar unha etiqueta de modificación, permitindo que os usuarios a usen manualmente.\n;deactivate:Desactivar unha etiqueta de modificación, impedindo que os usuarios a usen manualmente.",
+ "apihelp-managetags-param-tag": "Etiqueta para crear, borrar, activar ou desactivar. Para a creación da etiqueta, a etiqueta non pode existir previamente. Para o borrado da etiqueta, a etiqueta debe existir. Para a activación da etiqueta, a etiqueta debe existir e non pode ser usada por unha extensión. Para desactivar unha etiqueta, a etiqueta debe estar activa e definida manualmente.",
+ "apihelp-managetags-param-reason": "Un motivo opcional para crear, borrar, activar ou desactivar a etiqueta.",
+ "apihelp-managetags-param-ignorewarnings": "Ignorar calquera aviso que apareza durante a operación.",
+ "apihelp-managetags-example-create": "Crear unha etiqueta chamada <kbd>publicidade</kbd> coa razón <kbd>Para usar en vixiancia de edicións</kbd>",
+ "apihelp-managetags-example-delete": "Borrar a etiqueta <kbd>vandalismo</kbd> coa razón <kbd>Erros ortográficos</kbd>",
+ "apihelp-managetags-example-activate": "Activar a etiqueta chamada <kbd>publicidade</kbd> coa razón <kbd>Para usar en vixiancia de edicións</kbd>",
+ "apihelp-managetags-example-deactivate": "Desactivar a etiqueta chamada <kbd>publicidade</kbd> coa razón <kbd>Xa non é necesaria</kbd>",
+ "apihelp-move-description": "Mover unha páxina.",
+ "apihelp-move-param-from": "Título da páxina que quere renomear. Non pode usarse xunto con <var>$1fromid</var>.",
+ "apihelp-move-param-fromid": "Identificador da páxina que quere renomear. Non pode usarse xunto con <var>$1from</var>.",
+ "apihelp-move-param-to": "Título ó que renomear a páxina.",
+ "apihelp-move-param-reason": "Motivo para o renomeamento.",
+ "apihelp-move-param-movetalk": "Renomear a páxina de conversa, se existe.",
+ "apihelp-move-param-movesubpages": "Renomear as subpáxinas, se é aplicable.",
+ "apihelp-move-param-noredirect": "Non crear unha redirección.",
+ "apihelp-move-param-watch": "Engadir a páxina e a redirección á páxina de vixiancia do usuario actual.",
+ "apihelp-move-param-unwatch": "Eliminar a páxina e a redirección da páxina de vixiancia do usuario actual.",
+ "apihelp-move-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-move-param-ignorewarnings": "Ignorar as advertencias.",
+ "apihelp-move-example-move": "Mover <kbd>Títulomalo</kbd> a <kbd>Títulobo</kbd> sen deixar unha redirección.",
+ "apihelp-opensearch-description": "Buscar no wiki mediante o protocolo OpenSearch.",
+ "apihelp-opensearch-param-search": "Buscar texto.",
+ "apihelp-opensearch-param-limit": "Número máximo de resultados a visualizar.",
+ "apihelp-opensearch-param-namespace": "Espazo de nomes no que buscar.",
+ "apihelp-opensearch-param-suggest": "Non facer nada se <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> é falso.",
+ "apihelp-opensearch-param-redirects": "Como xestionar as redireccións:\n;return:Devolve a mesma redirección.\n;resolve:Devolve a páxina á que apunta. Pode devolver menos de $1limit resultados.\nPor razóns históricas, o valor por defecto para $1format=json é \"return\" e \"resolve\" para outros formatos.",
+ "apihelp-opensearch-param-format": "O formato de saída.",
+ "apihelp-opensearch-example-te": "Atopar páxinas que comezan por <kbd>Te</kbd>.",
+ "apihelp-options-description": "Cambiar as preferencias do usuario actual.\n\nSó se poden cambiar opcións que estean rexistradas no núcleo ou nunha das extensións instaladas, ou opcións con claves prefixadas con \"userjs-\" (previstas para ser usadas por scripts de usuario).",
+ "apihelp-options-param-reset": "Reiniciar preferencias ás iniciais do sitio.",
+ "apihelp-options-param-resetkinds": "Lista de tipos de opcións a reinicializar cando a opción <var>$1reset</var> está definida.",
+ "apihelp-options-param-change": "Lista de cambios, con formato nome=valor (p. ex. skin=vector). O valor non pode ter caracteres de barra vertical. Se non se indica un valor (sen u signo igual), p. ex. nomeopcion|outraopcion|..., a opción será gardada co seu valor por defecto.",
+ "apihelp-options-param-optionname": "Nome dunha opción que debe ser fixado ó valor dado por <var>$1optionvalue</var>.",
+ "apihelp-options-param-optionvalue": "Valor da opción especificada por <var>$1optionname</var>, pode conter o caracter da barra vertical.",
+ "apihelp-options-example-reset": "Restablecer tódaalas preferencias",
+ "apihelp-options-example-change": "Cambiar as preferencias <kbd>skin</kbd> and <kbd>hideminor</kbd>.",
+ "apihelp-options-example-complex": "Restaurar todas as preferencias, logo fixar <kbd>skin</kbd> e <kbd>nickname</kbd>.",
+ "apihelp-paraminfo-description": "Obter información sobre módulos API.",
+ "apihelp-paraminfo-param-modules": "Lista de nomes de módulos (valores dos parámetros <var>acción</var e <var>formato</var>, ou <kbd>principal</kbd>). Pode especificar submódulos con <kbd>+</kbd>.",
+ "apihelp-paraminfo-param-helpformat": "Formato das cadeas de axuda.",
+ "apihelp-paraminfo-param-querymodules": "Lista dos nomes de módulos de consulta (valores dos parámetros <var>prop</var>, <var>meta</var> ou <var>list</var>). Use <kbd>$1modules=query+foo</kbd> no canto de <kbd>$1querymodules=foo</kbd>.",
+ "apihelp-paraminfo-param-mainmodule": "Obter información sobre o módulo principal (nivel superior). No canto use <kbd>$1modules=main</kbd>.",
+ "apihelp-paraminfo-param-pagesetmodule": "Obter información sobre o módulo pageset (proporcionando títulos= e amigos).",
+ "apihelp-paraminfo-param-formatmodules": "Lista dos nomes de módulo de formato (valores do parámetro <var>formato</var>). No canto use <var>$1modules</var>.",
+ "apihelp-paraminfo-example-1": "Amosar información para <kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, e <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+ "apihelp-parse-param-title": "Título da páxina á que pertence o texto. Se non se indica, debe especificarse <var>$1contentmodel</var>, e [[API]] usarase como o título.",
+ "apihelp-parse-param-text": "Texto a analizar. Use <var>$1title</var> ou <var>$1contentmodel</var> para controlar o modelo de contido.",
+ "apihelp-parse-param-summary": "Resumo a analizar.",
+ "apihelp-parse-param-page": "Analizar o contido desta páxina. Non pode usarse de forma conxunta con <var>$1text</var> e <var>$1title</var>.",
+ "apihelp-parse-param-pageid": "Analizar o contido desta páxina. Ignora <var>$1page</var>.",
+ "apihelp-parse-param-redirects": "Se <var>$1page</var> ou <var>$1pageid</var> apuntar a unha redirección, resólvea.",
+ "apihelp-parse-param-oldid": "Analizar o contido desta revisión. Ignora <var>$1page</var> e <var>$1pageid</var>.",
+ "apihelp-parse-param-pst": "Fai unha transformación antes de gardar a entrada antes de analizala. Válida unicamente para usar con texto.",
+ "apihelp-parse-param-onlypst": "Facer unha transformación antes de gardar (PST) a entrada, pero sen analizala. Devolve o mesmo wikitexto, despois de que a PST foi aplicada. Só válida cando se usa con <var>$1text</var>.",
+ "apihelp-parse-param-effectivelanglinks": "Inclúe ligazóns de idioma proporcionadas polas extensións (para usar con <kbd>$1prop=langlinks</kbd>).",
+ "apihelp-parse-param-section": "Recuperar unicamente o contido deste número de sección ou cando <kbd>new</kbd> xera unha nova sección.\n\nA sección <kbd>new</kbd> só é atendida cando se especifica <var>text</var>.",
+ "apihelp-parse-param-sectiontitle": "Novo título de sección cando <var>section</var> é <kbd>new</kbd>.\n\nA diferenza da edición de páxinas, non se oculta no <var>summary</var> cando se omite ou está baleiro.",
+ "apihelp-parse-param-disablepp": "Desactivar o informe PP da saída do analizador.",
+ "apihelp-parse-param-disableeditsection": "Desactivar as ligazóns de edición de sección da saída do analizador.",
+ "apihelp-parse-param-generatexml": "Xenerar unha árbore de análise XML (necesita o modelo de contido <code>$1</code>).",
+ "apihelp-parse-param-preview": "Analizar en modo vista previa.",
+ "apihelp-parse-param-sectionpreview": "Analizar en modo vista previa de sección (activa tamén o modo de vista previa).",
+ "apihelp-parse-param-disabletoc": "Desactiva o índice na saída.",
+ "apihelp-parse-param-contentformat": "Formato de serialización do contido usado para o texto de entrada. Só válido cando se usa con $1text.",
+ "apihelp-parse-param-contentmodel": "Modelo de contido do texto de entrada. Se se omite, debe especificarse $1title, e o valor por defecto será o modelo do título especificado. Só válido cando se usa con $1text.",
+ "apihelp-parse-example-page": "Analizar unha páxina.",
+ "apihelp-parse-example-text": "Analizar un wikitexto.",
+ "apihelp-parse-example-texttitle": "Analizar wikitexto, especificando o título da páxina.",
+ "apihelp-parse-example-summary": "Analizar un resumo.",
+ "apihelp-patrol-description": "Patrullar unha páxina ou edición.",
+ "apihelp-patrol-param-rcid": "ID de modificación recente a vixiar.",
+ "apihelp-patrol-param-revid": "ID de revisión a vixiar.",
+ "apihelp-patrol-example-rcid": "Patrullar un cambio recente",
+ "apihelp-patrol-example-revid": "Patrullar unha revisión",
+ "apihelp-protect-description": "Cambiar o nivel de protección dunha páxina.",
+ "apihelp-protect-param-title": "Título da páxina que quere (des)protexer. Non pode usarse xunto con $1pageid.",
+ "apihelp-protect-param-pageid": "Identificador da páxina que quere (des)protexer. Non pode usarse xunto con $1title.",
+ "apihelp-protect-param-protections": "Lista dos niveis de protección, con formato <kbd>action=level</kbd> (p.ex. <kbd>edit=sysop</kbd>).\n\n<strong>Nota:</strong> Todas as accións que non estean listadas terán restriccións para ser eliminadas.",
+ "apihelp-protect-param-expiry": "Selos de tempo de caducidade. Se só se indica un selo de tempo, usarase para todas as proteccións. Use <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, ou <kbd>never</kbd>, para unha protección sen caducidade.",
+ "apihelp-protect-param-reason": "Razón para (des)protexer.",
+ "apihelp-protect-param-cascade": "Activar protección en cascada (p. ex. protexer páxinas incluídas nesta páxina). Ignorado se todos os niveis de protección proporcionados non permiten o uso en cascada.",
+ "apihelp-protect-param-watch": "Se se define este parámetro, engadir a páxina que se (des)protexe á lista de vixilancia do usuario actual.",
+ "apihelp-protect-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-protect-example-protect": "Protexer unha páxina",
+ "apihelp-protect-example-unprotect": "Desprotexer unha páxina poñendo as restricións a <kbd>all</kbd>.",
+ "apihelp-protect-example-unprotect2": "Desprotexer unha páxina quitando as restricións.",
+ "apihelp-purge-description": "Borrar a caché para os títulos indicados.\n\nPrecisa dunha petición POST se o usuario non está conectado.",
+ "apihelp-purge-param-forcelinkupdate": "Actualizar as táboas de ligazóns.",
+ "apihelp-purge-param-forcerecursivelinkupdate": "Actualizar a táboa de ligazóns, e actualizar as táboas de ligazóns para calquera páxina que use esta páxina como modelo.",
+ "apihelp-purge-example-simple": "Purgar a <kbd>Páxina Principal</kbd> e páxina da <kbd>API</kbd>.",
+ "apihelp-purge-example-generator": "Purgar as primeiras 10 páxinas no espazo de nomes principal.",
+ "apihelp-query-description": "Consultar datos de e sobre MediaWiki.\n\nTodas as modificacións de datos primeiro teñen que facer unha busca para obter un identificador para evitar abusos de sitios maliciosos.",
+ "apihelp-query-param-prop": "Que propiedades obter para as páxinas buscadas.",
+ "apihelp-query-param-list": "Que lista obter.",
+ "apihelp-query-param-meta": "Que metadatos obter.",
+ "apihelp-query-param-indexpageids": "Incluir una sección adicional de identificadores de páxina listando todos os IDs das páxinas devoltas.",
+ "apihelp-query-param-export": "Exportar as revisións actuais de todas as páxinas dadas ou xeneradas.",
+ "apihelp-query-param-exportnowrap": "Devolver o XML exportado sen incluílo nun resultado XML (mesmo formato que [[Special:Export]]). Só pode usarse con $1export.",
+ "apihelp-query-param-iwurl": "Se fai falta obter a URL completa se o título é unha ligazón interwiki.",
+ "apihelp-query-param-continue": "Cando está presente, formatea query-continue como pares clave-valor que simplemente serán mesturados na consulta orixinal. Este parámetro debe fixarse a unha cadea baleira na consulta inicial.\n\nEste parámetro está recomendado para todos os novos desenvolvementos, e será o usado por defecto na seguinte versión da API.",
+ "apihelp-query-param-rawcontinue": "Actualmente ignorado. No futuro, <var>$1continue</var> virá por defecto e será necesario para recibir os datos en bruto de <samp>query-continue</samp>.",
+ "apihelp-query-example-revisions": "Consultar [[Special:ApiHelp/query+siteinfo|información do sitio]] e [[Special:ApiHelp/query+revisions|as revisións]] da <kbd>Páxina Principal</kbd>.",
+ "apihelp-query-example-allpages": "Buscar revisións de páxinas que comecen por <kbd>API/</kbd>.",
+ "apihelp-query+allcategories-description": "Numerar tódalas categorías",
+ "apihelp-query+allcategories-param-from": "Categoría pola que comezar a enumeración.",
+ "apihelp-query+allcategories-param-to": "Categoría pola que rematar a enumeración.",
+ "apihelp-query+allcategories-param-prefix": "Buscar todos os títulos de categoría que comezan con este valor.",
+ "apihelp-query+allcategories-param-dir": "Dirección na que ordenar.",
+ "apihelp-query+allcategories-param-min": "Devolver só categorías con polo menos este número de membros.",
+ "apihelp-query+allcategories-param-max": "Devolver só categorías con como moito este número de membros.",
+ "apihelp-query+allcategories-param-limit": "Cantas categorías devolver.",
+ "apihelp-query+allcategories-param-prop": "Que propiedades recuperar:\n;size: Engade o número de páxinas na categoría.\n;hidden: Marca as categorías que están ocultas con _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+allcategories-example-size": "Listar categorías con información do número de páxinas en cada unha.",
+ "apihelp-query+allcategories-example-generator": "Obter información sobre a páxina de categoría para categorías que comezan por <kbd>List</kbd>.",
+ "apihelp-query+alldeletedrevisions-description": "Listar todas as revisións borradas por un usuario ou nun espazo de nomes.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Só pode usarse con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Non pode usarse con <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-start": "Selo de tempo para comezar a enumeración.",
+ "apihelp-query+alldeletedrevisions-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+alldeletedrevisions-param-from": "Comezar listado neste título.",
+ "apihelp-query+alldeletedrevisions-param-to": "Parar listado neste título.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Buscar tódolos títulos de páxinas que comezan con este valor.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+ "apihelp-query+alldeletedrevisions-param-user": "Só listar revisións deste usuario.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Non listar revisións deste usuario.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Só listar páxinas neste espazo de nomes.",
+ "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>Nota:</strong> Debido ó [[mw:Manual:$wgMiserMode|modo minimal]], ó usar á vez <var>$1user</var> e <var>$1namespace</var> pode devolver menos resultados de <var>$1limit</var> antes de continuar, en casos extremos, pode que non devolva resultados.",
+ "apihelp-query+alldeletedrevisions-param-generatetitles": "Usado como xenerador, xenera títulos no canto de IDs de revisión.",
+ "apihelp-query+alldeletedrevisions-example-user": "Listar as últimas 50 contribucións borradas do usuario <kbd>Exemplo<kbd>.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Listar as 50 primeiras revisións borradas no espazo de nomes principal.",
+ "apihelp-query+allfileusages-description": "Lista todos os usos de ficheiro, incluído os que non existen.",
+ "apihelp-query+allfileusages-param-from": "Título do ficheiro no que comezar a enumerar.",
+ "apihelp-query+allfileusages-param-to": "Título do ficheiro no que rematar de enumerar.",
+ "apihelp-query+allfileusages-param-prefix": "Buscar tódolos títulos de ficheiro que comezan con este valor.",
+ "apihelp-query+allfileusages-param-unique": "Mostrar só nomes de ficheiro distintos. Non pode usarse con $1prop=ids.\nCando se usa como xenerador, produce páxinas obxectivo no canto de páxinas fonte.",
+ "apihelp-query+allfileusages-param-prop": "Que partes de información incluír:\n;ids:Engade o ID de páxina usada (non pode usarse con $1unique).\n;title:Engade o nome do ficheiro.",
+ "apihelp-query+allfileusages-param-limit": "Número total de obxectos a devolver.",
+ "apihelp-query+allfileusages-param-dir": "Dirección na cal listar.",
+ "apihelp-query+allfileusages-example-B": "Lista títulos de ficheiro, incluíndo os eliminados, cos IDs de páxina dos que proveñen, comezando en <kbd>B</kbd>.",
+ "apihelp-query+allfileusages-example-unique": "Listar títulos únicos de ficheiros.",
+ "apihelp-query+allfileusages-example-unique-generator": "Obter todos os títulos de ficheiro, marcando os eliminados.",
+ "apihelp-query+allfileusages-example-generator": "Obtén as páxinas que conteñen os ficheiros.",
+ "apihelp-query+allimages-description": "Enumerar tódalas imaxes secuencialmente.",
+ "apihelp-query+allimages-param-sort": "Propiedade pola que ordenar.",
+ "apihelp-query+allimages-param-dir": "Dirección na cal listar.",
+ "apihelp-query+allimages-param-from": "Título da imaxe no que comezar a enumerar. Só pode usarse con $1sort=name.",
+ "apihelp-query+allimages-param-to": "Título da imaxe no que rematar a enumerar. Só pode usarse con $1sort=name.",
+ "apihelp-query+allimages-param-start": "Título do selo de tempo no que comezar a enumerar. Só pode usarse con $1sort=timestamp.",
+ "apihelp-query+allimages-param-end": "Título do selo de tempo no que rematar a enumerar. Só pode usarse con $1sort=timestamp.",
+ "apihelp-query+allimages-param-prefix": "Buscar todas as imaxes cuxo título comeza por este valor. Só pode usarse con $1sort=name.",
+ "apihelp-query+allimages-param-minsize": "Limitar a imaxes con polo menos este número de bytes.",
+ "apihelp-query+allimages-param-maxsize": "Limitar a imaxes con como máximo este número de bytes.",
+ "apihelp-query+allimages-param-sha1": "Función hash SHA1 da imaxe. Invalida $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "Función hash SHA1 da imaxe en base 36 (usada en MediaWiki).",
+ "apihelp-query+allimages-param-user": "Mostrar só ficheiros subidos por este usuario. Só pode usarse con $1sort=timestamp. Non se pode usar xunto a $1filterbots.",
+ "apihelp-query+allimages-param-filterbots": "Como filtrar ficheiros subidos por bots. Só pode usarse con $1sort=timestamp. Non pode usarse xunto con $1user.",
+ "apihelp-query+allimages-param-mime": "Que tipos MIME buscar, por exemplo <kbd>imaxe/jpeg</kbd>.",
+ "apihelp-query+allimages-param-limit": "Cantas imaxes mostar en total.",
+ "apihelp-query+allimages-example-B": "Mostrar unha lista de ficheiros que comezan por <kbd>B</kbd>.",
+ "apihelp-query+allimages-example-recent": "Mostrar unha lista de ficheiros subidos recentemente, similares a [[Special:NewFiles]].",
+ "apihelp-query+allimages-example-mimetypes": "Mostrar unha lista de ficheiros con tipo MIME <kbd>image/png</kbd> ou <kbd>image/gif</kbd>",
+ "apihelp-query+allimages-example-generator": "Mostar información sobre catro ficheiros que comecen pola letra <kbd>T</kbd>.",
+ "apihelp-query+alllinks-description": "Numerar tódalas ligazóns que apuntan a un nome de espazos determinado.",
+ "apihelp-query+alllinks-param-from": "Título da ligazón na que comezar a enumerar.",
+ "apihelp-query+alllinks-param-to": "Título da ligazón na que rematar de enumerar.",
+ "apihelp-query+alllinks-param-prefix": "Buscar tódolos títulos ligados que comezan con este valor.",
+ "apihelp-query+alllinks-param-unique": "Mostrar só títulos ligados distintos. Non pode usarse con <kbd>$1prop=ids</kbd>.\nCando se usa como xenerador, produce páxinas obxectivo no canto de páxinas fonte.",
+ "apihelp-query+alllinks-param-prop": "Que partes de información incluír:\n;ids: Engade o ID da páxina da ligazón (non pode usarse con <var>$1unique</var>).\n;título: Engade o título da ligazón.",
+ "apihelp-query+alllinks-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+alllinks-param-limit": "Número total de obxectos a devolver.",
+ "apihelp-query+alllinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+alllinks-example-B": "Lista os títulos ligados, incluíndo os eliminados, cos ID das páxinas das que proveñen, comezando en <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-unique": "Listar títulos ligados únicos",
+ "apihelp-query+alllinks-example-unique-generator": "Obtén tódolos títulos ligados, marcando os eliminados.",
+ "apihelp-query+alllinks-example-generator": "Obtén as páxinas que conteñen as ligazóns.",
+ "apihelp-query+allmessages-description": "Devolver mensaxes deste sitio.",
+ "apihelp-query+allmessages-param-messages": "Que mensaxes devolver. <kbd>*</kbd> (por defecto) significa todas as mensaxes",
+ "apihelp-query+allmessages-param-prop": "Que propiedades obter.",
+ "apihelp-query+allmessages-param-enableparser": "Marcar para activar o analizador, isto preprocesará o texto wiki da mensaxe (substituir palabras máxicas, xestionar modelo, etc.)",
+ "apihelp-query+allmessages-param-nocontent": "Se se marca, non inclúe o contido das mensaxes na saída.",
+ "apihelp-query+allmessages-param-includelocal": "Tamén inclúe mensaxes locais, p.ex. mensaxes que non existen no software pero existen como unha páxina MediaWiki:. \nIsto lista todas as páxinas MediaWiki:, polo que tamén listará as que non son realmente mensaxes como [[MediaWiki:Common.js|Common.js]].",
+ "apihelp-query+allmessages-param-args": "Argumentos a substituír na mensaxe.",
+ "apihelp-query+allmessages-param-filter": "Retornar só mensaxes con nomes que conteñan esta cadea.",
+ "apihelp-query+allmessages-param-customised": "Devolver só mensaxes neste estado de personalización.",
+ "apihelp-query+allmessages-param-lang": "Retornar mensaxes nesta lingua.",
+ "apihelp-query+allmessages-param-from": "Retornar mensaxes que comezan nesta mensaxe.",
+ "apihelp-query+allmessages-param-to": "Retornar mensaxes que rematan nesta mensaxe.",
+ "apihelp-query+allmessages-param-title": "Nome de páxina a usar como contexto cando se analice a mensaxe (para a opción $1enableparser)",
+ "apihelp-query+allmessages-param-prefix": "Devolver mensaxes con este prefixo.",
+ "apihelp-query+allmessages-example-ipb": "Mostar mensaxes que comecen por <kbd>ipb-</kbd>.",
+ "apihelp-query+allmessages-example-de": "Mostrar mensaxes <kbd>august</kbd> e <kbd>mainpage</kbd> en Alemán.",
+ "apihelp-query+allpages-description": "Numerar tódalas páxinas secuencialmente nun espazo de nomes determinado.",
+ "apihelp-query+allpages-param-from": "Título da páxina na que comezar a enumerar.",
+ "apihelp-query+allpages-param-to": "Título da páxina na que rematar de enumerar.",
+ "apihelp-query+allpages-param-prefix": "Buscar tódolos títulos de páxinas que comezan con este valor.",
+ "apihelp-query+allpages-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+allpages-param-filterredir": "Que páxinas listar.",
+ "apihelp-query+allpages-param-minsize": "Limitar a páxinas con polo menos este número de bytes.",
+ "apihelp-query+allpages-param-maxsize": "Limitar a páxinas con como máximo este número de bytes.",
+ "apihelp-query+allpages-param-prtype": "Limitar a só protección de páxinas.",
+ "apihelp-query+allpages-param-prlevel": "Filtrar proteccións baseándose no nivel de protección (debe empregarse có parámetro $1prtype= ).",
+ "apihelp-query+allpages-param-prfiltercascade": "Filtrar proteccións baseadas en cascada (ignoradas se $1prtype non ten valor).",
+ "apihelp-query+allpages-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+allpages-param-dir": "Dirección na cal listar.",
+ "apihelp-query+allpages-param-filterlanglinks": "Filtro baseado en si unha páxina ten ligazóns de lingua. Decátese de que esto pode non considerar as ligazóns de lingua engadidas polas extensións.",
+ "apihelp-query+allpages-param-prexpiry": "Que finalización de protección pola que filtrar a páxina:\n;indefinida: Só obter páxinas coa finalización de protección indefinida.\n;definite: Só obter páxinas cunha finalización de protección definida.\n;all: Obter páxinas con calquera finalización de protección.",
+ "apihelp-query+allpages-example-B": "Mostrar unha lista de páxinas que comezan pola letra <kbd>B</kbd>.",
+ "apihelp-query+allpages-example-generator": "Mostrar inforfmación sobre 4 páxinas que comecen pola letra <kbd>T</kbd>.",
+ "apihelp-query+allpages-example-generator-revisions": "Motrar o contido das dúas primeiras páxinas que non sexan redirección que comecen por <kbd>Re</kbd>.",
+ "apihelp-query+allredirects-description": "Lista tódalas redireccións a un espazo de nomes.",
+ "apihelp-query+allredirects-param-from": "Título da redirección na que comezar a enumerar.",
+ "apihelp-query+allredirects-param-to": "Título da redirección na que rematar de enumerar.",
+ "apihelp-query+allredirects-param-prefix": "Buscar todas as páxinas que comecen con este valor.",
+ "apihelp-query+allredirects-param-unique": "Só mostrar páxinas obxectivo distintas. Non pode usarse con $1prop=ids|fragment|interwiki.\nCando se usa como xenerador, produce páxinas obxectivo no canto de páxinas fonte.",
+ "apihelp-query+allredirects-param-prop": "Que información incluír:\n;ids:Engade o ID da páxina da redirección (non pode usarse con <var>$1unique</var>).\n;title:Engade o título da redirección.\n;fragment:Engade o fragmento da redirección, se o hai (non pode usarse con <var>$1unique</var>).\n;interwiki:Engade o prefixo interwiki da redirección, se o hai (non pode usarse con <var>$1unique</var>).",
+ "apihelp-query+allredirects-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+allredirects-param-limit": "Número total de obxectos a devolver.",
+ "apihelp-query+allredirects-param-dir": "Dirección na cal listar.",
+ "apihelp-query+allredirects-example-B": "Lista as páxinas obxectivo, incluíndo as eliminadas, cos ID das páxinas das que proveñen, comezando en <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-unique": "Lista páxinas obxectivo únicas.",
+ "apihelp-query+allredirects-example-unique-generator": "Obtén tódalas páxinas obxectivo, marcando as eliminadas.",
+ "apihelp-query+allredirects-example-generator": "Obtén as páxinas que conteñen as redireccións.",
+ "apihelp-query+alltransclusions-description": "Listar todas as transclusións (páxinas integradas usando &#123;&#123;x&#125;&#125;), incluíndo as eliminadas.",
+ "apihelp-query+alltransclusions-param-from": "Título da transclusión na que comezar a enumerar.",
+ "apihelp-query+alltransclusions-param-to": "Título da transclusión na que rematar de enumerar.",
+ "apihelp-query+alltransclusions-param-prefix": "Buscar todos os títulos transcluídos que comezan con este valor.",
+ "apihelp-query+alltransclusions-param-unique": "Mostrar só títulos transcluídos distintos. Non pode usarse con <kbd>$1prop=ids</kbd>.\nCando se usa como xenerador, produce páxinas obxectivo no canto de páxinas fonte.",
+ "apihelp-query+alltransclusions-param-prop": "Que partes de información incluír:\n;ids: Engade o ID da páxina da páxina transcluída (non pode usarse con $1unique).\n;title: Engade o título da transclusión.",
+ "apihelp-query+alltransclusions-param-namespace": "Nome de espazos a numerar.",
+ "apihelp-query+alltransclusions-param-limit": "Número total de obxectos a devolver.",
+ "apihelp-query+alltransclusions-param-dir": "Dirección na cal listar.",
+ "apihelp-query+alltransclusions-example-B": "Lista os títulos transcluídos, incluíndo os eliminados, cos ID das páxinas das que proveñen, comezando en <kbd>B</kbd>.",
+ "apihelp-query+alltransclusions-example-unique": "Lista os títulos transcluídos únicos.",
+ "apihelp-query+alltransclusions-example-unique-generator": "Obtén tódolos títulos transcluídos, marcando os eliminados.",
+ "apihelp-query+alltransclusions-example-generator": "Obtén as páxinas que conteñen as transclusións.",
+ "apihelp-query+allusers-description": "Enumerar tódolos usuarios rexistrados.",
+ "apihelp-query+allusers-param-from": "Nome de usuario para comezar a enumeración",
+ "apihelp-query+allusers-param-to": "Nome de usuario para rematar a enumeración.",
+ "apihelp-query+allusers-param-prefix": "Buscar tódolos nomes de usuario que comezan con este valor.",
+ "apihelp-query+allusers-param-dir": "Dirección na que ordenar.",
+ "apihelp-query+allusers-param-group": "Só incluír os usuarios nos grupos dados.",
+ "apihelp-query+allusers-param-excludegroup": "Excluír usuarios nos grupos dados.",
+ "apihelp-query+allusers-param-rights": "Incluír só ós usuarios cos dereitos dados. Non se inclúen grupo implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+ "apihelp-query+allusers-param-prop": "Que información incluír:\n;blockinfo:Engade información sobre o bloque actual do usuario.\n;groups:Lista de grupos nos que está o usuario. Isto usa máis recursos no servidor e pode devolver menos resultados que o límite.\n;implicitgroups:Lista todos os grupos ós que usuario pertence de forma automática.\n;rights:Lista os dereitos que ten o usuario.\n;editcount:Engade o número de edicións do usuario.\n;registration:Engade o selo de tempo do momento no que se rexistrou o usuario, se está dispoñible (pode ser branco).",
+ "apihelp-query+allusers-param-limit": "Número total de nomes de usuario a devolver.",
+ "apihelp-query+allusers-param-witheditsonly": "Só listar usuarios que teñan feito edicións.",
+ "apihelp-query+allusers-param-activeusers": "Só listar usuarios activos {{PLURAL:$1|no último día|nos $1 últimos días}}.",
+ "apihelp-query+allusers-example-Y": "Listar usuarios que comecen por <kbd>Y</kbd>.",
+ "apihelp-query+backlinks-description": "Atopar todas as páxinas que ligan coa páxina dada.",
+ "apihelp-query+backlinks-param-title": "Título a buscar. Non pode usarse xunto con <var>$1pageid</var>.",
+ "apihelp-query+backlinks-param-pageid": "Identificador de páxina a buscar. Non pode usarse xunto con <var>$1title</var>.",
+ "apihelp-query+backlinks-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+backlinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+backlinks-param-filterredir": "Como filtrar as redireccións. Se o valor é <kbd>nonredirects</kbd> cando <var>$1redirect</var> está activa, só se aplica ó segundo nivel.",
+ "apihelp-query+backlinks-param-limit": "Cantas páxinas devolver. Se <var>$1redirect</var> está activa, aplícase o límite a cada nivel de forma separada (isto significa que poden devolverse ata 2 * <var>$1limit</var> resultados).",
+ "apihelp-query+backlinks-param-redirect": "Se a ligazón sobre unha páxina é unha redirección, atopa tamén todas as páxinas que ligan con esa redirección. O límite máximo divídese á metade.",
+ "apihelp-query+backlinks-example-simple": "Mostrar ligazóns á <kbd>Páxina principal<kbd>.",
+ "apihelp-query+backlinks-example-generator": "Obter a información das páxinas que ligan á <kbd>Páxina principal<kbd>.",
+ "apihelp-query+blocks-description": "Listar todos os usuarios e direccións IP bloqueados.",
+ "apihelp-query+blocks-param-start": "Selo de tempo para comezar a enumeración.",
+ "apihelp-query+blocks-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+blocks-param-ids": "Lista de IDs de bloque a listar (opcional).",
+ "apihelp-query+blocks-param-users": "Lista de usuarios a buscar (opcional).",
+ "apihelp-query+blocks-param-ip": "Obter todos os bloques aplicables a esta IPs ou a este rango CIDR, incluíndo bloques de rangos.\nNon pode usarse xunto con <var>$3users</var>. Os rangos CIDR maiores que IPv4/$1 ou IPv6/$2 non se aceptan.",
+ "apihelp-query+blocks-param-limit": "Número máximo de bloques a listar.",
+ "apihelp-query+blocks-param-show": "Só mostrar elementos correspondentes a eses criterios.\nPor exemplo, para ver só bloques indefinidos en direccións IP, ponga <kbd>$1show=ip|!temp</kbd>.",
+ "apihelp-query+blocks-example-simple": "Listar bloques.",
+ "apihelp-query+blocks-example-users": "Lista de bloques de usuarios <kbd>Alice</kbd> e <kbd>Bob</kbd>.",
+ "apihelp-query+categories-description": "Listar todas as categorías ás que pertencen as páxinas.",
+ "apihelp-query+categories-param-prop": "Que propiedades adicionais obter para cada categoría:\n;sortkey:Engade a clave de ordenación (cadea hexadecimal) e o prefixo da clave de ordenación (parte lexible) da categoría.\n;timestamp:Engade o selo de tempo de cando se engadíu a categoría.\n;hidden:Pon unha marca nas categorías que están ocultas con _&#95;HIDDENCAT_&#95;.",
+ "apihelp-query+categories-param-show": "Tipo de categorías a amosar.",
+ "apihelp-query+categories-param-limit": "Cantas categorías devolver.",
+ "apihelp-query+categories-param-categories": "Listar só esas categorías. Útil para verificar se unha páxina concreta está nunha categoría determinada.",
+ "apihelp-query+categories-param-dir": "Dirección na cal listar.",
+ "apihelp-query+categories-example-simple": "Obter a lista de categorías ás que pertence a páxina <kbd>Albert Einstein</kbd>",
+ "apihelp-query+categories-example-generator": "Obter a información de todas as categorías usadas na páxina <kbd>Albert Einstein</kbd>.",
+ "apihelp-query+categoryinfo-description": "Devolver información sobre as categorías dadas.",
+ "apihelp-query+categoryinfo-example-simple": "Obter información sobre <kbd>Category:Foo</kbd> e <kbd>Category:Bar</kbd>",
+ "apihelp-query+categorymembers-description": "Listar tódalas páxinas nunha categoría determinada.",
+ "apihelp-query+categorymembers-param-title": "Que categoría enumerar (obrigatorio). Debe incluír o prefixo <kbd>{{ns:category}}:</kbd>. Non pode usarse xunto con <var>$1pageid</var>.",
+ "apihelp-query+categorymembers-param-pageid": "ID de páxina da categoría a enumerar. Non se pode usar xunto con <var>$1title</var>.",
+ "apihelp-query+categorymembers-param-prop": "Que información incluír:\n;ids:Engade o ID da páxina.\n;title:Engade o título e o ID do espazo de nomes da páxina.\n;sortkey:Engade a clave de ordenación usada para ordenala na categoría (cadea hexadecimal).\n;sortkeyprefix:Engade o prefixo da clave de ordenación usado para ordenala na categoría (parte lexible da clave de ordenación).\n;type:Engade o tipo no que foi categorizado a páxina (páxina, subcategoría ou ficheiro)\n;timestamp:Engade o selo de tempo no que foi incluída a páxina.",
+ "apihelp-query+categorymembers-param-namespace": "Só incluír páxinas nestes espazos de nomes. Decátese de que poden usarse <kbd>$1type=subcat</kbd> ou <kbd>$1type=file</kbd> no canto de <kbd>$1namespace=14</kbd> ou <kbd>6</kbd>.",
+ "apihelp-query+categorymembers-param-type": "Que tipo de membros da categoría incluír. Ignorado cando está activo <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-limit": "Máximo número de páxinas a retornar.",
+ "apihelp-query+categorymembers-param-sort": "Propiedade pola que ordenar.",
+ "apihelp-query+categorymembers-param-dir": "En que dirección ordenar.",
+ "apihelp-query+categorymembers-param-start": "Selo de tempo para comezar o listado. Só pode usarse con <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-end": "Selo de tempo co que rematar o listado. Só pode usarse con <kbd>$1sort=timestamp</kbd>.",
+ "apihelp-query+categorymembers-param-starthexsortkey": "Chave de ordenación coa que comezar o listado, como se indique en <kbd>$1prop=sortkey</kbd>. Pode usarse só con <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-endhexsortkey": "Chave de ordenación coa que rematar o listado, como se indique en <kbd>$1prop=sortkey</kbd>. Pode usarse só con <kbd>$1sort=sortkey</kbd>.",
+ "apihelp-query+categorymembers-param-startsortkeyprefix": "Prefixo da chave de ordenación coa que comezar o listado. Pode usarse só con <kbd>$1sort=sortkey</kbd>. Ignórase <var>$1starthexsortkey</var>.",
+ "apihelp-query+categorymembers-param-endsortkeyprefix": "Prefixo da chave de ordenación ANTES de rematar o listado (e non a, se existe este valor entón non será incluído!). Pode usarse só con <kbd>$1sort=sortkey</kbd>. Ignórase $1endhexsortkey.",
+ "apihelp-query+categorymembers-param-startsortkey": "Usar $1starthexsortkey no canto.",
+ "apihelp-query+categorymembers-param-endsortkey": "Usar $1endhexsortkey no canto.",
+ "apihelp-query+categorymembers-example-simple": "Obter as dez primeiras páxinas de <kbd>Category:Physics</kbd>.",
+ "apihelp-query+categorymembers-example-generator": "Obter a información das primeiras dez páxinas de <kbd>Category:Physics</kbd>.",
+ "apihelp-query+contributors-description": "Obter a lista de contribuidores conectados e o número de contribuidores anónimos dunha páxina.",
+ "apihelp-query+contributors-param-group": "Incluír só ós usuarios dos grupos dados. Non se inclúen grupos implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+ "apihelp-query+contributors-param-excludegroup": "Excluír usuarios nos grupos dados. Non se inclúen grupos implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+ "apihelp-query+contributors-param-rights": "Incluír só ós usuarios cos dereitos dados. Non se inclúen os dereitos dados a grupos implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+ "apihelp-query+contributors-param-excluderights": "Excluír usuarios cos dereitos dados. Non se inclúen os dereitos dados a grupos implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+ "apihelp-query+contributors-param-limit": "Número total de contribuidores a devolver.",
+ "apihelp-query+contributors-example-simple": "Mostrar os contribuidores á páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+deletedrevisions-description": "Obter a información da revisión eliminada.\n\nPode usarse de varias formas:\n#Obter as revisións borradas dun conxunto de páxinas, indicando os títulos ou os IDs das páxinas. Ordenado por título e selo de tempo.\n#Obter datos sobre un conxunto de revisións borradas, indicando os seus IDs e os seus IDs de revisión. Ordenado por ID de revisión.",
+ "apihelp-query+deletedrevisions-param-start": "Selo de tempo no que comezar a enumeración. Ignorado cando se está procesando unha lista de IDs de revisións.",
+ "apihelp-query+deletedrevisions-param-end": "Selo de tempo no que rematar a enumeración. Ignorado cando se está procesando unha lista de IDs de revisións.",
+ "apihelp-query+deletedrevisions-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+ "apihelp-query+deletedrevisions-param-user": "Só listar revisións deste usuario.",
+ "apihelp-query+deletedrevisions-param-excludeuser": "Non listar revisións deste usuario.",
+ "apihelp-query+deletedrevisions-param-limit": "Máximo número de revisións a listar.",
+ "apihelp-query+deletedrevisions-param-prop": "Que propiedades obter:\n;revid:Engade o ID da modificación borrada.\n;parentid:Engade o ID da modificación da modificación anterior da páxina.\n;user:Engade o usuario que fixo a modificación.\n;userid:Engade o ID do usuario que fixo a modificación.\n;comment:Engade o comentario da modificación.\n;parsedcomment:Engade o comentario analizado da modificación.\n;minor:Engade unha marca se a modificación é menor.\n;len:Engade a lonxitude (bytes) da modificación.\n;sha1:Engade a función SHA-1 (base 16) da modificación.\n;content:Engade o contido da modificación.\n;tags:Marcas da modificación.",
+ "apihelp-query+deletedrevisions-example-titles": "Listar as revisións borradas das páxinas <kbd>Main Page</kbd> e <kbd>Talk:Main Page</kbd>, con contido.",
+ "apihelp-query+deletedrevisions-example-revids": "Listar a información para a revisión borrada <kbd>123456</kbd>.",
+ "apihelp-query+deletedrevs-description": "Lista as modificación borradas.\n\nOpera según tres modos:\n#Lista as modificacións borradas dos títulos indicados, ordenados por selo de tempo.\n#Lista as contribucións borradas do usuario indicado, ordenadas por selo de tempo (sen indicar títulos).\n#Lista todas as modificacións borradas no espazo de nomes indicado, ordenadas por título e selo de tempo (sen indicar títulos, sen fixar $1user).\n\nCertos parámetros só se aplican a algúns modos e son ignorados noutros.",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
+ "apihelp-query+deletedrevs-param-start": "Selo de tempo no que comezar a enumeración.",
+ "apihelp-query+deletedrevs-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+deletedrevs-param-from": "Comezar listado neste título.",
+ "apihelp-query+deletedrevs-param-to": "Rematar listado neste título.",
+ "apihelp-query+deletedrevs-param-prefix": "Buscar tódolos títulos de páxina que comezan con este valor.",
+ "apihelp-query+deletedrevs-param-unique": "Só listar unha revisión por cada páxina.",
+ "apihelp-query+deletedrevs-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+ "apihelp-query+deletedrevs-param-user": "Só listar revisións deste usuario.",
+ "apihelp-query+deletedrevs-param-excludeuser": "Non listar revisións deste usuario.",
+ "apihelp-query+deletedrevs-param-namespace": "Só listar páxinas neste espazo de nomes.",
+ "apihelp-query+deletedrevs-param-limit": "Máximo número de revisións a listar.",
+ "apihelp-query+deletedrevs-example-mode1": "Listar as últimas revisións borradas das páxinas <kbd>Main Page</kbd> e <kbd>Talk:Main Page</kbd>, con contido (modo 1).",
+ "apihelp-query+deletedrevs-example-mode2": "Listar as últimas 50 contribucións borradas de <kbd>Bob</kbd> (modo 2).",
+ "apihelp-query+deletedrevs-example-mode3-main": "Listar as primeiras 50 revisións borradas no espazo de nomes principal (modo 3)",
+ "apihelp-query+deletedrevs-example-mode3-talk": "Listar as primeiras 50 páxinas no espazo de nomes {{ns:talk}} (modo 3).",
+ "apihelp-query+disabled-description": "Este módulo de consulta foi desactivado.",
+ "apihelp-query+duplicatefiles-description": "Listar todos os ficheiros que son duplicados dos fichieros dados baseado nos valores da función hash.",
+ "apihelp-query+duplicatefiles-param-limit": "Cantos ficheiros duplicados devolver.",
+ "apihelp-query+duplicatefiles-param-dir": "Dirección na cal listar.",
+ "apihelp-query+duplicatefiles-param-localonly": "Só buscar por ficheiros no repositorio local.",
+ "apihelp-query+duplicatefiles-example-simple": "Buscar duplicados de [[:File:Albert Einstein Head.jpg]]",
+ "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados de tódolos ficheiros",
+ "apihelp-query+embeddedin-description": "Atopar todas as páxinas que inclúen (por transclusión) o título dado.",
+ "apihelp-query+embeddedin-param-title": "Título a buscar. Non pode usarse xunto con $1pageid.",
+ "apihelp-query+embeddedin-param-pageid": "Identificador de páxina a buscar. Non pode usarse xunto con $1title.",
+ "apihelp-query+embeddedin-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+embeddedin-param-dir": "Dirección na cal listar.",
+ "apihelp-query+embeddedin-param-filterredir": "Como filtrar para redireccións.",
+ "apihelp-query+embeddedin-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+embeddedin-example-simple": "Mostrar as páxinas que inclúan <kbd>Template:Stub</kbd>.",
+ "apihelp-query+embeddedin-example-generator": "Obter información sobre as páxinas que inclúen <kbd>Template:Stub</kbd>.",
+ "apihelp-query+extlinks-description": "Devolve todas as URLs externas (sen ser interwikis) das páxinas dadas.",
+ "apihelp-query+extlinks-param-limit": "Cantas ligazóns devolver.",
+ "apihelp-query+extlinks-param-protocol": "Protocolo da URL. Se está baleiro e está activo <var>$1query</var>, o protocolo é <kbd>http</kbd>. Deixar esa variable e a <var>$1query</var> baleiras para listar todas as ligazóns externas.",
+ "apihelp-query+extlinks-param-query": "Buscar cadea sen protocolo. Útil para verificar se unha páxina determinada contén unha URL externa determinada.",
+ "apihelp-query+extlinks-param-expandurl": "Expandir as URLs relativas a un protocolo co protocolo canónico.",
+ "apihelp-query+extlinks-example-simple": "Obter unha de ligazóns externas á <kbd>Páxina Principal<kbd>.",
+ "apihelp-query+exturlusage-description": "Enumerar páxinas que conteñen unha dirección URL dada.",
+ "apihelp-query+exturlusage-param-prop": "Que información incluír:\n;ids:Engade o ID da páxina.\n;title:Engade o título e o ID do espazo de nomes da páxina.\n;url:Engade a URL usada na páxina.",
+ "apihelp-query+exturlusage-param-protocol": "Protocolo da URL. Se está baleiro e está activo <var>$1query</var>, o protocolo é <kbd>http</kbd>. Deixar esa variable e a <var>$1query</var> baleiras para listar todas as ligazóns externas.",
+ "apihelp-query+exturlusage-param-query": "Buscar unha cadea sen protocolo. Ver [[Special:LinkSearch]]. Deixar baleira para listar todas as ligazóns externas.",
+ "apihelp-query+exturlusage-param-namespace": "Espazo de nomes a enumerar.",
+ "apihelp-query+exturlusage-param-limit": "Cantas páxinas devolver.",
+ "apihelp-query+exturlusage-param-expandurl": "Expandir as URLs relativas a un protocolo co protocolo canónico.",
+ "apihelp-query+exturlusage-example-simple": "Mostrar páxinas ligando a <kbd>http://www.mediawiki.org</kbd>.",
+ "apihelp-query+filearchive-description": "Enumerar secuencialmente todos os ficheiros borrados.",
+ "apihelp-query+filearchive-param-from": "Título da imaxe coa que comezar a enumeración.",
+ "apihelp-query+filearchive-param-to": "Título da imaxe coa que rematar a enumeración.",
+ "apihelp-query+filearchive-param-prefix": "Buscar tódolos títulos de imaxes que comezan con este valor.",
+ "apihelp-query+filearchive-param-limit": "Cantas imaxes devolver en total.",
+ "apihelp-query+filearchive-param-dir": "Dirección na cal listar.",
+ "apihelp-query+filearchive-param-sha1": "Función hash SHA1 da imaxe. Invalida $1sha1base36.",
+ "apihelp-query+filearchive-param-sha1base36": "Función hash SHA1 da imaxe en base 36 (usado en MediaWiki).",
+ "apihelp-query+filearchive-example-simple": "Mostrar unha lista de tódolos fichieiros eliminados.",
+ "apihelp-query+filerepoinfo-description": "Devolver a meta información sobre os repositorios de imaxes configurados na wiki.",
+ "apihelp-query+filerepoinfo-param-prop": "Que propiedades do repositorio mostrar (pode haber máis dispoñible nalgunhas wikis):\n;apiurl:URL ó API do repositorio - útil para obter información das imaxes no host.\n;name:A clave do repositorio - usada p. ex. nas variables de retorno de <var>[[mw:Manual:$wgForeignFileRepos|$wgForeignFileRepos]]</var> e [[Special:ApiHelp/query+imageinfo|imageinfo]]\n;displayname:O nome lexible do wiki repositorio.\n;rooturl:URL raíz dos camiños de imaxe.\n;local:Se o repositorio é o repositorio local ou non.",
+ "apihelp-query+filerepoinfo-example-simple": "Obter infomación sobre os repositorios de ficheiros",
+ "apihelp-query+fileusage-description": "Atopar tódalas páxinas que usan os ficheiros dados.",
+ "apihelp-query+fileusage-param-prop": "Que propiedades obter:\n;pageid:ID de cada páxina.\n;título:Título de cada páxina.\n;redirect:Marca de se a páxina é unha redirección.",
+ "apihelp-query+fileusage-param-namespace": "Só incluír páxinas nestes espazos de nomes.",
+ "apihelp-query+fileusage-param-limit": "Cantos mostrar.",
+ "apihelp-query+fileusage-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+ "apihelp-query+fileusage-example-simple": "Obter unha lista de páxinas usando [[:File:Example.jpg]]",
+ "apihelp-query+fileusage-example-generator": "Obter infomación sobre páxinas que usan [[:File:Example.jpg]]",
+ "apihelp-query+imageinfo-description": "Devolve información de ficheiros e historial de subidas.",
+ "apihelp-query+imageinfo-param-prop": "Que información do ficheiro obter:",
+ "apihelp-query+imageinfo-paramvalue-prop-timestamp": "Engade selo de tempo á versión subida.",
+ "apihelp-query+imageinfo-paramvalue-prop-user": "Engade o usuario que subiu cada versión do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-userid": "Engade o ID de usuario que subiu cada versión do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "Comentario da versión.",
+ "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Analizar o comentario da versión.",
+ "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Engade o título canónico do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-url": "Devolve a URL ó ficheiro e á páxina de descrición.",
+ "apihelp-query+imageinfo-paramvalue-prop-size": "Engade o tamaño do ficheiro en bytes e a altura, a anchura e o contador de páxina (se é aplicable).",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias para o tamaño.",
+ "apihelp-query+imageinfo-paramvalue-prop-sha1": "Engade a función hash SHA-1 do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-mime": "Engade o tipo MIME do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "Engade o tipo MIME da miniatura da imaxe (precisa a url e o parámetro $1urlwidth).",
+ "apihelp-query+imageinfo-paramvalue-prop-mediatype": "Engade o tipo do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-metadata": "Lista os metadatos Exif da versión do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-commonmetadata": "Lista os metadatos xenéricos do formato do ficheiro para a versión do ficheiro.",
+ "apihelp-query+imageinfo-paramvalue-prop-extmetadata": "Lista os metadatos combinados formateados de múltiples fontes. Os resultados están en formato HTML.",
+ "apihelp-query+imageinfo-paramvalue-prop-archivename": "Engade o nome de ficheiro da versión do ficheiro para versións anteriores ás últimas.",
+ "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "Engade a profundidade de bits da versión.",
+ "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "Usado pola páxina Special:Upload para obter información sobre un ficheiro existente. Non previsto para usar fóra do núcleo MediaWiki.",
+ "apihelp-query+imageinfo-param-limit": "Cantas revisións de ficheiro a devolver por ficheiro.",
+ "apihelp-query+imageinfo-param-start": "Selo de tempo dende o que comezar a lista.",
+ "apihelp-query+imageinfo-param-end": "Selo de tempo no que rematar a lista.",
+ "apihelp-query+imageinfo-param-urlwidth": "Se $2prop=url está definido, será devolta unha URL a unha imaxe escalada a este ancho.\nPor razóns de rendimento se se usa esta opción, non se devolverán máis de $1 imaxes.",
+ "apihelp-query+imageinfo-param-urlheight": "Similar a $1urlwidth.",
+ "apihelp-query+imageinfo-param-metadataversion": "Versión de metadata a usar. Se <kbd>latest</kbd> está especificado, usa a última versión. Por defecto <kbd>1</kbd> para compatibilidade con versións anteriores.",
+ "apihelp-query+imageinfo-param-extmetadatalanguage": "Que lingua buscar en extmetadata. Isto afecta tanto á tradución a buscar, se hai varias dispoñibles, como a como se formatean cousas como os números e outros valores.",
+ "apihelp-query+imageinfo-param-extmetadatamultilang": "Se as traducións para a propiedade extmetadata están dispoñibles, búscaas todas.",
+ "apihelp-query+imageinfo-param-extmetadatafilter": "Se está especificado e non baleiro, só se devolverán esas claves para $1prop=extmetadata.",
+ "apihelp-query+imageinfo-param-localonly": "Só buscar ficheiros no repositorio local.",
+ "apihelp-query+imageinfo-example-simple": "Busca a información sobre a versión actual de [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageinfo-example-dated": "Busca información sobre as versións de [[:File:Test.jpg]] posteriores a 2008.",
+ "apihelp-query+images-description": "Devolve todos os ficheiros contidos nas páxinas dadas.",
+ "apihelp-query+images-param-limit": "Cantos ficheiros devolver.",
+ "apihelp-query+images-param-images": "Listar só eses ficheiros. Útil para verificar se unha páxina concreta ten un ficheiro determinado.",
+ "apihelp-query+images-param-dir": "Dirección na cal listar.",
+ "apihelp-query+images-example-simple": "Obter unha lista de arquivos empregados na [[Main Page]].",
+ "apihelp-query+images-example-generator": "Obter información sobre todos os ficheiros usados na [[Main Page]].",
+ "apihelp-query+imageusage-description": "Atopar tódalas páxinas que usan o título da imaxe dada.",
+ "apihelp-query+imageusage-param-title": "Título a buscar. Non pode usarse xunto con $1pageid.",
+ "apihelp-query+imageusage-param-pageid": "ID de páxina a buscar. Non pode usarse xunto con $1title.",
+ "apihelp-query+imageusage-param-namespace": "Nome de espazos a numerar.",
+ "apihelp-query+imageusage-param-dir": "Dirección na cal listar.",
+ "apihelp-query+imageusage-param-filterredir": "Como filtrar redireccións. Se se fixa a non redirección cando está activo $1redirect, isto só se aplica ó segundo nivel.",
+ "apihelp-query+imageusage-param-limit": "Cantas páxinas devolver. Se <var>$1redirect</var> está activa, aplícase o límite a cada nivel de forma separada (isto significa que poden devolverse ata 2 * <var>$1limit</var> resultados).",
+ "apihelp-query+imageusage-param-redirect": "Se a ligazón sobre unha páxina é unha redirección, atopa tamén todas as páxinas que ligan con esa redirección. O límite máximo divídese á metade.",
+ "apihelp-query+imageusage-example-simple": "Mostrar as páxinas que usan [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageusage-example-generator": "Obter información sobre as páxinas que usan [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+info-description": "Obter información básica da páxina.",
+ "apihelp-query+info-param-prop": "Que propiedades adicionais obter:",
+ "apihelp-query+info-paramvalue-prop-protection": "Listar o nivel de protección de cada páxina.",
+ "apihelp-query+info-paramvalue-prop-talkid": "O ID de páxina da páxina de conversa para cada páxina que non é páxina de conversa.",
+ "apihelp-query+info-paramvalue-prop-watched": "Listar o estado de vixiancia de cada páxina.",
+ "apihelp-query+info-paramvalue-prop-watchers": "O número de vixiantes, se está permitido.",
+ "apihelp-query+info-paramvalue-prop-notificationtimestamp": "O selo de tempo de notificación da lista de vixiancia de cada páxina.",
+ "apihelp-query+info-paramvalue-prop-subjectid": "O ID de páxina da páxina pai para cada páxina de conversa.",
+ "apihelp-query+info-paramvalue-prop-url": "Devolve unha URL completa, unha URL de modificación, e a URL canónica de cada páxina.",
+ "apihelp-query+info-paramvalue-prop-readable": "Se o usuario pode ler esta páxina.",
+ "apihelp-query+info-paramvalue-prop-preload": "Devolve o texto devolto por EditFormPreloadText.",
+ "apihelp-query+info-paramvalue-prop-displaytitle": "Devolve a forma na que se visualiza actualmente o título da páxina.",
+ "apihelp-query+info-param-testactions": "Proba se o usuario actual pode realizar certas accións na páxina.",
+ "apihelp-query+info-param-token": "Usar [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] no canto diso.",
+ "apihelp-query+info-example-simple": "Obter información sobre a páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+info-example-protection": "Obter información xeral e de protección sobre a páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+iwbacklinks-description": "Atopar todas as páxina que ligan á ligazón interwiki indicada.\n\nPode usarse para atopar todas as ligazóns cun prefixo, ou todas as ligazóns a un título (co prefixo indicado). Se non se usa ningún parámetro funciona como \"todas as ligazóns interwiki\".",
+ "apihelp-query+iwbacklinks-param-prefix": "Prefixo para a interwiki.",
+ "apihelp-query+iwbacklinks-param-title": "Ligazón interwiki a buscar. Debe usarse con <var>$1blprefix</var>.",
+ "apihelp-query+iwbacklinks-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+iwbacklinks-param-prop": "Que propiedades obter:\n;iwprefix:Engade o prefixo da interwiki.\n;iwtitle:Engade o título da interwiki.",
+ "apihelp-query+iwbacklinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+iwbacklinks-example-simple": "Obter as páxinas ligadas a [[wikibooks:Test]]",
+ "apihelp-query+iwbacklinks-example-generator": "Obter información sobre as páxinas que ligan a [[wikibooks:Test]].",
+ "apihelp-query+iwlinks-description": "Devolve todas as ligazóns interwiki ás páxinas indicadas.",
+ "apihelp-query+iwlinks-param-url": "Se obter a URL completa (non pode usarse con $1prop).",
+ "apihelp-query+iwlinks-param-prop": "Que propiedades adicionais obter para cada ligazón interwiki:\n;url:Engade a URL completa.",
+ "apihelp-query+iwlinks-param-limit": "Cantas ligazóns interwiki devolver.",
+ "apihelp-query+iwlinks-param-prefix": "Só devolver ligazóns interwiki con este prefixo.",
+ "apihelp-query+iwlinks-param-title": "Ligazón interwiki a buscar. Debe usarse con <var>$1prefix</var>.",
+ "apihelp-query+iwlinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+iwlinks-example-simple": "Obter as ligazóns interwiki da páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+langbacklinks-description": "Atopar todas as páxinas que ligan coa ligazón de lingua dada. \n\nPode usarse para atopar todas as ligazóns cun código de lingua, ou todas as ligazón a un título (cunha lingua dada). Non usar cun parámetro que sexa \"todas as ligazóns de lingua\".\n\nDecátese que isto pode non considerar as ligazóns de idioma engadidas polas extensións.",
+ "apihelp-query+langbacklinks-param-lang": "Lingua para a ligazón de lingua.",
+ "apihelp-query+langbacklinks-param-title": "Ligazón de lingua a buscar. Debe usarse con $1lang.",
+ "apihelp-query+langbacklinks-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+langbacklinks-param-prop": "Que propiedades obter:\n;lllang:Engade o código de lingua á ligazón de páxina.\n;lltitle:Engade o título da ligazón de lingua.",
+ "apihelp-query+langbacklinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+langbacklinks-example-simple": "Obter as páxinas ligadas a [[:fr:Test]].",
+ "apihelp-query+langbacklinks-example-generator": "Obter información sobre as páxinas que ligan a [[:fr:Test]].",
+ "apihelp-query+langlinks-description": "Devolve todas as ligazóns interwiki ás páxinas indicadas.",
+ "apihelp-query+langlinks-param-limit": "Cantas ligazóns de lingua devolver.",
+ "apihelp-query+langlinks-param-url": "Se obter a URL completa (non pode usarse con <var>$1prop</var>).",
+ "apihelp-query+langlinks-param-prop": "Que propiedades adicionais obter para cada ligazón interlingüística:\n;url:Engade a URL completa.\n;langname:Engade o nome localizado da lingua (o mellor intento). Use <var>$1inlanguagecode</var> para controlar a lingua.\n;autonym:Engade o nome nativo da lingua.",
+ "apihelp-query+langlinks-param-lang": "Devolver só ligazóns de lingua con este código de lingua.",
+ "apihelp-query+langlinks-param-title": "Ligazón a buscar. Debe usarse con <var>$1lang</var>.",
+ "apihelp-query+langlinks-param-dir": "Dirección na cal listar.",
+ "apihelp-query+langlinks-param-inlanguagecode": "Código de lingua para nomes de lingua localizados.",
+ "apihelp-query+langlinks-example-simple": "Obter ligazóns interlingua da páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+links-description": "Devolve todas as ligazóns das páxinas indicadas.",
+ "apihelp-query+links-param-namespace": "Mostra ligazóns só neste espazo de nomes.",
+ "apihelp-query+links-param-limit": "Cantas ligazóns devolver.",
+ "apihelp-query+links-param-titles": "Listar só as ligazóns a eses títulos. Útil para verificar se unha páxina concreta liga a un título determinado.",
+ "apihelp-query+links-param-dir": "Dirección na cal listar.",
+ "apihelp-query+links-example-simple": "Obter as ligazóns da páxina <kbd>Main Page</kbd>.",
+ "apihelp-query+links-example-generator": "Obter información sobre as ligazóns de páxina da <kbd>Main Page</kbd>.",
+ "apihelp-query+links-example-namespaces": "Obter as ligazóns á páxina <kbd>Main Page</kbd> nos espazos de nome {{ns:user}} e {{ns:template}}.",
+ "apihelp-query+linkshere-description": "Atopar todas as páxinas que ligan coas páxinas dadas.",
+ "apihelp-query+linkshere-param-prop": "Que propiedades obter:\n;pageid:ID de cada páxina.\n;título:Título de cada páxina.\n;redirect:Marca de se a páxina é unha redirección.",
+ "apihelp-query+linkshere-param-namespace": "Só incluír páxinas nestes espazos de nomes.",
+ "apihelp-query+linkshere-param-limit": "Cantos mostrar.",
+ "apihelp-query+linkshere-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+ "apihelp-query+linkshere-example-simple": "Obter unha lista que ligan á [[Main Page]]",
+ "apihelp-query+linkshere-example-generator": "Obter a información das páxinas que ligan á [[Main Page]].",
+ "apihelp-query+logevents-description": "Obter os eventos dos rexistros.",
+ "apihelp-query+logevents-param-type": "Filtrar as entradas do rexistro para mostrar só as deste tipo.",
+ "apihelp-query+logevents-param-action": "Filtrar accións no rexistro para mostrar só esta acción. Ignora <var>$1type</var>. Accións comodín como <kbd>action/*</kbd> permiten especificar calquera cadea para o asterisco.",
+ "apihelp-query+logevents-param-start": "Selo de tempo no que comezar a enumeración.",
+ "apihelp-query+logevents-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+logevents-param-user": "Filtrar entradas ás feitas polo usuario indicado.",
+ "apihelp-query+logevents-param-title": "Filtrar entradas ás asociadas á páxina indicada.",
+ "apihelp-query+logevents-param-namespace": "Filtrar entradas ás do espazo de nomes indicado.",
+ "apihelp-query+logevents-param-prefix": "Filtrar entradas ás que comezan por este prefixo.",
+ "apihelp-query+logevents-param-tag": "Só listar entradas de evento marcadas con esta etiqueta.",
+ "apihelp-query+logevents-param-limit": "Número total de entradas de evento a devolver.",
+ "apihelp-query+logevents-example-simple": "Lista de eventos recentes do rexistro.",
+ "apihelp-query+pagepropnames-description": "Listar os nomes de todas as propiedades de páxina usados na wiki.",
+ "apihelp-query+pagepropnames-param-limit": "Máximo número de nomes a retornar.",
+ "apihelp-query+pagepropnames-example-simple": "Obter os dez primeiros nomes de propiedade.",
+ "apihelp-query+pageprops-description": "Obter varias propiedades definidas no contido da páxina.",
+ "apihelp-query+pageprops-param-prop": "Listar só esas propiedades. Útil para verificar se unha páxina concreta usa unha propiedade de páxina determinada.",
+ "apihelp-query+pageprops-example-simple": "Obter as propiedades para <kbd>Category:Foo</kbd>.",
+ "apihelp-query+pageswithprop-description": "Mostrar a lista de páxinas que empregan unha propiedade determinada.",
+ "apihelp-query+pageswithprop-param-propname": "Propiedade de páxina pola que enumerar as páxinas.",
+ "apihelp-query+pageswithprop-param-prop": "Que información incluír:\n;ids:Engade o ID da páxina.\n;title:Engade o título e o ID do espazo de nomes da páxina.\n;value:Engade o valor da propiedade da páxina.",
+ "apihelp-query+pageswithprop-param-limit": "Máximo número de páxinas a retornar.",
+ "apihelp-query+pageswithprop-param-dir": "En que dirección ordenar.",
+ "apihelp-query+pageswithprop-example-simple": "Lista as dez primeiras páxinas que usan <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+ "apihelp-query+pageswithprop-example-generator": "Obter a infomación de páxina das dez primeiras páxinas que usan <code>_&#95;NOTOC_&#95;</code>.",
+ "apihelp-query+prefixsearch-description": "Facer unha busca de prefixo nos títulos das páxinas.",
+ "apihelp-query+prefixsearch-param-search": "Buscar texto.",
+ "apihelp-query+prefixsearch-param-namespace": "Espazo de nomes no que buscar.",
+ "apihelp-query+prefixsearch-param-limit": "Número máximo de resultados a visualizar.",
+ "apihelp-query+prefixsearch-param-offset": "Número de resultados a saltar.",
+ "apihelp-query+prefixsearch-example-simple": "Buscar títulos de páxina que comecen con <kbd>meaning</kbd>.",
+ "apihelp-query+protectedtitles-description": "Listar todos os títulos protexidos en creación.",
+ "apihelp-query+protectedtitles-param-namespace": "Só listar títulos nestes espazos de nomes.",
+ "apihelp-query+protectedtitles-param-level": "Só listar títulos con estos niveis de protección.",
+ "apihelp-query+protectedtitles-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+protectedtitles-param-start": "Comezar a listar neste selo de tempo de protección.",
+ "apihelp-query+protectedtitles-param-end": "Rematar de listar neste selo de tempo de protección.",
+ "apihelp-query+protectedtitles-param-prop": "Que propiedades obter:\n;timestamp:Engade o selo de tempo de cando se fixo a protección.\n;user:Engade o usuario que fixo a protección.\n;userid:Engade o ID do usuario que fixo a protección.\n;comment:Engade o comentario da protección.\n;parsedcomment:Engade o comentario analizado da protección.\n;expiry:Engade o selo de tempo no que rematará a protección\n;level:Engade o nivel de protección.",
+ "apihelp-query+protectedtitles-example-simple": "Listar títulos protexidos",
+ "apihelp-query+protectedtitles-example-generator": "Atopar ligazóns ós títulos protexidos no espazo de nomes principal",
+ "apihelp-query+querypage-description": "Obtén unha lista proporcionada por unha páxina especial basada en QueryPage.",
+ "apihelp-query+querypage-param-page": "Nome da páxina especial. Teña en conta que diferencia entre maiúsculas e minúsculas.",
+ "apihelp-query+querypage-param-limit": "Número de resultados a visualizar.",
+ "apihelp-query+querypage-example-ancientpages": "Resultados devoltos de [[Special:Ancientpages]].",
+ "apihelp-query+random-param-namespace": "Devolver páxinas só neste espazo de nomes.",
+ "apihelp-query+random-param-limit": "Limitar cantas páxinas aleatorias se van devolver.",
+ "apihelp-query+random-param-redirect": "Cargar unha redirección aleatoria no canto dunha páxina aleatoria.",
+ "apihelp-query+random-example-simple": "Obter dúas páxinas aleatorias do espazo de nomes principal.",
+ "apihelp-query+random-example-generator": "Obter a información da páxina de dúas páxinas aleatorias do espazo de nomes principal.",
+ "apihelp-query+recentchanges-description": "Enumerar cambios recentes.",
+ "apihelp-query+recentchanges-param-start": "Selo de tempo para comezar a enumeración.",
+ "apihelp-query+recentchanges-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+recentchanges-param-namespace": "Filtrar os cambios a só eses espazos de nomes.",
+ "apihelp-query+recentchanges-param-user": "Só listar cambios deste usuario.",
+ "apihelp-query+recentchanges-param-excludeuser": "Non listar cambios deste usuario.",
+ "apihelp-query+recentchanges-param-tag": "Só listar cambios marcados con esta etiqueta.",
+ "apihelp-query+recentchanges-param-token": "Usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> no canto diso.",
+ "apihelp-query+recentchanges-param-show": "Só mostrar elementos que cumpran esos criterios. Por exemplo, para ver só edicións menores feitas por usuarios conectados, activar $1show=minor|!anon.",
+ "apihelp-query+recentchanges-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+recentchanges-param-type": "Que tipos de cambios mostrar.",
+ "apihelp-query+recentchanges-param-toponly": "Listar só cambios que son a última revisión.",
+ "apihelp-query+recentchanges-example-simple": "Listar cambios recentes.",
+ "apihelp-query+recentchanges-example-generator": "Obter a información de páxina sobre cambios recentes sen vixiancia.",
+ "apihelp-query+redirects-description": "Devolve todas as redireccións das páxinas indicadas.",
+ "apihelp-query+redirects-param-prop": "Que propiedades recuperar:\n;pageid:ID de páxina de cada redirección.\n;title:Título de cada redirección.\n;fragment:Fragmento de cada redirección, se hai algún.",
+ "apihelp-query+redirects-param-namespace": "Só incluir páxinas nestes espacios de nomes.",
+ "apihelp-query+redirects-param-limit": "Cantos redireccións devolver.",
+ "apihelp-query+redirects-param-show": "Só mostrar elementos que cumpran estos criterios:\n;fragment:Só mostrar redireccións que teñan un fragmento.\n;!fragment:Só mostrar redireccións que non teñan un fragmento.",
+ "apihelp-query+redirects-example-simple": "Obter unha lista de redireccións á [[Main Page]]",
+ "apihelp-query+redirects-example-generator": "Obter información sobre tódalas redireccións á [[Main Page]]",
+ "apihelp-query+revisions-description": "Obter información da modificación.\n\nPode usarse de varias formas:\n#Obter datos sobre un conxunto de páxinas (última modificación), fixando os títulos ou os IDs das páxinas.\n#Obter as modificacións da páxina indicada, usando os títulos ou os IDs de páxinas con comezar, rematar ou límite.\n#Obter os datos sobre un conxunto de modificacións fixando os seus IDs cos seus IDs de modificación.",
+ "apihelp-query+revisions-paraminfo-singlepageonly": "Só pode usarse cunha única páxina (mode #2).",
+ "apihelp-query+revisions-param-startid": "Desde que ID de revisión comezar a enumeración.",
+ "apihelp-query+revisions-param-endid": "Rematar a enumeración de revisión neste ID de revisión.",
+ "apihelp-query+revisions-param-start": "Desde que selo de tempo comezar a enumeración.",
+ "apihelp-query+revisions-param-end": "Enumerar desde este selo de tempo.",
+ "apihelp-query+revisions-param-user": "Só incluir revisión feitas polo usuario.",
+ "apihelp-query+revisions-param-excludeuser": "Excluír revisións feitas polo usuario.",
+ "apihelp-query+revisions-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+ "apihelp-query+revisions-param-token": "Que identificadores obter para cada revisión.",
+ "apihelp-query+revisions-example-content": "Obter datos con contido da última revisión dos títulos <kbd>API</kbd> e <kbd>Main Page</kbd>.",
+ "apihelp-query+revisions-example-last5": "Mostrar as cinco últimas revisión da <kbd>Páxina Principal</kbd>.",
+ "apihelp-query+revisions-example-first5": "Mostar as cinco primeiras revisións da <kbd>Páxina Principal</kbd>.",
+ "apihelp-query+revisions-example-first5-after": "Mostrar as cinco primeiras revisións da <kbd>Páxina Principal</kbd> feitas despois de 2006-05-01.",
+ "apihelp-query+revisions-example-first5-not-localhost": "Mostrar as cinco primeiras revisións da <kbd>Páxina Principal</kbd> que non foron feitas polo usuario anónimo <kbd>127.0.0.1</kbd>.",
+ "apihelp-query+revisions-example-first5-user": "Mostrar as cinco primeiras revisión da <kbd>Páxina Principal</kbd> feitas polo usuario <kbd>MediaWiki default</kbd>.",
+ "apihelp-query+revisions+base-param-limit": "Limitar cantas revisións se van devolver.",
+ "apihelp-query+revisions+base-param-expandtemplates": "Expandir os modelos no contido da revisión (require $1prop=content).",
+ "apihelp-query+revisions+base-param-generatexml": "Xenerar a árbore de análise XML para o contido da revisión (require $1prop=content).",
+ "apihelp-query+revisions+base-param-parse": "Analizar o contido da revisión (require $1prop=content). Por razóns de rendemento, se se usa esta opción, $1limit cámbiase a 1.",
+ "apihelp-query+revisions+base-param-section": "Recuperar unicamente o contido deste número de sección.",
+ "apihelp-query+revisions+base-param-diffto": "ID de revisión a comparar con cada revisión. Use <kbd>prev</kbd>, <kbd>next</kbd> e <kbd>cur</kbd> para a versión precedente, seguinte e actual respectivamente.",
+ "apihelp-query+revisions+base-param-difftotext": "Texto co que comparar cada revisión. Só compara un número limitado de revisións. Ignora <var>$1diffto</var>. Se <var>$1section</var> ten valor, só se comparará co texto esa sección.",
+ "apihelp-query+revisions+base-param-contentformat": "Formato de serialización usado por <var>$1difftotext</var> e esperado para a saída do contido.",
+ "apihelp-query+search-description": "Facer unha busca por texto completo.",
+ "apihelp-query+search-param-search": "Buscar tódolos títulos de páxina (ou contido) que teñan este valor.",
+ "apihelp-query+search-param-namespace": "Buscar só nestes espazos de nomes.",
+ "apihelp-query+search-param-what": "Que tipo de busca lanzar.",
+ "apihelp-query+search-param-info": "Que metadatos devolver.",
+ "apihelp-query+search-param-limit": "Número total de páxinas a devolver.",
+ "apihelp-query+search-param-interwiki": "Incluir na busca resultados de interwikis, se é posible.",
+ "apihelp-query+search-param-backend": "Que servidor de busca usar, se non se indica usa o que hai por defecto.",
+ "apihelp-query+search-example-simple": "Buscar por <kbd>significado</kbd>.",
+ "apihelp-query+search-example-text": "Buscar texto por <kbd>significado</kbd>.",
+ "apihelp-query+search-example-generator": "Obter información da páxina sobre as páxinas devoltas por unha busca por <kbd>significado</kbd>.",
+ "apihelp-query+siteinfo-description": "Devolver información xeral sobre o sitio.",
+ "apihelp-query+siteinfo-param-filteriw": "Só devolver entradas locais ou só non locais da correspondencia interwiki.",
+ "apihelp-query+siteinfo-param-showalldb": "Listar todos os servidores de base de datos, non só o que teña máis retardo.",
+ "apihelp-query+siteinfo-param-numberingroup": "Listar o número de usuarios nos grupos de usuarios.",
+ "apihelp-query+siteinfo-param-inlanguagecode": "Código de lingua para os nomes de lingua localizados (a mellor forma posible) e nomes de presentación.",
+ "apihelp-query+siteinfo-example-simple": "Obter información do sitio.",
+ "apihelp-query+siteinfo-example-interwiki": "Obter unha lista de prefixos interwiki locais.",
+ "apihelp-query+siteinfo-example-replag": "Revisar o retardo de replicación actual.",
+ "apihelp-query+stashimageinfo-description": "Devolve a información dos ficheiros almacenados.",
+ "apihelp-query+stashimageinfo-param-filekey": "Clave que identifica unha subida precedente e que foi almacenada temporalmente.",
+ "apihelp-query+stashimageinfo-param-sessionkey": "Alias para $1filekey, para compatibilidade con versións antigas.",
+ "apihelp-query+stashimageinfo-example-simple": "Devolve a información dun ficheiro almacenado.",
+ "apihelp-query+stashimageinfo-example-params": "Devolve as miniaturas de dous ficheiros almacenados.",
+ "apihelp-query+tags-description": "Lista de marcas de cambios.",
+ "apihelp-query+tags-param-limit": "Máximo número de etiquetas a listar.",
+ "apihelp-query+tags-example-simple": "Listar as marcas dispoñibles",
+ "apihelp-query+templates-description": "Devolve todas as páxinas incluídas na páxina indicada.",
+ "apihelp-query+templates-param-namespace": "Mostrar modelos só neste espazo de nomes.",
+ "apihelp-query+templates-param-limit": "Número de modelos a devolver.",
+ "apihelp-query+templates-param-templates": "Listar só eses modelos. Útil para verificar se unha páxina concreta ten un modelo determinado.",
+ "apihelp-query+templates-param-dir": "Dirección na cal listar.",
+ "apihelp-query+templates-example-simple": "Coller os modelos usado na <kbd>Páxina Principal</kbd>.",
+ "apihelp-query+templates-example-generator": "Obter información sobre os modelos usados na <kbd>Páxina Principal</kbd>.",
+ "apihelp-query+templates-example-namespaces": "Obter páxinas nos espazos de nomes {{ns:user}} e {{ns:template}} que se transclúen na <kbd>Páxina Principal</kbd>.",
+ "apihelp-query+tokens-description": "Recupera os identificadores das accións de modificación de datos.",
+ "apihelp-query+tokens-param-type": "Tipos de identificadores a consultar.",
+ "apihelp-query+tokens-example-simple": "Recuperar un identificador csrf (por defecto).",
+ "apihelp-query+tokens-example-types": "Recuperar un identificador vixiancia e un de patrulla.",
+ "apihelp-query+transcludedin-description": "Atopar todas as páxinas que inclúen ás páxinas indicadas.",
+ "apihelp-query+transcludedin-param-prop": "Que propiedades obter:\n;pageid:ID de páxina de cada páxina.\n;title:Título de cada páxina.\n;redirect:Marca si a páxina é unha redirección.",
+ "apihelp-query+transcludedin-param-namespace": "Só incluir páxinas nestes espacios de nomes.",
+ "apihelp-query+transcludedin-param-limit": "Cantos mostrar.",
+ "apihelp-query+transcludedin-param-show": "Mostrar só elementos que cumpren estes criterios:\n;redirect:Só mostra redireccións.\n;!redirect:Só mostra as que non son redireccións.",
+ "apihelp-query+transcludedin-example-simple": "Obter unha lista de páxinas que inclúen a <kbd>Main Page</kbd>.",
+ "apihelp-query+transcludedin-example-generator": "Obter información sobre as páxinas que inclúen <kbd>Main Page</kbd>.",
+ "apihelp-query+usercontribs-description": "Mostrar tódalas edicións dun usuario.",
+ "apihelp-query+usercontribs-param-limit": "Máximo número de contribucións a mostar.",
+ "apihelp-query+usercontribs-param-start": "Selo de tempo de comezo ó que volver.",
+ "apihelp-query+usercontribs-param-end": "Selo de tempo de fin ó que volver.",
+ "apihelp-query+usercontribs-param-user": "Usuarios para os que recuperar as contribucións.",
+ "apihelp-query+usercontribs-param-userprefix": "Recuperar as contribucións de todos os usuarios cuxo nome comece por este valor. Ignora $1user.",
+ "apihelp-query+usercontribs-param-namespace": "Só listar contribucións nestes espazos de nomes.",
+ "apihelp-query+usercontribs-param-show": "Só mostrar elementos que cumpran estos criterios, p.ex. só edicións menores: <kbd>$2show=!minor</kbd>.\n\nSe está fixado <kbd>$2show=patrolled</kbd> ou <kbd>$2show=!patrolled</kbd>, as modificacións máis antigas que <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|segundo|segundos}}) non se mostrarán.",
+ "apihelp-query+usercontribs-param-tag": "Só listar revisións marcadas con esta etiqueta.",
+ "apihelp-query+usercontribs-param-toponly": "Listar só cambios que son a última revisión.",
+ "apihelp-query+usercontribs-example-user": "Mostrar as contribucións do usuario <kbd>Exemplo</kbd>.",
+ "apihelp-query+usercontribs-example-ipprefix": "Mostrar contribucións de tódalas direccións IP que comezan por <kbd>192.0.2.</kbd>.",
+ "apihelp-query+userinfo-description": "Obter información sobre o usuario actual.",
+ "apihelp-query+userinfo-example-simple": "Obter información sobre o usuario actual.",
+ "apihelp-query+userinfo-example-data": "Obter información adicional sobre o usuario actual.",
+ "apihelp-query+users-description": "Obter información sobre unha lista de usuarios.",
+ "apihelp-query+users-param-prop": "Que información incluír:\n;blockinfo:Etiquetas se o usuario está bloqueado, por quen, e por que razón.\n;groups:Lista todos os grupos ós que pertence cada usuario.\n;implicitgroups:Lista os grupos dos que un usuario é membro de forma automatica.\n;rights:Lista todos os dereitos que ten cada usuario.\n;editcount:Engade o contador de edicións do usuario.\n;registration:Engade o selo de tempo do rexistro do usuario.\n;emailable:Marca se o usuario pode e quere recibir correos usando [[Special:Emailuser]].\n;gender:Marca o xénero do usuario. Devolve \"home\", \"muller\" ou \"descoñecido\".",
+ "apihelp-query+users-param-users": "Lista de usuarios para os que obter información.",
+ "apihelp-query+users-param-token": "Usar <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> no canto diso.",
+ "apihelp-query+users-example-simple": "Mostar información para o usuario <kbd>Exemplo</kbd>.",
+ "apihelp-query+watchlist-description": "Ver os cambios recentes das páxinas na lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-param-allrev": "Incluír múltiples revisións da mesma páxina dentro do intervalo de tempo indicado.",
+ "apihelp-query+watchlist-param-start": "Selo de tempo para comezar a enumeración",
+ "apihelp-query+watchlist-param-end": "Selo de tempo para rematar a enumeración.",
+ "apihelp-query+watchlist-param-namespace": "Filtrar os cambios a só os espazos de nomes indicados.",
+ "apihelp-query+watchlist-param-user": "Só listar cambios deste usuario.",
+ "apihelp-query+watchlist-param-excludeuser": "Non listar cambios deste usuario.",
+ "apihelp-query+watchlist-param-limit": "Cantos resultados totais mostrar por petición.",
+ "apihelp-query+watchlist-param-show": "Só mostrar elementos que cumpran esos criterios. Por exemplo, para ver só edicións menores feitas por usuarios conectados, activar $1show=minor|!anon.",
+ "apihelp-query+watchlist-param-type": "Que tipos de cambios mostrar:\n;edit:Modificacións normais de páxina.\n;external:Modificacións externas.\n;new:Creación de páxinas.\n;log:Entradas no rexistro.",
+ "apihelp-query+watchlist-param-owner": "Usado con $1token para acceder á lista de páxinas de vixiancia doutro usuario.",
+ "apihelp-query+watchlist-param-token": "Identificador de seguridade (dispoñible nas [[Special:Preferences#mw-prefsection-watchlist|preferencias]] de usuario) para permitir o acceso a outros á súa páxina de vixiancia.",
+ "apihelp-query+watchlist-example-simple": "Listar a última revisión das páxinas recentemente modificadas da lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-example-props": "Buscar información adicional sobre a última revisión das páxinas modificadas recentemente da lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-example-allrev": "Buscar a información sobre todos os cambios recentes das páxinas da lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-example-generator": "Buscar a información de páxina das páxinas cambiadas recentemente da lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-example-generator-rev": "Buscar a información da revisión dos cambios recentes de páxinas na lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlist-example-wlowner": "Listar a última revisión das páxinas cambiadas recentemente da lista de vixiancia do usuario <kbd>Example</kbd>.",
+ "apihelp-query+watchlistraw-description": "Obter todas as páxinas da lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlistraw-param-namespace": "Só listar páxinas nestes espazos de nomes.",
+ "apihelp-query+watchlistraw-param-limit": "Cantos resultados totais mostrar por petición.",
+ "apihelp-query+watchlistraw-param-prop": "Que propiedades adicionais obter:\n;changed:Engade o selo de tempo da última notificación ó usuario dunha modificación.",
+ "apihelp-query+watchlistraw-param-show": "Só listar os elementos que cumplen estos criterios.",
+ "apihelp-query+watchlistraw-param-owner": "Usado con $1token para acceder á lista de páxinas de vixiancia doutro usuario.",
+ "apihelp-query+watchlistraw-param-token": "Identificador de seguridade (dispoñible nas [[Special:Preferences#mw-prefsection-watchlist|preferencias]] de usuario) para permitir o acceso a outros á súa páxina de vixiancia.",
+ "apihelp-query+watchlistraw-example-simple": "Listar páxinas na lista de vixiancia do usuario actual.",
+ "apihelp-query+watchlistraw-example-generator": "Buscar a información de páxina das páxinas da lista de vixiancia do usuario actual.",
+ "apihelp-revisiondelete-description": "Borrar e restaurar revisións.",
+ "apihelp-revisiondelete-param-type": "Tipo de borrado de revisión a ser tratada.",
+ "apihelp-revisiondelete-param-target": "Título de páxina para o borrado da revisión, se requerido para o tipo.",
+ "apihelp-revisiondelete-param-ids": "Identificadores para as revisións a ser borradas.",
+ "apihelp-revisiondelete-param-hide": "Que ocultar para cada revisión.",
+ "apihelp-revisiondelete-param-show": "Que mostrar para cada revisión.",
+ "apihelp-revisiondelete-param-suppress": "Eliminar os datos dos administradores así coma dos doutros.",
+ "apihelp-revisiondelete-param-reason": "Razón para o borrado ou restaurado.",
+ "apihelp-revisiondelete-example-revision": "Ocultar contido para revisión <kbd>12345</kbd> na <kbd>Páxina Principal</kbd>.",
+ "apihelp-revisiondelete-example-log": "Ocultar todos os datos da entrada de rexistro <kbd>67890</kbd> coa razón <kbd>BLP violation</kbd>.",
+ "apihelp-rollback-description": "Desfacer a última modificación da páxina.\n\nSe o último usuario que modificou a páxina fixo varias modificacións nunha fila, desfaranse todas.",
+ "apihelp-rollback-param-title": "Título da páxina a desfacer. Non pode usarse xunto con <var>$1pageid</var>.",
+ "apihelp-rollback-param-pageid": "ID da páxina a desfacer. Non pode usarse xunto con <var>$1title</var>.",
+ "apihelp-rollback-param-user": "Nome do usuario cuxas modificacións van a desfacerse.",
+ "apihelp-rollback-param-summary": "Personalizar o resumo de edición. Se está baleiro, usarase o resumo por defecto.",
+ "apihelp-rollback-param-markbot": "Marcar as edicións revertidas e a reversión como edicións de bot.",
+ "apihelp-rollback-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-rollback-example-simple": "Desfacer as últimas edicións á <kbd>Páxina Principal</kbd> do usuario <kbd>Exemplo</kbd>.",
+ "apihelp-rollback-example-summary": "Desfacer as últimas edicións á páxina <kbd>Main Page</kbd> polo usuario da dirección IP <kbd>192.0.2.5</kbd> co resumo de edición <kbd>Revertindo vandalismo</kbd>, marcar esas edicións e a reversión como edicións de bot.",
+ "apihelp-rsd-description": "Exportar un esquema RSD (Really Simple Discovery, Descubrimento Moi Simple).",
+ "apihelp-rsd-example-simple": "Exportar o esquema RSD.",
+ "apihelp-setnotificationtimestamp-description": "Actualiza o selo de tempo de notificación das páxinas vixiadas.\n\nIsto afecta ó resalte das páxinas modificadas na lista de vixiancia e historial, e o envío de correo cando a preferencia \"Mandarme un correo cando cambie unha páxina da miña lista de vixiancia\" está activa.",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "Traballar en tódalas páxinas vixiadas.",
+ "apihelp-setnotificationtimestamp-param-timestamp": "Selo de tempo ó que fixar a notificación.",
+ "apihelp-setnotificationtimestamp-param-torevid": "Modificación á que fixar o selo de tempo de modificación (só unha páxina).",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "Modificación na que fixar o selo de tempo de modificación máis recente (só unha páxina).",
+ "apihelp-setnotificationtimestamp-example-all": "Restaurar o estado de notificación para toda a páxina de vixiancia",
+ "apihelp-setnotificationtimestamp-example-page": "Restaurar o estado de notificación para a <kbd>Páxina Principal</kbd>.",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "Fixar o selo de tempo de notificación para a <kbd>Main page</kbd> de forma que todas as edicións dende o 1 se xaneiro de 2012 queden sen revisar.",
+ "apihelp-setnotificationtimestamp-example-allpages": "Restaurar o estado de notificación para as páxinas no espazo de nomes de <kbd>{{ns:user}}</kbd>.",
+ "apihelp-tokens-description": "Obter os identificadores para accións de modificación de datos.\n\nEste módulo está obsoleto e foi reemprazado por [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
+ "apihelp-tokens-param-type": "Tipos de identificadores a consultar.",
+ "apihelp-tokens-example-edit": "Recuperar un identificador de modificación (por defecto).",
+ "apihelp-tokens-example-emailmove": "Recuperar un identificador de correo e un identificador de movemento.",
+ "apihelp-unblock-description": "Desbloquear un usuario.",
+ "apihelp-unblock-param-id": "ID do bloque a desbloquear (obtido de <kbd>list=blocks</kbd>). Non pode usarse xunto con <var>$1user</var>.",
+ "apihelp-unblock-param-user": "Nome de usuario, dirección IP ou rango de direccións IP a desbloquear. Non pode usarse xunto con <var>$1id</var>.",
+ "apihelp-unblock-param-reason": "Razón para desbloquear.",
+ "apihelp-unblock-example-id": "Desbloquear bloqueo ID #<kbd>105</kbd>.",
+ "apihelp-unblock-example-user": "Desbloquear usuario <kbd>Bob</kbd> con razón <kbd>Síntoo Bob</kbd>.",
+ "apihelp-undelete-description": "Restaurar modificacións dunha páxina borrada.\n\nUnha lista de modificacións borradas (incluíndo os seus selos de tempo) pode consultarse a través de [[Special:ApiHelp/query+deletedrevs|list=deletedrevs]], e unha lista de IDs de ficheiros borrados pode consultarse a través de [[Special:ApiHelp/query+filearchive|list=filearchive]].",
+ "apihelp-undelete-param-title": "Título da páxina a restaurar.",
+ "apihelp-undelete-param-reason": "Razón para restaurar.",
+ "apihelp-undelete-param-timestamps": "Selos de tempo das modificacións a restaurar. Se <var>$1timestamps</var> e <var>$1fileids</var> están baleiras, restaurarase todo.",
+ "apihelp-undelete-param-fileids": "IDs das modificacións de ficheiro a restaurar. Se <var>$1timestamps</var> e <var>$1fileids</var> están baleiras, serán restauradas todas.",
+ "apihelp-undelete-param-watchlist": "Engadir ou eliminar a páxina da lista de vixiancia do usuario actual sen condicións, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-undelete-example-page": "Restaurar a <kbd>Páxina Principal</kbd>.",
+ "apihelp-undelete-example-revisions": "Restaurar dúas revisións de <kbd>[[Main Page]]</kbd>.",
+ "apihelp-upload-param-filename": "Nome de ficheiro obxectivo.",
+ "apihelp-upload-param-comment": "Subir comentario. Tamén usado como texto da páxina inicial para ficheiros novos se non se especifica <var>$1text</var>.",
+ "apihelp-upload-param-text": "Texto da páxina inicial para novos ficheiros.",
+ "apihelp-upload-param-watch": "Vixiar a páxina.",
+ "apihelp-upload-param-watchlist": "Engadir ou eliminar sen condicións a páxina da lista de vixiancia do usuario actual, use as preferencias ou non cambie a vixiancia.",
+ "apihelp-upload-param-ignorewarnings": "Ignorar as advertencias.",
+ "apihelp-upload-param-file": "Contido do ficheiro.",
+ "apihelp-upload-param-url": "URL onde buscar o ficheiro.",
+ "apihelp-upload-param-filekey": "Clave que identifica unha subida precedente e que foi almacenada temporalmente.",
+ "apihelp-upload-param-sessionkey": "Igual a $1filekey, mantido por razóns de compatibilidade con procesos antigos.",
+ "apihelp-upload-param-stash": "Se está indicado, o servidor almacenará o ficheiro temporalmente no canto de engadilo ó repositorio.",
+ "apihelp-upload-param-filesize": "Tamaño de ficheiro completo da carga.",
+ "apihelp-upload-param-offset": "Desaxuste do bloque en bytes.",
+ "apihelp-upload-param-chunk": "Contido do bloque.",
+ "apihelp-upload-param-async": "Facer de forma asíncrona as operacións de ficheiro potencialmente grandes cando sexa posible.",
+ "apihelp-upload-param-asyncdownload": "Facer de forma asíncrona a busca dunha URL.",
+ "apihelp-upload-param-leavemessage": "Se se usa asyncdownload, deixar unha mensaxe na páxina de conversa do usuario cando se remate.",
+ "apihelp-upload-param-statuskey": "Buscar o estado da subida para esta clave de ficheiro (subida por URL).",
+ "apihelp-upload-param-checkstatus": "Só buscar o estado da subida da clave de ficheiro indicada.",
+ "apihelp-upload-example-url": "Carga dunha URL",
+ "apihelp-upload-example-filekey": "Completar carga que fallou debido a avisos",
+ "apihelp-userrights-description": "Cambiar a pertencia dun usuario a un grupo.",
+ "apihelp-userrights-param-user": "Nome de usuario.",
+ "apihelp-userrights-param-userid": "ID de usuario.",
+ "apihelp-userrights-param-add": "Engadir o usuario a estes grupos.",
+ "apihelp-userrights-param-remove": "Eliminar o usuario destes grupos.",
+ "apihelp-userrights-param-reason": "Motivo para o cambio.",
+ "apihelp-userrights-example-user": "Engadir o usuario <kbd>FooBot</kbd> ó grupo <kbd>bot</kbd>, e eliminar dos grupos <kbd>sysop</kbd> e <kbd>burócrata</kbd>.",
+ "apihelp-userrights-example-userid": "Engadir ó usuario con ID <kbd>123</kbd> ó grupo <kbd>bot</kbd>, e borralo dos grupos <kbd>sysop</kbd> e <kbd>burócrata</kbd>.",
+ "apihelp-watch-description": "Engadir ou borrar páxinas da lista de vixiancia do usuario actual.",
+ "apihelp-watch-param-title": "Páxina a vixiar/deixar de vixiar. Usar no canto <var>$1titles</var>.",
+ "apihelp-watch-param-unwatch": "Se está definido, a páxina deixará de estar vixiada en vez de vixiada.",
+ "apihelp-watch-example-watch": "Vixiar a páxina <kbd>Páxina Principal</kbd>.",
+ "apihelp-watch-example-unwatch": "Deixar de vixiar a páxina <kbd>Páxina Principal</kbd>.",
+ "apihelp-watch-example-generator": "Vixiar as primeiras páxinas no espazo de nomes principal",
+ "apihelp-format-example-generic": "Formatar o resultado da consulta no formato $1.",
+ "apihelp-dbg-description": "Datos de saída en formato <code>var_export()</code> de PHP.",
+ "apihelp-dbgfm-description": "Datos de saída en formato <code>var_export()</code> de PHP(impresión en HTML).",
+ "apihelp-dump-description": "Datos de saída en formato PHP <code>var_dump()</code>.",
+ "apihelp-dumpfm-description": "Datos de saída en formato <code>var_dump()</code> de PHP(impresión en HTML).",
+ "apihelp-json-description": "Datos de saída en formato JSON.",
+ "apihelp-json-param-callback": "Se está especificado, inclúe a saída na chamada da función indicada. Para maior seguridade, todos os datos específicos do usuario serán restrinxidos.",
+ "apihelp-json-param-utf8": "Se está especificado, codifica a maioría (pero non todos) dos caracteres ASCII como UTF-8 no canto de reemprazalos con secuencias de escape hexadecimais.",
+ "apihelp-jsonfm-description": "Datos de saída en formato JSON(impresión en HTML).",
+ "apihelp-none-description": "Ningunha saída.",
+ "apihelp-php-description": "Datos de saída en formato serializado de PHP.",
+ "apihelp-phpfm-description": "Datos de saída en formato serializado de PHP(impresión en HTML).",
+ "apihelp-rawfm-description": "Datos de saída cos elementos de depuración en formato JSON(impresión en HTML).",
+ "apihelp-txt-description": "Datos de saída en formato PHP <code>print_r()</code>.",
+ "apihelp-txtfm-description": "Datos de saída en formato <code>print_r()</code> de PHP(impresión en HTML).",
+ "apihelp-wddx-description": "Datos de saída en formato WDDX.",
+ "apihelp-wddxfm-description": "Datos de saída en formato WDDX(impresión en HTML).",
+ "apihelp-xml-description": "Datos de saída en formato XML.",
+ "apihelp-xml-param-xslt": "Se está indicado, engade o nome da páxina como unha folla de estilo XSL. O valor debe ser un título no espazo de nomes {{ns:mediawiki}} rematando con <code>.xsl</code>.",
+ "apihelp-xml-param-includexmlnamespace": "Se está indicado, engade un espazo de nomes XML.",
+ "apihelp-xmlfm-description": "Datos de saída en formato XML(impresión en HTML).",
+ "apihelp-yaml-description": "Datos de saída en formato YAML.",
+ "apihelp-yamlfm-description": "Datos de saída en formato YAML(impresión en HTML).",
+ "api-format-title": "Resultado de API de MediaWiki",
+ "api-orm-param-props": "Campos a consultar.",
+ "api-orm-param-limit": "Número máximo de filas a mostrar.",
+ "api-pageset-param-titles": "Lista de títulos nos que traballar.",
+ "api-pageset-param-pageids": "Lista de identificadores de páxina nos que traballar.",
+ "api-pageset-param-revids": "Unha lista de IDs de modificacións sobre as que traballar.",
+ "api-pageset-param-generator": "Obter a lista de páxinas sobre as que traballar executando o módulo de consulta especificado.\n\n<strong>Nota:</strong>Os nomes de parámetro do xerador deben comezar cunha \"g\", vexa os exemplos.",
+ "api-pageset-param-redirects-generator": "Resolver automaticamente as redireccións en <var>$1titles</var>, <var>$1pageids</var>, e <var>$1revids</var>, e nas páxinas devoltas por <var>$1generator</var>.",
+ "api-pageset-param-redirects-nogenerator": "Resolver automaticamente as redireccións en <var>$1titles</var>, <var>$1pageids</var>, e <var>$1revids</var>.",
+ "api-pageset-param-converttitles": "Converter títulos a outras variantes se é preciso. Só funciona se a lingua de contido da wiki soporta a conversión en variantes. As linguas que soportan conversión en variante inclúen $1.",
+ "api-help-title": "Axuda da API de MediaWiki",
+ "api-help-lead": "Esta é unha páxina de documentación da API de MediaWiki xerada automaticamente.\n\nDocumentación e exemplos:\nhttps://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Módulo principal",
+ "api-help-flag-deprecated": "Este módulo está obsoleto.",
+ "api-help-flag-internal": "<strong>Este módulo é interno ou inestable. </strong> O seu funcionamento pode cambiar sen aviso previo.",
+ "api-help-flag-readrights": "Este módulo precisa permisos de lectura.",
+ "api-help-flag-writerights": "Este módulo precisa permisos de escritura.",
+ "api-help-flag-mustbeposted": "Este módulo só acepta peticións POST.",
+ "api-help-flag-generator": "Este módulo pode usarse como xenerador.",
+ "api-help-parameters": "{{PLURAL:$1|Parámetro|Parámetros}}:",
+ "api-help-param-deprecated": "Obsoleto.",
+ "api-help-param-required": "Este parámetro é obrigatorio.",
+ "api-help-param-list": "{{PLURAL:$1|1=Un valor|2=Valores (separados con <kbd>{{!}}</kbd>)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Debe ser baleiro|Pode ser baleiro, ou $2}}",
+ "api-help-param-limit": "Non se permiten máis de $1.",
+ "api-help-param-limit2": "Non se permiten máis de $1 ($2 para bots).",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=O valor debe ser maior |2=Os valores deben ser maiores}} que $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=O valor debe ser menor |2=Os valores deben ser menores}} que $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=O valor debe estar entre $2 e $3 |2=Os valores deben estar entre $2 e $3}}.",
+ "api-help-param-upload": "Debe ser enviado como un ficheiro importado usando multipart/form-data.",
+ "api-help-param-multi-separate": "Separe os valores con <kbd>|</kbd>.",
+ "api-help-param-multi-max": "O número máximo de valores é {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} para os bots).",
+ "api-help-param-default": "Por defecto: $1",
+ "api-help-param-default-empty": "Por defecto: <span class=\"apihelp-empty\">(baleiro)</span>",
+ "api-help-param-token": "Un identificador \"$1\" recuperado por [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "Por compatibilidade, o identificador usado na web UI tamén é aceptado.",
+ "api-help-param-disabled-in-miser-mode": "Desactivado debido ó [[mw:Manual:$wgMiserMode|modo minimal]].",
+ "api-help-param-limited-in-miser-mode": "<strong>Nota:</strong> Debido ó [[mw:Manual:$wgMiserMode|modo minimal]], usar isto pode devolver menos de <var>$1limit</var> resultados antes de seguir, en casos extremos, pode que non se devolvan resultados.",
+ "api-help-param-direction": "En que dirección enumerar:\n;newer:Lista os máis antigos primeiro. Nota: $1start ten que estar antes que $1end.\n;older:Lista os máis novos primeiro (por defecto). Nota: $1start ten que estar despois que $1end.",
+ "api-help-param-continue": "Cando estean dispoñibles máis resultados, use isto para continuar.",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(sen descrición)</span>",
+ "api-help-examples": "{{PLURAL:$1|Exemplo|Exemplos}}:",
+ "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Concedida a|Concedidas a}}: $2",
+ "api-help-right-apihighlimits": "Usar os valores superiores das consultas da API (consultas lentas: $1; consultas rápidas: $2). Os límites para as consultas lentas tamén se aplican ós parámetros multivaluados.",
+ "api-credits-header": "Créditos"
+}
diff --git a/includes/api/i18n/he.json b/includes/api/i18n/he.json
new file mode 100644
index 00000000..fcc7f7bd
--- /dev/null
+++ b/includes/api/i18n/he.json
@@ -0,0 +1,180 @@
+{
+ "@metadata": {
+ "authors": [
+ "Guycn2",
+ "Amire80",
+ "Inkbug",
+ "Danny-w",
+ "YaronSh",
+ "ערן"
+ ]
+ },
+ "apihelp-main-param-action": "איזו פעולה לבצע.",
+ "apihelp-main-param-format": "התבנית של הפלט.",
+ "apihelp-main-param-curtimestamp": "הכללת חותמת הזמן הנוכחית בתוצאה.",
+ "apihelp-block-description": "חסימת משתמש.",
+ "apihelp-block-param-user": "שם משתמש, כתובת IP, או טווח IP שהנך רוצה לחסום.",
+ "apihelp-block-param-reason": "סיבה לחסימה.",
+ "apihelp-compare-param-fromtitle": "כותרת ראשונה להשוואה.",
+ "apihelp-compare-param-fromid": "מס׳ זיהוי של העמוד הראשון להשוואה.",
+ "apihelp-compare-param-fromrev": "גרסה ראשונה להשוואה.",
+ "apihelp-compare-param-totitle": "כותרת שנייה להשוואה.",
+ "apihelp-compare-param-toid": "מס׳ מזהה של העמוד השני להשוואה.",
+ "apihelp-compare-param-torev": "גרסה שנייה להשוואה.",
+ "apihelp-compare-example-1": "יצירת תיעוד שינוי בין גרסה 1 ל־2.",
+ "apihelp-createaccount-description": "יצירת חשבון משתמש חדש.",
+ "apihelp-createaccount-param-name": "שם משתמש.",
+ "apihelp-createaccount-param-password": "ססמה (לא ישפיע אם הוגדר <var>$1mailpassword</var>).",
+ "apihelp-createaccount-param-domain": "שם מתחם לאימות חיצוני (רשות).",
+ "apihelp-createaccount-param-token": "אסימון יצירת חשבון הושג בבקשה הראשונה.",
+ "apihelp-createaccount-param-email": "כתובת הדוא״ל של המשתמש (רשות).",
+ "apihelp-createaccount-param-realname": "השם האמתי של המשתמש (רשות).",
+ "apihelp-createaccount-param-mailpassword": "אם הוגדר ערך כלשהו, תישלח ססמה אקראית אל המשתמש.",
+ "apihelp-createaccount-param-reason": "הסיבה כרשות ליצירת החשבון כפי שתופיע ברישומים.",
+ "apihelp-createaccount-param-language": "קוד השפה שיוגדר כבררת המחדל למשתמש (רשות, בררת המחדל היא שפת התוכן).",
+ "apihelp-createaccount-example-pass": "יצירת המשתמש <kbd>testuser</kbd> עם הססמה <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "יצירת המשתמש <kbd>testmailuser</kbd> ושליחת ססמה שיוצרה אקראית בדוא״ל.",
+ "apihelp-delete-description": "מחיקת דף.",
+ "apihelp-delete-param-title": "כותרת העמוד למחיקה. לא ניתן להשתמש בשילוב עם <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "מס׳ הזיהוי של העמוד למחיקה. לא ניתן להשתמש בשילוב עם <var>$1title</var>.",
+ "apihelp-delete-param-reason": "סיבת המחיקה. אם לא הוגדרה, תתווסף סיבה שנוצרה אוטומטית.",
+ "apihelp-delete-param-watch": "הוספת העמוד לרשימת המעקב של המשתמש הנוכחי.",
+ "apihelp-delete-param-unwatch": "הסרת הדף מרשימת המעקב של של המשתמש הנוכחי.",
+ "apihelp-delete-example-simple": "מחיקת הדף הראשי",
+ "apihelp-edit-param-text": "תוכן הדף.",
+ "apihelp-edit-param-minor": "עריכה משנית.",
+ "apihelp-edit-example-edit": "עריכת דף",
+ "apihelp-emailuser-description": "שליחת דוא\"ל למשתמש.",
+ "apihelp-expandtemplates-param-title": "כותרת הדף.",
+ "apihelp-feedcontributions-param-year": "החל משנה (ולפני כן).",
+ "apihelp-feedcontributions-param-month": "החל מחודש (ולפני כן).",
+ "apihelp-feedcontributions-param-tagfilter": "סינון תרומות בעלות התגיות הבאות.",
+ "apihelp-feedcontributions-param-deletedonly": "הצגת תרומות שנמחקו בלבד.",
+ "apihelp-feedcontributions-param-toponly": "הצגת עריכות שהן הגרסה העדכנית ביותר בלבד.",
+ "apihelp-feedcontributions-example-simple": "החזרת תרומות עבור המשתמש <kbd>Example</kbd>.",
+ "apihelp-feedrecentchanges-param-hideminor": "הסתרת שינוים משניים.",
+ "apihelp-feedrecentchanges-param-hidebots": "הסתרת שינויים שנעשו על ידי בוטים.",
+ "apihelp-feedrecentchanges-param-hideanons": "הסתרת שינויים שנעשו על ידי אנונימים.",
+ "apihelp-feedrecentchanges-param-hideliu": "הסתרת שינויים שנעשו על ידי משתמשים רשומים.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "הסתרת שינויים שנבדקו.",
+ "apihelp-feedrecentchanges-param-hidemyself": "הסתרת שינוים שנעשו על ידי המשתמש הנוכחי.",
+ "apihelp-feedrecentchanges-param-tagfilter": "סינון לפי תגית.",
+ "apihelp-feedrecentchanges-param-target": "הצגת שינויים שנעשו בדפים המקושרים לדף זה בלבד.",
+ "apihelp-feedrecentchanges-example-simple": "הצגת שינויים אחרונים.",
+ "apihelp-feedrecentchanges-example-30days": "הצגת שינויים אחרונים עבור 30 ימים.",
+ "apihelp-help-description": "הצגת עזרה עבור היחידות שצוינו.",
+ "apihelp-help-param-helpformat": "תסדיר פלט העזרה.",
+ "apihelp-help-param-toc": "לכלול תוכן עניינים בפלט HTML.",
+ "apihelp-import-param-xml": "קובץ XML שהועלה.",
+ "apihelp-login-param-name": "שם משתמש.",
+ "apihelp-login-param-password": "ססמה.",
+ "apihelp-login-param-domain": "שם מתחם (רשות).",
+ "apihelp-login-param-token": "אסימון כניסה התקבל בבקשה הראשונה.",
+ "apihelp-login-example-gettoken": "קבלת אסימון כניסה.",
+ "apihelp-login-example-login": "כניסה.",
+ "apihelp-logout-description": "יציאה וניקוי של נתוני הפעילות.",
+ "apihelp-logout-example-logout": "הוצאת המשתמש הנוכחי.",
+ "apihelp-managetags-description": "ביצוע פעולות ניהוליות הקשורות בשינוי תגיות.",
+ "apihelp-move-description": "העברת עמוד.",
+ "apihelp-opensearch-param-search": "מחרוזת לחיפוש.",
+ "apihelp-opensearch-param-namespace": "שמות מתחם לחיפוש.",
+ "apihelp-opensearch-param-format": "תסדיר הפלט.",
+ "apihelp-protect-example-protect": "הגנה על דף.",
+ "apihelp-query-param-list": "אילו רשימות לקבל.",
+ "apihelp-query+allcategories-description": "מניין של כל הקטגוריות.",
+ "apihelp-query+allcategories-param-from": "הקטגוריה ממנה להתחיל למנות.",
+ "apihelp-query+allimages-param-sha1": "גיבוב SHA1 של תמונה. דריסת $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "גיבוב SHA1 של התמונה בבסיס 36 (הבסיס בו נעשה שימוש במדיה־ויקי).",
+ "apihelp-query+allimages-param-limit": "כמה תמונות להחזיר בסך הכול.",
+ "apihelp-query+allimages-example-B": "הצגת רשימה של קבצים שמתחילים באות <kbd>B</kbd>.",
+ "apihelp-query+allimages-example-generator": "הצגת מידע על 4 קבצים המתחילים באות <kbd>T</kbd>.",
+ "apihelp-query+allmessages-param-prop": "אלו מאפיינים לקבל.",
+ "apihelp-query+allpages-param-limit": "כמה דפים להחזיר בסך הכול.",
+ "apihelp-query+allredirects-param-limit": "כמה פריטים להחזיר בסך הכול.",
+ "apihelp-query+categories-param-limit": "כמה קטגוריות להחזיר.",
+ "apihelp-query+categorymembers-param-startsortkey": "כדאי להשתמש ב־$1starthexsortkey במקום.",
+ "apihelp-query+categorymembers-param-endsortkey": "כדאי להשתמש ב־$1endhexsortkey במקום.",
+ "apihelp-query+categorymembers-example-simple": "קבלת עשרת העמודים הראשונים שתחת <kbd>קטגוריה:פיזיקה</kbd>.",
+ "apihelp-query+contributors-param-limit": "כמה תורמים להחזיר.",
+ "apihelp-query+contributors-example-simple": "הצגת תורמים לדף <kbd>עמוד ראשי</kbd>.",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|מצב|מצבים}}: $2",
+ "apihelp-query+duplicatefiles-param-limit": "כמה קבצים כפולים להחזיר.",
+ "apihelp-query+duplicatefiles-param-localonly": "חיפוש אחר קבצים במאגר המקומי בלבד.",
+ "apihelp-query+duplicatefiles-example-simple": "חיפוש אחר כפילויות של [[:קובץ:Albert Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "חיפוש אחר כפילויות בין כל הקבצים.",
+ "apihelp-query+extlinks-param-limit": "כמה קישורים להחזיר.",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "תגובה על הגרסה.",
+ "apihelp-query+imageinfo-param-localonly": "חיפוש אחר קבצים במאגר המקומי בלבד.",
+ "apihelp-query+imageinfo-example-simple": "קבלת פרטים על הגרסה הנוכחית של [[:קובץ:Albert Einstein Head.jpg]].",
+ "apihelp-query+images-param-limit": "כמה קבצים להחזיר.",
+ "apihelp-query+info-paramvalue-prop-watchers": "מספר העוקבים, אם קיבלת הרשאה.",
+ "apihelp-query+info-paramvalue-prop-readable": "האם המשתמש יכול להציג דף זה.",
+ "apihelp-query+langlinks-param-title": "קישור לחיפוש. חובה להשתמש עם <var>$1lang</var>.",
+ "apihelp-query+links-description": "החזרת כל הקישורים מהדפים שצוינו.",
+ "apihelp-query+linkshere-param-limit": "כמה להחזיר.",
+ "apihelp-query+linkshere-param-show": "הצגת פריטים שתואמים את הדרישות הללו בלבד:\n;redirect:הצגת הפניות בלבד.\n;!redirect:הצגת קישורים שאינם הפניות בלבד.",
+ "apihelp-query+logevents-description": "קבלת אירועים מהרישומים.",
+ "apihelp-query+pageswithprop-param-dir": "באיזה כיוון לסדר.",
+ "apihelp-query+pageswithprop-example-simple": "הצגת עשרת הדפים הראשונים שעושים שימוש ב־<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
+ "apihelp-query+pageswithprop-example-generator": "קבלת פרטיהם של עשרת הדפים הראשונים המשתמשים ב־<code>_&#95;NOTOC_&#95;</code>.",
+ "apihelp-query+prefixsearch-param-search": "מחרוזת לחיפוש.",
+ "apihelp-query+prefixsearch-param-limit": "מספר התוצאות המרבי להחזרה.",
+ "apihelp-query+prefixsearch-param-offset": "מספר תוצאות לדילוג.",
+ "apihelp-query+querypage-param-limit": "מספר תוצאות להחזרה.",
+ "apihelp-query+recentchanges-description": "מניית השינויים האחרונים.",
+ "apihelp-query+recentchanges-param-limit": "כמה שינויים להחזיר בסך הכול.",
+ "apihelp-query+recentchanges-param-type": "אילו סוגים של שינויים להציג.",
+ "apihelp-query+recentchanges-example-simple": "הצגת השינויים האחרונים.",
+ "apihelp-query+redirects-param-limit": "כמה הפניות להחזיר.",
+ "apihelp-query+revisions+base-param-limit": "הגבלת מספר הגרסאות שיוחזרו.",
+ "apihelp-query+tokens-example-types": "אחזור אסימון של רשימת המעקב ואסימון של ניטור",
+ "apihelp-xml-param-xslt": "אם צוין, יש להוסיף את שם הדף כגיליון עיצוב XSL. על הערך להיות כותרת ב {{ns:mediawiki}} במרחב שם המשתמש, המסתיים ב- <code>.xsl</code>.",
+ "api-format-title": "תוצאה של API של מדיה־ויקי",
+ "api-format-prettyprint-header": "זהו ייצוג ב־HTML של תסדיר $1. תסדיר HTML טוב לתיקון שגיאות, אבל אינו מתאים ליישומים.\n\nיש לציין את הפרמטר format כדי לשנות את תסדיר הפלט. כדי לראות ייצוג של תסדיר $1 לא ב־HTML יש לרשום format=$2.\n\nר' את [https://www.mediawiki.org/wiki/API התיעוד המלא], או את [[Special:ApiHelp/main|העזרה של API]] למידע נוסף.",
+ "api-orm-param-props": "באילו שדות לעשות שאילתה.",
+ "api-orm-param-limit": "מספר מרבי של שורות להחזיר.",
+ "api-pageset-param-titles": "רשימת כותרות.",
+ "api-pageset-param-pageids": "רשימת מזהי דף לעובד עליהם.",
+ "api-pageset-param-revids": "רשימת מזהי גרסה לעבוד עליהם.",
+ "api-pageset-param-generator": "קבלת רשימת דפים לעבוד עליהם על־ידי הרצת יחידת שאילתה שצוינה.\n\n'''לתשומת לבך:''' לשמות בפרמטר generator צריכה להיות התחילית \"g\", ר' דוגמאות.",
+ "api-pageset-param-redirects-generator": "פתרון אוטומטי של הפניות ב־$1titles, ב־$1pageids, וב־$1revids, ודפים שמחזיר $1generator.",
+ "api-pageset-param-redirects-nogenerator": "פתרון אוטומטי של הפניות ב־$1titles, ב־$1pageids וב־$1revids.",
+ "api-pageset-param-converttitles": "המרת כותרות לסוגי כתב אחרים אם זה נחוץ. זה עובד רק אם שפת הכותרת של הוויקי תומכת בהמרת סוגי כתב. השפות שתמכות בהמרת סוגי כתב הן $1.",
+ "api-help-title": "עזרה של MediaWiki API",
+ "api-help-lead": "זהו דף תיעוד של API שנוצר באופן אוטומטי.\n\nתיעוד ודוגמאות: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "יחידה ראשית",
+ "api-help-flag-deprecated": "יחידה זו אינה מומלצת לשימוש.",
+ "api-help-flag-internal": "<strong>יחידה זו היא פנימית או לא יציבה.</strong>\nהפעולה שלה עשויה להשתנות ללא הודעה מוקדמת.",
+ "api-help-flag-readrights": "יחידה זו דורשת הרשאות קריאה.",
+ "api-help-flag-writerights": "יחידה זו דורשת הרשאות כתיבה.",
+ "api-help-flag-mustbeposted": "יחידה זו מקבלת רק בקשות POST.",
+ "api-help-flag-generator": "היחידה הזאת יכולה להיות מחולל.",
+ "api-help-parameters": "{{PLURAL:$1|פרמטר|פרמטרים}}:",
+ "api-help-param-deprecated": "מיושן.",
+ "api-help-param-required": "פרמטר זה נדרש.",
+ "api-help-param-list": "{{PLURAL:$1|1=ערך אחד|2=ערכים (מופרדים באמצעות \"{{!}}\")}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=חייב להיות ריק|יכול להיות ריק או $2}}",
+ "api-help-param-limit": "מספר הפרמטרים לא יכול להיות גדול מ־$1.",
+ "api-help-param-limit2": "המספר המרבי המותר הוא $1 (עבור בוטים – $2).",
+ "api-help-param-integer-min": "ה{{PLURAL:$1|1=ערך|2=ערכים}} לא יכולים להיות קטנים מ־$2.",
+ "api-help-param-integer-max": "ה{{PLURAL:$1|1=ערך לא יכול להיות גדול|2=ערכים לא יכולים להיות גדולים}} מ־$3.",
+ "api-help-param-integer-minmax": "ה{{PLURAL:$1|1=ערך חייב|2=ערכים חייבים}} להיות בין $2 ל־$3.",
+ "api-help-param-upload": "חייב להישלח (posted) בתור העלאת קובץ באמצעות multipart/form-data.",
+ "api-help-param-multi-separate": "הפרדה בין ערכים נעשית באמצעות <kbd>|</kbd>",
+ "api-help-param-multi-max": "מספר הערכים המרבי הוא {{PLURAL:$1|$1}} (עבור בוטים – {{PLURAL:$2|$2}}).",
+ "api-help-param-default": "ברירת מחדל: $1",
+ "api-help-param-default-empty": "ברירת מחדל: <span class=\"apihelp-empty\">(ריק)</span>",
+ "api-help-param-token": "אסימון \"$1\" אוחזר מ־[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "לשם תאימות, גם האסימון שמשמש בממשק דפדפן מתקבל.",
+ "api-help-param-disabled-in-miser-mode": "כבוי בשל [https://www.mediawiki.org/wiki/Manual:$wgMiserMode מצב חיסכון].",
+ "api-help-param-limited-in-miser-mode": "'''לתשומת לבך:''' בשל [https://www.mediawiki.org/wiki/Manual:$wgMiserMode מצב חיסכון], שימוש בזה יכול להוביל לפחות מ־\"$1limit\" תוצאות לפני המשך; במצבים קיצוניים ייתכן שיחזרו אפס תוצאות.",
+ "api-help-param-direction": "באיזה כיוון למספר:\n;newer:לרשום את הישנים ביותר בהתחלה. לתשומת לבך: $1start חייב להיות לפני $1end.\n;older:לרשום את החדשים ביותר בהתחלה (בררת מחדל). לתשומת לבך: $1start חייב להיות אחרי $1end.",
+ "api-help-param-continue": "כשיש עוד תוצאות, להשתמש בזה בשביל להמשיך.",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(ללא תיאור)</span>",
+ "api-help-examples": "{{PLURAL:$1|דוגמה|דוגמאות}}:",
+ "api-help-permissions": "{{PLURAL:$1|הרשאה|הרשאות}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|הוענק ל|הוענקו ל}}: $2",
+ "api-help-right-apihighlimits": "להשתמש במגבלות גבוהות יותר בשאילתות API (שאילתות אטיות: $1; שאילתות מהירות: $2). המגבלות לשאילתות אטיות חלות גם על פרמטרים מרובי־ערכים.",
+ "api-credits-header": "קרדיטים",
+ "api-credits": "מפתחי ה־API:\n* רואן קטאו (מפתח מוביל 2007–2009)\n* ויקטור וסילייב\n* בריאן טונג מין\n* סאם ריד\n* יורי אסטרחן (יוצר, מפתח מוביל מספטמבר 2006 עד ספטמבר 2007)\n* בראד יורש (מפתח מוביל מאז 2013)\n\nאנא שלחו הערות, הצעות ושאלות לכתובת mediawiki-api@lists.wikimedia.org או כתבו דיווח באג באתר https://bugzilla.wikimedia.org."
+}
diff --git a/includes/api/i18n/hsb.json b/includes/api/i18n/hsb.json
new file mode 100644
index 00000000..b25ae9b2
--- /dev/null
+++ b/includes/api/i18n/hsb.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "J budissin"
+ ]
+ },
+ "apihelp-main-param-format": "Wudawanski format"
+}
diff --git a/includes/api/i18n/hu.json b/includes/api/i18n/hu.json
new file mode 100644
index 00000000..516d8c77
--- /dev/null
+++ b/includes/api/i18n/hu.json
@@ -0,0 +1,17 @@
+{
+ "@metadata": {
+ "authors": [
+ "Csega",
+ "Dorgan"
+ ]
+ },
+ "apihelp-block-description": "Szerkesztő blokkolása",
+ "apihelp-block-param-reason": "Blokkolás oka.",
+ "apihelp-block-param-nocreate": "Új regisztráció megakadályozása",
+ "apihelp-createaccount-param-name": "Felhasználónév.",
+ "apihelp-delete-description": "Lap törlése.",
+ "apihelp-delete-example-simple": "Kezdőlap törlése.",
+ "apihelp-edit-example-edit": "Lap szerkesztése",
+ "apihelp-expandtemplates-param-title": "Lap címe.",
+ "apihelp-userrights-param-userid": "Felhasználói azonosító."
+}
diff --git a/includes/api/i18n/ia.json b/includes/api/i18n/ia.json
new file mode 100644
index 00000000..de9d65fe
--- /dev/null
+++ b/includes/api/i18n/ia.json
@@ -0,0 +1,28 @@
+{
+ "@metadata": {
+ "authors": [
+ "McDutchie"
+ ]
+ },
+ "apihelp-main-param-action": "Qual action exequer.",
+ "apihelp-main-param-format": "Le formato del resultato.",
+ "apihelp-main-param-maxlag": "Le latentia maximal pote esser usate quando MediaWiki es installate in un cluster de base de datos replicate. Pro evitar actiones que causa additional latentia de replication de sito, iste parametro pote facer le cliente attender usque le latentia de replication es minus que le valor specificate. In caso de latentia excessive, le codice de error \"maxlag\" es retornate con un message como \"Attende $host: $lag secundas de latentia\".<br />Vide https://www.mediawiki.org/wiki/Manual:Maxlag_parameter pro plus information.",
+ "apihelp-main-param-smaxage": "Fixar le capite <code>s-maxage</code> a iste numero de secundas. Errores nunquam es mittite in cache.",
+ "apihelp-main-param-maxage": "Fixar le capite <code>max-age</code> a iste numero de secundas. Errores nunquam es mittite in cache.",
+ "apihelp-main-param-assert": "Verificar si le usator ha aperite session si mittite a \"user\", o si ha le derecto de usator robot si \"bot\".",
+ "apihelp-main-param-requestid": "Omne valor fornite hic essera includite in le responsa. Pote esser usate pro distinguer requestas.",
+ "apihelp-main-param-servedby": "Includer in le resultato le nomine del host que ha servite le requesta.",
+ "apihelp-main-param-curtimestamp": "Includer le data e hora actual in le resultato.",
+ "apihelp-main-param-origin": "Quando acceder al API usante un requesta AJAX inter-dominios (CORS), mitte isto al dominio de origine. Isto debe esser includite in omne requesta pre-flight, e dunque debe facer parte del URI del requesta (e non del corpore POST). Isto debe corresponder exactemente a un del origines in le capite Origin:, dunque illo debe esser mittite a qualcusa como http://ia.wikipedia.org o https://meta.wikimedia.org. Si iste parametro non corresponde al capite Origin:, un responsa 403 essera retornate. Si iste parametro corresponde al capite Origin: e le origine es in le lista blanc, un capite Access-Control-Allow-Origin essera inserite.",
+ "apihelp-main-param-uselang": "Lingua a usar pro traductiones de messages. Un lista de codices pote esser obtenite ab [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]] con siprop=languages, o specifica \"user\" pro usar le preferentia de lingua del usator actual, o specifica \"content\" pro usar le lingua de contento de iste wiki.",
+ "apihelp-block-description": "Blocar un usator.",
+ "apihelp-block-param-user": "Nomine de usator, adresse IP o intervallo IP que tu vole blocar.",
+ "apihelp-block-param-expiry": "Tempore de expiration. Pote esser relative (p.ex. \"5 months\" o \"2 weeks\") o absolute (p.ex. \"2014-09-18T12:34:56Z\"). Si es mittite a \"infinite\", \"indefinite\" o \"never\", le blocada nunquam expirara.",
+ "apihelp-block-param-reason": "Motivo del blocada.",
+ "apihelp-block-param-anononly": "Blocar solmente usatores anonyme (i.e. disactivar modificationes anonyme pro iste adresse IP).",
+ "apihelp-block-param-nocreate": "Impedir le creation de contos.",
+ "apihelp-block-param-autoblock": "Blocar automaticamente le adresse IP usate le plus recentemente, e omne IPs successive desde le quales ille/-a tenta facer modificationes.",
+ "apihelp-block-param-noemail": "Impedir que le usator invia e-mail per le wiki. (Require le derecto \"blockemail\").",
+ "apihelp-query+revisions-example-first5-not-localhost": "Obtener le prime 5 versiones del \"Pagina principal\" que non ha essite facite per le usator anonyme \"127.0.0.1\"",
+ "api-credits": "Programmatores del API:\n* Roan Kattouw (programmator dirigente Sept. 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (creator, programmator dirigente Sept. 2006–Sept. 2007)\n* Brad Jorsch (programmator dirigente 2013–presente)\n\nInvia tu commentos, suggestiones e questiones a mediawiki-api@lists.wikimedia.org\no insere un reportage de bug a https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/it.json b/includes/api/i18n/it.json
new file mode 100644
index 00000000..68f4e40a
--- /dev/null
+++ b/includes/api/i18n/it.json
@@ -0,0 +1,31 @@
+{
+ "@metadata": {
+ "authors": [
+ "Beta16",
+ "Nivit",
+ "Toadino2"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentazione (in inglese)]]\n* [[mw:API:FAQ|FAQ (in inglese)]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annunci sull'API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug & richieste]\n</div>\n<strong>Stato:</strong> Tutte le funzioni e caratteristiche mostrate su questa pagina dovrebbero funzionare, ma l'API è ancora in fase d'attivo sviluppo, e potrebbe cambiare in qualsiasi momenento. Iscriviti alla [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] per essere informato sugli aggiornamenti.\n\n<strong>Istruzioni sbagliate:</strong> quando vengono impartite all'API delle istruzioni sbagliate, un'intestazione HTTP verrà inviata col messaggio \"MediaWiki-API-Error\" e sia al valore dell'intestazione sia al codice d'errore verrà impostato lo stesso valore. Per maggiori informazioni leggi [[mw:API:Errors_and_warnings|API:Errori ed avvertimenti (in inglese)]].",
+ "apihelp-main-param-action": "Azione da compiere.",
+ "apihelp-main-param-format": "Formato dell'output.",
+ "apihelp-main-param-assert": "Verifica che l'utente sia loggato se si è impostato <kbd>utente</kbd>, o che abbia i permessi di bot se si è impostato <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Tutti i valori forniti saranno implementati nella risposta. Potrebbero venir utilizzati per distinguere le richieste.",
+ "apihelp-block-description": "Blocca un utente.",
+ "apihelp-block-param-reason": "Motivo del blocco.",
+ "apihelp-emailuser-description": "Manda un'e-mail ad un utente.",
+ "apihelp-emailuser-param-ccme": "Mandami una copia di questa mail.",
+ "apihelp-expandtemplates-description": "Espandi tutti i template nel wikitesto.",
+ "apihelp-expandtemplates-param-title": "Titolo della pagina.",
+ "apihelp-expandtemplates-param-text": "Wikitesto da convertire.",
+ "apihelp-query+recentchanges-example-simple": "Elenco modifiche recenti.",
+ "apihelp-upload-example-url": "Carica da un URL.",
+ "api-help-parameters": "{{PLURAL:$1|Parametro|Parametri}}:",
+ "api-help-param-deprecated": "Deprecato.",
+ "api-help-param-required": "Questo parametro è obbligatorio.",
+ "api-help-param-default": "Predefinito: $1",
+ "api-help-param-default-empty": "Predefinito: <span class=\"apihelp-empty\">(vuoto)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(nessuna descrizione)</span>",
+ "api-help-examples": "{{PLURAL:$1|Esempio|Esempi}}:",
+ "api-credits-header": "Crediti"
+}
diff --git a/includes/api/i18n/ja.json b/includes/api/i18n/ja.json
new file mode 100644
index 00000000..3940469a
--- /dev/null
+++ b/includes/api/i18n/ja.json
@@ -0,0 +1,213 @@
+{
+ "@metadata": {
+ "authors": [
+ "Shirayuki",
+ "2nd-player",
+ "Los688",
+ "Whym",
+ "Mfuji"
+ ]
+ },
+ "apihelp-main-param-action": "実行する操作です。",
+ "apihelp-main-param-format": "出力する形式です。",
+ "apihelp-main-param-smaxage": "<code>s-maxage</code> ヘッダーにこの秒数を設定します。エラーがキャッシュされることはありません。",
+ "apihelp-main-param-maxage": "<code>max-age</code> ヘッダーにこの秒数を設定します。エラーがキャッシュされることはありません。",
+ "apihelp-main-param-assert": "<kbd>user</kbd> を設定した場合は利用者がログイン済みかどうかを、<kbd>bot</kbd> を指定した場合はボット権限があるかどうかを、それぞれ検証します。",
+ "apihelp-main-param-requestid": "任意の値を指定でき、その値が結果に含められます。リクエストを識別するために使用できます。",
+ "apihelp-main-param-servedby": "リクエストを処理したホスト名を結果に含めます。",
+ "apihelp-main-param-curtimestamp": "現在のタイムスタンプを結果に含めます。",
+ "apihelp-main-param-uselang": "メッセージの翻訳に使用する言語です。コードの一覧は <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> に <kbd>siprop=languages</kbd> を付けることで取得できます。<kbd>user</kbd> を指定することで現在の利用者の個人設定の言語を、<kbd>content</kbd> を指定することでこのウィキの本文の言語を使用することもできます。",
+ "apihelp-block-description": "利用者をブロックします。",
+ "apihelp-block-param-user": "ブロックする利用者名、IPアドレスまたはIPレンジ。",
+ "apihelp-block-param-reason": "ブロックの理由。",
+ "apihelp-block-param-anononly": "匿名利用者のみブロックします(つまり、このIPアドレスからの匿名での編集を不可能にします)。",
+ "apihelp-block-param-nocreate": "アカウントの作成を禁止します。",
+ "apihelp-block-param-autoblock": "その利用者が最後に使用したIPアドレスと、ブロック後に編集を試みた際のIPアドレスを自動的にブロックします。",
+ "apihelp-block-param-noemail": "Wikiを通して電子メールを送信することを禁止します。(<code>blockemail</code> 権限が必要です)",
+ "apihelp-block-param-hidename": "ブロック記録から利用者名を秘匿します。(<code>hideuser</code> 権限が必要です)",
+ "apihelp-block-param-reblock": "その利用者がすでにブロックされている場合、ブロックを上書きします。",
+ "apihelp-block-param-watchuser": "その利用者またはIPアドレスの利用者ページとトークページをウォッチします。",
+ "apihelp-block-example-ip-simple": "IPアドレス <kbd>192.0.2.5</kbd> を <kbd>First strike<kbd> という理由で3日ブロックする",
+ "apihelp-block-example-user-complex": "利用者 <kbd>Vandal</kbd> を <kbd>Vandalism</kbd> という理由で無期限ブロックし、新たなアカウント作成とメールの送信を禁止する。",
+ "apihelp-checktoken-param-type": "調べるトークンの種類。",
+ "apihelp-checktoken-param-token": "調べるトークン。",
+ "apihelp-checktoken-example-simple": "<kbd>csrf</kbd> トークンの妥当性を調べる。",
+ "apihelp-compare-example-1": "版1と2の差分を生成する。",
+ "apihelp-createaccount-description": "新しい利用者アカウントを作成します。",
+ "apihelp-createaccount-param-name": "利用者名。",
+ "apihelp-createaccount-param-password": "パスワード (<var>$1mailpassword</var> が設定されると無視されます)。",
+ "apihelp-createaccount-param-token": "最初のリクエストで得られたアカウント作成用トークンです。",
+ "apihelp-createaccount-param-email": "利用者の電子メールアドレス (任意)。",
+ "apihelp-createaccount-param-realname": "利用者の本名 (省略可能)。",
+ "apihelp-createaccount-param-mailpassword": "設定されると (その値を問わず)、ランダムなパスワードがその利用者に電子メールで送られます。",
+ "apihelp-createaccount-param-reason": "ログに記録されるアカウント作成の理由 (任意)。",
+ "apihelp-createaccount-example-pass": "利用者 <kbd>testuser</kbd> をパスワード <kbd>test123</kbd> として作成する。",
+ "apihelp-createaccount-example-mail": "利用者 <kbd>testuser</kbd>を作成し、ランダムに生成されたパスワードをメールで送る",
+ "apihelp-delete-description": "ページを削除します。",
+ "apihelp-delete-param-title": "削除するページ名です。<var>$1pageid</var> とは同時に使用できません。",
+ "apihelp-delete-param-pageid": "削除するページIDです。<var>$1title</var> とは同時に使用できません。",
+ "apihelp-delete-param-reason": "削除の理由です。入力しない場合、自動的に生成された理由が使用されます。",
+ "apihelp-delete-param-watch": "そのページを現在の利用者のウォッチリストに追加します。",
+ "apihelp-delete-param-unwatch": "そのページを現在の利用者のウォッチリストから除去します。",
+ "apihelp-delete-example-simple": "<kbd>Main Page</kbd> を削除する",
+ "apihelp-delete-example-reason": "<kbd>Preparing for move</kbd> という理由で <kbd>Main Page</kbd> を削除する",
+ "apihelp-disabled-description": "このモジュールは無効化されています。",
+ "apihelp-edit-description": "ページを作成、編集します。",
+ "apihelp-edit-param-title": "編集するページ名です。<var>$1pageid</var> とは同時に使用できません。",
+ "apihelp-edit-param-pageid": "編集するページIDです。<var>$1title</var> とは同時に使用できません。",
+ "apihelp-edit-param-section": "節番号です。先頭の節の場合は <kbd>0</kbd>、新しい節の場合は <kbd>new</kbd>を指定します。",
+ "apihelp-edit-param-sectiontitle": "新しい節の名前です。",
+ "apihelp-edit-param-text": "ページの本文。",
+ "apihelp-edit-param-minor": "細部の編集",
+ "apihelp-edit-param-createonly": "すでにそのページが存在する場合は編集を行いません。",
+ "apihelp-edit-param-nocreate": "そのページが存在しない場合にエラーを返します。",
+ "apihelp-edit-param-watch": "そのページを現在の利用者のウォッチリストに追加します。",
+ "apihelp-edit-param-unwatch": "そのページを現在の利用者のウォッチリストから除去します。",
+ "apihelp-edit-param-token": "このトークンは常に最後のパラメーターとして、または少なくとも $1text パラメーターより後に送信されるべきです。",
+ "apihelp-edit-example-edit": "ページを編集",
+ "apihelp-emailuser-description": "利用者に電子メールを送信します。",
+ "apihelp-emailuser-param-target": "送信先の利用者名。",
+ "apihelp-emailuser-param-text": "電子メールの本文。",
+ "apihelp-emailuser-param-ccme": "電子メールの複製を自分にも送信します。",
+ "apihelp-emailuser-example-email": "利用者 <kbd>WikiSysop</kbd> に <kbd>Content</kbd> という本文の電子メールを送信。",
+ "apihelp-expandtemplates-description": "ウィキテキストに含まれるすべてのテンプレートを展開します。",
+ "apihelp-expandtemplates-param-title": "ページの名前です。",
+ "apihelp-expandtemplates-param-text": "変換するウィキテキストです。",
+ "apihelp-expandtemplates-example-simple": "ウィキテキスト <kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd> を展開する。",
+ "apihelp-feedcontributions-param-deletedonly": "削除された投稿記録のみ表示します。",
+ "apihelp-feedcontributions-param-toponly": "最新版の編集のみ表示します。",
+ "apihelp-feedcontributions-param-newonly": "ページ作成を伴う編集のみを表示します。",
+ "apihelp-feedcontributions-example-simple": "利用者 <kbd>Example</kbd> の投稿記録を取得する。",
+ "apihelp-feedrecentchanges-param-limit": "返す結果の最大数。",
+ "apihelp-feedrecentchanges-param-hideminor": "細部の変更を隠す。",
+ "apihelp-feedrecentchanges-param-hidebots": "ボットによる変更を隠す。",
+ "apihelp-feedrecentchanges-param-hideanons": "未登録利用者による変更を隠す。",
+ "apihelp-feedrecentchanges-param-hideliu": "登録利用者による変更を隠す。",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "巡回済みの変更を隠す。",
+ "apihelp-feedrecentchanges-example-simple": "最近の更新を表示する。",
+ "apihelp-feedrecentchanges-example-30days": "最近30日間の変更を表示する。",
+ "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd> を <kbd>2011-03-05T15:27:40Z</kbd> の版に差し戻す。",
+ "apihelp-help-description": "指定したモジュールのヘルプを表示します。",
+ "apihelp-help-param-modules": "ヘルプを表示するモジュールです (<var>action</var> パラメーターおよび <var>format</var> パラメーターの値、または <kbd>main</kbd>)。<kbd>+</kbd> を使用して下位モジュールを指定できます。",
+ "apihelp-help-param-submodules": "指定したモジュールの下位モジュールのヘルプを含めます。",
+ "apihelp-help-param-recursivesubmodules": "下位モジュールのヘルプを再帰的に含めます。",
+ "apihelp-help-param-helpformat": "ヘルプの出力形式です。",
+ "apihelp-help-param-toc": "HTML 出力に目次を含めます。",
+ "apihelp-help-example-main": "メイン モジュールのヘルプ",
+ "apihelp-help-example-recursive": "すべてのヘルプを1つのページに",
+ "apihelp-help-example-help": "ヘルプ モジュール自身のヘルプ",
+ "apihelp-help-example-query": "2つの下位モジュールのヘルプ",
+ "apihelp-imagerotate-example-simple": "<kbd>File:Example.png</kbd> を <kbd>90</kbd> 度回転させる。",
+ "apihelp-imagerotate-example-generator": "<kbd>Category:Flip</kbd> 内のすべての画像を <kbd>180</kbd> 度回転させる。",
+ "apihelp-import-param-xml": "XMLファイルをアップロード",
+ "apihelp-import-param-rootpage": "このページの下位ページとしてインポートする。",
+ "apihelp-import-example-import": "[[meta:Help:Parserfunctions]] をすべての履歴とともに名前空間100 にインポートする。",
+ "apihelp-login-param-name": "利用者名。",
+ "apihelp-login-param-password": "パスワード。",
+ "apihelp-login-param-token": "最初のリクエストで取得したログイントークンです。",
+ "apihelp-login-example-gettoken": "ログイントークンを取得する。",
+ "apihelp-login-example-login": "ログイン",
+ "apihelp-logout-description": "ログアウトしてセッションデータを消去します。",
+ "apihelp-logout-example-logout": "現在の利用者をログアウトする。",
+ "apihelp-move-description": "ページを移動します。",
+ "apihelp-move-param-from": "移動するページのページ名です。<var>$1fromid</var> とは同時に使用できません。",
+ "apihelp-move-param-fromid": "移動するページのページIDです。<var>$1from</var> とは同時に使用できません。",
+ "apihelp-move-param-to": "移動後のページ名。",
+ "apihelp-move-param-reason": "名称変更の理由。",
+ "apihelp-move-param-movetalk": "存在する場合、トークページも名前を変更します。",
+ "apihelp-move-param-movesubpages": "可能であれば、下位ページも名前を変更します。",
+ "apihelp-move-param-noredirect": "転送ページを作成しません。",
+ "apihelp-move-param-watch": "そのページと転送ページを現在の利用者のウォッチリストに追加します。",
+ "apihelp-move-param-unwatch": "そのページと転送ページを現在の利用者のウォッチリストから除去します。",
+ "apihelp-move-param-ignorewarnings": "あらゆる警告を無視",
+ "apihelp-move-example-move": "<kbd>Badtitle</kbd> を <kbd>Goodtitle</kbd> に転送ページを残さず移動",
+ "apihelp-opensearch-param-search": "検索文字列。",
+ "apihelp-opensearch-param-limit": "返す結果の最大数。",
+ "apihelp-opensearch-param-namespace": "検索する名前空間。",
+ "apihelp-opensearch-param-suggest": "<var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> が false の場合、何もしません。",
+ "apihelp-paraminfo-description": "API モジュールに関する情報を取得します。",
+ "apihelp-patrol-description": "ページまたは版を巡回済みにします。",
+ "apihelp-patrol-param-revid": "巡回済みにする版ID。",
+ "apihelp-patrol-example-rcid": "最近の更新を巡回",
+ "apihelp-protect-description": "ページの保護レベルを変更します。",
+ "apihelp-protect-param-title": "保護(解除)するページ名です。$1pageid とは同時に指定できません。",
+ "apihelp-protect-param-pageid": "保護(解除)するページIDです。$1title とは同時に指定できません。",
+ "apihelp-protect-param-expiry": "有効期限です。タイムスタンプがひとつだけ指定された場合は、それがすべての保護に適用されます。無期限の保護を行う場合は<kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, または <kbd>never</kbd> を指定します。",
+ "apihelp-protect-param-reason": "保護(解除)の理由。",
+ "apihelp-protect-param-watch": "指定されると、保護(解除)するページが現在の利用者のウォッチリストに追加されます。",
+ "apihelp-protect-example-protect": "ページを保護する。",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "<var>$3user</var> と同時に指定できません。",
+ "apihelp-query+alldeletedrevisions-param-user": "この利用者による版のみを一覧表示する。",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "この利用者による版を一覧表示しない。",
+ "apihelp-query+alldeletedrevisions-param-namespace": "この名前空間に含まれるページのみを一覧表示します。",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "標準名前空間にある削除された最初の50版を一覧表示する。",
+ "apihelp-query+categorymembers-example-simple": "<kbd>Category:Physics</kbd> に含まれる最初の10ページを取得する。",
+ "apihelp-query+categorymembers-example-generator": "<kbd>Category:Physics</kbd> に含まれる最初の10ページのページ情報を取得する。",
+ "apihelp-query+contributors-example-simple": "<kbd>Main Page</kbd> への投稿者を表示する。",
+ "apihelp-query+deletedrevisions-param-user": "この利用者による版のみを一覧表示。",
+ "apihelp-query+deletedrevisions-param-excludeuser": "この利用者による版を一覧表示しない。",
+ "apihelp-query+deletedrevisions-param-limit": "一覧表示する版の最大数。",
+ "apihelp-query+deletedrevisions-example-titles": "ページ <kbd>Main Page</kbd> および <kbd>Talk:Main Page</kbd> の削除された版とその内容を一覧表示する。",
+ "apihelp-query+deletedrevisions-example-revids": "削除された版 <kbd>123456</kbd> に関する情報を一覧表示する。",
+ "apihelp-query+info-description": "ページの基本的な情報を取得します。",
+ "apihelp-query+info-paramvalue-prop-protection": "それぞれのページの保護レベルを一覧表示する。",
+ "apihelp-query+info-example-simple": "<kbd>Main Page</kbd> に関する情報を取得する。",
+ "apihelp-query+iwbacklinks-example-simple": "[[wikibooks:Test]] へリンクしているページを取得する。",
+ "apihelp-query+iwbacklinks-example-generator": "[[wikibooks:Test]] へリンクしているページの情報を取得する。",
+ "apihelp-query+langbacklinks-example-simple": "[[:fr:Test]] へリンクしているページを取得する。",
+ "apihelp-query+langbacklinks-example-generator": "[[:fr:Test]] へリンクしているページの情報を取得する。",
+ "apihelp-format-example-generic": "クエリの結果を $1 形式に整形します",
+ "apihelp-dbg-description": "データを PHP の <code>var_export()</code> 形式で出力します。",
+ "apihelp-dbgfm-description": "データを PHP の <code>var_export()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-dump-description": "データを PHP の <code>var_dump()</code> 形式で出力します。",
+ "apihelp-dumpfm-description": "データを PHP の <code>var_dump()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-json-description": "データを JSON 形式で出力します。",
+ "apihelp-json-param-callback": "指定すると、指定した関数呼び出しで出力をラップします。安全のため、利用者固有のデータはすべて制限されます。",
+ "apihelp-json-param-utf8": "指定すると、大部分の非 ASCII 文字 (すべてではありません) を、16 進のエスケープ シーケンスに置換する代わりに UTF-8 として符号化します。",
+ "apihelp-jsonfm-description": "データを JSON 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-none-description": "何も出力しません。",
+ "apihelp-php-description": "データを PHP のシリアル化した形式で出力します。",
+ "apihelp-phpfm-description": "データを PHP のシリアル化した形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-rawfm-description": "データをデバッグ要素付きで JSON 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-txt-description": "データを PHP の <code>print_r()</code> 形式で出力します。",
+ "apihelp-txtfm-description": "データを PHP の <code>print_r()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-wddx-description": "データを WDDX 形式で出力します。",
+ "apihelp-wddxfm-description": "データを WDDX 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-xml-description": "データを XML 形式で出力します。",
+ "apihelp-xml-param-xslt": "指定すると、スタイルシートとして &lt;xslt&gt; を追加します。MediaWiki 名前空間の、ページ名の末尾が \".xsl\" のウィキページに対して使用すべきです。",
+ "apihelp-xml-param-includexmlnamespace": "指定すると、XML 名前空間を追加します。",
+ "apihelp-xmlfm-description": "データを XML 形式 (HTML に埋め込んだ形式) で出力します。",
+ "apihelp-yaml-description": "データを YAML 形式で出力します。",
+ "apihelp-yamlfm-description": "データを YAML 形式 (HTML に埋め込んだ形式) で出力します。",
+ "api-format-title": "MediaWiki API の結果",
+ "api-format-prettyprint-header": "このページは $1 形式を HTML で表現したものです。HTML はデバッグに役立ちますが、アプリケーションでの使用には適していません。\n\n<var>format</var> パラメーターを指定すると出力形式を変更できます 。$1 形式の非 HTML 版を閲覧するには、format=$2 を設定してください。\n\n詳細情報については [[mw:API|完全な説明文書]]または [[Special:ApiHelp/main|API のヘルプ]]を参照してください。",
+ "api-help-title": "MediaWiki API ヘルプ",
+ "api-help-lead": "このページは自動生成された MediaWiki API の説明文書ページです。\n\n説明文書と例: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "メイン モジュール",
+ "api-help-flag-deprecated": "このモジュールは廃止予定です。",
+ "api-help-flag-internal": "<strong>このモジュールは内部的または不安定です。</strong>動作が予告なく変更される場合があります。",
+ "api-help-flag-readrights": "このモジュールは読み取りの権限を必要とします。",
+ "api-help-flag-writerights": "このモジュールは書き込みの権限を必要とします。",
+ "api-help-flag-mustbeposted": "このモジュールは POST リクエストのみを受け付けます。",
+ "api-help-flag-generator": "このモジュールはジェネレーターとして使用できます。",
+ "api-help-parameters": "{{PLURAL:$1|パラメーター}}:",
+ "api-help-param-deprecated": "廃止予定です。",
+ "api-help-param-required": "このパラメーターは必須です。",
+ "api-help-param-list": "{{PLURAL:$1|1=値 (いずれか1つ)|2=値 (<kbd>{{!}}</kbd>で区切る)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=空欄にしてください|空欄にするか、または $2}}",
+ "api-help-param-integer-min": "{{PLURAL:$1|値}}は $2 以上にしてください。",
+ "api-help-param-integer-max": "{{PLURAL:$1|値}}は $3 以下にしてください。",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|値}}は $2 以上 $3 以下にしてください。",
+ "api-help-param-upload": "multipart/form-data 形式でファイルをアップロードしてください。",
+ "api-help-param-multi-separate": "複数の値は <kbd>|</kbd> で区切ってください。",
+ "api-help-param-multi-max": "値の最大値は {{PLURAL:$1|$1}} (ボットの場合は {{PLURAL:$2|$2}}) です。",
+ "api-help-param-default": "既定値: $1",
+ "api-help-param-default-empty": "既定値: <span class=\"apihelp-empty\">(空)</span>",
+ "api-help-param-token": "[[Special:ApiHelp/query+tokens|action=query&meta=tokens]] から取得した「$1」トークン",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(説明なし)</span>",
+ "api-help-examples": "{{PLURAL:$1|例}}:",
+ "api-help-permissions": "{{PLURAL:$1|権限}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|権限を持つグループ}}: $2",
+ "api-credits-header": "クレジット",
+ "api-credits": "API の開発者:\n* Roan Kattouw (2007年9月-2009年の主任開発者)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (作成者、2006年9月-2007年9月の主任開発者)\n* Brad Jorsch (2013年-現在の主任開発者)\n\nコメント、提案、質問は mediawiki-api@lists.wikimedia.org にお送りください。\nバグはこちらへご報告ください: https://phabricator.wikimedia.org/"
+}
diff --git a/includes/api/i18n/jam.json b/includes/api/i18n/jam.json
new file mode 100644
index 00000000..3c44fd2a
--- /dev/null
+++ b/includes/api/i18n/jam.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Chabi1"
+ ]
+ },
+ "api-help-main-header": "Mien madyuul"
+}
diff --git a/includes/api/i18n/ko.json b/includes/api/i18n/ko.json
new file mode 100644
index 00000000..540f64c8
--- /dev/null
+++ b/includes/api/i18n/ko.json
@@ -0,0 +1,36 @@
+{
+ "@metadata": {
+ "authors": [
+ "Kwj2772",
+ "Twotwo2019",
+ "아라"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page 설명문서]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 공지 사항] * [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청] </div>\n<strong>상태:</strong> 이 페이지에 표시된 모든 기능은 정상 작동할 것이지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 바뀔 수 있습니다. 업데이트 정보를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 https://www.mediawiki.org/wiki/API:Errors_and_warnings 를 참고하십시오.",
+ "apihelp-main-param-action": "수행할 동작",
+ "apihelp-main-param-format": "출력값의 형식.",
+ "apihelp-block-description": "사용자를 차단합니다.",
+ "apihelp-block-param-user": "차단하고자 하는 계정 이름, IP 주소 또는 대역",
+ "apihelp-block-param-expiry": "기한. 상대값(예시: \"5 months\" 또는 \"2 weeks\") 또는 절대값(예시: \"2014-09-18T12:34:56Z\")이 될 수 있습니다. \"infinite\", \"indefinite\" 또는 \"never\"로 설정하면 무기한으로 설정됩니다.",
+ "apihelp-block-param-reason": "차단 이유.",
+ "apihelp-block-param-anononly": "익명 사용자만 차단합니다. (즉, 이 IP의 익명 편집을 막음)",
+ "apihelp-block-param-nocreate": "계정 생성을 막습니다.",
+ "apihelp-block-param-autoblock": "최근 사용한 IP 주소나 로그인을 시도한 이후에 사용한 모든 IP 주소를 자동으로 차단합니다.",
+ "apihelp-block-param-noemail": "위키를 통해 이메일을 보내지 못하도록 막습니다. (<code>blockemail</code> 권한 필요)",
+ "apihelp-block-param-hidename": "차단 기록에서 사용자 이름을 숨깁니다. (<code>hideuser</code> 권한 필요)",
+ "apihelp-block-param-allowusertalk": "자신의 토론 문서를 편집할 수 있도록 허용합니다. (<var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> 값에 따라 다름)",
+ "apihelp-block-param-reblock": "사용자가 이미 차단된 경우, 기존 차단 설정을 바꿉니다.",
+ "apihelp-block-param-watchuser": "해당 사용자 또는 IP 주소의 사용자 문서 및 토론 문서를 주시합니다.",
+ "apihelp-block-example-ip-simple": "IP <kbd>192.0.2.5</kbd>에 대해 <kbd>First strike</kbd>라는 이유로 3일간 차단하기",
+ "apihelp-block-example-user-complex": "사용자 <kbd>Vandal</kbd>을 <kbd>Vandalism</kbd>이라는 이유로 무기한 차단하며 계정 생성 및 이메일 발송을 막기",
+ "apihelp-delete-example-simple": "<kbd>Main Page</kbd>를 삭제합니다.",
+ "apihelp-edit-description": "문서를 만들고 편집합니다.",
+ "apihelp-edit-param-sectiontitle": "새 문단을 위한 제목.",
+ "apihelp-edit-param-text": "문서 내용.",
+ "apihelp-edit-param-summary": "편집 요약. 또한 $1section=new 및 $1sectiontitle이 설정되어 있지 않을 때 문단 제목.",
+ "apihelp-edit-param-minor": "사소한 편집.",
+ "apihelp-edit-param-notminor": "사소하지 않은 편집.",
+ "apihelp-edit-param-bot": "이 편집을 봇으로 표시.",
+ "api-help-param-list": "{{PLURAL:$1|1=하나의 값|2=값 (\"{{!}}\"로 구분)}}: $2",
+ "api-help-param-default": "기본값: $1"
+}
diff --git a/includes/api/i18n/ksh.json b/includes/api/i18n/ksh.json
new file mode 100644
index 00000000..cdcca375
--- /dev/null
+++ b/includes/api/i18n/ksh.json
@@ -0,0 +1,311 @@
+{
+ "@metadata": {
+ "authors": [
+ "Purodha"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page/de|Dokemäntazjohn]]\n* [[mw:API:FAQ/de|Öff jefrohch]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mäileng_Leß]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Aanköndejonge zom <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i>]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Jemäldte Fähler un Wönsch]\n</div>\n<strong>Status:</strong> Alle op heh dä Sigg aanjzeischte Ußwahle sullte donn, ävver et <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> wee jrahd noch äntwekeld un et kann sesch alle Nahslangs jädd ändere. Holl Der de [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ Mäileng_Leß med Aanköndejonge], öm automattesch övver Neujeschkeite enfommehrt ze wähde.\n\n<strong>Kapodde Aanfrohe:</strong> Wam_mer kapodde Aanfroheaan et API <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> schek, kritt mer ene <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Transfer Protocol\">HTTP</i>-Kopp ußjejovve met däm Täx „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">MediaWiki-API-Error</code>“ dren, dä mer als ene Schlößel bedraachte kann. Mih dohzoh fengk met op dä Sigg [[mw:API:Errors_and_warnings|<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i>: Fähler un Warnonge]].",
+ "apihelp-main-param-action": "Wat för en Aufjahb.",
+ "apihelp-main-param-format": "Et Fommaht för ußzejävve.",
+ "apihelp-main-param-smaxage": "Säz <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">s-maxage</code> em Kobb obb esu vill Sekonde. Fähler wähde nit faßjehallde.",
+ "apihelp-main-param-maxage": "Säz <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">max-age</code> em Kobb obb esu vill Sekonde. Fähler wähde nit faßjehallde.",
+ "apihelp-main-param-assert": "Ställ sescher, dat dä Metmaacher enjelogg es (doh för jiff <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">user</kbd> en), udder ene Bot es (doh för jiff <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">bot</kbd> en).",
+ "apihelp-main-param-requestid": "Jehde Aanjahb vun heh weed widder med ußjejovve. Esuh kam_mer einzel Affrohre ussenein hallde.",
+ "apihelp-main-param-servedby": "Donn däm ẞööver, dä et jedonn hät, singe Nahme med ußjävve.",
+ "apihelp-main-param-curtimestamp": "Donn de aktoälle Zigg un et Dattum med ußjävve.",
+ "apihelp-block-description": "Ene Metmaacher schpärre.",
+ "apihelp-block-param-user": "Däm Nahme vun däm Metmaacher, de <i lang=\"en\" xml:lang=\"en\" title=\"Internet Protocol\">IP</i>-Addräß udder dä Berätt, dä De Schpärre wells.",
+ "apihelp-block-param-reason": "Der Schpärrjrond.",
+ "apihelp-block-param-anononly": "Bloß de nahmelohse Metmaaacher spärre, alsu donn et nahmelohse Beärbeide vun dä <i lang=\"en\" xml:lang=\"en\" title=\"Internet Protocol\">IP</i>-Addräß uß verhendere.",
+ "apihelp-block-param-nocreate": "Et Neu-Aanmelde verbeede",
+ "apihelp-block-param-autoblock": "Dun automattesch de läzde <i lang=\"en\" xml:lang=\"en\">IP</i>-Adräß schpärre, di dä Metmaacher jehatt hät, un och all di <i lang=\"en\" xml:lang=\"en\">IP</i>-Adräße, vun wo dä versöhk, jet ze ändere.",
+ "apihelp-block-param-reblock": "Wann dä Metmaacher als jeschpächd es, donn dat övverschrihve.",
+ "apihelp-block-param-watchuser": "Donn de Metmaachersigg un de Klaafsigg dohzoh op mig Oppaßleß säze.",
+ "apihelp-block-example-ip-simple": "Donn de <i lang=\"en\" xmL:lang=\"en\" title=\"Internet Protocol\">IP</i>-Addräß <kbd>192.0.2.5</kbd> för drei ääsch schpärre mem Jrond: <kbd>Eestschlaach</kbd>.",
+ "apihelp-compare-description": "Donn de Ongerscheide zwesche zwai Sigge beschtemme.\n\nDo moß derför jeweils en Väsjohn, en Övverschreff för di Sigg, odder ener Sigg iehr Kännong aanjävve, för de beide Sigge.",
+ "apihelp-compare-param-fromtitle": "Der Tettel vun dä eezte Sigg zom verjlihsche.",
+ "apihelp-compare-param-fromid": "De Kännong vun dä eezte Sigg zom verjlihsche.",
+ "apihelp-compare-param-fromrev": "De Väsjohn vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-totitle": "Der Tettel vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-toid": "De Kännong vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-param-torev": "De Väsjohn vun dä zwaite Sigg zom verjlihsche.",
+ "apihelp-compare-example-1": "Fengk de Ongerscheide zwesche dä Väsjohne 1 un 2",
+ "apihelp-createaccount-description": "Ene neue Zohjang för ene Metmaacher aanlähje.",
+ "apihelp-createaccount-param-name": "Der Nahme för dä Metmaacher.",
+ "apihelp-createaccount-param-password": "Et Paßwoot (Weed ävver it jebruc un övverjange, wann <code lang=\"en\" xml:lang=\"en\"><var>$1mailpassword</var></code> jesaz es)",
+ "apihelp-createaccount-param-email": "Däm Metmaacher sing Adräß för de <i lang=\"en\" xml:lang=\"en\">e-mail</i>, kann och fott bliive.",
+ "apihelp-createaccount-param-realname": "Dämm Medmaacher singe reschtejje Nahme - kann fott blihve.",
+ "apihelp-createaccount-param-mailpassword": "Wann heh jädd aanjejovve es, kritt dä Metmaacher e zohfällesch ußjesöhk neu Paßwood aan sing Adräß för de <i lang=\"en\" xml:lang=\"en\">e-mail</i> jescheck.",
+ "apihelp-createaccount-param-reason": "Ene Jrond för dä Zojang aanzelähje, dä en de Logböhscher kütt.",
+ "apihelp-createaccount-param-language": "Dat Schprohcheköözel, wadd als der Schtandatt för dä Metmaacher jesaz wähde sull. Kann läddesch blihve, dann es et di Schprohch vum Wikki.",
+ "apihelp-createaccount-example-pass": "Lääsch dä Metmaacher <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">testuser</kbd> aan, mem Paßwood <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Lääsch dä Metmaacher <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">testmailuser</kbd> aan med emem zohfällesch ußjewörfelte Paßwoot un schegg_em dat övver de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">e-mail</i>.",
+ "apihelp-delete-description": "Schmieß en Sigg fott.",
+ "apihelp-delete-param-watch": "Donn di Sigg en däm aktoälle Metmaacher sing Oppaßleß opnämme.",
+ "apihelp-delete-param-unwatch": "Schmihß di Sigg us däm aktoälle Metmaacher singe Oppaßless erus.",
+ "apihelp-delete-example-simple": "Schmiiß de <kbd>Houpsigg</kbd> fott",
+ "apihelp-delete-example-reason": "Schmiiß de <kbd>Houpsigg</kbd> fott mem Jrond: <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Preparing for move</kbd>.",
+ "apihelp-disabled-description": "Dat Moduhl wohd affjeschalldt.",
+ "apihelp-edit-description": "Sigge aanlähje un verändere.",
+ "apihelp-edit-param-sectiontitle": "De Övverschreff för ene neue Affschnett.",
+ "apihelp-edit-param-text": "Dä Sigg ehre Ennhalld.",
+ "apihelp-edit-param-minor": "En klein Änderong.",
+ "apihelp-edit-param-notminor": "Kein klein Änderong.",
+ "apihelp-edit-param-bot": "Makeer heh di Änderog als vun enem Bot jemaat.",
+ "apihelp-edit-param-createonly": "Donn di Sigg nit ändere, wann se ald doh es.",
+ "apihelp-edit-param-nocreate": "Mäld ene Fähler, wann di Sigg nit doh es.",
+ "apihelp-edit-param-watch": "Donn di Sigg op dem aktälle Metmaacher sing Oppaßleß.",
+ "apihelp-edit-param-unwatch": "schmiiß di Sigg uß heh däm Metmaacher singe oppaßleß.",
+ "apihelp-edit-param-redirect": "Verfollsch de Ömleidonge automattesch.",
+ "apihelp-edit-param-contentmodel": "Et Enhalltsmodäll för dä neue Ennhalld.",
+ "apihelp-edit-example-edit": "Veränder en Sigg.",
+ "apihelp-edit-example-prepend": "Donn <kbd>_&#95;NOTOC_&#95;</kbd> för en Sigg säze.",
+ "apihelp-emailuser-description": "Donn en <i lang=\"en\" xml:lang=\"en\">e-mail</i> aan dä Metmaacher schecke.",
+ "apihelp-emailuser-param-target": "D ä Metmaacher, dä di <i lang=\"en\" xml:lang=\"en\">e-mail</i> krijje sull.",
+ "apihelp-emailuser-param-subject": "Koppeih mem Beträff.",
+ "apihelp-emailuser-param-text": "Dä Täx en dä <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">e-mail</i>.",
+ "apihelp-emailuser-param-ccme": "scheck mer en Koppih vun heh dä <i lang=\"en\" xml:lang=\"en\">e-mail</i>.",
+ "apihelp-emailuser-example-email": "Donn en <i lang=\"en\" xml:lang=\"en\">e-mail</i> aan dä Metmaacher <kbd lang=\"en\" xml:lang=\"en\">WikiSysop</kbd> schecke mem Täx <kbd>Dä Enhalld</kbd> dren.",
+ "apihelp-expandtemplates-description": "Deiht alle Schablohne en Wikkitäx ömsäze.",
+ "apihelp-expandtemplates-param-title": "De Övverschreff vun dä Sigg.",
+ "apihelp-expandtemplates-param-text": "Dä Wikitäx zom ömwandelle.",
+ "apihelp-expandtemplates-param-includecomments": "Ov Aanmärkonge em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"HyperText Markup Language\">HTML</i>-Fommaht med ußjejovve wähde sulle.",
+ "apihelp-feedcontributions-param-feedformat": "Däm Kannahl sing Fommaht.",
+ "apihelp-feedcontributions-param-year": "Vum johr un fröhjer.",
+ "apihelp-feedcontributions-param-month": "Vun däm Mohnd un derför",
+ "apihelp-feedcontributions-param-deletedonly": "zeijsch blohß de fottjeschmeße Beijdrähsch.",
+ "apihelp-feedcontributions-param-toponly": "Zeich blohß de Änderonge, di och de neußte sin.",
+ "apihelp-feedcontributions-param-newonly": "Zeich blohß de Änderonge, woh Sigge neu aanjelaat woode sin.",
+ "apihelp-feedcontributions-param-showsizediff": "Zeijsch de Ongerscheijd en de Jrühße zwesche de Väsjohne.",
+ "apihelp-feedcontributions-example-simple": "Zeijsch de Änderonge vum Metmaacher <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Example</kbd>.",
+ "apihelp-feedrecentchanges-param-feedformat": "Däm Kannahl sing Fommaht.",
+ "apihelp-feedrecentchanges-param-limit": "De hühßte Aanzahl vun Äjeebnesse för zeröck ze jävve",
+ "apihelp-feedrecentchanges-param-from": "Zeijsch de Änderonge zigg dämm.",
+ "apihelp-feedrecentchanges-param-hideminor": "De kein Minni_Änderonge verschteijsche.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Nohjelohrte Änderonge övverjonn.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Änderonge vun heh dämm Metmaacher övverjonn.",
+ "apihelp-feedwatchlist-param-feedformat": "Däm Kannahl sing Fommaht.",
+ "apihelp-filerevert-param-filename": "De Zih_Dattei, der ohne „{{ne:file}}“ derför.",
+ "apihelp-filerevert-param-comment": "Aanmärkong huh lahde.",
+ "apihelp-help-description": "zeisch Hölp för de aanjejovve Moduhle.",
+ "apihelp-help-example-recursive": "Alle Hölp en eine Sigg.",
+ "apihelp-help-example-help": "Alle Hölp övver de Hölp säälver.",
+ "apihelp-imagerotate-description": "Ein udder mieh Bellder driehje.",
+ "apihelp-imagerotate-param-rotation": "Öm wi vill Jrahd sulle de Bellder noh de Uhr drieh wääde?",
+ "apihelp-imagerotate-example-simple": "Drieh de <kbd>Dattei:Beijschpell.png</kbd> öm <kbd>90</kbd> Jrahd.",
+ "apihelp-imagerotate-example-generator": "Drieh alle Bellder en dä <kbd>Saachjropp:Ömdriehje</kbd> öm <kbd>180</kbd> Jrahd.",
+ "apihelp-import-param-xml": "Donn en Dattei em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Extensible Markup Language\">XML</i>-Fommaht huhjahde.",
+ "apihelp-import-param-rootpage": "Als Ongersiff vun heh dä Sigg empottehre-",
+ "apihelp-login-param-name": "Metmaacher_Nahme.",
+ "apihelp-login-param-password": "Paßwoot.",
+ "apihelp-login-param-domain": "De Domaijn (kann fott bliehve)",
+ "apihelp-login-example-login": "Enlogge.",
+ "apihelp-logout-example-logout": "Donn dä aktoälle Metmaacher ußlogge.",
+ "apihelp-move-description": "Donn en Sigg ömbenänne",
+ "apihelp-move-param-to": "De neue Övverschreff för di Sigg drop ömzebenänne.",
+ "apihelp-move-param-reason": "Der jrond för di Sigg ömzebenänne.",
+ "apihelp-move-param-movetalk": "Donn de Klaafsigg ömbenänne, wann et se jitt.",
+ "apihelp-move-param-movesubpages": "Donn de Ongersigge ömbenänne, wann müjjelesch.",
+ "apihelp-move-param-noredirect": "Donn kein Ömleidong aanlähje.",
+ "apihelp-move-param-watch": "Donn de Sigg un de Ömleijdong op dem aktoälle Metmaacher sing Oppaßleß.",
+ "apihelp-move-param-unwatch": "Donn de Sigg un de Ömleijdong uß dem aktoälle Metmaacher sing Oppaßleß eruß nämme.",
+ "apihelp-move-param-watchlist": "Donn di Sigg en dem aktoälle Metmaacher sing Oppaßleß udder nemm se eruß, donn de Enschtällonge nämme udder donn de Oppaßleß nid ändere.",
+ "apihelp-move-param-ignorewarnings": "Donn alle Warnonge övverjonn",
+ "apihelp-move-example-move": "Donn <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Schlääschte Övverschreff</kbd> nach <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Johde Övverschreff</kbd> önmännde, der ohne en Ömleijdong aanzelähje.",
+ "apihelp-opensearch-description": "Em Wikki söhke mem <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„Offe Söhke“\">OpenSearch</i>",
+ "apihelp-opensearch-param-search": "Noh wat söhke?",
+ "apihelp-opensearch-param-limit": "De hühßte Aanzahl vun Äjeebnesse för zeröck ze jävve",
+ "apihelp-opensearch-param-namespace": "En wällschem Appachtemang söhke.",
+ "apihelp-opensearch-param-redirects": "How to handle redirects:\n;return:Return the redirect itself.\n;resolve:Return the target page. May return fewer than $1limit results.\nFor historical reasons, the default is \"return\" for $1format=json and \"resolve\" for other formats.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-opensearch-param-redirects/en\n-->",
+ "apihelp-opensearch-param-format": "Et Fommaht zom Ußjävve.",
+ "apihelp-opensearch-example-te": "Fengk Sigge, di met <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Te</kbd> aanfange.",
+ "apihelp-options-param-reset": "Säz de Enschtällonge op dem Wikki singe Standatt.",
+ "apihelp-options-example-reset": "Alle enschtälloonge retuur schtälle.",
+ "apihelp-paraminfo-description": "Holl Aanjahbe övver dä <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> ier Moduhle.",
+ "apihelp-paraminfo-param-helpformat": "Et Fommaht vun de Täxe för Hölp.",
+ "apihelp-paraminfo-param-formatmodules": "Leß met de Nahme vun de Moduhle zom Fommatehre (Wäät vum „<var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">format</var>“-Parramehter). Nemm schtatt dämm „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1modules</kbd>“.",
+ "apihelp-paraminfo-example-1": "Zisch Aanjahbe övver <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Special:ApiHelp/parse|action=parse]]</kbd>, <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>, <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>, un <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>.",
+ "apihelp-parse-param-summary": "De Zersammefaßong för ze pahse.",
+ "apihelp-parse-param-section": "Holl blohß dann der Ennhalld vun däm Affschnett met dä Nommer, udder wann „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">new</kbd>“ enjejovve es, maach ene neu Affschnett derbei.",
+ "apihelp-parse-param-sectiontitle": "De Övverschreff för dä neuje Afschnet, wann <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">section</var> = <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">new</kbd> es.\n\nAnders wi beim Beärbeide vun dä Sigg weed dä Parramehter nit dorsch de <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">summary</var> ußjetuusch, wann hä fottjelohße udder läddesch es.",
+ "apihelp-parse-example-page": "Donn en Sigg pahse.",
+ "apihelp-parse-example-text": "Donn Wikkitäx pahse.",
+ "apihelp-parse-example-texttitle": "Donn Wikkitäx pahse, un jiff derför en Övverschreff för en Sigg aan.",
+ "apihelp-parse-example-summary": "Donn Zersammefaßong pahse.",
+ "apihelp-patrol-description": "Donn en Sigg udder Väsjohn nohkike.",
+ "apihelp-patrol-param-rcid": "De Kännong in de läzde Änderonge zum Nohkike.",
+ "apihelp-patrol-param-revid": "De Kännong vun dä Väsjohn zum Nohkike.",
+ "apihelp-patrol-example-rcid": "Donn en läzde Änderonge nohkike.",
+ "apihelp-patrol-example-revid": "Donn en Väsjohn nohkike.",
+ "apihelp-protect-description": "Änder der Siggeschoz för en Sigg.",
+ "apihelp-protect-param-title": "De Övverschreff vun dä Sigg zom Schöze udder Freijävve. Kam_mer nit zesamme met\n„<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1pageid</code>“ bruche.",
+ "apihelp-protect-param-pageid": "De Kännong vun dä Sigg zom Schöze udder Freijävve. Kam_mer nit zesamme met\n„<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1pageid</code>“ bruche.",
+ "apihelp-protect-param-reason": "Der Jrond för et Schöze udder Freijävve.",
+ "apihelp-protect-example-protect": "Donn en Sigg schöze.",
+ "apihelp-query-param-list": "Wat för en Leßte holle.",
+ "apihelp-query-param-meta": "Wat för en Matta_Dahte ze holle.",
+ "apihelp-query+allcategories-description": "Alle Saachjroppe opzälle.",
+ "apihelp-query+allcategories-param-from": "De Saachjropp, vun woh aan opzälle.",
+ "apihelp-query+allcategories-param-to": "De Saachjropp, bes woh hen opzälle.",
+ "apihelp-query+allcategories-param-dir": "De Reijefollsch zum Zotehre.",
+ "apihelp-query+allcategories-param-limit": "Wi vell Saachjroppe ußjävve?",
+ "apihelp-query+allcategories-param-prop": "Which properties to get:\n;size:Adds number of pages in the category.\n;hidden:Tags categories that are hidden with _&#95;HIDDENCAT_&#95;.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Ballcategories-param-prop/ksh\n-->",
+ "apihelp-query+alldeletedrevisions-description": "Donn alle fottjeschmeße Väsjohne vun enem Metmaacher udder en enem Appachemang opleßte.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kam_mer blohß met <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$3user</var> bruche.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Kam_mer nit met <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$3user</var> bruche.",
+ "apihelp-query+alldeletedrevisions-param-start": "Et Dattom un de Zigg vun woh aff opjezallt wähde sull.",
+ "apihelp-query+alldeletedrevisions-param-end": "Et Dattom un de Zigg bes woh hen opjezallt wähde sull.",
+ "apihelp-query+alldeletedrevisions-param-from": "Bejenn de Leß bei heh dä Överschreff.",
+ "apihelp-query+alldeletedrevisions-param-to": "Hühr de Leß bei heh dä Överschreff oop.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Söhk noh Sigge, woh de Övverschrevv esu aanfängk.",
+ "apihelp-query+alldeletedrevisions-param-user": "Donn blohß Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Donn kein Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Donn blohß Siegg en heh däm Appachtemang opleßte.",
+ "apihelp-query+alldeletedrevisions-param-generatetitles": "Wann als ene Jenerahtor enjesaz, bräng Övverschreffte un kein Kännonge vu Väsjohne.",
+ "apihelp-query+alldeletedrevisions-example-user": "Donn de läzde fuffzisch fottjeschmeße Beijdrähsch vim Metmaacher „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Example<kbd>“ opleste.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Donn de läzde fuffzisch fottjeschmeße Väsjohne em Houp-Appachemang opleste.",
+ "apihelp-query+allfileusages-description": "Donn alle Dattei_Oprohfe opleste, och vun Datteije, di (noch) nit doh sin.",
+ "apihelp-query+allfileusages-param-from": "De Övverschreff vun dä Dattei, woh de Leß medd aanfange sull.",
+ "apihelp-query+allfileusages-param-to": "De Övverschreff vun dä Dattei, woh de Leß medd ophühre sull.",
+ "apihelp-query+allfileusages-param-prefix": "Söhk noh alle Övverschreffte, di met heh däm Täx aanfange.",
+ "apihelp-query+allfileusages-param-unique": "Donn blohß ongerscheidlijje Övverschreffte vun Datteije aanzeije. Kammer nit zesamme met „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1prop=ids<code>“ bruche.\nWann als ene Jenerahtor enjesaz, bräng Zihlsigge un kein Kwällsigge.",
+ "apihelp-query+allfileusages-param-prop": "Which pieces of information to include:\n;ids:Adds the page ID of the using page (cannot be used with $1unique).\n;title:Adds the title of the file.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Ballfileusages-param-prop/ksh\n-->",
+ "apihelp-query+allfileusages-param-limit": "Wi vill sulle överhoup aanjezeisch wähde?",
+ "apihelp-query+allfileusages-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+allfileusages-example-B": "Donn Övverschreffte vun Datteije aanzeije, och vun Datteije, di (noch) nit doh sin, zesame met dä Kännonge vun dä Sigge, woh se vun sin, aanjevange vun <kbd>B</kbd>.",
+ "apihelp-query+allfileusages-example-unique": "Donn ongerscheidlejje Övverschreffte vun Datteije opleßte.",
+ "apihelp-query+allfileusages-example-generator": "Holl Sigge, woh Datteieje dren vorkumme.",
+ "apihelp-query+allimages-description": "Donn alle Bellder der Reih noh opzälle.",
+ "apihelp-query+allimages-param-sort": "De Eijeschavv öm dernoh ze zottehre.",
+ "apihelp-query+allimages-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+allimages-param-limit": "Wi vell Bellder ennsjesamp ußjävve.",
+ "apihelp-query+allimages-example-generator": "Zeisch Aanjahbe övver veer Bellder un bejenn mem Bohchschtabe <kbd>T</kbd>.",
+ "apihelp-query+alllinks-description": "Donn alle Lengk opzälle, di en e beschtemmpt Appachtemang jonn.",
+ "apihelp-query+alllinks-param-from": "De Övverschreff vun däm Lengk, woh de Leß medd aanfange sull.",
+ "apihelp-query+alllinks-param-to": "De Övverschreff vun dä Dattei, woh et Zälle ophühre sull.",
+ "apihelp-query+alllinks-param-prefix": "Söhk noh alle verlengk Övverschreffte, di met heh däm Täx aanfange.",
+ "apihelp-query+alllinks-param-namespace": "Dat Appachtemang zom opzälle.",
+ "apihelp-query+alllinks-param-limit": "Wi vill sulle överhoup aanjezeisch wähde?",
+ "apihelp-query+alllinks-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+alllinks-example-unique": "Leß ongerscheidlejje verlengk Övverschreffte.",
+ "apihelp-query+alllinks-example-generator": "Holl Sigge, di di Lengks änthallde.",
+ "apihelp-query+allmessages-description": "Donn em Wikki sing Täxte un Nohreescht ußjävve.",
+ "apihelp-query+allmessages-param-prop": "Wat för en Eijeschaffte holle.",
+ "apihelp-query+allmessages-param-args": "De Parramehtere för en dä Täx udder en di Nohreesch enzeföhje.",
+ "apihelp-query+allmessages-param-filter": "Jiv blohß de Täxte un Nohreesche uß, woh heh dat Täxschtöck dren änthallde es.",
+ "apihelp-query+allmessages-param-customised": "Jiv bloß de Täxte un Nohreesche en heh däm Zohschtand uß.",
+ "apihelp-query+allmessages-param-lang": "Jiv de Täxte un Nohreesche en heh dä Schprohch uß.",
+ "apihelp-query+allmessages-param-from": "Jiv de Täxte un Nohreesche vun heh aan uß.",
+ "apihelp-query+allmessages-param-to": "Jiv de Täxte un Nohreesche bes heh uß.",
+ "apihelp-query+allmessages-param-prefix": "Jiv de Täxte un Nohreesche met heh däm Aanfang uß.",
+ "apihelp-query+allmessages-example-ipb": "Zeijsch Täxde udder Nohreeschte di met „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">ipb</kbd>“ aanfange.",
+ "apihelp-query+allmessages-example-de": "Zeijsch de Täxde udder Nohreeschte „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">august</kbd>“ un „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">mainpage</kbd>“ en Deutsch aan.",
+ "apihelp-query+allpages-description": "Donn alle Sigge der Reih noh en enem jejovve Appachtemang aan.",
+ "apihelp-query+allpages-param-from": "De Övverschreff vun dä Sigg, woh de Leß medd aanfange sull.",
+ "apihelp-query+allpages-param-to": "De Kännong vun dä Sigg, bes woh hen opzälle.",
+ "apihelp-query+allpages-param-prefix": "Söhk noh alle Övverschreffte vun Sigge, di met heh dämm Wäät bejenne.",
+ "apihelp-query+allpages-param-namespace": "De Saachjropp zom opzälle.",
+ "apihelp-query+allpages-param-filterredir": "Wat för en Sigg zem opleßte.",
+ "apihelp-query+allpages-param-minsize": "Bejränz op Sigge met winneschßdens esu vill Bytes dren.",
+ "apihelp-query+allpages-param-maxsize": "Bejränz op Sigge met hüüschßdens esu vill Bytes dren.",
+ "apihelp-query+allpages-param-prtype": "Bejränz op jeschöz Sigge.",
+ "apihelp-query+allpages-param-limit": "Wi vill Sigge zen aanzeije?",
+ "apihelp-query+allpages-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+allpages-example-B": "Zeisch en Leß met Sigge un bejenn mem Bohchschtabe <kbd>B</kbd>.",
+ "apihelp-query+allpages-example-generator": "Zeisch Aanjahbe övver veer Bellder un bejenn mem Bohchschtabe <kbd>T</kbd>.",
+ "apihelp-query+allpages-example-generator-revisions": "Zeisch der Enhalld vu de eetsde zwai Sigg un bejenn bei <kbd>Re</kbd>.",
+ "apihelp-query+allredirects-description": "Alle Ömleidonge op e beschtemmp Appachtemang opleßte.",
+ "apihelp-query+allredirects-param-from": "De Övverschreff vun dä Ömleidong, woh de Leß medd ophühre sull.",
+ "apihelp-query+allredirects-param-to": "De Övverschreff vun dä Sigg, woh et Zälle ophühre sull.",
+ "apihelp-query+allredirects-param-prefix": "Söhk not sigge, die esu aanfange.",
+ "apihelp-query+allredirects-param-namespace": "Dat Appachtemang zom opzälle.",
+ "apihelp-query+allredirects-param-limit": "Wi vill sulle överhoup aanjezeisch wääde?",
+ "apihelp-query+allredirects-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+allredirects-example-B": "Zeisch Zihlsigge, och di et (noch) nit jitt, met dä Kännonge, wo se her sin, un bejenn mem Bohchschtabe <kbd>B</kbd>.",
+ "apihelp-query+allredirects-example-unique": "Ongerscheidlijje Sigge opleste.",
+ "apihelp-query+allredirects-example-generator": "Holl de Sigge met de Ömleidonge.",
+ "apihelp-query+alltransclusions-param-namespace": "Dat Appachtemang zom opzälle.",
+ "apihelp-query+alltransclusions-param-limit": "Wi vill sulle överhoup aanjezeisch wähde?",
+ "apihelp-query+alltransclusions-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+allusers-description": "Donn alle aanjemälldte Metmaacher opzälle.",
+ "apihelp-query+allusers-param-from": "Dä Metmaacher_Nahme vun woh aan opzälle.",
+ "apihelp-query+allusers-param-to": "Dä Metmaacher_Nahme bes woh hen opzälle.",
+ "apihelp-query+allusers-param-prefix": "Söhk noh alle Metmaacher_Nahme, di mit heh däm Wäät bejenne.",
+ "apihelp-query+allusers-param-dir": "De Reijefollsch zum Zotehre.",
+ "apihelp-query+allusers-param-group": "Donn blohß Metmaacher uß dä aanjejovve Jroppe enschlehße.",
+ "apihelp-query+allusers-param-excludegroup": "Donn keine Metmaacher uß dä aanjejovve Jroppe enschlehße.",
+ "apihelp-query+allusers-param-limit": "Wi vill Nahme Metmaacher sulle mer krijje?",
+ "apihelp-query+allusers-param-witheditsonly": "Blohß Metmahcher, di och ens jät verändert han.",
+ "apihelp-query+allusers-param-activeusers": "Donn blohß Metmaacher opleßte, di {{PLURAL:$1|der läzde Daach|en de läzde $1 Dääsch|keine läzde Daach}} aktihf wohre.",
+ "apihelp-query+allusers-example-Y": "Monn metmaacher opleßte, woh de Nahme vun met <kbd>Y</kbd> aanfange.",
+ "apihelp-query+backlinks-description": "Fengk alle Sigge, di op de aanjejovve Sigg lengke.",
+ "apihelp-query+backlinks-param-namespace": "Dat Appachtemang zom opzälle.",
+ "apihelp-query+backlinks-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+backlinks-example-simple": "Zeijsch Lengks op de Sigg <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Main page<kbd>.",
+ "apihelp-query+blocks-param-start": "Et Dattom un de Zigg vun woh aff opjezallt wähde sull.",
+ "apihelp-query+blocks-param-end": "Et Dattom un de Zigg bes woh hen opjezallt wähde sull.",
+ "apihelp-query+blocks-param-limit": "De hühßde Aanzahl Spärre zom opleste.",
+ "apihelp-query+blocks-param-prop": "Which properties to get:\n;id:Adds the ID of the block.\n;user:Adds the username of the blocked user.\n;userid:Adds the user ID of the blocked user.\n;by:Adds the username of the blocking user.\n;byid:Adds the user ID of the blocking user.\n;timestamp:Adds the timestamp of when the block was given.\n;expiry:Adds the timestamp of when the block expires.\n;reason:Adds the reason given for the block.\n;range:Adds the range of IP addresses affected by the block.\n;flags:Tags the ban with (autoblock, anononly, etc.).\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Bblocks-param-prop/ksh\n-->",
+ "apihelp-query+blocks-example-simple": "Schpärre opleßte.",
+ "apihelp-query+blocks-example-users": "Donn de Schpärre vun dä Metmaacher <lang=\"en\" xml:lang=\"en\" dir=\"ltr\" kbd>Alice</kbd> un <lang=\"en\" xml:lang=\"en\" dir=\"ltr\" kbd>Bob</kbd> opleßte.",
+ "apihelp-query+categories-description": "Donn alle Saachjroppe epleßte, woh di Sigge dren sin.",
+ "apihelp-query+categories-param-prop": "Which additional properties to get for each category:\n;sortkey:Adds the sortkey (hexadecimal string) and sortkey prefix (human-readable part) for the category.\n;timestamp:Adds timestamp of when the category was added.\n;hidden:Tags categories that are hidden with _&#95;HIDDENCAT_&#95;.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Bcategories-param-prop/ksh\n-->",
+ "apihelp-query+categories-param-show": "Wat för en Zoot Saachjroppe zeije.",
+ "apihelp-query+categories-param-limit": "Wi vell Saachjroppe ußjävve?",
+ "apihelp-query+categories-param-dir": "En wälsche Reijefollsch?",
+ "apihelp-query+categories-example-simple": "Holl en Leß med alle Saachjroppe, woh di Sigg <kbd>Albert Einstein</kbd> dren es.",
+ "apihelp-query+categories-example-generator": "Holl Aanjahbe övver alle Saachjroppe, di en dä Sigg <kbd>Albert Einstein</kbd> jebruch wähde.",
+ "apihelp-query+categoryinfo-description": "Holl Aanjahbe övver de aanjejovve Saachjroppe.",
+ "apihelp-query+categorymembers-description": "Donn alle Sigge en ener aanjejove saachjrobb opleste.",
+ "apihelp-query+categorymembers-param-limit": "De jrüüßte Zahl Sigge för ußzejävve.",
+ "apihelp-query+categorymembers-param-sort": "De Eijeschavv öm dernoh ze zottehre.",
+ "apihelp-query+categorymembers-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+categorymembers-param-startsortkey": "Söhk „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1starthexsortkey</code>“ schtatt dämm.",
+ "apihelp-query+categorymembers-param-endsortkey": "Söhk „<code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1endhexsortkey </code>“ schtatt dämm.",
+ "apihelp-query+categorymembers-example-simple": "Holl de eezde zehn Sigge de dä <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Category:Physics</kbd>.",
+ "apihelp-query+categorymembers-example-generator": "Holl anjahbe övver de eezde zehn Sigge de dä <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Category:Physics</kbd>.",
+ "apihelp-query+deletedrevisions-param-user": "Donn blohß Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+deletedrevisions-param-excludeuser": "Donn kein Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+deletedrevisions-param-limit": "De hühßde Aanzahl Väsjohne för opzeleßte.",
+ "apihelp-query+deletedrevisions-param-prop": "Wat för en Eijeschaffte holle:\n;revid:Adds the revision ID of the deleted revision.\n;parentid:Adds the revision ID of the previous revision to the page.\n;user:Adds the user who made the revision.\n;userid:Adds the user ID who made the revision.\n;comment:Adds the comment of the revision.\n;parsedcomment:Adds the parsed comment of the revision.\n;minor:Tags if the revision is minor.\n;len:Adds the length (bytes) of the revision.\n;sha1:Adds the SHA-1 (base 16) of the revision.\n;content:Adds the content of the revision.\n;tags:Tags for the revision.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Bdeletedrevisions-param-prop/en\n-->",
+ "apihelp-query+deletedrevisions-example-revids": "Donn de Aanjahbe för de fottjeschmeße Väsjohn <kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">123456</kbd> holle.",
+ "apihelp-query+duplicatefiles-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+embeddedin-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+filearchive-param-dir": "En wälsche Reijefollsch opleßte.",
+ "apihelp-query+images-param-dir": "En wälsche Reijefollsch opleßte.",
+ "apihelp-query+imageusage-param-namespace": "Dat Appachtemang zom opzälle.",
+ "apihelp-query+imageusage-param-dir": "En wälsche Reijefollsch opleßte.",
+ "apihelp-query+info-paramvalue-prop-watchers": "De Aanzahl Oppaßer, wann zohjelohße.",
+ "apihelp-query+iwbacklinks-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+iwlinks-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+langbacklinks-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+langlinks-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+links-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+pagepropnames-param-limit": "De jrüüßte Zahl Nahme för ußzejävve.",
+ "apihelp-query+pagepropnames-example-simple": "Holl de eezde zehn Nahme vun Eijeschaffte.",
+ "apihelp-query+pageswithprop-param-limit": "De jrüüßte Zahl Sigge för ußzejävve.",
+ "apihelp-query+pageswithprop-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+prefixsearch-param-namespace": "En wällschem Appachtemang söhke.",
+ "apihelp-query+prefixsearch-param-limit": "De hühßte Aanzahl vun Äjeebnesse för zeröck ze jävve",
+ "apihelp-query+querypage-param-limit": "De Aanzahl vun Äjeebnesse för zeröck ze jävve",
+ "apihelp-query+random-param-limit": "Wi vill zohfälleje Sigge sulle ußjejovve wähde?",
+ "apihelp-query+revisions+base-param-limit": "Wi vill Väsjohne sulle ußjejovve wähde?",
+ "apihelp-query+siteinfo-param-numberingroup": "Donn de Aanzahl Metmaacher en de Jroppe vun Metmaacher opleßte.",
+ "apihelp-query+tags-param-limit": "De hühßde Aanzahl !!FUZY tags zom opleste.",
+ "apihelp-query+tags-param-prop": "Wat för en Eijschaffte holle:\n;name:Adds name of tag.\n;displayname:Adds system message for the tag.\n;description:Adds description of the tag.\n;hitcount:Adds the number of revisions and log entries that have this tag.\n;defined:Indicate whether the tag is defined.\n;source:Gets the sources of the tag, which may include <samp>extension</samp> for extension-defined tags and <samp>manual</samp> for tags that may be applied manually by users.\n;active:Whether the tag is still being applied.\n<!-- https://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Apihelp-query%2Btags-param-prop/ksh\n -->",
+ "apihelp-query+templates-param-limit": "Wi vill Schablohne sulle ußjejovve wähde?",
+ "apihelp-query+templates-param-dir": "En wälsche Reihjefollsch opleßte.",
+ "apihelp-query+usercontribs-param-limit": "De hühßte Aanzahl vun Meddeilonge för zeröck ze jävve",
+ "api-help-param-default": "Schtandatt: $1",
+ "api-help-param-default-empty": "Schtandatt: <span class=\"apihelp-empty\">(läddesch)</span>",
+ "api-help-param-limited-in-miser-mode": "<strong>opjepaß:</strong> Weil der [[mw:Manual:$wgMiserMode|miser mode]] enjeschalld es, künne heh winnijer wi <var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1limit</var> Äjehpneße ußjejejovve wähde, vör em Wigger_Mache. En Jränzfäll künne et Noll sin.",
+ "api-help-param-direction": "En wälsche Reihjefollsch opleßte:\n;newer:List oldest first. Note: $1start has to be before $1end.\n;older:List newest first (default). Note: $1start has to be later than $1end.\n<!-- \nhttps://translatewiki.net/wiki/Thread:Support/About_MediaWiki:Api-help-param-direction/ksh\n-->",
+ "api-help-param-continue": "Wann mih ze holle es, nemm dat för wigger ze maache.",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(nix drövver bikannt)</span>",
+ "api-help-examples": "{{PLURAL:$1|Beijschpell|Beijschpelle|Beijschpell}}:",
+ "api-help-permissions": "{{PLURAL:$1|Rääsch|Rääschde|Rääsch}}:",
+ "api-help-permissions-granted-to": "Jejovve aan: $2{{PLURAL:$1|}}",
+ "api-help-right-apihighlimits": "Donn de Beschängkonge vun Opdrähscht aan de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> kleiner maache (langsamme Opdrähscht: $1; flöcke Opdrähscht: $2). De Beschränkonge för lahme Opdrähscht jällde och för Parramehtere met vill Wähte.",
+ "api-credits-header": "Aanäkännong för Beijdrähsch",
+ "api-credits": "Dä <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Application Programming Interface\">API</i> ier Äntweklere:\n* Roan Kattouw (Aanföhrer zigg em Säptämber 2007 bes 2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (Bejenner un Aanföhrer vum Säptämber 2006 bes Säptämber 2007)\n* Brad Jorsch (Aanföhrer vun 2013 bes hük)\n\nDoht Ühr Aanmärkonge, Vörschlähsch un Frohre aan de Meijlengleß <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">mediawiki-api@lists.wikimedia.org</code> scheke, Ühr Vörschlähsch un Fählermälldong doht op <code lang=\"en\" xml:lang=\"en\" dir=\"ltr\">https://phabricator.wikimedia.org/</code> ennjävve."
+}
diff --git a/includes/api/i18n/ku-latn.json b/includes/api/i18n/ku-latn.json
new file mode 100644
index 00000000..a40e4c11
--- /dev/null
+++ b/includes/api/i18n/ku-latn.json
@@ -0,0 +1,9 @@
+{
+ "@metadata": {
+ "authors": [
+ "George Animal"
+ ]
+ },
+ "apihelp-delete-description": "Rûpelekê jê bibe.",
+ "apihelp-expandtemplates-param-title": "Sernavê rûpelê."
+}
diff --git a/includes/api/i18n/lb.json b/includes/api/i18n/lb.json
new file mode 100644
index 00000000..ac2a1d34
--- /dev/null
+++ b/includes/api/i18n/lb.json
@@ -0,0 +1,94 @@
+{
+ "@metadata": {
+ "authors": [
+ "Robby"
+ ]
+ },
+ "apihelp-block-description": "E Benotzer spären.",
+ "apihelp-block-param-user": "Benotzernumm, IP-Adress oder IP-Beräich deen Dir späre wëllt.",
+ "apihelp-block-param-reason": "Grond fir ze spären.",
+ "apihelp-block-param-anononly": "Nëmmen anonym Benotzer spären (z. Bsp. anonym Ännerunge vun dëser IP-Adress ausschalten)",
+ "apihelp-block-param-nocreate": "Opmaache vun engem Benotzerkont verhënneren.",
+ "apihelp-block-param-reblock": "Wann de Benotzer scho gespaart ass, déi aktuell Spär iwwerschreiwen.",
+ "apihelp-block-param-watchuser": "Dem Benotzer oder der IP-Adress hier Benotzer- an Diskussiouns-Säiten iwwerwaachen.",
+ "apihelp-compare-param-fromtitle": "Éischten Titel fir ze vergläichen.",
+ "apihelp-createaccount-description": "En neie Benotzerkont uleeën.",
+ "apihelp-createaccount-param-name": "Benotzernumm.",
+ "apihelp-createaccount-param-email": "E-Mail-Adress vum Benotzer (fakultativ).",
+ "apihelp-createaccount-param-realname": "Richtegen Numm vum Benotzer (fakultativ).",
+ "apihelp-delete-description": "Eng Säit läschen.",
+ "apihelp-delete-param-watch": "D'Säit op dem aktuelle Benotzer seng Iwwerwaachungslëscht dobäisetzen.",
+ "apihelp-delete-example-simple": "D'<kbd>Haaptsäit</kbd> läschen.",
+ "apihelp-disabled-description": "Dëse Modul gouf ausgeschalt.",
+ "apihelp-edit-param-sectiontitle": "Den Titel fir en neien Abschnitt.",
+ "apihelp-edit-param-minor": "Kleng Ännerung.",
+ "apihelp-edit-param-bot": "Dës Ännerung als Bot-Ännerung markéieren.",
+ "apihelp-edit-param-watch": "D'Säit op dem aktuelle Benotzer seng Iwwerwaachungslëscht dobäisetzen.",
+ "apihelp-edit-example-edit": "Eng Säit änneren",
+ "apihelp-expandtemplates-param-title": "Titel vun der Säit.",
+ "apihelp-feedrecentchanges-param-hideminor": "Kleng Ännerunge verstoppen.",
+ "apihelp-feedrecentchanges-param-hideanons": "Ännerunge vun anonyme Benotzer verstoppen.",
+ "apihelp-feedrecentchanges-param-hideliu": "Ännerunge vu registréierte Benotzer verstoppen.",
+ "apihelp-feedrecentchanges-example-simple": "Rezent Ännerunge weisen",
+ "apihelp-help-example-main": "Hëllef fir den Haaptmodul.",
+ "apihelp-help-example-recursive": "All Hëllef op enger Säit",
+ "apihelp-imagerotate-description": "Eent oder méi Biller dréinen.",
+ "apihelp-imagerotate-example-generator": "All Biller an der <kbd>Category:Flip]]<kbd> ëm <kbd>180<kbd> Grad dréinen.",
+ "apihelp-import-param-summary": "Resumé importéieren.",
+ "apihelp-login-param-name": "Benotzernumm.",
+ "apihelp-login-param-password": "Passwuert.",
+ "apihelp-login-example-login": "Aloggen.",
+ "apihelp-move-description": "Eng Säit réckelen.",
+ "apihelp-move-param-ignorewarnings": "All Warnungen ignoréieren.",
+ "apihelp-options-example-reset": "All Astellungen zrécksetzen",
+ "apihelp-patrol-example-rcid": "Eng rezent Ännerung nokucken.",
+ "apihelp-patrol-example-revid": "Eng Versioun nokucken.",
+ "apihelp-protect-example-protect": "Eng Säit spären",
+ "apihelp-query+allcategories-description": "All Kategorien opzielen.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kann nëmme mam <var>$3user</var> benotzt ginn.",
+ "apihelp-query+alldeletedrevisions-param-user": "Nëmme Versioune vun dësem Benotzer opzielen.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Versioune vun dësem Benotzer net opzielen.",
+ "apihelp-query+allusers-description": "All registréiert Benotzer opzielen.",
+ "apihelp-query+allusers-param-activeusers": "Nëmme Benotzer opzielen déi an de leschten $1 {{PLURAL:$1|Dag|Deeg}} aktiv waren.",
+ "apihelp-query+blocks-description": "Lëscht vun de gespaarte Benotzer an IP-Adressen.",
+ "apihelp-query+blocks-example-simple": "Lëscht vun de Spären",
+ "apihelp-query+categories-description": "All Kategorien opzielen zu deenen dës Säit gehéiert.",
+ "apihelp-query+categorymembers-description": "All Säiten aus enger bestëmmter Kategorie opzielen.",
+ "apihelp-query+categorymembers-example-simple": "Déi éischt 10 Säiten aus der <kbd>Category:Physics</kbd> kréien.",
+ "apihelp-query+deletedrevisions-param-excludeuser": "Versioune vun dësem Benotzer net opzielen.",
+ "apihelp-query+deletedrevs-param-unique": "Nëmmen eng Versioun fir all Säit weisen.",
+ "apihelp-query+filearchive-example-simple": "Eng Lëscht vun alle geläschte Fichiere weisen",
+ "apihelp-query+imageinfo-paramvalue-prop-user": "Setzt fir all Versioun vum Fichier de Benotzer dobäi deen en eropgelueden huet.",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "Bemierkung iwwert d'Versioun.",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias fir Gréisst.",
+ "apihelp-query+imageinfo-param-urlheight": "Ähnlech wéi $1urlwidth.",
+ "apihelp-query+images-example-simple": "Eng Lëscht vun de Fichiere kréien déi op der [[Main Page|Haaptsäit]] benotzt ginn",
+ "apihelp-query+imageusage-example-simple": "Säite weisen déi [[:File:Albert Einstein Head.jpg]] benotzen",
+ "apihelp-query+info-paramvalue-prop-readable": "Ob de Benotzer dës Säit liese kann.",
+ "apihelp-query+langlinks-param-lang": "Nëmme Sproochlinke mat dësem Sproochcode zréckginn.",
+ "apihelp-query+protectedtitles-param-namespace": "Nëmmen Titelen aus dësen Nummraim opzielen.",
+ "apihelp-query+recentchanges-param-user": "Nëmmen Ännerunge vun dësem Benotzer opzielen.",
+ "apihelp-query+recentchanges-example-simple": "Rezent Ännerunge weisen",
+ "apihelp-query+revisions-example-last5": "Déi lescht 5 Versioune vun der <kbd>Haaptsäit</kbd> kréien.",
+ "apihelp-query+usercontribs-description": "All Ännerunge vun engem Benotzer kréien.",
+ "apihelp-query+watchlist-param-user": "Nëmmen Ännerunge vun dësem Benotzer opzielen.",
+ "apihelp-query+watchlist-param-excludeuser": "Ännerunge vun dësem Benotzer net opzielen.",
+ "apihelp-query+watchlistraw-param-show": "Nëmmen Elementer opzielen déi dëse Critèren entspriechen.",
+ "apihelp-query+watchlistraw-example-simple": "Säite vum aktuelle Benotzer senger Iwwerwaachungslëscht opzielen",
+ "apihelp-revisiondelete-description": "Versioune läschen a restauréieren.",
+ "apihelp-revisiondelete-param-reason": "Grond fir ze Läschen oder ze Restauréieren.",
+ "apihelp-rsd-example-simple": "Den RSD-Schema exportéieren",
+ "apihelp-unblock-description": "D'Spär vun engem Benotzer ophiewen.",
+ "apihelp-unblock-param-reason": "Grond fir d'Spär opzehiewen",
+ "apihelp-undelete-param-reason": "Grond fir ze restauréieren.",
+ "apihelp-undelete-example-page": "<kbd>Main Page</kbd> restauréieren.",
+ "apihelp-upload-param-watch": "D'Säit iwwerwaachen.",
+ "apihelp-upload-example-url": "Vun enger URL eroplueden.",
+ "apihelp-userrights-param-user": "Benotzernumm.",
+ "apihelp-userrights-param-userid": "Benotzer Id.",
+ "apihelp-userrights-param-reason": "Grond fir d'Ännerung.",
+ "apihelp-watch-example-watch": "D'Säit <kbd>Haaptsäit</kbd> iwwerwaachen.",
+ "api-help-param-deprecated": "Vereelst.",
+ "api-help-param-required": "Dëse Parameter ass obligatoresch.",
+ "api-help-examples": "{{PLURAL:$1|Beispill|Beispiler}}:"
+}
diff --git a/includes/api/i18n/ln.json b/includes/api/i18n/ln.json
new file mode 100644
index 00000000..cd117465
--- /dev/null
+++ b/includes/api/i18n/ln.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Moyogo"
+ ]
+ },
+ "apihelp-edit-example-edit": "Kobɔngisa lokásá lɔ̌kɔ́."
+}
diff --git a/includes/api/i18n/lv.json b/includes/api/i18n/lv.json
new file mode 100644
index 00000000..b24e5f63
--- /dev/null
+++ b/includes/api/i18n/lv.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Papuass"
+ ]
+ },
+ "apihelp-userrights-param-userid": "Lietotāja ID:"
+}
diff --git a/includes/api/i18n/lzh.json b/includes/api/i18n/lzh.json
new file mode 100644
index 00000000..970bea94
--- /dev/null
+++ b/includes/api/i18n/lzh.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "RalfX"
+ ]
+ },
+ "apihelp-feedcontributions-param-toponly": "僅示至新審之纂"
+}
diff --git a/includes/api/i18n/mg.json b/includes/api/i18n/mg.json
new file mode 100644
index 00000000..8e2a8b56
--- /dev/null
+++ b/includes/api/i18n/mg.json
@@ -0,0 +1,11 @@
+{
+ "@metadata": {
+ "authors": [
+ "Jagwar"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Torohevitra be kokoa]\n* [https://www.mediawiki.org/wiki/API:FAQ Fanontaniana miverina matetika]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lisitry ny mailaka manaraka]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Filazana API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Baogy & hataka]\n</div>\n<strong>Status:</strong> \nTokony mandeha avokoa ny fitaovana aseho eto amin'ity pehy ity, na dia izany aza mbola am-panamboarana ny API ary mety hiova na oviana na oviana. Araho amin'ny alalan'ny fisoratana ny mailakao ao amin'ny [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce lisitra fampielezana] ny fiovana.\n\n<strong>Hataka diso:</strong> \nRehefa alefa ao amin'i API ny hata, ho alefa miaraka amin'ny lakile \"MediaWiki-API-Error\" ny header HTTP ary samy homen-tsanda mitovy ny header ary ny kaodin-kadisoana. Ho an'ny torohay fanampiny dia jereo https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+ "apihelp-main-param-action": "Inona ny zavatra ho atao.",
+ "apihelp-main-param-format": "Format mivoaka",
+ "apihelp-createaccount-param-name": "Anaram-pikambana."
+}
diff --git a/includes/api/i18n/mk.json b/includes/api/i18n/mk.json
new file mode 100644
index 00000000..1efb45f3
--- /dev/null
+++ b/includes/api/i18n/mk.json
@@ -0,0 +1,398 @@
+{
+ "@metadata": {
+ "authors": [
+ "Bjankuloski06"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Документација]\n* [https://www.mediawiki.org/wiki/API:FAQ ЧПП]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Поштенски список]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Соопштенија за Извршникот]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Грешки и барања]\n</div>\n<strong>Статус:</strong> Сите ставки на страницава би требало да работат, но Извршникот сепак е во активна разработка, што значи дека може да се смени во секое време. Објавите за измени можете да ги дознавате ако се пријавите на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ поштенскиот список „the mediawiki-api-announce“].\n\n<strong>Погрешни барања:</strong> Кога Извршникот ќе добие погрешни барања, ќе се испрати HTTP-заглавие со клучот „MediaWiki-API-Error“ и потоа на вредностите на заглавието и шифрата на грешката што ќе се појават ќе им биде зададена истата вредност. ПОвеќе информации ќе најдете на https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+ "apihelp-main-param-action": "Кое дејство да се изврши.",
+ "apihelp-main-param-format": "Формат на изводот.",
+ "apihelp-main-param-maxlag": "Максималниот заостаток може да се користи кога МедијаВики е воспоставен на грозд умножен од базата. За да спречите дополнителни заостатоци од дејства, овој параметар му наложува на клиентот да почека додека заостатокот не се намали под укажаната вредност. Во случај на преголем заостаток, системт ја дава грешката со код „maxlag“ со порака од обликот „Го чекам $host: има заостаток од $lag секунди“.<br />Погл. https://www.mediawiki.org/wiki/Manual:Maxlag_parameter за повеќе информации.",
+ "apihelp-main-param-smaxage": "Задајте му олку секунди на заглавитето <code>s-maxage</code>. Грешките никогаш не се чуваат во меѓускладот.",
+ "apihelp-main-param-maxage": "Задајте му олку секунди на заглавитето <code>max-age</code>. Грешките никогаш не се чуваат во меѓускладот.",
+ "apihelp-main-param-assert": "Провери дали корисникот е најавен ако е зададено „user“ или дали го има корисничкото право на бот, ако е зададено „bot“.",
+ "apihelp-main-param-requestid": "Тука внесената вредност ќе биде вклучена во извештајот. Може да се користи за разликување на барањата.",
+ "apihelp-main-param-servedby": "Вклучи го домаќинското име што го услужило барањето во резултатите.",
+ "apihelp-main-param-curtimestamp": "Бклучи тековно време и време и датум во резултатот.",
+ "apihelp-main-param-origin": "Кога му пристапувате на Пирлогот користејќи повеќедоменско AJAX-барање (CORS), задајте му го на ова изворниот домен. Ова мора да се вклучи во секое подготвително барање и затоа мора да биде дел од URI на барањето (не главната содржина во POST). Ова мора точно да се совпаѓа со еден од изворниците на заглавието Origin:, така што мора да е зададен на нешто како http://en.wikipedia.org or https://meta.wikimedia.org. Ако овој параметар не се совпаѓа со заглавието Origin:, ќе се појави одговор 403. Ако се совпаѓа, а изворникот е на бел список (на допуштени), тогаш ќе се зададе ззаглавието Контрола на пристап-Изворник.",
+ "apihelp-main-param-uselang": "Јазик за преведување на пораките. Список на јазични кодови ќе најдете на [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]] со siprop=languages или укажете „user“ за да го користите тековно зададениот јазик корисникот, или пак укажете „content“ за да го користите јазикот на содржината на ова вики.",
+ "apihelp-block-description": "Блокирај корисник.",
+ "apihelp-block-param-user": "Корисничко име, IP-адреса или IP-опсег ако сакате да блокирате.",
+ "apihelp-block-param-expiry": "Време на истек. Може да биде релативно (на пр. „5 месеци“ или „2 недели“) или пак апсолутно (на пр. „2014-09-18T12:34:56Z“). Ако го зададете „бесконечно“, „неодредено“ или „никогаш“, блокот ќе трае засекогаш.",
+ "apihelp-block-param-reason": "Причина за блокирање.",
+ "apihelp-block-param-anononly": "Блокирај само анонимни корисници (т.е. оневозможи анонимно уредување од оваа IP-адреса).",
+ "apihelp-block-param-nocreate": "Оневозможи создавање кориснички сметки.",
+ "apihelp-block-param-autoblock": "Автоматски блокирај ја последно употребената IP-адреса и сите понатамошни IP-адреси од кои лицето ќе се обиде да се најави.",
+ "apihelp-block-param-noemail": "Оневозможи му на корисникот да испаќа е-пошта преку викито. (Го бара правото „блокирање е-пошта“).",
+ "apihelp-block-param-hidename": "Скриј го корисничкото име од дневникот на блокирања. (Го бара правото „скривање корисник“)",
+ "apihelp-block-param-allowusertalk": "Овозможи му на корисникот да си ја уредува сопствената страница за разговор (зависи од <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Ако корисникот е веќе блокиран, наметни врз постоечкиот блок.",
+ "apihelp-block-param-watchuser": "Набљудувај ја корисничката страница и страницата за разговор на овој корисник или IP-адреса",
+ "apihelp-block-example-ip-simple": "Блокирај ја IP-адресата 192.0.2.5 три дена со причината „Прва опомена“",
+ "apihelp-block-example-user-complex": "Блокирај го корисникот Вандал (Vandal) бесконечно со причината „Вандализам“ и оневозможи создавање на нови сметки и праќање е-пошта",
+ "apihelp-clearhasmsg-description": "Ја отстранува ознаката „<code>hasmsg</code>“ од тековниот корисник.",
+ "apihelp-clearhasmsg-example-1": "Отстрани ја ознаката „<code>hasmsg</code>“ од тековниот корисник",
+ "apihelp-compare-description": "Добивање на разлика помеѓу две страници.\n\nМора да се добие број на преработката, наслов на странивата или пак нејзина назнака. Важи и за „од“ и за „на“.",
+ "apihelp-compare-param-fromtitle": "Прв наслов за споредба.",
+ "apihelp-compare-param-fromid": "Прва назнака на страница за споредба.",
+ "apihelp-compare-param-fromrev": "Прва преработка за споредба.",
+ "apihelp-compare-param-totitle": "Втор наслов за споредба.",
+ "apihelp-compare-param-toid": "Втора назнака на страница за споредба.",
+ "apihelp-compare-param-torev": "Бтора преработка за споредба.",
+ "apihelp-compare-example-1": "Дај разлика помеѓу преработките 1 и 2",
+ "apihelp-createaccount-description": "Создај нова корисничка сметка.",
+ "apihelp-createaccount-param-name": "Корисничко име.",
+ "apihelp-createaccount-param-password": "Лозинка (се занемарува ако е зададено <var>$1mailpassword</var>).",
+ "apihelp-createaccount-param-domain": "Домен за надворешна заверка (незадолжително).",
+ "apihelp-createaccount-param-token": "Шифра за создавање сметка добиена во првото барање.",
+ "apihelp-createaccount-param-email": "Е-пошта на корисникот (незадолжително).",
+ "apihelp-createaccount-param-realname": "Вистинско име на корисникот (незадолжително).",
+ "apihelp-createaccount-param-mailpassword": "Ако му се зададе било каква вредност, тогаш на корисникот ќе му биде испратена случајна лозинка.",
+ "apihelp-createaccount-param-reason": "Незадолжителна прочина за создавање на сметката која ќе стои во дневниците.",
+ "apihelp-createaccount-param-language": "Јазичен код кој ќе биде стандарден за корисникот (незадолжително, по основно: јазикот на самото вики).",
+ "apihelp-createaccount-example-pass": "Создај го корисникот „testuser“ со лозинката „test123“",
+ "apihelp-createaccount-example-mail": "Создај го корисникот „testmailuser“ и испрати случајно-создадена лозинка по е-пошта",
+ "apihelp-delete-description": "Избриши страница.",
+ "apihelp-delete-param-title": "Наслов на страницата што сакате да ја избришете. Не може да се користи заедно со $1pageid.",
+ "apihelp-delete-param-pageid": "Назнака на страницата што сакате да ја избришете. Не може да се користи заедно со $1title.",
+ "apihelp-delete-param-reason": "Причина за бришење. Ако не се зададе, ќе се наведе автоматска причина.",
+ "apihelp-delete-param-watch": "Додај ја страницата во набљудуваните.",
+ "apihelp-delete-param-watchlist": "Безусловно додај или отстрани ја страницата од набљудуваните, користете ги нагодувањата или не ги менувајте набљудуваните.",
+ "apihelp-delete-param-unwatch": "Отстрани ја страницата од набљудуваните.",
+ "apihelp-delete-param-oldimage": "Името на страта слика за бришење според добиеното од [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+ "apihelp-delete-example-simple": "Избриши ја Главната страница",
+ "apihelp-delete-example-reason": "Избриши ја Главната страница со причината „Подготовка за преместување“",
+ "apihelp-disabled-description": "Модулот е деактивиран.",
+ "apihelp-edit-description": "Создај или уреди страници.",
+ "apihelp-edit-param-title": "Наслов на страницата што сакате да ја уредите. Не може да се користи заедно со $1pageid.",
+ "apihelp-edit-param-pageid": "Назнака на страницата што сакате да ја уредите. Не може да се користи заедно со $1title.",
+ "apihelp-edit-param-section": "Број на поднасловот. 0 за првиот, „new“ за нов.",
+ "apihelp-edit-param-sectiontitle": "Назив на новиот поднаслов",
+ "apihelp-edit-param-text": "Содржина на страницата.",
+ "apihelp-edit-param-summary": "Опис на уредувањето. Ова е и назив на поднасловот кога не се зададени $1section=new и $1sectiontitle.",
+ "apihelp-edit-param-minor": "Ситно уредување.",
+ "apihelp-edit-param-notminor": "Неситно уредување.",
+ "apihelp-edit-param-bot": "Означи го уредувањево како ботско.",
+ "apihelp-edit-param-basetimestamp": "Датум и време на преработката на базата, кои се користат за утврдување на спротиставености во уредувањето. Може да се добие преку [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "Датум и време кога сте го почнале уредувањето, кои се користат за утврдување на спротиставености во уредувањата. Соодветната вредност се добива користејќи [[Special:ApiHelp/main|curtimestamp]] кога ќе почнете со уредување (на пр. кога ќе се вчита содржината што ќе ја уредувате).",
+ "apihelp-edit-param-recreate": "Занемари ги грешките што се појавуваат во врска со статијата што е избришана во меѓувреме.",
+ "apihelp-edit-param-createonly": "Не ја уредувај страницата ако веќе постои.",
+ "apihelp-edit-param-nocreate": "Дај грешка ако страницата не постои.",
+ "apihelp-edit-param-watch": "Додај ја страницата во набљудуваните.",
+ "apihelp-edit-param-unwatch": "Отстрани ја страницата од набљудуваните.",
+ "apihelp-edit-param-watchlist": "Безусловно додај или отстрани ја страницата од набљудуваните, користете ги нагодувањата или не ги менувајте набљудуваните.",
+ "apihelp-edit-param-md5": "MD5-тарабата на параметарот $1text, или параметрите $1prependtext и $1appendtext поврзани. Ако е зададено, уредувањето нема да се изврши без тарабата да биде исправна.",
+ "apihelp-edit-param-prependtext": "Ставете го текстов на почетокот од страницата. Го заменува $1text.",
+ "apihelp-edit-param-appendtext": "Ставете го текстов на крајот од страницата. Го заменува $1text.\n\nКористете $1section=new наместо овој параметар за да приложите кон новиот поднаслов.",
+ "apihelp-edit-param-undo": "Отповикај ја преработкава. Ги заменува $1text, $1prependtext и $1appendtext.",
+ "apihelp-edit-param-undoafter": "Отповикај ги преработките од $1undo до оваа. Ако не е зададено, отповикај само една.",
+ "apihelp-edit-param-redirect": "Автоматски решавај пренасочувања.",
+ "apihelp-edit-param-contentformat": "Форматот за серијализација на содржината што се користи во вносниот текст.",
+ "apihelp-edit-param-contentmodel": "Содржински модел на новата содржина.",
+ "apihelp-edit-param-token": "Шифрата треба секогаш да се испраќа како последниот параметар, или барем по параметарот $1text.",
+ "apihelp-edit-example-edit": "Уреди страница",
+ "apihelp-edit-example-prepend": "Стави <kbd>_&#95;NOTOC_&#95;</kbd> пред страницата",
+ "apihelp-edit-example-undo": "Отповикај ги преработките од 13579 до 13585 со автоматски опис",
+ "apihelp-emailuser-description": "Испрати е-пошта на корисник.",
+ "apihelp-emailuser-param-target": "На кој корисник да му се испрати е-поштата.",
+ "apihelp-emailuser-param-subject": "Наслов.",
+ "apihelp-emailuser-param-text": "Содржина.",
+ "apihelp-emailuser-param-ccme": "Прати ми примерок и мене.",
+ "apihelp-emailuser-example-email": "Испрати е-пошта на корисникот „WikiSysop“ со текстот „Содржина“",
+ "apihelp-expandtemplates-description": "Ги проширува сите шаблони во викитекст.",
+ "apihelp-expandtemplates-param-title": "Наслов на страница.",
+ "apihelp-expandtemplates-param-text": "Викитекст за претворање.",
+ "apihelp-expandtemplates-param-revid": "Назнака на преработката, за <nowiki>{{REVISIONID}}</nowiki> и слични променливи.",
+ "apihelp-expandtemplates-param-prop": "Кои информации треба да ги добиете:\n;wikitext:The expanded wikitext.\n;categories: Категориите присутно во вносот кои не се претставени во викитекстуалниот извод.\n;volatile: Дали изводот е месно врзан и не треба да се преупотребува на други места во страницата.\n;ttl: Максималното време по кое треба да се поништи меѓускладираниот резултат.\n;parsetree: XML-дрвото на расчленување за изводот.\nИмајте на ум дека ако не изберете никаква вредност, резултатот ќе го содржи викитекстот, но изводот ќе биде во застарен формат.",
+ "apihelp-expandtemplates-param-includecomments": "Дали во изводот да се вклучени HTML-коментари.",
+ "apihelp-expandtemplates-param-generatexml": "Создај XML-дрво на расчленување (заменето со $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Прошири го викитекстот „<nowiki>{{Project:Sandbox}}</nowiki>“",
+ "apihelp-feedcontributions-description": "Дава канал со придонеси на корисник.",
+ "apihelp-feedcontributions-param-feedformat": "Формат на каналот.",
+ "apihelp-feedcontributions-param-user": "За кои корисници да се прикажуваат придонесите.",
+ "apihelp-feedcontributions-param-namespace": "По кој именски простор да се филтрираат придонесите:",
+ "apihelp-feedcontributions-param-year": "Од година (и порано):",
+ "apihelp-feedcontributions-param-month": "Од месец (и порано):",
+ "apihelp-feedcontributions-param-tagfilter": "Филтрирај придонеси што имаат ознаки.",
+ "apihelp-feedcontributions-param-deletedonly": "Прикажувај само избришани придонеси.",
+ "apihelp-feedcontributions-param-toponly": "Прикажувај само последни преработки.",
+ "apihelp-feedcontributions-param-newonly": "Прикажувај само новосоздадени страници",
+ "apihelp-feedcontributions-param-showsizediff": "Покажувај ја големинската разлика меѓу преработките.",
+ "apihelp-feedcontributions-example-simple": "Покажувај придонеси на [[Корисник:Пример]]",
+ "apihelp-feedrecentchanges-description": "Дава канал со скорешни промени.",
+ "apihelp-feedrecentchanges-param-feedformat": "Форматот на каналот.",
+ "apihelp-feedrecentchanges-param-namespace": "На кој именски простор да се ограничат резултатите.",
+ "apihelp-feedrecentchanges-param-invert": "Сите именски простори освен избраниот.",
+ "apihelp-feedrecentchanges-param-associated": "Вклучи придружни именски простори (разговор или главен).",
+ "apihelp-feedrecentchanges-param-days": "На кои денови да се ограничат резултатите.",
+ "apihelp-feedrecentchanges-param-limit": "Максималниот број на резултати за прикажување.",
+ "apihelp-feedrecentchanges-param-from": "Прикажи ги промените оттогаш.",
+ "apihelp-feedrecentchanges-param-hideminor": "Скриј ги ситните промени.",
+ "apihelp-feedrecentchanges-param-hidebots": "Скриј ги промените напарвени од ботови.",
+ "apihelp-feedrecentchanges-param-hideanons": "Скриј ги промените направени од анонимни корисници.",
+ "apihelp-feedrecentchanges-param-hideliu": "Скриј ги промените направени од регистрирани корисници.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Скриј ги испатролираните промени.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Скриј ги моите промени.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Филтрирање по ознака.",
+ "apihelp-feedrecentchanges-param-target": "Прикажи само промени на страници што водат од оваа.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Наместо тоа, прикажи ги промените на страниците поврзани со избраната страница.",
+ "apihelp-feedrecentchanges-example-simple": "Прикажи скорешни промени",
+ "apihelp-feedrecentchanges-example-30days": "Прикажувај скорешни промени 30 дена",
+ "apihelp-feedwatchlist-description": "Дава канал од набљудуваните.",
+ "apihelp-feedwatchlist-param-feedformat": "Форматот на каналот.",
+ "apihelp-feedwatchlist-param-hours": "Испиши страници изменети во рок од олку часови отсега.",
+ "apihelp-feedwatchlist-param-linktosections": "Давај ме право на изменетите делови, ако е можно.",
+ "apihelp-feedwatchlist-example-default": "Прикажи го каналот од набљудуваните.",
+ "apihelp-feedwatchlist-example-all6hrs": "Прикажи ги сите промени во набљудуваните во последните 6 часа",
+ "apihelp-filerevert-description": "Врати податотека на претходна верзија.",
+ "apihelp-filerevert-param-filename": "Име на целната податотека, без претставката „Податотека:“.",
+ "apihelp-filerevert-param-comment": "Коментар за подигањето.",
+ "apihelp-filerevert-param-archivename": "Архивски назив на преработката што ја повраќате.",
+ "apihelp-filerevert-example-revert": "Врати ја <kbd>Wiki.png</kbd> на верзијата од <kbd>2011-03-05T15:27:40Z</kbd>",
+ "apihelp-help-description": "Прикажувај помош за укажаните модули.",
+ "apihelp-help-param-modules": "Модули за приказ на помош за (вредности на параметрите action= и format=, или пак „main“). Може да се укажат подмодули со „+“.",
+ "apihelp-help-param-submodules": "Прикажувај и помош за подмодули на именуваниот модул.",
+ "apihelp-help-param-recursivesubmodules": "Прикажувај и помош за подмодули рекурзивно.",
+ "apihelp-help-param-helpformat": "Формат на изводот на помошта.",
+ "apihelp-help-param-wrap": "Обвиткај го изводот како станрадна одѕивна структура од прилотот.",
+ "apihelp-help-param-toc": "Вклучи табела со содржина во HTML-изводот.",
+ "apihelp-help-example-main": "Помош за главниот модул",
+ "apihelp-help-example-recursive": "Сета помош на една страница",
+ "apihelp-help-example-help": "Помош за самиот помошен модул",
+ "apihelp-help-example-query": "Помош за два подмодула за барања",
+ "apihelp-imagerotate-description": "Сврти една или повеќе слики.",
+ "apihelp-imagerotate-param-rotation": "За колку степени да се сврти надесно.",
+ "apihelp-imagerotate-example-simple": "Сврти ја [[:Податотека:Пример.png]] за 90 степени",
+ "apihelp-imagerotate-example-generator": "Сврти ги сите слики во [[:Категорија:Некоја]] за 180 степени",
+ "apihelp-import-description": "Увези страница од друго вики или XML-податотека.\n\nИмајте на ум дека POST на HTTP мора да се изведе како подигање на податотеката (т.е. користејќи повеќеделни податоци/податоци од образец) кога ја испраќате податотеката за параметарот „xml“.",
+ "apihelp-import-param-summary": "Увези опис.",
+ "apihelp-import-param-xml": "Подигната XML-податотека.",
+ "apihelp-import-param-interwikisource": "За меѓујазични увози: од кое вики да се увезе.",
+ "apihelp-import-param-interwikipage": "За меѓујазични увози: страница за увоз.",
+ "apihelp-import-param-fullhistory": "За меѓујазични увози:: увези ја целата историја, а не само тековната верзија.",
+ "apihelp-import-param-templates": "За меѓујазични увози: увези ги и сите вклучени шаблони.",
+ "apihelp-import-param-namespace": "За меѓујазични увози: увези во овој именски простор.",
+ "apihelp-import-param-rootpage": "Увези како потстраница на страницава.",
+ "apihelp-import-example-import": "Увези [[meta:Help:Parserfunctions]] во именскиот простор 100 со целата историја.",
+ "apihelp-login-description": "Најавете се и добијте колачиња за заверка.\n\nВо случај кога ќе се најавите успешно, потребните колачиња ќе се придодадат кон заглавијата на HTTP-одѕивот. Во случај да не успеете да се најавите, понатамошните обиди може да се ограничат за да се ограничат нападите со автоматизирано погодување на лозинката.",
+ "apihelp-login-param-name": "Корисничко име.",
+ "apihelp-login-param-password": "Лозинка.",
+ "apihelp-login-param-domain": "Домен (незадолжително).",
+ "apihelp-login-param-token": "Најавна шифра добиена со првото барање.",
+ "apihelp-login-example-gettoken": "Набави најавна шифра.",
+ "apihelp-login-example-login": "Најава",
+ "apihelp-logout-description": "Одјави се и исчисти ги податоците на седницата.",
+ "apihelp-logout-example-logout": "Одјави го тековниот корисник",
+ "apihelp-move-description": "Премести страница.",
+ "apihelp-move-param-from": "Наслов на страницата што сакате да ја преместите. Не може да се користи заедно со $1fromid.",
+ "apihelp-move-param-fromid": "Назнака на страницата што сакате да ја преместите. Не може да се користи заедно со $1from.",
+ "apihelp-move-param-to": "Како сакате да гласи новиот наслов на страницата.",
+ "apihelp-move-param-reason": "Причина за преместувањето.",
+ "apihelp-move-param-movetalk": "Премести ја и страницата за разговор, ако ја има.",
+ "apihelp-move-param-movesubpages": "Премести потстраници, ако има",
+ "apihelp-move-param-noredirect": "Не прави пренасочување.",
+ "apihelp-move-param-watch": "Додај ги страницата и пренасочувањето во набљудуваните.",
+ "apihelp-move-param-unwatch": "Отстрани ги страницата и пренасочувањето од набљудуваните.",
+ "apihelp-move-param-watchlist": "Безусловно додај или отстрани ја страницата од набљудуваните, користете ги нагодувањата или не ги менувајте набљудуваните.",
+ "apihelp-move-param-ignorewarnings": "Занемари предупредувања.",
+ "apihelp-move-example-move": "Премести го „Лош наслов“ на „Добар наслов“, неоставајќи пренасочување",
+ "apihelp-opensearch-description": "Пребарување на викито со протоколот OpenSearch.",
+ "apihelp-opensearch-param-search": "Низа за пребарување.",
+ "apihelp-opensearch-param-limit": "Максималниот број на резултати за прикажување.",
+ "apihelp-opensearch-param-namespace": "Именски простори за пребарување.",
+ "apihelp-opensearch-param-suggest": "Не прави ништо ако [https://www.mediawiki.org/wiki/Manual:$wgEnableOpenSearchSuggest $wgEnableOpenSearchSuggest] е неточно.",
+ "apihelp-opensearch-param-redirects": "Како да се работи со пренасочувања:\n;return: Дај го самото пренасочување.\n;resolve: Дај ја целната страница. Може да даде помалку од $1limit резултати.\nОд историски причини, по основно е „return“ за $1format=json и „resolve“ за други формати.",
+ "apihelp-opensearch-param-format": "Формат на изводот.",
+ "apihelp-opensearch-example-te": "Најди страници што почнуваат со „Те“",
+ "apihelp-options-description": "Смени ги нагодувањата на тековниот корисник.\n\nМожат да се зададат само можностите заведени во јадрото или во едно од воспоставените додатоци, или пак можности со клуч кој ја има претставката „userjs-“ (предвиден за употреба од кориснички скрипти).",
+ "apihelp-options-param-reset": "Ги враќа поставките по основно.",
+ "apihelp-options-param-resetkinds": "Писок на типови можности за повраток кога е зададена можноста „$1reset“.",
+ "apihelp-options-param-change": "Список на промени во форматот name=value (на пр. skin=vector). Вредностите не треба да содржат исправени црти. Ако не зададете вредност (дури ни знак за равенство), на пр., можност|другаможност|..., ќе биде зададена вредноста на можноста по основно.",
+ "apihelp-options-param-optionname": "Назив на можноста што треба да ѝ се зададе на вредноста дадена од „$1optionvalue“.",
+ "apihelp-options-param-optionvalue": "Вредноста на можноста укажана од „$1optionnam“. Може да содржи исправени црти.",
+ "apihelp-options-example-reset": "Врати ги сите поставки по основно",
+ "apihelp-options-example-change": "Смени ги поставките „skinЗ“ и „hideminor“",
+ "apihelp-options-example-complex": "Врати ги сите нагодувања по основно, а потоа задај ги „skin“ и „nickname“",
+ "apihelp-paraminfo-description": "Набави информации за извршнички (API) модули.",
+ "apihelp-paraminfo-param-modules": "Список на називи на модули (вредности на параметрите action= и format=, или пак „main“). Може да се укажат подмодули со „+“.",
+ "apihelp-paraminfo-param-helpformat": "Формат на помошните низи.",
+ "apihelp-paraminfo-param-querymodules": "Список на називи на модули за барања (вредност на параметарот prop=, meta= или list=). Користете го „$1modules=query+foo“ наместо „$1querymodules=foo“.",
+ "apihelp-paraminfo-param-mainmodule": "Добави информации и за главниот (врховен) модул. Користете го „$1modules=main“ наместо тоа.",
+ "apihelp-paraminfo-param-pagesetmodule": "Дај ги сите информации и за модулот на збирот страници (укажувајќи titles= и сродни).",
+ "apihelp-paraminfo-param-formatmodules": "Список на називи на форматни модули (вредностза параметарот format=). Наместо тоа, користете го „$1modules“.",
+ "apihelp-parse-param-summary": "Опис за расчленување.",
+ "apihelp-parse-param-preview": "Расчлени во прегледен режим.",
+ "apihelp-parse-param-sectionpreview": "Расчлени во прегледен режим на поднасловот (го овозможува и прегледниот режим).",
+ "apihelp-parse-param-disabletoc": "Изземи го преглед на содржината во изводеот.",
+ "apihelp-parse-param-contentformat": "Формат на серијализацијата на содржината во вносниот текст. Важи само кога се користи со $1text.",
+ "apihelp-parse-example-page": "Расчлени страница.",
+ "apihelp-parse-example-text": "Расчлени викитекст.",
+ "apihelp-parse-example-texttitle": "Расчлени страница, укажувајќи го насловот на страницата.",
+ "apihelp-parse-example-summary": "Расчлени опис.",
+ "apihelp-patrol-description": "Испатролирај страница или ревизија.",
+ "apihelp-patrol-param-rcid": "Назнака на спорешните промени за патролирање.",
+ "apihelp-patrol-param-revid": "Назнака на преработката за патролирање.",
+ "apihelp-patrol-example-rcid": "Испатролирај скорешна промена",
+ "apihelp-patrol-example-revid": "Патролирај праработка",
+ "apihelp-protect-description": "Смени го степенот на заштита на страница.",
+ "apihelp-protect-param-title": "Наслов на страница што се (од)заштитува. Не може да се користи заедно со $1pageid.",
+ "apihelp-protect-param-pageid": "Назнака на страница што се (од)заштитува. Не може да се користи заедно со $1title.",
+ "apihelp-protect-param-reason": "Причиина за (од)заштитување",
+ "apihelp-protect-example-protect": "Заштити страница",
+ "apihelp-purge-param-forcelinkupdate": "Поднови ги табелите со врски.",
+ "apihelp-purge-example-simple": "Превчитај ги „Главна страница“ и „Извршник“",
+ "apihelp-query-param-list": "Кои списоци да се набават.",
+ "apihelp-query-param-meta": "Кои метаподатоци да се набават.",
+ "apihelp-query+allcategories-description": "Наброј ги сите категории.",
+ "apihelp-query+allcategories-param-from": "Од која категорија да почне набројувањето.",
+ "apihelp-query+allcategories-param-to": "На која категорија да запре набројувањето.",
+ "apihelp-query+allcategories-param-dir": "Насока на подредувањето.",
+ "apihelp-query+alldeletedrevisions-param-from": "Почни го исписот од овој наслов.",
+ "apihelp-query+alldeletedrevisions-param-to": "Запри го исписот на овој наслов.",
+ "apihelp-query+alldeletedrevisions-example-user": "Список на последните 50 избришани придонеси на Корисник:Пример",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Список на последните 50 избришани преработки во главниот именски простор",
+ "apihelp-query+allimages-example-B": "Прикажи список на податотеки што почнуваат со буквата „Б“",
+ "apihelp-query+allimages-example-recent": "Прикажи список на неодамна подигнати податотеки сличен на [[Special:NewFiles]]",
+ "apihelp-query+allimages-example-generator": "Прикажи информации за околу 4 податотеки што почнуваат со буквата „Т“",
+ "apihelp-query+alllinks-description": "Наброј ги сите врски што водат кон даден именски простор.",
+ "apihelp-query+alllinks-param-from": "Наслов на врската од која ќе почне набројувањето.",
+ "apihelp-query+alllinks-param-to": "Наслов на врската на која ќе запре набројувањето.",
+ "apihelp-query+alllinks-param-prefix": "Пребарај ги сите сврзани наслови што почнуваат со оваа вредност.",
+ "apihelp-query+alllinks-param-unique": "Прикажувај само различни поврзани наслови. Не може да се користи со $1prop=ids.\nКога се користи како создавач, дава целни страници наместо изворни.",
+ "apihelp-query+alllinks-param-namespace": "Именскиот простор што се набројува.",
+ "apihelp-query+alllinks-param-limit": "Колку вкупно ставки да се дадат.",
+ "apihelp-query+alllinks-param-dir": "Насока на исписот.",
+ "apihelp-query+alllinks-example-B": "Списока на наслови со врски, вклучувајќи ги отсутните, со назнаки на нивните страници, почнувајќи од Б",
+ "apihelp-query+alllinks-example-unique": "Испиши единствени наслови со врски",
+ "apihelp-query+alllinks-example-unique-generator": "Ги дава сите наслови со врски, означувајќи ги отсутните",
+ "apihelp-query+alllinks-example-generator": "Дава страници што ги содржат врските",
+ "apihelp-query+allmessages-description": "Дава пораки од ова мрежно место.",
+ "apihelp-query+allmessages-param-prop": "Кои својства да се дадат.",
+ "apihelp-query+allmessages-param-filter": "Дај само пораки со називи што ја содржат оваа низа.",
+ "apihelp-query+allmessages-param-customised": "Дај само пораки во оваа состојба на прилагоденост.",
+ "apihelp-query+allmessages-param-lang": "Дај само пораки на овој јазик.",
+ "apihelp-query+allmessages-param-from": "Дај ги пораките што почнуваат од оваа порака.",
+ "apihelp-query+allmessages-param-to": "Дај пораки што завршуваат со оваа порака.",
+ "apihelp-query+allmessages-param-title": "Назив на страницата што ќе се користи во контекст кога се расчленува порака (за можноста $1enableparser).",
+ "apihelp-query+allmessages-param-prefix": "Дај пораки со оваа претставка.",
+ "apihelp-query+allmessages-example-ipb": "Прикажи ги пораките што започнуваат со „ipb-“",
+ "apihelp-query+allmessages-example-de": "Прикажи ги пораките „август“ и „главна страница“ на германски",
+ "apihelp-query+allpages-description": "Наброј ги сите страници последователно во даден именски простор.",
+ "apihelp-query+allpages-param-from": "Наслов на страницата од која ќе почне набројувањето.",
+ "apihelp-query+allpages-param-to": "Наслов на страницата на која ќе запре набројувањето.",
+ "apihelp-query+allpages-param-prefix": "Пребарај ги сите наслови на страници што почнуваат со оваа вредност.",
+ "apihelp-query+allpages-param-namespace": "Именскиот простор што се набројува.",
+ "apihelp-query+allpages-param-filterredir": "Кои страници да се испишат.",
+ "apihelp-query+allpages-param-minsize": "Ограничи на страници со барем олку бајти.",
+ "apihelp-query+allpages-param-maxsize": "Ограничи на страници со највеќе олку бајти.",
+ "apihelp-query+allpages-param-prtype": "Ограничи на само заштитени страници.",
+ "apihelp-query+backlinks-example-simple": "Прикажи врски до [[Главна страница|Главната страница]]",
+ "apihelp-query+backlinks-example-generator": "Дава информации за страниците што водат до [[Главна страница|Главната страница]]",
+ "apihelp-query+blocks-description": "Список на сите блокирани корисници и IP-адреси",
+ "apihelp-query+blocks-param-start": "Од кој датум и време да почне набројувањето.",
+ "apihelp-query+blocks-param-end": "На кој датум и време да запре набројувањето.",
+ "apihelp-query+blocks-param-ids": "Список на назнаки на блоковите за испис (незадолжително)",
+ "apihelp-query+blocks-param-users": "Список на корисници што ќе се пребаруваат (незадолжително)",
+ "apihelp-query+imageinfo-param-urlheight": "Слично на $1urlwidth.",
+ "apihelp-query+revisions-example-last5": "Дај ги последните 5 преработки на „Главна страница“",
+ "apihelp-query+revisions-example-first5": "Дај ги првите 5 преработки на „Главна страница“",
+ "apihelp-query+revisions-example-first5-after": "Дај ги првите 5 преработки на „Главна страница“ направени по 2006-05-01 (1 мај 2006 г.)",
+ "apihelp-query+revisions-example-first5-not-localhost": "Дај ги првите 5 преработки на „Главна страница“ кои не се направени од анонимниот корисник „127.0.0.1“",
+ "apihelp-query+revisions-example-first5-user": "Дај ги првите 5 преработки на „Главна страница“ кои се направени од корисникот „зададен од МедијаВики“ (MediaWiki default)",
+ "apihelp-query+search-example-simple": "Побарај „meaning“",
+ "apihelp-query+search-example-text": "Побарај го „meaning“ по текстовите",
+ "apihelp-query+search-example-generator": "Дај информации за страниците што излегуваат во резултатите од пребарувањето на „meaning“",
+ "apihelp-query+siteinfo-description": "Дај општи информации за мрежното место.",
+ "apihelp-upload-param-filename": "Целно име на податотеката.",
+ "apihelp-upload-param-comment": "Коментар при подигање. Се користи и како првичен текст на страницата за нови податотеки ако не е укажано „$1text“.",
+ "apihelp-upload-param-text": "Првичен текст на страницата за нови податотеки.",
+ "apihelp-upload-param-watch": "Набљудувај ја страницата.",
+ "apihelp-upload-param-watchlist": "Безусловно додај или отстрани ја страницата од набљудуваните, користете ги нагодувањата или не ги менувајте набљудуваните.",
+ "apihelp-upload-param-ignorewarnings": "Занемари предупредувања.",
+ "apihelp-upload-param-file": "Содржина на податотеката.",
+ "apihelp-upload-param-url": "Од која URL-адреса да се преземе податотеката.",
+ "apihelp-upload-param-filekey": "Клуч на претходното подигање кое е привремено складирано.",
+ "apihelp-upload-param-sessionkey": "Исто што и $1filekey. Се одржува за назадна складност.",
+ "apihelp-upload-param-stash": "Ако е зададено, опслужувачот ќе ја стави податотеката на привремено чување наместо да го додаде во складиштето.",
+ "apihelp-upload-param-filesize": "Големина на целото подигање.",
+ "apihelp-upload-param-offset": "Зафатнина на делот во бајти.",
+ "apihelp-upload-param-chunk": "Содржина на делот.",
+ "apihelp-upload-param-async": "Направи ги работите со потенцијално големи податотеки неусогласени, кога е можно.",
+ "apihelp-upload-param-asyncdownload": "Направи го добивањето на URL-адреса неусогласено.",
+ "apihelp-upload-param-leavemessage": "Ако се користи неусогласено преземање, остави порака на страницата за разговор на корисникот ако е готово.",
+ "apihelp-upload-param-statuskey": "Дај ја состојбата на подигнатост за овој податотечен клуч (подигање по URL-адреса).",
+ "apihelp-upload-param-checkstatus": "Дај ја состојбата на подигнатост само за дадениот податотечен клуч.",
+ "apihelp-upload-example-url": "Подигни од URL-адреса",
+ "apihelp-userrights-param-userid": "Корисничка назнака.",
+ "apihelp-userrights-param-add": "Стави го корисникот во следниве групи.",
+ "apihelp-userrights-param-remove": "Отстрани го корисникот од следниве групи.",
+ "apihelp-userrights-param-reason": "Причина за промената.",
+ "apihelp-watch-example-watch": "Набљудувај ја страницата „Главна страница“",
+ "apihelp-watch-example-unwatch": "Отстрани ја страницата „Главна страница“ од набљудуваните",
+ "apihelp-watch-example-generator": "Набљудувај ги првите неколку страници во главниот именски простор",
+ "apihelp-format-example-generic": "Форматирај го резултатот од барањето во $1-формат",
+ "apihelp-dbg-description": "Давај го изводот во PHP-форматот var_export().",
+ "apihelp-dbgfm-description": "Давај го изводот во PHP-форматот var_export() (подобрен испис во HTML).",
+ "apihelp-dump-description": "Давај го изводот во PHP-форматот var_dump().",
+ "apihelp-dumpfm-description": "Давај го изводот во PHP-форматот var_dump() (подобрен испис во HTML).",
+ "apihelp-json-description": "Давај го изводот во JSON-формат.",
+ "apihelp-json-param-callback": "Ако е укажано, го обвива изводот во даден повик на функција. За безбедност, ќе се ограничат сите податоци што се однесуваат на корисниците.",
+ "apihelp-json-param-utf8": "Ако е укажано, ја ги шифрира највеќето (но не сите) не-ASCII знаци како UTF-8 наместо да ги заменува со хексадецимални изводни низи.",
+ "apihelp-jsonfm-description": "Давај го изводот во JSON-формат (подобрен испис во HTML).",
+ "apihelp-none-description": "Де давај извод.",
+ "apihelp-php-description": "Давај го изводот во серијализиран PHP-формат.",
+ "apihelp-phpfm-description": "Давај го изводот во серијализиран PHP-формат (подобрен испис во HTML).",
+ "apihelp-rawfm-description": "Давај го изводот со елементи за отстранување грешки во JSON-формат (подобрен испис во HTML).",
+ "apihelp-txt-description": "Давај го изводот во PHP-форматот print_r().",
+ "apihelp-txtfm-description": "Давај го изводот во PHP-форматот print_r() (подобрен испис во HTML).",
+ "apihelp-wddx-description": "Давај го изводот во WDDX-формат.",
+ "apihelp-wddxfm-description": "Давај го изводот во WDDX-формат (подобрен испис во HTML).",
+ "apihelp-xml-description": "Давај го изводот во XML-формат.",
+ "apihelp-xml-param-xslt": "Ако е укажано, додава &lt;xslt&gt; како стилска страница. Ова треба да е викистраница во именскиот простор МедијаВики (MediaWiki) чиј наслов завршува со „.xsl“.",
+ "apihelp-xml-param-includexmlnamespace": "Ако е укажано, додава именски простор XML.",
+ "apihelp-xmlfm-description": "Давај го изводот во XML-формат (подобрен испис во HTML).",
+ "apihelp-yaml-description": "Давај го изводот во YAML-формат.",
+ "apihelp-yamlfm-description": "Давај го изводот во YAML-формат (подобрен испис во HTML).",
+ "api-format-title": "Резултат од Извршникот на МедијаВики",
+ "api-format-prettyprint-header": "Ја гледате HTML-претставата на форматот $1. HTML е добар за отстранување на грешки, но не е погоден за употреба во извршник.\n\nУкажете го параметарот за формат за да го смените изводниот формат. За да ги видите претставите на форматот $1 вон HTML, задајте format=$2.\n\nПовеќе информации ќе најдете на [https://www.mediawiki.org/wiki/API целосната документација], или пак [[Special:ApiHelp/main|помош со извршникот]].",
+ "api-orm-param-props": "Полиња за пребарување.",
+ "api-orm-param-limit": "Макс. број на редови во изводот.",
+ "api-pageset-param-titles": "Список на наслови на кои ќе се работи",
+ "api-pageset-param-pageids": "Список на назнаки за страници на кои ќе се работи",
+ "api-pageset-param-revids": "Список на назнаки на преработки на кои ќе се работи",
+ "api-pageset-param-generator": "Дај го списокот на страници на кои ќе се работи исполнувајќи го укажаниот модул за барање.\n\n'''НАПОМЕНА:''' називите на создавачките параметри мора да ја имаат претставката „g“. Погледајте ги примерите.",
+ "api-help-title": "Помош со Извршникот на МедијаВики",
+ "api-help-lead": "Ова е самосоздадена документациска страница за извршникот на МедијаВики.\n\nДокументација и примери: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Главен модул",
+ "api-help-flag-deprecated": "Овој модул е застарен.",
+ "api-help-flag-internal": "<strong>Овој модул е внатрешен или нестабилен.</strong> Работењето може да му се промени без предупредување.",
+ "api-help-flag-readrights": "За овој модул се потребни права на читање.",
+ "api-help-flag-writerights": "За овој модул се потребни права на пишување.",
+ "api-help-flag-mustbeposted": "Овој модул прифаќа само POST-барања.",
+ "api-help-flag-generator": "Овој модул може да се користи како создавач.",
+ "api-help-parameters": "{{PLURAL:$1|Параметар|Параметри}}:",
+ "api-help-param-deprecated": "Застарен.",
+ "api-help-param-required": "Овој параметар е задолжителен.",
+ "api-help-param-list": "{{PLURAL:$1|1=Една вредност|2=Вредности (одделени со „{{!}}“)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Мора да биде празно|Може да биде празно или $2}}",
+ "api-help-param-limit": "Не се допушта повеќе од $1.",
+ "api-help-param-limit2": "Не се допушта повеќе од $1 ($2 за ботови).",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=Вредноста не може да изнесува|2=Вредностите не може да изнесуваат}} помалку од $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=Вредноста не може да изнесува|2=Вредностите е може да изнесуваат}} повеќе од $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=Вредноста мора да изнесува|2=Вредностите мораат да изнесуваат}} помеѓу $2 и $3.",
+ "api-help-param-upload": "Мора да биде објавено како податотечно подигање користејќи податоци кои се повеќеделни или од образец.",
+ "api-help-param-multi-separate": "Одделувајте ги вредностите со „|“.",
+ "api-help-param-multi-max": "Максималниот број на вредности изнесува {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} за ботови).",
+ "api-help-param-default": "По основно: $1",
+ "api-help-param-default-empty": "По основно: <span class=\"apihelp-empty\">(празно)</span>",
+ "api-help-param-token": "Шифра „$1“ добиена од [[Special:ApiHelp/query+tokens|action=query&meta=tokens]]",
+ "api-help-param-token-webui": "За складност, се прифаќа и шифрата што се користи за обичниот кориснички посредник.",
+ "api-help-param-disabled-in-miser-mode": "Исклучено поради [https://www.mediawiki.org/wiki/Manual:$wgMiserMode скржавиот режим].",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(нема опис)</span>",
+ "api-help-examples": "{{PLURAL:$1|Пример|Примери}}:",
+ "api-help-permissions": "{{PLURAL:$1|Дозвола|Дозволи}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Доделена на}: $2",
+ "api-help-right-apihighlimits": "Уоптреба на повисоки ограничувања за приложни барања (бавни барања: $1; брзи барања: $2). Ограничувањата за бавни барања важат и за повеќевредносни параметри.",
+ "api-credits-header": "Признанија",
+ "api-credits": "Разработувачи на Извршникот:\n* Роан Катау (главен резработувач од септември 2007 до 2009 г.)\n* Виктор Василев\n* Брајан Тонг Мињ\n* Сем Рид\n* Јуриј Астрахан (создавач, главен разработувач од септември 2006 до септември 2007 г.)\n* Brad Jorsch (главен разработувач од 2013 г. до денес)\n\nВашите коментари, предлози и прашања испраќајте ги на mediawiki-api@lists.wikimedia.org\nа грешките пријавувајте ги на https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/ms.json b/includes/api/i18n/ms.json
new file mode 100644
index 00000000..041cf2c0
--- /dev/null
+++ b/includes/api/i18n/ms.json
@@ -0,0 +1,61 @@
+{
+ "@metadata": {
+ "authors": [
+ "Anakmalaysia"
+ ]
+ },
+ "apihelp-main-param-action": "Tindakan mana untuk dilakukan.",
+ "apihelp-main-param-format": "Format output.",
+ "apihelp-main-param-uselang": "Bahasa yang hendak digunakan untuk penterjemahan mesej. Senarai kod boleh diperoleh dari [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo&siprop=languages]], ataupun menyatakan \"user\" untuk menggunakan bahasa kegemaran pengguna semasa.",
+ "apihelp-expandtemplates-example-simple": "Perluaskan \"<nowiki>{{Project:Sandbox}}</nowiki>\" wikiteks",
+ "apihelp-help-param-helpformat": "Format output bantuan.",
+ "apihelp-help-example-main": "Bantuan untuk modul utama",
+ "apihelp-help-example-recursive": "Segala bantuan dalam satu halaman",
+ "apihelp-help-example-help": "Bantuan untuk modul bantuan",
+ "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "Menambahkan jenis MIME thumbnail imej (memerlukan url dan param $1urlwidth).",
+ "apihelp-query+prefixsearch-param-offset": "Bilangan hasil untuk dilangkau.",
+ "apihelp-query+usercontribs-param-show": "Hanya paparkan item-item yang mematuhi kriteria ini, cth. suntingan selain yang kecil sahaja: $2show=!minor.\n\nJika ditetapkannya $2show=patrolled atau $2show=!patrolled, maka semakan-semakan yang lebih lama daripada [https://www.mediawiki.org/wiki/Manual:$wgRCMaxAge $wgRCMaxAge] ($1 saat) tidak akan dipaparkan.",
+ "apihelp-userrights-param-userid": "ID pengguna.",
+ "apihelp-dbgfm-description": "Data output dalam format var_export() PHP (''pretty-print'' dalam HTML).",
+ "apihelp-dump-description": "Output data dalam format var_dump() PHP.",
+ "apihelp-dumpfm-description": "Data output dalam format var_dump() PHP (''pretty-print'' dalam HTML).",
+ "apihelp-json-description": "Data output dalam format JSON.",
+ "apihelp-json-param-utf8": "Jika dinyatakan, mengekodkan kenanyakan (tetapi bukan semua) aksara bukan ASCII sebagai UTF-8 daripada menggantikannya dengan jujukan lepasan perenambelasan.",
+ "apihelp-jsonfm-description": "Output data dalam format JSON (''pretty-print'' dalam HTML).",
+ "apihelp-php-description": "Data output dalam format PHP bersiri.",
+ "apihelp-txt-description": "Data output dalam format print_r() PHP.",
+ "apihelp-txtfm-description": "Data output dalam format print_r() PHP (''pretty-print'' dalam HTML).",
+ "apihelp-wddx-description": "Data output dalam format WDDX.",
+ "apihelp-wddxfm-description": "Output data dalam format WDDX (''pretty-print'' dalam HTML).",
+ "apihelp-xml-description": "Data output dalam format XML.",
+ "apihelp-xmlfm-description": "Data output dalam format XML (''pretty-print'' dalam HTML).",
+ "apihelp-yaml-description": "Data output dalam format YAML.",
+ "apihelp-yamlfm-description": "Output data dalam format YAML (''pretty-print'' dalam HTML).",
+ "api-format-title": "Hasil API MediaWiki",
+ "api-format-prettyprint-header": "Anda sedang menyaksikan representasi format $1 dalam bentuk HTML. HTML bagus untuk menyah pepijat, tetapi tidak sesuai untuk kegunaan aplikasi.\n\nNyatakan parameter format untuk mengubah format outputnya. Untuk melihat representasi format $1 yang bukan HTML, tetapkan format=$2.\n\nSila rujuk [https://www.mediawiki.org/wiki/API dokumentasi lengkapnya] ataupun [[Special:ApiHelp/main|bantuan API]] untuk keterangan lanjut.",
+ "api-help-title": "Bantuan API MediaWiki",
+ "api-help-lead": "Ini merupakan laman dokumentasi MediaWiki API yang dihasilkan secara automatik.\n\nDokumentasi dan contoh-contoh: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Modul utama",
+ "api-help-flag-deprecated": "Modul ini sudah lapuk.",
+ "api-help-flag-internal": "<strong>Modul ini dalaman atau tidak stabil.</strong> Operasinya boleh berubah tanpa amaran.",
+ "api-help-flag-readrights": "Modul ini memerlukan hak membaca.",
+ "api-help-flag-writerights": "Modul ini memerlukan hak menulis.",
+ "api-help-flag-mustbeposted": "Modul ini menerima permohonan POST sahaja.",
+ "api-help-flag-generator": "Modul ini boleh digunakan sebagai penjana.",
+ "api-help-parameters": "{{PLURAL:$1|Parameter}}:",
+ "api-help-param-deprecated": "Lapuk.",
+ "api-help-param-required": "Parameter ini diwajibkan.",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Mestilah kosong|Bolehlah kosong atau $2}}",
+ "api-help-param-limit2": "Dibenarkannya tidak lebih daripada $1 ($2 untuk bot).",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=Nilainya|2=Nilai-nilainya}} mesti tidak melebihi $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=Nilainya|2=Nilai-nilainya}} mestilah antara $2 hingga $3.",
+ "api-help-param-multi-separate": "Asingkan nilai-nilai dengan \"|\".",
+ "api-help-param-multi-max": "Bilangan nilai maksimum adalah {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} untuk bot).",
+ "api-help-param-default": "Asal: $1",
+ "api-help-param-default-empty": "Asal: <span class=\"apihelp-empty\">(kosong)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(tiada keterangan)</span>",
+ "api-help-examples": "{{PLURAL:$1|Contoh|Contoh-contoh}}:",
+ "api-help-permissions": "{{PLURAL:$1|Keizinan}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Diberikan kepada}}: $2",
+ "api-credits-header": "Kredit"
+}
diff --git a/includes/api/i18n/nap.json b/includes/api/i18n/nap.json
new file mode 100644
index 00000000..a285b04a
--- /dev/null
+++ b/includes/api/i18n/nap.json
@@ -0,0 +1,10 @@
+{
+ "@metadata": {
+ "authors": [
+ "Chelin"
+ ]
+ },
+ "apihelp-block-description": "Blocca n'utente.",
+ "apihelp-createaccount-param-name": "Nomme utente.",
+ "apihelp-delete-description": "Scancella 'na paggena."
+}
diff --git a/includes/api/i18n/nb.json b/includes/api/i18n/nb.json
new file mode 100644
index 00000000..6dcba40a
--- /dev/null
+++ b/includes/api/i18n/nb.json
@@ -0,0 +1,24 @@
+{
+ "@metadata": {
+ "authors": [
+ "Jeblad"
+ ]
+ },
+ "apihelp-main-param-action": "Hvilken handling skal utføres",
+ "apihelp-main-param-format": "Resultatets format.",
+ "apihelp-main-param-servedby": "Inkluder navnet på tjeneren som utførte forespørselen i resultatene.",
+ "apihelp-main-param-curtimestamp": "Inkluder det nåværende tidsmerket i resultatet.",
+ "apihelp-dbg-description": "Resultatdata i PHP's var_export() format.",
+ "apihelp-dbgfm-description": "Resultatdata i PHP's var_export() format (pen utskrift i HTML).",
+ "apihelp-dump-description": "Resultatdata i PHP's var_export() format.",
+ "apihelp-dumpfm-description": "Resultatdata i PHP's var_export() format (pen utskrift i HTML).",
+ "apihelp-json-description": "Resultatdata i JSON-format.",
+ "apihelp-none-description": "Ingen resultat.",
+ "api-help-flag-readrights": "Denne modulen krever lesetilgang.",
+ "api-help-flag-writerights": "Denne modulen krever skrivetilgang.",
+ "api-help-flag-mustbeposted": "Denne modulen aksepterer bare POST forespørsler.",
+ "api-help-flag-generator": "Denne modulen kan brukes som en generator.",
+ "api-help-parameters": "{{PLURAL:$1|Parameter|Parametre}}:",
+ "api-help-param-deprecated": "Utgått.",
+ "api-help-param-required": "Denne parameteren er påkrevd."
+}
diff --git a/includes/api/i18n/nds.json b/includes/api/i18n/nds.json
new file mode 100644
index 00000000..3f7cb12e
--- /dev/null
+++ b/includes/api/i18n/nds.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Servien"
+ ]
+ },
+ "apihelp-login-param-password": "Passwoort."
+}
diff --git a/includes/api/i18n/nl.json b/includes/api/i18n/nl.json
new file mode 100644
index 00000000..72816b99
--- /dev/null
+++ b/includes/api/i18n/nl.json
@@ -0,0 +1,61 @@
+{
+ "@metadata": {
+ "authors": [
+ "Siebrand",
+ "Sjoerddebruin",
+ "Robin0van0der0vliet",
+ "Mar(c)",
+ "Valhallasw",
+ "Sikjes",
+ "Macofe",
+ "SPQRobin"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentatie]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-maillijst]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aankondigingen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & verzoeken]\n</div>\n<strong>Status:</strong> Alle functies die op deze pagina worden weergegeven horen te werken. Aan de API wordt actief gewerkt, en deze kan gewijzigd worden. Abonneer u op de [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-maillijst mediawiki-api-announce] voor meldingen over aanpassingen.\n\n<strong>Foutieve verzoeken:</strong> als de API foutieve verzoeken ontvangt, wordt er geantwoord met een HTTP-header met de sleutel \"MediaWiki-API-Error\" en daarna worden de waarde van de header en de foutcode op dezelfde waarde ingesteld. Zie [[mw:API:Errors_and_warnings|API: Errors and warnings]] voor meer informatie.",
+ "apihelp-main-param-action": "Welke handeling uit te voeren.",
+ "apihelp-main-param-format": "De opmaak van de uitvoer.",
+ "apihelp-main-param-maxlag": "De maximale vertraging kan gebruikt worden als MediaWiki is geïnstalleerd op een databasecluster die gebruik maakt van replicatie. Om te voorkomen dat handelingen nog meer databasereplicatievertraging veroorzaken, kan deze parameter er voor zorgen dat de client wacht totdat de replicatievertraging lager is dan de aangegeven waarde. In het geval van buitensporige vertraging, wordt de foutcode <samp>maxlag</samp> teruggegeven met een bericht als <samp>Waiting for $host: $lag seconds lagged</samp>.<br />Zie [[mw:Manual:Maxlag_parameter|Handboek: Maxlag parameter]] voor mee informatie.",
+ "apihelp-main-param-smaxage": "Stelt de header \"<code>s-maxage</code>\" in op het aangegeven aantal seconden. Foutmeldingen komen nooit in de cache.",
+ "apihelp-main-param-maxage": "Stelt de header \"<code>max-age</code>\" in op het aangegeven aantal seconden. Foutmeldingen komen nooit in de cache.",
+ "apihelp-main-param-assert": "Controleer of de gebruiker is aangemeld als <kbd>user</kbd> is meegegeven, en of de gebruiker het robotgebruikersrecht heeft als <kbd>bot</kbd> is meegegeven.",
+ "apihelp-main-param-requestid": "Elke waarde die hier gegeven wordt, wordt aan het antwoord toegevoegd. Dit kan gebruikt worden om verzoeken te onderscheiden.",
+ "apihelp-main-param-servedby": "Voeg de hostnaam van de server die de aanvraag heeft afgehandeld toe aan het antwoord.",
+ "apihelp-main-param-curtimestamp": "Huidige tijd aan het antwoord toevoegen.",
+ "apihelp-block-description": "Gebruiker blokkeren.",
+ "apihelp-block-param-reason": "Reden voor blokkade.",
+ "apihelp-block-param-autoblock": "Blokkeer automatisch het laatst gebruikte IP-adres en ieder volgend IP-adres van waaruit ze proberen in te loggen.",
+ "apihelp-block-param-reblock": "De huidige blokkade aanpassen als de gebruiker al geblokkeerd is.",
+ "apihelp-createaccount-param-name": "Gebruikersnaam.",
+ "apihelp-delete-description": "Verwijder een pagina.",
+ "apihelp-delete-example-simple": "Verwijder <kbd>Hoofdpagina</kbd>.",
+ "apihelp-delete-example-reason": "Verwijder <kbd>Hoofdpagina</kbd> met als reden <kbd>Voorbereiding voor verplaatsing</kbd>.",
+ "apihelp-disabled-description": "Deze module is uitgeschakeld.",
+ "apihelp-edit-param-minor": "Kleine bewerking.",
+ "apihelp-edit-param-notminor": "Geen kleine bewerking.",
+ "apihelp-edit-param-bot": "Markeer deze bewerking als bot.",
+ "apihelp-edit-param-createonly": "Bewerk de pagina niet als die al bestaat.",
+ "apihelp-edit-param-nocreate": "Geef een foutmelding als de pagina niet bestaat.",
+ "apihelp-edit-param-watch": "Voeg de pagina toe aan je volglijst.",
+ "apihelp-edit-param-unwatch": "Verwijder de pagina van je volglijst.",
+ "apihelp-edit-example-edit": "Pagina bewerken",
+ "apihelp-emailuser-description": "Gebruiker e-mailen.",
+ "apihelp-emailuser-param-target": "Gebruiker naar wie de e-mail moet worden gestuurd.",
+ "apihelp-emailuser-param-subject": "Onderwerpkoptekst.",
+ "apihelp-emailuser-param-text": "E-mailtekst.",
+ "apihelp-emailuser-param-ccme": "Stuur mij een kopie van deze e-mail.",
+ "apihelp-expandtemplates-param-title": "Paginanaam.",
+ "apihelp-feedcontributions-param-year": "Van jaar (en eerder).",
+ "apihelp-feedcontributions-param-month": "Van maand (en eerder).",
+ "apihelp-login-param-name": "Gebruikersnaam.",
+ "apihelp-login-param-password": "Wachtwoord.",
+ "apihelp-login-param-domain": "Domein (optioneel).",
+ "apihelp-login-example-login": "Aanmelden",
+ "apihelp-move-description": "Pagina hernoemen.",
+ "api-help-flag-readrights": "Voor deze module zijn leesrechten nodig.",
+ "api-help-flag-writerights": "Voor deze module zijn schrijfrechten nodig.",
+ "api-help-parameters": "{{PLURAL:$1|Parameter|Parameters}}:",
+ "api-help-param-deprecated": "Verouderd.",
+ "api-help-param-default": "Standaard: $1",
+ "api-credits-header": "Vermeldingen",
+ "api-credits": "API-ontwikkelaars:\n* Roan Kattouw (hoofdontwikkelaar september 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (oorspronkelijke ontwikkelaar, hoofdontwikkelaar september 2006 – september 2007)\n* Brad Jorsch (hoofdontwikkelaar 2013 – heden)\n\nStuur uw opmerkingen, suggesties en vragen naar mediawiki-api@lists.wikimedia.org\nof maak een melding aan op https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/oc.json b/includes/api/i18n/oc.json
new file mode 100644
index 00000000..dc12b663
--- /dev/null
+++ b/includes/api/i18n/oc.json
@@ -0,0 +1,17 @@
+{
+ "@metadata": {
+ "authors": [
+ "Cedric31"
+ ]
+ },
+ "apihelp-main-param-action": "Quina accion cal efectuar.",
+ "apihelp-main-param-format": "Lo format de sortida.",
+ "apihelp-block-description": "Blocar un utilizaire.",
+ "apihelp-block-param-reason": "Motiu del blocatge.",
+ "apihelp-block-param-nocreate": "Empachar la creacion de compte.",
+ "apihelp-checktoken-param-token": "Geton de testar.",
+ "apihelp-createaccount-param-name": "Nom d'utilizaire.",
+ "apihelp-delete-example-simple": "Suprimir la <kbd>Pagina principala</kbd>.",
+ "apihelp-edit-param-text": "Contengut de la pagina.",
+ "apihelp-edit-param-minor": "Modificacion menora."
+}
diff --git a/includes/api/i18n/pa.json b/includes/api/i18n/pa.json
new file mode 100644
index 00000000..96c86941
--- /dev/null
+++ b/includes/api/i18n/pa.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Babanwalia"
+ ]
+ },
+ "apihelp-help-example-recursive": "ਇੱਕੋ ਸਫ਼ੇ 'ਤੇ ਸਾਰੀ ਮਦਦ"
+}
diff --git a/includes/api/i18n/pam.json b/includes/api/i18n/pam.json
new file mode 100644
index 00000000..c82d88fc
--- /dev/null
+++ b/includes/api/i18n/pam.json
@@ -0,0 +1,31 @@
+{
+ "@metadata": {
+ "authors": [
+ "Leeheonjin"
+ ]
+ },
+ "apihelp-delete-example-simple": "Buran ya ing <kbd>Pun Bulung</kbd>.",
+ "apihelp-edit-example-edit": "Alilan ya ing bulung.",
+ "apihelp-feedrecentchanges-example-simple": "Pakit deng bayung mengayalili.",
+ "apihelp-help-example-main": "Saup para king pun modyul.",
+ "apihelp-help-example-recursive": "Deng eganaganang saup king metung a bulung.",
+ "apihelp-login-example-login": "Magpatala (login)",
+ "apihelp-patrol-example-rcid": "Magbante king bayung mengayalili.",
+ "apihelp-patrol-example-revid": "Banten ing meyalili.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "E malyaring gamitan a yating <var>$3user</var>.",
+ "apihelp-query+allpages-example-B": "Ipakit ing talaan da reng bulung a mangumpisa king titik <kbd>B</kbd>.",
+ "apihelp-query+categoryinfo-example-simple": "Kumuwa ning impormasyun tungkul king <kbd>Kategorya:Foo</kbd> at <kbd>Kategorya:Bar</kbd>.",
+ "apihelp-query+deletedrevs-example-mode2": "Ilista la reng 50 binurang kontribusyun nang <kbd>Bob</kbd> (mode 2).",
+ "apihelp-query+deletedrevs-example-mode3-talk": "Ilista mu la reng minunang 50 meburang bulung king {{ns:talk}} lagyu-espasyu (mode 3)",
+ "apihelp-query+duplicatefiles-example-generated": "Mayintun para kareng duplika da reng egana-ganang simpan (file).",
+ "apihelp-query+extlinks-example-simple": "Kumuwa ning lista da reng suglung paluwal king <kbd>Pun Bulung</kbd>.",
+ "apihelp-query+exturlusage-example-simple": "Pakit la reng bulung a makasuglung king <kbd>http://www.mediawiki.org</kbd>.",
+ "apihelp-query+imageusage-example-simple": "Ipakit la reng bulung a gagamit ning [[:Simpan:Albert Einstein Head.jpg]].",
+ "apihelp-query+langbacklinks-example-simple": "Kunan deng bulung a maka-suglung king [[:fr:Test]].",
+ "apihelp-query+protectedtitles-example-generator": "Pantunan deng suglung king maka-protektang titulu king pun lagyu-espasyu.",
+ "apihelp-query+recentchanges-example-simple": "Talaan da reng bayung mengayalili.",
+ "apihelp-query+search-example-text": "Pantunan mo la reng tekstu para king <kbd>kabaldugan</kbd>",
+ "apihelp-query+siteinfo-example-simple": "Kung ing impormasyun ning sityu.",
+ "apihelp-upload-example-url": "Maglulan (upload) ibat king URL.",
+ "apihelp-watch-example-unwatch": "E banten ing bulung <kbd>Pun Bulung</kbd>"
+}
diff --git a/includes/api/i18n/pl.json b/includes/api/i18n/pl.json
new file mode 100644
index 00000000..1a5c8975
--- /dev/null
+++ b/includes/api/i18n/pl.json
@@ -0,0 +1,117 @@
+{
+ "@metadata": {
+ "authors": [
+ "Chrumps",
+ "Py64",
+ "Pan Cube",
+ "Alan ffm",
+ "Devwebtel",
+ "Macofe",
+ "Pio387",
+ "Peter Bowman",
+ "Darellur"
+ ]
+ },
+ "apihelp-main-param-action": "Wybierz akcję do wykonania.",
+ "apihelp-main-param-format": "Format danych wyjściowych.",
+ "apihelp-main-param-maxlag": "Maksymalne opóźnienie mogą być używane kiedy MediaWiki jest zainstalowana w klastrze zreplikowanej bazy danych. By zapisać działania powodujące większe opóźnienie replikacji, ten parametr może wymusić czekanie u klienta, dopóki opóźnienie replikacji jest mniejsze niż określona wartość. W przypadku nadmiernego opóźnienia, kod błędu <samp>maxlag</samp> jest zwracany z wiadomością jak <samp>Oczekiwanie na $host: $lag sekund opóźnienia</samp>.<br />Zobacz [[mw:Manual:Maxlag_parameter|Podręcznik:Parametr Maxlag]] by uzyskać więcej informacji.",
+ "apihelp-main-param-assert": "Sprawdź, czy użytkownik jest zalogowany jeżeli jest ustawiony na <kbd>użytkownik</kbd>, lub ma prawa bota jeśli <kbd>bot</kbd>.",
+ "apihelp-block-description": "Zablokuj użytkownika.",
+ "apihelp-block-param-user": "Nazwa użytkownika, adres IP lub zakres adresów IP, które chcesz zablokować.",
+ "apihelp-block-param-reason": "Powód blokady.",
+ "apihelp-block-param-nocreate": "Zapobiegnij utworzeniu konta.",
+ "apihelp-block-param-watchuser": "Obserwuj stronę użytkownika i jego IP oraz jego stronę dyskusji.",
+ "apihelp-block-example-ip-simple": "Zablokuj IP <kbd>192.0.2.5</kbd> na 3 dni za <kbd>Pierwszy atak</kbd>.",
+ "apihelp-createaccount-param-name": "Nazwa użytkownika",
+ "apihelp-delete-description": "Usuń stronę.",
+ "apihelp-delete-param-watch": "Dodaj stronę do twojej listy obserwowanych.",
+ "apihelp-delete-param-unwatch": "Usuń stronę z twojej listy obserwowanych.",
+ "apihelp-delete-example-simple": "Usuń stronę główną",
+ "apihelp-disabled-description": "Ten moduł został wyłączony.",
+ "apihelp-edit-description": "Utwórz i edytuj strony.;",
+ "apihelp-edit-param-text": "Zawartość strony.",
+ "apihelp-edit-param-minor": "Drobna zmiana.",
+ "apihelp-edit-param-notminor": "Nie drobna zmiana.",
+ "apihelp-edit-param-bot": "Oznacz tę edycję jako edycję bota.",
+ "apihelp-edit-param-watch": "Dodaj stronę do aktualnej listy obserwacji użytkownika.",
+ "apihelp-edit-param-unwatch": "Usuń stronę z aktualnej listy obserwacji użytkownika.",
+ "apihelp-edit-example-edit": "Edytuj stronę",
+ "apihelp-emailuser-description": "Wyślij e‐mail do użytkownika.",
+ "apihelp-feedrecentchanges-example-simple": "Pokaż ostatnie zmiany.",
+ "apihelp-help-description": "Wyświetl pomoc dla określonych modułów.",
+ "apihelp-help-param-modules": "Moduły do wyświetlenia pomocy dla (wartości <var>action</var> i <var>format</var> parametry, lub <kbd>main</kbd>). Może określić podmoduły z <kbd>+</kbd>.",
+ "apihelp-help-param-recursivesubmodules": "Zawiera pomoc dla podmodułów rekursywnie.",
+ "apihelp-help-example-main": "Pomoc dla modułu głównego",
+ "apihelp-help-example-recursive": "Cała pomoc na jednej stronie.",
+ "apihelp-help-example-help": "Pomoc dla modułu pomocy",
+ "apihelp-login-param-name": "Nazwa użytkownika.",
+ "apihelp-login-param-password": "Hasło.",
+ "apihelp-login-example-login": "Zaloguj się",
+ "apihelp-managetags-param-ignorewarnings": "Czy zignorować ostrzeżenia, które pojawiają się w trakcie operacji.",
+ "apihelp-move-description": "Przenieś stronę.",
+ "apihelp-move-param-reason": "Powód zmiany nazwy.",
+ "apihelp-move-param-ignorewarnings": "Ignoruj wszystkie ostrzeżenia.",
+ "apihelp-protect-example-protect": "Zabezpiecz stronę",
+ "apihelp-query+allpages-example-B": "Pokaż listę stron rozpoczynających się na literę <kbd>B</kbd>.",
+ "apihelp-query+filearchive-example-simple": "Pokaż listę wszystkich usuniętych plików.",
+ "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Dodaje kanoniczny tytuł pliku.",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias rozmiaru.",
+ "apihelp-query+imageinfo-paramvalue-prop-mime": "Dodaje typ MIME pliku.",
+ "apihelp-query+info-paramvalue-prop-watchers": "Liczba obserwujących, jeśli jest to dozwolone.",
+ "apihelp-query+info-paramvalue-prop-readable": "Czy użytkownik może przeczytać tę stronę.",
+ "apihelp-query+prefixsearch-param-offset": "Liczba wyników do pominięcia.",
+ "apihelp-query+recentchanges-example-simple": "Lista ostatnich zmian.",
+ "apihelp-query+search-description": "Wykonaj wyszukiwanie pełnotekstowe.",
+ "apihelp-query+watchlist-param-excludeuser": "Nie wyświetlaj zmian wykonanych przez tego użytkownika.",
+ "apihelp-unblock-param-reason": "Powód odblokowania.",
+ "apihelp-undelete-param-reason": "Powód przywracania.",
+ "apihelp-upload-param-filename": "Nazwa pliku docelowego.",
+ "apihelp-userrights-param-user": "Nazwa użytkownika.",
+ "apihelp-userrights-param-reason": "Powód zmiany.",
+ "apihelp-dbg-description": "Dane wyjściowe w formacie <code>var_export()</code> (funkcji PHP).",
+ "apihelp-dbgfm-description": "Dane wyjściowe w formacie <code>var_export()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+ "apihelp-dump-description": "Dane wyjściowe w formacie <code>var_dump()</code> (funkcji PHP).",
+ "apihelp-dumpfm-description": "Dane wyjściowe w formacie <code>var_dump()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+ "apihelp-json-description": "Dane wyjściowe w formacie JSON.",
+ "apihelp-jsonfm-description": "Dane wyjściowe w formacie JSON (prawidłowo wyświetlane w HTML).",
+ "apihelp-php-description": "Dane wyjściowe w serializowany formacie PHP.",
+ "apihelp-phpfm-description": "Dane wyjściowe w serializowanym formacie PHP (prawidłowo wyświetlane w HTML).",
+ "apihelp-txt-description": "Dane wyjściowe w formacie <code>print_r()</code> (funkcji PHP).",
+ "apihelp-txtfm-description": "Dane wyjściowe w formacie <code>print_r()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+ "apihelp-wddx-description": "Dane wyjściowe w formacie WDDX.",
+ "apihelp-wddxfm-description": "Dane wyjściowe w formacie WDDX (prawidłowo wyświetlane w HTML).",
+ "apihelp-xml-description": "Dane wyjściowe w formacie XML.",
+ "apihelp-xml-param-xslt": "Jeśli określony, dodaje &lt;xslt&gt; jako arkusz styli. Powinna to być strona wiki w przestrzeni nazw MediaWiki, której nazwy stron kończą się na \".xsl\".",
+ "apihelp-xmlfm-description": "Dane wyjściowe w formacie XML (prawidłowo wyświetlane w HTML).",
+ "apihelp-yaml-description": "Dane wyjściowe w formacie YAML.",
+ "apihelp-yamlfm-description": "Dane wyjściowe w formacie YAML (prawidłowo wyświetlane w HTML).",
+ "api-format-title": "Wynik MediaWiki API",
+ "api-help-title": "Pomoc MediaWiki API",
+ "api-help-lead": "To jest automatycznie wygenerowana strona dokumentacji MediaWiki API.\nDokumentacja i przykłady: https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "Moduł główny",
+ "api-help-flag-deprecated": "Ten moduł jest przestarzały.",
+ "api-help-flag-internal": "<strong>Ten moduł jest wewnętrzny lub niestabilny.</strong> Jego działanie może się zmienić bez uprzedzenia.",
+ "api-help-flag-readrights": "Ten moduł wymaga praw odczytu.",
+ "api-help-flag-writerights": "Ten moduł wymaga praw zapisu.",
+ "api-help-flag-mustbeposted": "Ten moduł akceptuje tylko żądania POST.",
+ "api-help-flag-generator": "Ten moduł może być użyty jako generator.",
+ "api-help-parameters": "{{PLURAL:$1|Parametr|Parametry}}:",
+ "api-help-param-deprecated": "Przestarzałe.",
+ "api-help-param-required": "Ten parametr jest wymagany.",
+ "api-help-param-list": "{{PLURAL:$1|1=Jedna wartość|2=Wartości (oddziel za pomocą <kbd>{{!}}</kbd>)}}: $2",
+ "api-help-param-limit": "Nie więcej niż $1 dozwolone.",
+ "api-help-param-limit2": "Nie więcej niż $1 ($2 dla botów) dozwolone.",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=Wartość|2=Wartości}} musza być mniejsze niż $2.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=Wartość musi|2=Wartości muszą}} być nie większa niż $3.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=Wartość musi|2=Wartości muszą}} być pomiędzy $2 a $3.",
+ "api-help-param-multi-separate": "Oddziel wartości za pomocą <kbd>|</kbd>.",
+ "api-help-param-multi-max": "Maksymalna ilość wartości to {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} dla botów).",
+ "api-help-param-default": "Domyślnie: $1",
+ "api-help-param-default-empty": "Domyślnie: <span class=\"apihelp-empty\">(puste)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(bez opisu)</span>",
+ "api-help-examples": "{{PLURAL:$1|Przykład|Przykłady}}:",
+ "api-help-permissions": "{{PLURAL:$2|Uprawnienie|Uprawnienia}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Przydzielone dla}}: $2",
+ "api-credits-header": "Twórcy",
+ "api-credits": "Deweloperzy API:\n* Roan Kattouw (główny programista wrzesień 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (twórca, główny programista wrzesień 2006–wrzesień 2007)\n* Brad Jorsch (główny programista 2013–obecnie)\n\nProsimy wysyłać komentarze, sugestie i pytania do mediawiki-api@lists.wikimedia.org\nlub zgłoś błąd na https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/ps.json b/includes/api/i18n/ps.json
new file mode 100644
index 00000000..b9399024
--- /dev/null
+++ b/includes/api/i18n/ps.json
@@ -0,0 +1,29 @@
+{
+ "@metadata": {
+ "authors": [
+ "Ahmed-Najib-Biabani-Ibrahimkhel"
+ ]
+ },
+ "apihelp-block-description": "په يو کارن بنديز لگول.",
+ "apihelp-block-param-user": "کارن-نوم، IP پته، يا IP سيمې باندې بنديز لگول.",
+ "apihelp-block-param-reason": "د بنديز سبب.",
+ "apihelp-createaccount-param-name": "کارن-نوم.",
+ "apihelp-delete-description": "يو مخ ړنگول.",
+ "apihelp-edit-param-text": "مخ مېنځپانگه.",
+ "apihelp-edit-example-edit": "يو مخ سمول.",
+ "apihelp-emailuser-description": "کارن ته برېښليک لېږل.",
+ "apihelp-expandtemplates-param-title": "د مخ سرليک.",
+ "apihelp-login-param-name": "کارن نوم.",
+ "apihelp-login-param-password": "پټنوم.",
+ "apihelp-login-param-domain": "شپول (اختياري).",
+ "apihelp-login-example-login": "ننوتل.",
+ "apihelp-move-description": "يو مخ لېږدول.",
+ "apihelp-query+search-example-simple": "د <kbd>مانا</kbd> پلټل.",
+ "apihelp-query+search-example-text": "د <kbd>مانا</kbd> لپاره متنونه پلټل.",
+ "apihelp-userrights-param-user": "کارن نوم.",
+ "apihelp-userrights-param-userid": "کارن پېژند.",
+ "api-help-param-default": "تلواليز: $1",
+ "api-help-param-default-empty": "تلواليز: <span class=\"apihelp-empty\">(تش)</span>",
+ "api-help-examples": "{{PLURAL:$1|بېلگه|بېلگې}}:",
+ "api-help-permissions": "{{PLURAL:$1|پرېښه|پرېښې}}:"
+}
diff --git a/includes/api/i18n/pt-br.json b/includes/api/i18n/pt-br.json
new file mode 100644
index 00000000..5af806d0
--- /dev/null
+++ b/includes/api/i18n/pt-br.json
@@ -0,0 +1,14 @@
+{
+ "@metadata": {
+ "authors": [
+ "Fasouzafreitas"
+ ]
+ },
+ "apihelp-main-param-requestid": "Qualquer valor dado aqui será incluído na resposta. Pode ser usado para distinguir requisições.",
+ "apihelp-block-description": "Bloquear um usuário",
+ "apihelp-block-param-user": "Nome de usuário, endereço IP ou faixa de IP para bloquear.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Ocultar alterações feitas pelo usuário atual.",
+ "apihelp-feedrecentchanges-example-30days": "Mostrar as alterações recentes por 30 dias.",
+ "apihelp-move-param-movetalk": "Renomear a página de discussão, se existir.",
+ "apihelp-options-example-reset": "Resetar todas as preferências"
+}
diff --git a/includes/api/i18n/pt.json b/includes/api/i18n/pt.json
new file mode 100644
index 00000000..72044db9
--- /dev/null
+++ b/includes/api/i18n/pt.json
@@ -0,0 +1,104 @@
+{
+ "@metadata": {
+ "authors": [
+ "Vitorvicentevalente",
+ "Fúlvio",
+ "Macofe"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentação]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discussão]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anúncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitações]\n</div>\n<strong>Estado:</strong> Todas as funcionalidades mostradas nesta página deveriam estar a funcionar, mas a API ainda está em activo desenvolvimento, e pode ser alterada a qualquer momento. Inscreva-se na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discussão mediawiki-api-announce] para ser informado acerca das actualizações.\n\n<strong>Solicitações erradas:</strong> Quando solicitações erradas são enviadas à API, um cabeçalho em HTTP será enviado com a chave \"MediaWiki-API-Error\" e, em seguida, tanto o valor do cabeçalho quanto o código de erro retornado serão definidos com o mesmo valor. Para mais informação, consulte [[mw:API:Errors_and_warnings|API: Errors and warnings]].",
+ "apihelp-main-param-action": "Qual acção a executar.",
+ "apihelp-main-param-format": "O formato de saída.",
+ "apihelp-block-description": "Bloquear um utilizador.",
+ "apihelp-block-param-user": "Nome de utilizador(a), endereço ou gama de IP que pretende bloquear.",
+ "apihelp-block-param-reason": "Motivo do bloqueio.",
+ "apihelp-block-param-nocreate": "Impedir criação de contas.",
+ "apihelp-createaccount-description": "Criar uma nova conta.",
+ "apihelp-createaccount-param-name": "Nome de utilizador(a).",
+ "apihelp-createaccount-param-email": "Endereço de correio eletrónico do utilizador (opcional).",
+ "apihelp-createaccount-param-realname": "Nome verdadeiro do utilizador (opcional).",
+ "apihelp-delete-description": "Eliminar uma página.",
+ "apihelp-delete-param-watch": "Adicionar esta página à lista de vigiadas.",
+ "apihelp-delete-param-unwatch": "Remover esta página da lista de vigiadas.",
+ "apihelp-delete-example-simple": "Eliminar <kbd>Página Principal</kbd>.",
+ "apihelp-disabled-description": "O módulo foi desativado.",
+ "apihelp-edit-description": "Criar e editar páginas.",
+ "apihelp-edit-param-sectiontitle": "Título para uma nova seção.",
+ "apihelp-edit-param-text": "Conteúdo da página.",
+ "apihelp-edit-param-minor": "Edição menor.",
+ "apihelp-edit-param-bot": "Marcar esta edição como robô.",
+ "apihelp-edit-example-edit": "Editar uma página",
+ "apihelp-emailuser-description": "Enviar correio eletrónico a utilizador.",
+ "apihelp-emailuser-param-subject": "Assunto.",
+ "apihelp-emailuser-param-text": "Texto.",
+ "apihelp-expandtemplates-param-title": "Título da página.",
+ "apihelp-feedcontributions-param-feedformat": "O formato do feed.",
+ "apihelp-feedcontributions-param-deletedonly": "Mostrar apenas contribuições eliminadas.",
+ "apihelp-feedcontributions-param-showsizediff": "Mostrar diferença de tamanho entre edições.",
+ "apihelp-feedrecentchanges-param-feedformat": "O formato do feed.",
+ "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados a apresentar.",
+ "apihelp-feedrecentchanges-param-from": "Mostrar alterações desde então.",
+ "apihelp-feedrecentchanges-param-hideminor": "Ocultar edições menores.",
+ "apihelp-feedrecentchanges-param-hidebots": "Ocultar alterações feitas por robôs.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar alterações patrulhadas.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Ocultar alterações feitas por mim.",
+ "apihelp-feedrecentchanges-param-target": "Mostrar apenas mudanças em páginas afluentes a esta.",
+ "apihelp-feedrecentchanges-example-simple": "Mostrar mudanças recentes",
+ "apihelp-help-example-main": "Ajuda para o módulo principal",
+ "apihelp-help-example-recursive": "Toda a ajuda numa página",
+ "apihelp-login-param-name": "Nome de utilizador(a).",
+ "apihelp-login-param-password": "Palavra-passe.",
+ "apihelp-login-param-domain": "Domínio (opcional).",
+ "apihelp-login-example-login": "Entrar",
+ "apihelp-logout-description": "Terminar e limpar dados de sessão.",
+ "apihelp-managetags-description": "Executar tarefas de gestão relacionadas com alteração de etiquetas.",
+ "apihelp-managetags-param-reason": "Um motivo, opcional, para a criação, eliminação, ativação ou desativação da etiqueta.",
+ "apihelp-move-description": "Mover uma página.",
+ "apihelp-move-param-noredirect": "Não criar um redirecionamento.",
+ "apihelp-move-param-ignorewarnings": "Ignorar quaisquer avisos.",
+ "apihelp-opensearch-param-limit": "Número máximo de resultados a apresentar.",
+ "apihelp-options-param-reset": "Reiniciar preferências para os padrões do sítio.",
+ "apihelp-options-example-reset": "Reiniciar todas as preferências",
+ "apihelp-patrol-description": "Patrulhar uma página ou edição.",
+ "apihelp-patrol-example-rcid": "Patrulhar uma mudança recente",
+ "apihelp-patrol-example-revid": "Patrulhar uma edição",
+ "apihelp-protect-example-protect": "Proteger uma página",
+ "apihelp-query+allcategories-description": "Enumerar todas as categorias.",
+ "apihelp-query+allpages-param-prefix": "Pesquisa para todos os títulos de páginas que comecem com este valor.",
+ "apihelp-query+allpages-example-generator": "Mostrar informação sobre 4 páginas que comecem com a letra <kbd>T</kbd>.",
+ "apihelp-query+allusers-example-Y": "Lista de utilizadores que comecem com <kbd>Y</kbd>.",
+ "apihelp-query+blocks-param-limit": "O número máximo de bloqueios a listar.",
+ "apihelp-query+categorymembers-description": "Lista de todas as páginas numa categoria fornecida.",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
+ "apihelp-query+deletedrevs-param-excludeuser": "Não listar edições deste utilizador.",
+ "apihelp-query+deletedrevs-param-namespace": "Listar apenas as páginas neste domínio.",
+ "apihelp-query+filearchive-example-simple": "Mostrar lista de todos os ficheiros eliminados",
+ "apihelp-query+info-description": "Obter informação básica da página.",
+ "apihelp-query+recentchanges-example-simple": "Lista de mudanças recentes",
+ "apihelp-unblock-description": "Desbloquear um utilizador.",
+ "apihelp-unblock-param-reason": "Motivo para o desbloqueio.",
+ "apihelp-undelete-param-title": "Título da página a restaurar.",
+ "apihelp-upload-param-watch": "Vigiar página.",
+ "apihelp-upload-param-ignorewarnings": "Ignorar todos os avisos.",
+ "apihelp-userrights-param-user": "Nome de utilizador(a).",
+ "apihelp-userrights-param-userid": "ID de utilizador.",
+ "apihelp-userrights-param-add": "Adicionar o utilizador a estes grupos.",
+ "apihelp-userrights-param-remove": "Remover este utilizador destes grupos.",
+ "apihelp-watch-example-unwatch": "Deixar de vigiar a página <kbd>Página Principal</kbd>.",
+ "apihelp-json-description": "Dados de saída em formato JSON.",
+ "api-help-title": "Ajuda API da MediaWiki",
+ "api-help-main-header": "Módulo principal",
+ "api-help-flag-deprecated": "Este módulo está obsoleto.",
+ "api-help-parameters": "{{PLURAL:$1|Parâmetro|Parâmetros}}:",
+ "api-help-param-deprecated": "Obsoleto.",
+ "api-help-param-required": "Este parâmetro é obrigatório.",
+ "api-help-param-multi-separate": "Separe os valores com <kbd>|</kbd>.",
+ "api-help-param-default": "Padrão: $1",
+ "api-help-param-default-empty": "Padrão: <span class=\"apihelp-empty\">(vazio)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(sem descrição)</span>",
+ "api-help-examples": "{{PLURAL:$1|Exemplo|Exemplos}}:",
+ "api-help-permissions": "{{PLURAL:$1|Permissão|Permissiões}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|Concedida a|Concedidas a}}: $2",
+ "api-credits-header": "Créditos",
+ "api-credits": "Programadores API:\n* Roan Kattouw (programador principal Set 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (criador, programador-líder Set 2006–Set 2007)\n* Brad Jorsch (programador-líder 2013–presente)\n\nPor favor, envie os seus comentários, sugestões e perguntas para mediawiki-api@lists.wikimedia.org ou reporte um erro técnico em https://phabricator.wikimedia.org/."
+}
diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json
new file mode 100644
index 00000000..9bf98247
--- /dev/null
+++ b/includes/api/i18n/qqq.json
@@ -0,0 +1,1069 @@
+{
+ "@metadata": {
+ "authors": [
+ "Liuxinyu970226",
+ "Robby",
+ "Shirayuki",
+ "Umherirrender",
+ "McDutchie",
+ "Raymond",
+ "Anomie"
+ ]
+ },
+ "apihelp-main-description": "{{doc-apihelp-description|main}}",
+ "apihelp-main-param-action": "{{doc-apihelp-param|main|action}}",
+ "apihelp-main-param-format": "{{doc-apihelp-param|main|format}}",
+ "apihelp-main-param-maxlag": "{{doc-apihelp-param|main|maxlag}}\n\n\"$host\" and \"$lag\" are not variables and appear as is.",
+ "apihelp-main-param-smaxage": "{{doc-apihelp-param|main|smaxage}}",
+ "apihelp-main-param-maxage": "{{doc-apihelp-param|main|maxage}}",
+ "apihelp-main-param-assert": "{{doc-apihelp-param|main|assert}}",
+ "apihelp-main-param-requestid": "{{doc-apihelp-param|main|requestid}}",
+ "apihelp-main-param-servedby": "{{doc-apihelp-param|main|servedby}}",
+ "apihelp-main-param-curtimestamp": "{{doc-apihelp-param|main|curtimestamp}}",
+ "apihelp-main-param-origin": "{{doc-apihelp-param|main|origin}}",
+ "apihelp-main-param-uselang": "{{doc-apihelp-param|main|uselang}}",
+ "apihelp-block-description": "{{doc-apihelp-description|block}}",
+ "apihelp-block-param-user": "{{doc-apihelp-param|block|user}}",
+ "apihelp-block-param-expiry": "{{doc-apihelp-param|block|expiry}}\n{{doc-important|Do not translate \"5 months\", \"2 weeks\", \"infinite\", \"indefinite\" or \"never\"!}}",
+ "apihelp-block-param-reason": "{{doc-apihelp-param|block|reason}}",
+ "apihelp-block-param-anononly": "{{doc-apihelp-param|block|anononly}}\n* See also {{msg-mw|ipb-hardblock}}",
+ "apihelp-block-param-nocreate": "{{doc-apihelp-param|block|nocreate}}\n* See also {{msg-mw|ipbcreateaccount}}",
+ "apihelp-block-param-autoblock": "{{doc-singularthey}}\n{{doc-apihelp-param|block|autoblock}}\n* See also {{msg-mw|ipbenableautoblock}}",
+ "apihelp-block-param-noemail": "{{doc-apihelp-param|block|noemail}}\n* See also {{msg-mw|ipbemailban}}",
+ "apihelp-block-param-hidename": "{{doc-apihelp-param|block|hidename}}",
+ "apihelp-block-param-allowusertalk": "{{doc-apihelp-param|block|allowusertalk}}\n* See also {{msg-mw|ipb-disableusertalk}}",
+ "apihelp-block-param-reblock": "{{doc-apihelp-param|block|reblock}}",
+ "apihelp-block-param-watchuser": "{{doc-apihelp-param|block|watchuser}}",
+ "apihelp-block-example-ip-simple": "{{doc-apihelp-example|block}}",
+ "apihelp-block-example-user-complex": "{{doc-apihelp-example|block}}",
+ "apihelp-checktoken-description": "{{doc-apihelp-description|checktoken}}",
+ "apihelp-checktoken-param-type": "{{doc-apihelp-param|checktoken|type}}",
+ "apihelp-checktoken-param-token": "{{doc-apihelp-param|checktoken|token}}",
+ "apihelp-checktoken-param-maxtokenage": "{{doc-apihelp-param|checktoken|maxtokenage}}",
+ "apihelp-checktoken-example-simple": "{{doc-apihelp-example|checktoken}}",
+ "apihelp-clearhasmsg-description": "{{doc-apihelp-description|clearhasmsg}}",
+ "apihelp-clearhasmsg-example-1": "{{doc-apihelp-example|clearhasmsg}}",
+ "apihelp-compare-description": "{{doc-apihelp-description|compare}}",
+ "apihelp-compare-param-fromtitle": "{{doc-apihelp-param|compare|fromtitle}}",
+ "apihelp-compare-param-fromid": "{{doc-apihelp-param|compare|fromid}}",
+ "apihelp-compare-param-fromrev": "{{doc-apihelp-param|compare|fromrev}}",
+ "apihelp-compare-param-totitle": "{{doc-apihelp-param|compare|totitle}}",
+ "apihelp-compare-param-toid": "{{doc-apihelp-param|compare|toid}}",
+ "apihelp-compare-param-torev": "{{doc-apihelp-param|compare|torev}}",
+ "apihelp-compare-example-1": "{{doc-apihelp-example|compare}}",
+ "apihelp-createaccount-description": "{{doc-apihelp-description|createaccount}}",
+ "apihelp-createaccount-param-name": "{{doc-apihelp-param|createaccount|name}}",
+ "apihelp-createaccount-param-password": "{{doc-apihelp-param|createaccount|password}}",
+ "apihelp-createaccount-param-domain": "{{doc-apihelp-param|createaccount|domain}}",
+ "apihelp-createaccount-param-token": "{{doc-apihelp-param|createaccount|token}}",
+ "apihelp-createaccount-param-email": "{{doc-apihelp-param|createaccount|email}}",
+ "apihelp-createaccount-param-realname": "{{doc-apihelp-param|createaccount|realname}}",
+ "apihelp-createaccount-param-mailpassword": "{{doc-apihelp-param|createaccount|mailpassword}}",
+ "apihelp-createaccount-param-reason": "{{doc-apihelp-param|createaccount|reason}}",
+ "apihelp-createaccount-param-language": "{{doc-apihelp-param|createaccount|language}}",
+ "apihelp-createaccount-example-pass": "{{doc-apihelp-example|createaccount}}",
+ "apihelp-createaccount-example-mail": "{{doc-apihelp-example|createaccount}}",
+ "apihelp-delete-description": "{{doc-apihelp-description|delete}}",
+ "apihelp-delete-param-title": "{{doc-apihelp-param|delete|title}}",
+ "apihelp-delete-param-pageid": "{{doc-apihelp-param|delete|pageid}}",
+ "apihelp-delete-param-reason": "{{doc-apihelp-param|delete|reason}}",
+ "apihelp-delete-param-watch": "{{doc-apihelp-param|delete|watch}}",
+ "apihelp-delete-param-watchlist": "{{doc-apihelp-param|delete|watchlist}}",
+ "apihelp-delete-param-unwatch": "{{doc-apihelp-param|delete|unwatch}}",
+ "apihelp-delete-param-oldimage": "{{doc-apihelp-param|delete|oldimage}}",
+ "apihelp-delete-example-simple": "{{doc-apihelp-example|delete}}",
+ "apihelp-delete-example-reason": "{{doc-apihelp-example|delete}}",
+ "apihelp-disabled-description": "{{doc-apihelp-description|disabled}}",
+ "apihelp-edit-description": "{{doc-apihelp-description|edit}}",
+ "apihelp-edit-param-title": "{{doc-apihelp-param|edit|title}}",
+ "apihelp-edit-param-pageid": "{{doc-apihelp-param|edit|pageid}}",
+ "apihelp-edit-param-section": "{{doc-apihelp-param|edit|section}}",
+ "apihelp-edit-param-sectiontitle": "{{doc-apihelp-param|edit|sectiontitle}}",
+ "apihelp-edit-param-text": "{{doc-apihelp-param|edit|text}}",
+ "apihelp-edit-param-summary": "{{doc-apihelp-param|edit|summary}}",
+ "apihelp-edit-param-tags": "{{doc-apihelp-param|edit|tags}}",
+ "apihelp-edit-param-minor": "{{doc-apihelp-param|edit|minor}}\n{{Identical|Minor edit}}",
+ "apihelp-edit-param-notminor": "{{doc-apihelp-param|edit|notminor}}",
+ "apihelp-edit-param-bot": "{{doc-apihelp-param|edit|bot}}",
+ "apihelp-edit-param-basetimestamp": "{{doc-apihelp-param|edit|basetimestamp}}",
+ "apihelp-edit-param-starttimestamp": "{{doc-apihelp-param|edit|starttimestamp}}",
+ "apihelp-edit-param-recreate": "{{doc-apihelp-param|edit|recreate}}",
+ "apihelp-edit-param-createonly": "{{doc-apihelp-param|edit|createonly}}",
+ "apihelp-edit-param-nocreate": "{{doc-apihelp-param|edit|nocreate}}",
+ "apihelp-edit-param-watch": "{{doc-apihelp-param|edit|watch}}",
+ "apihelp-edit-param-unwatch": "{{doc-apihelp-param|edit|unwatch}}",
+ "apihelp-edit-param-watchlist": "{{doc-apihelp-param|edit|watchlist}}",
+ "apihelp-edit-param-md5": "{{doc-apihelp-param|edit|md5}}",
+ "apihelp-edit-param-prependtext": "{{doc-apihelp-param|edit|prependtext}}",
+ "apihelp-edit-param-appendtext": "{{doc-apihelp-param|edit|appendtext}}",
+ "apihelp-edit-param-undo": "{{doc-apihelp-param|edit|undo}}",
+ "apihelp-edit-param-undoafter": "{{doc-apihelp-param|edit|undoafter}}",
+ "apihelp-edit-param-redirect": "{{doc-apihelp-param|edit|redirect}}",
+ "apihelp-edit-param-contentformat": "{{doc-apihelp-param|edit|contentformat}}",
+ "apihelp-edit-param-contentmodel": "{{doc-apihelp-param|edit|contentmodel}}",
+ "apihelp-edit-param-token": "{{doc-apihelp-param|edit|token}}",
+ "apihelp-edit-example-edit": "{{doc-apihelp-example|edit}}",
+ "apihelp-edit-example-prepend": "{{doc-apihelp-example|edit}}",
+ "apihelp-edit-example-undo": "{{doc-apihelp-example|edit}}",
+ "apihelp-emailuser-description": "{{doc-apihelp-description|emailuser}}",
+ "apihelp-emailuser-param-target": "{{doc-apihelp-param|emailuser|target}}",
+ "apihelp-emailuser-param-subject": "{{doc-apihelp-param|emailuser|subject}}",
+ "apihelp-emailuser-param-text": "{{doc-apihelp-param|emailuser|text}}",
+ "apihelp-emailuser-param-ccme": "{{doc-apihelp-param|emailuser|ccme}}",
+ "apihelp-emailuser-example-email": "{{doc-apihelp-example|emailuser}}",
+ "apihelp-expandtemplates-description": "{{doc-apihelp-description|expandtemplates}}",
+ "apihelp-expandtemplates-param-title": "{{doc-apihelp-param|expandtemplates|title}}",
+ "apihelp-expandtemplates-param-text": "{{doc-apihelp-param|expandtemplates|text}}",
+ "apihelp-expandtemplates-param-revid": "{{doc-apihelp-param|expandtemplates|revid}}\n{{doc-important|Do not translate <code><<nowiki />nowiki>{{<nowiki />REVISIONID}}<<nowiki />/nowiki></code>}}",
+ "apihelp-expandtemplates-param-prop": "{{doc-apihelp-param|expandtemplates|prop}}",
+ "apihelp-expandtemplates-param-includecomments": "{{doc-apihelp-param|expandtemplates|includecomments}}",
+ "apihelp-expandtemplates-param-generatexml": "{{doc-apihelp-param|expandtemplates|generatexml}}",
+ "apihelp-expandtemplates-example-simple": "{{doc-apihelp-example|expandtemplates}}",
+ "apihelp-feedcontributions-description": "{{doc-apihelp-description|feedcontributions}}",
+ "apihelp-feedcontributions-param-feedformat": "{{doc-apihelp-param|feedcontributions|feedformat}}",
+ "apihelp-feedcontributions-param-user": "{{doc-apihelp-param|feedcontributions|user}}",
+ "apihelp-feedcontributions-param-namespace": "{{doc-apihelp-param|feedcontributions|namespace}}",
+ "apihelp-feedcontributions-param-year": "{{doc-apihelp-param|feedcontributions|year}}",
+ "apihelp-feedcontributions-param-month": "{{doc-apihelp-param|feedcontributions|month}}",
+ "apihelp-feedcontributions-param-tagfilter": "{{doc-apihelp-param|feedcontributions|tagfilter}}",
+ "apihelp-feedcontributions-param-deletedonly": "{{doc-apihelp-param|feedcontributions|deletedonly}}",
+ "apihelp-feedcontributions-param-toponly": "{{doc-apihelp-param|feedcontributions|toponly}}",
+ "apihelp-feedcontributions-param-newonly": "{{doc-apihelp-param|feedcontributions|newonly}}",
+ "apihelp-feedcontributions-param-showsizediff": "{{doc-apihelp-param|feedcontributions|showsizediff}}",
+ "apihelp-feedcontributions-example-simple": "{{doc-apihelp-example|feedcontributions}}",
+ "apihelp-feedrecentchanges-description": "{{doc-apihelp-description|feedrecentchanges}}",
+ "apihelp-feedrecentchanges-param-feedformat": "{{doc-apihelp-param|feedrecentchanges|feedformat}}",
+ "apihelp-feedrecentchanges-param-namespace": "{{doc-apihelp-param|feedrecentchanges|namespace}}",
+ "apihelp-feedrecentchanges-param-invert": "{{doc-apihelp-param|feedrecentchanges|invert}}",
+ "apihelp-feedrecentchanges-param-associated": "{{doc-apihelp-param|feedrecentchanges|associated}}",
+ "apihelp-feedrecentchanges-param-days": "{{doc-apihelp-param|feedrecentchanges|days}}",
+ "apihelp-feedrecentchanges-param-limit": "{{doc-apihelp-param|feedrecentchanges|limit}}",
+ "apihelp-feedrecentchanges-param-from": "{{doc-apihelp-param|feedrecentchanges|from}}",
+ "apihelp-feedrecentchanges-param-hideminor": "{{doc-apihelp-param|feedrecentchanges|hideminor}}",
+ "apihelp-feedrecentchanges-param-hidebots": "{{doc-apihelp-param|feedrecentchanges|hidebots}}",
+ "apihelp-feedrecentchanges-param-hideanons": "{{doc-apihelp-param|feedrecentchanges|hideanons}}",
+ "apihelp-feedrecentchanges-param-hideliu": "{{doc-apihelp-param|feedrecentchanges|hideliu}}",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "{{doc-apihelp-param|feedrecentchanges|hidepatrolled}}",
+ "apihelp-feedrecentchanges-param-hidemyself": "{{doc-apihelp-param|feedrecentchanges|hidemyself}}",
+ "apihelp-feedrecentchanges-param-tagfilter": "{{doc-apihelp-param|feedrecentchanges|tagfilter}}",
+ "apihelp-feedrecentchanges-param-target": "{{doc-apihelp-param|feedrecentchanges|target}}",
+ "apihelp-feedrecentchanges-param-showlinkedto": "{{doc-apihelp-param|feedrecentchanges|showlinkedto}}",
+ "apihelp-feedrecentchanges-example-simple": "{{doc-apihelp-example|feedrecentchanges}}",
+ "apihelp-feedrecentchanges-example-30days": "{{doc-apihelp-example|feedrecentchanges}}",
+ "apihelp-feedwatchlist-description": "{{doc-apihelp-description|feedwatchlist}}",
+ "apihelp-feedwatchlist-param-feedformat": "{{doc-apihelp-param|feedwatchlist|feedformat}}",
+ "apihelp-feedwatchlist-param-hours": "{{doc-apihelp-param|feedwatchlist|hours}}",
+ "apihelp-feedwatchlist-param-linktosections": "{{doc-apihelp-param|feedwatchlist|linktosections}}",
+ "apihelp-feedwatchlist-example-default": "{{doc-apihelp-example|feedwatchlist}}",
+ "apihelp-feedwatchlist-example-all6hrs": "{{doc-apihelp-example|feedwatchlist}}",
+ "apihelp-filerevert-description": "{{doc-apihelp-description|filerevert}}",
+ "apihelp-filerevert-param-filename": "{{doc-apihelp-param|filerevert|filename}}",
+ "apihelp-filerevert-param-comment": "{{doc-apihelp-param|filerevert|comment}}",
+ "apihelp-filerevert-param-archivename": "{{doc-apihelp-param|filerevert|archivename}}",
+ "apihelp-filerevert-example-revert": "{{doc-apihelp-example|filerevert}}",
+ "apihelp-help-description": "{{doc-apihelp-description|help}}",
+ "apihelp-help-param-modules": "{{doc-apihelp-param|help|modules}}",
+ "apihelp-help-param-submodules": "{{doc-apihelp-param|help|submodules}}",
+ "apihelp-help-param-recursivesubmodules": "{{doc-apihelp-param|help|recursivesubmodules}}",
+ "apihelp-help-param-helpformat": "{{doc-apihelp-param|help|helpformat}}",
+ "apihelp-help-param-wrap": "{{doc-apihelp-param|help|wrap}}",
+ "apihelp-help-param-toc": "{{doc-apihelp-param|help|toc}}",
+ "apihelp-help-example-main": "{{doc-apihelp-example|help}}",
+ "apihelp-help-example-recursive": "{{doc-apihelp-example|help}}",
+ "apihelp-help-example-help": "{{doc-apihelp-example|help}}",
+ "apihelp-help-example-query": "{{doc-apihelp-example|help}}",
+ "apihelp-imagerotate-description": "{{doc-apihelp-description|imagerotate}}",
+ "apihelp-imagerotate-param-rotation": "{{doc-apihelp-param|imagerotate|rotation}}",
+ "apihelp-imagerotate-example-simple": "{{doc-apihelp-example|imagerotate}}",
+ "apihelp-imagerotate-example-generator": "{{doc-apihelp-example|imagerotate}}",
+ "apihelp-import-description": "{{doc-apihelp-description|import}}",
+ "apihelp-import-param-summary": "{{doc-apihelp-param|import|summary}}",
+ "apihelp-import-param-xml": "{{doc-apihelp-param|import|xml}}",
+ "apihelp-import-param-interwikisource": "{{doc-apihelp-param|import|interwikisource}}",
+ "apihelp-import-param-interwikipage": "{{doc-apihelp-param|import|interwikipage}}",
+ "apihelp-import-param-fullhistory": "{{doc-apihelp-param|import|fullhistory}}",
+ "apihelp-import-param-templates": "{{doc-apihelp-param|import|templates}}",
+ "apihelp-import-param-namespace": "{{doc-apihelp-param|import|namespace}}",
+ "apihelp-import-param-rootpage": "{{doc-apihelp-param|import|rootpage}}",
+ "apihelp-import-example-import": "{{doc-apihelp-example|import}}",
+ "apihelp-login-description": "{{doc-apihelp-description|login}}",
+ "apihelp-login-param-name": "{{doc-apihelp-param|login|name}}\n{{Identical|Username}}",
+ "apihelp-login-param-password": "{{doc-apihelp-param|login|password}}\n{{Identical|Password}}",
+ "apihelp-login-param-domain": "{{doc-apihelp-param|login|domain}}",
+ "apihelp-login-param-token": "{{doc-apihelp-param|login|token}}",
+ "apihelp-login-example-gettoken": "{{doc-apihelp-example|login}}",
+ "apihelp-login-example-login": "{{doc-apihelp-example|login}}",
+ "apihelp-logout-description": "{{doc-apihelp-description|logout}}",
+ "apihelp-logout-example-logout": "{{doc-apihelp-example|logout}}",
+ "apihelp-managetags-description": "{{doc-apihelp-description|managetags}}",
+ "apihelp-managetags-param-operation": "{{doc-apihelp-param|managetags|operation}}",
+ "apihelp-managetags-param-tag": "{{doc-apihelp-param|managetags|tag}}",
+ "apihelp-managetags-param-reason": "{{doc-apihelp-param|managetags|reason}}",
+ "apihelp-managetags-param-ignorewarnings": "{{doc-apihelp-param|managetags|ignorewarnings}}",
+ "apihelp-managetags-example-create": "{{doc-apihelp-example|managetags}}",
+ "apihelp-managetags-example-delete": "{{doc-apihelp-example|managetags|info={{doc-important|The text \"vandlaism\" in this message is intentionally misspelled; the example being documented by this message is the deletion of a misspelled tag.}}}}",
+ "apihelp-managetags-example-activate": "{{doc-apihelp-example|managetags}}",
+ "apihelp-managetags-example-deactivate": "{{doc-apihelp-example|managetags}}",
+ "apihelp-move-description": "{{doc-apihelp-description|move}}",
+ "apihelp-move-param-from": "{{doc-apihelp-param|move|from}}",
+ "apihelp-move-param-fromid": "{{doc-apihelp-param|move|fromid}}",
+ "apihelp-move-param-to": "{{doc-apihelp-param|move|to}}",
+ "apihelp-move-param-reason": "{{doc-apihelp-param|move|reason}}",
+ "apihelp-move-param-movetalk": "{{doc-apihelp-param|move|movetalk}}",
+ "apihelp-move-param-movesubpages": "{{doc-apihelp-param|move|movesubpages}}",
+ "apihelp-move-param-noredirect": "{{doc-apihelp-param|move|noredirect}}",
+ "apihelp-move-param-watch": "{{doc-apihelp-param|move|watch}}",
+ "apihelp-move-param-unwatch": "{{doc-apihelp-param|move|unwatch}}",
+ "apihelp-move-param-watchlist": "{{doc-apihelp-param|move|watchlist}}",
+ "apihelp-move-param-ignorewarnings": "{{doc-apihelp-param|move|ignorewarnings}}",
+ "apihelp-move-example-move": "{{doc-apihelp-example|move}}",
+ "apihelp-opensearch-description": "{{doc-apihelp-description|opensearch}}",
+ "apihelp-opensearch-param-search": "{{doc-apihelp-param|opensearch|search}}",
+ "apihelp-opensearch-param-limit": "{{doc-apihelp-param|opensearch|limit}}",
+ "apihelp-opensearch-param-namespace": "{{doc-apihelp-param|opensearch|namespace}}",
+ "apihelp-opensearch-param-suggest": "{{doc-apihelp-param|opensearch|suggest}}",
+ "apihelp-opensearch-param-redirects": "{{doc-apihelp-param|opensearch|redirects}}",
+ "apihelp-opensearch-param-format": "{{doc-apihelp-param|opensearch|format}}",
+ "apihelp-opensearch-param-warningsaserror": "{{doc-apihelp-param|opensearch|warningsaserror}}",
+ "apihelp-opensearch-example-te": "{{doc-apihelp-example|opensearch}}",
+ "apihelp-options-description": "{{doc-apihelp-description|options}}",
+ "apihelp-options-param-reset": "{{doc-apihelp-param|options|reset}}",
+ "apihelp-options-param-resetkinds": "{{doc-apihelp-param|options|resetkinds}}",
+ "apihelp-options-param-change": "{{doc-apihelp-param|options|change}}",
+ "apihelp-options-param-optionname": "{{doc-apihelp-param|options|optionname}}",
+ "apihelp-options-param-optionvalue": "{{doc-apihelp-param|options|optionvalue}}",
+ "apihelp-options-example-reset": "{{doc-apihelp-example|options}}",
+ "apihelp-options-example-change": "{{doc-apihelp-example|options}}",
+ "apihelp-options-example-complex": "{{doc-apihelp-example|options}}",
+ "apihelp-paraminfo-description": "{{doc-apihelp-description|paraminfo}}",
+ "apihelp-paraminfo-param-modules": "{{doc-apihelp-param|paraminfo|modules}}",
+ "apihelp-paraminfo-param-helpformat": "{{doc-apihelp-param|paraminfo|helpformat}}",
+ "apihelp-paraminfo-param-querymodules": "{{doc-apihelp-param|paraminfo|querymodules}}",
+ "apihelp-paraminfo-param-mainmodule": "{{doc-apihelp-param|paraminfo|mainmodule}}",
+ "apihelp-paraminfo-param-pagesetmodule": "{{doc-apihelp-param|paraminfo|pagesetmodule}}",
+ "apihelp-paraminfo-param-formatmodules": "{{doc-apihelp-param|paraminfo|formatmodules}}",
+ "apihelp-paraminfo-example-1": "{{doc-apihelp-example|paraminfo}}",
+ "apihelp-parse-description": "{{doc-apihelp-description|parse}}",
+ "apihelp-parse-param-title": "{{doc-apihelp-param|parse|title}}",
+ "apihelp-parse-param-text": "{{doc-apihelp-param|parse|text}}",
+ "apihelp-parse-param-summary": "{{doc-apihelp-param|parse|summary}}",
+ "apihelp-parse-param-page": "{{doc-apihelp-param|parse|page}}",
+ "apihelp-parse-param-pageid": "{{doc-apihelp-param|parse|pageid}}",
+ "apihelp-parse-param-redirects": "{{doc-apihelp-param|parse|redirects}}",
+ "apihelp-parse-param-oldid": "{{doc-apihelp-param|parse|oldid}}",
+ "apihelp-parse-param-prop": "{{doc-apihelp-param|parse|prop}}",
+ "apihelp-parse-param-pst": "{{doc-apihelp-param|parse|pst}}",
+ "apihelp-parse-param-onlypst": "{{doc-apihelp-param|parse|onlypst}}",
+ "apihelp-parse-param-effectivelanglinks": "{{doc-apihelp-param|parse|effectivelanglinks}}",
+ "apihelp-parse-param-section": "{{doc-apihelp-param|parse|section}}",
+ "apihelp-parse-param-sectiontitle": "{{doc-apihelp-param|parse|sectiontitle}}",
+ "apihelp-parse-param-disablepp": "{{doc-apihelp-param|parse|disablepp}}",
+ "apihelp-parse-param-disableeditsection": "{{doc-apihelp-param|parse|disableeditsection}}",
+ "apihelp-parse-param-generatexml": "{{doc-apihelp-param|parse|generatexml|params=* $1 - Value of the constant CONTENT_MODEL_WIKITEXT|paramstart=2}}",
+ "apihelp-parse-param-preview": "{{doc-apihelp-param|parse|preview}}",
+ "apihelp-parse-param-sectionpreview": "{{doc-apihelp-param|parse|sectionpreview}}",
+ "apihelp-parse-param-disabletoc": "{{doc-apihelp-param|parse|disabletoc}}",
+ "apihelp-parse-param-contentformat": "{{doc-apihelp-param|parse|contentformat}}",
+ "apihelp-parse-param-contentmodel": "{{doc-apihelp-param|parse|contentmodel}}",
+ "apihelp-parse-example-page": "{{doc-apihelp-example|parse}}",
+ "apihelp-parse-example-text": "{{doc-apihelp-example|parse}}",
+ "apihelp-parse-example-texttitle": "{{doc-apihelp-example|parse}}",
+ "apihelp-parse-example-summary": "{{doc-apihelp-example|parse}}",
+ "apihelp-patrol-description": "{{doc-apihelp-description|patrol}}",
+ "apihelp-patrol-param-rcid": "{{doc-apihelp-param|patrol|rcid}}",
+ "apihelp-patrol-param-revid": "{{doc-apihelp-param|patrol|revid}}",
+ "apihelp-patrol-example-rcid": "{{doc-apihelp-example|patrol}}",
+ "apihelp-patrol-example-revid": "{{doc-apihelp-example|patrol}}",
+ "apihelp-protect-description": "{{doc-apihelp-description|protect}}",
+ "apihelp-protect-param-title": "{{doc-apihelp-param|protect|title}}",
+ "apihelp-protect-param-pageid": "{{doc-apihelp-param|protect|pageid}}",
+ "apihelp-protect-param-protections": "{{doc-apihelp-param|protect|protections}}",
+ "apihelp-protect-param-expiry": "{{doc-apihelp-param|protect|expiry}}",
+ "apihelp-protect-param-reason": "{{doc-apihelp-param|protect|reason}}",
+ "apihelp-protect-param-cascade": "{{doc-apihelp-param|protect|cascade}}",
+ "apihelp-protect-param-watch": "{{doc-apihelp-param|protect|watch}}",
+ "apihelp-protect-param-watchlist": "{{doc-apihelp-param|protect|watchlist}}",
+ "apihelp-protect-example-protect": "{{doc-apihelp-example|protect}}",
+ "apihelp-protect-example-unprotect": "{{doc-apihelp-example|protect}}",
+ "apihelp-protect-example-unprotect2": "{{doc-apihelp-example|protect}}",
+ "apihelp-purge-description": "{{doc-apihelp-description|purge}}",
+ "apihelp-purge-param-forcelinkupdate": "{{doc-apihelp-param|purge|forcelinkupdate}}",
+ "apihelp-purge-param-forcerecursivelinkupdate": "{{doc-apihelp-param|purge|forcerecursivelinkupdate}}",
+ "apihelp-purge-example-simple": "{{doc-apihelp-example|purge}}",
+ "apihelp-purge-example-generator": "{{doc-apihelp-example|purge}}",
+ "apihelp-query-description": "{{doc-apihelp-description|query}}",
+ "apihelp-query-param-prop": "{{doc-apihelp-param|query|prop}}",
+ "apihelp-query-param-list": "{{doc-apihelp-param|query|list}}",
+ "apihelp-query-param-meta": "{{doc-apihelp-param|query|meta}}",
+ "apihelp-query-param-indexpageids": "{{doc-apihelp-param|query|indexpageids}}",
+ "apihelp-query-param-export": "{{doc-apihelp-param|query|export}}",
+ "apihelp-query-param-exportnowrap": "{{doc-apihelp-param|query|exportnowrap}}",
+ "apihelp-query-param-iwurl": "{{doc-apihelp-param|query|iwurl}}",
+ "apihelp-query-param-continue": "{{doc-apihelp-param|query|continue}}",
+ "apihelp-query-param-rawcontinue": "{{doc-apihelp-param|query|rawcontinue}}",
+ "apihelp-query-example-revisions": "{{doc-apihelp-example|query}}",
+ "apihelp-query-example-allpages": "{{doc-apihelp-example|query}}",
+ "apihelp-query+allcategories-description": "{{doc-apihelp-description|query+allcategories}}",
+ "apihelp-query+allcategories-param-from": "{{doc-apihelp-param|query+allcategories|from}}",
+ "apihelp-query+allcategories-param-to": "{{doc-apihelp-param|query+allcategories|to}}",
+ "apihelp-query+allcategories-param-prefix": "{{doc-apihelp-param|query+allcategories|prefix}}",
+ "apihelp-query+allcategories-param-dir": "{{doc-apihelp-param|query+allcategories|dir}}",
+ "apihelp-query+allcategories-param-min": "{{doc-apihelp-param|query+allcategories|min}}",
+ "apihelp-query+allcategories-param-max": "{{doc-apihelp-param|query+allcategories|max}}",
+ "apihelp-query+allcategories-param-limit": "{{doc-apihelp-param|query+allcategories|limit}}",
+ "apihelp-query+allcategories-param-prop": "{{doc-apihelp-param|query+allcategories|prop}}",
+ "apihelp-query+allcategories-example-size": "{{doc-apihelp-example|query+allcategories}}",
+ "apihelp-query+allcategories-example-generator": "{{doc-apihelp-example|query+allcategories}}",
+ "apihelp-query+alldeletedrevisions-description": "{{doc-apihelp-description|query+alldeletedrevisions}}",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "{{doc-apihelp-paraminfo|query+alldeletedrevisions|useronly}}",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "{{doc-apihelp-paraminfo|query+alldeletedrevisions|nonuseronly}}",
+ "apihelp-query+alldeletedrevisions-param-start": "{{doc-apihelp-param|query+alldeletedrevisions|start}}",
+ "apihelp-query+alldeletedrevisions-param-end": "{{doc-apihelp-param|query+alldeletedrevisions|end}}",
+ "apihelp-query+alldeletedrevisions-param-from": "{{doc-apihelp-param|query+alldeletedrevisions|from}}",
+ "apihelp-query+alldeletedrevisions-param-to": "{{doc-apihelp-param|query+alldeletedrevisions|to}}",
+ "apihelp-query+alldeletedrevisions-param-prefix": "{{doc-apihelp-param|query+alldeletedrevisions|prefix}}",
+ "apihelp-query+alldeletedrevisions-param-tag": "{{doc-apihelp-param|query+alldeletedrevisions|tag}}",
+ "apihelp-query+alldeletedrevisions-param-user": "{{doc-apihelp-param|query+alldeletedrevisions|user}}",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "{{doc-apihelp-param|query+alldeletedrevisions|excludeuser}}",
+ "apihelp-query+alldeletedrevisions-param-namespace": "{{doc-apihelp-param|query+alldeletedrevisions|namespace}}",
+ "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "{{doc-apihelp-param|query+alldeletedrevisions|miser-user-namespace}}",
+ "apihelp-query+alldeletedrevisions-param-generatetitles": "{{doc-apihelp-param|query+alldeletedrevisions|generatetitles}}",
+ "apihelp-query+alldeletedrevisions-example-user": "{{doc-apihelp-example|query+alldeletedrevisions}}",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "{{doc-apihelp-example|query+alldeletedrevisions}}",
+ "apihelp-query+allfileusages-description": "{{doc-apihelp-description|query+allfileusages}}",
+ "apihelp-query+allfileusages-param-from": "{{doc-apihelp-param|query+allfileusages|from}}",
+ "apihelp-query+allfileusages-param-to": "{{doc-apihelp-param|query+allfileusages|to}}",
+ "apihelp-query+allfileusages-param-prefix": "{{doc-apihelp-param|query+allfileusages|prefix}}",
+ "apihelp-query+allfileusages-param-unique": "{{doc-apihelp-param|query+allfileusages|unique}}",
+ "apihelp-query+allfileusages-param-prop": "{{doc-apihelp-param|query+allfileusages|prop}}",
+ "apihelp-query+allfileusages-param-limit": "{{doc-apihelp-param|query+allfileusages|limit}}",
+ "apihelp-query+allfileusages-param-dir": "{{doc-apihelp-param|query+allfileusages|dir}}",
+ "apihelp-query+allfileusages-example-B": "{{doc-apihelp-example|query+allfileusages}}",
+ "apihelp-query+allfileusages-example-unique": "{{doc-apihelp-example|query+allfileusages}}",
+ "apihelp-query+allfileusages-example-unique-generator": "{{doc-apihelp-example|query+allfileusages}}",
+ "apihelp-query+allfileusages-example-generator": "{{doc-apihelp-example|query+allfileusages}}",
+ "apihelp-query+allimages-description": "{{doc-apihelp-description|query+allimages}}",
+ "apihelp-query+allimages-param-sort": "{{doc-apihelp-param|query+allimages|sort}}",
+ "apihelp-query+allimages-param-dir": "{{doc-apihelp-param|query+allimages|dir}}",
+ "apihelp-query+allimages-param-from": "{{doc-apihelp-param|query+allimages|from}}",
+ "apihelp-query+allimages-param-to": "{{doc-apihelp-param|query+allimages|to}}",
+ "apihelp-query+allimages-param-start": "{{doc-apihelp-param|query+allimages|start}}",
+ "apihelp-query+allimages-param-end": "{{doc-apihelp-param|query+allimages|end}}",
+ "apihelp-query+allimages-param-prefix": "{{doc-apihelp-param|query+allimages|prefix}}",
+ "apihelp-query+allimages-param-minsize": "{{doc-apihelp-param|query+allimages|minsize}}",
+ "apihelp-query+allimages-param-maxsize": "{{doc-apihelp-param|query+allimages|maxsize}}",
+ "apihelp-query+allimages-param-sha1": "{{doc-apihelp-param|query+allimages|sha1}}",
+ "apihelp-query+allimages-param-sha1base36": "{{doc-apihelp-param|query+allimages|sha1base36}}",
+ "apihelp-query+allimages-param-user": "{{doc-apihelp-param|query+allimages|user}}",
+ "apihelp-query+allimages-param-filterbots": "{{doc-apihelp-param|query+allimages|filterbots}}",
+ "apihelp-query+allimages-param-mime": "{{doc-apihelp-param|query+allimages|mime}}",
+ "apihelp-query+allimages-param-limit": "{{doc-apihelp-param|query+allimages|limit}}",
+ "apihelp-query+allimages-example-B": "{{doc-apihelp-example|query+allimages}}",
+ "apihelp-query+allimages-example-recent": "{{doc-apihelp-example|query+allimages}}",
+ "apihelp-query+allimages-example-mimetypes": "{{doc-apihelp-example|query+allimages}}",
+ "apihelp-query+allimages-example-generator": "{{doc-apihelp-example|query+allimages}}",
+ "apihelp-query+alllinks-description": "{{doc-apihelp-description|query+alllinks}}",
+ "apihelp-query+alllinks-param-from": "{{doc-apihelp-param|query+alllinks|from}}",
+ "apihelp-query+alllinks-param-to": "{{doc-apihelp-param|query+alllinks|to}}",
+ "apihelp-query+alllinks-param-prefix": "{{doc-apihelp-param|query+alllinks|prefix}}",
+ "apihelp-query+alllinks-param-unique": "{{doc-apihelp-param|query+alllinks|unique}}",
+ "apihelp-query+alllinks-param-prop": "{{doc-apihelp-param|query+alllinks|prop}}",
+ "apihelp-query+alllinks-param-namespace": "{{doc-apihelp-param|query+alllinks|namespace}}",
+ "apihelp-query+alllinks-param-limit": "{{doc-apihelp-param|query+alllinks|limit}}",
+ "apihelp-query+alllinks-param-dir": "{{doc-apihelp-param|query+alllinks|dir}}",
+ "apihelp-query+alllinks-example-B": "{{doc-apihelp-example|query+alllinks}}",
+ "apihelp-query+alllinks-example-unique": "{{doc-apihelp-example|query+alllinks}}",
+ "apihelp-query+alllinks-example-unique-generator": "{{doc-apihelp-example|query+alllinks}}",
+ "apihelp-query+alllinks-example-generator": "{{doc-apihelp-example|query+alllinks}}",
+ "apihelp-query+allmessages-description": "{{doc-apihelp-description|query+allmessages}}",
+ "apihelp-query+allmessages-param-messages": "{{doc-apihelp-param|query+allmessages|messages}}",
+ "apihelp-query+allmessages-param-prop": "{{doc-apihelp-param|query+allmessages|prop}}",
+ "apihelp-query+allmessages-param-enableparser": "{{doc-apihelp-param|query+allmessages|enableparser}}",
+ "apihelp-query+allmessages-param-nocontent": "{{doc-apihelp-param|query+allmessages|nocontent}}",
+ "apihelp-query+allmessages-param-includelocal": "{{doc-apihelp-param|query+allmessages|includelocal}}",
+ "apihelp-query+allmessages-param-args": "{{doc-apihelp-param|query+allmessages|args}}",
+ "apihelp-query+allmessages-param-filter": "{{doc-apihelp-param|query+allmessages|filter}}",
+ "apihelp-query+allmessages-param-customised": "{{doc-apihelp-param|query+allmessages|customised}}",
+ "apihelp-query+allmessages-param-lang": "{{doc-apihelp-param|query+allmessages|lang}}",
+ "apihelp-query+allmessages-param-from": "{{doc-apihelp-param|query+allmessages|from}}",
+ "apihelp-query+allmessages-param-to": "{{doc-apihelp-param|query+allmessages|to}}",
+ "apihelp-query+allmessages-param-title": "{{doc-apihelp-param|query+allmessages|title}}",
+ "apihelp-query+allmessages-param-prefix": "{{doc-apihelp-param|query+allmessages|prefix}}",
+ "apihelp-query+allmessages-example-ipb": "{{doc-apihelp-example|query+allmessages}}",
+ "apihelp-query+allmessages-example-de": "{{doc-apihelp-example|query+allmessages}}",
+ "apihelp-query+allpages-description": "{{doc-apihelp-description|query+allpages}}",
+ "apihelp-query+allpages-param-from": "{{doc-apihelp-param|query+allpages|from}}",
+ "apihelp-query+allpages-param-to": "{{doc-apihelp-param|query+allpages|to}}",
+ "apihelp-query+allpages-param-prefix": "{{doc-apihelp-param|query+allpages|prefix}}",
+ "apihelp-query+allpages-param-namespace": "{{doc-apihelp-param|query+allpages|namespace}}",
+ "apihelp-query+allpages-param-filterredir": "{{doc-apihelp-param|query+allpages|filterredir}}",
+ "apihelp-query+allpages-param-minsize": "{{doc-apihelp-param|query+allpages|minsize}}",
+ "apihelp-query+allpages-param-maxsize": "{{doc-apihelp-param|query+allpages|maxsize}}",
+ "apihelp-query+allpages-param-prtype": "{{doc-apihelp-param|query+allpages|prtype}}",
+ "apihelp-query+allpages-param-prlevel": "{{doc-apihelp-param|query+allpages|prlevel}}",
+ "apihelp-query+allpages-param-prfiltercascade": "{{doc-apihelp-param|query+allpages|prfiltercascade}}",
+ "apihelp-query+allpages-param-limit": "{{doc-apihelp-param|query+allpages|limit}}",
+ "apihelp-query+allpages-param-dir": "{{doc-apihelp-param|query+allpages|dir}}",
+ "apihelp-query+allpages-param-filterlanglinks": "{{doc-apihelp-param|query+allpages|filterlanglinks}}",
+ "apihelp-query+allpages-param-prexpiry": "{{doc-apihelp-param|query+allpages|prexpiry}}",
+ "apihelp-query+allpages-example-B": "{{doc-apihelp-example|query+allpages}}",
+ "apihelp-query+allpages-example-generator": "{{doc-apihelp-example|query+allpages}}",
+ "apihelp-query+allpages-example-generator-revisions": "{{doc-apihelp-example|query+allpages}}",
+ "apihelp-query+allredirects-description": "{{doc-apihelp-description|query+allredirects}}",
+ "apihelp-query+allredirects-param-from": "{{doc-apihelp-param|query+allredirects|from}}",
+ "apihelp-query+allredirects-param-to": "{{doc-apihelp-param|query+allredirects|to}}",
+ "apihelp-query+allredirects-param-prefix": "{{doc-apihelp-param|query+allredirects|prefix}}",
+ "apihelp-query+allredirects-param-unique": "{{doc-apihelp-param|query+allredirects|unique}}",
+ "apihelp-query+allredirects-param-prop": "{{doc-apihelp-param|query+allredirects|prop}}",
+ "apihelp-query+allredirects-param-namespace": "{{doc-apihelp-param|query+allredirects|namespace}}",
+ "apihelp-query+allredirects-param-limit": "{{doc-apihelp-param|query+allredirects|limit}}",
+ "apihelp-query+allredirects-param-dir": "{{doc-apihelp-param|query+allredirects|dir}}",
+ "apihelp-query+allredirects-example-B": "{{doc-apihelp-example|query+allredirects}}",
+ "apihelp-query+allredirects-example-unique": "{{doc-apihelp-example|query+allredirects}}",
+ "apihelp-query+allredirects-example-unique-generator": "{{doc-apihelp-example|query+allredirects}}",
+ "apihelp-query+allredirects-example-generator": "{{doc-apihelp-example|query+allredirects}}",
+ "apihelp-query+alltransclusions-description": "{{doc-apihelp-description|query+alltransclusions}}",
+ "apihelp-query+alltransclusions-param-from": "{{doc-apihelp-param|query+alltransclusions|from}}",
+ "apihelp-query+alltransclusions-param-to": "{{doc-apihelp-param|query+alltransclusions|to}}",
+ "apihelp-query+alltransclusions-param-prefix": "{{doc-apihelp-param|query+alltransclusions|prefix}}",
+ "apihelp-query+alltransclusions-param-unique": "{{doc-apihelp-param|query+alltransclusions|unique}}",
+ "apihelp-query+alltransclusions-param-prop": "{{doc-apihelp-param|query+alltransclusions|prop}}",
+ "apihelp-query+alltransclusions-param-namespace": "{{doc-apihelp-param|query+alltransclusions|namespace}}",
+ "apihelp-query+alltransclusions-param-limit": "{{doc-apihelp-param|query+alltransclusions|limit}}",
+ "apihelp-query+alltransclusions-param-dir": "{{doc-apihelp-param|query+alltransclusions|dir}}",
+ "apihelp-query+alltransclusions-example-B": "{{doc-apihelp-example|query+alltransclusions}}",
+ "apihelp-query+alltransclusions-example-unique": "{{doc-apihelp-example|query+alltransclusions}}",
+ "apihelp-query+alltransclusions-example-unique-generator": "{{doc-apihelp-example|query+alltransclusions}}",
+ "apihelp-query+alltransclusions-example-generator": "{{doc-apihelp-example|query+alltransclusions}}",
+ "apihelp-query+allusers-description": "{{doc-apihelp-description|query+allusers}}",
+ "apihelp-query+allusers-param-from": "{{doc-apihelp-param|query+allusers|from}}",
+ "apihelp-query+allusers-param-to": "{{doc-apihelp-param|query+allusers|to}}",
+ "apihelp-query+allusers-param-prefix": "{{doc-apihelp-param|query+allusers|prefix}}",
+ "apihelp-query+allusers-param-dir": "{{doc-apihelp-param|query+allusers|dir}}",
+ "apihelp-query+allusers-param-group": "{{doc-apihelp-param|query+allusers|group}}",
+ "apihelp-query+allusers-param-excludegroup": "{{doc-apihelp-param|query+allusers|excludegroup}}",
+ "apihelp-query+allusers-param-rights": "{{doc-apihelp-param|query+allusers|rights}}",
+ "apihelp-query+allusers-param-prop": "{{doc-apihelp-param|query+allusers|prop}}",
+ "apihelp-query+allusers-param-limit": "{{doc-apihelp-param|query+allusers|limit}}",
+ "apihelp-query+allusers-param-witheditsonly": "{{doc-apihelp-param|query+allusers|witheditsonly}}",
+ "apihelp-query+allusers-param-activeusers": "{{doc-apihelp-param|query+allusers|activeusers|params=* $1 - Value of [[mw:Manual:$wgActiveUserDays]]|paramstart=2}}",
+ "apihelp-query+allusers-example-Y": "{{doc-apihelp-example|query+allusers}}",
+ "apihelp-query+backlinks-description": "{{doc-apihelp-description|query+backlinks}}",
+ "apihelp-query+backlinks-param-title": "{{doc-apihelp-param|query+backlinks|title}}",
+ "apihelp-query+backlinks-param-pageid": "{{doc-apihelp-param|query+backlinks|pageid}}",
+ "apihelp-query+backlinks-param-namespace": "{{doc-apihelp-param|query+backlinks|namespace}}",
+ "apihelp-query+backlinks-param-dir": "{{doc-apihelp-param|query+backlinks|dir}}",
+ "apihelp-query+backlinks-param-filterredir": "{{doc-apihelp-param|query+backlinks|filterredir}}",
+ "apihelp-query+backlinks-param-limit": "{{doc-apihelp-param|query+backlinks|limit}}",
+ "apihelp-query+backlinks-param-redirect": "{{doc-apihelp-param|query+backlinks|redirect}}",
+ "apihelp-query+backlinks-example-simple": "{{doc-apihelp-example|query+backlinks}}",
+ "apihelp-query+backlinks-example-generator": "{{doc-apihelp-example|query+backlinks}}",
+ "apihelp-query+blocks-description": "{{doc-apihelp-description|query+blocks}}",
+ "apihelp-query+blocks-param-start": "{{doc-apihelp-param|query+blocks|start}}",
+ "apihelp-query+blocks-param-end": "{{doc-apihelp-param|query+blocks|end}}",
+ "apihelp-query+blocks-param-ids": "{{doc-apihelp-param|query+blocks|ids}}",
+ "apihelp-query+blocks-param-users": "{{doc-apihelp-param|query+blocks|users}}",
+ "apihelp-query+blocks-param-ip": "{{doc-apihelp-param|query+blocks|ip|params=* $1 - Minimum CIDR prefix for IPv4\n* $2 - Minimum CIDR prefix for IPv6|paramstart=3}}",
+ "apihelp-query+blocks-param-limit": "{{doc-apihelp-param|query+blocks|limit}}",
+ "apihelp-query+blocks-param-prop": "{{doc-apihelp-param|query+blocks|prop}}",
+ "apihelp-query+blocks-param-show": "{{doc-apihelp-param|query+blocks|show}}",
+ "apihelp-query+blocks-example-simple": "{{doc-apihelp-example|query+blocks}}",
+ "apihelp-query+blocks-example-users": "{{doc-apihelp-example|query+blocks}}",
+ "apihelp-query+categories-description": "{{doc-apihelp-description|query+categories}}",
+ "apihelp-query+categories-param-prop": "{{doc-apihelp-param|query+categories|prop}}",
+ "apihelp-query+categories-param-show": "{{doc-apihelp-param|query+categories|show}}",
+ "apihelp-query+categories-param-limit": "{{doc-apihelp-param|query+categories|limit}}",
+ "apihelp-query+categories-param-categories": "{{doc-apihelp-param|query+categories|categories}}",
+ "apihelp-query+categories-param-dir": "{{doc-apihelp-param|query+categories|dir}}",
+ "apihelp-query+categories-example-simple": "{{doc-apihelp-example|query+categories}}",
+ "apihelp-query+categories-example-generator": "{{doc-apihelp-example|query+categories}}",
+ "apihelp-query+categoryinfo-description": "{{doc-apihelp-description|query+categoryinfo}}",
+ "apihelp-query+categoryinfo-example-simple": "{{doc-apihelp-example|query+categoryinfo}}",
+ "apihelp-query+categorymembers-description": "{{doc-apihelp-description|query+categorymembers}}",
+ "apihelp-query+categorymembers-param-title": "{{doc-apihelp-param|query+categorymembers|title}}",
+ "apihelp-query+categorymembers-param-pageid": "{{doc-apihelp-param|query+categorymembers|pageid}}",
+ "apihelp-query+categorymembers-param-prop": "{{doc-apihelp-param|query+categorymembers|prop}}",
+ "apihelp-query+categorymembers-param-namespace": "{{doc-apihelp-param|query+categorymembers|namespace}}",
+ "apihelp-query+categorymembers-param-type": "{{doc-apihelp-param|query+categorymembers|type}}",
+ "apihelp-query+categorymembers-param-limit": "{{doc-apihelp-param|query+categorymembers|limit}}",
+ "apihelp-query+categorymembers-param-sort": "{{doc-apihelp-param|query+categorymembers|sort}}",
+ "apihelp-query+categorymembers-param-dir": "{{doc-apihelp-param|query+categorymembers|dir}}",
+ "apihelp-query+categorymembers-param-start": "{{doc-apihelp-param|query+categorymembers|start}}",
+ "apihelp-query+categorymembers-param-end": "{{doc-apihelp-param|query+categorymembers|end}}",
+ "apihelp-query+categorymembers-param-starthexsortkey": "{{doc-apihelp-param|query+categorymembers|starthexsortkey}}",
+ "apihelp-query+categorymembers-param-endhexsortkey": "{{doc-apihelp-param|query+categorymembers|endhexsortkey}}",
+ "apihelp-query+categorymembers-param-startsortkeyprefix": "{{doc-apihelp-param|query+categorymembers|startsortkeyprefix}}",
+ "apihelp-query+categorymembers-param-endsortkeyprefix": "{{doc-apihelp-param|query+categorymembers|endsortkeyprefix}}",
+ "apihelp-query+categorymembers-param-startsortkey": "{{doc-apihelp-param|query+categorymembers|startsortkey}}",
+ "apihelp-query+categorymembers-param-endsortkey": "{{doc-apihelp-param|query+categorymembers|endsortkey}}",
+ "apihelp-query+categorymembers-example-simple": "{{doc-apihelp-example|query+categorymembers}}",
+ "apihelp-query+categorymembers-example-generator": "{{doc-apihelp-example|query+categorymembers}}",
+ "apihelp-query+contributors-description": "{{doc-apihelp-description|query+contributors}}",
+ "apihelp-query+contributors-param-group": "{{doc-apihelp-param|query+contributors|group}}",
+ "apihelp-query+contributors-param-excludegroup": "{{doc-apihelp-param|query+contributors|excludegroup}}",
+ "apihelp-query+contributors-param-rights": "{{doc-apihelp-param|query+contributors|rights}}",
+ "apihelp-query+contributors-param-excluderights": "{{doc-apihelp-param|query+contributors|excluderights}}",
+ "apihelp-query+contributors-param-limit": "{{doc-apihelp-param|query+contributors|limit}}",
+ "apihelp-query+contributors-example-simple": "{{doc-apihelp-example|query+contributors}}",
+ "apihelp-query+deletedrevisions-description": "{{doc-apihelp-description|query+deletedrevisions}}",
+ "apihelp-query+deletedrevisions-param-start": "{{doc-apihelp-param|query+deletedrevisions|start}}",
+ "apihelp-query+deletedrevisions-param-end": "{{doc-apihelp-param|query+deletedrevisions|end}}",
+ "apihelp-query+deletedrevisions-param-tag": "{{doc-apihelp-param|query+deletedrevisions|tag}}",
+ "apihelp-query+deletedrevisions-param-user": "{{doc-apihelp-param|query+deletedrevisions|user}}",
+ "apihelp-query+deletedrevisions-param-excludeuser": "{{doc-apihelp-param|query+deletedrevisions|excludeuser}}",
+ "apihelp-query+deletedrevisions-param-limit": "{{doc-apihelp-param|query+deletedrevisions|limit}}",
+ "apihelp-query+deletedrevisions-param-prop": "{{doc-apihelp-param|query+deletedrevisions|prop}}",
+ "apihelp-query+deletedrevisions-example-titles": "{{doc-apihelp-example|query+deletedrevisions}}",
+ "apihelp-query+deletedrevisions-example-revids": "{{doc-apihelp-example|query+deletedrevisions}}",
+ "apihelp-query+deletedrevs-description": "{{doc-apihelp-description|query+deletedrevs}}",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{doc-apihelp-paraminfo|query+deletedrevs|modes}}\n{{Identical|Mode}}",
+ "apihelp-query+deletedrevs-param-start": "{{doc-apihelp-param|query+deletedrevs|start}}",
+ "apihelp-query+deletedrevs-param-end": "{{doc-apihelp-param|query+deletedrevs|end}}",
+ "apihelp-query+deletedrevs-param-from": "{{doc-apihelp-param|query+deletedrevs|from}}",
+ "apihelp-query+deletedrevs-param-to": "{{doc-apihelp-param|query+deletedrevs|to}}",
+ "apihelp-query+deletedrevs-param-prefix": "{{doc-apihelp-param|query+deletedrevs|prefix}}",
+ "apihelp-query+deletedrevs-param-unique": "{{doc-apihelp-param|query+deletedrevs|unique}}",
+ "apihelp-query+deletedrevs-param-tag": "{{doc-apihelp-param|query+deletedrevs|tag}}",
+ "apihelp-query+deletedrevs-param-user": "{{doc-apihelp-param|query+deletedrevs|user}}",
+ "apihelp-query+deletedrevs-param-excludeuser": "{{doc-apihelp-param|query+deletedrevs|excludeuser}}",
+ "apihelp-query+deletedrevs-param-namespace": "{{doc-apihelp-param|query+deletedrevs|namespace}}",
+ "apihelp-query+deletedrevs-param-limit": "{{doc-apihelp-param|query+deletedrevs|limit}}",
+ "apihelp-query+deletedrevs-param-prop": "{{doc-apihelp-param|query+deletedrevs|prop}}",
+ "apihelp-query+deletedrevs-example-mode1": "{{doc-apihelp-example|query+deletedrevs}}",
+ "apihelp-query+deletedrevs-example-mode2": "{{doc-apihelp-example|query+deletedrevs}}",
+ "apihelp-query+deletedrevs-example-mode3-main": "{{doc-apihelp-example|query+deletedrevs}}",
+ "apihelp-query+deletedrevs-example-mode3-talk": "{{doc-apihelp-example|query+deletedrevs}}",
+ "apihelp-query+disabled-description": "{{doc-apihelp-description|query+disabled}}",
+ "apihelp-query+duplicatefiles-description": "{{doc-apihelp-description|query+duplicatefiles}}",
+ "apihelp-query+duplicatefiles-param-limit": "{{doc-apihelp-param|query+duplicatefiles|limit}}",
+ "apihelp-query+duplicatefiles-param-dir": "{{doc-apihelp-param|query+duplicatefiles|dir}}",
+ "apihelp-query+duplicatefiles-param-localonly": "{{doc-apihelp-param|query+duplicatefiles|localonly}}",
+ "apihelp-query+duplicatefiles-example-simple": "{{doc-apihelp-example|query+duplicatefiles}}",
+ "apihelp-query+duplicatefiles-example-generated": "{{doc-apihelp-example|query+duplicatefiles}}",
+ "apihelp-query+embeddedin-description": "{{doc-apihelp-description|query+embeddedin}}",
+ "apihelp-query+embeddedin-param-title": "{{doc-apihelp-param|query+embeddedin|title}}",
+ "apihelp-query+embeddedin-param-pageid": "{{doc-apihelp-param|query+embeddedin|pageid}}",
+ "apihelp-query+embeddedin-param-namespace": "{{doc-apihelp-param|query+embeddedin|namespace}}",
+ "apihelp-query+embeddedin-param-dir": "{{doc-apihelp-param|query+embeddedin|dir}}",
+ "apihelp-query+embeddedin-param-filterredir": "{{doc-apihelp-param|query+embeddedin|filterredir}}",
+ "apihelp-query+embeddedin-param-limit": "{{doc-apihelp-param|query+embeddedin|limit}}",
+ "apihelp-query+embeddedin-example-simple": "{{doc-apihelp-example|query+embeddedin}}",
+ "apihelp-query+embeddedin-example-generator": "{{doc-apihelp-example|query+embeddedin}}",
+ "apihelp-query+extlinks-description": "{{doc-apihelp-description|query+extlinks}}",
+ "apihelp-query+extlinks-param-limit": "{{doc-apihelp-param|query+extlinks|limit}}",
+ "apihelp-query+extlinks-param-protocol": "{{doc-apihelp-param|query+extlinks|protocol}}",
+ "apihelp-query+extlinks-param-query": "{{doc-apihelp-param|query+extlinks|query}}",
+ "apihelp-query+extlinks-param-expandurl": "{{doc-apihelp-param|query+extlinks|expandurl}}",
+ "apihelp-query+extlinks-example-simple": "{{doc-apihelp-example|query+extlinks}}",
+ "apihelp-query+exturlusage-description": "{{doc-apihelp-description|query+exturlusage}}",
+ "apihelp-query+exturlusage-param-prop": "{{doc-apihelp-param|query+exturlusage|prop}}",
+ "apihelp-query+exturlusage-param-protocol": "{{doc-apihelp-param|query+exturlusage|protocol}}",
+ "apihelp-query+exturlusage-param-query": "{{doc-apihelp-param|query+exturlusage|query}}",
+ "apihelp-query+exturlusage-param-namespace": "{{doc-apihelp-param|query+exturlusage|namespace}}",
+ "apihelp-query+exturlusage-param-limit": "{{doc-apihelp-param|query+exturlusage|limit}}",
+ "apihelp-query+exturlusage-param-expandurl": "{{doc-apihelp-param|query+exturlusage|expandurl}}",
+ "apihelp-query+exturlusage-example-simple": "{{doc-apihelp-example|query+exturlusage}}",
+ "apihelp-query+filearchive-description": "{{doc-apihelp-description|query+filearchive}}",
+ "apihelp-query+filearchive-param-from": "{{doc-apihelp-param|query+filearchive|from}}",
+ "apihelp-query+filearchive-param-to": "{{doc-apihelp-param|query+filearchive|to}}",
+ "apihelp-query+filearchive-param-prefix": "{{doc-apihelp-param|query+filearchive|prefix}}",
+ "apihelp-query+filearchive-param-limit": "{{doc-apihelp-param|query+filearchive|limit}}",
+ "apihelp-query+filearchive-param-dir": "{{doc-apihelp-param|query+filearchive|dir}}",
+ "apihelp-query+filearchive-param-sha1": "{{doc-apihelp-param|query+filearchive|sha1}}",
+ "apihelp-query+filearchive-param-sha1base36": "{{doc-apihelp-param|query+filearchive|sha1base36}}",
+ "apihelp-query+filearchive-param-prop": "{{doc-apihelp-param|query+filearchive|prop}}",
+ "apihelp-query+filearchive-example-simple": "{{doc-apihelp-example|query+filearchive}}",
+ "apihelp-query+filerepoinfo-description": "{{doc-apihelp-description|query+filerepoinfo}}",
+ "apihelp-query+filerepoinfo-param-prop": "{{doc-apihelp-param|query+filerepoinfo|prop}}",
+ "apihelp-query+filerepoinfo-example-simple": "{{doc-apihelp-example|query+filerepoinfo}}",
+ "apihelp-query+fileusage-description": "{{doc-apihelp-description|query+fileusage}}",
+ "apihelp-query+fileusage-param-prop": "{{doc-apihelp-param|query+fileusage|prop}}",
+ "apihelp-query+fileusage-param-namespace": "{{doc-apihelp-param|query+fileusage|namespace}}",
+ "apihelp-query+fileusage-param-limit": "{{doc-apihelp-param|query+fileusage|limit}}",
+ "apihelp-query+fileusage-param-show": "{{doc-apihelp-param|query+fileusage|show}}",
+ "apihelp-query+fileusage-example-simple": "{{doc-apihelp-example|query+fileusage}}",
+ "apihelp-query+fileusage-example-generator": "{{doc-apihelp-example|query+fileusage}}",
+ "apihelp-query+imageinfo-description": "{{doc-apihelp-description|query+imageinfo}}",
+ "apihelp-query+imageinfo-param-prop": "{{doc-apihelp-param|query+imageinfo|prop|paramvalues=1}}",
+ "apihelp-query+imageinfo-paramvalue-prop-timestamp": "{{doc-apihelp-paramvalue|query+imageinfo|prop|timestamp}}",
+ "apihelp-query+imageinfo-paramvalue-prop-user": "{{doc-apihelp-paramvalue|query+imageinfo|prop|user}}",
+ "apihelp-query+imageinfo-paramvalue-prop-userid": "{{doc-apihelp-paramvalue|query+imageinfo|prop|userid}}",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "{{doc-apihelp-paramvalue|query+imageinfo|prop|comment}}",
+ "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "{{doc-apihelp-paramvalue|query+imageinfo|prop|parsedcomment}}",
+ "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "{{doc-apihelp-paramvalue|query+imageinfo|prop|canonicaltitle}}",
+ "apihelp-query+imageinfo-paramvalue-prop-url": "{{doc-apihelp-paramvalue|query+imageinfo|prop|url}}",
+ "apihelp-query+imageinfo-paramvalue-prop-size": "{{doc-apihelp-paramvalue|query+imageinfo|prop|size}}",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "{{doc-apihelp-paramvalue|query+imageinfo|prop|dimensions}}",
+ "apihelp-query+imageinfo-paramvalue-prop-sha1": "{{doc-apihelp-paramvalue|query+imageinfo|prop|sha1}}",
+ "apihelp-query+imageinfo-paramvalue-prop-mime": "{{doc-apihelp-paramvalue|query+imageinfo|prop|mime}}",
+ "apihelp-query+imageinfo-paramvalue-prop-thumbmime": "{{doc-apihelp-paramvalue|query+imageinfo|prop|thumbmime}}",
+ "apihelp-query+imageinfo-paramvalue-prop-mediatype": "{{doc-apihelp-paramvalue|query+imageinfo|prop|mediatype}}",
+ "apihelp-query+imageinfo-paramvalue-prop-metadata": "{{doc-apihelp-paramvalue|query+imageinfo|prop|metadata}}",
+ "apihelp-query+imageinfo-paramvalue-prop-commonmetadata": "{{doc-apihelp-paramvalue|query+imageinfo|prop|commonmetadata}}",
+ "apihelp-query+imageinfo-paramvalue-prop-extmetadata": "{{doc-apihelp-paramvalue|query+imageinfo|prop|extmetadata}}",
+ "apihelp-query+imageinfo-paramvalue-prop-archivename": "{{doc-apihelp-paramvalue|query+imageinfo|prop|archivename}}",
+ "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "{{doc-apihelp-paramvalue|query+imageinfo|prop|bitdepth}}",
+ "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "{{doc-apihelp-paramvalue|query+imageinfo|prop|uploadwarning}}",
+ "apihelp-query+imageinfo-param-limit": "{{doc-apihelp-param|query+imageinfo|limit}}",
+ "apihelp-query+imageinfo-param-start": "{{doc-apihelp-param|query+imageinfo|start}}",
+ "apihelp-query+imageinfo-param-end": "{{doc-apihelp-param|query+imageinfo|end}}",
+ "apihelp-query+imageinfo-param-urlwidth": "{{doc-apihelp-param|query+imageinfo|urlwidth|params=* $1 - Maximum number of thumbnails per query|paramstart=2}}",
+ "apihelp-query+imageinfo-param-urlheight": "{{doc-apihelp-param|query+imageinfo|urlheight}}",
+ "apihelp-query+imageinfo-param-metadataversion": "{{doc-apihelp-param|query+imageinfo|metadataversion}}",
+ "apihelp-query+imageinfo-param-extmetadatalanguage": "{{doc-apihelp-param|query+imageinfo|extmetadatalanguage}}",
+ "apihelp-query+imageinfo-param-extmetadatamultilang": "{{doc-apihelp-param|query+imageinfo|extmetadatamultilang}}",
+ "apihelp-query+imageinfo-param-extmetadatafilter": "{{doc-apihelp-param|query+imageinfo|extmetadatafilter}}",
+ "apihelp-query+imageinfo-param-urlparam": "{{doc-apihelp-param|query+imageinfo|urlparam}}",
+ "apihelp-query+imageinfo-param-localonly": "{{doc-apihelp-param|query+imageinfo|localonly}}",
+ "apihelp-query+imageinfo-example-simple": "{{doc-apihelp-example|query+imageinfo}}",
+ "apihelp-query+imageinfo-example-dated": "{{doc-apihelp-example|query+imageinfo}}",
+ "apihelp-query+images-description": "{{doc-apihelp-description|query+images}}",
+ "apihelp-query+images-param-limit": "{{doc-apihelp-param|query+images|limit}}",
+ "apihelp-query+images-param-images": "{{doc-apihelp-param|query+images|images}}",
+ "apihelp-query+images-param-dir": "{{doc-apihelp-param|query+images|dir}}",
+ "apihelp-query+images-example-simple": "{{doc-apihelp-example|query+images}}",
+ "apihelp-query+images-example-generator": "{{doc-apihelp-example|query+images}}",
+ "apihelp-query+imageusage-description": "{{doc-apihelp-description|query+imageusage}}",
+ "apihelp-query+imageusage-param-title": "{{doc-apihelp-param|query+imageusage|title}}",
+ "apihelp-query+imageusage-param-pageid": "{{doc-apihelp-param|query+imageusage|pageid}}",
+ "apihelp-query+imageusage-param-namespace": "{{doc-apihelp-param|query+imageusage|namespace}}",
+ "apihelp-query+imageusage-param-dir": "{{doc-apihelp-param|query+imageusage|dir}}",
+ "apihelp-query+imageusage-param-filterredir": "{{doc-apihelp-param|query+imageusage|filterredir}}",
+ "apihelp-query+imageusage-param-limit": "{{doc-apihelp-param|query+imageusage|limit}}",
+ "apihelp-query+imageusage-param-redirect": "{{doc-apihelp-param|query+imageusage|redirect}}",
+ "apihelp-query+imageusage-example-simple": "{{doc-apihelp-example|query+imageusage}}",
+ "apihelp-query+imageusage-example-generator": "{{doc-apihelp-example|query+imageusage}}",
+ "apihelp-query+info-description": "{{doc-apihelp-description|query+info}}",
+ "apihelp-query+info-param-prop": "{{doc-apihelp-param|query+info|prop|paramvalues=1}}",
+ "apihelp-query+info-paramvalue-prop-protection": "{{doc-apihelp-paramvalue|query+info|prop|protection}}",
+ "apihelp-query+info-paramvalue-prop-talkid": "{{doc-apihelp-paramvalue|query+info|prop|talkid}}",
+ "apihelp-query+info-paramvalue-prop-watched": "{{doc-apihelp-paramvalue|query+info|prop|watched}}",
+ "apihelp-query+info-paramvalue-prop-watchers": "{{doc-apihelp-paramvalue|query+info|prop|watchers}}",
+ "apihelp-query+info-paramvalue-prop-notificationtimestamp": "{{doc-apihelp-paramvalue|query+info|prop|notificationtimestamp}}",
+ "apihelp-query+info-paramvalue-prop-subjectid": "{{doc-apihelp-paramvalue|query+info|prop|subjectid}}",
+ "apihelp-query+info-paramvalue-prop-url": "{{doc-apihelp-paramvalue|query+info|prop|url}}",
+ "apihelp-query+info-paramvalue-prop-readable": "{{doc-apihelp-paramvalue|query+info|prop|readable}}",
+ "apihelp-query+info-paramvalue-prop-preload": "{{doc-apihelp-paramvalue|query+info|prop|preload}}",
+ "apihelp-query+info-paramvalue-prop-displaytitle": "{{doc-apihelp-paramvalue|query+info|prop|displaytitle}}",
+ "apihelp-query+info-param-testactions": "{{doc-apihelp-param|query+info|testactions}}",
+ "apihelp-query+info-param-token": "{{doc-apihelp-param|query+info|token}}",
+ "apihelp-query+info-example-simple": "{{doc-apihelp-example|query+info}}",
+ "apihelp-query+info-example-protection": "{{doc-apihelp-example|query+info}}",
+ "apihelp-query+iwbacklinks-description": "{{doc-apihelp-description|query+iwbacklinks}}",
+ "apihelp-query+iwbacklinks-param-prefix": "{{doc-apihelp-param|query+iwbacklinks|prefix}}",
+ "apihelp-query+iwbacklinks-param-title": "{{doc-apihelp-param|query+iwbacklinks|title}}",
+ "apihelp-query+iwbacklinks-param-limit": "{{doc-apihelp-param|query+iwbacklinks|limit}}",
+ "apihelp-query+iwbacklinks-param-prop": "{{doc-apihelp-param|query+iwbacklinks|prop}}",
+ "apihelp-query+iwbacklinks-param-dir": "{{doc-apihelp-param|query+iwbacklinks|dir}}",
+ "apihelp-query+iwbacklinks-example-simple": "{{doc-apihelp-example|query+iwbacklinks}}",
+ "apihelp-query+iwbacklinks-example-generator": "{{doc-apihelp-example|query+iwbacklinks}}",
+ "apihelp-query+iwlinks-description": "{{doc-apihelp-description|query+iwlinks}}",
+ "apihelp-query+iwlinks-param-url": "{{doc-apihelp-param|query+iwlinks|url}}",
+ "apihelp-query+iwlinks-param-prop": "{{doc-apihelp-param|query+iwlinks|prop}}",
+ "apihelp-query+iwlinks-param-limit": "{{doc-apihelp-param|query+iwlinks|limit}}",
+ "apihelp-query+iwlinks-param-prefix": "{{doc-apihelp-param|query+iwlinks|prefix}}",
+ "apihelp-query+iwlinks-param-title": "{{doc-apihelp-param|query+iwlinks|title}}",
+ "apihelp-query+iwlinks-param-dir": "{{doc-apihelp-param|query+iwlinks|dir}}",
+ "apihelp-query+iwlinks-example-simple": "{{doc-apihelp-example|query+iwlinks}}",
+ "apihelp-query+langbacklinks-description": "{{doc-apihelp-description|query+langbacklinks}}",
+ "apihelp-query+langbacklinks-param-lang": "{{doc-apihelp-param|query+langbacklinks|lang}}",
+ "apihelp-query+langbacklinks-param-title": "{{doc-apihelp-param|query+langbacklinks|title}}",
+ "apihelp-query+langbacklinks-param-limit": "{{doc-apihelp-param|query+langbacklinks|limit}}",
+ "apihelp-query+langbacklinks-param-prop": "{{doc-apihelp-param|query+langbacklinks|prop}}",
+ "apihelp-query+langbacklinks-param-dir": "{{doc-apihelp-param|query+langbacklinks|dir}}",
+ "apihelp-query+langbacklinks-example-simple": "{{doc-apihelp-example|query+langbacklinks}}",
+ "apihelp-query+langbacklinks-example-generator": "{{doc-apihelp-example|query+langbacklinks}}",
+ "apihelp-query+langlinks-description": "{{doc-apihelp-description|query+langlinks}}",
+ "apihelp-query+langlinks-param-limit": "{{doc-apihelp-param|query+langlinks|limit}}",
+ "apihelp-query+langlinks-param-url": "{{doc-apihelp-param|query+langlinks|url}}",
+ "apihelp-query+langlinks-param-prop": "{{doc-apihelp-param|query+langlinks|prop}}",
+ "apihelp-query+langlinks-param-lang": "{{doc-apihelp-param|query+langlinks|lang}}",
+ "apihelp-query+langlinks-param-title": "{{doc-apihelp-param|query+langlinks|title}}",
+ "apihelp-query+langlinks-param-dir": "{{doc-apihelp-param|query+langlinks|dir}}",
+ "apihelp-query+langlinks-param-inlanguagecode": "{{doc-apihelp-param|query+langlinks|inlanguagecode}}",
+ "apihelp-query+langlinks-example-simple": "{{doc-apihelp-example|query+langlinks}}",
+ "apihelp-query+links-description": "{{doc-apihelp-description|query+links}}",
+ "apihelp-query+links-param-namespace": "{{doc-apihelp-param|query+links|namespace}}",
+ "apihelp-query+links-param-limit": "{{doc-apihelp-param|query+links|limit}}",
+ "apihelp-query+links-param-titles": "{{doc-apihelp-param|query+links|titles}}",
+ "apihelp-query+links-param-dir": "{{doc-apihelp-param|query+links|dir}}",
+ "apihelp-query+links-example-simple": "{{doc-apihelp-example|query+links}}",
+ "apihelp-query+links-example-generator": "{{doc-apihelp-example|query+links}}",
+ "apihelp-query+links-example-namespaces": "{{doc-apihelp-example|query+links}}",
+ "apihelp-query+linkshere-description": "{{doc-apihelp-description|query+linkshere}}",
+ "apihelp-query+linkshere-param-prop": "{{doc-apihelp-param|query+linkshere|prop}}",
+ "apihelp-query+linkshere-param-namespace": "{{doc-apihelp-param|query+linkshere|namespace}}",
+ "apihelp-query+linkshere-param-limit": "{{doc-apihelp-param|query+linkshere|limit}}",
+ "apihelp-query+linkshere-param-show": "{{doc-apihelp-param|query+linkshere|show}}",
+ "apihelp-query+linkshere-example-simple": "{{doc-apihelp-example|query+linkshere}}",
+ "apihelp-query+linkshere-example-generator": "{{doc-apihelp-example|query+linkshere}}",
+ "apihelp-query+logevents-description": "{{doc-apihelp-description|query+logevents}}",
+ "apihelp-query+logevents-param-prop": "{{doc-apihelp-param|query+logevents|prop}}",
+ "apihelp-query+logevents-param-type": "{{doc-apihelp-param|query+logevents|type}}",
+ "apihelp-query+logevents-param-action": "{{doc-apihelp-param|query+logevents|action}}",
+ "apihelp-query+logevents-param-start": "{{doc-apihelp-param|query+logevents|start}}",
+ "apihelp-query+logevents-param-end": "{{doc-apihelp-param|query+logevents|end}}",
+ "apihelp-query+logevents-param-user": "{{doc-apihelp-param|query+logevents|user}}",
+ "apihelp-query+logevents-param-title": "{{doc-apihelp-param|query+logevents|title}}",
+ "apihelp-query+logevents-param-namespace": "{{doc-apihelp-param|query+logevents|namespace}}",
+ "apihelp-query+logevents-param-prefix": "{{doc-apihelp-param|query+logevents|prefix}}",
+ "apihelp-query+logevents-param-tag": "{{doc-apihelp-param|query+logevents|tag}}",
+ "apihelp-query+logevents-param-limit": "{{doc-apihelp-param|query+logevents|limit}}",
+ "apihelp-query+logevents-example-simple": "{{doc-apihelp-example|query+logevents}}",
+ "apihelp-query+pagepropnames-description": "{{doc-apihelp-description|query+pagepropnames}}",
+ "apihelp-query+pagepropnames-param-limit": "{{doc-apihelp-param|query+pagepropnames|limit}}",
+ "apihelp-query+pagepropnames-example-simple": "{{doc-apihelp-example|query+pagepropnames}}",
+ "apihelp-query+pageprops-description": "{{doc-apihelp-description|query+pageprops}}",
+ "apihelp-query+pageprops-param-prop": "{{doc-apihelp-param|query+pageprops|prop}}",
+ "apihelp-query+pageprops-example-simple": "{{doc-apihelp-example|query+pageprops}}",
+ "apihelp-query+pageswithprop-description": "{{doc-apihelp-description|query+pageswithprop}}",
+ "apihelp-query+pageswithprop-param-propname": "{{doc-apihelp-param|query+pageswithprop|propname}}",
+ "apihelp-query+pageswithprop-param-prop": "{{doc-apihelp-param|query+pageswithprop|prop}}",
+ "apihelp-query+pageswithprop-param-limit": "{{doc-apihelp-param|query+pageswithprop|limit}}",
+ "apihelp-query+pageswithprop-param-dir": "{{doc-apihelp-param|query+pageswithprop|dir}}",
+ "apihelp-query+pageswithprop-example-simple": "{{doc-apihelp-example|query+pageswithprop}}",
+ "apihelp-query+pageswithprop-example-generator": "{{doc-apihelp-example|query+pageswithprop}}",
+ "apihelp-query+prefixsearch-description": "{{doc-apihelp-description|query+prefixsearch}}",
+ "apihelp-query+prefixsearch-param-search": "{{doc-apihelp-param|query+prefixsearch|search}}",
+ "apihelp-query+prefixsearch-param-namespace": "{{doc-apihelp-param|query+prefixsearch|namespace}}",
+ "apihelp-query+prefixsearch-param-limit": "{{doc-apihelp-param|query+prefixsearch|limit}}",
+ "apihelp-query+prefixsearch-param-offset": "{{doc-apihelp-param|query+prefixsearch|offset}}",
+ "apihelp-query+prefixsearch-example-simple": "{{doc-apihelp-example|query+prefixsearch}}",
+ "apihelp-query+protectedtitles-description": "{{doc-apihelp-description|query+protectedtitles}}",
+ "apihelp-query+protectedtitles-param-namespace": "{{doc-apihelp-param|query+protectedtitles|namespace}}",
+ "apihelp-query+protectedtitles-param-level": "{{doc-apihelp-param|query+protectedtitles|level}}",
+ "apihelp-query+protectedtitles-param-limit": "{{doc-apihelp-param|query+protectedtitles|limit}}",
+ "apihelp-query+protectedtitles-param-start": "{{doc-apihelp-param|query+protectedtitles|start}}",
+ "apihelp-query+protectedtitles-param-end": "{{doc-apihelp-param|query+protectedtitles|end}}",
+ "apihelp-query+protectedtitles-param-prop": "{{doc-apihelp-param|query+protectedtitles|prop}}",
+ "apihelp-query+protectedtitles-example-simple": "{{doc-apihelp-example|query+protectedtitles}}",
+ "apihelp-query+protectedtitles-example-generator": "{{doc-apihelp-example|query+protectedtitles}}",
+ "apihelp-query+querypage-description": "{{doc-apihelp-description|query+querypage}}",
+ "apihelp-query+querypage-param-page": "{{doc-apihelp-param|query+querypage|page}}",
+ "apihelp-query+querypage-param-limit": "{{doc-apihelp-param|query+querypage|limit}}",
+ "apihelp-query+querypage-example-ancientpages": "{{doc-apihelp-example|query+querypage}}",
+ "apihelp-query+random-description": "{{doc-apihelp-description|query+random}}",
+ "apihelp-query+random-param-namespace": "{{doc-apihelp-param|query+random|namespace}}",
+ "apihelp-query+random-param-limit": "{{doc-apihelp-param|query+random|limit}}",
+ "apihelp-query+random-param-redirect": "{{doc-apihelp-param|query+random|redirect}}",
+ "apihelp-query+random-example-simple": "{{doc-apihelp-example|query+random}}",
+ "apihelp-query+random-example-generator": "{{doc-apihelp-example|query+random}}",
+ "apihelp-query+recentchanges-description": "{{doc-apihelp-description|query+recentchanges}}",
+ "apihelp-query+recentchanges-param-start": "{{doc-apihelp-param|query+recentchanges|start}}",
+ "apihelp-query+recentchanges-param-end": "{{doc-apihelp-param|query+recentchanges|end}}",
+ "apihelp-query+recentchanges-param-namespace": "{{doc-apihelp-param|query+recentchanges|namespace}}",
+ "apihelp-query+recentchanges-param-user": "{{doc-apihelp-param|query+recentchanges|user}}",
+ "apihelp-query+recentchanges-param-excludeuser": "{{doc-apihelp-param|query+recentchanges|excludeuser}}",
+ "apihelp-query+recentchanges-param-tag": "{{doc-apihelp-param|query+recentchanges|tag}}",
+ "apihelp-query+recentchanges-param-prop": "{{doc-apihelp-param|query+recentchanges|prop}}",
+ "apihelp-query+recentchanges-param-token": "{{doc-apihelp-param|query+recentchanges|token}}",
+ "apihelp-query+recentchanges-param-show": "{{doc-apihelp-param|query+recentchanges|show}}",
+ "apihelp-query+recentchanges-param-limit": "{{doc-apihelp-param|query+recentchanges|limit}}",
+ "apihelp-query+recentchanges-param-type": "{{doc-apihelp-param|query+recentchanges|type}}",
+ "apihelp-query+recentchanges-param-toponly": "{{doc-apihelp-param|query+recentchanges|toponly}}",
+ "apihelp-query+recentchanges-example-simple": "{{doc-apihelp-example|query+recentchanges}}",
+ "apihelp-query+recentchanges-example-generator": "{{doc-apihelp-example|query+recentchanges}}",
+ "apihelp-query+redirects-description": "{{doc-apihelp-description|query+redirects}}",
+ "apihelp-query+redirects-param-prop": "{{doc-apihelp-param|query+redirects|prop}}",
+ "apihelp-query+redirects-param-namespace": "{{doc-apihelp-param|query+redirects|namespace}}",
+ "apihelp-query+redirects-param-limit": "{{doc-apihelp-param|query+redirects|limit}}",
+ "apihelp-query+redirects-param-show": "{{doc-apihelp-param|query+redirects|show}}",
+ "apihelp-query+redirects-example-simple": "{{doc-apihelp-example|query+redirects}}",
+ "apihelp-query+redirects-example-generator": "{{doc-apihelp-example|query+redirects}}",
+ "apihelp-query+revisions-description": "{{doc-apihelp-description|query+revisions}}",
+ "apihelp-query+revisions-paraminfo-singlepageonly": "{{doc-apihelp-paraminfo|query+revisions|singlepageonly}}",
+ "apihelp-query+revisions-param-startid": "{{doc-apihelp-param|query+revisions|startid}}",
+ "apihelp-query+revisions-param-endid": "{{doc-apihelp-param|query+revisions|endid}}",
+ "apihelp-query+revisions-param-start": "{{doc-apihelp-param|query+revisions|start}}",
+ "apihelp-query+revisions-param-end": "{{doc-apihelp-param|query+revisions|end}}",
+ "apihelp-query+revisions-param-user": "{{doc-apihelp-param|query+revisions|user}}",
+ "apihelp-query+revisions-param-excludeuser": "{{doc-apihelp-param|query+revisions|excludeuser}}",
+ "apihelp-query+revisions-param-tag": "{{doc-apihelp-param|query+revisions|tag}}",
+ "apihelp-query+revisions-param-token": "{{doc-apihelp-param|query+revisions|token}}",
+ "apihelp-query+revisions-example-content": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions-example-last5": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions-example-first5": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions-example-first5-after": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions-example-first5-not-localhost": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions-example-first5-user": "{{doc-apihelp-example|query+revisions}}",
+ "apihelp-query+revisions+base-param-prop": "{{doc-apihelp-param|query+revisions+base|prop|description=the \"prop\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-limit": "{{doc-apihelp-param|query+revisions+base|limit|description=the \"limit\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-expandtemplates": "{{doc-apihelp-param|query+revisions+base|expandtemplates|description=the \"expandtemplates\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-generatexml": "{{doc-apihelp-param|query+revisions+base|generatexml|description=the \"generatexml\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-parse": "{{doc-apihelp-param|query+revisions+base|parse|description=the \"parse\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-section": "{{doc-apihelp-param|query+revisions+base|section|description=the \"section\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-diffto": "{{doc-apihelp-param|query+revisions+base|diffto|description=the \"diffto\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-difftotext": "{{doc-apihelp-param|query+revisions+base|difftotext|description=the \"difftotext\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+revisions+base-param-contentformat": "{{doc-apihelp-param|query+revisions+base|contentformat|description=the \"contentformat\" parameter to revision querying modules|noseealso=1}}",
+ "apihelp-query+search-description": "{{doc-apihelp-description|query+search}}",
+ "apihelp-query+search-param-search": "{{doc-apihelp-param|query+search|search}}",
+ "apihelp-query+search-param-namespace": "{{doc-apihelp-param|query+search|namespace}}",
+ "apihelp-query+search-param-what": "{{doc-apihelp-param|query+search|what}}",
+ "apihelp-query+search-param-info": "{{doc-apihelp-param|query+search|info}}",
+ "apihelp-query+search-param-prop": "{{doc-apihelp-param|query+search|prop}}",
+ "apihelp-query+search-param-limit": "{{doc-apihelp-param|query+search|limit}}",
+ "apihelp-query+search-param-interwiki": "{{doc-apihelp-param|query+search|interwiki}}",
+ "apihelp-query+search-param-backend": "{{doc-apihelp-param|query+search|backend}}",
+ "apihelp-query+search-example-simple": "{{doc-apihelp-example|query+search}}",
+ "apihelp-query+search-example-text": "{{doc-apihelp-example|query+search}}",
+ "apihelp-query+search-example-generator": "{{doc-apihelp-example|query+search}}",
+ "apihelp-query+siteinfo-description": "{{doc-apihelp-description|query+siteinfo}}",
+ "apihelp-query+siteinfo-param-prop": "{{doc-apihelp-param|query+siteinfo|prop}}",
+ "apihelp-query+siteinfo-param-filteriw": "{{doc-apihelp-param|query+siteinfo|filteriw}}",
+ "apihelp-query+siteinfo-param-showalldb": "{{doc-apihelp-param|query+siteinfo|showalldb}}",
+ "apihelp-query+siteinfo-param-numberingroup": "{{doc-apihelp-param|query+siteinfo|numberingroup}}",
+ "apihelp-query+siteinfo-param-inlanguagecode": "{{doc-apihelp-param|query+siteinfo|inlanguagecode}}",
+ "apihelp-query+siteinfo-example-simple": "{{doc-apihelp-example|query+siteinfo}}",
+ "apihelp-query+siteinfo-example-interwiki": "{{doc-apihelp-example|query+siteinfo}}",
+ "apihelp-query+siteinfo-example-replag": "{{doc-apihelp-example|query+siteinfo}}",
+ "apihelp-query+stashimageinfo-description": "{{doc-apihelp-description|query+stashimageinfo}}",
+ "apihelp-query+stashimageinfo-param-filekey": "{{doc-apihelp-param|query+stashimageinfo|filekey}}",
+ "apihelp-query+stashimageinfo-param-sessionkey": "{{doc-apihelp-param|query+stashimageinfo|sessionkey}}",
+ "apihelp-query+stashimageinfo-example-simple": "{{doc-apihelp-example|query+stashimageinfo}}",
+ "apihelp-query+stashimageinfo-example-params": "{{doc-apihelp-example|query+stashimageinfo}}",
+ "apihelp-query+tags-description": "{{doc-apihelp-description|query+tags}}",
+ "apihelp-query+tags-param-limit": "{{doc-apihelp-param|query+tags|limit}}",
+ "apihelp-query+tags-param-prop": "{{doc-apihelp-param|query+tags|prop}}",
+ "apihelp-query+tags-example-simple": "{{doc-apihelp-example|query+tags}}",
+ "apihelp-query+templates-description": "{{doc-apihelp-description|query+templates}}",
+ "apihelp-query+templates-param-namespace": "{{doc-apihelp-param|query+templates|namespace}}",
+ "apihelp-query+templates-param-limit": "{{doc-apihelp-param|query+templates|limit}}",
+ "apihelp-query+templates-param-templates": "{{doc-apihelp-param|query+templates|templates}}",
+ "apihelp-query+templates-param-dir": "{{doc-apihelp-param|query+templates|dir}}",
+ "apihelp-query+templates-example-simple": "{{doc-apihelp-example|query+templates}}",
+ "apihelp-query+templates-example-generator": "{{doc-apihelp-example|query+templates}}",
+ "apihelp-query+templates-example-namespaces": "{{doc-apihelp-example|query+templates}}",
+ "apihelp-query+tokens-description": "{{doc-apihelp-description|query+tokens}}",
+ "apihelp-query+tokens-param-type": "{{doc-apihelp-param|query+tokens|type}}",
+ "apihelp-query+tokens-example-simple": "{{doc-apihelp-example|query+tokens}}",
+ "apihelp-query+tokens-example-types": "{{doc-apihelp-example|query+tokens}}",
+ "apihelp-query+transcludedin-description": "{{doc-apihelp-description|query+transcludedin}}",
+ "apihelp-query+transcludedin-param-prop": "{{doc-apihelp-param|query+transcludedin|prop}}",
+ "apihelp-query+transcludedin-param-namespace": "{{doc-apihelp-param|query+transcludedin|namespace}}",
+ "apihelp-query+transcludedin-param-limit": "{{doc-apihelp-param|query+transcludedin|limit}}",
+ "apihelp-query+transcludedin-param-show": "{{doc-apihelp-param|query+transcludedin|show}}",
+ "apihelp-query+transcludedin-example-simple": "{{doc-apihelp-example|query+transcludedin}}",
+ "apihelp-query+transcludedin-example-generator": "{{doc-apihelp-example|query+transcludedin}}",
+ "apihelp-query+usercontribs-description": "{{doc-apihelp-description|query+usercontribs}}",
+ "apihelp-query+usercontribs-param-limit": "{{doc-apihelp-param|query+usercontribs|limit}}",
+ "apihelp-query+usercontribs-param-start": "{{doc-apihelp-param|query+usercontribs|start}}",
+ "apihelp-query+usercontribs-param-end": "{{doc-apihelp-param|query+usercontribs|end}}",
+ "apihelp-query+usercontribs-param-user": "{{doc-apihelp-param|query+usercontribs|user}}",
+ "apihelp-query+usercontribs-param-userprefix": "{{doc-apihelp-param|query+usercontribs|userprefix}}",
+ "apihelp-query+usercontribs-param-namespace": "{{doc-apihelp-param|query+usercontribs|namespace}}",
+ "apihelp-query+usercontribs-param-prop": "{{doc-apihelp-param|query+usercontribs|prop}}",
+ "apihelp-query+usercontribs-param-show": "{{doc-apihelp-param|query+usercontribs|show|params=* $1 - Value of [[mw:Manual:$RCMaxAge|$RCMaxAge]]|paramstart=2}}",
+ "apihelp-query+usercontribs-param-tag": "{{doc-apihelp-param|query+usercontribs|tag}}",
+ "apihelp-query+usercontribs-param-toponly": "{{doc-apihelp-param|query+usercontribs|toponly}}",
+ "apihelp-query+usercontribs-example-user": "{{doc-apihelp-example|query+usercontribs}}",
+ "apihelp-query+usercontribs-example-ipprefix": "{{doc-apihelp-example|query+usercontribs}}",
+ "apihelp-query+userinfo-description": "{{doc-apihelp-description|query+userinfo}}",
+ "apihelp-query+userinfo-param-prop": "{{doc-apihelp-param|query+userinfo|prop|params=* $1 - Maximum value for the \"unreadcount\" property.\n$2 - Return value when there are more unread pages.|paramstart=3}}",
+ "apihelp-query+userinfo-example-simple": "{{doc-apihelp-example|query+userinfo}}",
+ "apihelp-query+userinfo-example-data": "{{doc-apihelp-example|query+userinfo}}",
+ "apihelp-query+users-description": "{{doc-apihelp-description|query+users}}",
+ "apihelp-query+users-param-prop": "{{doc-apihelp-param|query+users|prop}}",
+ "apihelp-query+users-param-users": "{{doc-apihelp-param|query+users|users}}",
+ "apihelp-query+users-param-token": "{{doc-apihelp-param|query+users|token}}",
+ "apihelp-query+users-example-simple": "{{doc-apihelp-example|query+users}}",
+ "apihelp-query+watchlist-description": "{{doc-apihelp-description|query+watchlist}}",
+ "apihelp-query+watchlist-param-allrev": "{{doc-apihelp-param|query+watchlist|allrev}}",
+ "apihelp-query+watchlist-param-start": "{{doc-apihelp-param|query+watchlist|start}}",
+ "apihelp-query+watchlist-param-end": "{{doc-apihelp-param|query+watchlist|end}}",
+ "apihelp-query+watchlist-param-namespace": "{{doc-apihelp-param|query+watchlist|namespace}}",
+ "apihelp-query+watchlist-param-user": "{{doc-apihelp-param|query+watchlist|user}}",
+ "apihelp-query+watchlist-param-excludeuser": "{{doc-apihelp-param|query+watchlist|excludeuser}}",
+ "apihelp-query+watchlist-param-limit": "{{doc-apihelp-param|query+watchlist|limit}}",
+ "apihelp-query+watchlist-param-prop": "{{doc-apihelp-param|query+watchlist|prop}}",
+ "apihelp-query+watchlist-param-show": "{{doc-apihelp-param|query+watchlist|show}}",
+ "apihelp-query+watchlist-param-type": "{{doc-apihelp-param|query+watchlist|type}}",
+ "apihelp-query+watchlist-param-owner": "{{doc-apihelp-param|query+watchlist|owner}}",
+ "apihelp-query+watchlist-param-token": "{{doc-apihelp-param|query+watchlist|token}}",
+ "apihelp-query+watchlist-example-simple": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlist-example-props": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlist-example-allrev": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlist-example-generator": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlist-example-generator-rev": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlist-example-wlowner": "{{doc-apihelp-example|query+watchlist}}",
+ "apihelp-query+watchlistraw-description": "{{doc-apihelp-description|query+watchlistraw}}",
+ "apihelp-query+watchlistraw-param-namespace": "{{doc-apihelp-param|query+watchlistraw|namespace}}",
+ "apihelp-query+watchlistraw-param-limit": "{{doc-apihelp-param|query+watchlistraw|limit}}",
+ "apihelp-query+watchlistraw-param-prop": "{{doc-apihelp-param|query+watchlistraw|prop}}",
+ "apihelp-query+watchlistraw-param-show": "{{doc-apihelp-param|query+watchlistraw|show}}",
+ "apihelp-query+watchlistraw-param-owner": "{{doc-apihelp-param|query+watchlistraw|owner}}",
+ "apihelp-query+watchlistraw-param-token": "{{doc-apihelp-param|query+watchlistraw|token}}",
+ "apihelp-query+watchlistraw-example-simple": "{{doc-apihelp-example|query+watchlistraw}}",
+ "apihelp-query+watchlistraw-example-generator": "{{doc-apihelp-example|query+watchlistraw}}",
+ "apihelp-revisiondelete-description": "{{doc-apihelp-description|revisiondelete}}",
+ "apihelp-revisiondelete-param-type": "{{doc-apihelp-param|revisiondelete|type}}",
+ "apihelp-revisiondelete-param-target": "{{doc-apihelp-param|revisiondelete|target}}",
+ "apihelp-revisiondelete-param-ids": "{{doc-apihelp-param|revisiondelete|ids}}",
+ "apihelp-revisiondelete-param-hide": "{{doc-apihelp-param|revisiondelete|hide}}",
+ "apihelp-revisiondelete-param-show": "{{doc-apihelp-param|revisiondelete|show}}",
+ "apihelp-revisiondelete-param-suppress": "{{doc-apihelp-param|revisiondelete|suppress}}",
+ "apihelp-revisiondelete-param-reason": "{{doc-apihelp-param|revisiondelete|reason}}",
+ "apihelp-revisiondelete-example-revision": "{{doc-apihelp-example|revisiondelete}}",
+ "apihelp-revisiondelete-example-log": "{{doc-apihelp-example|revisiondelete}}",
+ "apihelp-rollback-description": "{{doc-apihelp-description|rollback}}",
+ "apihelp-rollback-param-title": "{{doc-apihelp-param|rollback|title}}",
+ "apihelp-rollback-param-pageid": "{{doc-apihelp-param|rollback|pageid}}",
+ "apihelp-rollback-param-user": "{{doc-apihelp-param|rollback|user}}",
+ "apihelp-rollback-param-summary": "{{doc-apihelp-param|rollback|summary}}",
+ "apihelp-rollback-param-markbot": "{{doc-apihelp-param|rollback|markbot}}",
+ "apihelp-rollback-param-watchlist": "{{doc-apihelp-param|rollback|watchlist}}",
+ "apihelp-rollback-example-simple": "{{doc-apihelp-example|rollback}}",
+ "apihelp-rollback-example-summary": "{{doc-apihelp-example|rollback}}",
+ "apihelp-rsd-description": "{{doc-apihelp-description|rsd}}",
+ "apihelp-rsd-example-simple": "{{doc-apihelp-example|rsd}}",
+ "apihelp-setnotificationtimestamp-description": "{{doc-apihelp-description|setnotificationtimestamp}}",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "{{doc-apihelp-param|setnotificationtimestamp|entirewatchlist}}",
+ "apihelp-setnotificationtimestamp-param-timestamp": "{{doc-apihelp-param|setnotificationtimestamp|timestamp}}",
+ "apihelp-setnotificationtimestamp-param-torevid": "{{doc-apihelp-param|setnotificationtimestamp|torevid}}",
+ "apihelp-setnotificationtimestamp-param-newerthanrevid": "{{doc-apihelp-param|setnotificationtimestamp|newerthanrevid}}",
+ "apihelp-setnotificationtimestamp-example-all": "{{doc-apihelp-example|setnotificationtimestamp}}",
+ "apihelp-setnotificationtimestamp-example-page": "{{doc-apihelp-example|setnotificationtimestamp}}",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "{{doc-apihelp-example|setnotificationtimestamp}}",
+ "apihelp-setnotificationtimestamp-example-allpages": "{{doc-apihelp-example|setnotificationtimestamp}}",
+ "apihelp-tag-description": "{{doc-apihelp-description|tag}}",
+ "apihelp-tag-param-rcid": "{{doc-apihelp-param|tag|rcid}}",
+ "apihelp-tag-param-revid": "{{doc-apihelp-param|tag|revid}}",
+ "apihelp-tag-param-logid": "{{doc-apihelp-param|tag|logid}}",
+ "apihelp-tag-param-add": "{{doc-apihelp-param|tag|add}}",
+ "apihelp-tag-param-remove": "{{doc-apihelp-param|tag|remove}}",
+ "apihelp-tag-param-reason": "{{doc-apihelp-param|tag|reason}}",
+ "apihelp-tag-example-rev": "{{doc-apihelp-example|tag}}",
+ "apihelp-tag-example-log": "{{doc-apihelp-example|tag}}",
+ "apihelp-tokens-description": "{{doc-apihelp-description|tokens}}",
+ "apihelp-tokens-param-type": "{{doc-apihelp-param|tokens|type}}",
+ "apihelp-tokens-example-edit": "{{doc-apihelp-example|tokens}}",
+ "apihelp-tokens-example-emailmove": "{{doc-apihelp-example|tokens}}",
+ "apihelp-unblock-description": "{{doc-apihelp-description|unblock}}",
+ "apihelp-unblock-param-id": "{{doc-apihelp-param|unblock|id}}",
+ "apihelp-unblock-param-user": "{{doc-apihelp-param|unblock|user}}",
+ "apihelp-unblock-param-reason": "{{doc-apihelp-param|unblock|reason}}",
+ "apihelp-unblock-example-id": "{{doc-apihelp-example|unblock}}",
+ "apihelp-unblock-example-user": "{{doc-apihelp-example|unblock}}",
+ "apihelp-undelete-description": "{{doc-apihelp-description|undelete}}",
+ "apihelp-undelete-param-title": "{{doc-apihelp-param|undelete|title}}",
+ "apihelp-undelete-param-reason": "{{doc-apihelp-param|undelete|reason}}",
+ "apihelp-undelete-param-timestamps": "{{doc-apihelp-param|undelete|timestamps}}",
+ "apihelp-undelete-param-fileids": "{{doc-apihelp-param|undelete|fileids}}",
+ "apihelp-undelete-param-watchlist": "{{doc-apihelp-param|undelete|watchlist}}",
+ "apihelp-undelete-example-page": "{{doc-apihelp-example|undelete}}",
+ "apihelp-undelete-example-revisions": "{{doc-apihelp-example|undelete}}",
+ "apihelp-upload-description": "{{doc-apihelp-description|upload}}",
+ "apihelp-upload-param-filename": "{{doc-apihelp-param|upload|filename}}",
+ "apihelp-upload-param-comment": "{{doc-apihelp-param|upload|comment}}",
+ "apihelp-upload-param-text": "{{doc-apihelp-param|upload|text}}",
+ "apihelp-upload-param-watch": "{{doc-apihelp-param|upload|watch}}",
+ "apihelp-upload-param-watchlist": "{{doc-apihelp-param|upload|watchlist}}",
+ "apihelp-upload-param-ignorewarnings": "{{doc-apihelp-param|upload|ignorewarnings}}",
+ "apihelp-upload-param-file": "{{doc-apihelp-param|upload|file}}",
+ "apihelp-upload-param-url": "{{doc-apihelp-param|upload|url}}",
+ "apihelp-upload-param-filekey": "{{doc-apihelp-param|upload|filekey}}",
+ "apihelp-upload-param-sessionkey": "{{doc-apihelp-param|upload|sessionkey}}",
+ "apihelp-upload-param-stash": "{{doc-apihelp-param|upload|stash}}",
+ "apihelp-upload-param-filesize": "{{doc-apihelp-param|upload|filesize}}",
+ "apihelp-upload-param-offset": "{{doc-apihelp-param|upload|offset}}",
+ "apihelp-upload-param-chunk": "{{doc-apihelp-param|upload|chunk}}",
+ "apihelp-upload-param-async": "{{doc-apihelp-param|upload|async}}",
+ "apihelp-upload-param-asyncdownload": "{{doc-apihelp-param|upload|asyncdownload}}",
+ "apihelp-upload-param-leavemessage": "{{doc-apihelp-param|upload|leavemessage}}",
+ "apihelp-upload-param-statuskey": "{{doc-apihelp-param|upload|statuskey}}",
+ "apihelp-upload-param-checkstatus": "{{doc-apihelp-param|upload|checkstatus}}",
+ "apihelp-upload-example-url": "{{doc-apihelp-example|upload}}",
+ "apihelp-upload-example-filekey": "{{doc-apihelp-example|upload}}",
+ "apihelp-userrights-description": "{{doc-apihelp-description|userrights}}",
+ "apihelp-userrights-param-user": "{{doc-apihelp-param|userrights|user}}\n{{Identical|Username}}",
+ "apihelp-userrights-param-userid": "{{doc-apihelp-param|userrights|userid}}\n{{Identical|User ID}}",
+ "apihelp-userrights-param-add": "{{doc-apihelp-param|userrights|add}}",
+ "apihelp-userrights-param-remove": "{{doc-apihelp-param|userrights|remove}}",
+ "apihelp-userrights-param-reason": "{{doc-apihelp-param|userrights|reason}}",
+ "apihelp-userrights-example-user": "{{doc-apihelp-example|userrights}}",
+ "apihelp-userrights-example-userid": "{{doc-apihelp-example|userrights}}",
+ "apihelp-watch-description": "{{doc-apihelp-description|watch}}",
+ "apihelp-watch-param-title": "{{doc-apihelp-param|watch|title}}",
+ "apihelp-watch-param-unwatch": "{{doc-apihelp-param|watch|unwatch}}",
+ "apihelp-watch-example-watch": "{{doc-apihelp-example|watch}}",
+ "apihelp-watch-example-unwatch": "{{doc-apihelp-example|watch}}",
+ "apihelp-watch-example-generator": "{{doc-apihelp-example|watch}}",
+ "apihelp-format-example-generic": "{{doc-apihelp-example|format|params=* $1 - Format name|paramstart=2|noseealso=1}}",
+ "apihelp-dbg-description": "{{doc-apihelp-description|dbg|seealso=* {{msg-mw|apihelp-dbgfm-description}}}}",
+ "apihelp-dbgfm-description": "{{doc-apihelp-description|dbgfm|seealso=* {{msg-mw|apihelp-dbg-description}}}}",
+ "apihelp-dump-description": "{{doc-apihelp-description|dump|seealso=* {{msg-mw|apihelp-dumpfm-description}}}}",
+ "apihelp-dumpfm-description": "{{doc-apihelp-description|dumpfm|seealso=* {{msg-mw|apihelp-dump-description}}}}",
+ "apihelp-json-description": "{{doc-apihelp-description|json|seealso=* {{msg-mw|apihelp-jsonfm-description}}}}",
+ "apihelp-json-param-callback": "{{doc-apihelp-param|json|callback}}",
+ "apihelp-json-param-utf8": "{{doc-apihelp-param|json|utf8}}",
+ "apihelp-json-param-ascii": "{{doc-apihelp-param|json|ascii}}",
+ "apihelp-json-param-formatversion": "{{doc-apihelp-param|json|formatversion}}",
+ "apihelp-jsonfm-description": "{{doc-apihelp-description|jsonfm|seealso=* {{msg-mw|apihelp-json-description}}}}",
+ "apihelp-none-description": "{{doc-apihelp-description|none}}",
+ "apihelp-php-description": "{{doc-apihelp-description|php|seealso=* {{msg-mw|apihelp-phpfm-description}}}}",
+ "apihelp-php-param-formatversion": "{{doc-apihelp-param|json|formatversion}}",
+ "apihelp-phpfm-description": "{{doc-apihelp-description|phpfm|seealso=* {{msg-mw|apihelp-php-description}}}}",
+ "apihelp-rawfm-description": "{{doc-apihelp-description|rawfm|seealso=* {{msg-mw|apihelp-raw-description}}}}",
+ "apihelp-txt-description": "{{doc-apihelp-description|txt|seealso=* {{msg-mw|apihelp-txtfm-description}}}}",
+ "apihelp-txtfm-description": "{{doc-apihelp-description|txtfm|seealso=* {{msg-mw|apihelp-txt-description}}}}",
+ "apihelp-wddx-description": "{{doc-apihelp-description|wddx|seealso=* {{msg-mw|apihelp-wddxfm-description}}}}",
+ "apihelp-wddxfm-description": "{{doc-apihelp-description|wddxfm|seealso=* {{msg-mw|apihelp-wddx-description}}}}",
+ "apihelp-xml-description": "{{doc-apihelp-description|xml|seealso=* {{msg-mw|apihelp-xmlfm-description}}}}",
+ "apihelp-xml-param-xslt": "{{doc-apihelp-param|xml|xslt}}",
+ "apihelp-xml-param-includexmlnamespace": "{{doc-apihelp-param|xml|includexmlnamespace}}",
+ "apihelp-xmlfm-description": "{{doc-apihelp-description|xmlfm|seealso=* {{msg-mw|apihelp-xml-description}}}}",
+ "apihelp-yaml-description": "{{doc-apihelp-description|yaml|seealso=* {{msg-mw|apihelp-yamlfm-description}}}}",
+ "apihelp-yamlfm-description": "{{doc-apihelp-description|yamlfm|seealso=* {{msg-mw|apihelp-yaml-description}}}}",
+ "api-format-title": "{{technical}}\nPage title when API output is pretty-printed in HTML.",
+ "api-format-prettyprint-header": "{{technical}} Displayed as a header when API output is pretty-printed in HTML.\n\nParameters:\n* $1 - Format name\n* $2 - Non-pretty-printing module name",
+ "api-orm-param-props": "{{doc-apihelp-param|orm|props|description=the \"props\" parameter in subclasses of ApiQueryORM}}",
+ "api-orm-param-limit": "{{doc-apihelp-param|orm|limit|description=the \"limit\" parameter in subclasses of ApiQueryORM}}",
+ "api-pageset-param-titles": "{{doc-apihelp-param|pageset|titles|description=the \"titles\" parameter in pageset-using modules}}",
+ "api-pageset-param-pageids": "{{doc-apihelp-param|pageset|pageids|description=the \"pageids\" parameter in pageset-using modules}}",
+ "api-pageset-param-revids": "{{doc-apihelp-param|pageset|revids|description=the \"revids\" parameter in pageset-using modules}}",
+ "api-pageset-param-generator": "{{doc-apihelp-param|pageset|generator|description=the \"generator\" parameter in pageset-using modules}}",
+ "api-pageset-param-redirects-generator": "{{doc-apihelp-param|pageset|redirects-generator|description=the \"redirects\" parameter in pageset-using modules when the \"generator\" parameter is also available}}",
+ "api-pageset-param-redirects-nogenerator": "{{doc-apihelp-param|pageset|redirects-generator|description=the \"redirects\" parameter in pageset-using modules when the \"generator\" parameter is not available}}",
+ "api-pageset-param-converttitles": "{{doc-apihelp-param|pageset|converttitles|description=the \"converttitles\" parameter in pageset-using modules|params=* $1 - List of languages with variants|paramstart=2}}",
+ "api-help-title": "Page title for the auto-generated help output",
+ "api-help-lead": "Text displayed at the top of the API help page",
+ "api-help-main-header": "Text for the header of the main module",
+ "api-help-fallback-description": "{{notranslate}}",
+ "api-help-fallback-parameter": "{{notranslate}}",
+ "api-help-fallback-example": "{{notranslate}}",
+ "api-help-flags": "{{optional}} Label for the API help flags box\n\nParameters:\n* $1 - Number of flags to be displayed",
+ "api-help-flag-deprecated": "Flag displayed for an API module that is deprecated",
+ "api-help-flag-internal": "Flag displayed for an API module that is considered internal or unstable",
+ "api-help-flag-readrights": "Flag displayed for an API module that requires read rights",
+ "api-help-flag-writerights": "Flag displayed for an API module that requires write rights",
+ "api-help-flag-mustbeposted": "Flag displayed for an API module that only accepts POST requests",
+ "api-help-flag-generator": "Flag displayed for an API module that can be used as a generator",
+ "api-help-help-urls": "{{optional}} Label for the API help urls section\n\nParameters:\n* $1 - Number of urls to be displayed",
+ "api-help-parameters": "Label for the API help parameters section\n\nParameters:\n* $1 - Number of parameters to be displayed\n{{Identical|Parameter}}",
+ "api-help-param-deprecated": "Displayed in the API help for any deprecated parameter\n{{Identical|Deprecated}}",
+ "api-help-param-required": "Displayed in the API help for any required parameter",
+ "api-help-param-list": "Used to display the possible values for a parameter taking a list of values\n\nParameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes any number of values\n* $2 - Comma-separated list of values, possibly formatted using {{msg-mw|api-help-param-list-can-be-empty}}\n{{Identical|Value}}",
+ "api-help-param-list-can-be-empty": "Used to indicate that one of the possible values in the list is the empty string.\n\nParameters:\n* $1 - Number of items in the rest of the list; may be 0\n* $2 - Remainder of the list as a comma-separated string",
+ "api-help-param-limit": "Used to display the maximum value of a limit parameter\n\nParameters:\n* $1 - Maximum value",
+ "api-help-param-limit2": "Used to display the maximum values of a limit parameter\n\nParameters:\n* $1 - Maximum value without the apihighlimits right\n* $2 - Maximum value with the apihighlimits right",
+ "api-help-param-integer-min": "Used to display an integer parameter with a minimum but no maximum value\n\nParameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes any number of values\n* $2 - Minimum value\n* $3 - unused\n\nSee also:\n* {{msg-mw|api-help-param-integer-max}}\n* {{msg-mw|api-help-param-integer-minmax}}",
+ "api-help-param-integer-max": "Used to display an integer parameter with a maximum but no minimum value.\n\nParameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes any number of values\n* $2 - (Unused)\n* $3 - Maximum value\nSee also:\n* {{msg-mw|Api-help-param-integer-min}}\n* {{msg-mw|Api-help-param-integer-minmax}}",
+ "api-help-param-integer-minmax": "Used to display an integer parameter with a maximum and minimum values\n\nParameters:\n* $1 - 1 if the parameter takes one value, 2 if the parameter takes any number of values\n* $2 - Minimum value\n* $3 - Maximum value\n\nSee also:\n* {{msg-mw|api-help-param-integer-min}}\n* {{msg-mw|api-help-param-integer-max}}",
+ "api-help-param-upload": "{{technical}} Used to indicate that an 'upload'-type parameter must be posted as a file upload using multipart/form-data",
+ "api-help-param-multi-separate": "Used to indicate how to separate multiple values. Not used with {{msg-mw|api-help-param-list}}.",
+ "api-help-param-multi-max": "Used to indicate the maximum number of values accepted for a multi-valued parameter.\n\nParameters:\n* $1 - Maximum value without the apihighlimits right\n* $2 - Maximum value with the apihighlimits right",
+ "api-help-param-default": "Used to display the default value for an API parameter\n\nParameters:\n* $1 - Default value\n\nSee also:\n* {{msg-mw|api-help-param-default-empty}}\n{{Identical|Default}}",
+ "api-help-param-default-empty": "Used to display the default value for an API parameter when that default is an empty value\n\nSee also:\n* {{msg-mw|api-help-param-default}}",
+ "api-help-param-token": "{{doc-apihelp-param|description=any 'token' parameter|paramstart=2|params=\n* $1 - Token type|noseealso=1}}",
+ "api-help-param-token-webui": "{{doc-apihelp-param|description=additional text for any \"token\" parameter, explaining that web UI tokens are also accepted|noseealso=1}}",
+ "api-help-param-disabled-in-miser-mode": "{{doc-apihelp-param|description=any parameter that is disabled when [[mw:Manual:$wgMiserMode|$wgMiserMode]] is set.|noseealso=1}}",
+ "api-help-param-limited-in-miser-mode": "{{doc-apihelp-param|description=additional text for any parameter that may cause the module to return few results when [[mw:Manual:$wgMiserMode|$wgMiserMode]] is set.|noseealso=1}}",
+ "api-help-param-direction": "{{doc-apihelp-param|description=any standard \"dir\" parameter|noseealso=1}}",
+ "api-help-param-continue": "{{doc-apihelp-param|description=any standard \"continue\" parameter, or other parameter with the same semantics|noseealso=1}}",
+ "api-help-param-no-description": "Displayed on API parameters that lack any description",
+ "api-help-examples": "Label for the API help examples section\n\nParameters:\n* $1 - Number of examples to be displayed\n{{Identical|Example}}",
+ "api-help-permissions": "Label for the \"permissions\" section in the main module's help output.\n\nParameters:\n* $1 - Number of permissions displayed\n{{Identical|Permission}}",
+ "api-help-permissions-granted-to": "Used to introduce the list of groups each permission is assigned to.\n\nParameters:\n* $1 - Number of groups\n* $2 - List of group names, comma-separated",
+ "api-help-right-apihighlimits": "{{technical}}{{doc-right|apihighlimits|prefix=api-help}}\nThis message is used instead of {{msg-mw|right-apihighlimits}} in the API help to display the actual limits.\n\nParameters:\n* $1 - Limit for slow queries\n* $2 - Limit for fast queries",
+ "api-credits-header": "Header for the API credits section in the API help output\n{{Identical|Credit}}",
+ "api-credits": "API credits text, displayed in the API help output"
+}
diff --git a/includes/api/i18n/roa-tara.json b/includes/api/i18n/roa-tara.json
new file mode 100644
index 00000000..07064122
--- /dev/null
+++ b/includes/api/i18n/roa-tara.json
@@ -0,0 +1,11 @@
+{
+ "@metadata": {
+ "authors": [
+ "Joetaras"
+ ]
+ },
+ "apihelp-block-param-reason": "Mutive pu blocche.",
+ "apihelp-createaccount-param-name": "Nome de l'utende.",
+ "apihelp-edit-param-text": "Vôsce.",
+ "apihelp-edit-example-edit": "Cange 'na pàgene"
+}
diff --git a/includes/api/i18n/ru.json b/includes/api/i18n/ru.json
new file mode 100644
index 00000000..e533d799
--- /dev/null
+++ b/includes/api/i18n/ru.json
@@ -0,0 +1,55 @@
+{
+ "@metadata": {
+ "authors": [
+ "Mahairod",
+ "Okras",
+ "Eakarpov",
+ "Kaganer"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Документация]]\n* [[mw:API:FAQ|ЧаВО]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Почтовая рассылка]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Новости API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Ошибки и запросы]\n</div>\n<strong>Статус:</strong> Все отображаемые на этой странице функции должны работать, однако API находится в статусе активной разработки, и может измениться в любой момент. Подпишитесь на [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ почтовую рассылку mediawiki-api-announce], чтобы быть в курсе обновлений.\n\n<strong>Ошибочные запросы:</strong> Если API получает запрос с ошибкой, вернётся заголовок HTTP с ключом \"MediaWiki-API-Error\", после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:API:Errors_and_warnings|API: Ошибки и предупреждения]].",
+ "apihelp-main-param-action": "Действие, которое следует выполнить.",
+ "apihelp-main-param-format": "Формат вывода.",
+ "apihelp-main-param-smaxage": "Устанавливает заголовок <code>s-maxage</code> в заданное число секунд. Ошибки никогда не кэшируются.",
+ "apihelp-main-param-maxage": "Устанавливает заголовок <code>max-age</code> в заданное число секунд. Ошибки никогда не кэшируются.",
+ "apihelp-main-param-assert": "Удостовериться, что пользователь авторизован, если задано <kbd>user</kbd>, или что имеет права бота, если задано <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Любое заданное здесь значение будет включено в ответ. Может быть использовано для различения запросов.",
+ "apihelp-main-param-servedby": "Включить в результаты имя хоста, обработавшего запрос.",
+ "apihelp-main-param-curtimestamp": "Включить в результаты временную метку.",
+ "apihelp-main-param-origin": "При обращении к API, используя кросс-доменный AJAX-запрос (CORS), задайте параметру значение исходного домена. Он должен быть включён в любой предварительный запрос и таким образом должен быть частью URI-запроса (не тела POST). Он должен точно соответствовать одному из источников в заголовке <code>Origin<code>, так что он должен быть задан наподобие <kbd>https://ru.wikipedia.org</kbd> или <kbd>https://meta.wikimedia.org</kbd>. Если параметр не соответствует заголовку <code>Origin<code>, будет возвращён ответ с кодом ошибки 403. Если параметр соответствует заголовку <code>Origin</code>, и источник находится в белом списке, будет установлен заголовок <code>Access-Control-Allow-Origin</code>.",
+ "apihelp-block-description": "Блокировка участника.",
+ "apihelp-block-param-user": "Имя участника, IP-адрес или диапазон IP-адресов, которые вы хотите заблокировать.",
+ "apihelp-block-param-reason": "Причина блокировки.",
+ "apihelp-block-param-nocreate": "Запретить создание учётных записей.",
+ "apihelp-createaccount-param-name": "Имя участника.",
+ "apihelp-delete-description": "Удалить страницу.",
+ "apihelp-delete-param-watch": "Добавить страницу к текущему списку наблюдения пользователя.",
+ "apihelp-disabled-description": "Этот модуль был отключен.",
+ "apihelp-edit-param-sectiontitle": "Заголовок для нового раздела.",
+ "apihelp-edit-param-text": "Содержание страницы.",
+ "apihelp-edit-param-minor": "Незначительное изменение (малая правка).",
+ "apihelp-edit-param-notminor": "Значительное изменение (обычная, не «малая», правка).",
+ "apihelp-edit-param-bot": "Пометить правку как сделанную ботом.",
+ "apihelp-edit-param-watch": "Добавить страницу к текущему списку наблюдения пользователя.",
+ "apihelp-edit-example-edit": "Редактировать страницу",
+ "apihelp-expandtemplates-param-title": "Заголовок страницы.",
+ "apihelp-import-param-xml": "Загруженный XML-файл.",
+ "apihelp-login-param-name": "Имя участника.",
+ "apihelp-login-param-password": "Пароль.",
+ "apihelp-login-param-domain": "Домен (необязательно).",
+ "apihelp-login-example-login": "Войти",
+ "apihelp-logout-description": "Выйти и очистить данные сессии.",
+ "apihelp-query+alllinks-example-unique-generator": "Получить все названия-ссылки, выделяя пропущенные.",
+ "apihelp-query+duplicatefiles-example-generated": "Поиск дубликатов всех файлов.",
+ "apihelp-query+recentchanges-example-simple": "Список последних изменений.",
+ "apihelp-upload-example-url": "Загрузить через URL",
+ "api-help-main-header": "Главный модуль",
+ "api-help-parameters": "Параметр{{PLURAL:$1||ы}}:",
+ "api-help-param-deprecated": "Устаревший.",
+ "api-help-param-required": "Этот параметр является обязательным.",
+ "api-help-param-default": "По умолчанию: $1",
+ "api-help-param-default-empty": "По умолчанию: <span class=\"apihelp-empty\">(пусто)</span>",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(описание отсутствует)</span>",
+ "api-help-examples": "Пример{{PLURAL:$1||ы}}:",
+ "api-credits-header": "Создатели"
+}
diff --git a/includes/api/i18n/si.json b/includes/api/i18n/si.json
new file mode 100644
index 00000000..a075a49f
--- /dev/null
+++ b/includes/api/i18n/si.json
@@ -0,0 +1,70 @@
+{
+ "@metadata": {
+ "authors": [
+ "Susith Chandira Gts"
+ ]
+ },
+ "apihelp-main-param-action": "ඉටු කිරීමට ඇත්තේ කුමන ක්‍රියාවද.",
+ "apihelp-main-param-format": "ප්‍රතිදානයේ ආකෘතිය.",
+ "apihelp-main-param-requestid": "මෙහි ඇති සියලුම වටිනාකම් ප්‍රතිචාරයන්හි අන්තර්ගතකොට ඇත. ඇතැම් විට පැහැදිලිව වටහාගත් ඉල්ලීම් සදහා භාවිතා වේ.",
+ "apihelp-main-param-servedby": "ප්‍රතිපලයන්හි ඉල්ලීම් ඉටුකළ ධාරකනාමය ඇතුලත් කරන්න.",
+ "apihelp-main-param-curtimestamp": "ප්‍රථිපලයන්හි කාල මුද්‍රාව ඇතුලත් කරන්න.",
+ "apihelp-help-description": "නිරූපිත ඒකක සදහා උදවු පෙන්වන්න.",
+ "apihelp-help-param-submodules": "නම් කරන ලද ඒකකයේ, අනුඒකක සදහා උදවු ඇතුලත් කරන්න.",
+ "apihelp-help-param-helpformat": "උදවු ප්‍රතිදානයේ ආකෘතිය.",
+ "apihelp-help-param-wrap": "ප්‍රතිදානය නියමිත API අනුකූලතා ආකෘතියකට හරවන්න.",
+ "apihelp-help-param-toc": "HTML ප්‍රතිදනයන්ගේ පටුනේ ලැයිස්තුවක් ඇතුලත් කරන්න.",
+ "apihelp-help-example-main": "ප්‍රධාන ඒකකය සදහා උදවු කරන්න",
+ "apihelp-help-example-recursive": "සියලුම උදවු එක පිටුවක් තුල",
+ "apihelp-help-example-query": "සැකසහිත අනුඒකක සදහා උදවු කරන්න",
+ "apihelp-format-example-generic": "$1 ආකෘතියේ ඇති සැක සහිත ප්‍රථිපල පරිවර්තනය කරන්න",
+ "apihelp-dbg-description": "ප්‍රතිදාන දත්ත PHP හි var_export() ආකෘතියෙන් පවතී.",
+ "apihelp-dbgfm-description": "ප්‍රතිදාන දත්ත PHP හි var_export() ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-dump-description": "ප්‍රතිදාන දත්ත PHP හි var_dump() ආකෘතියෙන් පවතී.",
+ "apihelp-dumpfm-description": "ප්‍රතිදාන දත්ත PHP හි var_dump() ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-json-description": "ප්‍රතිදාන දත්ත JSON ආකෘතියෙන් පවතී.",
+ "apihelp-jsonfm-description": "ප්‍රතිදාන දත්ත JSON ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-none-description": "ප්‍රතිදානයේ කිසිවක් නොමැත.",
+ "apihelp-php-description": "ප්‍රතිදාන දත්ත serialized PHP ආකෘතියෙන් පවතී.",
+ "apihelp-phpfm-description": "ප්‍රතිදාන දත්ත serialized PHP ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-txt-description": "ප්‍රතිදාන දත්ත PHP හි print_r() ආකෘතියෙන් පවතී.",
+ "apihelp-txtfm-description": "ප්‍රතිදාන දත්ත PHP හි print_r() ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-wddx-description": "ප්‍රතිදාන දත්ත WDDX ආකෘතියෙන් පවතී",
+ "apihelp-wddxfm-description": "ප්‍රතිදාන දත්ත WDDX ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-xml-description": "ප්‍රතිදාන දත්ත XML ආකෘතියෙන් පවතී.",
+ "apihelp-xml-param-includexmlnamespace": "නිරූපණය කළා නම්, XML නාමාවකාශයක් එකතු කරන්න.",
+ "apihelp-xmlfm-description": "ප්‍රතිදාන දත්ත XML ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "apihelp-yaml-description": "ප්‍රතිදාන දත්ත YAML ආකෘතියෙන් පවතී.",
+ "apihelp-yamlfm-description": "ප්‍රතිදාන දත්ත YAML ආකෘතියෙන් පවතී (හොදම පිටපත HTML භාෂාවෙනි).",
+ "api-format-title": "මාධ්‍යවිකි API ප්‍රථිපල",
+ "api-help-title": "මාධ්‍යවිකි API උදවු",
+ "api-help-lead": "මෙය ස්වයං-ජනිත මාධ්‍යවිකි API \tප්‍රලේඛන පිටුවකි.\n\nප්‍රලේඛනය සහ උදාහරණ:\nhttps://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "ප්‍රධාන ආකෘතිය",
+ "api-help-flag-deprecated": "මෙම ආකෘතිය විරුද්ධත්වය ප්‍රකාශ කරන ලදී.",
+ "api-help-flag-internal": "<strong>මෙම ඒකකය අභ්‍යන්තර හෝ අස්ථායි.\n</strong> එහි ක්‍රියාකාරිත්වය දැනුම් දීමකින් තොරව වෙනස් වියහැක.",
+ "api-help-flag-readrights": "මෙම ඒකකය සදහා හිමිකම් කියවීම අවශ්‍ය වේ.",
+ "api-help-flag-writerights": "මෙම ඒකකය සදහා හිමිකම් ලිවීම අවශ්‍ය වේ.",
+ "api-help-flag-mustbeposted": "මෙම ඒකකය POST ඉල්ලීම් පමණක් බාරගනී.",
+ "api-help-flag-generator": "මෙම ආකෘතිය \tඋත්පාදකයක් ලෙස භාවිතා කල හැක.",
+ "api-help-parameters": "{{PLURAL:$1|පරාමිතිය|පරාමිතීන්}}:",
+ "api-help-param-deprecated": "විරුද්ධත්වය ප්‍රකාශ කර ඇත.",
+ "api-help-param-required": "මෙම පරාමිතිය අවශ්‍යයි.",
+ "api-help-param-list": "{{PLURAL:$1|1=එක් වටිනාකමක්|2=වටිනාකම් (\"{{!}}\" සමග වෙන් කරන්න)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=හිස් කල යුතුයි|හිස් කල හැකියි, හෝ $2}}",
+ "api-help-param-limit": "$1 ට වඩා අනුමත නොකරයි.",
+ "api-help-param-limit2": "$1 කට වැඩ අනුමත කරන්නේ නැත ($2 බොට්ස් සදහාය).",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=අගය|2=අගයන්}} $2 ට වඩා අඩු නොවිය යුතුය.",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=වටිනාකම|2=වටිනාකම්}} $3 ට ව වැඩි නොවිය යුතුය.",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=අගය|2=අගයන්}} $2 සහ $3 අතර පැවතිය යුතුය.",
+ "api-help-param-multi-separate": "වටිනාකම් \"|\" සමග වෙන් කරන්න.",
+ "api-help-param-multi-max": "අංක සදහා උපරිම වටිනාකම {{PLURAL:$1|$1}}\n({{PLURAL:$2|$2}} බොට්ස් සදහා)",
+ "api-help-param-default": "Default: $1",
+ "api-help-param-default-empty": "Default: <span class=\"apihelp-empty\">(හිස්)</span>",
+ "api-help-param-token": "[[Special:ApiHelp/query+tokens|action=query&meta=tokens]] මගින් \"$1\" \tසංඥාව සොයාගන්නා ලදී",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(විස්තරයක් නැත)</span>",
+ "api-help-examples": "{{PLURAL:$1|උදාහරණය|උදාහරණ}}:",
+ "api-help-permissions": "{{PLURAL:$1|අවසරය|අවසරයන්}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|\tප්‍රදානලාභියාට}}: $2",
+ "api-credits-header": "ස්තුතිය",
+ "api-credits": "API වැඩිදියුණු කරන්නන්:\n* Roan Kattouw (ප්‍රධානියා 2007 සැප්. –2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (නිර්මාපකයා, ප්‍රධානියා 2006 සැප්. – 2007 සැප්.)\n* Brad Jorsch (ප්‍රධානියා 2013–මේ දක්වා)\n\nඔබගේ අදහස්, යෝජනා හා ගැටළු mediawiki-api@lists.wikimedia.org වෙත යොමු කරන්න, පින්තූර හෝ ගොනු හරහා ගැටළු ඉදිරිපත් කිරීමට https://phabricator.wikimedia.org/ වෙත පිවිසෙන්න."
+}
diff --git a/includes/api/i18n/sr-ec.json b/includes/api/i18n/sr-ec.json
new file mode 100644
index 00000000..db801b8c
--- /dev/null
+++ b/includes/api/i18n/sr-ec.json
@@ -0,0 +1,24 @@
+{
+ "@metadata": {
+ "authors": [
+ "Milicevic01",
+ "Aktron"
+ ]
+ },
+ "apihelp-block-description": "Блокирај корисника.",
+ "apihelp-block-param-reason": "Разлог за блокирање.",
+ "apihelp-createaccount-param-name": "Корисничко име.",
+ "apihelp-delete-description": "Обриши страницу.",
+ "apihelp-edit-param-text": "Страница са садржајем.",
+ "apihelp-edit-param-minor": "Мања измена.",
+ "apihelp-edit-example-edit": "Уређивање странице.",
+ "apihelp-emailuser-description": "Слање е-поруке кориснику",
+ "apihelp-emailuser-param-target": "Корисник је послао е-поруку.",
+ "apihelp-feedcontributions-param-year": "Од године (и раније).",
+ "apihelp-filerevert-description": "Вратити датотеку у ранију верзију.",
+ "apihelp-help-example-recursive": "Сва помоћ у једној страници.",
+ "apihelp-login-param-name": "Корисничко име.",
+ "apihelp-login-param-password": "Лозинка.",
+ "apihelp-login-example-login": "Пријавa.",
+ "apihelp-move-description": "Премештање странице."
+}
diff --git a/includes/api/i18n/sr-el.json b/includes/api/i18n/sr-el.json
new file mode 100644
index 00000000..55611f08
--- /dev/null
+++ b/includes/api/i18n/sr-el.json
@@ -0,0 +1,11 @@
+{
+ "@metadata": {
+ "authors": [
+ "Milicevic01"
+ ]
+ },
+ "apihelp-block-description": "Blokiraj korisnika.",
+ "apihelp-block-param-reason": "Razlog za blokiranje.",
+ "apihelp-delete-description": "Obriši stranicu.",
+ "apihelp-edit-param-minor": "Manja izmena."
+}
diff --git a/includes/api/i18n/sv.json b/includes/api/i18n/sv.json
new file mode 100644
index 00000000..aa88484f
--- /dev/null
+++ b/includes/api/i18n/sv.json
@@ -0,0 +1,372 @@
+{
+ "@metadata": {
+ "authors": [
+ "Jopparn",
+ "Lokal Profil",
+ "WikiPhoenix",
+ "Victorsa",
+ "Albinomamba",
+ "Peki01",
+ "Stens51",
+ "Boom",
+ "Jenniesarina",
+ "Marfuas",
+ "VickyC"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-postlista]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aviseringar]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R|Buggar & förslag]\n</div>\n<strong>Status:</strong> Alla funktioner som visas på denna sida borde fungera. API:et är dock fortfarande under aktiv utveckling och kan ändras när som helst. Prenumerera på [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/mediawiki-api-announce e-postlistan] för att få aviseringar om uppdateringar.\n\n<strong>Felaktiga förfrågningar:</strong> När felaktiga förfrågningar skickas till API:et skickas en HTTP-header med nyckeln \"MediaWiki-API-Error\" och sedan sätts både värdet på headern och den felkoden som returneras till samma värde. För mer information läs [[mw:API:Errors_and_warnings|API: Fel och varningar]].",
+ "apihelp-main-param-action": "Vilken åtgärd som ska utföras.",
+ "apihelp-main-param-format": "Formatet för utdata.",
+ "apihelp-main-param-smaxage": "Ange headervärdet <code>s-maxage</code> till så här många sekunder. Fel cachelagras aldrig.",
+ "apihelp-main-param-maxage": "Ange headervärdet <code>max-age</code> till så här många sekunder. Fel cachelagras aldrig.",
+ "apihelp-main-param-assert": "Bekräftar att användaren är inloggad om satt till <kbd>user</kbd>, eller har bot-användarrättigheter om satt till <kbd>bot</kbd>.",
+ "apihelp-main-param-requestid": "Alla värde som anges här kommer att inkluderas i svaret. Kan användas för att särskilja förfrågningar.",
+ "apihelp-main-param-servedby": "Inkludera det värdnamn som besvarade förfrågan i resultatet.",
+ "apihelp-main-param-curtimestamp": "Inkludera den aktuella tidsstämpeln i resultatet.",
+ "apihelp-main-param-origin": "När API:et används genom en cross-domain AJAX-begäran (CORS), ange detta till den ursprungliga domänen. Detta måste inkluderas i alla pre-flight-begäran, och mpste därför vara en del av den begärda URI:n (inte i POST-datat). Detta måste överensstämma med en av källorna i headern <code>Origin</code> exakt, så den måste sättas till något i stil med <kbd>http://en.wikipedia.org</kbd> eller <kbd>https://meta.wikimedia.org</kbd>. Om denna parameter inte överensstämmer med headern <code>Origin</code>, returneras ett 403-svar. Om denna parameter överensstämmer med headern <code>Origin</code> och källan är vitlistad, sätts en <code>Access-Control-Allow-Origin</code>-header.",
+ "apihelp-main-param-uselang": "Språk som ska användas för meddelandeöversättningar. En lista med koder kan hämtas från <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages</kbd>, eller ange <kbd>user</kbd> för att använda den aktuella användarens språkpreferenser, eller ange <kbd>content</kbd> för att använda innehållsspråket.",
+ "apihelp-block-description": "Blockera en användare.",
+ "apihelp-block-param-user": "Användare, IP-adress eller IP-intervall du vill blockera.",
+ "apihelp-block-param-expiry": "Förfallotid. Kan vara Kan vara relativt (t.ex. <kbd>5 months</kbd> eller <kbd>2 weeks</kbd>) eller absolut (t.ex. <kbd>2014-09-18T12:34:56Z</kbd>). Om satt till <kbd>infinite</kbd>, <kbd>indefinite</kbd> eller <kbd>never</kbd>, kommer blockeringen aldrig att löpa ut.",
+ "apihelp-block-param-reason": "Orsak till blockering.",
+ "apihelp-block-param-anononly": "Blockera endast anonyma användare (t.ex. inaktivera anonyma redigeringar för denna IP-adress).",
+ "apihelp-block-param-nocreate": "Förhindra registrering av användarkonton.",
+ "apihelp-block-param-autoblock": "Blockera automatiskt den senast använda IP-adressen, och alla efterföljande IP-adresser de försöker logga in från.",
+ "apihelp-block-param-noemail": "Hindra användaren från att skicka e-post via wikin. (Kräver rättigheten <code>blockemail</code>).",
+ "apihelp-block-param-hidename": "Döljer användarnamnet från blockeringsloggen. (Kräver rättigheten <code>hideuser</code>).",
+ "apihelp-block-param-allowusertalk": "Låt användaren redigera sin egen diskussionssida (beror på <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
+ "apihelp-block-param-reblock": "Skriv över befintlig blockering om användaren redan är blockerad.",
+ "apihelp-block-param-watchuser": "Bevaka användarens eller IP-adressens användarsida och diskussionssida",
+ "apihelp-block-example-ip-simple": "Blockera IP-adressen <kbd>192.0.2.5</kbd> i tre dagar med motivationen <kbd>First strike</kbd>",
+ "apihelp-block-example-user-complex": "Blockera användare <kbd>Vandal</kbd> på obegränsad tid med motivationen <kbd>Vandalism</kbd>, och förhindra kontoskapande och e-post.",
+ "apihelp-clearhasmsg-description": "Rensa <code>hasmsg</code>-flaggan för den aktuella användaren.",
+ "apihelp-clearhasmsg-example-1": "Rensa <code>hasmsg</code>-flaggan för den aktuella användaren",
+ "apihelp-compare-description": "Hämta skillnaden mellan två sidor.\n\nEtt versionsnummer, en sidtitel, eller ett sid-Id för både \"from\" och \"to\" måste skickas.",
+ "apihelp-compare-param-fromtitle": "Första titeln att jämföra.",
+ "apihelp-compare-param-fromid": "Första sid-ID att jämföra.",
+ "apihelp-compare-param-fromrev": "Första version att jämföra.",
+ "apihelp-compare-param-totitle": "Andra titeln att jämföra.",
+ "apihelp-compare-param-toid": "Andra sid-ID att jämföra.",
+ "apihelp-compare-param-torev": "Andra version att jämföra.",
+ "apihelp-compare-example-1": "Skapa en diff mellan version 1 och 2",
+ "apihelp-createaccount-description": "Skapa ett nytt användarkonto.",
+ "apihelp-createaccount-param-name": "Användarnamn.",
+ "apihelp-createaccount-param-password": "Lösenord (ignoreras om <var>$1mailpassword</var> angetts).",
+ "apihelp-createaccount-param-domain": "Domän för extern autentisering (frivillig).",
+ "apihelp-createaccount-param-token": "Nyckel för kontoskapande erhölls i första begäran.",
+ "apihelp-createaccount-param-email": "Användarens e-postadress (valfritt).",
+ "apihelp-createaccount-param-realname": "Användarens riktiga namn (valfritt).",
+ "apihelp-createaccount-param-mailpassword": "Om satt till ett värde, skickas ett slumpmässigt lösenord till användaren via e-post.",
+ "apihelp-createaccount-param-reason": "Valfri anledning för att skapa kontot för att läggas till i loggarna.",
+ "apihelp-createaccount-param-language": "Språkkod att använda som standard för användaren (valfri, standardvärdet är innehållsspråket).",
+ "apihelp-createaccount-example-pass": "Skapa användaren <kbd>testuser</kbd> med lösenordet <kbd>test123</kbd>",
+ "apihelp-createaccount-example-mail": "Skapa användaren <kbd>testmailuser</kbd> och skicka ett slumpgenererat lösenord via e-post",
+ "apihelp-delete-description": "Radera en sida.",
+ "apihelp-delete-param-title": "Titel på sidan du vill radera. Kan inte användas tillsammans med <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "Sid-ID för sidan att radera. Kan inte användas tillsammans med <var>$1titel</var>.",
+ "apihelp-delete-param-reason": "Orsak till radering. Om orsak inte ges kommer en orsak att automatiskt genereras och användas.",
+ "apihelp-delete-param-watch": "Lägg till sidan i aktuell användares bevakningslista.",
+ "apihelp-delete-param-watchlist": "Lägg till eller ta bort sidan ovillkorligen från den aktuella användarens bevakningslista, använd inställningar eller ändra inte bevakning.",
+ "apihelp-delete-param-unwatch": "Ta bort sidan från aktuell användares bevakningslista.",
+ "apihelp-delete-param-oldimage": "Namnet på den gamla bilden att radera som tillhandahålls av [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+ "apihelp-delete-example-simple": "Radera <kbd>huvudsidan</kbd>.",
+ "apihelp-delete-example-reason": "Raderar <kbd>huvudsidan</kbd> med orsaken <kbd>Förbereder flyttning</kbd>.",
+ "apihelp-disabled-description": "Denna modul har inaktiverats.",
+ "apihelp-edit-description": "Skapa och redigera sidor.",
+ "apihelp-edit-param-title": "Titel på sidan du vill redigera. Kan inte användas tillsammans med <var>$1pageid</var>.",
+ "apihelp-edit-param-pageid": "Sid-ID för sidan du vill redigera. Kan inte användas tillsammans med <var>$1titel</var>.",
+ "apihelp-edit-param-section": "Avsnittsnummer. <kbd>0</kbd> för det översta avsnittet, <kbd>new</kbd> för ett nytt avsnitt.",
+ "apihelp-edit-param-sectiontitle": "Rubriken för ett nytt avsnitt.",
+ "apihelp-edit-param-text": "Sidans innehåll.",
+ "apihelp-edit-param-summary": "Redigeringssammanfattning. Även avsnittets rubrik när $1section=new och $1sectiontitle inte anges.",
+ "apihelp-edit-param-minor": "Mindre redigering.",
+ "apihelp-edit-param-notminor": "Icke-mindre redigering.",
+ "apihelp-edit-param-bot": "Markera denna redigering som robotredigering.",
+ "apihelp-edit-param-basetimestamp": "Tidsstämpel för grundversionen, används för att upptäcka redigeringskonflikter. Kan erhållas genom [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
+ "apihelp-edit-param-starttimestamp": "Tidsstämpel för när redigeringsprocessen började, används för att upptäcka redigeringskonflikter. Ett lämpligt värde kan erhållas via <var>[[Special:ApiHelp/main|curtimestamp]]</var> när redigeringsprocessen startas (t.ex. när sidans innehåll laddas för redigering).",
+ "apihelp-edit-param-recreate": "Ignorera felmeddelande om sidan har blivit raderad under tiden.",
+ "apihelp-edit-param-createonly": "Redigera inte sidan om den redan finns.",
+ "apihelp-edit-param-nocreate": "Kasta ett fel om sidan inte finns.",
+ "apihelp-edit-param-watch": "Lägg till sidan i den aktuella användarens bevakningslista.",
+ "apihelp-edit-param-unwatch": "Ta bort sidan från aktuell användares bevakningslista.",
+ "apihelp-edit-param-watchlist": "Lägg till eller ta bort sidan ovillkorligen från den aktuella användarens bevakningslista, använd inställningar eller ändra inte bevakning.",
+ "apihelp-edit-param-md5": "MD5-hash för $1text-parametern, eller $1prependtext- och $1appendtext-parametrarna sammanfogade.",
+ "apihelp-edit-param-prependtext": "Lägg till denna text i början på sidan. Ersätter $1text.",
+ "apihelp-edit-param-appendtext": "Lägg till denna text i slutet på sidan. Ersätter $1text.\n\nAnvänd $1section=new för att lägga till en ny sektion, hellre än denna parameter.",
+ "apihelp-edit-param-redirect": "Åtgärda automatiskt omdirigeringar.",
+ "apihelp-edit-param-contentformat": "Det serialiseringsformat som används för indatatexten.",
+ "apihelp-edit-param-contentmodel": "Det nya innehållets innehållsmodell.",
+ "apihelp-edit-param-token": "Token ska alltid skickas som sista parameter, eller åtminstone efter $1text-parametern",
+ "apihelp-edit-example-edit": "Redigera en sida",
+ "apihelp-emailuser-description": "Skicka e-post till en användare.",
+ "apihelp-emailuser-param-target": "Användare att skicka e-post till.",
+ "apihelp-emailuser-param-subject": "Ämnesrubrik.",
+ "apihelp-emailuser-param-text": "E-postmeddelandets innehåll.",
+ "apihelp-emailuser-param-ccme": "Skicka en kopia av detta e-postmeddelande till mig.",
+ "apihelp-emailuser-example-email": "Skicka ett e-postmeddelande till användaren <kbd>WikiSysop</kbd> med texten <kbd>Content</kbd>.",
+ "apihelp-expandtemplates-description": "Expanderar alla mallar i wikitext.",
+ "apihelp-expandtemplates-param-title": "Sidans rubrik.",
+ "apihelp-expandtemplates-param-text": "Wikitext att konvertera.",
+ "apihelp-expandtemplates-param-revid": "Revision ID, för <nowiki>{{REVISIONID}}</nowiki> och liknande variabler.",
+ "apihelp-expandtemplates-param-includecomments": "Om HTML-kommentarer skall inkluderas i utdata.",
+ "apihelp-expandtemplates-param-generatexml": "Generera ett XML tolknings träd (ersatt av $1prop=parsetree).",
+ "apihelp-expandtemplates-example-simple": "Expandera wikitexten <kbd><nowiki>{{Projekt:Sandbox}}</nowiki></kbd>.",
+ "apihelp-feedcontributions-description": "Returnerar en användares bidragsflöde.",
+ "apihelp-feedcontributions-param-feedformat": "Flödets format.",
+ "apihelp-feedcontributions-param-user": "De användare vars bidrag ska hämtas.",
+ "apihelp-feedcontributions-param-namespace": "Vilken namnrymd att filtrera bidrag med.",
+ "apihelp-feedcontributions-param-year": "Från år (och tidigare).",
+ "apihelp-feedcontributions-param-month": "Från månad (och tidigare).",
+ "apihelp-feedcontributions-param-tagfilter": "Filtrera bidrag som har dessa taggar.",
+ "apihelp-feedcontributions-param-deletedonly": "Visa bara borttagna bidrag.",
+ "apihelp-feedcontributions-param-toponly": "Visa endast ändringar som är senaste revideringen.",
+ "apihelp-feedcontributions-param-newonly": "Visa endast redigeringar där sidor skapas.",
+ "apihelp-feedcontributions-param-showsizediff": "Visa skillnaden i storlek mellan revisioner.",
+ "apihelp-feedcontributions-example-simple": "Returnera bidrag för <kbd>Exempel</kbd>",
+ "apihelp-feedrecentchanges-description": "Returnerar ett flöde med senaste ändringar.",
+ "apihelp-feedrecentchanges-param-feedformat": "Flödets format.",
+ "apihelp-feedrecentchanges-param-namespace": "Namnrymder att begränsa resultaten till.",
+ "apihelp-feedrecentchanges-param-invert": "Alla namnrymder utom den valda.",
+ "apihelp-feedrecentchanges-param-days": "Dagar att begränsa resultaten till.",
+ "apihelp-feedrecentchanges-param-limit": "Maximalt antal resultat att returnera.",
+ "apihelp-feedrecentchanges-param-from": "Visa förändringar sedan dess.",
+ "apihelp-feedrecentchanges-param-hideminor": "Dölj mindre ändringar.",
+ "apihelp-feedrecentchanges-param-hidebots": "Dölj robotändringar.",
+ "apihelp-feedrecentchanges-param-hideanons": "Dölj ändringar av oinloggade användare.",
+ "apihelp-feedrecentchanges-param-hideliu": "Dölj ändringar av inloggade användare.",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "Dölj patrullerade ändringar.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Dölj ändringar av aktuell användare.",
+ "apihelp-feedrecentchanges-param-tagfilter": "Filtrera efter tagg.",
+ "apihelp-feedrecentchanges-param-target": "Visa endast ändringarna av sidor som den här sidan länkar till.",
+ "apihelp-feedrecentchanges-param-showlinkedto": "Visa ändringarna på sidor som är länkade till den valda sidan i stället.",
+ "apihelp-feedrecentchanges-example-simple": "Visa senaste ändringar",
+ "apihelp-feedrecentchanges-example-30days": "Visa senaste ändringar för 30 dygn",
+ "apihelp-feedwatchlist-description": "Returnerar ett flöde från bevakningslistan.",
+ "apihelp-feedwatchlist-param-feedformat": "Flödets format.",
+ "apihelp-feedwatchlist-param-hours": "Lista sidor ändrade inom så här många timmar från nu.",
+ "apihelp-feedwatchlist-param-linktosections": "Länka direkt till ändrade avsnitt om möjligt.",
+ "apihelp-feedwatchlist-example-default": "Visa flödet från bevakningslistan.",
+ "apihelp-feedwatchlist-example-all6hrs": "Visa alla ändringar på besökta sidor under de senaste sex timmarna.",
+ "apihelp-filerevert-description": "Återställ en fil till en äldre version.",
+ "apihelp-filerevert-param-filename": "Målfilens namn, utan prefixet Fil:.",
+ "apihelp-filerevert-param-comment": "Ladda upp kommentar.",
+ "apihelp-filerevert-param-archivename": "Arkiv-namn för revisionen att gå tillbaka till.",
+ "apihelp-filerevert-example-revert": "Återställ <kbd>Wiki.png</kbd> till versionen från <kbd>2011-03-05T15:27:40Z</kbd>",
+ "apihelp-help-description": "Visa hjälp för de angivna modulerna.",
+ "apihelp-help-param-modules": "Vilka moduler som hjälpen ska visas för (värdena på parametrarna <var>action</var> och <var>format</var>, eller <kbd>main</kbd>). Undermoduler kan anges med ett plustecken (<kbd>+</kbd>).",
+ "apihelp-help-param-submodules": "Inkludera hjälp för undermoduler av den namngivna modulen.",
+ "apihelp-help-param-recursivesubmodules": "Inkludera hjälp för undermoduler rekursivt.",
+ "apihelp-help-param-helpformat": "Formatet för hjälp-utdata.",
+ "apihelp-help-param-wrap": "Omge utdatan i en standard API respons struktur.",
+ "apihelp-help-param-toc": "Inkludera en innehållsförteckning i HTML-utdata.",
+ "apihelp-help-example-main": "Hjälp för huvudmodul",
+ "apihelp-help-example-recursive": "All hjälp på en sida",
+ "apihelp-help-example-help": "Hjälp för själva hjälpmodulen",
+ "apihelp-imagerotate-description": "Rotera en eller flera bilder.",
+ "apihelp-imagerotate-param-rotation": "Grader att rotera bild medurs.",
+ "apihelp-imagerotate-example-simple": "Rotera <kbd>File:Example.png</kbd> med <kbd>90</kbd> grader",
+ "apihelp-imagerotate-example-generator": "Rotera alla bilder i <kbd>Category:Flip</kbd> med <kbd>180</kbd> grader.",
+ "apihelp-import-description": "Importera en sida från en annan wiki, eller en XML fil. \n\nNotera att HTTP POST måste bli gjord som en fil uppladdning (d.v.s med multipart/form-data) när man skickar en fil för <var>xml</var> parametern.",
+ "apihelp-import-param-summary": "Importera sammanfattning.",
+ "apihelp-import-param-xml": "Uppladdad XML-fil.",
+ "apihelp-import-param-interwikisource": "För interwiki-importer: wiki som du vill importera från.",
+ "apihelp-import-param-interwikipage": "För interwiki-importer: sidan som du vill importera.",
+ "apihelp-import-param-fullhistory": "För interwiki-importer: importera hela historiken, inte bara den aktuella versionen.",
+ "apihelp-import-param-templates": "För interwiki-importer: importera även alla mallar som ingår.",
+ "apihelp-import-param-namespace": "För interwiki-importer: importera till denna namnrymd.",
+ "apihelp-import-param-rootpage": "Importera som undersida till denna sida.",
+ "apihelp-import-example-import": "Importera [[meta:Help:Parserfunktioner]] till namnrymd 100 med full historik.",
+ "apihelp-login-description": "Logga in och hämta autentiserings-cookies.\n\nOm inloggningen lyckas, finns de cookies som krävs med i HTTP-svarshuvuden. Om inloggningen misslyckas kan ytterligare försök per tidsenhet begränsas, som ett sätt att försöka minska risken för automatiserade lösenordsgissningar.",
+ "apihelp-login-param-name": "Användarnamn.",
+ "apihelp-login-param-password": "Lösenord.",
+ "apihelp-login-param-domain": "Domän (valfritt).",
+ "apihelp-login-param-token": "Login nyckel erhållen i första begäran.",
+ "apihelp-login-example-gettoken": "Hämta en login nyckel.",
+ "apihelp-login-example-login": "Logga in",
+ "apihelp-logout-description": "Logga ut och rensa sessionsdata.",
+ "apihelp-logout-example-logout": "Logga ut den aktuella användaren",
+ "apihelp-managetags-description": "Utför hanterings uppgifter relaterade till förändrings taggar.",
+ "apihelp-managetags-param-tag": "Tagg för att skapa, radera, aktivera eller inaktivera. Vid skapande av tagg kan taggen inte existera. Vid raderande av tagg måste taggen existera. För aktiverande av tagg måste taggen existera och inte användas i ett tillägg. För inaktivering av tagg måste taggen användas just nu och vara manuellt definierad.",
+ "apihelp-managetags-param-reason": "En icke-obligatorisk orsak för att skapa, radera, aktivera, eller inaktivera taggen.",
+ "apihelp-managetags-param-ignorewarnings": "Om du vill ignorera varningar som utfärdas under operationen.",
+ "apihelp-managetags-example-create": "Skapa en tagg vid namn <kbd>spam</kbd> med anledningen: <kbd>För användning i redigerings patrullering</kbd>",
+ "apihelp-managetags-example-delete": "Radera <kbd>vandalims</kbd> taggen med andledningen: <kbd>Felstavat</kbd>",
+ "apihelp-managetags-example-activate": "Aktivera en tagg med namn <kbd>spam</kbd> med anledningen: <kbd>För användning i redigerings patrullering</kbd>",
+ "apihelp-managetags-example-deactivate": "Inaktivera en tagg vid namn <kbd>spam</kbd> med anledningen: <kbd>Inte längre behövd</kbd>",
+ "apihelp-move-description": "Flytta en sida.",
+ "apihelp-move-param-from": "Titeln på sidan du vill flytta. Kan inte användas tillsammans med <var>$1fromid</var>.",
+ "apihelp-move-param-fromid": "Sid-ID för sidan att byta namn. Kan inte användas tillsammans med <var>$1from</var>.",
+ "apihelp-move-param-to": "Titel att byta namn på sidan till.",
+ "apihelp-move-param-reason": "Orsak till namnbytet.",
+ "apihelp-move-param-movetalk": "Byt namn på diskussionssidan, om den finns.",
+ "apihelp-move-param-movesubpages": "Byt namn på undersidor, om tillämpligt.",
+ "apihelp-move-param-noredirect": "Skapa inte en omdirigering.",
+ "apihelp-move-param-watch": "Lägg till sidan och omdirigeringen till den aktuella användarens bevakningslista.",
+ "apihelp-move-param-unwatch": "Ta bort sidan och omdirigeringen från den aktuella användarens bevakningslista.",
+ "apihelp-move-param-watchlist": "Lägg till eller ta bort sidan ovillkorligen från den aktuella användarens bevakningslista, använd inställningar eller ändra inte bevakning.",
+ "apihelp-move-param-ignorewarnings": "Ignorera alla varningar.",
+ "apihelp-move-example-move": "Flytta <kbd>Felaktig titel</kbd> till <kbd>Korrekt titel</kbd> utan att lämna en omdirigering.",
+ "apihelp-opensearch-description": "Sök wikin med protokollet OpenSearch.",
+ "apihelp-opensearch-param-search": "Söksträng.",
+ "apihelp-opensearch-param-limit": "Maximalt antal resultat att returnera.",
+ "apihelp-opensearch-param-namespace": "Namnrymder att genomsöka.",
+ "apihelp-opensearch-param-suggest": "Gör ingenting om <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> är falskt.",
+ "apihelp-opensearch-param-format": "Formatet för utdata.",
+ "apihelp-opensearch-example-te": "Hitta sidor som börjar med <kbd>Te</kbd>.",
+ "apihelp-options-param-reset": "Återställer inställningarna till sidans standardvärden.",
+ "apihelp-options-example-reset": "Återställ alla inställningar",
+ "apihelp-options-example-complex": "Återställ alla inställningar, ställ sedan in <kbd>skin</kbd> och <kbd>nickname</kbd>.",
+ "apihelp-paraminfo-description": "Få information om API moduler.",
+ "apihelp-paraminfo-param-helpformat": "Format för hjälpsträngar.",
+ "apihelp-paraminfo-param-mainmodule": "Få information om huvud-modulen (top-level) också. Använd <kbd>$1modules=main</kbd> istället.",
+ "apihelp-parse-param-summary": "Sammanfattning att tolka.",
+ "apihelp-parse-param-page": "Tolka innehållet av denna sida. Kan inte användas tillsammans med <var>$1text</var> och <var>$1title</var>.",
+ "apihelp-parse-param-pageid": "Tolka innehållet på denna sida. Åsidosätter <var>$1sidan</var>.",
+ "apihelp-parse-param-preview": "Tolka i preview-läget.",
+ "apihelp-parse-example-page": "Tolka en sida.",
+ "apihelp-parse-example-text": "Tolka wikitext.",
+ "apihelp-parse-example-texttitle": "Tolka wikitext, specificera sid-titeln.",
+ "apihelp-parse-example-summary": "Tolka en sammanfattning.",
+ "apihelp-patrol-description": "Patrullera en sida eller en version.",
+ "apihelp-patrol-param-revid": "Versions ID att patrullera.",
+ "apihelp-patrol-example-rcid": "Patrullera en nykommen ändring.",
+ "apihelp-patrol-example-revid": "Patrullera en sidversion",
+ "apihelp-protect-description": "Ändra skyddsnivån för en sida.",
+ "apihelp-protect-example-protect": "Skydda en sida",
+ "apihelp-query-param-list": "Vilka listor att hämta.",
+ "apihelp-query-param-meta": "Vilka metadata att hämta.",
+ "apihelp-query+allcategories-param-dir": "Riktning att sortera mot.",
+ "apihelp-query+allcategories-param-min": "Returnera endast kategorier med minst så här många medlemmar.",
+ "apihelp-query+allcategories-param-max": "Returnera endast kategorier med som mest så här många medlemmar.",
+ "apihelp-query+allcategories-param-limit": "Hur många kategorier att returnera.",
+ "apihelp-query+alldeletedrevisions-description": "Lista alla raderade revisioner av en användare or inom en namnrymd.",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kan endast användas med <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Kan inte användas med <var>$3user</var>.",
+ "apihelp-query+alldeletedrevisions-param-from": "Börja lista vid denna titel.",
+ "apihelp-query+alldeletedrevisions-param-to": "Sluta lista vid denna titel.",
+ "apihelp-query+alldeletedrevisions-param-prefix": "Sök alla sid-titlar som börjar med detta värde.",
+ "apihelp-query+alldeletedrevisions-param-tag": "Lista bara revideringar taggade med denna tagg.",
+ "apihelp-query+alldeletedrevisions-param-user": "Lista bara revideringar av denna användaren.",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "Lista inte revideringar av denna användaren.",
+ "apihelp-query+alldeletedrevisions-param-namespace": "Lista bara sidor i denna namnrymd.",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "Lista dem första 50 revideringarna i huvud-namnrymden",
+ "apihelp-query+allfileusages-description": "Lista all fil användningsområden, inklusive icke-existerande.",
+ "apihelp-query+allfileusages-param-prefix": "Sök för all fil-titlar som börjar med detta värde.",
+ "apihelp-query+allfileusages-param-limit": "Hur många saker att returnera totalt.",
+ "apihelp-query+allfileusages-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+allfileusages-example-unique": "Lista unika filtitlar",
+ "apihelp-query+allfileusages-example-unique-generator": "Hämtar alla fil titlar, markerar dem saknade.",
+ "apihelp-query+allfileusages-example-generator": "Hämtar sidor som innehåller filerna.",
+ "apihelp-query+allimages-param-sort": "Egenskap att sortera efter.",
+ "apihelp-query+allimages-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+allimages-param-prefix": "Sök för alla bild titlar som börjar med detta värde. Kan endast användas med $1sort=name.",
+ "apihelp-query+allimages-param-minsize": "Begränsning på bilder med åtminstone så här många bytes.",
+ "apihelp-query+allimages-param-maxsize": "Begränsning på bilder med som mest så här många bytes.",
+ "apihelp-query+allimages-param-sha1": "SHA1 hash av bild. Åsidosätter $1sha1base36.",
+ "apihelp-query+allimages-param-sha1base36": "SHA1 hash av bild i bas 36 (används i MediaWiki).",
+ "apihelp-query+allimages-param-user": "Returnera enbart filer uppladdade av denna användare. Kan enbart användas med $1sort=timestamp. Kan inte användas tillsammans med $1filterbots.",
+ "apihelp-query+allimages-param-filterbots": "Hur man filtrerar filer uppladdade av bots. Kan enbart användas med $1sort=timestamp. Kan inte användas tillsammans med $1user.",
+ "apihelp-query+allimages-param-mime": "Vilka MIME-typer du vill söka efter, t.ex. <kbd>image/jpeg</kbd>.",
+ "apihelp-query+allimages-param-limit": "Hur många bilder att returnera totalt.",
+ "apihelp-query+allimages-example-B": "Visa en lista över filer som börjar på bokstaven <kbd>B</kbd>.",
+ "apihelp-query+allimages-example-recent": "Visa en lista över nyligen överförda filer, ungefär som [[Special:Nya_filer]].",
+ "apihelp-query+allimages-example-mimetypes": "Visa en lista över filer med MIME-typen <kbd>image/png</kbd> eller <kbd>image/gif</kbd>",
+ "apihelp-query+allimages-example-generator": "Visa info om 4 filer som börjar med bokstaven <kbd>T</kbd>.",
+ "apihelp-query+alllinks-param-prefix": "Sök alla länkade titlar som börjar med detta värde.",
+ "apihelp-query+alllinks-param-limit": "Hur många saker att returnera totalt.",
+ "apihelp-query+alllinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+alllinks-example-B": "Lista länkade titlar, inkluderade saknade, med dem sid-IDs dem är från, med början vid <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-unique": "Lista unika länkade titlar.",
+ "apihelp-query+alllinks-example-unique-generator": "Hämtar alla länkade titlar, markera de saknade.",
+ "apihelp-query+alllinks-example-generator": "Hämtar sidor som innehåller länkarna.",
+ "apihelp-query+allmessages-description": "Returnera meddelande från denna sida.",
+ "apihelp-query+allmessages-param-messages": "Vilka meddelande att ge som utdata. <kbd>*</kbd> (standard) betyder alla meddelande .",
+ "apihelp-query+allmessages-param-prop": "Vilka egenskaper att hämta.",
+ "apihelp-query+allmessages-param-args": "Argument som ska substitueras i meddelandet.",
+ "apihelp-query+allmessages-param-filter": "Returnera enbart meddelande med namn som innehåller denna sträng.",
+ "apihelp-query+allmessages-param-customised": "Returnera endast meddelanden i detta anpassningstillstånd.",
+ "apihelp-query+allmessages-param-lang": "Returnera meddelanden på detta språk.",
+ "apihelp-query+allmessages-param-from": "Returnera meddelanden med början på detta meddelande.",
+ "apihelp-query+allmessages-param-to": "Returnera meddelanden fram till och med detta meddelande.",
+ "apihelp-query+allmessages-param-title": "Sidnamn som ska användas som kontext vid parsning av meddelande (för alternativet $1enableparser).",
+ "apihelp-query+allmessages-param-prefix": "Returnera meddelanden med detta prefix.",
+ "apihelp-query+allmessages-example-ipb": "Visa meddelanden som börjar med <kbd>ipb-</kbd>.",
+ "apihelp-query+allmessages-example-de": "Visa meddelanden <kbd>august</kbd> och <kbd>mainpage</kbd> på tyska.",
+ "apihelp-query+allpages-param-prefix": "Sök efter alla sidtitlar som börjar med detta värde.",
+ "apihelp-query+allpages-param-filterredir": "Vilka sidor att lista.",
+ "apihelp-query+allpages-param-minsize": "Begränsa till sidor med detta antal byte eller fler.",
+ "apihelp-query+allpages-param-maxsize": "Begränsa till sidor med högst så här många byte.",
+ "apihelp-query+allpages-param-prtype": "Begränsa till endast skyddade sidor.",
+ "apihelp-query+allpages-param-limit": "Hur många sidor att returnera totalt.",
+ "apihelp-query+allpages-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+allpages-example-B": "Visa en lista över sidor som börjar på bokstaven <kbd>B</kbd>.",
+ "apihelp-query+allredirects-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+allredirects-example-unique-generator": "Hämtar alla målsidor, markerar de som saknas.",
+ "apihelp-query+alltransclusions-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+allusers-param-prefix": "Sök för alla användare som börjar med detta värde.",
+ "apihelp-query+allusers-param-dir": "Riktning att sortera i.",
+ "apihelp-query+allusers-param-group": "Inkludera bara användare i de givna grupperna.",
+ "apihelp-query+allusers-param-excludegroup": "Exkludera användare i de givna grupperna.",
+ "apihelp-query+allusers-param-rights": "Inkludera bara användare med de givna rättigheterna. Inkluderar inte rättigheter givna med implicita eller automatiskt promotade grupper som *, användare, eller auto-konfirmerad.",
+ "apihelp-query+allusers-param-limit": "Hur många användarnamn att returnera totalt.",
+ "apihelp-query+allusers-param-witheditsonly": "Lista bara användare som har gjort redigeringar.",
+ "apihelp-query+allusers-param-activeusers": "Lista bara användare aktiva i dem sista $1{{PLURAL:$1|dagen|dagarna}}.",
+ "apihelp-query+allusers-example-Y": "Lista användare som börjar på <kbd>Y</kbd>.",
+ "apihelp-query+backlinks-description": "Hitta alla sidor som länkar till den givna sidan.",
+ "apihelp-query+backlinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+categories-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+duplicatefiles-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+duplicatefiles-example-generated": "Leta efter kopior av alla filer.",
+ "apihelp-query+embeddedin-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+embeddedin-param-limit": "Hur många sidor att returnera totalt.",
+ "apihelp-query+filearchive-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+filearchive-example-simple": "Visa en lista över alla borttagna filer.",
+ "apihelp-query+images-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+imageusage-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+imageusage-example-simple": "Visa sidor med hjälp av [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+imageusage-example-generator": "Hämta information om sidor med hjälp av [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+iwbacklinks-param-limit": "Hur många sidor att returnera totalt.",
+ "apihelp-query+iwbacklinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+iwlinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+langbacklinks-param-limit": "Hur många sidor att returnera totalt.",
+ "apihelp-query+langbacklinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+langbacklinks-example-simple": "Hämta sidor som länkar till [[:fr:Test]].",
+ "apihelp-query+langlinks-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+links-param-dir": "Riktningen att lista mot.",
+ "apihelp-query+protectedtitles-param-limit": "Hur många sidor att returnera totalt.",
+ "apihelp-query+protectedtitles-example-simple": "Lista skyddade titlar.",
+ "apihelp-query+recentchanges-example-simple": "Lista de senaste ändringarna.",
+ "apihelp-query+revisions-example-first5-not-localhost": "Hämta första 5 revideringarna av \"huvudsidan\" och som inte gjorts av anonym användare \"127.0.0.1\"",
+ "apihelp-query+siteinfo-example-simple": "Hämta information om webbplatsen.",
+ "apihelp-query+stashimageinfo-description": "Returnerar filinformation för temporära filer.",
+ "apihelp-query+stashimageinfo-param-filekey": "Nyckel som identifierar en tidigare uppladdning som lagrats temporärt.",
+ "apihelp-query+stashimageinfo-example-simple": "Returnerar information för en temporär fil",
+ "apihelp-query+tags-example-simple": "Lista tillgängliga taggar.",
+ "apihelp-query+userinfo-example-simple": "Få information om den aktuella användaren.",
+ "apihelp-query+userinfo-example-data": "Få ytterligare information om den aktuella användaren.",
+ "apihelp-query+watchlist-description": "Hämta de senaste ändringarna på sidor i den nuvarande användarens bevakningslista.",
+ "apihelp-query+watchlist-example-allrev": "Hämta information om de senaste ändringarna på sidor på den aktuella användarens bevakningslista.",
+ "apihelp-query+watchlist-example-generator": "Hämta sidinformation för nyligen uppdaterade sidor på nuvarande användares bevakningslista.",
+ "apihelp-query+watchlist-example-generator-rev": "Hämta ändringsinformation för nyligen uppdaterade sidor på nuvarande användares bevakningslista.",
+ "apihelp-query+watchlistraw-description": "Hämta alla sidor på den aktuella användarens bevakningslista.",
+ "apihelp-query+watchlistraw-example-simple": "Lista sidor på den aktuella användarens bevakningslista.",
+ "apihelp-setnotificationtimestamp-example-all": "Återställ meddelandestatus för hela bevakningslistan.",
+ "apihelp-upload-param-filekey": "Nyckel som identifierar en tidigare uppladdning som lagrats temporärt.",
+ "apihelp-upload-param-stash": "Om angiven, kommer servern att temporärt lagra filen istället för att lägga till den i centralförvaret.",
+ "apihelp-upload-example-url": "Ladda upp från URL.",
+ "apihelp-upload-example-filekey": "Slutför en uppladdning som misslyckades på grund av varningar.",
+ "api-help-main-header": "Huvudmodul",
+ "api-help-flag-deprecated": "Denna modul är föråldrad.",
+ "api-help-flag-internal": "<strong>Denna modul är intern eller instabil.</strong> Dess funktion kan ändras utan föregående meddelande.",
+ "api-help-flag-readrights": "Denna modul kräver läsrättigheter.",
+ "api-help-flag-writerights": "Denna modul kräver skrivrättigheter.",
+ "api-help-flag-mustbeposted": "Denna modul accepterar endast POST-begäranden.",
+ "api-help-flag-generator": "Denna modul kan användas som en generator.",
+ "api-help-parameters": "{{PLURAL:$1|Parameter|Parametrar}}:",
+ "api-help-param-deprecated": "Föråldrad.",
+ "api-help-param-required": "Denna parameter är obligatorisk.",
+ "api-help-param-list": "{{PLURAL:$1|1=ett värde|2=värden (separade med \"{{!}}\")}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Måste vara tom|Kan vara tom, eller $2}}",
+ "api-help-param-limit": "Inte mer än $1 tillåts.",
+ "api-help-param-limit2": "Inte mer än $1 ($2 för robotar) tillåts."
+}
diff --git a/includes/api/i18n/te.json b/includes/api/i18n/te.json
new file mode 100644
index 00000000..8678f2a2
--- /dev/null
+++ b/includes/api/i18n/te.json
@@ -0,0 +1,8 @@
+{
+ "@metadata": {
+ "authors": [
+ "Veeven"
+ ]
+ },
+ "apihelp-feedrecentchanges-example-simple": "ఇటీవలి మార్పులను చూడండి"
+}
diff --git a/includes/api/i18n/tl.json b/includes/api/i18n/tl.json
new file mode 100644
index 00000000..ddf52d40
--- /dev/null
+++ b/includes/api/i18n/tl.json
@@ -0,0 +1,35 @@
+{
+ "@metadata": {
+ "authors": [
+ "Leeheonjin"
+ ]
+ },
+ "apihelp-feedrecentchanges-example-simple": "Ipakit ang mga kamakailangang pagbabago.",
+ "apihelp-feedrecentchanges-example-30days": "Ipakita ang mga huling pagbabago sa loob para sa 30 araw.",
+ "apihelp-help-example-main": "Tulong para sa pangunahing modulo.",
+ "apihelp-help-example-recursive": "Lahat ng tulong sa iisang pahina.",
+ "apihelp-login-example-login": "Lumagda (Mag-log in).",
+ "apihelp-move-example-move": "I-urong ang <kbd>Badtitle</kbd> sa <kbd>Goodtitle</kbd> nang hindi nag-iiwan ng redirekta.",
+ "apihelp-options-example-reset": "Ibalik sa dati ang lahat ng mga kanaisan.",
+ "apihelp-patrol-example-rcid": "Bantayan ang kasalukuyang pagbabago.",
+ "apihelp-query+allimages-example-B": "Ipakita ang talaan ng mga talakasang nagsisimula sa titik <kbd>B</kbd>.",
+ "apihelp-query+alllinks-example-generator": "Kinukuha ang mga pahinang naglalaman ng mga kawing.",
+ "apihelp-query+allpages-example-B": "Ipakita ang talaan ng mga pahinang nagsisimula sa titik <kbd>B</kbd>.",
+ "apihelp-query+alltransclusions-example-generator": "Kinukuha ang mga pahinang naglalaman ng mga transklusyon.",
+ "apihelp-query+backlinks-example-simple": "Ipakita ang mga kawing sa <kbd>Unang pahina<kbd>.",
+ "apihelp-query+categoryinfo-example-simple": "Kumuha ng impormasyon tungkol sa <kbd>Kategorya:Foo</kbd> at <kbd>Kategorya:Bar</kbd>.",
+ "apihelp-query+duplicatefiles-example-simple": "Maghanap para sa mga duplika ng [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+duplicatefiles-example-generated": "Hanapin ang mga duplika ng lahat ng talakasan.",
+ "apihelp-query+images-example-simple": "Kumuha ng talaan ng mga talakasang ginagamit sa [[Unang Pahina]].",
+ "apihelp-query+imageusage-example-simple": "Ipakita ang mga pahina gamit ang [[:File:Albert Einstein Head.jpg]].",
+ "apihelp-query+iwbacklinks-example-simple": "Kumuha ng mga pahinang nakarugtong sa [[wikibooks:Test]].",
+ "apihelp-query+linkshere-example-generator": "Kumuha ng kabatiran tungkol sa mga pahina na kumakawing sa [[Unang Pahina]].",
+ "apihelp-query+recentchanges-example-simple": "Talaan ng mga kamakailang pagbabago.",
+ "apihelp-query+search-example-text": "Hanapin ang mga teksto para sa <kbd>kahulugan</kbd>.",
+ "apihelp-query+siteinfo-example-simple": "Kunin ang impormasyon ng sityo.",
+ "apihelp-query+templates-example-simple": "Kumuha ng mga suleras o padron na ginamit sa pahinang <kbd>Unang Pahina</kbd>.",
+ "apihelp-query+watchlist-example-simple": "Itala ang mga punong pagbabago ng mga kasalukuyang binagong pahina sa kasalukuyang listahan ng binabantayan ng tagagamit.",
+ "apihelp-revisiondelete-example-revision": "Itago ang nilalaman para sa pagbabago ng <kbd>12345</kbd> sa pahinang <kbd>Unang Pahina</kbd>.",
+ "apihelp-upload-example-url": "Mag-karga mula sa URL.",
+ "apihelp-watch-example-watch": "Bantayan ang pahinang <kbd>Unang Pahina</kbd>."
+}
diff --git a/includes/api/i18n/tr.json b/includes/api/i18n/tr.json
new file mode 100644
index 00000000..3a9ff258
--- /dev/null
+++ b/includes/api/i18n/tr.json
@@ -0,0 +1,40 @@
+{
+ "@metadata": {
+ "authors": [
+ "Sayginer"
+ ]
+ },
+ "apihelp-edit-param-text": "Sayfa içeriği.",
+ "apihelp-edit-param-minor": "Küçük değişiklik.",
+ "apihelp-edit-param-nocreate": "Sayfa mevcut değilse hata oluştur.",
+ "apihelp-edit-param-watch": "Sayfayı izleme listenize ekleyin.",
+ "apihelp-edit-param-unwatch": "Sayfayı izleme listenizden çıkarın.",
+ "apihelp-edit-param-redirect": "Yönlendirmeleri otomatik olarak çöz.",
+ "apihelp-emailuser-description": "Bir kullanıcıya e-posta gönder.",
+ "apihelp-emailuser-param-target": "E-posta gönderilecek kullanıcı.",
+ "apihelp-emailuser-param-subject": "Konu başlığı.",
+ "apihelp-emailuser-param-text": "E-posta metni.",
+ "apihelp-emailuser-param-ccme": "Bu e-postanın bir kopyasını bana gönder.",
+ "apihelp-feedcontributions-param-toponly": "Yalnızca son revizyon olan değişiklikleri göster.",
+ "apihelp-feedcontributions-param-newonly": "Yalnızca yeni sayfa oluşturan değişiklikleri göster.",
+ "apihelp-feedcontributions-param-showsizediff": "Sürümler arasındaki boyut farkını göster.",
+ "apihelp-feedrecentchanges-param-limit": "Verilecek azami sonuç sayısı.",
+ "apihelp-feedrecentchanges-param-hideminor": "Küçük değişiklikleri gizle.",
+ "apihelp-feedrecentchanges-param-hidebots": "Bot değişikliklerini gizle.",
+ "apihelp-feedrecentchanges-param-hideanons": "Anonim kullanıcı değişikliklerini gizle.",
+ "apihelp-feedrecentchanges-param-hideliu": "Kayıtlı kullanıcı değişikliklerini gizle.",
+ "apihelp-feedrecentchanges-param-hidemyself": "Kendi değişikliklerini gizle.",
+ "apihelp-feedrecentchanges-example-simple": "Son değişiklikleri göster",
+ "apihelp-feedrecentchanges-example-30days": "Son 30 gündeki değişiklikleri göster",
+ "apihelp-filerevert-description": "Bir dosyayı eski bir sürümüne geri döndür.",
+ "apihelp-move-description": "Bir sayfayı taşı.",
+ "apihelp-move-param-from": "Taşımak istediğiniz sayfanın başlığı. $1fromid ile birlikte kullanılamaz.",
+ "apihelp-move-param-noredirect": "Yönlendirme oluşturmayın.",
+ "apihelp-opensearch-param-limit": "Verilecek azami sonuç sayısı.",
+ "apihelp-options-example-reset": "Tüm tercihleri sıfırla",
+ "api-help-title": "MediaWiki API yardımı",
+ "api-help-parameters": "{{PLURAL:$1|Parametre|Parametre}}:",
+ "api-help-param-limit": "$1 taneden fazla olamaz.",
+ "api-help-param-limit2": "$1 taneden fazla (botlar için $2) olamaz.",
+ "api-help-param-default": "Varsayılan: $1"
+}
diff --git a/includes/api/i18n/uk.json b/includes/api/i18n/uk.json
new file mode 100644
index 00000000..13ce4907
--- /dev/null
+++ b/includes/api/i18n/uk.json
@@ -0,0 +1,30 @@
+{
+ "@metadata": {
+ "authors": [
+ "Ата",
+ "A1"
+ ]
+ },
+ "apihelp-main-param-action": "Яку дію виконати.",
+ "apihelp-main-param-format": "Формат виводу.",
+ "apihelp-block-description": "Заблокувати користувача.",
+ "apihelp-block-param-user": "Ім'я користувача, IP-адреса або діапазон IP-адрес для блокування.",
+ "apihelp-block-param-reason": "Причина блокування.",
+ "apihelp-block-param-nocreate": "Заборонити створення облікових записів.",
+ "apihelp-createaccount-param-name": "Ім'я користувача.",
+ "apihelp-createaccount-param-password": "Пароль (ігнорується, якщо встановлено <var>$1mailpassword</var>).",
+ "apihelp-createaccount-param-domain": "Домен для зовнішньої аутентифікації (опціонально).",
+ "apihelp-edit-example-edit": "Редагувати сторінку",
+ "apihelp-edit-example-prepend": "Додати зміст на початок сторінки",
+ "apihelp-edit-example-undo": "Скасувати версії з 13579 по 13585 з автоматичним описом змін",
+ "apihelp-emailuser-description": "Надіслати електронного листа користувачеві",
+ "apihelp-emailuser-param-target": "Користувач, якому відправляється електронний лист.",
+ "apihelp-emailuser-param-subject": "Заголовок теми.",
+ "apihelp-emailuser-param-text": "Тіло листа.",
+ "apihelp-emailuser-param-ccme": "Надіслати копію цього повідомлення мені.",
+ "apihelp-emailuser-example-email": "Відправити листа користувачу \"WikiSysop\" з текстом \"Вміст\"",
+ "apihelp-expandtemplates-description": "Розгортає усі шаблони у вікітекст.",
+ "apihelp-expandtemplates-param-title": "Заголовок сторінки.",
+ "apihelp-expandtemplates-param-text": "Вікітекст для перетворення.",
+ "apihelp-move-param-ignorewarnings": "Ігнорувати всі попередження"
+}
diff --git a/includes/api/i18n/vi.json b/includes/api/i18n/vi.json
new file mode 100644
index 00000000..a027d9d8
--- /dev/null
+++ b/includes/api/i18n/vi.json
@@ -0,0 +1,156 @@
+{
+ "@metadata": {
+ "authors": [
+ "Minh Nguyen",
+ "Max20091",
+ "Dinhxuanduyet"
+ ]
+ },
+ "apihelp-main-param-action": "Tác vụ để thực hiện.",
+ "apihelp-main-param-format": "Định dạng của dữ liệu được cho ra.",
+ "apihelp-block-description": "Cấm người dùng.",
+ "apihelp-block-param-user": "Tên truy nhập, địa chỉ IP hoặc dãi IP mà bạn muốn chặn.",
+ "apihelp-block-param-reason": "Lý do cấm.",
+ "apihelp-block-param-nocreate": "Cấm tạo tài khoản.",
+ "apihelp-clearhasmsg-description": "Xóa cờ <code>hasmsg</code> cho người dùng hiện tại.",
+ "apihelp-clearhasmsg-example-1": "Xóa cờ <code>hasmsg</code> cho người dùng hiện tại",
+ "apihelp-compare-param-fromtitle": "So sánh tiêu đề đầu tiên.",
+ "apihelp-compare-param-fromid": "So sánh ID trang đầu tiên.",
+ "apihelp-compare-param-fromrev": "So sánh sửa đổi đầu tiên.",
+ "apihelp-compare-param-totitle": "So sánh tiêu đề thứ hai.",
+ "apihelp-compare-param-toid": "So sánh ID tran thứ hai.",
+ "apihelp-compare-param-torev": "So sánh sửa đổi thứ hai.",
+ "apihelp-compare-example-1": "Tạo một so sánh giữa phiên bản 1 và 2.",
+ "apihelp-createaccount-description": "Mở tài khoản mới.",
+ "apihelp-createaccount-param-name": "Tên người dùng.",
+ "apihelp-createaccount-param-password": "Mật khẩu (được bỏ qua nếu <var>$1mailpassword</var> được đặt).",
+ "apihelp-createaccount-param-domain": "Tên miền để xác thực bên ngoài (tùy chọn).",
+ "apihelp-createaccount-param-token": "Dấu hiệu mở tài khoản được lấy trong yêu cầu đầu tiên.",
+ "apihelp-createaccount-param-email": "Địa chỉ thư điện tử của thành viên (tùy chọn).",
+ "apihelp-createaccount-param-realname": "Tên thật của thành viên (tùy chọn).",
+ "apihelp-createaccount-param-mailpassword": "Nếu đặt bất kỳ giá trị nào, một mật khẩu ngẫu nhiên sẽ được email lại cho người dùng.",
+ "apihelp-createaccount-param-reason": "Lý do tùy chọn cho việc tạo tài khoản để đăng nhập.",
+ "apihelp-createaccount-param-language": "Mã ngôn ngữ để thiết lập mặc định cho người dùng (tùy chọn, mặc định là ngôn ngữ nội dung).",
+ "apihelp-createaccount-example-pass": "Tạo người dùng <kbd>người kiểm tra</kbd> với mật khẩu <kbd>test123</kbd>.",
+ "apihelp-createaccount-example-mail": "Tạo người dùng <kbd>người dùng kiểm tra email> và email một mật khẩu được tạo ra ngẫu nhiên.",
+ "apihelp-delete-description": "Xóa trang.",
+ "apihelp-delete-param-title": "Xóa tiêu đề của trang. Không thể sử dụng cùng với <var>$1pageid</var>.",
+ "apihelp-delete-param-pageid": "Xóa ID của trang. Không thể sử dụng cùng với <var>$1title</var>.",
+ "apihelp-delete-param-watch": "Thêm trang vào danh sách theo dõi của bạn.",
+ "apihelp-delete-param-unwatch": "Bỏ trang này khỏi danh sách theo dõi của bạn.",
+ "apihelp-delete-example-simple": "Xóa Trang Chính",
+ "apihelp-delete-example-reason": "Xóa Trang Chính với lý do “Chuẩn bị di chuyển”",
+ "apihelp-disabled-description": "Mô đun này đã bị vô hiệu hóa.",
+ "apihelp-edit-description": "Tạo và sửa trang.",
+ "apihelp-edit-param-section": "Số phần trang. 0 là phần đầu; “new” là phần mới.",
+ "apihelp-edit-param-sectiontitle": "Tên của phần mới.",
+ "apihelp-edit-param-text": "Nội dung trang.",
+ "apihelp-edit-param-summary": "Tóm lược sửa đổi. Cũng là tên phần khi $1section=new và $1sectiontitle không được đặt.",
+ "apihelp-edit-param-minor": "Sửa đổi nhỏ.",
+ "apihelp-edit-param-notminor": "Sửa đổi không nhỏ.",
+ "apihelp-edit-param-bot": "Đánh dấu sửa đổi này là do bot thực hiện.",
+ "apihelp-edit-param-createonly": "Không sửa đổi trang nếu nó đã tồn tại.",
+ "apihelp-edit-param-nocreate": "Gây lỗi nếu trang không tồn tại.",
+ "apihelp-edit-param-watch": "Thêm trang vào danh sách theo dõi của bạn.",
+ "apihelp-edit-param-unwatch": "Bỏ trang này khỏi danh sách theo dõi của bạn.",
+ "apihelp-edit-param-undo": "Hoàn tác sửa đổi này. Ghi đè $1text, $1prependtext và $ 1appendtext.",
+ "apihelp-edit-param-undoafter": "Hoàn tác tất cả các sửa đổi từ $1undo cho tới sửa đổi này. Nếu không được thiết lập, chỉ cần lùi lại một sửa đổi.",
+ "apihelp-edit-example-edit": "Sửa đổi trang",
+ "apihelp-edit-example-prepend": "Đưa <kbd>_&#95;NOTOC_&#95;</kbd> vào đầu trang",
+ "apihelp-edit-example-undo": "Lùi sửa các thay đổi 13579–13585 và tự động tóm lược",
+ "apihelp-emailuser-description": "Gửi thư cho người dùng.",
+ "apihelp-emailuser-param-target": "Người dùng để gửi thư điện tử cho.",
+ "apihelp-emailuser-param-subject": "Tiêu đề bức thư.",
+ "apihelp-emailuser-param-text": "Nội dung bức thư.",
+ "apihelp-emailuser-param-ccme": "Gửi bản sao của thư này cho tôi.",
+ "apihelp-emailuser-example-email": "Gửi thư điện tử cho thành viên “BQVWiki” với văn bản “Nội dung”",
+ "apihelp-expandtemplates-description": "Bung tất cả bản mẫu trong văn bản wiki.",
+ "apihelp-expandtemplates-param-title": "Tên trang.",
+ "apihelp-expandtemplates-param-text": "Văn bản wiki để bung.",
+ "apihelp-filerevert-param-comment": "Tải lên bình luận.",
+ "apihelp-filerevert-param-archivename": "Tên lưu trữ của bản sửa đổi để trở lại .",
+ "apihelp-filerevert-example-revert": "Hoàn nguyên <kbd>Wiki.png</kbd> veef phiên bản 2011-03-05T15 : 27:40Z",
+ "apihelp-help-description": "Hiển thị trợ giúp cho các mô-đun xác định.",
+ "apihelp-help-param-helpformat": "Định dạng của văn bản trợ giúp được cho ra.",
+ "apihelp-help-example-recursive": "Tất cả trợ giúp trong một trang",
+ "apihelp-help-example-help": "Trợ giúp cho chính bản thân module trợ giúp",
+ "apihelp-help-example-query": "Trợ giúp cho hai module con truy vấn",
+ "apihelp-imagerotate-description": "Xoay một hoặc nhiều hình ảnh.",
+ "apihelp-imagerotate-param-rotation": "Độ xoay hình ảnh theo chiều kim đồng hồ.",
+ "apihelp-imagerotate-example-simple": "Xoay [[:Tập tin:Ví dụ.jpg]] 90 độ",
+ "apihelp-imagerotate-example-generator": "Xoay tất cả các hình ảnh trong [[:Thể loại:Búng]] 180 độ",
+ "apihelp-login-param-name": "Tên người dùng.",
+ "apihelp-login-param-password": "Mật khẩu.",
+ "apihelp-login-param-domain": "Tên miền (tùy chọn).",
+ "apihelp-login-param-token": "Dấu hiệu đăng nhập được lấy trong yêu cầu đầu tiên.",
+ "apihelp-login-example-gettoken": "Lấy dấu hiệu đăng nhập",
+ "apihelp-login-example-login": "Đăng nhập",
+ "apihelp-logout-example-logout": "Đăng xuất người dùng hiện tại",
+ "apihelp-move-description": "Di chuyển trang.",
+ "apihelp-move-param-reason": "Lý do di chuyển.",
+ "apihelp-move-param-noredirect": "Không tạo trang đổi hướng.",
+ "apihelp-move-param-ignorewarnings": "Bỏ qua tất cả các cảnh báo.",
+ "apihelp-opensearch-description": "Tìm kiếm trong wiki qua giao thức OpenSearch.",
+ "apihelp-opensearch-param-search": "Chuỗi tìm kiếm.",
+ "apihelp-opensearch-param-limit": "Đa số kết quả để cho ra.",
+ "apihelp-opensearch-param-namespace": "Không gian tên để tìm kiếm.",
+ "apihelp-opensearch-param-format": "Định dạng kết quả được cho ra.",
+ "apihelp-opensearch-example-te": "Tìm trang bắt đầu với “Te”",
+ "apihelp-options-example-reset": "Mặc định lại các tùy chọn",
+ "apihelp-paraminfo-param-helpformat": "Định dạng chuỗi trợ giúp.",
+ "apihelp-parse-param-summary": "Lời tóm lược để phân tích.",
+ "apihelp-parse-param-section": "Chỉ truy xuất nội dung của số bộ phận này.",
+ "apihelp-parse-param-disablepp": "Vô hiệu hóa phân tích cú pháp đầu ra của Báo cáo PP .",
+ "apihelp-parse-example-page": "Phân tích trang.",
+ "apihelp-parse-example-text": "Phân tích văn bản wiki.",
+ "apihelp-parse-example-texttitle": "Phân tích văn bản wiki theo tên trang.",
+ "apihelp-parse-example-summary": "Phân tích lời tóm lược.",
+ "apihelp-protect-example-protect": "Khóa trang.",
+ "apihelp-protect-example-unprotect": "Mở khóa trang bằng cách đặt hạn chế thành “all”",
+ "apihelp-protect-example-unprotect2": "Mở khóa trang bằng cách không đặt hạn chế nào",
+ "apihelp-purge-param-forcelinkupdate": "Cập nhật các bảng liên kết.",
+ "apihelp-purge-example-generator": "Làm mới 10 trang đầu tiên trong không gian tên chính",
+ "apihelp-query-param-prop": "Các thuộc tính để lấy khi truy vấn các trang.",
+ "apihelp-query-param-list": "Các danh sách để lấy.",
+ "apihelp-query-param-meta": "Siêu dữ liệu để lấy.",
+ "apihelp-query+allcategories-param-dir": "Hướng xếp loại.",
+ "apihelp-rollback-description": "Hoàn tác chỉnh sửa cuối cùng của trang này.\n\nNếu người dùng cuối cùng đã cỉnh sửa trang này nhiều lần, tất cả chúng sẽ được hoàn tác lại như ban đầu.",
+ "apihelp-format-example-generic": "Định dạng kết quả truy vấn dưới dạng $1",
+ "apihelp-dbg-description": "Cho ra dữ liệu dưới dạng var_export() của PHP.",
+ "apihelp-dbgfm-description": "Cho ra dữ liệu dưới dạng var_export() của PHP (định dạng bằng HTML).",
+ "apihelp-dump-description": "Cho ra dữ liệu dưới dạng var_dump() của PHP.",
+ "apihelp-dumpfm-description": "Cho ra dữ liệu dưới dạng var_dump() của PHP (định dạng bằng HTML).",
+ "apihelp-json-description": "Cho ra dữ liệu dưới dạng JSON.",
+ "apihelp-jsonfm-description": "Cho ra dữ liệu dưới dạng JSON (định dạng bằng HTML).",
+ "apihelp-none-description": "Không cho ra gì.",
+ "apihelp-rawfm-description": "Cho ra dữ liệu với các phần tử gỡ lỗi dưới dạng JSON (định dạng bằng HTML).",
+ "apihelp-txt-description": "Cho ra dữ liệu dưới dạng print_r() của PHP.",
+ "apihelp-txtfm-description": "Cho ra dữ liệu dưới dạng print_r() của PHP (định dạng bằng HTML).",
+ "apihelp-wddx-description": "Cho ra dữ liệu dưới dạng WDDX.",
+ "apihelp-wddxfm-description": "Cho ra dữ liệu dưới dạng WDDX (định dạng bằng HTML).",
+ "apihelp-xml-description": "Cho ra dữ liệu dưới dạng XML.",
+ "apihelp-xmlfm-description": "Cho ra dữ liệu dưới dạng XML (định dạng bằng HTML).",
+ "apihelp-yaml-description": "Cho ra dữ liệu dưới dạng YAML.",
+ "apihelp-yamlfm-description": "Cho ra dữ liệu dưới dạng YAML (định dạng bằng HTML).",
+ "api-format-title": "Kết quả API MediaWiki",
+ "api-help-title": "Trợ giúp về API MediaWiki",
+ "api-help-main-header": "Mô đun chính",
+ "api-help-flag-deprecated": "Mô đun này đã bị phản đối.",
+ "api-help-flag-readrights": "Mô đun này cần quyền đọc.",
+ "api-help-flag-writerights": "Mô đun này cần quyền ghi.",
+ "api-help-flag-mustbeposted": "Mô đun này chỉ có nhận các yêu cầu POST.",
+ "api-help-parameters": "{{PLURAL:$1|Tham số|Các tham số}}:",
+ "api-help-param-deprecated": "Bị phản đối.",
+ "api-help-param-required": "Tham số này là bắt buộc.",
+ "api-help-param-list": "{{PLURAL:$1|1=Một giá trị|2=Các giá trị (phân tách bằng “{{!}}”)}}: $2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=Cần phải để trống|Cần phải để trống hoặc là $2}}",
+ "api-help-param-limit": "Không cho phép hơn $1.",
+ "api-help-param-limit2": "Không cho phép hơn $1 ($2 đối với các bot).",
+ "api-help-param-multi-separate": "Phân tách các giá trị bằng “|”.",
+ "api-help-param-default": "Mặc định: $1",
+ "api-help-param-default-empty": "Mặc định: <span class=\"apihelp-empty\">(trống)</span>",
+ "api-help-examples": "{{PLURAL:$1|Ví dụ|Các ví dụ}}:",
+ "api-help-permissions": "{{PLURAL:$1|Quyền hạn|Các quyền hạn}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1}}Cấp cho: $2",
+ "api-credits-header": "Ghi công"
+}
diff --git a/includes/api/i18n/zh-hans.json b/includes/api/i18n/zh-hans.json
new file mode 100644
index 00000000..722803bf
--- /dev/null
+++ b/includes/api/i18n/zh-hans.json
@@ -0,0 +1,782 @@
+{
+ "@metadata": {
+ "authors": [
+ "Gaoxuewei",
+ "Linforest",
+ "Liuxinyu970226",
+ "Papapasan",
+ "LNDDYL",
+ "Shizhao",
+ "Yfdyh000",
+ "JuneAugsut",
+ "EagerLin",
+ "Simon xianyu",
+ "Kuailong"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文档]]\n* [[mw:API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:API:Errors_and_warnings|API: 错误与警告]]。",
+ "apihelp-main-param-action": "要执行的操作。",
+ "apihelp-main-param-format": "输出的格式。",
+ "apihelp-main-param-maxlag": "最大延迟可被用于MediaWiki安装于数据库复制集中。要保存导致更多网站复制延迟的操作,此参数可使客户端等待直到复制延迟少于指定值时。万一发生过多延迟,错误代码<samp>maxlag</samp>会返回消息,例如<samp>等待$host中:延迟$lag秒</samp>。<br />参见[[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]]以获取更多信息。",
+ "apihelp-main-param-smaxage": "设置<code>s-maxage</code>页顶至这些秒。错误不会缓存。",
+ "apihelp-main-param-maxage": "设置<code>max-age</code>页顶至这些秒。错误不会缓存。",
+ "apihelp-main-param-assert": "如果设置为<kbd>user</kbd>就验证用户是否登录,或如果设置为<kbd>bot</kbd>就验证是否有机器人用户权限。",
+ "apihelp-main-param-requestid": "任何在此提供的值将包含在响应中。可能可以用以区别请求。",
+ "apihelp-main-param-servedby": "包含保存结果请求的主机名。",
+ "apihelp-main-param-curtimestamp": "在结果中包括当前时间戳。",
+ "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。这必须匹配<code>Origin</code>中的一个起点:从头到底,因此它已经设置为像<kbd>https://zh.wikipedia.org</kbd>或<kbd>https://meta.wikimedia.org</kbd>的东西。如果此参数不匹配<code>Origin</code>页顶,就返回403错误响应。如果此参数匹配<code>Origin</code>页顶并且起点被白名单,将设置一个<code>Access-Control-Allow-Origin</code>开头。",
+ "apihelp-main-param-uselang": "用于消息翻译的语言。代码列表可从<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>通过<kbd>siprop=languages</kbd>获取,或指定<kbd>user</kbd>以使用当前用户的语言设置,或指定<kbd>content</kbd>以使用此wiki的内容语言。",
+ "apihelp-block-description": "封禁一位用户。",
+ "apihelp-block-param-user": "您要封禁的用户、IP地址或IP地址段。",
+ "apihelp-block-param-expiry": "到期时间。可以是相对时间(例如<kbd>5 months</kbd>或<kbd>2 weeks</kbd>)或绝对时间(例如<kbd>2014-09-18T12:34:56Z</kbd>)。如果设置为<kbd>infinite</kbd>、<kbd>indefinite</kbd>或<kbd>never</kbd>,封禁将无限期。",
+ "apihelp-block-param-reason": "封禁的原因",
+ "apihelp-block-param-anononly": "只封禁匿名用户(也就是说禁止此 IP 地址的匿名编辑)。",
+ "apihelp-block-param-nocreate": "防止创建帐户。",
+ "apihelp-block-param-autoblock": "自动封禁最近使用的IP地址,以及以后他们尝试登陆使用的IP地址。",
+ "apihelp-block-param-noemail": "阻止用户通过wiki发送电子邮件。(需要<code>blockemail</code>权限)。",
+ "apihelp-block-param-hidename": "从封禁日志中隐藏用户名。(需要<code>hideuser</code>权限)。",
+ "apihelp-block-param-allowusertalk": "允许用户编辑自己的讨论页(取决于<var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>)。",
+ "apihelp-block-param-reblock": "如果该用户已被封禁,则覆盖已有的封禁。",
+ "apihelp-block-param-watchuser": "监视用户或该 IP 的用户页和讨论页。",
+ "apihelp-block-example-ip-simple": "封禁IP地址<kbd>192.0.2.5</kbd>三天,原因<kbd>First strike</kbd>。",
+ "apihelp-block-example-user-complex": "无限期封禁用户<kbd>Vandal</kbd>,原因<kbd>Vandalism</kbd>,并阻止新账户创建和电子邮件发送。",
+ "apihelp-checktoken-description": "从<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>检查令牌有效性。",
+ "apihelp-checktoken-param-type": "已开始测试的令牌类型。",
+ "apihelp-checktoken-param-token": "要测试的令牌。",
+ "apihelp-checktoken-param-maxtokenage": "令牌的最大允许年龄,以秒计。",
+ "apihelp-checktoken-example-simple": "测试<kbd>csrf</kbd>令牌的有效性。",
+ "apihelp-clearhasmsg-description": "清除当前用户的<code>hasmsg</code>标记。",
+ "apihelp-clearhasmsg-example-1": "清除当前用户的<code>hasmsg</code>标记。",
+ "apihelp-compare-description": "获得2个页面之间的差别。\n\n用于“from”和“to”的修订版本号、页面标题或页面 ID 必须获得通过。",
+ "apihelp-compare-param-fromtitle": "要比较的第一个标题。",
+ "apihelp-compare-param-fromid": "要比较的第一个页面 ID。",
+ "apihelp-compare-param-fromrev": "要比较的第一个修订版本。",
+ "apihelp-compare-param-totitle": "要比较的第二个标题。",
+ "apihelp-compare-param-toid": "要比较的第二个页面 ID。",
+ "apihelp-compare-param-torev": "要比较的第二个修订版本。",
+ "apihelp-compare-example-1": "在版本1和2中创建差异",
+ "apihelp-createaccount-description": "创建一个新用户账户。",
+ "apihelp-createaccount-param-name": "用户名",
+ "apihelp-createaccount-param-password": "密码(如果设置<var>$1mailpassword</var>则忽略)。",
+ "apihelp-createaccount-param-domain": "外部身份验证域 (可选)。",
+ "apihelp-createaccount-param-token": "在第一个请求中获得的帐户创建标记。",
+ "apihelp-createaccount-param-email": "用户的电子邮件地址(可选)。",
+ "apihelp-createaccount-param-realname": "用户的真实姓名(可选)。",
+ "apihelp-createaccount-param-mailpassword": "如果设置为任何值,将向用户发送一个随机密码。",
+ "apihelp-createaccount-param-reason": "将要放在日志中的,关于创建帐户的可选原因。",
+ "apihelp-createaccount-param-language": "要为用户设置为默认值的语言代码(可选,默认为内容语言)。",
+ "apihelp-createaccount-example-pass": "创建用户<kbd>testuser</kbd>和密码<kbd>test123</kbd>。",
+ "apihelp-createaccount-example-mail": "创建用户<kbd>testmailuser</kbd>并电邮发送一个随机生成的密码。",
+ "apihelp-delete-description": "删除一个页面。",
+ "apihelp-delete-param-title": "你所希望删除的页面的标题。不能与<var>$1pageid</var>一起使用。",
+ "apihelp-delete-param-pageid": "要删除的页面的页面 ID。不能与<var>$1title</var>一起使用。",
+ "apihelp-delete-param-reason": "删除原因。如果未设置,将使用一个自动生成的原因。",
+ "apihelp-delete-param-watch": "将该页面加入当前用户的监视列表。",
+ "apihelp-delete-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-delete-param-unwatch": "将该页面从当前用户的监视列表删除。",
+ "apihelp-delete-param-oldimage": "由[[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]]提供的要删除的旧图片名称。",
+ "apihelp-delete-example-simple": "删除<kbd>Main Page</kbd>。",
+ "apihelp-delete-example-reason": "删除<kbd>Main Page</kbd>,原因<kbd>Preparing for move</kbd>。",
+ "apihelp-disabled-description": "此模块已禁用。",
+ "apihelp-edit-description": "创建和编辑页面。",
+ "apihelp-edit-param-title": "您希望编辑的页面标题。不能与<var>$1pageid</var>一起使用。",
+ "apihelp-edit-param-pageid": "要编辑的页面的页面 ID。不能与<var>$1title</var>一起使用。",
+ "apihelp-edit-param-section": "段落数。<kbd>0</kbd>用于首段,<kbd>new</kbd>用于新的段落。",
+ "apihelp-edit-param-sectiontitle": "新小节的标题。",
+ "apihelp-edit-param-text": "页面内容。",
+ "apihelp-edit-param-summary": "编辑摘要。当$1section=new且未设置$1sectiontitle时,还包括小节标题。",
+ "apihelp-edit-param-minor": "小编辑。",
+ "apihelp-edit-param-notminor": "不是小编辑。",
+ "apihelp-edit-param-bot": "标记此编辑为机器人编辑。",
+ "apihelp-edit-param-basetimestamp": "基础修订的时间戳,用于检测编辑冲突。也许可以通过[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]得到。",
+ "apihelp-edit-param-starttimestamp": "编辑过程开始的时间戳,用于检测编辑冲突。当开始编辑过程时(例如当加载要编辑的页面时)使用<var>[[Special:ApiHelp/main|curtimestamp]]</var>可能取得一个适当的值。",
+ "apihelp-edit-param-recreate": "覆盖有关该页面在此期间已被删除的任何错误。",
+ "apihelp-edit-param-createonly": "不要编辑页面,如果已经存在。",
+ "apihelp-edit-param-nocreate": "如果该页面不存在,则抛出一个错误。",
+ "apihelp-edit-param-watch": "将页面加入当前用户的监视列表。",
+ "apihelp-edit-param-unwatch": "将页面从当前用户的监视列表中移除。",
+ "apihelp-edit-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-edit-param-md5": "$1text参数或$1prependtext和$1appendtext级联参数的MD5哈希值。如果设置,除非哈希值正确否则编辑无法完成。",
+ "apihelp-edit-param-prependtext": "将该文本添加到该页面的开始。覆盖$1text。",
+ "apihelp-edit-param-appendtext": "将该文本添加到该页面的结尾。覆盖$1text。\n\n采用$1section=new来添加一个新的章节,而不是这个参数。",
+ "apihelp-edit-param-undo": "撤销此次修订。覆盖$1text、$1prependtext和$1appendtext。",
+ "apihelp-edit-param-undoafter": "撤销从$1undo至此的所有修订。如果不设置就撤销一次修订。",
+ "apihelp-edit-param-redirect": "自动解析重定向。",
+ "apihelp-edit-param-contentformat": "用于输入文本的内容串行化格式。",
+ "apihelp-edit-param-contentmodel": "新内容的内容模型。",
+ "apihelp-edit-param-token": "令牌应总是发送为最后参数,或至少在$1text参数之后。",
+ "apihelp-edit-example-edit": "编辑一个页面",
+ "apihelp-edit-example-prepend": "页面中预置<kbd>_&#95;NOTOC_&#95;</kbd>",
+ "apihelp-edit-example-undo": "通过13585撤销修订版本13579并自动填写编辑摘要",
+ "apihelp-emailuser-description": "电子邮件联系一位用户。",
+ "apihelp-emailuser-param-target": "电子邮件的目标用户。",
+ "apihelp-emailuser-param-subject": "主题页眉。",
+ "apihelp-emailuser-param-text": "邮件正文。",
+ "apihelp-emailuser-param-ccme": "给我发送一份该邮件的副本。",
+ "apihelp-emailuser-example-email": "向用户<kbd>WikiSysop</kbd>发送邮件,带文字<kbd>Content</kbd>。",
+ "apihelp-expandtemplates-description": "展开维基文本中的所有模板。",
+ "apihelp-expandtemplates-param-title": "页面标题。",
+ "apihelp-expandtemplates-param-text": "要转换的wiki文本。",
+ "apihelp-expandtemplates-param-revid": "修订版本ID,用于<nowiki>{{REVISIONID}}</nowiki>和类似变体。",
+ "apihelp-expandtemplates-param-prop": "要获取的那条信息:\n;wikitext:展开的wiki文本。\n;categories:任何在不代表wiki文本输出的输入框出现的分类。\n;properties:由wiki文本中扩充的魔术字定义的页面属性。\n;volatile:输出是否不稳定,并且不应在任何页面中再度使用。\n;ttl:结果的哪个缓存后等待最长时间应无效化。\n;parsetree:输入的XML解析树。\n注意如果没有选定值,结果将包含wiki文本,但将以弃用的格式显示。",
+ "apihelp-expandtemplates-param-includecomments": "输出时是否包含HTML摘要。",
+ "apihelp-expandtemplates-param-generatexml": "生成XML解析树(取代自$1prop=parsetree)。",
+ "apihelp-expandtemplates-example-simple": "展开wiki文本<kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>。",
+ "apihelp-feedcontributions-description": "返回用户贡献纲要。",
+ "apihelp-feedcontributions-param-feedformat": "纲要的格式。",
+ "apihelp-feedcontributions-param-user": "获取哪些用户的贡献。",
+ "apihelp-feedcontributions-param-namespace": "过滤哪些命名空间的贡献。",
+ "apihelp-feedcontributions-param-year": "起始年份(及更早)。",
+ "apihelp-feedcontributions-param-month": "起始月份(及更早)。",
+ "apihelp-feedcontributions-param-tagfilter": "过滤有这些标签的贡献者。",
+ "apihelp-feedcontributions-param-deletedonly": "仅显示已删除的贡献。",
+ "apihelp-feedcontributions-param-toponly": "仅仅显示那些作为最新修订的编辑。",
+ "apihelp-feedcontributions-param-newonly": "仅仅显示那些作为页面创建的编辑。",
+ "apihelp-feedcontributions-param-showsizediff": "显示修订版本之间的大小差别。",
+ "apihelp-feedcontributions-example-simple": "返回用户<kbd>Example</kbd>的贡献。",
+ "apihelp-feedrecentchanges-description": "返回最新变更纲要。",
+ "apihelp-feedrecentchanges-param-feedformat": "纲要的格式。",
+ "apihelp-feedrecentchanges-param-namespace": "用于限制结果的命名空间。",
+ "apihelp-feedrecentchanges-param-invert": "除所选定者外的所有命名空间。",
+ "apihelp-feedrecentchanges-param-associated": "包括相关的命名空间(讨论页或主要)。",
+ "apihelp-feedrecentchanges-param-days": "用于限制结果的天数。",
+ "apihelp-feedrecentchanges-param-limit": "所要返回结果的最大数目。",
+ "apihelp-feedrecentchanges-param-from": "显示自那时以来的更改。",
+ "apihelp-feedrecentchanges-param-hideminor": "隐藏小更改。",
+ "apihelp-feedrecentchanges-param-hidebots": "隐藏机器人所做的更改。",
+ "apihelp-feedrecentchanges-param-hideanons": "隐藏匿名用户做出的更改。",
+ "apihelp-feedrecentchanges-param-hideliu": "隐藏注册用户做出的更改。",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "隐藏已巡查更改。",
+ "apihelp-feedrecentchanges-param-hidemyself": "隐藏当前用户做出的更改。",
+ "apihelp-feedrecentchanges-param-tagfilter": "按标签过滤。",
+ "apihelp-feedrecentchanges-param-target": "仅仅显示从该页面链出的那些页面的变更。",
+ "apihelp-feedrecentchanges-param-showlinkedto": "仅仅显示链入到该页面的那些页面的变更。",
+ "apihelp-feedrecentchanges-example-simple": "显示最近更改",
+ "apihelp-feedrecentchanges-example-30days": "显示最近30天的更改",
+ "apihelp-feedwatchlist-description": "返回监视列表纲要。",
+ "apihelp-feedwatchlist-param-feedformat": "纲要的格式。",
+ "apihelp-feedwatchlist-param-hours": "列出从现在起数小时内修改的页面。",
+ "apihelp-feedwatchlist-param-linktosections": "如果可能的话,直接链接到已变更的小节。",
+ "apihelp-feedwatchlist-example-default": "显示监视列表订阅",
+ "apihelp-feedwatchlist-example-all6hrs": "显示过去6小时内受监视页面的所有更改。",
+ "apihelp-filerevert-description": "回退一个文件至某一旧版本。",
+ "apihelp-filerevert-param-filename": "目标文件名,不包含前缀“File:”。",
+ "apihelp-filerevert-param-comment": "上传评论。",
+ "apihelp-filerevert-param-archivename": "恢复到修订版存档名称。",
+ "apihelp-filerevert-example-revert": "回退<kbd>Wiki.png</kbd>至<kbd>2011-03-05T15:27:40Z</kbd>的版本。",
+ "apihelp-help-description": "显示指定模块的帮助。",
+ "apihelp-help-param-modules": "用于显示帮助的模块(<var>action</var>和<var>format</var>参数值,或<kbd>main</kbd>)。可通过<kbd>+</kbd>指定子模块。",
+ "apihelp-help-param-submodules": "包括给定名称模块的子模块的帮助。",
+ "apihelp-help-param-recursivesubmodules": "包括递归子模块的帮助。",
+ "apihelp-help-param-helpformat": "帮助的输出格式。",
+ "apihelp-help-param-wrap": "在一个标准API响应结构中包裹输出。",
+ "apihelp-help-param-toc": "在HTML输出中包括目录。",
+ "apihelp-help-example-main": "主模块帮助",
+ "apihelp-help-example-recursive": "一个页面中的所有帮助",
+ "apihelp-help-example-help": "帮助模块本身的帮助",
+ "apihelp-help-example-query": "两个查询子模块的帮助",
+ "apihelp-imagerotate-description": "旋转一幅或多幅图像。",
+ "apihelp-imagerotate-param-rotation": "顺时针旋转图像的度数。",
+ "apihelp-imagerotate-example-simple": "<kbd>90</kbd>度旋转<kbd>File:Example.png</kbd>。",
+ "apihelp-imagerotate-example-generator": "将<kbd>Category:Flip</kbd>之中的所有图像旋转<kbd>180</kbd>度。",
+ "apihelp-import-description": "从另一个wiki导入一个页面,或一个XML文件。\n\n注意当发送一个用于<var>xml</var>参数的文件时,HTTP POST必须作为一次文件上传完成(也就是使用multipart/form-data)。",
+ "apihelp-import-param-summary": "导入摘要。",
+ "apihelp-import-param-xml": "上传的XML文件。",
+ "apihelp-import-param-interwikisource": "用于跨wiki导入:导入的来源wiki。",
+ "apihelp-import-param-interwikipage": "用于跨wiki导入:导入的页面。",
+ "apihelp-import-param-fullhistory": "用于跨wiki导入:完整导入历史,而不只是最新版本。",
+ "apihelp-import-param-templates": "用于跨wiki导入:连带导入所有包含的模板。",
+ "apihelp-import-param-namespace": "用于跨wiki导入:导入到此名字空间。",
+ "apihelp-import-param-rootpage": "导入作为此页面的子页面。",
+ "apihelp-import-example-import": "将页面[[meta:Help:Parserfunctions]]连带完整历史导入至100名字空间。",
+ "apihelp-login-description": "登录并获得身份验证Cookie。\n\n在成功登录的情况下,所需的Cookie将包含在HTTP响应头中。在登录失败的情况下,进一步的尝试可能会被自动密码猜解攻击的限制所遏制。",
+ "apihelp-login-param-name": "用户名。",
+ "apihelp-login-param-password": "密码。",
+ "apihelp-login-param-domain": "域名(可选)。",
+ "apihelp-login-param-token": "在首个请求中获得的登录令牌。",
+ "apihelp-login-example-gettoken": "检索登录令牌",
+ "apihelp-login-example-login": "登录",
+ "apihelp-logout-description": "退出并清除会话数据。",
+ "apihelp-logout-example-logout": "退出当前用户",
+ "apihelp-managetags-description": "执行有关更改标签的管理任务。",
+ "apihelp-managetags-param-operation": "要执行哪个操作:\n;create:创建一个新的更改标签供手动使用。\n;delete:从数据库中移除一个更改标签,包括移除已使用在所有修订版本、最近更改记录和日志记录上的该标签。\n;activate:激活一个更改标签,允许用户手动应用它。\n;deactivate:停用一个更改标签,阻止用户手动应用它。",
+ "apihelp-managetags-param-tag": "要创建、删除、激活或取消激活的标签。要创建标签,标签必须不存在。要删除标签,标签必须存在。要激活标签,标签必须存在,且不被任何扩展使用。要取消激活标签,标签必须当前处于激活状态,且被手动定义。",
+ "apihelp-managetags-param-reason": "一个创建、删除、激活或停用标签时的原因,可选。",
+ "apihelp-managetags-param-ignorewarnings": "是否忽略操作期间发生的任何警告。",
+ "apihelp-managetags-example-create": "创建一个名为<kbd>spam</kbd>的标签,原因<kbd>For use in edit patrolling</kbd>",
+ "apihelp-managetags-example-delete": "删除<kbd>vandlaism</kbd>标签,原因<kbd>Misspelt</kbd>",
+ "apihelp-managetags-example-activate": "激活一个名为<kbd>spam</kbd>的标签,原因<kbd>For use in edit patrolling</kbd>",
+ "apihelp-managetags-example-deactivate": "停用一个名为<kbd>spam</kbd>的标签,原因<kbd>No longer required</kbd>",
+ "apihelp-move-description": "移动一个页面。",
+ "apihelp-move-param-from": "要重命名的页面标题。不能与<var>$1fromid</var>一起使用。",
+ "apihelp-move-param-fromid": "您希望移动的页面ID。不能与<var>$1from</var>一起使用。",
+ "apihelp-move-param-to": "页面重命名的目标标题。",
+ "apihelp-move-param-reason": "重命名的原因。",
+ "apihelp-move-param-movetalk": "重命名讨论页,如果存在。",
+ "apihelp-move-param-movesubpages": "重命名子页面,如果可以。",
+ "apihelp-move-param-noredirect": "不要创建重定向。",
+ "apihelp-move-param-watch": "将页面和重定向加入至当前用户的监视列表中。",
+ "apihelp-move-param-unwatch": "从当前用户的监视列表中移除页面及重定向。",
+ "apihelp-move-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-move-param-ignorewarnings": "忽略任何警告。",
+ "apihelp-move-example-move": "移动<kbd>坏标题</kbd>到<kbd>好标题</kbd>并且不留下重定向。",
+ "apihelp-opensearch-description": "使用OpenSearch协议搜索本wiki。",
+ "apihelp-opensearch-param-search": "搜索字符串。",
+ "apihelp-opensearch-param-limit": "要返回的结果最大数。",
+ "apihelp-opensearch-param-namespace": "搜索的名字空间。",
+ "apihelp-opensearch-param-suggest": "如果<var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var>设置为false则不做任何事情。",
+ "apihelp-opensearch-param-redirects": "如何处理重定向:\n;return:返回重定向本身。\n;resolve:返回目标页面。可能返回少于$1limit个结果。\n由于历史原因,$1format=json默认为\"return\",其他格式默认为\"resolve\"。",
+ "apihelp-opensearch-param-format": "输出格式。",
+ "apihelp-opensearch-example-te": "查找以<kbd>Te</kbd>开头的页面。",
+ "apihelp-options-description": "更改当前用户的偏好设置。\n\n只有注册在核心或者已安装扩展中的选项,或者具有\"userjs-\"键值前缀(旨在被用户脚本使用)的选项可被设置。",
+ "apihelp-options-param-reset": "重置偏好设置到网站默认设置。",
+ "apihelp-options-param-resetkinds": "当<var>$1reset</var>选项被设置时,要重置的选项类型列表。",
+ "apihelp-options-param-change": "更改列表,以name=value格式化(例如skin=vector)。值不能包含管道字符。如果没提供值(甚至没有等号),例如optionname|otheroption|...,选项将重置为默认值。",
+ "apihelp-options-param-optionname": "应设置为由<var>$1optionvalue</var>提供值的选项名称。",
+ "apihelp-options-param-optionvalue": "使用<var>$1选项名</var>指定的选项值中,可以包含管道字符",
+ "apihelp-options-example-reset": "重置所有用户设置",
+ "apihelp-options-example-change": "更改<kbd>skin</kbd>和<kbd>hideminor</kbd>设置。",
+ "apihelp-options-example-complex": "重置所有设置,然后设置<kbd>皮肤</kbd>和<kbd>昵称</kbd>。",
+ "apihelp-paraminfo-description": "获取关于 API 模块的信息。",
+ "apihelp-paraminfo-param-modules": "模块名称(<var>action</var>和<var>format</var>参数值,或<kbd>main</kbd>)的列表。可通过<kbd>+</kbd>指定子模块。",
+ "apihelp-paraminfo-param-helpformat": "帮助字符串的格式。",
+ "apihelp-paraminfo-param-querymodules": "查询模块名称(<var>prop</var>、<var>meta</var>或<var>list</var>参数值)的列表。使用<kbd>$1modules=query+foo</kbd>而不是<kbd>$1querymodules=foo</kbd>。",
+ "apihelp-paraminfo-param-mainmodule": "获得有关主要(最高级)模块的信息。也可使用<kbd>$1modules=main</kbd>。",
+ "apihelp-paraminfo-param-pagesetmodule": "获得有关页面设置模块(提供titles=和朋友)的信息。",
+ "apihelp-paraminfo-param-formatmodules": "格式模块名称(<var>format</var>参数的值)的列表。也可使用<var>$1modules</var>。",
+ "apihelp-paraminfo-example-1": "显示<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>、<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>、<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>和<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>的信息。",
+ "apihelp-parse-description": "解析内容并返回解析器输出。\n\n参见<kbd>[[Special:ApiHelp/query|action=query]]</kbd>的各种prop-module以从页面的当前版本获得信息。\n\n这里有几种方法可以指定解析的文本:\n# 指定一个页面或修订,使用<var>$1page</var>、<var>$1pageid</var>或<var>$1oldid</var>。\n# 明确指定内容,使用<var>$1text</var>、<var>$1title</var>和<var>$1contentmodel</var>。\n# 只指定一段摘要解析。<var>$1prop</var>应提供一个空值。",
+ "apihelp-parse-param-title": "文本属于的页面标题。如果省略,<var>$1contentmodel</var>就必须被指定,且[[API]]将作为标题使用。",
+ "apihelp-parse-param-text": "要解析的文本。使用<var>$1title</var>或<var>$1contentmodel</var>以控制内容模型。",
+ "apihelp-parse-param-summary": "所要解析的摘要。",
+ "apihelp-parse-param-page": "解析此页的内容。不能与<var>$1text</var>和<var>$1title</var>一起使用。",
+ "apihelp-parse-param-pageid": "解析此页的内容。覆盖<var>$1page</var>。",
+ "apihelp-parse-param-redirects": "如果<var>$1page</var>或<var>$1pageid</var>被设置为一个重定向,则解析它。",
+ "apihelp-parse-param-oldid": "解析该修订版本的内容。覆盖<var>$1page</var>和<var>$1pageid</var>。",
+ "apihelp-parse-param-pst": "在解析输入前,对输入做一次保存前变换处理。仅当使用文本时有效。",
+ "apihelp-parse-param-effectivelanglinks": "包含由扩展提供的语言链接(用于与<kbd>$1prop=langlinks</kbd>一起使用)。",
+ "apihelp-parse-param-section": "只检索此段数的内容,或只当<kbd>new</kbd>生成新的段落时检索。\n\n<kbd>new</kbd>段落只当指定<var>text</var>时受尊重。",
+ "apihelp-parse-param-sectiontitle": "当<var>section</var>为<kbd>new</kbd>时新段落标题。\n\n不像页面编辑,当省略或为空时将不会备选为<var>summary</var>。",
+ "apihelp-parse-param-disablepp": "从解析器输出中禁用PP报告。",
+ "apihelp-parse-param-disableeditsection": "从解析器输出中禁用编辑段落链接。",
+ "apihelp-parse-param-generatexml": "生成XML解析树(需要内容模型<code>$1</code>)。",
+ "apihelp-parse-param-preview": "在预览模式下解析。",
+ "apihelp-parse-param-sectionpreview": "在小节预览模式下解析 (同时要启用预览模式)。",
+ "apihelp-parse-param-disabletoc": "在输出中禁用目录。",
+ "apihelp-parse-example-page": "解析一个页面。",
+ "apihelp-parse-example-text": "解析wiki文本。",
+ "apihelp-parse-example-texttitle": "解析维基文本,指定页面标题。",
+ "apihelp-parse-example-summary": "解析一个摘要。",
+ "apihelp-patrol-description": "巡查页面或修订版本。",
+ "apihelp-patrol-param-rcid": "所要巡查的最近变更 ID。",
+ "apihelp-patrol-param-revid": "要巡查的修订版本ID。",
+ "apihelp-patrol-example-rcid": "巡查一次最近更改",
+ "apihelp-patrol-example-revid": "巡查一次修订",
+ "apihelp-protect-description": "更改页面的保护等级。",
+ "apihelp-protect-param-title": "要(解除)保护的页面标题。不能与$1pageid一起使用。",
+ "apihelp-protect-param-pageid": "要(解除)保护的页面ID。不能与$1title一起使用。",
+ "apihelp-protect-param-protections": "保护等级列表,格式:<kbd>action=level</kbd>(例如<kbd>edit=sysop</kbd>)。\n\n<strong>注意:</strong>未列出的操作将移除限制。",
+ "apihelp-protect-param-expiry": "到期时间戳。如果只有一个时间戳被设置,它将被用于所有保护。使用<kbd>infinite</kbd>、<kbd>indefinite</kbd>、<kbd>infinity</kbd>或<kbd>never</kbd>用于永不过期的保护。",
+ "apihelp-protect-param-reason": "(解除)保护的原因。",
+ "apihelp-protect-param-cascade": "启用级联保护(也就是保护包含于此页面的页面)。如果所有提供的保护等级不支持级联,就将其忽略。",
+ "apihelp-protect-param-watch": "如果设置,就加入已开始(解除)保护的页面至当前用户的监视列表。",
+ "apihelp-protect-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-protect-example-protect": "保护一个页面",
+ "apihelp-protect-example-unprotect": "通过设置限制为<kbd>all</kbd>解除保护一个页面。",
+ "apihelp-protect-example-unprotect2": "通过设置没有限制解除保护一个页面",
+ "apihelp-purge-description": "为指定标题刷新缓存。\n\n如果用户尚未登录的话,就需要POST请求。",
+ "apihelp-purge-param-forcelinkupdate": "更新链接表。",
+ "apihelp-purge-param-forcerecursivelinkupdate": "更新链接表中,并更新任何使用此页作为模板的页面的链接表。",
+ "apihelp-purge-example-simple": "刷新<kbd>Main Page</kbd>和<kbd>API</kbd>页面。",
+ "apihelp-purge-example-generator": "刷新主名字空间的前10个页面",
+ "apihelp-query-description": "获取来自和有关MediaWiki的数据。\n\n所有数据修改将首先要使用查询以获得令牌以阻止来自恶意网站的滥用破坏。",
+ "apihelp-query-param-prop": "要为已查询页面获取的属性。",
+ "apihelp-query-param-list": "要获取的列表。",
+ "apihelp-query-param-meta": "要获取的元数据。",
+ "apihelp-query-param-rawcontinue": "目前被忽略。将来<var>$1continue</var>将成为默认,且这里将需要得到原始的<samp>query-continue</samp>数据。",
+ "apihelp-query-example-revisions": "获取<kbd>Main Page</kbd>的[[Special:ApiHelp/query+siteinfo|网站信息]]和[[Special:ApiHelp/query+revisions|修订版本]]。",
+ "apihelp-query-example-allpages": "获取以<kbd>API/</kbd>开头的页面的修订版本",
+ "apihelp-query+allcategories-description": "枚举所有类别。",
+ "apihelp-query+allcategories-param-from": "要作为枚举起始点的类别。",
+ "apihelp-query+allcategories-param-to": "要作为枚举终止点的类别。",
+ "apihelp-query+allcategories-param-prefix": "搜索此值开头的所有分类标题。",
+ "apihelp-query+allcategories-param-dir": "排序方向。",
+ "apihelp-query+allcategories-param-min": "只返回至少带这么多成员的分类。",
+ "apihelp-query+allcategories-param-max": "只返回最多带这么多成员的分类。",
+ "apihelp-query+allcategories-param-limit": "要返回多少个类别。",
+ "apihelp-query+allcategories-param-prop": "要获取的属性:\n;size:在分类中添加页面数。\n;hidden:标记由_&#95;HIDDENCAT_&#95;隐藏的分类。",
+ "apihelp-query+allcategories-example-size": "列出分类及其含有多少页面的信息。",
+ "apihelp-query+alldeletedrevisions-paraminfo-useronly": "只可以与<var>$3user</var>一起使用。",
+ "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "不能与<var>$3user</var>一起使用。",
+ "apihelp-query+alldeletedrevisions-param-start": "枚举的起始时间戳。",
+ "apihelp-query+alldeletedrevisions-param-end": "枚举的结束时间戳。",
+ "apihelp-query+alldeletedrevisions-param-from": "从此标题开始列出。",
+ "apihelp-query+alldeletedrevisions-param-to": "列出至此标题为止。",
+ "apihelp-query+alldeletedrevisions-param-tag": "只列出被此标签标记的修订。",
+ "apihelp-query+alldeletedrevisions-param-user": "只列出此用户做出的修订。",
+ "apihelp-query+alldeletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
+ "apihelp-query+alldeletedrevisions-param-namespace": "只列出此名字空间的页面。",
+ "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>注意:</strong>由于[[mw:Manual:$wgMiserMode|miser模式]],同时使用<var>$1user</var>和<var>$1namespace</var>将导致继续前返回少于<var>$1limit</var>个结果,在极端条件下可能不返回任何结果。",
+ "apihelp-query+alldeletedrevisions-example-user": "列出由<kbd>Example<kbd>作出的最近50次已删除贡献。",
+ "apihelp-query+alldeletedrevisions-example-ns-main": "列出前50次已删除的主名字空间修订。",
+ "apihelp-query+allfileusages-description": "列出所有文件用途,包括不存在的。",
+ "apihelp-query+allfileusages-param-from": "文件的标题开始枚举于.",
+ "apihelp-query+allfileusages-param-prefix": "搜索此值开头的所有文件标题。",
+ "apihelp-query+allfileusages-param-prop": "要包含的信息束:\n;ids:添加使用中的页面的页面ID(不能与$1unique一起使用)。\n;title:添加文件的标题。",
+ "apihelp-query+allfileusages-param-limit": "要返回的总计项目。",
+ "apihelp-query+allfileusages-param-dir": "罗列所采用的方向。",
+ "apihelp-query+allfileusages-example-unique": "列出唯一性的文件标题",
+ "apihelp-query+allfileusages-example-unique-generator": "获取所有文件标题,并标记出缺失者",
+ "apihelp-query+allfileusages-example-generator": "获取包含这些文件的页面",
+ "apihelp-query+allimages-description": "按顺序枚举所有图像。",
+ "apihelp-query+allimages-param-sort": "要作为排序方式的属性。",
+ "apihelp-query+allimages-param-dir": "罗列所采用的方向。",
+ "apihelp-query+allimages-param-minsize": "限于至少这么多字节的图像。",
+ "apihelp-query+allimages-param-maxsize": "限于顶多这么多字节的图像。",
+ "apihelp-query+allimages-param-sha1": "图像的 SHA1 哈希。覆盖$1sha1base36。",
+ "apihelp-query+allimages-param-sha1base36": "基于base 36的图片的SHA1哈希值(用于MediaWiki)。",
+ "apihelp-query+allimages-param-mime": "要搜索的MIME类型,例如<kbd>image/jpeg</kbd>。",
+ "apihelp-query+allimages-param-limit": "共计要返回多少图像。",
+ "apihelp-query+allimages-example-B": "显示以字母<kbd>B</kbd>开始的文件列表。",
+ "apihelp-query+allimages-example-recent": "显示一个最近上传文件的列表,类似[[Special:NewFiles]]。",
+ "apihelp-query+allimages-example-mimetypes": "显示带MIME类型<kbd>image/png</kbd>或<kbd>image/gif</kbd>的文件列表",
+ "apihelp-query+allimages-example-generator": "显示有关4个以<kbd>T</kbd>开头的文件的信息。",
+ "apihelp-query+alllinks-param-namespace": "要列举的名字空间。",
+ "apihelp-query+alllinks-param-limit": "总共要返回多少个项目。",
+ "apihelp-query+alllinks-param-dir": "列出方向。",
+ "apihelp-query+alllinks-example-unique": "列出唯一的链接标题",
+ "apihelp-query+alllinks-example-unique-generator": "获得所有已链接的标题,标记缺少的。",
+ "apihelp-query+alllinks-example-generator": "获取包含这些链接的页面",
+ "apihelp-query+allmessages-description": "返回来自该网站的消息。",
+ "apihelp-query+allmessages-param-messages": "要输出的消息。<kbd>*</kbd>(默认)表示所有消息。",
+ "apihelp-query+allmessages-param-prop": "要获取的属性。",
+ "apihelp-query+allmessages-param-customised": "只返回在此定制情形下的消息。",
+ "apihelp-query+allmessages-param-lang": "返回这种语言的信息。",
+ "apihelp-query+allmessages-param-from": "从此消息开始返回消息。",
+ "apihelp-query+allmessages-param-to": "返回消息至此消息为止。",
+ "apihelp-query+allmessages-param-prefix": "返回带有该前缀的消息。",
+ "apihelp-query+allmessages-example-ipb": "显示以<kbd>ipb-</kbd>开始的消息。",
+ "apihelp-query+allmessages-example-de": "显示德语版的<kbd>august</kbd>和<kbd>mainpage</kbd>消息。",
+ "apihelp-query+allpages-param-namespace": "要列举的名字空间。",
+ "apihelp-query+allpages-param-filterredir": "要列出哪些页面。",
+ "apihelp-query+allpages-param-minsize": "限于至少这么多字节的页面。",
+ "apihelp-query+allpages-param-maxsize": "限于至多这么多字节的页面。",
+ "apihelp-query+allpages-param-prtype": "仅限于受保护页面。",
+ "apihelp-query+allpages-param-limit": "返回的总计页面数。",
+ "apihelp-query+allpages-example-B": "显示以字母<kbd>B</kbd>开头的页面的列表。",
+ "apihelp-query+allpages-example-generator": "显示有关4个以字母<kbd>T</kbd>开头的页面的信息。",
+ "apihelp-query+allpages-example-generator-revisions": "显示前2个以<kbd>Re</kbd>开头的非重定向页面的内容。",
+ "apihelp-query+allredirects-description": "列出至一个名字空间的重定向。",
+ "apihelp-query+allredirects-param-namespace": "要列举的名字空间。",
+ "apihelp-query+allredirects-param-limit": "返回的总计项目数。",
+ "apihelp-query+allredirects-param-dir": "罗列所采用的方向。",
+ "apihelp-query+allredirects-example-unique": "列出孤立目标页面",
+ "apihelp-query+allredirects-example-unique-generator": "获得所有目标页面,标记丢失的",
+ "apihelp-query+allredirects-example-generator": "获得包含重定向的页面",
+ "apihelp-query+alltransclusions-description": "列出所有嵌入页面(使用&#123;&#123;x&#125;&#125;嵌入的页面),包括不存在的。",
+ "apihelp-query+alltransclusions-param-namespace": "要列举的名字空间。",
+ "apihelp-query+alltransclusions-param-limit": "要返回的总计项目。",
+ "apihelp-query+alltransclusions-param-dir": "罗列所采用的方向。",
+ "apihelp-query+alltransclusions-example-unique": "列出孤立嵌入标题",
+ "apihelp-query+alltransclusions-example-generator": "获得包含嵌入内容的页面。",
+ "apihelp-query+allusers-description": "列举所有注册用户。",
+ "apihelp-query+allusers-param-from": "枚举的起始用户名。",
+ "apihelp-query+allusers-param-to": "枚举的结束用户名。",
+ "apihelp-query+allusers-param-prefix": "搜索以此值开始的所有用户。",
+ "apihelp-query+allusers-param-dir": "排序方向。",
+ "apihelp-query+allusers-param-group": "只包含指定组中的用户。",
+ "apihelp-query+allusers-param-excludegroup": "排除指定组中的用户。",
+ "apihelp-query+allusers-param-rights": "仅列出有所选权限的用户。不包括隐性的或自动加入的用户组别(如*、用户或自动确认用户)所授予的权限。",
+ "apihelp-query+allusers-param-limit": "返回的总计用户数。",
+ "apihelp-query+allusers-param-witheditsonly": "只列出有编辑的用户。",
+ "apihelp-query+allusers-param-activeusers": "只列出最近$1天内活跃的用户。",
+ "apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>开头的用户。",
+ "apihelp-query+backlinks-description": "查找所有链接至指定页面的页面。",
+ "apihelp-query+backlinks-param-title": "要搜索的标题。不能与<var>$1pageid</var>一起使用。",
+ "apihelp-query+backlinks-param-pageid": "要搜索的页面ID。不能与<var>$1title</var>一起使用。",
+ "apihelp-query+backlinks-param-namespace": "要列举的名字空间。",
+ "apihelp-query+backlinks-param-dir": "罗列所采用的方向。",
+ "apihelp-query+backlinks-param-limit": "返回总计页面数。如果<var>$1redirect</var>被启用,则限定分别适用于每一等级(这意味着将返回多达2 * <var>$1limit</var>个结果)。",
+ "apihelp-query+backlinks-example-simple": "显示至<kbd>Main page<kbd>的链接。",
+ "apihelp-query+backlinks-example-generator": "获得关于链接至<kbd>Main page<kbd>的页面的信息。",
+ "apihelp-query+blocks-description": "列出所有被封禁的用户和IP地址。",
+ "apihelp-query+blocks-param-ids": "要列出的封禁ID列表(可选)。",
+ "apihelp-query+blocks-param-users": "要搜索的用户列表(可选)。",
+ "apihelp-query+blocks-param-prop": "要获取的属性:\n;id:添加封禁ID。\n;user:添加被封禁用户的用户名。\n;userid:添加被封禁用户的用户ID。\n;by:添加执行封禁的用户的用户名。\n;byid:添加执行封禁的用户的用户ID。\n;timestamp:添加封禁生效时的时间戳。\n;expiry:添加封禁截止时的时间戳。\n;reason:添加封禁原因。\n;range:添加受封禁影响的IP地址段。\n;flags:标记编辑禁止(自动封禁、仅限匿名用户等)。",
+ "apihelp-query+blocks-example-simple": "封禁列表",
+ "apihelp-query+blocks-example-users": "列出用户<kbd>Alice</kbd>和<kbd>Bob</kbd>的封禁。",
+ "apihelp-query+categories-description": "页面属于的所有分类列表。",
+ "apihelp-query+categories-param-prop": "要为每个分类获取的额外属性:\n;sortkey:为每个分类添加关键词(十六进制字符串)和关键词前缀(人类可读部分)。\n;timestamp:添加分类添加时的时间戳。\n;hidden:标记由_&#95;HIDDENCAT_&#95;隐藏的分类。",
+ "apihelp-query+categories-param-show": "显示何种分类。",
+ "apihelp-query+categories-param-limit": "返回多少分类。",
+ "apihelp-query+categories-param-dir": "罗列所采用的方向。",
+ "apihelp-query+categories-example-simple": "获取属于<kbd>Albert Einstein</kbd>的分类列表。",
+ "apihelp-query+categories-example-generator": "获得有关用于<kbd>Albert Einstein</kbd>的分类的信息。",
+ "apihelp-query+categoryinfo-description": "返回有关给定分类的信息。",
+ "apihelp-query+categoryinfo-example-simple": "获取有关<kbd>Category:Foo</kbd>和<kbd>Category:Bar</kbd>的信息。",
+ "apihelp-query+categorymembers-description": "在指定的分类中列出所有页面。",
+ "apihelp-query+categorymembers-param-title": "要列举的分类(必需)。必须包括<kbd>{{ns:category}}:</kbd>前缀。不能与<var>$1pageid</var>一起使用。",
+ "apihelp-query+categorymembers-param-pageid": "要枚举的分类的页面 ID。不能与<var>$1title</var>一起使用。",
+ "apihelp-query+categorymembers-param-namespace": "仅包含这些名字空间的页面。注意<kbd>$1type=subcat</kbd>或<kbd>$1type=file</kbd>可能被使用,而不是<kbd>$1namespace=14</kbd>或<kbd>6</kbd>。",
+ "apihelp-query+categorymembers-param-type": "包含的分类成员类型。当<kbd>$1sort=timestamp</kbd>被设置时会忽略。",
+ "apihelp-query+categorymembers-param-limit": "返回页面的最大数量。",
+ "apihelp-query+categorymembers-param-sort": "要作为排序方式的属性。",
+ "apihelp-query+categorymembers-param-dir": "排序的方向。",
+ "apihelp-query+categorymembers-param-start": "开始列举的时间戳。只能与<kbd>$1sort=timestamp</kbd>一起使用。",
+ "apihelp-query+categorymembers-param-end": "列举的结尾时间戳。只能与<kbd>$1sort=timestamp</kbd>一起使用。",
+ "apihelp-query+categorymembers-param-starthexsortkey": "开始列举的关键词,由<kbd>$1prop=sortkey</kbd>返回。不能与<kbd>$1sort=sortkey</kbd>一起使用。",
+ "apihelp-query+categorymembers-param-endhexsortkey": "结束列举的关键词,由<kbd>$1prop=sortkey</kbd>返回。不能与<kbd>$1sort=sortkey</kbd>一起使用。",
+ "apihelp-query+categorymembers-param-startsortkey": "请改用$1starthexsortkey。",
+ "apihelp-query+categorymembers-param-endsortkey": "请改用$1endhexsortkey。",
+ "apihelp-query+categorymembers-example-simple": "获得<kbd>Category:Physics</kbd>中的前10个页面。",
+ "apihelp-query+categorymembers-example-generator": "获得有关<kbd>Category:Physics</kbd>中的前10个页面的页面信息。",
+ "apihelp-query+contributors-description": "获取对一个页面的登录贡献者列表和匿名贡献数。",
+ "apihelp-query+contributors-param-limit": "返回的贡献数。",
+ "apihelp-query+contributors-example-simple": "显示<kbd>Main Page</kbd>的贡献。",
+ "apihelp-query+deletedrevisions-description": "获得删除修订版本信息。\n\n可在很多途径中使用:\n# 获得一组页面的已删除修订,通过设置标题或页面ID。以标题和时间戳排序。\n# 通过设置它们的ID与修订ID获得关于一组已删除修订。以修订ID排序。",
+ "apihelp-query+deletedrevisions-param-tag": "只列出被此标签标记的修订。",
+ "apihelp-query+deletedrevisions-param-user": "只列出此用户做出的修订。",
+ "apihelp-query+deletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
+ "apihelp-query+deletedrevisions-param-limit": "要列出的修订的最高数额。",
+ "apihelp-query+deletedrevisions-param-prop": "要获取的属性:\n;revid:添加已删除修订的修订ID。\n;parentid:添加上一修订的修订ID至页面中。\n;user:添加做出修订的用户。\n;userid:添加做出修订的用户ID。\n;comment:添加修订的摘要。\n;parsedcomment:添加修订的解析摘要。\n;minor:如果修订为小修订则予以标记。\n;len:添加修订的长度(字节)。\n;sha1:添加修订的SHA-1(base 16)。\n;content:添加修订内容。\n;tags:用于修订的标签。",
+ "apihelp-query+deletedrevisions-example-titles": "列出页面<kbd>Main Page</kbd>和<kbd>Talk:Main Page</kbd>的已删除修订,包含内容。",
+ "apihelp-query+deletedrevisions-example-revids": "列出已删除修订<kbd>123456</kbd>的信息。",
+ "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|模式}}:$2",
+ "apihelp-query+deletedrevs-param-from": "从此标题开始列出。",
+ "apihelp-query+deletedrevs-param-to": "列出至此标题为止。",
+ "apihelp-query+deletedrevs-param-user": "只列出此用户做出的修订。",
+ "apihelp-query+deletedrevs-param-excludeuser": "不要列出此用户做出的修订。",
+ "apihelp-query+deletedrevs-param-namespace": "只列出此名字空间的页面。",
+ "apihelp-query+deletedrevs-example-mode1": "列出最近已删除的对页面<kbd>Main Page</kbd>和<kbd>Talk:Main Page</kbd>的贡献,带内容(模式1)。",
+ "apihelp-query+deletedrevs-example-mode2": "列出由<kbd>Bob</kbd>作出的最近50次已删除贡献(模式2)。",
+ "apihelp-query+deletedrevs-example-mode3-main": "列出前50次主名字空间已删除贡献(模式3)",
+ "apihelp-query+deletedrevs-example-mode3-talk": "列出前50次{{ns:talk}}名字空间已删除页面(模式3):",
+ "apihelp-query+disabled-description": "此查询模块已被禁用。",
+ "apihelp-query+duplicatefiles-param-limit": "返回多少重复文件。",
+ "apihelp-query+duplicatefiles-param-dir": "罗列所采用的方向。",
+ "apihelp-query+duplicatefiles-param-localonly": "只看本地存储库的文件。",
+ "apihelp-query+duplicatefiles-example-simple": "查找与[[:File:Albert Einstein Head.jpg]]重复的文件",
+ "apihelp-query+duplicatefiles-example-generated": "查找所有文件的重复文件",
+ "apihelp-query+embeddedin-param-title": "要搜索的标题。不能与$1pageid一起使用。",
+ "apihelp-query+embeddedin-param-pageid": "要搜索的页面ID。不能与$1title一起使用。",
+ "apihelp-query+embeddedin-param-namespace": "列举的名字空间。",
+ "apihelp-query+embeddedin-param-dir": "罗列所采用的方向。",
+ "apihelp-query+embeddedin-param-filterredir": "如何过滤重定向。",
+ "apihelp-query+embeddedin-param-limit": "返回的总计页面数。",
+ "apihelp-query+embeddedin-example-simple": "显示嵌入<kbd>Template:Stub</kbd>的页面。",
+ "apihelp-query+embeddedin-example-generator": "获得有关显示嵌入<kbd>Template:Stub</kbd>的页面的信息。",
+ "apihelp-query+extlinks-param-limit": "返回多少链接。",
+ "apihelp-query+extlinks-example-simple": "获取<kbd>首页</kbd>的外部链接列表。",
+ "apihelp-query+exturlusage-param-protocol": "URL协议。如果为空并且<var>$1query</var>被设置,协议为<kbd>http</kbd>。将此和<var>$1query</var>都留空以列举所有外部链接。",
+ "apihelp-query+exturlusage-param-query": "不包括协议的搜索字符串。参见[[Special:LinkSearch]]。留空以列出所有外部链接。",
+ "apihelp-query+exturlusage-param-namespace": "要列举的页面名字空间。",
+ "apihelp-query+exturlusage-param-limit": "返回多少页面。",
+ "apihelp-query+exturlusage-example-simple": "显示链接至<kbd>http://www.mediawiki.org</kbd>的页面。",
+ "apihelp-query+filearchive-param-from": "枚举的起始图片标题。",
+ "apihelp-query+filearchive-param-to": "枚举的结束图片标题。",
+ "apihelp-query+filearchive-param-prefix": "搜索所有以此值开头的图像标题。",
+ "apihelp-query+filearchive-param-limit": "返回图像的总数。",
+ "apihelp-query+filearchive-param-dir": "罗列所采用的方向。",
+ "apihelp-query+filearchive-param-sha1": "图片的SHA1哈希值。覆盖$1sha1base36。",
+ "apihelp-query+filearchive-param-sha1base36": "基于base 36的图片的SHA1哈希值(用于MediaWiki)。",
+ "apihelp-query+filearchive-example-simple": "显示已删除文件列表",
+ "apihelp-query+filerepoinfo-example-simple": "获得有关文件存储库的信息。",
+ "apihelp-query+fileusage-param-prop": "要获取的属性:\n;pageid:每个页面的页面ID。\n;title:每个页面的标题。\n;redirect:标记作为重定向的页面。",
+ "apihelp-query+fileusage-param-namespace": "只包括这些名字空间的页面。",
+ "apihelp-query+fileusage-param-limit": "返回多少。",
+ "apihelp-query+fileusage-example-simple": "获取使用[[:File:Example.jpg]]的页面列表",
+ "apihelp-query+fileusage-example-generator": "获取有关使用[[:File:Example.jpg]]的页面的信息",
+ "apihelp-query+imageinfo-description": "返回文件信息和上传历史。",
+ "apihelp-query+imageinfo-param-prop": "要获取的文件信息:",
+ "apihelp-query+imageinfo-paramvalue-prop-timestamp": "添加时间戳至上传的版本。",
+ "apihelp-query+imageinfo-paramvalue-prop-comment": "此版本的摘要。",
+ "apihelp-query+imageinfo-paramvalue-prop-dimensions": "大小别名。",
+ "apihelp-query+imageinfo-paramvalue-prop-sha1": "为文件加入SHA-1哈希值。",
+ "apihelp-query+imageinfo-paramvalue-prop-mime": "添加文件的MIME类型。",
+ "apihelp-query+imageinfo-paramvalue-prop-mediatype": "添加文件媒体类型。",
+ "apihelp-query+imageinfo-param-start": "开始列举的时间戳。",
+ "apihelp-query+imageinfo-param-end": "列举的结束时间戳。",
+ "apihelp-query+imageinfo-param-urlheight": "与$1urlwidth类似。",
+ "apihelp-query+imageinfo-param-metadataversion": "要使用的元数据版本。如果<kbd>latest</kbd>被指定,则使用最新版本。默认为<kbd>1</kbd>以便向下兼容。",
+ "apihelp-query+imageinfo-param-localonly": "只看本地存储库的文件。",
+ "apihelp-query+imageinfo-example-simple": "获取有关[[:File:Albert Einstein Head.jpg]]的当前版本的信息",
+ "apihelp-query+imageinfo-example-dated": "获取有关[[:File:Albert Einstein Head.jpg]]自2008年以来版本的信息",
+ "apihelp-query+images-param-limit": "返回多少文件。",
+ "apihelp-query+images-param-dir": "罗列所采用的方向。",
+ "apihelp-query+images-example-simple": "获取[[首页]]使用的文件列表",
+ "apihelp-query+images-example-generator": "获取有关[[首页]]使用的文件的信息",
+ "apihelp-query+imageusage-description": "查找所有使用指定图片标题的页面。",
+ "apihelp-query+imageusage-param-title": "要搜索的标题。不能与$1pageid一起使用。",
+ "apihelp-query+imageusage-param-pageid": "要搜索的页面ID。不能与$1title一起使用。",
+ "apihelp-query+imageusage-param-namespace": "要列举的名字空间。",
+ "apihelp-query+imageusage-param-dir": "罗列所采用的方向。",
+ "apihelp-query+imageusage-example-simple": "显示使用[[:File:Albert Einstein Head.jpg]]的页面",
+ "apihelp-query+imageusage-example-generator": "获取有关使用[[:File:Albert Einstein Head.jpg]]的页面的信息",
+ "apihelp-query+info-description": "获取基本页面信息。",
+ "apihelp-query+info-param-prop": "要获取的额外属性:",
+ "apihelp-query+info-paramvalue-prop-protection": "列出每个页面的保护等级。",
+ "apihelp-query+info-paramvalue-prop-watched": "列出每个页面的被监视状态。",
+ "apihelp-query+info-paramvalue-prop-watchers": "监视人员数,如果允许。",
+ "apihelp-query+info-paramvalue-prop-readable": "用户是否可以阅读此页面。",
+ "apihelp-query+info-param-testactions": "测试当前用户是否可以在页面上执行某种操作。",
+ "apihelp-query+info-param-token": "请改用[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
+ "apihelp-query+info-example-simple": "获得有关页面<kbd>Main Page</kbd>的信息。",
+ "apihelp-query+info-example-protection": "获取<kbd>首页</kbd>相关的常规和保护信息。",
+ "apihelp-query+iwbacklinks-param-prefix": "跨维基前缀。",
+ "apihelp-query+iwbacklinks-param-title": "要搜索的跨wiki链接。必须与<var>$1blprefix</var>一起使用。",
+ "apihelp-query+iwbacklinks-param-limit": "返回的总计页面数。",
+ "apihelp-query+iwbacklinks-param-prop": "要获取的属性:\n;iwprefix:加入跨wiki前缀。\n;iwtitle:加入跨wiki标题。",
+ "apihelp-query+iwbacklinks-param-dir": "罗列所采用的方向。",
+ "apihelp-query+iwbacklinks-example-simple": "获得链接至[[wikibooks:Test]]的页面。",
+ "apihelp-query+iwbacklinks-example-generator": "获得有关链接至[[wikibooks:Test]]的页面的信息。",
+ "apihelp-query+iwlinks-description": "从指定页面返回所有跨wiki链接。",
+ "apihelp-query+iwlinks-param-url": "是否获取完整URL(不能与$1prop一起使用)。",
+ "apihelp-query+iwlinks-param-limit": "返回多少跨wiki链接。",
+ "apihelp-query+iwlinks-param-prefix": "只返回此前缀的跨wiki链接。",
+ "apihelp-query+iwlinks-param-title": "用于搜索的跨wiki链接。必须与<var>$1prefix</var>一起使用。",
+ "apihelp-query+iwlinks-param-dir": "罗列所采用的方向。",
+ "apihelp-query+iwlinks-example-simple": "从页面<kbd>Main Page</kbd>获得跨wiki链接。",
+ "apihelp-query+langbacklinks-param-lang": "用于语言链接的语言。",
+ "apihelp-query+langbacklinks-param-title": "要搜索的语言链接。必须与$1lang一起使用。",
+ "apihelp-query+langbacklinks-param-limit": "返回的总计页面数。",
+ "apihelp-query+langbacklinks-param-prop": "要获得的属性:\n;lllang:添加语言链接的语言代码。\n;lltitle:添加语言链接的标题。",
+ "apihelp-query+langbacklinks-param-dir": "罗列所采用的方向。",
+ "apihelp-query+langbacklinks-example-simple": "获取链接至[[:fr:Test]]的页面",
+ "apihelp-query+langbacklinks-example-generator": "获取链接至[[:fr:Test]]的页面的信息",
+ "apihelp-query+langlinks-description": "从指定页面返回所有跨语言链接。",
+ "apihelp-query+langlinks-param-limit": "返回多少语言链接。",
+ "apihelp-query+langlinks-param-url": "是否获取完整URL(不能与<var>$1prop</var>一起使用)。",
+ "apihelp-query+langlinks-param-lang": "只返回带此语言代码的语言链接。",
+ "apihelp-query+langlinks-param-title": "要搜索的链接。必须与<var>$1lang</var>一起使用。",
+ "apihelp-query+langlinks-param-dir": "罗列所采用的方向。",
+ "apihelp-query+langlinks-param-inlanguagecode": "本地化语言名称的语言代码。",
+ "apihelp-query+langlinks-example-simple": "从页面<kbd>Main Page</kbd>获得跨语言链接。",
+ "apihelp-query+links-description": "从指定页面返回所有链接。",
+ "apihelp-query+links-param-namespace": "只显示这些名字空间的链接。",
+ "apihelp-query+links-param-limit": "返回多少链接。",
+ "apihelp-query+links-param-dir": "罗列所采用的方向。",
+ "apihelp-query+links-example-simple": "从页面<kbd>Main Page</kbd>获得链接",
+ "apihelp-query+links-example-generator": "获得有关在页面<kbd>Main Page</kbd>中连接的页面的信息。",
+ "apihelp-query+links-example-namespaces": "获得在{{ns:user}}和{{ns:template}}名字空间中来自页面<kbd>Main Page</kbd>的链接。",
+ "apihelp-query+linkshere-description": "查找所有链接至指定页面的页面。",
+ "apihelp-query+linkshere-param-prop": "要获得的属性:\n;pageid:每个页面的页面ID。\n;title:每个页面的标题。\n;redirect:如果页面是一个重定向就标记。",
+ "apihelp-query+linkshere-param-namespace": "只包括这些名字空间的页面。",
+ "apihelp-query+linkshere-param-limit": "返回多少。",
+ "apihelp-query+linkshere-param-show": "只显示符合以下标准的项:\n;redirect:只显示重定向。\n;!redirect:只显示非重定向。",
+ "apihelp-query+linkshere-example-simple": "获取链接至[[首页]]的页面列表",
+ "apihelp-query+linkshere-example-generator": "获取有关链接至[[首页]]的页面的信息",
+ "apihelp-query+logevents-description": "从日志获取事件。",
+ "apihelp-query+logevents-param-start": "枚举的起始时间戳。",
+ "apihelp-query+logevents-param-end": "枚举的结束时间戳。",
+ "apihelp-query+logevents-example-simple": "列出最近日志活动",
+ "apihelp-query+pagepropnames-description": "列出wiki中所有使用中的页面属性名称。",
+ "apihelp-query+pagepropnames-param-limit": "返回名称的最大数量。",
+ "apihelp-query+pagepropnames-example-simple": "获取前10个属性名称。",
+ "apihelp-query+pageprops-example-simple": "获得用于<kbd>Category:Foo</kbd>的属性。",
+ "apihelp-query+pageswithprop-description": "列出所有使用指定页面属性的页面。",
+ "apihelp-query+pageswithprop-param-limit": "返回页面的最大数量。",
+ "apihelp-query+pageswithprop-param-dir": "排序的方向。",
+ "apihelp-query+pageswithprop-example-simple": "列出前10个使用<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>的页面。",
+ "apihelp-query+pageswithprop-example-generator": "获取有关前10个使用<code>_&#95;NOTOC_&#95;</code>的页面的信息。",
+ "apihelp-query+prefixsearch-param-search": "搜索字符串。",
+ "apihelp-query+prefixsearch-param-namespace": "搜索的名字空间。",
+ "apihelp-query+prefixsearch-param-limit": "要返回的结果最大数。",
+ "apihelp-query+prefixsearch-param-offset": "跳过的结果数。",
+ "apihelp-query+prefixsearch-example-simple": "搜索以<kbd>meaning</kbd>开头的页面标题。",
+ "apihelp-query+protectedtitles-param-namespace": "只列出这些名字空间的标题。",
+ "apihelp-query+protectedtitles-param-limit": "返回的总计页面数。",
+ "apihelp-query+protectedtitles-example-simple": "受保护标题列表",
+ "apihelp-query+protectedtitles-example-generator": "找到主命名空间中已保护的标题的链接。",
+ "apihelp-query+querypage-param-limit": "返回的结果数。",
+ "apihelp-query+querypage-example-ancientpages": "返回[[Special:Ancientpages]]的结果。",
+ "apihelp-query+random-param-namespace": "只返回这些名字空间的页面。",
+ "apihelp-query+random-param-limit": "限制返回多少随机页面。",
+ "apihelp-query+random-param-redirect": "加载一个随机重定向而不是一个随机页面。",
+ "apihelp-query+random-example-simple": "从主名字空间返回两个随机页面。",
+ "apihelp-query+recentchanges-description": "枚举最近更改。",
+ "apihelp-query+recentchanges-param-start": "枚举的起始时间戳。",
+ "apihelp-query+recentchanges-param-end": "枚举的结束时间戳。",
+ "apihelp-query+recentchanges-param-user": "只列出此用户的更改。",
+ "apihelp-query+recentchanges-param-excludeuser": "不要列出此用户的更改。",
+ "apihelp-query+recentchanges-param-tag": "只列出带此标签的更改。",
+ "apihelp-query+recentchanges-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
+ "apihelp-query+recentchanges-param-limit": "返回总计更新数。",
+ "apihelp-query+recentchanges-param-type": "显示的更改类型。",
+ "apihelp-query+recentchanges-example-simple": "最近更改列表",
+ "apihelp-query+redirects-description": "返回至指定页面的所有重定向。",
+ "apihelp-query+redirects-param-namespace": "只包含这些名字空间的页面。",
+ "apihelp-query+redirects-param-limit": "返回多少重定向。",
+ "apihelp-query+redirects-example-simple": "获取至[[Project:首页]]的重定向列表",
+ "apihelp-query+redirects-example-generator": "获取所有重定向至[[首页]]的信息",
+ "apihelp-query+revisions-example-content": "获得带内容的数据,用于标题<kbd>API</kbd>和<kbd>Main Page</kbd>的最近修订。",
+ "apihelp-query+revisions-example-last5": "获取<kbd>Main Page</kbd>的最近5次修订。",
+ "apihelp-query+revisions-example-first5": "获取<kbd>Main Page</kbd>的前5次修订。",
+ "apihelp-query+revisions-example-first5-after": "获得<kbd>Main Page</kbd>于2006年05月01日之后做出的前5次修订版本。",
+ "apihelp-query+revisions-example-first5-not-localhost": "获取<kbd>Main Page</kbd>的前5次不是由匿名用户<kbd>127.0.0.1</kbd>做出的修订。",
+ "apihelp-query+revisions-example-first5-user": "获取<kbd>Main Page</kbd>的前5次由用户<kbd>MediaWiki default</kbd>做出的修订。",
+ "apihelp-query+revisions+base-param-limit": "限制返回多少修订。",
+ "apihelp-query+search-param-search": "搜索所有拥有此值的页面标题(或内容)。",
+ "apihelp-query+search-param-namespace": "只在这些名字空间搜索。",
+ "apihelp-query+search-param-info": "要返回的元数据。",
+ "apihelp-query+search-param-limit": "返回的总计页面数。",
+ "apihelp-query+search-param-interwiki": "搜索结果中包含跨wiki结果,如果可用。",
+ "apihelp-query+search-example-simple": "搜索<kbd>meaning</kbd>。",
+ "apihelp-query+search-example-text": "搜索文本<kbd>meaning</kbd>。",
+ "apihelp-query+search-example-generator": "获得有关搜索<kbd>meaning</kbd>返回页面的页面信息。",
+ "apihelp-query+siteinfo-param-numberingroup": "列出用户组中的用户数。",
+ "apihelp-query+siteinfo-example-simple": "获取网站信息",
+ "apihelp-query+siteinfo-example-interwiki": "获取本地跨wiki前缀列表",
+ "apihelp-query+siteinfo-example-replag": "检查当前的响应延迟。",
+ "apihelp-query+stashimageinfo-example-simple": "返回藏匿文件的信息。",
+ "apihelp-query+tags-description": "列出更改标签。",
+ "apihelp-query+tags-param-limit": "列出标签的最大数量。",
+ "apihelp-query+tags-param-prop": "要获取哪个属性:\n;name:添加标签名称。\n;displayname:为标签添加系统消息。\n;description:为标签添加描述。\n;hitcount:已添加此标签的修订版本与日志数量。\n;defined:标识标签是否已定义。\n;source:获得标签来源,它可能包括用于扩展定义的标签的<samp>extension</samp>,以及用于可被用户手动应用的标签的<samp>manual</samp>。\n;active:标签是否仍可被应用。",
+ "apihelp-query+tags-example-simple": "可用标签列表",
+ "apihelp-query+templates-param-namespace": "只显示此名字空间的模板。",
+ "apihelp-query+templates-param-limit": "返回多少模板。",
+ "apihelp-query+templates-param-templates": "只列出这些模板。对于检查某一页面使用某一模板很有用。",
+ "apihelp-query+templates-param-dir": "罗列所采用的方向。",
+ "apihelp-query+templates-example-simple": "获得在页面<kbd>Main Page</kbd>使用的模板。",
+ "apihelp-query+templates-example-generator": "获得有关<kbd>Main Page</kbd>中使用的模板页面的信息。",
+ "apihelp-query+templates-example-namespaces": "获得在{{ns:user}}和{{ns:template}}名字空间中,嵌入在<kbd>Main Page</kbd>页面的页面。",
+ "apihelp-query+tokens-param-type": "要请求的令牌类型。",
+ "apihelp-query+transcludedin-param-namespace": "至包含这些名字空间的页面。",
+ "apihelp-query+transcludedin-param-limit": "返回多少。",
+ "apihelp-query+transcludedin-example-simple": "获得嵌入<kbd>Main Page</kbd>的页面列表。",
+ "apihelp-query+transcludedin-example-generator": "获得有关嵌入<kbd>Main Page</kbd>的页面的信息。",
+ "apihelp-query+usercontribs-description": "获取一位用户的所有编辑。",
+ "apihelp-query+usercontribs-param-limit": "返回贡献的最大数量。",
+ "apihelp-query+usercontribs-param-start": "返回的起始时间戳。",
+ "apihelp-query+usercontribs-param-end": "返回的最终时间戳。",
+ "apihelp-query+usercontribs-param-namespace": "只列出这些名字空间的贡献。",
+ "apihelp-query+usercontribs-example-user": "显示用户<kbd>Example</kbd>的贡献。",
+ "apihelp-query+usercontribs-example-ipprefix": "显示来自<kbd>192.0.2.</kbd>前缀所有 IP 地址的贡献。",
+ "apihelp-query+userinfo-description": "获取有关当前用户的信息。",
+ "apihelp-query+userinfo-example-simple": "获取有关当前用户的信息",
+ "apihelp-query+userinfo-example-data": "获取有关当前用户的额外信息",
+ "apihelp-query+users-description": "获取有关列出用户的信息。",
+ "apihelp-query+users-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
+ "apihelp-query+users-example-simple": "返回用户<kbd>Example</kbd>的信息。",
+ "apihelp-query+watchlist-param-start": "枚举的起始时间戳。",
+ "apihelp-query+watchlist-param-end": "枚举的结束时间戳。",
+ "apihelp-query+watchlist-param-user": "只列出此用户的更改。",
+ "apihelp-query+watchlist-param-excludeuser": "不要列出此用户的更改。",
+ "apihelp-query+watchlist-param-limit": "根据结果返回的结果总数。",
+ "apihelp-query+watchlist-param-token": "允许访问其他用户监视列表的安全密钥(可通过用户的[[Special:Preferences#mw-prefsection-watchlist|参数设置]]找到)。",
+ "apihelp-query+watchlist-example-generator": "在当前用户的监视列表中检索用于最近更改页面的页面信息。",
+ "apihelp-query+watchlistraw-description": "获得当前用户的监视列表上的所有页面。",
+ "apihelp-query+watchlistraw-param-namespace": "只列出指定名字空间的页面。",
+ "apihelp-query+watchlistraw-param-limit": "根据结果返回的结果总数。",
+ "apihelp-query+watchlistraw-param-token": "允许访问其他用户监视列表的安全密钥(可通过用户的[[Special:Preferences#mw-prefsection-watchlist|参数设置]]找到)。",
+ "apihelp-query+watchlistraw-example-simple": "列出当前用户的监视列表中的页面。",
+ "apihelp-revisiondelete-description": "删除和恢复修订版本。",
+ "apihelp-revisiondelete-param-hide": "每次修订要隐藏的东西。",
+ "apihelp-revisiondelete-param-show": "每次修订要恢复显示的东西。",
+ "apihelp-revisiondelete-param-reason": "删除或恢复的原因。",
+ "apihelp-revisiondelete-example-revision": "隐藏<kbd>首页</kbd>的修订版本<kbd>12345</kbd>的内容。",
+ "apihelp-rollback-param-title": "要回退的页面标题。不能与<var>$1pageid</var>一起使用。",
+ "apihelp-rollback-param-pageid": "要回退的页面的页面 ID。不能与<var>$1title</var>一起使用。",
+ "apihelp-rollback-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-rollback-example-simple": "回退由用户<kbd>Example</kbd>对<kbd>Main Page</kbd>做出的最近编辑。",
+ "apihelp-rollback-example-summary": "回退由IP用户<kbd>192.0.2.5</kbd>对页面<kbd>Main Page</kbd>做出的最近编辑,带编辑摘要<kbd>Reverting vandalism</kbd>,并将这些编辑和回退标记为机器人编辑。",
+ "apihelp-rsd-description": "导出一个RSD(Really Simple Discovery)架构",
+ "apihelp-rsd-example-simple": "导出RSD架构",
+ "apihelp-setnotificationtimestamp-param-entirewatchlist": "工作于所有已监视页面。",
+ "apihelp-setnotificationtimestamp-example-all": "重置整个监视列表的通知状态。",
+ "apihelp-setnotificationtimestamp-example-pagetimestamp": "设置<kbd>Main page</kbd>的通知时间戳,这样所有从2012年1月1日起的编辑都会是未复核的。",
+ "apihelp-setnotificationtimestamp-example-allpages": "重置在<kbd>{{ns:user}}</kbd>名字空间中的页面的通知状态。",
+ "apihelp-tokens-param-type": "要请求的令牌类型。",
+ "apihelp-unblock-description": "解封一位用户。",
+ "apihelp-unblock-param-id": "解封时需要的封禁ID(通过<kbd>list=blocks</kbd>获得)。不能与<var>$1user</var>一起使用。",
+ "apihelp-unblock-param-user": "要解封的用户名、IP地址或IP段。不能与<var>$1id</var>一起使用。",
+ "apihelp-unblock-param-reason": "解封的原因。",
+ "apihelp-unblock-example-id": "解封封禁ID #<kbd>105</kbd>。",
+ "apihelp-unblock-example-user": "解封用户<kbd>Bob</kbd>,原因<kbd>Sorry Bob</kbd>。",
+ "apihelp-undelete-param-title": "要恢复的页面标题。",
+ "apihelp-undelete-param-reason": "恢复的原因。",
+ "apihelp-undelete-param-fileids": "要恢复的文件修订ID。如果<var>$1timestamps</var>和<var>$1fileids</var>都为空,所有将被恢复。",
+ "apihelp-undelete-example-page": "恢复页面<kbd>Main Page</kbd>。",
+ "apihelp-undelete-example-revisions": "恢复<kbd>首页</kbd>的两个修订。",
+ "apihelp-upload-param-filename": "目标文件名。",
+ "apihelp-upload-param-comment": "上传注释。如果没有指定<var>$1text</var>,那么它也被用于新文件的初始页面文本。",
+ "apihelp-upload-param-watch": "监视页面。",
+ "apihelp-upload-param-watchlist": "无条件地将页面加入至当前用户的监视列表或将其移除,使用设置或不更改监视。",
+ "apihelp-upload-param-ignorewarnings": "忽略任何警告。",
+ "apihelp-upload-param-file": "文件内容。",
+ "apihelp-upload-param-stash": "如果设置,服务器将临时藏匿文件而不是加入存储库。",
+ "apihelp-upload-param-offset": "块的偏移量(字节)。",
+ "apihelp-upload-param-chunk": "大块内容。",
+ "apihelp-upload-example-url": "从URL上传",
+ "apihelp-upload-example-filekey": "完成一次由于警告而失败的上传。",
+ "apihelp-userrights-description": "更改一位用户的组成员。",
+ "apihelp-userrights-param-user": "用户名。",
+ "apihelp-userrights-param-userid": "用户ID。",
+ "apihelp-userrights-param-add": "将用户加入至这些组中。",
+ "apihelp-userrights-param-remove": "将用户从这些组中移除。",
+ "apihelp-userrights-param-reason": "更改原因。",
+ "apihelp-userrights-example-user": "将用户<kbd>FooBot</kbd>添加至<kbd>bot</kbd>用户组,并从<kbd>sysop</kbd>和<kbd>bureaucrat</kbd>组移除。",
+ "apihelp-userrights-example-userid": "将ID为<kbd>123</kbd>的用户加入至<kbd>机器人</kbd>组,并将其从<kbd>管理员</kbd>和<kbd>行政员</kbd>组移除。",
+ "apihelp-watch-param-title": "要(取消)监视的页面。也可使用<var>$1titles</var>。",
+ "apihelp-watch-example-watch": "监视页面<kbd>Main Page</kbd>。",
+ "apihelp-watch-example-unwatch": "取消监视页面<kbd>首页</kbd>。",
+ "apihelp-format-example-generic": "格式化查询结果为$1格式。",
+ "apihelp-dbg-description": "输出数据为PHP的<code>var_export()</code>格式。",
+ "apihelp-dbgfm-description": "输出数据为PHP的<code>var_export()</code>格式(HTML优质打印效果)。",
+ "apihelp-dump-description": "输出数据为PHP的<code>var_dump()</code>格式。",
+ "apihelp-dumpfm-description": "输出数据为PHP的<code>var_dump()</code>格式(HTML优质打印效果)。",
+ "apihelp-json-description": "输出数据为JSON格式。",
+ "apihelp-jsonfm-description": "输出数据为JSON格式(HTML优质打印效果)。",
+ "apihelp-none-description": "不输出任何东西。",
+ "apihelp-php-description": "输出数据为序列化PHP格式。",
+ "apihelp-phpfm-description": "输出数据为序列化PHP格式(HTML优质打印效果)。",
+ "apihelp-rawfm-description": "输出数据为JSON格式,带调试元素(HTML优质打印效果)。",
+ "apihelp-txt-description": "输出数据为PHP的<code>print_r()</code>格式。",
+ "apihelp-txtfm-description": "输出数据为PHP的<code>print_r()</code>格式(HTML优质打印效果)。",
+ "apihelp-wddx-description": "输出数据为WDDX格式。",
+ "apihelp-wddxfm-description": "输出数据为WDDX格式(HTML优质打印效果)。",
+ "apihelp-xml-description": "输出数据为XML格式。",
+ "apihelp-xml-param-xslt": "如果指定,加入已命名的页面作为一个XSL样式表。值必须是在{{ns:mediawiki}}名字空间以<code>.xsl</code>为结尾的标题。",
+ "apihelp-xmlfm-description": "输出数据为XML格式(HTML优质打印效果)。",
+ "apihelp-yaml-description": "输出数据为YAML格式。",
+ "apihelp-yamlfm-description": "输出数据为YAML格式(HTML优质打印效果)。",
+ "api-format-title": "MediaWiki API 结果",
+ "api-format-prettyprint-header": "这是$1格式的HTML表示。HTML对调试很有用,但不适合应用程序使用。\n\n指定<var>format</var>参数以更改输出格式。要查看$1格式的非HTML表示,设置<kbd>format=$2</kbd>。\n\n参见[[mw:API|完整文档]],或[[Special:ApiHelp/main|API 帮助]]以获取更多信息。",
+ "api-orm-param-props": "要查询的字段。",
+ "api-orm-param-limit": "返回的总行数。",
+ "api-pageset-param-generator": "通过执行指定查询模块获得页面列表以工作。\n\n<strong>注意:</strong>发生器参数名称必须以“g”开头,参见例子。",
+ "api-pageset-param-redirects-nogenerator": "自动解决<var>$1titles</var>、<var>$1pageids</var>和<var>$1revids</var>中的重定向。",
+ "api-help-title": "MediaWiki API 帮助",
+ "api-help-lead": "这是自动生成的MediaWiki API文档页面。\n\n文档和例子:https://www.mediawiki.org/wiki/API:Main_page/zh",
+ "api-help-main-header": "主模块",
+ "api-help-flag-deprecated": "此模块已弃用。",
+ "api-help-flag-internal": "<strong>此模块是内部或不稳定的。</strong>它的操作可以更改而不另行通知。",
+ "api-help-flag-readrights": "此模块需要读取权限。",
+ "api-help-flag-writerights": "此模块需要写入权限。",
+ "api-help-flag-mustbeposted": "此模块只允许POST请求。",
+ "api-help-flag-generator": "此模块可作为发生器使用。",
+ "api-help-parameters": "{{PLURAL:$1|参数}}:",
+ "api-help-param-deprecated": "不推荐使用。",
+ "api-help-param-required": "这个参数是必须的。",
+ "api-help-param-list": "{{PLURAL:$1|1=一个值|2=值(以<kbd>{{!}}</kbd>分隔)}}:$2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=必须为空|可以为空,或$2}}",
+ "api-help-param-limit": "不允许超过$1。",
+ "api-help-param-limit2": "不允许超过$1个(对于机器人则是$2个)。",
+ "api-help-param-integer-min": "{{PLURAL:$1|值}}必须不少于$2。",
+ "api-help-param-integer-max": "{{PLURAL:$1|值}}必须不大于$3。",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|值}}必须介于$2和$3之间。",
+ "api-help-param-multi-separate": "通过“<kbd>|</kbd>”隔开各值。",
+ "api-help-param-multi-max": "值的最高数字是{{PLURAL:$1|$1}}(对于机器人则是{{PLURAL:$2|$2}})。",
+ "api-help-param-default": "默认:$1",
+ "api-help-param-default-empty": "默认:<span class=\"apihelp-empty\">(空)</span>",
+ "api-help-param-token": "从[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]取回的“$1”令牌",
+ "api-help-param-disabled-in-miser-mode": "由于[[mw:Manual:$wgMiserMode|miser模式]]而禁用。",
+ "api-help-param-limited-in-miser-mode": "<strong>注意:</strong>由于[[mw:Manual:$wgMiserMode|miser模式]],使用这个可能导致继续前返回少于<var>$1limit</var>个结果;极端情况下可能不会返回任何结果。",
+ "api-help-param-direction": "列举的方向:\n;newer:最早的优先。注意:$1start应早于$1end。\n;older:最新的优先(默认)。注意:$1start应晚于$1end。",
+ "api-help-param-continue": "当更多结果可用时,使用这个继续。",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(没有说明)</span>",
+ "api-help-examples": "{{PLURAL:$1|例子}}:",
+ "api-help-permissions": "{{PLURAL:$1|权限}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|授予}}:$2",
+ "api-credits-header": "制作人员",
+ "api-credits": "API 开发人员:\n* Roan Kattouw(2007年9月~2009年的开发组领导)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan(创建者,2006年9月~2007年9月的开发组领导)\n* Brad Jorsch(2013年至今的开发组领导)\n\n请将您的评论、建议和问题发送至mediawiki-api@lists.wikimedia.org,或提交错误请求在https://phabricator.wikimedia.org/。"
+}
diff --git a/includes/api/i18n/zh-hant.json b/includes/api/i18n/zh-hant.json
new file mode 100644
index 00000000..dc3cc2d8
--- /dev/null
+++ b/includes/api/i18n/zh-hant.json
@@ -0,0 +1,244 @@
+{
+ "@metadata": {
+ "authors": [
+ "Cwlin0416",
+ "Liuxinyu970226",
+ "LNDDYL",
+ "EagerLin"
+ ]
+ },
+ "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文件]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 郵件清單]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug與請求]\n</div>\n<strong>狀態資訊:</strong>本頁所展示的所有功能都應正常工作,但是 API 仍在開發當中,將會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵件清單]以便得到更新通知。\n\n<strong>錯誤請求:</strong>當 API 收到錯誤請求時, HTTP header 將會返回一個包含「MediaWiki-API-Error」的值,隨後 header 的值與錯誤碼將會送回並設定為相同的值。詳細資訊請參閱[[mw:API:Errors_and_warnings|API: 錯誤與警告]]。",
+ "apihelp-main-param-action": "要執行的動作。",
+ "apihelp-main-param-format": "輸出的格式。",
+ "apihelp-block-description": "封鎖使用者。",
+ "apihelp-block-param-user": "您要封鎖的使用者名稱、IP 位址或 IP 範圍。",
+ "apihelp-block-param-reason": "封鎖原因。",
+ "apihelp-block-param-anononly": "僅封鎖匿名使用者 (禁止這個 IP 位址的匿名使用者編輯)。",
+ "apihelp-block-param-nocreate": "禁止建立帳號。",
+ "apihelp-block-param-autoblock": "自動封鎖最後使用的 IP 位址,以及在這之後嘗試登入的 IP 位址。",
+ "apihelp-block-param-noemail": "禁止使用者透過 Wiki 寄送電子郵件。 (需要 <code>blockemail</code> 權限)。",
+ "apihelp-block-param-hidename": "隱藏封鎖日誌的使用者名稱。 (需要 <code>hideuser</code> 權限)。",
+ "apihelp-block-param-allowusertalk": "允許使用者編輯自己的對話頁面 (依據 <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> 的設定)。",
+ "apihelp-block-param-reblock": "若使用者已被封鎖,覆寫既有的封鎖設定值。",
+ "apihelp-block-param-watchuser": "監視使用者或 IP 位址的使用者頁面與對話頁面。",
+ "apihelp-block-example-ip-simple": "封鎖 IP 位址 <kbd>192.0.2.5</kbd> 三天,原因為 <kbd>First strike</kbd>。",
+ "apihelp-block-example-user-complex": "永久封鎖 IP 位址 <kbd>Vandal</kbd>,原因為 <kbd>First strike</kbd>。",
+ "apihelp-checktoken-description": "檢查來自 <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> 的密鑰有效性。",
+ "apihelp-checktoken-param-type": "要測試的密鑰類型。",
+ "apihelp-checktoken-param-token": "要測試的密鑰。",
+ "apihelp-checktoken-param-maxtokenage": "密鑰的有效期間,以秒為單位。",
+ "apihelp-checktoken-example-simple": "測試 <kbd>csrf</kbd> 密鑰的有效性。",
+ "apihelp-clearhasmsg-description": "清除目前使用者的 <code>hasmsg</code> 標記。",
+ "apihelp-clearhasmsg-example-1": "清除目前使用者的 <code>hasmsg</code> 標記。",
+ "apihelp-compare-description": "比較 2 個頁面間的差異。\n\n\"from\" 以及 \"to\" 的修訂編號,頁面標題或頁面 ID 為必填。",
+ "apihelp-compare-param-fromtitle": "要比對的第一個標題。",
+ "apihelp-compare-param-fromid": "要比對的第一個頁面 ID。",
+ "apihelp-compare-param-fromrev": "要比對的第一個修訂。",
+ "apihelp-compare-param-totitle": "要比對的第二個標題。",
+ "apihelp-compare-param-toid": "要比對的第二個頁面 ID。",
+ "apihelp-compare-param-torev": "要比對的第二個修訂。",
+ "apihelp-compare-example-1": "建立修訂 1 與 1 的差異檔",
+ "apihelp-createaccount-description": "建立新使用者帳號。",
+ "apihelp-createaccount-param-name": "使用者名稱。",
+ "apihelp-createaccount-param-password": "密碼 (若有設定 <var>$1mailpassword</var> 則可略過)。",
+ "apihelp-createaccount-param-domain": "外部認証使用的網域 (選填)。",
+ "apihelp-createaccount-param-token": "已取得帳號建立密鑰於第一次請求。",
+ "apihelp-createaccount-param-email": "使用者的電子郵件地址 (選填) 。",
+ "apihelp-createaccount-param-realname": "使用者的真實姓名 (選填)。",
+ "apihelp-createaccount-param-mailpassword": "若設為其他值,將會以電子郵件寄送隨機密碼給使用者。",
+ "apihelp-createaccount-param-reason": "建立帳號時選填的原因,會被記錄到日誌當中。",
+ "apihelp-createaccount-param-language": "要設定的使用者預設語言代碼 (選填,預設依據內容語言)。",
+ "apihelp-createaccount-example-pass": "建立使用者 <kbd>testuser</kbd> 使用密碼 <kbd>test123</kbd>",
+ "apihelp-createaccount-example-mail": "建立使用者 <kbd>testmailuser</kbd> 並且電子郵件通知隨機產生的密碼。",
+ "apihelp-delete-description": "刪除頁面。",
+ "apihelp-delete-param-title": "您欲刪除的頁面標題。 無法與 <var>$1pageid</var> 同時使用。",
+ "apihelp-delete-param-pageid": "您欲刪除頁面的頁面 ID。 無法與 <var>$1title</var> 同時使用。",
+ "apihelp-delete-param-reason": "刪除的原因。 若未設定,將會使用自動產生的原因。",
+ "apihelp-delete-param-watch": "加入目前頁面至您的監視清單。",
+ "apihelp-delete-param-watchlist": "無條件使用設置將頁面加入或移除目前使用者的監視清單或者是不更改監視清單。",
+ "apihelp-delete-param-unwatch": "從您的監視清單中移除目前頁面。",
+ "apihelp-delete-param-oldimage": "由 [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]] 所提供要刪除的舊圖片名稱。",
+ "apihelp-delete-example-simple": "刪除 <kbd>Main Page</kbd>。",
+ "apihelp-delete-example-reason": "刪除 <kbd>Main Page</kbd> 原因為 <kbd>Preparing for move</kbd>。",
+ "apihelp-disabled-description": "已停用此模組。",
+ "apihelp-edit-description": "建立與編輯頁面。",
+ "apihelp-edit-param-title": "您欲編輯的頁面標題。 無法與 <var>$1pageid</var> 同時使用。",
+ "apihelp-edit-param-pageid": "您欲編輯頁面的頁面 ID。 無法與 <var>$1title</var> 同時使用。",
+ "apihelp-edit-param-section": "章節編號。 <kbd>0</kbd> 代表最上層章節,<kbd>new</kbd> 代表新章節。",
+ "apihelp-edit-param-sectiontitle": "新章節的標題。",
+ "apihelp-edit-param-text": "頁面內容。",
+ "apihelp-edit-param-summary": "編輯摘要。 當未設定 $1section=new 與 $1sectiontitle 時也會當做章節標題。",
+ "apihelp-edit-param-minor": "小編輯。",
+ "apihelp-edit-param-notminor": "非小編輯。",
+ "apihelp-edit-param-bot": "標記此編輯為機器人編輯。",
+ "apihelp-edit-param-basetimestamp": "基於修訂的時間戳記,用來檢測編輯衝突。也许可以取得[[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]認可。",
+ "apihelp-edit-param-createonly": "若頁面已存在,則不編輯頁面。",
+ "apihelp-edit-param-nocreate": "若頁面不存在,則產生錯誤。",
+ "apihelp-edit-param-watch": "加入目前頁面至您的監視清單。",
+ "apihelp-edit-param-unwatch": "從您的監視清單中移除目前頁面。",
+ "apihelp-edit-example-edit": "編輯頁面",
+ "apihelp-emailuser-description": "寄送電子郵件給使用者。",
+ "apihelp-emailuser-param-target": "電子郵件的收件使用者。",
+ "apihelp-emailuser-param-subject": "郵件主旨。",
+ "apihelp-emailuser-param-text": "郵件內容。",
+ "apihelp-emailuser-param-ccme": "寄送一份此郵件的複本給我。",
+ "apihelp-emailuser-example-email": "寄送電子郵件給使用者 <kbd>WikiSysop</kbd> 使用內容 <kbd>Content</kbd>",
+ "apihelp-expandtemplates-description": "展開所有於 wikitext 中模板。",
+ "apihelp-expandtemplates-param-title": "頁面標題。",
+ "apihelp-expandtemplates-param-text": "要轉換的 Wikitext。",
+ "apihelp-feedcontributions-param-showsizediff": "顯示修訂版本之間的差異大小。",
+ "apihelp-feedcontributions-example-simple": "返回使用者<kbd>Example</kbd>的貢獻。",
+ "apihelp-feedrecentchanges-description": "返回近期邊更摘要。",
+ "apihelp-feedrecentchanges-param-feedformat": "摘要格式。",
+ "apihelp-feedrecentchanges-param-namespace": "用於限制結果的命名空間。",
+ "apihelp-feedrecentchanges-param-invert": "除所選定者外的所有命名空間。",
+ "apihelp-feedrecentchanges-param-limit": "回傳的結果數量上限。",
+ "apihelp-feedrecentchanges-param-hideminor": "隱藏小編輯。",
+ "apihelp-feedrecentchanges-param-hidebots": "隱藏由機器人做的變更。",
+ "apihelp-feedrecentchanges-param-hideanons": "隱藏匿名使用者做的變更。",
+ "apihelp-feedrecentchanges-param-hideliu": "隱藏已註冊使用者做的變更。",
+ "apihelp-feedrecentchanges-param-hidepatrolled": "隱藏已巡查的變更。",
+ "apihelp-feedrecentchanges-example-simple": "顯示近期變動",
+ "apihelp-feedrecentchanges-example-30days": "顯示近期30天內的變動",
+ "apihelp-feedwatchlist-description": "返回監視清單 feed。",
+ "apihelp-feedwatchlist-param-feedformat": "Feed 的格式。",
+ "apihelp-filerevert-param-comment": "上載意見。",
+ "apihelp-help-example-main": "主模組使用說明",
+ "apihelp-help-example-recursive": "一個頁面中的所有說明。",
+ "apihelp-help-example-help": "說明模組自身的說明。",
+ "apihelp-imagerotate-description": "旋轉一張或多張圖片。",
+ "apihelp-import-param-summary": "匯入摘要。",
+ "apihelp-import-param-xml": "上載的 XML 檔。",
+ "apihelp-import-param-interwikisource": "用於跨 wiki 匯入:匯入的來源 wiki。",
+ "apihelp-import-param-interwikipage": "用於跨 wiki 匯入:匯入的頁面。",
+ "apihelp-import-param-fullhistory": "用於跨 wiki 匯入:完整匯入歷史,而不只是最新版本。",
+ "apihelp-import-param-templates": "用於跨 wiki 匯入:匯入一切包含的模板。",
+ "apihelp-import-param-namespace": "用於跨 wiki 匯入:匯入至此命名空間。",
+ "apihelp-import-param-rootpage": "匯入作為此頁面的子頁面。",
+ "apihelp-login-param-name": "使用者名稱。",
+ "apihelp-login-param-password": "密碼。",
+ "apihelp-login-param-domain": "網域名稱(可選)。",
+ "apihelp-login-example-login": "登入",
+ "apihelp-logout-description": "登出並清除 session 資料。",
+ "apihelp-logout-example-logout": "登出當前使用者",
+ "apihelp-move-description": "移動頁面。",
+ "apihelp-move-param-from": "重新命名本頁面的標題。不能與 <var>$1fromid</var> 一起出現。",
+ "apihelp-move-param-fromid": "重新命名本頁面的 ID 。不能與 <var>$1fromid</var> 一起出現。",
+ "apihelp-move-param-to": "將本頁面的標題重新命名為",
+ "apihelp-move-param-reason": "重新命名的原因。",
+ "apihelp-move-param-movesubpages": "如果適用,則重新命名子頁面。",
+ "apihelp-move-param-noredirect": "不要建立重新導向。",
+ "apihelp-move-param-ignorewarnings": "忽略所有警告。",
+ "apihelp-opensearch-description": "使用 OpenSearch 協定搜尋本 wiki。",
+ "apihelp-opensearch-param-search": "搜尋字串。",
+ "apihelp-opensearch-param-limit": "回傳的結果數量上限。",
+ "apihelp-opensearch-param-namespace": "搜尋的命名空間。",
+ "apihelp-opensearch-param-format": "輸出的格式。",
+ "apihelp-options-example-reset": "重設所有偏好設定",
+ "apihelp-query+allcategories-param-limit": "要回傳的分類數量。",
+ "apihelp-query+allfileusages-param-limit": "要回傳的項目總數。",
+ "apihelp-query+allimages-param-limit": "要回傳的圖片總數。",
+ "apihelp-query+alllinks-param-limit": "要回傳的項目總數。",
+ "apihelp-query+allpages-param-limit": "要回傳的頁面總數。",
+ "apihelp-query+allredirects-param-limit": "要回傳的項目總數。",
+ "apihelp-query+alltransclusions-param-limit": "要回傳的項目總數。",
+ "apihelp-query+categories-param-limit": "要回傳的分類數量。",
+ "apihelp-query+categorymembers-param-limit": "回傳的頁面數量上限。",
+ "apihelp-query+contributors-param-limit": "要回傳的貢獻人員數量。",
+ "apihelp-query+duplicatefiles-param-limit": "要回傳的重複檔案數量。",
+ "apihelp-query+embeddedin-param-limit": "要回傳的頁面總數。",
+ "apihelp-query+extlinks-param-limit": "要回傳的連結數量。",
+ "apihelp-query+exturlusage-param-limit": "要回傳的頁面數量。",
+ "apihelp-query+filearchive-param-limit": "要回傳的圖片總數。",
+ "apihelp-query+fileusage-param-limit": "要回傳的數量。",
+ "apihelp-query+imageinfo-param-limit": "每個檔案要回傳的檔案修訂數量。",
+ "apihelp-query+images-param-limit": "要回傳的檔案數量。",
+ "apihelp-query+iwlinks-param-limit": "要回傳的跨 Wiki 連結數量。",
+ "apihelp-query+langbacklinks-param-limit": "要回傳的頁面總數。",
+ "apihelp-query+langlinks-param-limit": "要回傳的 langlinks 數量。",
+ "apihelp-query+links-param-limit": "要回傳的連結數量。",
+ "apihelp-query+linkshere-param-limit": "要回傳的數量。",
+ "apihelp-query+logevents-param-limit": "要回傳的事件項目總數。",
+ "apihelp-query+pagepropnames-param-limit": "回傳的名稱數量上限。",
+ "apihelp-query+pageswithprop-param-limit": "回傳的頁面數量上限。",
+ "apihelp-query+prefixsearch-param-limit": "回傳的結果數量上限。",
+ "apihelp-query+protectedtitles-param-limit": "要回傳的頁面總數。",
+ "apihelp-query+querypage-param-limit": "回傳的結果數量。",
+ "apihelp-query+recentchanges-description": "列舉出近期變動。",
+ "apihelp-query+recentchanges-param-limit": "要回傳變更總數。",
+ "apihelp-query+recentchanges-example-simple": "近期變動清單",
+ "apihelp-query+redirects-param-limit": "要回傳的重新導向數量。",
+ "apihelp-query+search-param-limit": "要回傳的頁面總數。",
+ "apihelp-query+templates-param-limit": "要回傳的樣板數量。",
+ "apihelp-query+tokens-param-type": "要請求的密鑰類型。",
+ "apihelp-query+tokens-example-simple": "接收 csrf 密鑰 (預設)。",
+ "apihelp-query+tokens-example-types": "接收監視密鑰以及巡邏密鑰。",
+ "apihelp-query+transcludedin-param-limit": "回傳的數量。",
+ "apihelp-query+usercontribs-param-limit": "回傳的貢獻數量上限。",
+ "apihelp-query+watchlist-param-limit": "每個請求要回傳的結果總數。",
+ "apihelp-query+watchlistraw-param-limit": "每個請求要回傳的結果總數。",
+ "apihelp-tokens-description": "取得資料修改動作的密鑰。\n\n此模組已因支援 [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] 而停用。",
+ "apihelp-unblock-param-reason": "解除封鎖的原因。",
+ "apihelp-unblock-example-id": "解除封銷 ID #<kbd>105</kbd>。",
+ "apihelp-undelete-param-reason": "還原的原因。",
+ "apihelp-userrights-description": "更改一位使用者的群組成員。",
+ "apihelp-userrights-param-user": "使用者名稱。",
+ "apihelp-userrights-param-userid": "使用者 ID。",
+ "apihelp-userrights-param-add": "加入使用者至這些群組。",
+ "apihelp-userrights-param-remove": "從這些群組移除使用者。",
+ "apihelp-userrights-param-reason": "變更的原因。",
+ "apihelp-format-example-generic": "格式化查詢結果為 $1 格式",
+ "apihelp-dbg-description": "使用 PHP 的 <code>var_export()</code> 格式輸出資料。",
+ "apihelp-dbgfm-description": "使用 PHP 的 <code>var_export()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-dump-description": "使用 PHP 的 <code>var_dump()</code> 格式輸出資料。",
+ "apihelp-dumpfm-description": "使用 PHP 的 <code>var_dump()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-json-description": "使用 JSON 格式輸出資料。",
+ "apihelp-jsonfm-description": "使用 JSON 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-none-description": "不輸出。",
+ "apihelp-php-description": "使用序列化 PHP 格式輸出資料。",
+ "apihelp-phpfm-description": "使用序列化 PHP 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-rawfm-description": "使用 JSON 格式的除錯元素輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-txt-description": "使用 PHP 的 <code>print_r()</code> 格式輸出資料。",
+ "apihelp-txtfm-description": "使用 PHP 的 <code>print_r()</code> 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-wddx-description": "使用 WDDX 格式輸出資料。",
+ "apihelp-wddxfm-description": "使用 WDDX 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-xml-description": "使用 XML 格式輸出資料。",
+ "apihelp-xmlfm-description": "使用 XML 格式輸出資料 (使用 HTML 格式顯示)。",
+ "apihelp-yaml-description": "使用 YAML 格式輸出資料。",
+ "apihelp-yamlfm-description": "使用 YAML 格式輸出資料 (使用 HTML 格式顯示)。",
+ "api-format-title": "MediaWiki API 結果",
+ "api-orm-param-props": "要查詢的欄位。",
+ "api-orm-param-limit": "回傳的列數上限。",
+ "api-pageset-param-titles": "要使用的標題清單。",
+ "api-pageset-param-pageids": "要使用的頁面 ID 清單。",
+ "api-pageset-param-revids": "要使用的修訂 ID 清單。",
+ "api-help-title": "MediaWiki API 說明",
+ "api-help-lead": "此頁為自動產生的 MediaWiki API 說明文件頁面。\n\n說明文件與範例:https://www.mediawiki.org/wiki/API",
+ "api-help-main-header": "主要模組",
+ "api-help-flag-deprecated": "此模組已停用。",
+ "api-help-flag-readrights": "此模組需要讀取權限。",
+ "api-help-flag-writerights": "此模組需要寫入權限。",
+ "api-help-flag-mustbeposted": "此模組僅接受 POST 請求。",
+ "api-help-parameters": "{{PLURAL:$1|參數}}:",
+ "api-help-param-deprecated": "已停用。",
+ "api-help-param-required": "此參數為必填。",
+ "api-help-param-list": "{{PLURAL:$1|1=單值|2=多值 (以 <kbd>{{!}}</kbd> 分隔)}}:$2",
+ "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=必須空白|可以空白,或 $2}}",
+ "api-help-param-limit": "不允許超過 $1。",
+ "api-help-param-limit2": "不允許超過 $1 (機器人為 $2)。",
+ "api-help-param-integer-min": "{{PLURAL:$1|1=數值|2=數值}}不可小於 $2。",
+ "api-help-param-integer-max": "{{PLURAL:$1|1=數值|2=數值}}不可大於 $3。",
+ "api-help-param-integer-minmax": "{{PLURAL:$1|1=數值|2=數值}}必須在 $2 與 $3 之間。",
+ "api-help-param-upload": "必須使用 multipart/form-data 以檔案上傳的方式傳送。",
+ "api-help-param-multi-separate": "使用 <kbd>|</kbd> 分隔數值。",
+ "api-help-param-multi-max": "上限值為 {{PLURAL:$1|$1}} (機器人為 {{PLURAL:$2|$2}})。",
+ "api-help-param-default": "預設值:$1",
+ "api-help-param-default-empty": "預設值:<span class=\"apihelp-empty\">(空)</span>",
+ "api-help-param-token": "自 [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] 接收的 \"$1\" 密鑰。",
+ "api-help-param-no-description": "<span class=\"apihelp-empty\">(無描述)</span>",
+ "api-help-examples": "{{PLURAL:$1|範例}}:",
+ "api-help-permissions": "{{PLURAL:$1|權限}}:",
+ "api-help-permissions-granted-to": "{{PLURAL:$1|已授權給}}: $2",
+ "api-credits-header": "製作群",
+ "api-credits": "API 開發人員:\n* Roan Kattouw (首席開發者 Sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Yuri Astrakhan (創立者,首席開發者 Sep 2006–Sep 2007)\n* Brad Jorsch (首席開發者 2013–present)\n\n請傳送您的評論、建議以及問題至 mediawiki-api@lists.wikimedia.org\n或者回報問題至 https://phabricator.wikimedia.org/。"
+}