按指定格式输出数组内容
{{#arrayprint: 数组名 | 分隔符 | 占位符 | 输出格式 | 选项 }}
相关函数
相关资源
arrayprint
按指定格式输出数组内容。出自扩展 Arrays BWIKI和各大Wiki平台广泛使用此扩展。<br>在遥远的未来,它可能与Mediawiki新的并行解析器不兼容,请参阅扩展主页了解更多信息。。
比如将数组 boss(包含 red, orange, blue)中的每个元素使用Boss模板渲染输出。
通常用于将计算后的数组转换为可视化内容,如生成导航列表、批量创建链接或调用模板等场景。
语法
{{#arrayprint: 数组名 | 分隔符 | 占位符 | 输出格式 | 选项 }}
参数
- 数组名
- 要输出的数组名称(需先通过
arraydefine 等函数定义)
- 分隔符
- 用于分隔多个数组元素的字符串
- 默认为
、(Wiki 界面语言的顿号,BWiki 为中文)
- 支持 HTML 标签,如
<br/>
- 占位符
- 在"输出格式"中标记数组元素的插入位置
- 常用
@、@@@ 等字符串
- 输出格式
- 定义单个数组元素的输出方式(一段 wikitext)
- 必须包含占位符,支持嵌入模板、解析函数、Wiki 链接等
- 选项
- 额外的输出选项,支持:
print=pretty:将最后一个分隔符替换为 和(自然语言列表)
效果
- 输出:按指定格式将数组元素拼接为字符串并输出
- 效果:支持占位符替换、Wikitext 展开(模板、解析函数等),可生成复杂的格式化内容
示例
先定义数组:{{#arraydefine:b|red, orange, blue}}
| 代码 |
效果
|
{{#arrayprint:b}}
|
red、orange、blue
|
{{#arrayprint:b | }}
|
redorangeblue
|
{{#arrayprint:b |<br/> }}
|
red orange blue
|
{{#arrayprint:b | <br/> | @ | @的长度:{{#len:@}} }}
|
red的长度:3 orange的长度:6 blue的长度:4
|
{{#arrayprint:b | <br/> | @ | {{Color| @ | @ }} }}
|
red orange blue
|
{{#arrayprint:b | , | @ | @ |print=pretty}}
|
red,orange和blue
|
使用场景
用于批量格式化输出数组,数组数据可以来源多样,经多次运算得到。
场景 1:批量生成链接
从分类页面或 SMW 查询结果中提取页面名,生成导航列表:
{{#arraydefine:pages|页面A,页面B,页面C}}
{{#arrayprint:pages | 、 | @ | [[@]] }}
场景 2:调用模板渲染内容
将数组元素传递给模板,批量生成卡片、标签等:
{{#arraydefine:tags|火系,水系,土系}}
{{#arrayprint:tags | <br/> | @ | {{属性图标|@}} }}
场景 3:自然语言列表
使用 print=pretty 选项生成符合语言习惯的列表:
{{#arraydefine:items|苹果,香蕉,橙子}}
你购买了:{{#arrayprint:items | 、 | @ | @ | print=pretty}}
输出:"你购买了:苹果、香蕉和橙子"
场景 4:复杂格式组合
结合解析函数创建表格行(当然这是糟糕的写法):
{{#arraydefine:data|10,20,30}}
{| class="wikitable"
{{#arrayprint:data | | @ |<nowiki/>
{{!}}-
{{!}} @ {{!}}{{!}} {{#expr:@ * 2}}
}}
|}
底层代码
/** mediawiki-extensions-Arrays-REL1_37 ExtArrays.php
* print an array.
* foreach element of the array, print 'subject' where all occurrences of 'search' is replaced with the element,
* and each element print-out is deliminated by 'delimiter'
* The subject can embed parser functions; wiki links; and templates.
* usage:
* {{#arrayprint:arrayid|delimiter|search|subject|options}}
* examples:
* {{#arrayprint:b}} -- simple
* {{#arrayprint:b|<br/>}} -- add change line
* {{#arrayprint:b|<br/>|@@@|[[@@@]]}} -- embed wiki links
* {{#arrayprint:b|<br/>|@@@|{{#set:prop=@@@}} }} -- embed parser function
* {{#arrayprint:b|<br/>|@@@|{{f.tag{{f.print.vbar}}prop{{f.print.vbar}}@@@}} }} -- embed template function
* {{#arrayprint:b|<br/>|@@@|[[name::@@@]]}} -- make SMW links
*/
public static function pfObj_arrayprint( Parser &$parser, PPFrame $frame, $args ) {
global $egArraysCompatibilityMode, $egArraysExpansionEscapeTemplates;
// Get Parameters
$arrayId = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';
$delimiter = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : self::$mDefaultSep;
/*
* PPFrame::NO_ARGS and PPFrame::NO_TEMPLATES for expansion make a lot of sense here since the patterns getting replaced
* in $subject before $subject is being parsed. So any template or argument influence in the patterns wouldn't make any
* sense in any sane scenario.
*/
$search = isset( $args[2] ) ? trim( $frame->expand( $args[2], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : null;
$subject = isset( $args[3] ) ? trim( $frame->expand( $args[3], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : null;
// options array:
$options = isset( $args[4] )
? self::parse_options( $frame->expand( $args[4] ) )
: [];
// get array, null if non-existant:
$array = self::get( $parser )->getArray( $arrayId );
if ( $array === null ) {
// array we want to print doesn't exist!
if ( !$egArraysCompatibilityMode ) {
return '';
} else {
// COMPATIBILITY-MODE
return "undefined array: $arrayId";
}
}
// if there is no subject, there is no point in expanding. Faster!
if ( $subject === null ) {
if ( !$egArraysCompatibilityMode && $egArraysExpansionEscapeTemplates !== null ) {
// we can ignore options here, since if subject is null, options won't be set as well!
return trim( implode( $delimiter, $array ) );
} else {
// COMPATIBILITY-MODE
// set search and subject so the old routine can be done
$search = $subject = '@@@@';
}
}
$rendered_values = [];
foreach ( $array as $val ) {
if ( !$egArraysCompatibilityMode ) {
// NO COMPATIBILITY-MODE
/**
* escape the array value so it won't destroy the users wiki markup expression.
*/
$val = self::escapeForExpansion( $val );
}
// replace place holder with current value:
$rawResult = str_replace( $search, $val, $subject );
/*
* $subjectd still is un-expanded (this allows to use some parser functions like
* {{FULLPAGENAME:@@@@}} directly without getting parsed before @@@@ is replaced.
* Expand it so we replace templates like {{!}} which we need for the final parse.
*/
$rawResult = $parser->preprocessToDom( $rawResult, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
$rawResult = trim( $frame->expand( $rawResult ) );
$rendered_values[] = $rawResult;
}
// follow special print options:
switch ( self::array_value( $options, 'print' ) ) {
case 'pretty':
// pretty list print with ' and ' connecting the last two items
if ( $delimiter === '' ) {
// '' as delimiter isn't pretty, so in this case we take the (languages) default
$output = self::arrayToText( $rendered_values );
} else {
$output = self::arrayToText( $rendered_values, $delimiter );
}
break;
default:
// normal print with one delimiter, might be the languages default
$output = implode( $delimiter, $rendered_values );
break;
}
if ( $egArraysCompatibilityMode || $egArraysExpansionEscapeTemplates === null ) {
// COMPATIBILITY-MODE:
/*
* don't leave the final parse to Parser::braceSubstitution() since there are some special cases where it
* would produce unexpected output (it uses a new child frame and ignores whether the frame is a template!)
*/
$output = $parser->preprocessToDom( $output, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
$output = $frame->expand( $output );
}
return trim( $output );
}
处理流程:
- 参数解析:提取数组名、分隔符、占位符、输出格式和选项。获取指定数组,若不存在则根据兼容模式返回空或错误信息
- 简化处理:若未指定输出格式,直接用分隔符拼接数组元素
- 元素遍历:对每个数组元素执行占位符替换
- 转义处理:对数组值进行转义,防止破坏 Wiki 标记
- Wikitext 展开:预处理并展开模板、解析函数等
- 格式化输出:根据选项(如
print=pretty)选择拼接方式
- 返回结果:输出处理后的字符串
MediaWiki:WikiparserHighlight.Test.js
MediaWiki:WikiparserHighlight.css