From d25cb99202789448c1074bbf50c037f16e4391b5 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Wed, 17 Sep 2014 15:43:31 -0400 Subject: [PATCH] API: Clean up and internationalize pretty-printed output The syntax highlighting applied to the XML format is not all that great, and applying it to other formats is just wrong. Instead of doing it ourselves, let's just add a hook and let Extension:SyntaxHighlight_GeSHi do it for us. But for that to work, we have to add RL support to the pretty-printed output, which means OutputPage. At the same time, lets internationalize the header. Bug: 65403 Change-Id: I04b1a3842abdf1fb360c54aa7164fc7cd2e50f4b --- RELEASE-NOTES-1.25 | 10 + docs/hooks.txt | 7 + includes/api/ApiFormatBase.php | 253 +++++++++--------- includes/api/ApiFormatDbg.php | 4 - includes/api/ApiFormatDump.php | 4 - includes/api/ApiFormatJson.php | 26 +- includes/api/ApiFormatNone.php | 4 - includes/api/ApiFormatPhp.php | 4 - includes/api/ApiFormatRaw.php | 27 +- includes/api/ApiFormatTxt.php | 4 - includes/api/ApiFormatWddx.php | 4 - includes/api/ApiFormatXml.php | 21 +- includes/api/ApiFormatYaml.php | 4 - includes/api/ApiHelp.php | 4 +- includes/api/ApiMain.php | 4 - includes/api/i18n/en.json | 27 ++ includes/api/i18n/qqq.json | 27 ++ resources/Resources.php | 4 + .../src/mediawiki/mediawiki.apipretty.css | 11 + .../includes/api/format/ApiFormatTestBase.php | 6 +- 20 files changed, 256 insertions(+), 199 deletions(-) create mode 100644 resources/src/mediawiki/mediawiki.apipretty.css diff --git a/RELEASE-NOTES-1.25 b/RELEASE-NOTES-1.25 index 717f0c6aa4..93f3be846b 100644 --- a/RELEASE-NOTES-1.25 +++ b/RELEASE-NOTES-1.25 @@ -47,6 +47,8 @@ production. * Default output format for the API is now jsonfm. * Simplified continuation will return a "batchcomplete" property in the result when a batch of pages is complete. +* Pretty-printed HTML output now has nicer formatting and (if available) + better syntax highlighting. === Action API internal changes in 1.25 === * ApiHelp has been rewritten to support i18n and paginated HTML output. @@ -66,6 +68,11 @@ production. * Api formatters will no longer be asked to display the help screen on errors. * ApiMain::getCredits() was removed. The credits are available in the 'api-credits' i18n message. +* ApiFormatBase has been changed to support i18n and syntax highlighting via + extensions with the new 'ApiFormatHighlight' hook. Core syntax highlighting + has been removed. +* ApiFormatBase now always buffers. Output is done when + ApiFormatBase::closePrinter is called. * The following methods have been deprecated and may be removed in a future release: * ApiBase::getDescription @@ -77,6 +84,9 @@ production. * ApiFormatBase::setUnescapeAmps * ApiFormatBase::getWantsHelp * ApiFormatBase::setHelp + * ApiFormatBase::formatHTML + * ApiFormatBase::setBufferResult + * ApiFormatBase::getDescription * ApiMain::setHelp * ApiMain::reallyMakeHelpMsg * ApiMain::makeHelpMsgHeader diff --git a/docs/hooks.txt b/docs/hooks.txt index 6448512538..c60cc7618c 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -379,6 +379,13 @@ $editPage : the EditPage object $text : the new text of the article (has yet to be saved) &$resultArr : data in this array will be added to the API result +'ApiFormatHighlight': Use to syntax-highlight API pretty-printed output. When +highlighting, add output to $context->getOutput() and return false. +$context: An IContextSource. +$text: Text to be highlighted. +$mime: MIME type of $text. +$format: API format code for $text. + 'APIGetAllowedParams': Use this hook to modify a module's parameters. &$module: ApiBase Module object &$params: Array of parameters diff --git a/includes/api/ApiFormatBase.php b/includes/api/ApiFormatBase.php index c3731aa6f5..1baaaecc86 100644 --- a/includes/api/ApiFormatBase.php +++ b/includes/api/ApiFormatBase.php @@ -30,8 +30,8 @@ * @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; /** * If $format ends with 'fm', pretty-print the output in HTML. @@ -48,12 +48,14 @@ 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(); @@ -74,21 +76,6 @@ abstract class ApiFormatBase extends ApiBase { return $this->mFormat; } - /** - * Specify whether or not sequences like " should be unescaped - * to " . 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; - } - /** * Returns true when the HTML pretty-printer should be used. * The default implementation assumes that formats ending with 'fm' @@ -100,32 +87,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 - * @deprecated since 1.25 - * @return bool - */ - public function getWantsHelp() { - wfDeprecated( __METHOD__, '1.25' ); - 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 */ @@ -134,24 +116,19 @@ 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). + * Initialize the printer function and prepare the output headers. * @param bool $unused Always false since 1.25 */ function initPrinter( $unused ) { 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 } @@ -162,80 +139,60 @@ abstract class ApiFormatBase extends ApiBase { if ( $apiFrameOptions ) { $this->getMain()->getRequest()->response()->header( "X-Frame-Options: $apiFrameOptions" ); } - - if ( $isHtml ) { -?> - - - -mUnescapeAmps ) { -?> MediaWiki API - MediaWiki API Result - - - -
- -You are looking at the HTML representation of the mFormat; ?> format.
-HTML is good for debugging, but is unsuitable for application use.
-Specify the format parameter to change the output format.
-To see the non HTML representation of the mFormat; ?> format, set format=mFormat ); ?>.
-See the complete documentation, or -API help for more information. -
-
-mDisabled ) {
 			return;
 		}
