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

帮助:解析函数/arraymaptemplate

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

Arraymaptemplate是一个解析函数。帮助:解析函数页列出了所有解析函数的说明。

arraymaptemplate

分割字符串,用指定模板逐一输出。出自扩展 Page Forms

具体来说,按分隔符切分字符串,并把每个片段作为参数{{{1}}}传给指定模板,再用“输出分隔符”连接结果。行为类似 #arraymap,但把“格式化逻辑”下放到模板中处理。

当每个元素需要较复杂的渲染(多行结构、带条件判断、包含链接/图标/样式等)时,优先使用本函数,以避免在 #arraymap 中堆叠复杂 wikitext,造成“嵌套地狱”。

语法

{{#arraymaptemplate: 字符串 | 模板名 | 分隔符 | 输出分隔符 }}

参数:

  • 字符串:要拆分的原始文本。
  • 模板名:用于渲染每个片段的模板。片段作为 {{{1}}}(即参数1)传入模板。
  • 分隔符:用来切分字符串(非正则)。留空时改为“逐字符切分”。
  • 输出分隔符(可选):连接各次模板输出的文本,默认为 , (英文逗号+空格)。

示例

比如模板 "ListLine"内容如下:

* {{{1}}}

调用:

{{#arraymaptemplate:托奇、环理、辰纱|ListLine|、|\n}}

效果:

  • 托奇
  • 环理
  • 辰纱


底层代码

/** mediawiki-extensions-PageForms-REL1_37 includes\parserfunctions\PF_ArrayMapTemplate.php
 * '#arraymaptemplate' is called as:
 *
 * {{#arraymaptemplate:value|template|delimiter|new_delimiter}}
 *
 * This function makes the same template call for every section of a
 * delimited string; each such section, as dictated by the 'delimiter'
 * value, is passed as a first parameter to the template specified.
 * Finally, the transformed strings are joined together using the
 * 'new_delimiter' string. Both 'delimiter' and 'new_delimiter'
 * default to commas.
 *
 * Example: to take a semicolon-delimited list, and call a template
 * named 'Beautify' on each element in the list, you could call the
 * following:
 *
 * {{#arraymaptemplate:blue;red;yellow|Beautify|;|;}}
 */

class PFArrayMapTemplate {
	public static function run( Parser $parser, $frame, $args ) {
		// Set variables.
		$value = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';
		$template = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : '';
		$delimiter = isset( $args[2] ) ? trim( $frame->expand( $args[2] ) ) : ',';
		$new_delimiter = isset( $args[3] ) ? trim( $frame->expand( $args[3] ) ) : ', ';
		// Unstrip some.
		if ( method_exists( $parser, 'getStripState' ) ) {
			// MW 1.35+
			$delimiter = $parser->getStripState()->unstripNoWiki( $delimiter );
		} else {
			$delimiter = $parser->mStripState->unstripNoWiki( $delimiter );
		}
		// let '\n' represent newlines
		$delimiter = str_replace( '\n', "\n", $delimiter );
		$new_delimiter = str_replace( '\n', "\n", $new_delimiter );

		if ( $delimiter == '' ) {
			$values_array = preg_split( '/(.)/u', $value, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
		} else {
			$values_array = explode( $delimiter, $value );
		}

		$results_array = [];
		foreach ( $values_array as $old_value ) {
			$old_value = trim( $old_value );
			if ( $old_value == '' ) {
				continue;
			}
			$bracketed_value = $frame->virtualBracketedImplode( '{{', '|', '}}',
				$template, '1=' . $old_value );
			// Special handling if preprocessor class is set to
			// 'Preprocessor_Hash'.
			if ( $bracketed_value instanceof PPNode_Hash_Array ) {
				$bracketed_value = $bracketed_value->value;
			}
			$results_array[] = $parser->replaceVariables(
				implode( '', $bracketed_value ), $frame );
		}
		return implode( $new_delimiter, $results_array );
	}
}

代码逻辑简述:

  • 解析参数,并将分隔符、输出分隔符中的 \n 转为真实换行;对分隔符做 nowiki 反转义(unstripNoWiki)。
  • 拆分字符串。如果分隔符为空就逐字符分割
  • 对每个非空字符串片段,构造 {{模板名|1=片段}} 并展开。
  • new_delimiter 连接展开结果;默认 ,

实际用例

一些Wiki使用了相关特性,如下所示这个静态列表可能在下列页面更改后过时仅供批判性参考