本文最后更新于2019年03月22日,共1126字。如有问题或建议,欢迎在文章底部留言参与讨论!

前记:前面写过一篇关于图片懒加载的文章,详见:Typecho实现图片懒加载(lazyload)。文中提到需要对图片标签<img>添加data-orignal属性,当时使用了ob_start()函数的方法对图片在后台进行统一处理,虽然也实现了其目的,但经后续测试,处理的并不彻底,且略显复杂。昨天脑洞大开,想到了另一种批量处理图片<img>标签的方法,即通过typecho的HyperDown在Markdown文本被解析为HTML输出的过程中统一添加data-orignal自定义属性,使图片标签符合<img src="img/loading.gif" data-orignal="xxxx.png"/>这种结构,该方法为typecho原生,经测试可完美实现以上目的且简单、高效。

HyperDown简介

HyperDown为Markdown语法解析器,通过它可以将Markdown格式文本标记语言创建的文章和页面解析为HTML超文本标记语言,使网页浏览器得以加载并显示为网页。

typecho原生支持Markdown排版语法,我们在编辑器发布的文章和页面必须经过HyperDown解析为HTML后才能以网页的形式展现出来。

typecho的解析器文件位于网站根目录下var\HyperDown.php。我们可以借助它的解析过程为对文章和页面中的HTML标签设置统一的属性和格式。

以下示例仅介绍几个我在用的方法,提供一个思路供大家参考!

注:本文以 typecho 1.1(17.10.30) 正式稳定版 为例。

为图片标签<img>添加统一的属性

前面写过一篇关于图片懒加载的文章,详见:Typecho实现图片懒加载(lazyload)。文中提到需要对图片标签<img>添加data-orignal属性,当时使用了ob_start()函数的方法对图片进行后台统一处理,使图片标签符合<img src="img/loading.gif" data-orignal="xxxx.png"/>这种结构。

这里介绍一下使用HyperDown在解析过程中为<img>标签统一添加data-orignal自定义属性。

<img>标签添加data-original自定义属性

HyperDown.php中找到第349行// image,本段代码如下:

// image
$text = preg_replace_callback(
    "/!\[((?:[^\]]|\\\\\]|\\\\\[)*?)\]\(((?:[^\)]|\\\\\)|\\\\\()+?)\)/",
    function ($matches) use ($self) {
        $escaped = htmlspecialchars($self->escapeBracket($matches[1]));
        $url = $self->escapeBracket($matches[2]);
        $url = $self->cleanUrl($url);
        return $self->makeHolder(
            "<img src=\"{$url}\" alt=\"{$escaped}\" title=\"{$escaped}\">"
        );
    },
    $text
);

将本段代码中以下一行:

"<img src=\"{$url}\" alt=\"{$escaped}\" title=\"{$escaped}\">"

修改为:

// 前面src中为占位图片,data-original中为图片真实地址
"<img src=\"https://www.nanlon.cn/usr/uploads/loading.gif\" data-original=\"{$url}\" alt=\"{$escaped}\" title=\"{$escaped}\">"

当然这里也可以统一处理 img 标签的其他属性,比如:

<img>标签设置统一的heightwidth属性

<img>标签的height和width属性,即图像宽度和高度。

以下示例统一设置图像的高为600px、宽为800px,代码如下:

将本段代码中以下一行:

"<img src=\"{$url}\" alt=\"{$escaped}\" title=\"{$escaped}\">"

修改为:

"<img src=\"{$url}\" height=\"600\" width=\"800\" alt=\"{$escaped}\" title=\"{$escaped}\">"

为链接标签<a>添加统一的属性

HyperDown.php中找到第377行// link,本段代码如下:

// link
$text = preg_replace_callback(
    "/\[((?:[^\]]|\\\\\]|\\\\\[)+?)\]\(((?:[^\)]|\\\\\)|\\\\\()+?)\)/",
    function ($matches) use ($self) {
        $escaped = $self->parseInline(
            $self->escapeBracket($matches[1]),  '',  false, false
        );
        $url = $self->escapeBracket($matches[2]);
        $url = $self->cleanUrl($url);
        return $self->makeHolder("<a href=\"{$url}\">{$escaped}</a>");
    },
    $text
);

为链接添加nofollow属性

nofollow是HTML页面中<a>标签的属性值。这个标签的意义是告诉搜索引擎“不要追踪此网页上的链接或不要追踪此特定链接”。

将本段代码中以下一行:

return $self->makeHolder("<a href=\"{$url}\">{$escaped}</a>");

修改为:

return $self->makeHolder("<a href=\"{$url}\" rel=\"nofollow\">{$escaped}</a>");

当然我们可以在这里添加判断只为外链添加nofollow属性,而对网站内链不使用nofollow属性。

将上面示例中的那行代码修改为:

//这里判断是否为站内链接,比如我的为 www.nanlon.cn
if (strstr($url,'//www.nanlon.cn') == false ) {
    return $self->makeHolder("<a href=\"{$url}\" rel=\"nofollow\">{$escaped}</a>");
    } else {
    return $self->makeHolder("<a href=\"{$url}\">{$escaped}</a>");
}

修改链接target属性

target是HTML页面中<a>标签的属性值。<a>标签的target属性规定在何处打开链接文档。

详见:HTML<a>标签的target属性

// 以下示例将链接始终在浏览器新窗口或新标签页打开:

将本段代码中以下一行:

return $self->makeHolder("<a href=\"{$url}\">{$escaped}</a>");

修改为:

return $self->makeHolder("<a href=\"{$url}\" target=\"_blank\">{$escaped}</a>");

当然以上两个属性可以同时添加,即:

//这里判断是否为站内链接,比如我的为 www.nanlon.cn
if (strstr($url,'//www.nanlon.cn') == false ) {
    return $self->makeHolder("<a href=\"{$url}\" target=\"_blank\" rel=\"nofollow\">{$escaped}</a>");
    } else {
    return $self->makeHolder("<a href=\"{$url}\" target=\"_blank\">{$escaped}</a>");
}

禁止将文章或页面中的网址自动解析为超连接

在typecho后台编辑器编辑文章或页面时输入的网址(例如:https://www.nanlon.cn),即使你没有使用[超链接名](https://xxx.com)这种Markdown标准的超链接格式书写,默认也会在解析时自动解析为超链接。

示例:

这是直接写的网址:

https://www.nanlon.cn

这是使用Markdown标准的超链接格式书写的网址:

https://www.nanlon.cn

即:[https://www.nanlon.cn](https://www.nanlon.cn)

在前端显示的是一样的结果,都以超链接的形式被显示出来。

如果不想文章中的网址被自动解析为超链接,可以使用以下方法修改,此方法不会影响以Markdown语法插入的超链接,即:你仍然可以后台编辑器中使用[超链接名](https://xxx.com)这种格式给网址插入超链接。

禁止自动超链接的方法:

HyperDown.php中找到第262行,代码如下:

public function parseInline($text, $whiteList = '', $clearHolders = true, $enableAutoLink = true)

将本行代码中$enableAutoLink的值修改为false

public function parseInline($text, $whiteList = '', $clearHolders = true, $enableAutoLink = false)

后记:以上示例仅展示了其中一部分应用,介绍一下思路,其他方面的应用期待你的发挥!