Включение внешних файлов в шаблон Jekyll

Можно ли включить html-файл из другого домена в шаблон Jekyll? И если да, то какой будет синтаксис?

Я не разработчик Ruby или Jekyll, более или менее спрашиваю от имени другого, поэтому, пожалуйста, простите меня, если ответ очевиден! По крайней мере, я не мог найти ответ с некоторыми первоначальными исследованиями.

По сути, мы пытаемся извлечь разметку нижнего колонтитула из другого домена, именно так будет работать производство, поэтому мы на самом деле просто пытаемся смоделировать его в результатах нашего шаблона.

Ваше здоровье


person Chris    schedule 19.02.2013    source источник


Ответы (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 не будет перестроен.

person bwest    schedule 19.02.2013
comment
Мне потребовалось несколько времени, чтобы обойти это, но я получаю сообщение об ошибке Ошибка жидкости: неверный URI (не URI?): myurl.com - person Chris; 01.03.2013
comment
myurl.com не является URI; URI должны включать схему, например. file:// или http:// или ftp://, например http://myurl.com - person bwest; 02.03.2013
comment
Привет, Бренд, спасибо за обновление, мой псевдоним был неверным, но вот именно то, что я помещаю. {% remote_footer localhost:8080/cm/header.jsp %} с сообщением "Жидкая ошибка : неверный URI (это не URI?): localhost:8080/cm/header.jsp ' - person Chris; 06.03.2013
comment
О.. Я думаю, что stackoverflow удаляет бит http! Я могу подтвердить, что добавляю их. - person Chris; 08.03.2013
comment
Это немного сложно отладить удаленно, но работает ли это с известным доступным веб-сайтом, таким как google.com? Вы также можете попробовать заключить URI в кавычки. - person bwest; 15.03.2013
comment
Привет, Бренд, если вы не против взглянуть на экран (dl. dropbox.com/u/140080/so/screen.jpg), я скопировал ваш фрагмент кода и попытался применить его. Я пробовал Google и некоторые другие домены. Я пробовал без кавычек, одиночных и двойных. При заключении кавычек я получаю сообщение об ошибке «файл/каталог не найден» на веб-странице. Если я попробую абсолютный путь, он просто попадет в строку 22. Еще раз спасибо, все, что вы можете придумать, приветствуется. - person Chris; 18.03.2013

Я только что столкнулся с этой проблемой и не смог найти никакого рабочего решения, учитывающего все варианты использования, которые у меня были, поэтому я написал свой собственный плагин.

Н.Б. Это первая часть рубина, которую я написал.

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

Лицензия МИТ.

person kilianc    schedule 28.11.2015