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

帮助:解析函数/forargs

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

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

forargs

在模板中遍历参数并对每个参数执行指定代码的解析函数。出自扩展 Loops

forargs解析函数允许用户通过指定过滤器、键变量名和值变量名,遍历模板传入的参数,并在每次迭代中执行提供的代码块。

语法

{{#forargs: prefix | key | value | code}}

  • prefix:参数名的前缀。
  • key:变量名,存储参数名,不包括前缀。
  • value:变量名,存储参数值。
  • code:每次循环时被解析的wikitext,支持使用、帮助:解析函数输出参数名和值。

如果前缀非数字,仅处理匹配前缀的命名参数。前缀是数字时,处理所有参数(编号参数和命名参数)中匹配前缀的参数。

前缀为空时,遍历处理所有参数。

示例

在模板:Test中编写如下代码,遍历前缀为a的参数:

<includeonly>{{#forargs:a
 | key
 | value
 | {{#var:key}} = {{#var:value}}<br>
}}
</includeonly><noinclude>
{{Test|a1=1|a2=2|b1=4|b2=5|c1=6|c2=7|8|9}}
</noinclude>

输出为:

1 = 1
2 = 2


在模板:Test中编写如下代码,遍历所有参数:

<includeonly>{{#forargs:| key | value | {{#var:key}} = {{#var:value}}; }}</includeonly><noinclude>
{{Test|a1=1|a2=2|a3=3|b1=4|b2=5|c1=6|c2=7|8|9}}
</noinclude>

输出为:

1 = 8; 2 = 9; a1 = 1; a2 = 2; a3 = 3; b1 = 4; b2 = 5; c1 = 6; c2 = 7;


使用switch跳过或单独处理指定参数:

<includeonly>{{#forargs:| key | value |{{#switch: {{#var:key}}
| a1 = <!-- 跳过a1 -->
| b2 = 单独处理b2; 
| #default = {{#var:key}} = {{#var:value}}; 
}}}}</includeonly><noinclude>
{{Test|a1=1|a2=2|a3=3|b1=4|b2=5|c1=6|c2=7|8|9}}
</noinclude>

输出为:

1 = 8;2 = 9;a2 = 2;a3 = 3;b1 = 4;单独处理b2;c1 = 6;c2 = 7;


注意,forargs的参数key、value会在展开wikitext后才按指定格式输出,这可能会导致非预期行为。

假设模板B的内容是

{{#vardefine:active|233}}

模板A的内容是

{{#vardefine:active|0}}
{{#forargs:| k | v | {{#var:active}} }}

那么,{{A| {{B}} }}的结果会是233


底层代码

/** mediawiki-extensions-Loops-REL1_37\ExtLoops.php
 * #forargs: filter | keyVarName | valVarName | code
 * @param Parser $parser
 * @param PPFrame $frame
 * @param array $args
 * @return string
 */
public static function pfObj_forargs( Parser $parser, PPFrame $frame, array $args ) {
	// The first arg is already expanded, but this is a good habit to have...
	$filter = array_shift( $args );
	$filter = $filter !== null ? trim( $frame->expand( $filter ) ) : '';

	// if prefix contains numbers only or isn't set, get all arguments, otherwise just non-numeric
	$tArgs = ( preg_match( '/^([1-9][0-9]*)?$/', $filter ) > 0 )
			? $frame->getArguments()
			: $frame->getNamedArguments();

	return self::perform_forargs( $parser, $frame, $args, $tArgs, $filter );
}



/** mediawiki-extensions-Loops-REL1_37\ExtLoops.php
    * Generic function handling '#forargs' and '#fornumargs' as one
    * @param Parser $parser
    * @param PPFrame $frame
    * @param array $funcArgs
    * @param array $templateArgs
    * @param string $prefix
    * @return string
    */
protected static function perform_forargs(
        Parser $parser,
        PPFrame $frame,
        array $funcArgs,
        array $templateArgs,
        $prefix = ''
) {
    // if not called within template instance:
    if ( !( $frame->isTemplate() ) ) {
        return '';
    }

    // name of the variable to store the argument name:
    $keyVar  = array_shift( $funcArgs );
    $keyVar  = $keyVar !== null ? trim( $frame->expand( $keyVar ) ) : '';
    // name of the variable to store the argument value:
    $valVar  = array_shift( $funcArgs );
    $valVar  = $valVar !== null ? trim( $frame->expand( $valVar ) ) : '';
    // unexpanded code:
    $rawCode = array_shift( $funcArgs );
    $rawCode = $rawCode !== null ? $rawCode : '';

    $output = '';

    // if prefix contains numbers only or isn't set, get all arguments, otherwise just non-numeric
    $tArgs = preg_match( '/^([1-9][0-9]*)?$/', $prefix ) > 0
            ? $frame->getArguments() : $frame->getNamedArguments();

    foreach ( $templateArgs as $argName => $argVal ) {
        // if no filter or prefix in argument name:
        if ( $prefix !== '' && strpos( $argName, $prefix ) !== 0 ) {
            continue;
        }
        if ( $keyVar !== $valVar ) {
            // variable with the argument name without prefix as value:
            self::setVariable( $parser, $keyVar, substr( $argName, strlen( $prefix ) ) );
        }
        // variable with the arguments value:
        self::setVariable( $parser, $valVar, $argVal );

        // expand current run:
        $output .= trim( $frame->expand( $rawCode ) );
    }

    return $output;
}
代码逻辑:
  • 检查是否在模板实例中调用,如果不是则返回空字符串。
  • 提取并处理参数。
  • 根据前缀决定处理哪些参数。
  • 循环遍历符合条件的参数,设置变量的值,并执行code代码块,将结果拼接起来返回。

实际用例

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

坎特伯雷公主与骑士唤醒冠军之剑的奇幻冒险 - gt

黑神话:悟空 - wukong

WIKI实验室 - tools

卡拉彼丘 - klbq

白荆回廊 - bjhl

女神转生 - persona

重返未来:1999 - reverse1999

偶像大师灰姑娘女孩 - imascg

奇迹暖暖 - qjnn

戴森球计划 - dsp

怪物弹珠 - gwdz

魔法使的约定 - mahoyaku

灵魂潮汐 - lhcx

气球塔防6 - btd6

腐蚀 - rust

星引擎 - starengine

四叶草剧场 - clover

美妙世界 - twewy