在 YAML 变量中包含 jekyll / 液体模板数据?
Posted
技术标签:
【中文标题】在 YAML 变量中包含 jekyll / 液体模板数据?【英文标题】:Include jekyll / liquid template data in a YAML variable? 【发布时间】:2013-01-07 08:51:09 【问题描述】:我正在使用 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 标头中使用液体标记?
-
如果是,我在显示的示例中做错了什么?
如果不允许,我还能用谁来达到我的目的?我目前正在我的笔记本电脑上开发我的网站,并且不想硬编码基本 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
【问题讨论】:
一个问题可能是您的excerpt
值包含一个冒号(:
)。如果值包含冒号,则应在 YAML 中引用该值。
@mipadi 谢谢你。即使我引用问题仍然存在
【参考方案1】:
今天我遇到了类似的问题。作为一个解决方案,我创建了以下简单的 Jekyll 过滤器插件,它允许在其中扩展嵌套的液体模板(例如 YAML 前端的液体变量):
module Jekyll
module LiquifyFilter
def liquify(input)
Liquid::Template.parse(input).render(@context)
end
end
end
Liquid::Template.register_filter(Jekyll::LiquifyFilter)
可以将过滤器添加到 Jekyll 站点,方法是将它们放在站点根目录的“_plugins”子目录中。上面的代码可以简单的粘贴到 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。
【讨论】:
这很完美,正是我想要的。这个插件应该完全是核心jekyll的一个特性 有没有办法在 github 页面中使用它? @cregox GitHub Pages 不允许使用插件进行构建。 Jekyll 文档中有关于插件的信息提示,“GitHub Pages 由 Jekyll 提供支持。但是,出于安全原因,所有 Pages 站点都是使用--safe
选项禁用自定义插件生成的。不幸的是,这意味着您的插件将无法工作如果你正在部署到 GitHub Pages。你仍然可以使用 GitHub Pages 发布你的站点,但是你需要在本地转换站点并将生成的静态文件推送到你的 GitHub 存储库而不是 Jekyll 源文件。来源:jekyllrb.com/docs/plugins
@cregox 或将 Netlify 与 GitHub 结合使用,netlify.com。
@BrianZ 感谢 netlify 提示!我过去看过它,甚至在那里创建了一个帐户,但由于某种原因在中间放弃了它......如果其他人可能感兴趣,他们会为非商业开源提供免费的专业计划,并且与 jekyll @ 集成非常简单987654324@ - 我今天会尝试设置它。 :)【参考方案2】:
我不相信在 YAML 中嵌套液体变量是可能的。至少,我还没有弄清楚该怎么做。
一种可行的方法是使用Liquid's replace filter。具体来说,定义一个要用于变量替换的字符串(例如!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
一个重要的注意事项是you must explicitly set the site.url 值。 Jekyll 不是免费的。您可以在 _config.yml
文件中设置它:
url: http://alanwsmith.com
或者,在调用 jekyll 时定义它:
jekyll --url http://alanwsmith.com
【讨论】:
+1 感谢 Alan 为您提供详尽且图文并茂的答案。 (我在_config.yml
中设置了site.url
并且应该提到这一点。)我会再等一会儿,看看是否有人有任何其他想法/建议,但如果没有,我会接受这个。干杯。【参考方案3】:
如果您需要从另一个 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!
就像site.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
【讨论】:
以上是关于在 YAML 变量中包含 jekyll / 液体模板数据?的主要内容,如果未能解决你的问题,请参考以下文章
Jekyll 检测以 yaml 前端为页面的 sass 文件