-		if ( $this->getIsHtml() ) {
-?>
 
-
- - -getMimeType(); + if ( $this->getIsHtml() && $mime !== null ) { + $format = $this->getFormat(); + $result = $this->getBuffer(); + + $context = new DerivativeContext( $this->getMain() ); + $context->setUser( new User ); // anon to avoid caching issues + $context->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'apioutput' ) ); + $out = new OutputPage( $context ); + $out->addModules( 'mediawiki.apipretty' ); + $out->setPageTitle( $context->msg( 'api-format-title' ) ); + $context->setOutput( $out ); + + $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 ( wfRunHooks( 'ApiFormatHighlight', array( $context, $result, $mime, $format ) ) ) { + $out->addHTML( + Html::element( 'pre', array( 'class' => 'api-pretty-content' ), $result ) + ); + } + + $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; } /** @@ -246,12 +203,59 @@ See the complete documentation, return $this->mBuffer; } + public 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 &quot; should be unescaped + * to " . 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(); } /** @@ -267,10 +271,13 @@ See the complete documentation, /** * 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 ); @@ -323,30 +330,26 @@ See the complete documentation, 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 ) { } + + /**@}*/ } + +/** + * 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 594cd8bd15..273e205a87 100644 --- a/includes/api/ApiFormatDbg.php +++ b/includes/api/ApiFormatDbg.php @@ -43,10 +43,6 @@ class ApiFormatDbg extends ApiFormatBase { $this->printText( var_export( $this->getResultData(), true ) ); } - public function getDescription() { - return '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 1588fd814e..7ef8960b38 100644 --- a/includes/api/ApiFormatDump.php +++ b/includes/api/ApiFormatDump.php @@ -47,10 +47,6 @@ class ApiFormatDump extends ApiFormatBase { $this->printText( $result ); } - public function getDescription() { - return 'Output data in PHP\'s var_dump() format' . parent::getDescription(); - } - public function isDeprecated() { return true; } diff --git a/includes/api/ApiFormatJson.php b/includes/api/ApiFormatJson.php index db87e35209..ce8656e221 100644 --- a/includes/api/ApiFormatJson.php +++ b/includes/api/ApiFormatJson.php @@ -80,25 +80,13 @@ class ApiFormatJson extends ApiFormatBase { public function getAllowedParams() { return array( - 'callback' => null, - 'utf8' => false, + 'callback' => array( + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback', + ), + 'utf8' => array( + ApiBase::PARAM_DFLT => false, + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-utf8', + ), ); } - - 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(); - } - - return 'Output data in JSON format' . parent::getDescription(); - } } diff --git a/includes/api/ApiFormatNone.php b/includes/api/ApiFormatNone.php index 78023af3d7..dc623ac1e9 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 b2d1f044da..ae93812254 100644 --- a/includes/api/ApiFormatPhp.php +++ b/includes/api/ApiFormatPhp.php @@ -37,8 +37,4 @@ class ApiFormatPhp extends ApiFormatBase { public function execute() { $this->printText( serialize( $this->getResultData() ) ); } - - public function getDescription() { - return 'Output data in serialized PHP format' . parent::getDescription(); - } } diff --git a/includes/api/ApiFormatRaw.php b/includes/api/ApiFormatRaw.php index 3f5c8b7384..235fca1454 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(); 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() { + public function initPrinter( $unused ) { + $data = $this->getResultData(); + if ( isset( $data['error'] ) ) { + $this->errorFallback->initPrinter( $unused ); + } else { + parent::initPrinter( $unused ); + } + } + + public function closePrinter() { $data = $this->getResultData(); if ( isset( $data['error'] ) ) { - $this->mErrorFallback->execute(); + $this->errorFallback->closePrinter(); + } else { + parent::closePrinter(); + } + } + public function execute() { + $data = $this->getResultData(); + if ( isset( $data['error'] ) ) { + $this->errorFallback->execute(); return; } diff --git a/includes/api/ApiFormatTxt.php b/includes/api/ApiFormatTxt.php index 6c75a56462..505b259f58 100644 --- a/includes/api/ApiFormatTxt.php +++ b/includes/api/ApiFormatTxt.php @@ -43,10 +43,6 @@ class ApiFormatTxt extends ApiFormatBase { $this->printText( print_r( $this->getResultData(), true ) ); } - public function getDescription() { - return '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 b961a4cb98..e2d4d612db 100644 --- a/includes/api/ApiFormatWddx.php +++ b/includes/api/ApiFormatWddx.php @@ -109,10 +109,6 @@ class ApiFormatWddx extends ApiFormatBase { } } - public function getDescription() { - return '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 b3d5937950..4ed4944cf7 100644 --- a/includes/api/ApiFormatXml.php +++ b/includes/api/ApiFormatXml.php @@ -237,20 +237,13 @@ class ApiFormatXml extends ApiFormatBase { public function getAllowedParams() { return array( - 'xslt' => null, - 'includexmlnamespace' => false, + 'xslt' => array( + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback', + ), + 'includexmlnamespace' => array( + ApiBase::PARAM_DFLT => false, + ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback', + ), ); } - - public function getParamDescription() { - return array( - 'xslt' => 'If specified, adds 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 3658003bda..c9089a7d04 100644 --- a/includes/api/ApiFormatYaml.php +++ b/includes/api/ApiFormatYaml.php @@ -40,10 +40,6 @@ class ApiFormatYaml extends ApiFormatJson { parent::execute(); } - public function getDescription() { - return '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 42ec264b8a..0c962d0a96 100644 --- a/includes/api/ApiHelp.php +++ b/includes/api/ApiHelp.php @@ -42,10 +42,12 @@ class ApiHelp extends ApiBase { } // Get the help - $context = new RequestContext; + $context = new DerivativeContext( $this->getMain()->getContext() ); $context->setUser( new User ); // anon to avoid caching issues $context->setSkin( SkinFactory::getDefaultInstance()->makeSkin( 'apioutput' ) ); $context->setLanguage( $this->getMain()->getLanguage() ); + $out = new OutputPage( $context ); + $context->setOutput( $out ); self::getHelp( $context, $modules, $params ); diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 1dc3dc447d..a759c11600 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -396,10 +396,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(); } diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index 0c6b29f6d1..6c4542590a 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -18,6 +18,30 @@ "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 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.", "apihelp-main-param-uselang": "Language to use for message translations. A list of codes may be fetched from [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo&siprop=languages]], or specify \"user\" to use the current user's language preference.", + "apihelp-format-example-generic": "Format the query result in the $1 format", + "apihelp-dbg-description": "Output data in PHP's var_export() format.", + "apihelp-dbgfm-description": "Output data in PHP's var_export() format (pretty-print in HTML).", + "apihelp-dump-description": "Output data in PHP's var_dump() format.", + "apihelp-dumpfm-description": "Output data in PHP's var_dump() 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.", + "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-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 print_r() format.", + "apihelp-txtfm-description": "Output data in PHP's print_r() 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 <xslt> as stylesheet. This should be a wiki page in the MediaWiki namespace whose page name ends with \".xsl\".", + "apihelp-xml-param-includexmlnamespac": "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).", + "apihelp-help-description": "Display help for the specified modules.", "apihelp-help-param-modules": "Modules to display help for (values of the action= and format= parameters, or \"main\"). Can specify submodules with a \"+\".", "apihelp-help-param-submodules": "Include help for submodules of the named module.", @@ -30,6 +54,9 @@ "apihelp-help-example-help": "Help for the help module itself", "apihelp-help-example-query": "Help for two query submodules", + "api-format-title": "MediaWiki API result", + "api-format-prettyprint-header": "You are looking at the HTML representation of the $1 format. HTML is good for debugging, but is unsuitable for application use.\n\nSpecify the format parameter to change the output format. To see the non-HTML representation of the $1 format, set format=$2.\n\nSee the [https://www.mediawiki.org/wiki/API complete documentation], or [[Special:ApiHelp/main|API help]] for more information.", + "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", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index cecb3cd3fa..a4dfd7c076 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -16,6 +16,30 @@ "apihelp-main-param-origin": "{{doc-apihelp-param|main|origin}}", "apihelp-main-param-uselang": "{{doc-apihelp-param|main|uselang}}", + "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-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-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-includexmlnamespac": "{{doc-apihelp-param|xml|includexmlnamespac}}", + "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}}}}", + "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}}", @@ -28,6 +52,9 @@ "apihelp-help-example-help": "{{doc-apihelp-example|help}}", "apihelp-help-example-query": "{{doc-apihelp-example|help}}", + "api-format-title": "Page 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-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", diff --git a/resources/Resources.php b/resources/Resources.php index 5415a9764b..acc937e2e7 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -779,6 +779,10 @@ return array( 'mediawiki.hlist', ), ), + 'mediawiki.apipretty' => array( + 'styles' => 'resources/src/mediawiki/mediawiki.apipretty.css', + 'targets' => array( 'desktop', 'mobile' ), + ), 'mediawiki.api' => array( 'scripts' => 'resources/src/mediawiki.api/mediawiki.api.js', 'dependencies' => 'mediawiki.util', diff --git a/resources/src/mediawiki/mediawiki.apipretty.css b/resources/src/mediawiki/mediawiki.apipretty.css new file mode 100644 index 0000000000..fe5e634d72 --- /dev/null +++ b/resources/src/mediawiki/mediawiki.apipretty.css @@ -0,0 +1,11 @@ +h1.firstHeading { + display: none; +} + +.api-pretty-header { + font-size: small; +} + +.api-pretty-content { + white-space: pre-wrap; +} diff --git a/tests/phpunit/includes/api/format/ApiFormatTestBase.php b/tests/phpunit/includes/api/format/ApiFormatTestBase.php index 052bf45d71..af775708cd 100644 --- a/tests/phpunit/includes/api/format/ApiFormatTestBase.php +++ b/tests/phpunit/includes/api/format/ApiFormatTestBase.php @@ -17,13 +17,11 @@ abstract class ApiFormatTestBase extends ApiTestCase { $printer = $module->createPrinterByName( $format ); - $printer->initPrinter( false ); - ob_start(); + $printer->initPrinter( false ); $printer->execute(); - $out = ob_get_clean(); - $printer->closePrinter(); + $out = ob_get_clean(); return $out; } -- 2.20.1