是否可以在Jekyll模板中包含来自其他域的html文件?如果是这样,语法是什么?
我不是Ruby或Jekyll开发人员,或多或少代表另一个人请求,如果答案显而易见,请原谅我!至少我在初步研究中找不到答案。
本质上我们试图从另一个域中提取页脚的标记,这就是生产将如何工作所以我们实际上只是试图在我们的模板交付中模拟它。
干杯
答案 0 :(得分:2)
您无法在模板内执行此操作。但是,您可以定义一个自定义Liquid标签,用于擦除远程页面的标记,然后将该标记放入模板中。这将在一个名为例如plugins/remote_footer.rb
require 'nokogiri'
require 'open-uri'
require 'uri'
module Jekyll
class RemoteFooterTag < Liquid::Tag
def initialize(tag_name, markup, tokens)
#markup is what is defined in the tag. Lets make it a URL so devs
#don't have to update code if the URL changes.
url = markup
#check if the URL is valid
if url =~ URI::regexp
#grab the remote document with nokogiri
doc = Nokogiri::HTML(open(url))
#search the document for the HTML element you want
@node = doc.at_xpath("//div[@id='footer']")
else
raise 'Invalid URL passed to RemoteFooterTag'
end
super
end
def render(context)
output = super
if @node
node.to_s
else
"Something went wrong in RemoteFooterTag"
end
end
end
end
Liquid::Template.register_tag('remote_footer', Jekyll::RemoteFooterTag)
然后在你的模板中:
{% remote_footer http://google.com %}
我把它快速地扔在一起,并没有检查它是否运行,但希望它足以与之合作。请记住,当液体分析器在页面上运行时,这将运行一次,如果远程元素发生更改,则在重建Jekyll站点之前不会反映该内容。
答案 1 :(得分:2)
我只是偶然发现了这个问题,我找不到任何解决我所有用例的工作解决方案,所以我编写了自己的插件。
N.B。这是我写过的第一首红宝石。
require 'nokogiri'
require 'open-uri'
require 'uri'
class Jekyll::IncludeRemoteTag < Jekyll::Tags::IncludeTag
@@remote_cache = {}
def initialize(tag_name, markup, tokens)
super
@url = @file
end
def validate_url(url)
if url !~ URI::regexp
raise ArgumentError.new <<-eos
Invalid syntax for include_remote tag. URL contains invalid characters or sequences:
#{url}
Valid syntax:
#{syntax_example}
eos
end
end
def syntax_example
"{% #{@tag_name} http://domain.ltd css=\".menu\" xpath=\"//div[@class='.menu']\" param=\"value\" param2=\"value\" %}"
end
def render(context)
@url = render_variable(context) || @url
validate_url(@url)
if @params
validate_params
@params = parse_params(context)
end
xpath = @params['xpath']
css = @params['css']
if ! html = @@remote_cache["#{@url}_#{xpath}"]
# fetch remote file
page = Nokogiri::HTML(open(@url))
# parse extract xpath/css fragments if necessary
node = page.at_xpath(xpath) if xpath
node = page.css(css) if css
node = page if !node
raise IOError.new "Error while parsing remote file '#{@url}': '#{xpath||css}' not found" if !node
# cache result
html = @@remote_cache["#{@url}_#{xpath}"] = node.to_s
end
begin
partial = Liquid::Template.parse(html)
context.stack do
context['include'] = @params
partial.render!(context)
end
rescue => e
raise Jekyll::Tags::IncludeTagError.new e.message, @url
end
end
end
Liquid::Template.register_tag('include_remote', Jekyll::IncludeRemoteTag)
你会像这样使用它:
<!-- fetch header.html -->
{% assign url = 'http://mything.me/_includes/header.html' %}
{% include_remote {{ url }} %}
<!-- fetch menu.html and extract div.menu -->
{% include_remote 'http://mything.me/_includes/menu.html' css="div.menu" links=site.data.menu %}
<!-- fetch menu.html and extract div.menu (xpath version) -->
{% include_remote 'http://mything.me/_includes/menu.html' xpath="div[@class='menu']" links=site.data.menu %}
它基本上与普通的包含文件完全相同,但它是远程的。
可从此处下载:https://gist.github.com/kilianc/a6d87879735d4a68b34f
MIT许可证。