2013-02-19 4 views
3

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

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

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

Cheers

ответ

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 не будет восстановлен.

+0

Мне потребовалось несколько человек, чтобы обойти это, но я получаю сообщение об ошибке Ошибка жидкости: неправильный URI (не URI?): Myurl.com – Chris

+0

myurl.com не является URI; URI должны включать в себя схему, например. file: // или http: // или ftp: //, например. 'http: // myurl.com' – bwest

+0

Привет, спасибо, за обновление, мое псевдо было неверно, но вот именно то, что я делаю. {% remote_footer http: // localhost: 8080/cm/header.jsp%} с сообщением «Ошибка жидкости: неправильный URI (не URI?): http: // localhost: 8080/cm/header.jsp ' – Chris

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.