Tools 是非官方社区Wiki。社区文档正在编写中,欢迎参与。 Wiki编辑答疑群:717421103
版本250923.2
全站通知:

帮助:解析函数/arrayprint

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索
arrayprint 悬浮框🟢稳定可用
按指定格式输出数组内容
{{#arrayprint: 数组名 | 分隔符 | 占位符 | 输出格式 | 选项 }}
扩展:Arrays
数组
变量
相关函数
相关资源

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

处理流程

  1. 参数解析:提取数组名、分隔符、占位符、输出格式和选项。获取指定数组,若不存在则根据兼容模式返回空或错误信息
  2. 简化处理:若未指定输出格式,直接用分隔符拼接数组元素
  3. 元素遍历:对每个数组元素执行占位符替换
  4. 转义处理:对数组值进行转义,防止破坏 Wiki 标记
  5. Wikitext 展开:预处理并展开模板、解析函数等
  6. 格式化输出:根据选项(如 print=pretty)选择拼接方式
  7. 返回结果:输出处理后的字符串