中间人:从 markdown 引用存储在数据文件中的 URL

Middleman: referencing URL stored in a data file from markdown

为了我的 Middleman-built website I have stored links and other information about all pages in a data file.

data/pages.yaml:

pageA:
  link: /some-long-url-subject-to-change.html
  name: PageA name
  info: Some other related info

然后,在我的 HAML 模板 (source/test.haml) 中,我可以使用 = data.pages.pageA.link.

打印 pageA 的相对路径

现在,我想使用 markdown 语法通过名称 (pageA) 引用该页面。

示例 (source/test.html.haml):

.info
    :markdown
        This is some text with a [manual link](https://google.com) to somewhere. 
        This is another text with a [data-referenced link](pageA) to that page.

与第一个 "manual link" link 到 Google 相同的方式,我希望第二个 link 使用存储在数据文件中的相对路径来创建一个 link。我认为解决此问题的一种解决方案是在 markdown 呈现之前用 = data.pages.pageA.link 的评估替换 (pageA) 文本。

我认为这可以通过创建自定义助手来实现,但我不太确定。


我的解决方案尝试

我尝试编写一个自定义帮助程序,以在由 markdown 呈现之前用 = data.pages.pageA.link 的评估替换 (pageA) 文本。

我能够用数据中的信息替换特定文本 (pageA),我还能够编写更通用的案例,用典型数据引用的显式文本替换所有数据引用。但是我无法在一般情况下替换 data.pages.pageA.link 以评估 = data.pages.pageA.link.

我的帮手:

# Replace specific text with information from ``data/pages.yaml``
specific = text.gsub("pageA",data.pages.pageA.link)
# Generic case: using explicit text
generic = text.gsub(/\]\((.*?)\)/,'](data.pages..link)')
# Generic case: trying to use variable name, but getting explicit text
generic = text.gsub(/\]\((.*?)\)/,'](#{data.pages..link})')

我的助手的用法 test.html.haml:

= myhelper("This is another text with a [data-referenced link](pageA) to that page.")

打印 specific 变量给了我想要的 (/some-long-url-subject-to-change.html)。但是打印 generic 变量结果为纯文本,而不是来自数据文件的信息。

可能是我缺乏一些基本的Ruby知识,解决方法确实很简单。

我不确定你在这里遇到了什么。以下对我有效:

假设您的数据文件data/pages.yaml包含

pageA:
  link: /some-long-url-subject-to-change.html
  name: PageA name
  info: Some other related info

你的模板 test.haml.md.erb 看起来像

---
title: Test
---

This is another text with a [<%= data.pages.pageA.name %>](<%= data.pages.pageA.link %>) to that page.

输出应如下所示,其中 PageA 名称 是可点击的 link。

This is another text with a PageA name to that page.

看来您 运行 对降价解释有疑问。尝试将模板文件名从 test.haml 调整为 test.haml.md.erb

这个结构告诉 Middleman 首先解释 ERB 位,然后是 Markdown 位,最后是 HAML(如果不使用 HAML,则直接 HTML)。

看起来您正在尝试编写自己的模板系统,这可能不是最好的主意。首先,您需要编写一个正则表达式来正确解析 Markdown 并找到 link 符号。然后您需要评估您提取的字符串以从数据中获取值。最后,您需要用该值替换占位符。我或多或少地在 config.rb:

中使用这段代码
helpers do
  def myhelper(text)
    page=/\]\((.*?)\)/.match(text)[1]
    link=eval( "data.pages.#{page}.link" )
    text.gsub(page,link)
  end
end

但请不要使用此代码!它很脆弱且容易出错。更糟糕的是,有一种更简单的方法可以完成您想要做的事情。将 test.haml 替换为 test.haml.erb:

.info
    :markdown
        This is some text with a [manual link](https://google.com) to somewhere. 
        This is another text with a [data-referenced link](<%= data.pages.pageA.link %>) to that page.

= myhelper("This is another text with a [data-referenced link](pageA) to that page.")

.erb 扩展名告诉 Middleman 将该文件视为 ERB template。特别是,它将评估 <%=%> 之间的任何内容作为 Ruby 代码。这意味着您可以跳过使用杂乱的辅助方法。作为奖励,您无需编写更多代码即可获取其他数据位:

  • <%= data.pages.pageA.name %> => 'PageA name'
  • <%= data.pages.pageA.info %> => 'Some other related info'

如果您需要做一些更复杂的处理,例如遍历列表,您可以直接在模板中完成。这样更容易阅读和维护。

作为对比,我还包含了对辅助方法的调用。与仅使用现有的模板系统相比,发生了什么不太清楚。另外,您一定会忘记将所有相关字符串包装在方法中,并最终以损坏的 links 结束。

作为, you might be even better off using Markdown directly and skipping Haml