【问题标题】:Including external files in a Jekyll template在 Jekyll 模板中包含外部文件
【发布时间】:2021-11-08 02:38:37
【问题描述】:

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

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

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

干杯

【问题讨论】:

    标签: ruby jekyll jekyll-extensions


    【解决方案1】:

    您不能在模板本身内执行此操作。但是,您可以定义一个自定义 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 站点重建之前不会反映出来。

    【讨论】:

    • 我花了一些时间来解决这个问题,但我收到一个错误 Liquid error: bad URI(is not URI?): myurl.com
    • myurl.com 不是 URI; URI 必须包含一个方案,例如file:// 或 http:// 或 ftp://,例如http://myurl.com
    • 嗨,品牌,感谢您的更新,我的伪代码不正确,但这正是我要说的。 {% remote_footer localhost:8080/cm/header.jsp %} 带有消息“液体错误:错误的 URI(不是 URI?):localhost:8080/cm/header.jsp
    • 哦..我认为stackoverflow正在剥离http位!我可以确认我正在添加这些。
    • 远程调试有点困难,但它是否适用于像 google.com 这样的已知可访问网站?您也可以尝试将 URI 用引号括起来
    【解决方案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

    许可证 MIT。

    【讨论】:

      【解决方案3】:

      你可以加入Liquid tag plugin for Jekyll,它对我有用。

      将此添加到您网站的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 }}
      

      【讨论】:

        猜你喜欢
        • 2020-05-23
        • 1970-01-01
        • 2018-10-26
        • 1970-01-01
        • 2016-03-13
        • 2016-05-05
        • 1970-01-01
        • 2021-09-17
        相关资源
        最近更新 更多