You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.7 KiB
77 lines
1.7 KiB
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']
|
|
|
|
# force params to strings
|
|
xpath = xpath.to_s if xpath
|
|
css = css.to_s if css
|
|
|
|
if ! html = @@remote_cache["#{@url}_#{xpath}_#{css}"]
|
|
# fetch remote file
|
|
page = Nokogiri::HTML(open(@url))
|
|
# puts @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}_#{css}"] = 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)
|