自定義 STL 标簽

STL 标簽是(shì) XYCMS 模闆解析并生成靜态頁面的(de)核心,通過添加自定義 STL 标簽,我們将可以(yǐ)實現自己的(de)專屬标簽,方便模闆調用。

我們以(yǐ) XYCMS 二維碼顯示插件 (opens new window)作爲(wéi / wèi)示例來(lái)說(shuō)明如何實現自定義标簽。

二維碼插件使用 stl:qrCode 标簽生成二維碼,可以(yǐ)設置url 屬性指定二維碼地(dì / de)址,size 屬性指定二維碼圖片尺寸,标簽使用代碼如下:

<stl:qrCode url="https://xycms.com" size="128"></stl:qrCode>
1

爲(wéi / wèi)了(le/liǎo)實現自定義 STL 标簽,我們需要(yào / yāo)繼承 IPluginParseAsync 接口并實現 ParseAsync 方法,此方法的(de)返回值爲(wéi / wèi)字符串,此字符串即自定義标簽解析後的(de)值。

我們以(yǐ) XYCMS 二維碼顯示插件 (opens new window)的(de) StlQRCode (opens new window)類作爲(wéi / wèi)示例說(shuō)明如何自定義 STL 标簽:

using System.Threading.Tasks;
using XYCMS.Parse;
using XYCMS.Plugins;
using XYCMS.Repositories;
using XYCMS.Services;
using XYCMS.Utils;

namespace XYCMS.QRCode
{
    public class StlQRCode : IPluginParseAsync
    {
        private const string AttributeUrl = "url";
        private const string AttributeSize = "size";

        private readonly IPathManager _pathManager;
        private readonly ISiteRepository _siteRepository;

        public StlQRCode(IPathManager pathManager, ISiteRepository siteRepository)
        {
            _pathManager = pathManager;
            _siteRepository = siteRepository;
        }

        public string ElementName => "stl:qrcode";

        public async Task<string> ParseAsync(IParseStlContext context)
        {
            var url = string.Empty;
            var size = 0;

            foreach (var name in context.StlAttributes.AllKeys)
            {
                var value = context.StlAttributes[name];

                if (StringUtils.EqualsIgnoreCase(name, AttributeUrl))
                {
                    url = await context.ParseAsync(value);
                }
                else if (StringUtils.EqualsIgnoreCase(name, AttributeSize))
                {
                    size = TranslateUtils.ToInt(value);
                }
            }

            url = string.IsNullOrEmpty(url) ? "location.href" : quot;'{url}'";

            var guid = StringUtils.Guid();
            var site = await _siteRepository.GetAsync(context.SiteId);
            var libUrl = _pathManager.GetApiHostUrl(site, "/assets/qrcode/qrcode.min.js");

            return size == 0
                ? $@"
<div class=""qrcode"" id=""{guid}""></div>
<script type=""text/javascript"" src=""{libUrl}""></script>
<script type=""text/javascript"">
new QRCode(document.getElementById('{guid}'), {url});
</script>
"
                : $@"
<div class=""qrcode"" id=""{guid}""></div>
<script type=""text/javascript"" src=""{libUrl}""></script>
<script type=""text/javascript"">
new QRCode(document.getElementById('{guid}'), {{
    text: {url},
	width: {size},
	height: {size}
}});
</script>
";
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

首先,我們在(zài)類的(de)構造函數中注入了(le/liǎo)需要(yào / yāo)使用的(de)接口,接下來(lái)我們通過實現 ElementName 屬性定義了(le/liǎo)自定義 STL 标簽的(de)名稱 stl:qrcode。

在(zài) ParseAsync 方法中,我們通過方法傳遞的(de)參數 IParseStlContext context 獲取了(le/liǎo)标簽所處環境的(de)上(shàng)下文,IParseStlContext 接口能夠獲得當前站點、欄目以(yǐ)及内容的(de)信息,同時(shí)還能獲取标簽的(de)屬性、嵌套的(de)内部标簽等信息。

最後,我們組合各類信息,返回字符串,最終 stl:qrcode 标簽解析的(de)結果将是(shì)我們在(zài)此方法中返回的(de)字符串值。