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
This commit is contained in:
Brad Jorsch 2014-09-17 15:43:31 -04:00
parent af0121f9c8
commit d25cb99202
20 changed files with 307 additions and 250 deletions

View file

@ -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

View file

@ -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

View file

@ -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,6 +76,161 @@ abstract class ApiFormatBase extends ApiBase {
return $this->mFormat;
}
/**
* Returns true when the HTML pretty-printer should be used.
* The default implementation assumes that formats ending with 'fm'
* should be formatted in HTML.
* @return bool
*/
public function getIsHtml() {
return $this->mIsHtml;
}
/**
* 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.
* @since 1.23
* @return bool
*/
public function canPrintErrors() {
return true;
}
/**
* Initialize the printer function and prepare the output headers.
* @param bool $unused Always false since 1.25
*/
function initPrinter( $unused ) {
if ( $this->mDisabled ) {
return;
}
$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 ( $mime === null ) {
return; // skip any initialization
}
$this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" );
//Set X-Frame-Options API results (bug 39180)
$apiFrameOptions = $this->getConfig()->get( 'ApiFrameOptions' );
if ( $apiFrameOptions ) {
$this->getMain()->getRequest()->response()->header( "X-Frame-Options: $apiFrameOptions" );
}
}
/**
* Finish printing and output buffered data.
*/
public function closePrinter() {
if ( $this->mDisabled ) {
return;
}
$mime = $this->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();
}
}
/**
* Append text to the output buffer.
* @param string $text
*/
public function printText( $text ) {
$this->mBuffer .= $text;
}
/**
* Get the contents of the buffer.
* @return string
*/
public function getBuffer() {
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';
}
/**
* 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.
*/
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 " should be unescaped
* to " . This should only be set to true for the help message
@ -89,16 +246,6 @@ abstract class ApiFormatBase extends ApiBase {
$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.
* @return bool
*/
public function getIsHtml() {
return $this->mIsHtml;
}
/**
* Whether this formatter can format the help message in a nice way.
* By default, this returns the same as getIsHtml().
@ -111,149 +258,6 @@ abstract class ApiFormatBase extends ApiBase {
return $this->getIsHtml();
}
/**
* Disable the formatter completely. This causes calls to initPrinter(),
* printText() and closePrinter() to be ignored.
*/
public function disable() {
$this->mDisabled = true;
}
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.
* @since 1.23
* @return bool
*/
public function canPrintErrors() {
return true;
}
/**
* 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 $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' );
// Some printers (ex. Feed) do their own header settings,
// in which case $mime will be set to null
if ( is_null( $mime ) ) {
return; // skip any initialization
}
$this->getMain()->getRequest()->response()->header( "Content-Type: $mime; charset=utf-8" );
//Set X-Frame-Options API results (bug 39180)
$apiFrameOptions = $this->getConfig()->get( 'ApiFrameOptions' );
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
}
// @codingStandardsIgnoreStart Exclude long line from CodeSniffer checks
?>
</head>
<body>
<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
}
}
/**
* Finish printing. Closes HTML tags.
*/
public function closePrinter() {
if ( $this->mDisabled ) {
return;
}
if ( $this->getIsHtml() ) {
?>
</pre>
</body>
</html>
<?php
}
}
/**
* 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'.
* @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;
}
}
/**
* Get the contents of the buffer.
* @return string
*/
public function getBuffer() {
return $this->mBuffer;
}
/**
* Set the flag to buffer the result instead of printing it.
* @param bool $value
*/
public function setBufferResult( $value ) {
$this->mBufferResult = $value;
}
/**
* Sets whether the pretty-printer should format *bold*
* @deprecated since 1.25
@ -267,10 +271,13 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
/**
* 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 <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 ) {
}
/**@}*/
}
/**
* For really cool vim folding this needs to be at the end:
* vim: foldmarker=@{,@} foldmethod=marker
*/

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}
}

View file

@ -36,8 +36,4 @@ class ApiFormatNone extends ApiFormatBase {
public function execute() {
}
public function getDescription() {
return 'Output nothing' . parent::getDescription();
}
}

View file

@ -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();
}
}

View file

@ -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 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->errorFallback->closePrinter();
} else {
parent::closePrinter();
}
}
public function execute() {
$data = $this->getResultData();
if ( isset( $data['error'] ) ) {
$this->mErrorFallback->execute();
$this->errorFallback->execute();
return;
}

View file

@ -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;
}

View file

@ -109,10 +109,6 @@ class ApiFormatWddx extends ApiFormatBase {
}
}
public function getDescription() {
return 'Output data in WDDX format' . parent::getDescription();
}
public function isDeprecated() {
return true;
}

View file

@ -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 <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();
}
}

View file

@ -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;
}

View file

@ -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 );

View file

@ -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();
}

View file

@ -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 &lt;xslt&gt; 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",

View file

@ -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",

View file

@ -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',

View file

@ -0,0 +1,11 @@
h1.firstHeading {
display: none;
}
.api-pretty-header {
font-size: small;
}
.api-pretty-content {
white-space: pre-wrap;
}

View file

@ -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;
}