mediawiki-extensions-Templa.../includes/TemplateDataHtmlFormatter.php
Thiemo Kreuz 8497d85a2d Fix CSS styling of the HTML rendering broken since 2016
Some time ago there was a little bit of custom CSS applied to the HTML
table rendering. This is broken since patch I74214ea from 2016. This
patch renamed all CSS classes but forgot to update the PHP code
accordingly.

I decided to not change the HTML rendering because these class names
might already be used in custom per-wiki or per-user CSS. Instead I
partly revert I74214ea.

Unfortunately, some of the styles are quite dramatic, don't look good
or just don't work. I decided to remove some. The argument is that
the HTML rendering looks the same for 6 years now. I don't see a good
reason to change it now.

In detail:
* Suggested values are not aliases and should not be rendered in
  gray.
* The message "no description" is rendered in gray and italics. But
  this was applied to the wrong DOM element and made everything else
  gray and italic as well.
* The color #777 is not readable, violating WCAG rules. While it's ok
  to dim aliases and such, it must be at least #555 or darker.
* The "nowrap" destroys the table the moment one of the parameters
  does have a longer name or alias. Let the browser handle this, as
  it did for 6 years now.
* Same for rendering aliases as individual, indented blocks. This
  makes the table unnecessarily big when there are many aliases, and
  just doesn't look right. Again, let's stick to what we had for
  6 years.

Change-Id: Idfa76eed6e2d68474c79d4674efce091cb031b66
2022-08-08 11:56:16 +02:00

245 lines
7.3 KiB
PHP

