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

帮助:解析函数/rel2abs

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

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

rel2abs

将相对路径转换为绝对路径。出自扩展 ParserFunctions

语法

{{#rel2abs: 相对路径 }}{{#rel2abs: 相对路径 | 基础路径 }}

  • 相对路径:要转换的路径,支持标准路径语法
  • 基础路径(可选):作为参考的基础路径,默认为当前页面标题

说明

  • 路径语法:
    • . 表示当前路径级别
    • .. 表示上一级路径
    • /foo 表示进入子目录foo

多余的/.会被自动清理。

如果路径尝试访问根目录之上的层级,会返回错误。

函数#iferror可以捕获此函数的错误。

示例

  • {{#rel2abs: /quok | Help:Foo/bar/baz }} → Help:Foo/bar/baz/quok
  • {{#rel2abs: ../quok | Help:Foo/bar/baz }} → Help:Foo/bar/quok
  • {{#rel2abs: ../../quok | Help:Foo/bar/baz }} → Help:Foo/quok
  • {{#rel2abs: ../../../quok | Help:Foo/bar/baz }} → quok
  • {{#rel2abs: ../../../../quok | Help:Foo/bar/baz }}错误:无效路径深度:“Help:Foo/bar/baz/../../../../quok”(尝试访问根节点以上节点)
  • {{#iferror: {{#rel2abs: ../../../../quok | Help:Foo/bar/baz }} | 出错了 | 正常 }} → 出错了

底层代码

来自MediaWiki及其扩展的源代码,运行在服务端。此处仅供快速查阅,便于更充分的挖掘其“特性”。

/** mediawiki-1.37.0\extensions\ParserFunctions\includes\ParserFunctions.php
 * {{#rel2abs: path }} or {{#rel2abs: path | base path }}
 *
 * Returns the absolute path to a subpage, relative to the current article
 * title. Treats titles as slash-separated paths.
 *
 * Following subpage link syntax instead of standard path syntax, an
 * initial slash is treated as a relative path, and vice versa.
 *
 * @link https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##rel2abs
 *
 * @param Parser $parser
 * @param string $to
 * @param string $from
 *
 * @return string
 */
public static function rel2abs( Parser $parser, $to = '', $from = '' ) {
	$from = trim( $from );
	if ( $from === '' ) {
		$from = $parser->getTitle()->getPrefixedText();
	}

	$to = rtrim( $to, ' /' );

	// if we have an empty path, or just one containing a dot
	if ( $to === '' || $to === '.' ) {
		return $from;
	}

	// if the path isn't relative
	if ( substr( $to, 0, 1 ) !== '/' &&
		substr( $to, 0, 2 ) !== './' &&
		substr( $to, 0, 3 ) !== '../' &&
		$to !== '..'
	) {
		$from = '';
	}
	// Make a long path, containing both, enclose it in /.../
	$fullPath = '/' . $from . '/' . $to . '/';

	// remove redundant current path dots
	$fullPath = preg_replace( '!/(\./)+!', '/', $fullPath );

	// remove double slashes
	$fullPath = preg_replace( '!/{2,}!', '/', $fullPath );

	// remove the enclosing slashes now
	$fullPath = trim( $fullPath, '/' );
	$exploded = explode( '/', $fullPath );
	$newExploded = [];

	foreach ( $exploded as $current ) {
		if ( $current === '..' ) { // removing one level
			if ( !count( $newExploded ) ) {
				// attempted to access a node above root node
				$msg = wfMessage( 'pfunc_rel2abs_invalid_depth', $fullPath )
					->inContentLanguage()->escaped();
				return '<strong class="error">' . $msg . '</strong>';
			}
			// remove last level from the stack
			array_pop( $newExploded );
		} else {
			// add the current level to the stack
			$newExploded[] = $current;
		}
	}

	// we can now join it again
	return implode( '/', $newExploded );
}
代码逻辑:
  • 输入处理
    • 如果未提供基础路径($from),则使用当前页面标题作为基础路径
    • 移除相对路径($to)末尾的斜杠和空格
  • 特殊路径处理:空路径或单点路径(.)直接返回基础路径;非相对路径(不以/, ./../开头)时清空基础路径
  • 路径规范化:合并基础路径和相对路径为完整路径。正则替换处理冗余的./和连续斜杠
  • 层级解析:按斜杠分割路径为数组,遍历数组元素:
    • 遇到..时向上跳转一级(弹出数组最后一个元素)
    • 若尝试跳出根目录则返回错误
    • 其他情况保留当前层级
  • 生成结果:将处理后的数组用斜杠重新连接为字符串

实际用例

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