4

是否可以在 Jekyll 模板中包含来自另一个域的 html 文件?如果是这样,语法是什么?

我不是 Ruby 或 Jekyll 开发人员,或多或少是代表另一个人提问,所以如果答案很明显,请原谅我!至少我无法通过一些初步研究找到答案。

本质上,我们试图从另一个域中提取页脚的标记,这就是生产的工作方式,所以我们实际上只是试图在我们的模板可交付成果中模拟它。

干杯

4

3 回答 3

2

You cannot do this within the template itself. However, you could define a custom Liquid tag that scrapes the markup of the remote page, and then put that tag into template. This would be in a file called e.g. 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)

And then in your template:

{% remote_footer http://google.com %}

I threw this together quickly and didn't check if it runs, but hopefully it's enough to work with. Keep in mind that this will run once when the liquid parser runs on the page, and if the remote element changes that will not be reflected until the Jekyll site is rebuilt.

于 2013-02-19T17:05:58.213 回答
2

我只是偶然发现了这个问题,我找不到任何可行的解决方案来解决我拥有的所有用例,所以我编写了自己的插件。

注意这是我写的第一块红宝石。

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

许可麻省理工学院。

于 2015-11-28T03:44:38.043 回答
0

你可以包含Jekyll 的 Liquid 标签插件,它对我有用。

将此添加到您的站点中Gemfile

group :jekyll_plugins do
    gem 'jekyll-remote-include', :github => 'netrics/jekyll-remote-include'
end

在您的帖子中使用标签,如下所示:

{% remote_include https://raw.githubusercontent.com/jekyll/jekyll/master/README.markdown %}

或者

{% capture products %}
{% remote_include http://localhost:8888/products.json %}
{% endcapture %}

...

{{ products }}
于 2021-11-07T18:38:37.267 回答