<?php
namespace MediaWiki\Extension\TemplateData;
use Html;
use MessageLocalizer;
use stdClass;
class TemplateDataHtmlFormatter {
/** @var MessageLocalizer */
private $localizer;
/** @var string */
private $languageCode;
/**
* @param MessageLocalizer $localizer
* @param string $languageCode
*/
public function __construct( MessageLocalizer $localizer, string $languageCode = 'en' ) {
$this->localizer = $localizer;
$this->languageCode = $languageCode;
}
/**
* @param TemplateDataBlob $templateData
*
* @return string HTML
*/
public function getHtml( TemplateDataBlob $templateData ): string {
$data = $templateData->getDataInLanguage( $this->languageCode );
$icon = null;
$formatMsg = null;
if ( isset( $data->format ) && is_string( $data->format ) ) {
$format = $data->format;
'@phan-var string $format';
if ( isset( TemplateDataValidator::PREDEFINED_FORMATS[$format] ) ) {
// The following icon names are used here:
// * template-format-block
// * template-format-inline
$icon = 'template-format-' . $format;
// Messages that can be used here:
// * templatedata-doc-format-block
// * templatedata-doc-format-inline
$formatMsg = $this->localizer->msg( 'templatedata-doc-format-' . $format );
}
if ( !$formatMsg || $formatMsg->isDisabled() ) {
$icon = 'settings';
$formatMsg = $this->localizer->msg( 'templatedata-doc-format-custom' );
}
}
$sorting = count( (array)$data->params ) > 1 ? " sortable" : "";
$html = '<header>'
. Html::element( 'p',
[
'class' => [
'mw-templatedata-doc-desc',
'mw-templatedata-doc-muted' => $data->description === null,
]
],
$data->description ??
$this->localizer->msg( 'templatedata-doc-desc-empty' )->text()
)
. '</header>'
. '<table class="wikitable mw-templatedata-doc-params' . $sorting . '">'
. Html::rawElement( 'caption', [],
Html::element( 'p', [],
$this->localizer->msg( 'templatedata-doc-params' )->text()
)
. ( $formatMsg ?
Html::rawElement( 'p', [],
new \OOUI\IconWidget( [ 'icon' => $icon ] )
. Html::element(
'span',
[ 'class' => 'mw-templatedata-format' ],
$formatMsg->text()
)
) :
''
)
)
. '<thead><tr>'
. Html::element( 'th', [ 'colspan' => 2 ],
$this->localizer->msg( 'templatedata-doc-param-name' )->text()
)
. Html::element( 'th', [],
$this->localizer->msg( 'templatedata-doc-param-desc' )->text()
)
. Html::element( 'th', [],
$this->localizer->msg( 'templatedata-doc-param-type' )->text()
)
. Html::element( 'th', [],
$this->localizer->msg( 'templatedata-doc-param-status' )->text()
)
. '</tr></thead>'
. '<tbody>';
$paramNames = $data->paramOrder ?? array_keys( (array)$data->params );
if ( !$paramNames ) {
// Display no parameters message
$html .= '<tr>'
. Html::element( 'td',
[
'class' => 'mw-templatedata-doc-muted',
'colspan' => 7
],
$this->localizer->msg( 'templatedata-doc-no-params-set' )->text()
)
. '</tr>';
}
foreach ( $paramNames as $paramName ) {
$html .= $this->formatParameterTableRow( $paramName, $data->params->$paramName );
}
$html .= '</tbody></table>';
return Html::rawElement( 'section', [ 'class' => 'mw-templatedata-doc-wrap' ], $html );
}
/**
* @param int|string $paramName
* @param stdClass $param
*
* @return string HTML
*/
private function formatParameterTableRow( $paramName, stdClass $param ): string {
'@phan-var object $param';
$allParamNames = [ Html::element( 'code', [], $paramName ) ];
foreach ( $param->aliases as $alias ) {
$allParamNames[] = Html::element( 'code', [ 'class' => 'mw-templatedata-doc-param-alias' ],
$alias
);
}
$suggestedValues = [];
foreach ( $param->suggestedvalues as $suggestedValue ) {
$suggestedValues[] = Html::element( 'code', [], $suggestedValue );
}
if ( $param->deprecated ) {
$status = 'deprecated';
} elseif ( $param->required ) {
$status = 'required';
} elseif ( $param->suggested ) {
$status = 'suggested';
} else {
$status = 'optional';
}
return '<tr>'
// Label
. Html::element( 'th', [], $param->label ?? $paramName )
// Parameters and aliases
. Html::rawElement( 'td', [ 'class' => 'mw-templatedata-doc-param-name' ],
implode( $this->localizer->msg( 'word-separator' )->escaped(), $allParamNames )
)
// Description
. Html::rawElement( 'td', [],
Html::element( 'p',
[
'class' => $param->description ? null : 'mw-templatedata-doc-muted',
],
$param->description ??
$this->localizer->msg( 'templatedata-doc-param-desc-empty' )->text()
)
. Html::rawElement( 'dl', [],
// Suggested Values
( $suggestedValues ? ( Html::element( 'dt', [],
$this->localizer->msg( 'templatedata-doc-param-suggestedvalues' )->text()
)
. Html::rawElement( 'dd', [],
implode( $this->localizer->msg( 'word-separator' )->escaped(), $suggestedValues )
) ) : '' ) .
// Default
( $param->default !== null ? ( Html::element( 'dt', [],
$this->localizer->msg( 'templatedata-doc-param-default' )->text()
)
. Html::element( 'dd', [],
$param->default
) ) : '' )
// Example
. ( $param->example !== null ? ( Html::element( 'dt', [],
$this->localizer->msg( 'templatedata-doc-param-example' )->text()
)
. Html::element( 'dd', [],
$param->example
) ) : '' )
// Auto value
. ( $param->autovalue !== null ? ( Html::element( 'dt', [],
$this->localizer->msg( 'templatedata-doc-param-autovalue' )->text()
)
. Html::rawElement( 'dd', [],
Html::element( 'code', [], $param->autovalue )
) ) : '' )
)
)
// Type
. Html::element( 'td',
[
'class' => [
'mw-templatedata-doc-param-type',
'mw-templatedata-doc-muted' => $param->type === 'unknown'
]
],
// Known messages, for grepping:
// templatedata-doc-param-type-boolean, templatedata-doc-param-type-content,
// templatedata-doc-param-type-date, templatedata-doc-param-type-line,
// templatedata-doc-param-type-number, templatedata-doc-param-type-string,
// templatedata-doc-param-type-unbalanced-wikitext, templatedata-doc-param-type-unknown,
// templatedata-doc-param-type-url, templatedata-doc-param-type-wiki-file-name,
// templatedata-doc-param-type-wiki-page-name, templatedata-doc-param-type-wiki-template-name,
// templatedata-doc-param-type-wiki-user-name
$this->localizer->msg( 'templatedata-doc-param-type-' . $param->type )->text()
)
// Status
. Html::element( 'td',
[
// CSS class names that can be used here:
// mw-templatedata-doc-param-status-deprecated
// mw-templatedata-doc-param-status-optional
// mw-templatedata-doc-param-status-required
// mw-templatedata-doc-param-status-suggested
'class' => "mw-templatedata-doc-param-status-$status",
'data-sort-value' => [
'deprecated' => -1,
'suggested' => 1,
'required' => 2,
][$status] ?? 0,
],
// Messages that can be used here:
// templatedata-doc-param-status-deprecated
// templatedata-doc-param-status-optional
// templatedata-doc-param-status-required
// templatedata-doc-param-status-suggested
$this->localizer->msg( "templatedata-doc-param-status-$status" )->text()
)
. '</tr>';
}
}