41

我正在使用 Markdown 文件的 YAML 标题将excerpt变量添加到可以在其他地方使用的博客文章中。在其中一个摘录中,我通过 markdown 链接标记引用了之前的一篇博客文章,并且我使用液体模板数据变量{{ site.url }}代替了网站的基本 URL。

所以我有类似的东西(稍微修剪一下)

--- 
title: "Decluttering ordination plots in vegan part 2: orditorp()"
status: publish
layout: post
published: true
tags: 
- tag1
- tag2
excerpt: In the [earlier post in this series]({{ site.url }}/2013/01/12/
decluttering-ordination-plots-in-vegan-part-1-ordilabel/ "Decluttering ordination
plots in vegan part 1: ordilabel()") I looked at the `ordilabel()` function
----

但是,jekyll 和 Maruku md 解析器不喜欢这样,这让我怀疑您不能在 YAML 标头中使用液体标记。

是否可以在 jekyll 处理的页面的 YAML 标头中使用液体标记?

  1. 如果是,我在显示的示例中做错了什么?
  2. 如果不允许,还有谁可以达到我的预期?我目前正在我的笔记本电脑上开发我的网站,并且不想硬编码基本 URL,因为当我准备好部署时它必须更改。

我从 Maruku 得到的错误是:

| Maruku tells you:
+---------------------------------------------------------------------------
| Must quote title
| ---------------------------------------------------------------------------
|  the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-o
| --------------------------------------|-------------------------------------
|                                       +--- Byte 40

| Maruku tells you:
+---------------------------------------------------------------------------
| Unclosed link
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
|                                       +--- Byte 41

| Maruku tells you:
+---------------------------------------------------------------------------
| No closing ): I will not create the link for ["earlier post in this series"]
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
|                                       +--- Byte 41
4

3 回答 3

49

今天我遇到了类似的问题。作为一个解决方案,我创建了以下简单的 Jekyll 过滤器插件,它允许在其中扩展嵌套的液体模板(例如 YAML 前端的液体变量):

module Jekyll
  module LiquifyFilter
    def liquify(input)
      Liquid::Template.parse(input).render(@context)
    end
  end
end

Liquid::Template.register_filter(Jekyll::LiquifyFilter)

通过将过滤器放置在站点根目录的“_plugins”子目录中,可以将过滤器添加到 Jekyll 站点。上面的代码可以简单地粘贴到 yoursite/_plugins/liquify_filter.rb 文件中。

之后,像...这样的模板

---
layout: default
first_name: Harry
last_name: Potter
greetings: Greetings {{ page.first_name }} {{ page.last_name }}!
---
{{ page.greetings | liquify }}

...应该呈现一些输出,例如“问候哈利波特!”。扩展也适用于更深的嵌套结构 - 只要在内部液体输出块上也指定了液化过滤器。像 {{ site.url }} 这样的东西当然也可以。

更新- 看起来现在可以作为 Ruby gem 使用:https ://github.com/gemfarmer/jekyll-liquify 。

于 2013-06-11T14:34:02.593 回答
35

我不相信在 YAML 中嵌套液体变量是可能的。至少,我还没有弄清楚该怎么做。

一种可行的方法是使用Liquid 的替换过滤器。具体来说,定义一个要用于变量替换的字符串(例如!SITE_URL!)。然后,在输出期间使用替换过滤器将其切换为所需的 Jekyll 变量(例如site.url)。这是一个精简的 .md 文件,它在我的 jekyll 0.11 安装中的行为符合预期:

---
layout: post

excerpt: In the [earlier post in this series](!SITE_URL!/2013/01/12/)

---

{{ page.excerpt | replace: '!SITE_URL!', site.url }}

在我的机器上进行测试,正确插入了 URL,然后按预期从 markdown 转换为 HTML 链接。如果您有多个要替换的项目,您可以将多个替换调用串在一起。

---
layout: post

my_name: Alan W. Smith
multi_replace_test: 'Name: !PAGE_MY_NAME! - Site: [!SITE_URL!](!SITE_URL!)'

---

{{ page.multi_replace_test | replace: '!SITE_URL!', site.url | replace: '!PAGE_MY_NAME!', page.my_name }}

一个重要的注意事项是您必须明确设置 site.url值。Jekyll 不是免费的。你可以在你的_config.yml文件中设置它:

url: http://alanwsmith.com

或者,在调用 jekyll 时定义它:

jekyll --url http://alanwsmith.com
于 2013-02-01T16:31:19.173 回答
0

如果您需要替换data/yml另一个data/yml文件中的值,我编写了插件。它不是那么优雅但有效:

我做了一些代码改进。现在它捕获一个字符串中的所有出现并使用嵌套值。

module LiquidReplacer
  class Generator < Jekyll::Generator
    REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/
  
    def replace_str(str)
      out = str
      str.to_s.to_enum(:scan, REGEX).map { 
        m = Regexp.last_match.to_s
        val = m.gsub('!', '').split('.')
        vv = $site_data[val[0]]
        val.delete_at(0)
        val.length.times.with_index do |i|
          if val.nil? || val[i].nil? || vv.nil? ||vv[val[i]].nil?
            puts "ERROR IN BUILDING YAML WITH KEY:\n#{m}"
          else
            vv = vv[val[i]]
          end
        end
        out = out.gsub(m, vv)
      }
      out
    end

    def deeper(in_hash)
      if in_hash.class == Hash || in_hash.class == Array
        _in_hash = in_hash.to_a
        _out_hash = {}
        _in_hash.each do |dd|
          case dd
          when Hash
            _dd = dd.to_a
            _out_hash[_dd[0]] = deeper(_dd[1])
          when Array
            _out_hash[dd[0]] = deeper(dd[1])
          else
            _out_hash = replace_str(dd)
          end
        end
      else
        _out_hash = replace_str(in_hash)
      end
      return _out_hash
    end

    def generate(site)
        $site_data = site.data
        site.data.each do |data|
            site.data[data[0]] = deeper(data[1])
        end
    end
  end
end

将此代码放入site/_plugins/liquid_replacer.rb

yml文件中使用!something.someval!assite.data.something.someval但没有site.data部分。

例子 :

_data/one.yml

foo: foo

_data/two.yml

bar: "!one.foo!bar"

调用{{ site.data.two.bar }}会产生foobar

======= 旧代码 ======

module LiquidReplacer
  class Generator < Jekyll::Generator
    REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/

    def generate(site)
      site.data.each do |d|
        d[1].each_pair do |k,v|
          v.to_s.match(REGEX) do |m|
            val = m[0].gsub('!', '').split('.')
            vv = site.data[val[0]]
            val.delete_at(0)
            val.length.times.with_index do |i|
              vv = vv[val[i]]
            end
            d[1][k] = d[1][k].gsub(m[0], vv)
          end
        end
      end
    end
  end
end
于 2021-02-05T23:43:01.330 回答