consume liquid tag

did committed Feb 02, 2015
commit 182fecbc9144a0da9132f05063f40b9d2d4ead1a
Showing 31 changed files with 1118 additions and 901 deletions
locomotive/steam.rb b/lib/locomotive/steam.rb +1 -0
@@ @@ -2,6 +2,7 @@
# require 'locomotive/decorators'
require 'locomotive/common'
+ require_relative 'steam/core_ext'
require_relative 'steam/exceptions'
require_relative 'steam/decorators'
require_relative 'steam/configuration'
locomotive/steam/liquid.rb b/lib/locomotive/steam/liquid.rb +3 -3
@@ @@ -5,10 +5,10 @@ require 'solid'
require_relative 'liquid/errors'
require_relative 'liquid/patches'
require_relative 'liquid/drops/base'
- # require_relative 'liquid/tags/hybrid'
- # require_relative 'liquid/tags/path_helper'
+ require_relative 'liquid/tags/hybrid'
+ require_relative 'liquid/tags/path_helper'
# %w{. drops tags filters}.each do |dir|
- %w{. filters}.each do |dir|
+ %w{. filters tags}.each do |dir|
Dir[File.join(File.dirname(__FILE__), 'liquid', dir, '*.rb')].each { |lib| require lib }
end
locomotive/steam/liquid/tags/consume.rb b/lib/locomotive/steam/liquid/tags/consume.rb +86 -76
@@ @@ -1,104 +1,114 @@
module Locomotive
- module Liquid
+ module Steam
+ module Liquid
module Tags
- # Consume web services as easy as pie directly in liquid !
- #
- # Usage:
- #
- # {% consume blog from 'http://nocoffee.tumblr.com/api/read.json?num=3' username: 'john', password: 'easy', format: 'json', expires_in: 3000 %}
- # {% for post in blog.posts %}
- # {{ post.title }}
- # {% endfor %}
- # {% endconsume %}
- #
- class Consume < ::Liquid::Block
-
- Syntax = /(#{::Liquid::VariableSignature}+)\s*from\s*(#{::Liquid::QuotedString}|#{::Liquid::VariableSignature}+)(.*)?/
-
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @target = $1
-
- self.prepare_url($2)
- self.prepare_api_arguments($3)
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
- end
+ # Consume web services as easy as pie directly in liquid !
+ #
+ # Usage:
+ #
+ # {% consume blog from 'http://nocoffee.tumblr.com/api/read.json?num=3' username: 'john', password: 'easy', format: 'json', expires_in: 3000 %}
+ # {% for post in blog.posts %}
+ # {{ post.title }}
+ # {% endfor %}
+ # {% endconsume %}
+ #
+ class Consume < ::Liquid::Block
+
+ Syntax = /(#{::Liquid::VariableSignature}+)\s*from\s*(#{::Liquid::QuotedString}|#{::Liquid::VariableSignature}+)(.*)?/
+
+ def initialize(tag_name, markup, options)
+ if markup =~ Syntax
+ @target = $1
+
+ self.prepare_url($2)
+ self.prepare_api_arguments($3)
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
+ end
- @local_cache_key = self.hash
+ @local_cache_key = self.hash
- super
- end
+ super
+ end
- def render(context)
- self.set_api_options(context)
+ def render(context)
+ self.set_api_options(context)
- if instance_variable_defined? :@variable_name
- @url = context[@variable_name]
- end
+ if instance_variable_defined? :@variable_name
+ @url = context[@variable_name]
+ end
- render_all_and_cache_it(context)
- end
+ render_all_and_cache_it(context)
+ end
- protected
+ protected
- def prepare_url(token)
- if token.match(::Liquid::QuotedString)
- @url = token.gsub(/['"]/, '')
- elsif token.match(::Liquid::VariableSignature)
- @variable_name = token
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
+ def prepare_url(token)
+ if token.match(::Liquid::QuotedString)
+ @url = token.gsub(/['"]/, '')
+ elsif token.match(::Liquid::VariableSignature)
+ @variable_name = token
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'consume' - Valid syntax: consume <var> from \"<url>\" [username: value, password: value]")
+ end
end
- end
- def prepare_api_arguments(string)
- string = string.gsub(/^(\s*,)/, '').strip
- @api_arguments = Solid::Arguments.parse(string)
- end
+ def prepare_api_arguments(string)
+ string = string.gsub(/^(\s*,)/, '').strip
+ @api_arguments = Solid::Arguments.parse(string)
+ end
- def set_api_options(context)
- @api_options = @api_arguments ? @api_arguments.interpolate(context).first || {} : {}
- @expires_in = @api_options.delete(:expires_in) || 0
- end
+ def set_api_options(context)
+ @api_options = @api_arguments ? @api_arguments.interpolate(context).first || {} : {}
+ @expires_in = @api_options.delete(:expires_in) || 0
+ end
- def page_fragment_cache_key(url)
- Digest::SHA1.hexdigest(@target.to_s + url)
- end
+ def page_fragment_cache_key(url)
+ Digest::SHA1.hexdigest(@target.to_s + url)
+ end
- def cached_response
- @@local_cache ||= {}
- @@local_cache[@local_cache_key]
- end
+ def cached_response
+ @@local_cache ||= {}
+ @@local_cache[@local_cache_key]
+ end
- def cached_response=(response)
- @@local_cache ||= {}
- @@local_cache[@local_cache_key] = response
- end
+ def cached_response=(response)
+ @@local_cache ||= {}
+ @@local_cache[@local_cache_key] = response
+ end
- def render_all_and_cache_it(context)
- Rails.cache.fetch(page_fragment_cache_key(@url), expires_in: @expires_in, force: @expires_in == 0) do
- self.render_all_without_cache(context)
+ def render_all_and_cache_it(context)
+ cache_service(context).fetch(page_fragment_cache_key(@url), expires_in: @expires_in, force: @expires_in == 0) do
+ self.render_all_without_cache(context)
+ end
end
- end
- def render_all_without_cache(context)
- context.stack do
- begin
- context.scopes.last[@target.to_s] = Locomotive::Httparty::Webservice.consume(@url, @api_options)
- self.cached_response = context.scopes.last[@target.to_s]
- rescue Timeout::Error
- context.scopes.last[@target.to_s] = self.cached_response
+ def render_all_without_cache(context)
+ context.stack do
+ begin
+ context.scopes.last[@target.to_s] = service(context).consume(@url, @api_options)
+ self.cached_response = context.scopes.last[@target.to_s]
+ rescue Timeout::Error
+ context.scopes.last[@target.to_s] = self.cached_response
+ end
+
+ @body.render(context)
end
+ end
- render_all(@nodelist, context)
+ def service(context)
+ context.registers[:services].external_api
end
+
+ def cache_service(context)
+ context.registers[:services].cache
+ end
+
end
+ ::Liquid::Template.register_tag('consume', Consume)
end
-
- ::Liquid::Template.register_tag('consume', Consume)
end
end
end
locomotive/steam/liquid/tags/csrf.rb b/lib/locomotive/steam/liquid/tags/csrf.rb +26 -24
@@ @@ -1,40 +1,42 @@
module Locomotive
- module Liquid
- module Tags
- module Csrf
+ module Steam
+ module Liquid
+ module Tags
+ module Csrf
- class Param < ::Liquid::Tag
+ class Param < ::Liquid::Tag
- def render(context)
- controller = context.registers[:controller]
- name = controller.send(:request_forgery_protection_token).to_s
- value = controller.send(:form_authenticity_token)
+ def render(context)
+ controller = context.registers[:controller]
+ name = controller.send(:request_forgery_protection_token).to_s
+ value = controller.send(:form_authenticity_token)
+
+ %(<input type="hidden" name="#{name}" value="#{value}">)
+ end
- %(<input type="hidden" name="#{name}" value="#{value}">)
end
- end
+ class Meta < ::Liquid::Tag
- class Meta < ::Liquid::Tag
+ def render(context)
+ controller = context.registers[:controller]
+ name = controller.send(:request_forgery_protection_token).to_s
+ value = controller.send(:form_authenticity_token)
- def render(context)
- controller = context.registers[:controller]
- name = controller.send(:request_forgery_protection_token).to_s
- value = controller.send(:form_authenticity_token)
+ %{
+ <meta name="csrf-param" content="#{name}">
+ <meta name="csrf-token" content="#{value}">
+ }
+ end
- %{
- <meta name="csrf-param" content="#{name}">
- <meta name="csrf-token" content="#{value}">
- }
end
end
- end
-
- ::Liquid::Template.register_tag('csrf_param', Csrf::Param)
- ::Liquid::Template.register_tag('csrf_meta', Csrf::Meta)
+ ::Liquid::Template.register_tag('csrf_param', Csrf::Param)
+ ::Liquid::Template.register_tag('csrf_meta', Csrf::Meta)
+ end
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/editable.rb b/lib/locomotive/steam/liquid/tags/editable.rb +4 -4
@@ @@ -1,4 +1,4 @@
- require 'locomotive/liquid/tags/editable/base'
- require 'locomotive/liquid/tags/editable/text'
- require 'locomotive/liquid/tags/editable/file'
- require 'locomotive/liquid/tags/editable/control'
\ No newline at end of file
+ # require 'locomotive/liquid/tags/editable/base'
+ # require 'locomotive/liquid/tags/editable/text'
+ # require 'locomotive/liquid/tags/editable/file'
+ # require 'locomotive/liquid/tags/editable/control'
locomotive/steam/liquid/tags/extends.rb b/lib/locomotive/steam/liquid/tags/extends.rb +31 -29
@@ @@ -1,47 +1,49 @@
module Locomotive
- module Liquid
- module Tags
- class Extends < ::Liquid::Extends
+ module Steam
+ module Liquid
+ module Tags
+ class Extends < ::Liquid::Extends
- def prepare_parsing
- super
+ def prepare_parsing
+ super
- parent_page = @context[:parent_page]
+ parent_page = @context[:parent_page]
- @context[:page].merge_editable_elements_from_page(parent_page)
+ @context[:page].merge_editable_elements_from_page(parent_page)
- @context[:snippets] = parent_page.snippet_dependencies
- @context[:templates] = ([*parent_page.template_dependencies] + [parent_page.id]).compact
- end
+ @context[:snippets] = parent_page.snippet_dependencies
+ @context[:templates] = ([*parent_page.template_dependencies] + [parent_page.id]).compact
+ end
- private
+ private
- def parse_parent_template
- if @template_name == 'parent'
- @context[:parent_page] = @context[:cached_parent] || @context[:page].parent
- else
- locale = ::Mongoid::Fields::I18n.locale
+ def parse_parent_template
+ if @template_name == 'parent'
+ @context[:parent_page] = @context[:cached_parent] || @context[:page].parent
+ else
+ locale = ::Mongoid::Fields::I18n.locale
- @context[:parent_page] = @context[:cached_pages].try(:[], @template_name) ||
- @context[:site].pages.where("fullpath.#{locale}" => @template_name).first
- end
+ @context[:parent_page] = @context[:cached_pages].try(:[], @template_name) ||
+ @context[:site].pages.where("fullpath.#{locale}" => @template_name).first
+ end
- raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil?
+ raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil?
- # be sure to work with a copy of the parent template otherwise there will be conflicts
- parent_template = @context[:parent_page].template.try(:clone)
+ # be sure to work with a copy of the parent template otherwise there will be conflicts
+ parent_template = @context[:parent_page].template.try(:clone)
- raise PageNotTranslated.new("Page with fullpath '#{@template_name}' was not translated") if parent_template.nil?
+ raise PageNotTranslated.new("Page with fullpath '#{@template_name}' was not translated") if parent_template.nil?
- # force the page to restore the original version of its template (from the serialized version)
- @context[:parent_page].instance_variable_set(:@template, nil)
+ # force the page to restore the original version of its template (from the serialized version)
+ @context[:parent_page].instance_variable_set(:@template, nil)
+
+ parent_template
+ end
- parent_template
end
+ ::Liquid::Template.register_tag('extends', Extends)
end
-
- ::Liquid::Template.register_tag('extends', Extends)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/fetch_page.rb b/lib/locomotive/steam/liquid/tags/fetch_page.rb +27 -25
@@ @@ -1,36 +1,38 @@
module Locomotive
- module Liquid
- module Tags
+ module Steam
+ module Liquid
+ module Tags
- # Fetch a page from its handle and assign it to a liquid variable.
- #
- # Usage:
- #
- # {% fetch_page 'about_us' as a_page %}
- # <p>{{ a_page.title }}</p>
- #
- class FetchPage < ::Liquid::Tag
+ # Fetch a page from its handle and assign it to a liquid variable.
+ #
+ # Usage:
+ #
+ # {% fetch_page 'about_us' as a_page %}
+ # <p>{{ a_page.title }}</p>
+ #
+ class FetchPage < ::Liquid::Tag
- Syntax = /(#{::Liquid::VariableSignature}+)\s+as\s+(#{::Liquid::VariableSignature}+)/
+ Syntax = /(#{::Liquid::VariableSignature}+)\s+as\s+(#{::Liquid::VariableSignature}+)/
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @handle = $1
- @var = $2
- else
- raise SyntaxError.new("Syntax Error in 'fetch_page' - Valid syntax: fetch_page page_handle as variable")
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @handle = $1
+ @var = $2
+ else
+ raise SyntaxError.new("Syntax Error in 'fetch_page' - Valid syntax: fetch_page page_handle as variable")
+ end
+
+ super
end
- super
+ def render(context)
+ context.scopes.last[@var] = context.registers[:site].pages.where(handle: @handle).first
+ ''
+ end
end
- def render(context)
- context.scopes.last[@var] = context.registers[:site].pages.where(handle: @handle).first
- ''
- end
+ ::Liquid::Template.register_tag('fetch_page', FetchPage)
end
-
- ::Liquid::Template.register_tag('fetch_page', FetchPage)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/google_analytics.rb b/lib/locomotive/steam/liquid/tags/google_analytics.rb +28 -26
@@ @@ -1,39 +1,41 @@
module Liquid
- module Locomotive
- module Tags
- class GoogleAnalytics < ::Liquid::Tag
+ module Steam
+ module Locomotive
+ module Tags
+ class GoogleAnalytics < ::Liquid::Tag
- Syntax = /(#{::Liquid::Expression}+)?/
+ Syntax = /(#{::Liquid::Expression}+)?/
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @account_id = $1.gsub('\'', '')
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'google_analytics' - Valid syntax: google_analytics <account_id>")
- end
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @account_id = $1.gsub('\'', '')
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'google_analytics' - Valid syntax: google_analytics <account_id>")
+ end
- super
- end
+ super
+ end
- def render(context)
- %{
- <script type="text/javascript">
+ def render(context)
+ %{
+ <script type="text/javascript">
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', '#{@account_id}']);
- _gaq.push(['_trackPageview']);
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', '#{@account_id}']);
+ _gaq.push(['_trackPageview']);
- (function() \{
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
- \})();
+ (function() \{
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ \})();
- </script>}
+ </script>}
+ end
end
- end
- ::Liquid::Template.register_tag('google_analytics', GoogleAnalytics)
+ ::Liquid::Template.register_tag('google_analytics', GoogleAnalytics)
+ end
end
end
end
locomotive/steam/liquid/tags/hybrid.rb b/lib/locomotive/steam/liquid/tags/hybrid.rb +23 -17
@@ @@ -1,25 +1,31 @@
module Locomotive
- module Liquid
- module Tags
- class Hybrid < ::Liquid::Block
- def parse(tokens)
- nesting = 0
- tokens.each do |token|
- next unless token =~ IsTag
- if token =~ FullToken
- if nesting == 0 && $1 == block_delimiter
- @render_as_block = true
- super
- return
- elsif $1 == block_name
- nesting += 1
- elsif $1 == block_delimiter
- nesting -= 1
+ module Steam
+ module Liquid
+ module Tags
+
+ class Hybrid < ::Liquid::Block
+
+ def parse(tokens)
+ nesting = 0
+ tokens.each do |token|
+ next unless token =~ IsTag
+ if token =~ FullToken
+ if nesting == 0 && $1 == block_delimiter
+ @render_as_block = true
+ super
+ return
+ elsif $1 == block_name
+ nesting += 1
+ elsif $1 == block_delimiter
+ nesting -= 1
+ end
end
end
end
+
end
+
end
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/inherited_block.rb b/lib/locomotive/steam/liquid/tags/inherited_block.rb +20 -18
@@ @@ -1,31 +1,33 @@
module Locomotive
- module Liquid
- module Tags
- class InheritedBlock < ::Liquid::InheritedBlock
+ module Steam
+ module Liquid
+ module Tags
+ class InheritedBlock < ::Liquid::InheritedBlock
- def end_tag
- super
+ def end_tag
+ super
- if !self.contains_super?(@nodelist) # then disable all editable_elements coming from the parent block too and not used
- @context[:page].disable_parent_editable_elements(@name) unless @context[:page].nil?
+ if !self.contains_super?(@nodelist) # then disable all editable_elements coming from the parent block too and not used
+ @context[:page].disable_parent_editable_elements(@name) unless @context[:page].nil?
+ end
end
- end
- protected
+ protected
- def contains_super?(nodelist)
- nodelist.any? do |node|
- if node.is_a?(::Liquid::Variable) && node.name == 'block.super'
- true
- elsif node.respond_to?(:nodelist) && !node.nodelist.nil? && !node.is_a?(Locomotive::Liquid::Tags::InheritedBlock)
- contains_super?(node.nodelist)
+ def contains_super?(nodelist)
+ nodelist.any? do |node|
+ if node.is_a?(::Liquid::Variable) && node.name == 'block.super'
+ true
+ elsif node.respond_to?(:nodelist) && !node.nodelist.nil? && !node.is_a?(Locomotive::Liquid::Tags::InheritedBlock)
+ contains_super?(node.nodelist)
+ end
end
end
+
end
+ ::Liquid::Template.register_tag('block', InheritedBlock)
end
-
- ::Liquid::Template.register_tag('block', InheritedBlock)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/inline_editor.rb b/lib/locomotive/steam/liquid/tags/inline_editor.rb +0 -40
@@ @@ -1,40 +0,0 @@
- module Liquid
- module Locomotive
- module Tags
- class InlineEditor < ::Liquid::Tag
-
- def render(context)
- if context.registers[:current_locomotive_account] && context.registers[:inline_editor]
-
- plugins = 'common/ui,common/format,common/table,common/list,common/link,common/highlighteditables,common/block,common/undo,common/contenthandler,common/paste,common/commands,common/abbr,common/align,common/horizontalruler,common/image,custom/locomotive_media,custom/inputcontrol'
-
- controller = context.registers[:controller]
- controller.instance_variable_set(:@plugins, plugins)
-
- page = context.registers[:page].to_presenter.as_json_for_html_view
- page['lang'] = context['locale']
-
- html = <<-HTML
- %meta{ content: true, name: 'inline-editor' }
-
- = stylesheet_link_tag 'aloha/css/aloha.css'
- = javascript_include_tag 'locomotive/aloha', :'data-aloha-plugins' => @plugins
-
- %script{ type: 'text/javascript' }
- :plain
- Aloha.ready(function() \{
- window.parent.application_view.set_page(#{controller.view_context.escape_json page.to_json.html_safe});
- \});
- HTML
-
- Haml::Engine.new(html.gsub(/\n+/, "\n").gsub(/^\s{14}/, ''), escape_html: true).render(controller.view_context)
- else
- ''
- end
- end
- end
-
- ::Liquid::Template.register_tag('inline_editor', InlineEditor)
- end
- end
- end
\ No newline at end of file
locomotive/steam/liquid/tags/javascript.rb b/lib/locomotive/steam/liquid/tags/javascript.rb +16 -11
@@ @@ -1,16 +1,21 @@
module Locomotive
- module Liquid
- module Tags
- class Javascript < ::Liquid::Block
-
- include ActionView::Helpers::JavaScriptHelper
- include ActionView::Helpers::TagHelper
-
- def render(context)
- javascript_tag super
+ module Steam
+ module Liquid
+ module Tags
+ class Javascript < ::Liquid::Block
+
+ # TODO
+ # include ActionView::Helpers::JavaScriptHelper
+ # include ActionView::Helpers::TagHelper
+
+ def render(context)
+ javascript_tag super
+ end
end
+
+ ::Liquid::Template.register_tag('javascript', Javascript)
+
end
- ::Liquid::Template.register_tag('javascript', Javascript)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/link_to.rb b/lib/locomotive/steam/liquid/tags/link_to.rb +28 -26
@@ @@ -1,43 +1,45 @@
module Locomotive
- module Liquid
- module Tags
- class LinkTo < Hybrid
+ module Steam
+ module Liquid
+ module Tags
+ class LinkTo < Hybrid
- include PathHelper
- include ActionView::Helpers::UrlHelper
+ include PathHelper
+ # include ActionView::Helpers::UrlHelper
- def render(context)
- render_path(context) do |page, path|
- label = label_from_page(page)
+ def render(context)
+ render_path(context) do |page, path|
+ label = label_from_page(page)
- if @render_as_block
- context.scopes.last['target'] = page
- label = super.html_safe
- end
+ if @render_as_block
+ context.scopes.last['target'] = page
+ label = super.html_safe
+ end
- link_to label, path
+ link_to label, path
+ end
end
- end
- def wrong_syntax!
- raise SyntaxError.new("Syntax Error in 'link_to' - Valid syntax: link_to page_handle, locale es (locale is optional)")
- end
+ def wrong_syntax!
+ raise SyntaxError.new("Syntax Error in 'link_to' - Valid syntax: link_to page_handle, locale es (locale is optional)")
+ end
- protected
+ protected
- def label_from_page(page)
- ::Mongoid::Fields::I18n.with_locale(@options['locale']) do
- if page.templatized?
- page.content_entry._label
- else
- page.title
+ def label_from_page(page)
+ ::Mongoid::Fields::I18n.with_locale(@options['locale']) do
+ if page.templatized?
+ page.content_entry._label
+ else
+ page.title
+ end
end
end
+
end
+ ::Liquid::Template.register_tag('link_to', LinkTo)
end
-
- ::Liquid::Template.register_tag('link_to', LinkTo)
end
end
end
locomotive/steam/liquid/tags/locale_switcher.rb b/lib/locomotive/steam/liquid/tags/locale_switcher.rb +67 -65
@@ @@ -1,83 +1,85 @@
module Locomotive
- module Liquid
- module Tags
- # Display the links to change the locale of the current page
- #
- # Usage:
- #
- # {% locale_switcher %} => <div id="locale-switcher"><a href="/features" class="current en">Features</a><a href="/fr/fonctionnalites" class="fr">Fonctionnalités</a></div>
- #
- # {% locale_switcher label: locale, sep: ' - ' }
- #
- # options:
- # - label: iso (de, fr, en, ...etc), locale (Deutsch, Français, English, ...etc), title (page title)
- # - sep: piece of html code separating 2 locales
- #
- # notes:
- # - "iso" is the default choice for label
- # - " | " is the default separating code
- #
- class LocaleSwitcher < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::Expression}+)?/
-
- def initialize(tag_name, markup, tokens, context)
- @options = { label: 'iso', sep: ' | ' }
-
- if markup =~ Syntax
- markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
-
- @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'locale_switcher' - Valid syntax: locale_switcher <options>")
+ module Steam
+ module Liquid
+ module Tags
+ # Display the links to change the locale of the current page
+ #
+ # Usage:
+ #
+ # {% locale_switcher %} => <div id="locale-switcher"><a href="/features" class="current en">Features</a><a href="/fr/fonctionnalites" class="fr">Fonctionnalités</a></div>
+ #
+ # {% locale_switcher label: locale, sep: ' - ' }
+ #
+ # options:
+ # - label: iso (de, fr, en, ...etc), locale (Deutsch, Français, English, ...etc), title (page title)
+ # - sep: piece of html code separating 2 locales
+ #
+ # notes:
+ # - "iso" is the default choice for label
+ # - " | " is the default separating code
+ #
+ class LocaleSwitcher < ::Liquid::Tag
+
+ Syntax = /(#{::Liquid::Expression}+)?/
+
+ def initialize(tag_name, markup, tokens, context)
+ @options = { label: 'iso', sep: ' | ' }
+
+ if markup =~ Syntax
+ markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
+
+ @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'locale_switcher' - Valid syntax: locale_switcher <options>")
+ end
+
+ super
end
- super
- end
+ def render(context)
+ @site, @page = context.registers[:site], context.registers[:page]
- def render(context)
- @site, @page = context.registers[:site], context.registers[:page]
+ output = %(<div id="locale-switcher">)
- output = %(<div id="locale-switcher">)
+ output += @site.locales.collect do |locale|
+ ::Mongoid::Fields::I18n.with_locale(locale) do
+ fullpath = @site.localized_page_fullpath(@page, locale)
- output += @site.locales.collect do |locale|
- ::Mongoid::Fields::I18n.with_locale(locale) do
- fullpath = @site.localized_page_fullpath(@page, locale)
+ if @page.templatized?
+ fullpath.gsub!('content_type_template', context['entry']._permalink)
+ end
- if @page.templatized?
- fullpath.gsub!('content_type_template', context['entry']._permalink)
- end
+ css = link_class(locale, context['locale'])
- css = link_class(locale, context['locale'])
-
- %(<a href="/#{fullpath}" class="#{css}">#{link_label(locale)}</a>)
- end
- end.join(@options[:sep])
+ %(<a href="/#{fullpath}" class="#{css}">#{link_label(locale)}</a>)
+ end
+ end.join(@options[:sep])
- output += %(</div>)
- end
+ output += %(</div>)
+ end
- private
+ private
- def link_class(locale, current_locale)
- css = [locale]
- css << 'current' if locale == current_locale
- css.join(' ')
- end
+ def link_class(locale, current_locale)
+ css = [locale]
+ css << 'current' if locale == current_locale
+ css.join(' ')
+ end
- def link_label(locale)
- case @options[:label]
- when 'iso' then locale
- when 'locale' then I18n.t("locomotive.locales.#{locale}")
- when 'title' then @page.title # FIXME: this returns nil if the page has not been translated in the locale
- else
- locale
+ def link_label(locale)
+ case @options[:label]
+ when 'iso' then locale
+ when 'locale' then I18n.t("locomotive.locales.#{locale}")
+ when 'title' then @page.title # FIXME: this returns nil if the page has not been translated in the locale
+ else
+ locale
+ end
end
+
end
+ ::Liquid::Template.register_tag('locale_switcher', LocaleSwitcher)
end
-
- ::Liquid::Template.register_tag('locale_switcher', LocaleSwitcher)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/model_form.rb b/lib/locomotive/steam/liquid/tags/model_form.rb +70 -68
@@ @@ -1,75 +1,77 @@
module Locomotive
- module Liquid
- module Tags
-
- # Display the form html tag with the appropriate hidden fields in order to create
- # a content entry from a public site.
- # It handles callbacks, csrf and target url out of the box.
- #
- # Usage:
- #
- # {% model_form 'newsletter_addresses' %}
- # <input type='text' name='content[email]' />
- # <input type='submit' value='Add' />
- # {% endform_form %}
- #
- # {% model_form 'newsletter_addresses', class: 'a-css-class', success: 'http://www.google.fr', error: '/error' %}...{% endform_form %}
- #
- class ModelForm < Solid::Block
-
- tag_name :model_form
-
- def display(*options, &block)
- name = options.shift
- options = options.shift || {}
-
- form_attributes = { method: 'POST', enctype: 'multipart/form-data' }.merge(options.slice(:id, :class))
-
- html_content_tag :form,
- content_type_html(name) + csrf_html + callbacks_html(options) + yield,
- form_attributes
- end
-
- def content_type_html(name)
- html_tag :input, type: 'hidden', name: 'content_type_slug', value: name
- end
-
- def csrf_html
- name = controller.send(:request_forgery_protection_token).to_s
- value = controller.send(:form_authenticity_token)
-
- html_tag :input, type: 'hidden', name: name, value: value
- end
-
- def callbacks_html(options)
- options.slice(:success, :error).map do |(name, value)|
- html_tag :input, type: 'hidden', name: "#{name}_callback", value: value
- end.join('')
- end
+ module Steam
+ module Liquid
+ module Tags
+
+ # Display the form html tag with the appropriate hidden fields in order to create
+ # a content entry from a public site.
+ # It handles callbacks, csrf and target url out of the box.
+ #
+ # Usage:
+ #
+ # {% model_form 'newsletter_addresses' %}
+ # <input type='text' name='content[email]' />
+ # <input type='submit' value='Add' />
+ # {% endform_form %}
+ #
+ # {% model_form 'newsletter_addresses', class: 'a-css-class', success: 'http://www.google.fr', error: '/error' %}...{% endform_form %}
+ #
+ class ModelForm < Solid::Block
+
+ tag_name :model_form
+
+ def display(*options, &block)
+ name = options.shift
+ options = options.shift || {}
+
+ form_attributes = { method: 'POST', enctype: 'multipart/form-data' }.merge(options.slice(:id, :class))
+
+ html_content_tag :form,
+ content_type_html(name) + csrf_html + callbacks_html(options) + yield,
+ form_attributes
+ end
+
+ def content_type_html(name)
+ html_tag :input, type: 'hidden', name: 'content_type_slug', value: name
+ end
+
+ def csrf_html
+ name = controller.send(:request_forgery_protection_token).to_s
+ value = controller.send(:form_authenticity_token)
+
+ html_tag :input, type: 'hidden', name: name, value: value
+ end
+
+ def callbacks_html(options)
+ options.slice(:success, :error).map do |(name, value)|
+ html_tag :input, type: 'hidden', name: "#{name}_callback", value: value
+ end.join('')
+ end
+
+ private
+
+ def controller
+ current_context.registers[:controller]
+ end
+
+ def html_content_tag(name, content, options = {})
+ "<#{name} #{inline_options(options)}>#{content}</#{name}>"
+ end
+
+ def html_tag(name, options = {})
+ "<#{name} #{inline_options(options)} />"
+ end
+
+ # Write options (Hash) into a string according to the following pattern:
+ # <key1>="<value1>", <key2>="<value2", ...etc
+ def inline_options(options = {})
+ return '' if options.empty?
+ (options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ')
+ end
- private
-
- def controller
- current_context.registers[:controller]
- end
-
- def html_content_tag(name, content, options = {})
- "<#{name} #{inline_options(options)}>#{content}</#{name}>"
- end
-
- def html_tag(name, options = {})
- "<#{name} #{inline_options(options)} />"
- end
-
- # Write options (Hash) into a string according to the following pattern:
- # <key1>="<value1>", <key2>="<value2", ...etc
- def inline_options(options = {})
- return '' if options.empty?
- (options.stringify_keys.to_a.collect { |a, b| "#{a}=\"#{b}\"" }).join(' ')
end
end
-
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/nav.rb b/lib/locomotive/steam/liquid/tags/nav.rb +123 -121
@@ @@ -1,164 +1,166 @@
module Locomotive
- module Liquid
- module Tags
- # Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
- # The html output is based on the ul/li tags.
- #
- # Passing through depth will control how many nested children are output
- #
- # Usage:
- #
- # {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
- #
- # {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }
- #
- class Nav < ::Liquid::Tag
-
- Syntax = /(#{::Liquid::Expression}+)?/
-
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @source = ($1 || 'page').gsub(/"|'/, '')
- @options = { id: 'nav', depth: 1, class: '', active_class: 'on', bootstrap: false }
- markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
-
- @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
-
- @options[:add_attributes] = []
- if @options[:snippet]
- template = @options[:snippet].include?('{') ? @options[:snippet] : context[:site].snippets.where(slug: @options[:snippet] ).try(:first).try(:template)
- unless template.blank?
- @options[:liquid_render] = ::Liquid::Template.parse(template)
- @options[:add_attributes] = ['editable_elements']
+ module Steam
+ module Liquid
+ module Tags
+ # Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
+ # The html output is based on the ul/li tags.
+ #
+ # Passing through depth will control how many nested children are output
+ #
+ # Usage:
+ #
+ # {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
+ #
+ # {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav', class: 'nav', active_class: 'on' }
+ #
+ class Nav < ::Liquid::Tag
+
+ Syntax = /(#{::Liquid::Expression}+)?/
+
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @source = ($1 || 'page').gsub(/"|'/, '')
+ @options = { id: 'nav', depth: 1, class: '', active_class: 'on', bootstrap: false }
+ markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
+
+ @options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
+
+ @options[:add_attributes] = []
+ if @options[:snippet]
+ template = @options[:snippet].include?('{') ? @options[:snippet] : context[:site].snippets.where(slug: @options[:snippet] ).try(:first).try(:template)
+ unless template.blank?
+ @options[:liquid_render] = ::Liquid::Template.parse(template)
+ @options[:add_attributes] = ['editable_elements']
+ end
end
+
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <page|site> <options>")
end
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <page|site> <options>")
+ super
end
- super
- end
+ def render(context)
+ children_output = []
- def render(context)
- children_output = []
+ entries = fetch_entries(context)
- entries = fetch_entries(context)
+ entries.each_with_index do |p, index|
+ css = []
+ css << 'first' if index == 0
+ css << 'last' if index == entries.size - 1
- entries.each_with_index do |p, index|
- css = []
- css << 'first' if index == 0
- css << 'last' if index == entries.size - 1
+ children_output << render_entry_link(context, p, css.join(' '), 1)
+ end
- children_output << render_entry_link(context, p, css.join(' '), 1)
- end
+ output = children_output.join("\n")
- output = children_output.join("\n")
+ if @options[:no_wrapper] != 'true'
+ list_class = !@options[:class].blank? ? %( class="#{@options[:class]}") : ''
+ output = %{<nav id="#{@options[:id]}"#{list_class}><ul>\n#{output}</ul></nav>}
+ end
- if @options[:no_wrapper] != 'true'
- list_class = !@options[:class].blank? ? %( class="#{@options[:class]}") : ''
- output = %{<nav id="#{@options[:id]}"#{list_class}><ul>\n#{output}</ul></nav>}
+ output
end
- output
- end
+ private
- private
+ # Determines root node for the list
+ def fetch_entries(context)
+ @site, @page = context.registers[:site], context.registers[:page]
- # Determines root node for the list
- def fetch_entries(context)
- @site, @page = context.registers[:site], context.registers[:page]
+ children = (case @source
+ when 'site' then @site.pages.root.minimal_attributes(@options[:add_attributes]).first # start from home page
+ when 'parent' then @page.parent || @page
+ when 'page' then @page
+ else
+ @site.pages.fullpath(@source).minimal_attributes(@options[:add_attributes]).first
+ end).children_with_minimal_attributes(@options[:add_attributes]).to_a
- children = (case @source
- when 'site' then @site.pages.root.minimal_attributes(@options[:add_attributes]).first # start from home page
- when 'parent' then @page.parent || @page
- when 'page' then @page
- else
- @site.pages.fullpath(@source).minimal_attributes(@options[:add_attributes]).first
- end).children_with_minimal_attributes(@options[:add_attributes]).to_a
+ children.delete_if { |p| !include_page?(p) }
+ end
- children.delete_if { |p| !include_page?(p) }
- end
+ # Returns a list element, a link to the page and its children
+ def render_entry_link(context, page, css, depth)
+ selected = @page.fullpath =~ /^#{page.fullpath}(\/.*)?$/ ? " #{@options[:active_class]}" : ''
- # Returns a list element, a link to the page and its children
- def render_entry_link(context, page, css, depth)
- selected = @page.fullpath =~ /^#{page.fullpath}(\/.*)?$/ ? " #{@options[:active_class]}" : ''
+ icon = @options[:icon] ? '<span></span>' : ''
+ title = render_title(context, page)
+ label = %{#{icon if @options[:icon] != 'after' }#{title}#{icon if @options[:icon] == 'after' }}
- icon = @options[:icon] ? '<span></span>' : ''
- title = render_title(context, page)
- label = %{#{icon if @options[:icon] != 'after' }#{title}#{icon if @options[:icon] == 'after' }}
+ link_options = caret = ''
+ href = File.join('/', @site.localized_page_fullpath(page))
- link_options = caret = ''
- href = File.join('/', @site.localized_page_fullpath(page))
+ if render_children_for_page?(page, depth) && bootstrap?
+ css += ' dropdown'
+ link_options = %{ class="dropdown-toggle" data-toggle="dropdown"}
+ href = '#'
+ caret = %{ <b class="caret"></b>}
+ end
+
+ output = %{<li id="#{page.slug.to_s.dasherize}-link" class="link#{selected} #{css}">}
+ output << %{<a href="#{href}"#{link_options}>#{label}#{caret}</a>}
+ output << render_entry_children(context, page, depth.succ) if (depth.succ <= @options[:depth].to_i)
+ output << %{</li>}
- if render_children_for_page?(page, depth) && bootstrap?
- css += ' dropdown'
- link_options = %{ class="dropdown-toggle" data-toggle="dropdown"}
- href = '#'
- caret = %{ <b class="caret"></b>}
+ output.strip
end
- output = %{<li id="#{page.slug.to_s.dasherize}-link" class="link#{selected} #{css}">}
- output << %{<a href="#{href}"#{link_options}>#{label}#{caret}</a>}
- output << render_entry_children(context, page, depth.succ) if (depth.succ <= @options[:depth].to_i)
- output << %{</li>}
+ def render_children_for_page?(page, depth)
+ depth.succ <= @options[:depth].to_i && page.children.reject { |c| !include_page?(c) }.any?
+ end
- output.strip
- end
+ # Recursively creates a nested unordered list for the depth specified
+ def render_entry_children(context, page, depth)
+ output = %{}
- def render_children_for_page?(page, depth)
- depth.succ <= @options[:depth].to_i && page.children.reject { |c| !include_page?(c) }.any?
- end
+ children = page.children_with_minimal_attributes(@options[:add_attributes]).reject { |c| !include_page?(c) }
+ if children.present?
+ output = %{<ul id="#{@options[:id]}-#{page.slug.to_s.dasherize}" class="#{bootstrap? ? 'dropdown-menu' : ''}">}
+ children.each do |c, page|
+ css = []
+ css << 'first' if children.first == c
+ css << 'last' if children.last == c
- # Recursively creates a nested unordered list for the depth specified
- def render_entry_children(context, page, depth)
- output = %{}
+ output << render_entry_link(context, c, css.join(' '), depth)
+ end
+ output << %{</ul>}
+ end
- children = page.children_with_minimal_attributes(@options[:add_attributes]).reject { |c| !include_page?(c) }
- if children.present?
- output = %{<ul id="#{@options[:id]}-#{page.slug.to_s.dasherize}" class="#{bootstrap? ? 'dropdown-menu' : ''}">}
- children.each do |c, page|
- css = []
- css << 'first' if children.first == c
- css << 'last' if children.last == c
+ output
+ end
- output << render_entry_link(context, c, css.join(' '), depth)
+ def render_title(context, page)
+ if @options[:liquid_render]
+ context.stack do
+ context['page'] = page
+ @options[:liquid_render].render(context)
+ end
+ else
+ page.title
end
- output << %{</ul>}
end
- output
- end
-
- def render_title(context, page)
- if @options[:liquid_render]
- context.stack do
- context['page'] = page
- @options[:liquid_render].render(context)
+ # Determines whether or not a page should be a part of the menu
+ def include_page?(page)
+ if !page.listed? || page.templatized? || !page.published?
+ false
+ elsif @options[:exclude]
+ (page.fullpath =~ @options[:exclude]).nil?
+ else
+ true
end
- else
- page.title
end
- end
- # Determines whether or not a page should be a part of the menu
- def include_page?(page)
- if !page.listed? || page.templatized? || !page.published?
- false
- elsif @options[:exclude]
- (page.fullpath =~ @options[:exclude]).nil?
- else
- true
+ def bootstrap?
+ @options[:bootstrap] == 'true'
end
- end
- def bootstrap?
- @options[:bootstrap] == 'true'
end
+ ::Liquid::Template.register_tag('nav', Nav)
end
-
- ::Liquid::Template.register_tag('nav', Nav)
end
end
end
locomotive/steam/liquid/tags/paginate.rb b/lib/locomotive/steam/liquid/tags/paginate.rb +90 -91
@@ @@ -1,114 +1,113 @@
module Locomotive
-
- module Liquid
-
+ module Steam
+ module Liquid
module Tags
- # Paginate a collection
- #
- # Usage:
- #
- # {% paginate contents.projects by 5 %}
- # {% for project in paginate.collection %}
- # {{ project.name }}
- # {% endfor %}
- # {% endpaginate %}
- #
-
- class Paginate < ::Liquid::Block
-
- Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
-
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @collection_name = $1
- @per_page = $2.to_i
- @options = { }
- markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/^'/, '').gsub(/'$/, '') }
- @window_size = @options[:window_size] ? @options[:window_size].to_i : 3
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'paginate' - Valid syntax: paginate <collection> by <number>")
- end
+ # Paginate a collection
+ #
+ # Usage:
+ #
+ # {% paginate contents.projects by 5 %}
+ # {% for project in paginate.collection %}
+ # {{ project.name }}
+ # {% endfor %}
+ # {% endpaginate %}
+ #
+
+ class Paginate < ::Liquid::Block
+
+ Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
+
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @collection_name = $1
+ @per_page = $2.to_i
+ @options = { }
+ markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/^'/, '').gsub(/'$/, '') }
+ @window_size = @options[:window_size] ? @options[:window_size].to_i : 3
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'paginate' - Valid syntax: paginate <collection> by <number>")
+ end
- super
- end
+ super
+ end
- def render(context)
- context.stack do
- collection = context[@collection_name]
+ def render(context)
+ context.stack do
+ collection = context[@collection_name]
- raise ::Liquid::ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection.nil?
+ raise ::Liquid::ArgumentError.new("Cannot paginate array '#{@collection_name}'. Not found.") if collection.nil?
- if collection.is_a? Array
- pagination = Kaminari.paginate_array(collection).page(context['current_page']).per(@per_page).to_liquid.stringify_keys
- else
- pagination = collection.send(:paginate, {
- page: context['current_page'],
- per_page: @per_page
- }).to_liquid.stringify_keys
- end
- page_count, current_page = pagination['total_pages'], pagination['current_page']
-
- path = sanitize_path(context['fullpath'])
-
- pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
- pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']
- pagination['parts'] = []
-
- hellip_break = false
-
- if page_count > 1
- 1.upto(page_count) do |page|
- if current_page == page
- pagination['parts'] << no_link(page)
- elsif page == 1
- pagination['parts'] << link(page, page, path)
- elsif page == page_count - 1
- pagination['parts'] << link(page, page, path)
- elsif page <= current_page - window_size or page >= current_page + window_size
- next if hellip_break
- pagination['parts'] << no_link('&hellip;')
- hellip_break = true
- next
- else
- pagination['parts'] << link(page, page, path)
+ if collection.is_a? Array
+ pagination = Kaminari.paginate_array(collection).page(context['current_page']).per(@per_page).to_liquid.stringify_keys
+ else
+ pagination = collection.send(:paginate, {
+ page: context['current_page'],
+ per_page: @per_page
+ }).to_liquid.stringify_keys
+ end
+ page_count, current_page = pagination['total_pages'], pagination['current_page']
+
+ path = sanitize_path(context['fullpath'])
+
+ pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
+ pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']
+ pagination['parts'] = []
+
+ hellip_break = false
+
+ if page_count > 1
+ 1.upto(page_count) do |page|
+ if current_page == page
+ pagination['parts'] << no_link(page)
+ elsif page == 1
+ pagination['parts'] << link(page, page, path)
+ elsif page == page_count - 1
+ pagination['parts'] << link(page, page, path)
+ elsif page <= current_page - window_size or page >= current_page + window_size
+ next if hellip_break
+ pagination['parts'] << no_link('&hellip;')
+ hellip_break = true
+ next
+ else
+ pagination['parts'] << link(page, page, path)
+ end
+
+ hellip_break = false
end
-
- hellip_break = false
end
- end
- context['paginate'] = pagination
+ context['paginate'] = pagination
- render_all(@nodelist, context)
+ render_all(@nodelist, context)
+ end
end
- end
- private
+ private
- def sanitize_path(path)
- _path = path.gsub(/page=[0-9]+&?/, '').gsub(/_pjax=true&?/, '')
- _path = _path.slice(0..-2) if _path.last == '?' || _path.last == '&'
- _path
- end
+ def sanitize_path(path)
+ _path = path.gsub(/page=[0-9]+&?/, '').gsub(/_pjax=true&?/, '')
+ _path = _path.slice(0..-2) if _path.last == '?' || _path.last == '&'
+ _path
+ end
- def window_size
- @window_size
- end
+ def window_size
+ @window_size
+ end
- def no_link(title)
- { 'title' => title, 'is_link' => false, 'hellip_break' => title == '&hellip;' }
- end
+ def no_link(title)
+ { 'title' => title, 'is_link' => false, 'hellip_break' => title == '&hellip;' }
+ end
- def link(title, page, path)
- _path = %(#{path}#{path.include?('?') ? '&' : '?'}page=#{page})
- { 'title' => title, 'url' => _path, 'is_link' => true }
+ def link(title, page, path)
+ _path = %(#{path}#{path.include?('?') ? '&' : '?'}page=#{page})
+ { 'title' => title, 'url' => _path, 'is_link' => true }
+ end
end
+
+ ::Liquid::Template.register_tag('paginate', Paginate)
end
- ::Liquid::Template.register_tag('paginate', Paginate)
end
-
end
-
end
locomotive/steam/liquid/tags/path_helper.rb b/lib/locomotive/steam/liquid/tags/path_helper.rb +58 -56
@@ @@ -1,84 +1,86 @@
module Locomotive
- module Liquid
- module Tags
- module PathHelper
+ module Steam
+ module Liquid
+ module Tags
+ module PathHelper
- Syntax = /(#{::Liquid::Expression}+)(#{::Liquid::TagAttributes}?)/
+ Syntax = /(#{::Liquid::Expression}+)(#{::Liquid::TagAttributes}?)/
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @handle = $1
- @options = {}
- markup.scan(::Liquid::TagAttributes) do |key, value|
- @options[key] = value
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @handle = $1
+ @options = {}
+ markup.scan(::Liquid::TagAttributes) do |key, value|
+ @options[key] = value
+ end
+ else
+ self.wrong_syntax!
end
- else
- self.wrong_syntax!
- end
- super
- end
+ super
+ end
- def render_path(context, &block)
- site = context.registers[:site]
+ def render_path(context, &block)
+ site = context.registers[:site]
- if page = self.retrieve_page_from_handle(site, context)
- path = self.public_page_fullpath(site, page)
+ if page = self.retrieve_page_from_handle(site, context)
+ path = self.public_page_fullpath(site, page)
- if block_given?
- block.call page, path
+ if block_given?
+ block.call page, path
+ else
+ path
+ end
else
- path
+ '' # no page found
end
- else
- '' # no page found
end
- end
- protected
+ protected
- def retrieve_page_from_handle(site, context)
- handle = context[@handle] || @handle
+ def retrieve_page_from_handle(site, context)
+ handle = context[@handle] || @handle
- case handle
- when Locomotive::Page then handle
- when Locomotive::Liquid::Drops::Page then handle.instance_variable_get(:@_source)
- when String then fetch_page(site, handle)
- when Locomotive::ContentEntry then fetch_page(site, handle, true)
- when Locomotive::Liquid::Drops::ContentEntry then fetch_page(site, handle.instance_variable_get(:@_source), true)
- else
- nil
+ case handle
+ when Locomotive::Page then handle
+ when Locomotive::Liquid::Drops::Page then handle.instance_variable_get(:@_source)
+ when String then fetch_page(site, handle)
+ when Locomotive::ContentEntry then fetch_page(site, handle, true)
+ when Locomotive::Liquid::Drops::ContentEntry then fetch_page(site, handle.instance_variable_get(:@_source), true)
+ else
+ nil
+ end
end
- end
- def fetch_page(site, handle, templatized = false)
- ::Mongoid::Fields::I18n.with_locale(self.locale) do
- if templatized
- criteria = site.pages.where(target_klass_name: handle.class.to_s, templatized: true)
- criteria = criteria.where(handle: @options['with']) if @options['with']
- criteria.first.tap do |page|
- page.content_entry = handle if page
+ def fetch_page(site, handle, templatized = false)
+ ::Mongoid::Fields::I18n.with_locale(self.locale) do
+ if templatized
+ criteria = site.pages.where(target_klass_name: handle.class.to_s, templatized: true)
+ criteria = criteria.where(handle: @options['with']) if @options['with']
+ criteria.first.tap do |page|
+ page.content_entry = handle if page
+ end
+ else
+ site.pages.where(handle: handle).first
end
- else
- site.pages.where(handle: handle).first
end
end
- end
- def public_page_fullpath(site, page)
- fullpath = site.localized_page_fullpath(page, self.locale)
+ def public_page_fullpath(site, page)
+ fullpath = site.localized_page_fullpath(page, self.locale)
+
+ if page.templatized?
+ fullpath.gsub!('content_type_template', page.content_entry._slug)
+ end
- if page.templatized?
- fullpath.gsub!('content_type_template', page.content_entry._slug)
+ File.join('/', fullpath)
end
- File.join('/', fullpath)
- end
+ def locale
+ @options['locale'] || I18n.locale
+ end
- def locale
- @options['locale'] || I18n.locale
end
-
end
end
end
locomotive/steam/liquid/tags/path_to.rb b/lib/locomotive/steam/liquid/tags/path_to.rb +13 -11
@@ @@ -1,21 +1,23 @@
module Locomotive
- module Liquid
- module Tags
- class PathTo < ::Liquid::Tag
+ module Steam
+ module Liquid
+ module Tags
+ class PathTo < ::Liquid::Tag
- include PathHelper
+ include PathHelper
- def render(context)
- render_path(context)
- end
+ def render(context)
+ render_path(context)
+ end
+
+ def wrong_syntax!
+ raise SyntaxError.new("Syntax Error in 'path_to' - Valid syntax: path_to <page|page_handle|content_entry>(, locale: [fr|de|...], with: <page_handle>")
+ end
- def wrong_syntax!
- raise SyntaxError.new("Syntax Error in 'path_to' - Valid syntax: path_to <page|page_handle|content_entry>(, locale: [fr|de|...], with: <page_handle>")
end
+ ::Liquid::Template.register_tag('path_to', PathTo)
end
-
- ::Liquid::Template.register_tag('path_to', PathTo)
end
end
end
locomotive/steam/liquid/tags/seo.rb b/lib/locomotive/steam/liquid/tags/seo.rb +58 -56
@@ @@ -1,72 +1,74 @@
module Locomotive
- module Liquid
- module Tags
- module SEO
-
- class Base < ::Liquid::Tag
-
- def render(context)
- %{
- #{self.render_title(context)}
- #{self.render_metadata(context)}
- }
- end
-
- protected
-
- def render_title(context)
- title = self.value_for(:seo_title, context)
- title = context.registers[:site].name if title.blank?
-
- %{
- <title>#{title}</title>
- }
- end
-
- def render_metadata(context)
- %{
- <meta name="description" content="#{self.value_for(:meta_description, context)}">
- <meta name="keywords" content="#{self.value_for(:meta_keywords, context)}">
- }
+ module Steam
+ module Liquid
+ module Tags
+ module SEO
+
+ class Base < ::Liquid::Tag
+
+ def render(context)
+ %{
+ #{self.render_title(context)}
+ #{self.render_metadata(context)}
+ }
+ end
+
+ protected
+
+ def render_title(context)
+ title = self.value_for(:seo_title, context)
+ title = context.registers[:site].name if title.blank?
+
+ %{
+ <title>#{title}</title>
+ }
+ end
+
+ def render_metadata(context)
+ %{
+ <meta name="description" content="#{self.value_for(:meta_description, context)}">
+ <meta name="keywords" content="#{self.value_for(:meta_keywords, context)}">
+ }
+ end
+
+ # Removes whitespace and quote charactets from the input
+ def sanitized_string(string)
+ string ? string.strip.gsub(/"/, '') : ''
+ end
+
+ def value_for(attribute, context)
+ object = self.metadata_object(context)
+ value = object.try(attribute.to_sym).blank? ? context.registers[:site].send(attribute.to_sym) : object.send(attribute.to_sym)
+ self.sanitized_string(value)
+ end
+
+ def metadata_object(context)
+ context['content_entry'] || context['page']
+ end
end
- # Removes whitespace and quote charactets from the input
- def sanitized_string(string)
- string ? string.strip.gsub(/"/, '') : ''
- end
-
- def value_for(attribute, context)
- object = self.metadata_object(context)
- value = object.try(attribute.to_sym).blank? ? context.registers[:site].send(attribute.to_sym) : object.send(attribute.to_sym)
- self.sanitized_string(value)
- end
-
- def metadata_object(context)
- context['content_entry'] || context['page']
- end
- end
+ class Title < Base
- class Title < Base
+ def render(context)
+ self.render_title(context)
+ end
- def render(context)
- self.render_title(context)
end
- end
+ class Metadata < Base
- class Metadata < Base
+ def render(context)
+ self.render_metadata(context)
+ end
- def render(context)
- self.render_metadata(context)
end
end
+ ::Liquid::Template.register_tag('seo', SEO::Base)
+ ::Liquid::Template.register_tag('seo_title', SEO::Title)
+ ::Liquid::Template.register_tag('seo_metadata', SEO::Metadata)
end
-
- ::Liquid::Template.register_tag('seo', SEO::Base)
- ::Liquid::Template.register_tag('seo_title', SEO::Title)
- ::Liquid::Template.register_tag('seo_metadata', SEO::Metadata)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/session_assign.rb b/lib/locomotive/steam/liquid/tags/session_assign.rb +29 -27
@@ @@ -1,39 +1,41 @@
module Locomotive
- module Liquid
- module Tags
+ module Steam
+ module Liquid
+ module Tags
- # Assign sets a variable in your session.
- #
- # {% session_assign foo = 'monkey' %}
- #
- # You can then use the variable later in the page.
- #
- # {{ session.foo }}
- #
- class SessionAssign < ::Liquid::Tag
- Syntax = /(#{::Liquid::VariableSignature}+)\s*=\s*(#{::Liquid::QuotedFragment}+)/
+ # Assign sets a variable in your session.
+ #
+ # {% session_assign foo = 'monkey' %}
+ #
+ # You can then use the variable later in the page.
+ #
+ # {{ session.foo }}
+ #
+ class SessionAssign < ::Liquid::Tag
+ Syntax = /(#{::Liquid::VariableSignature}+)\s*=\s*(#{::Liquid::QuotedFragment}+)/
- def initialize(tag_name, markup, tokens, context)
- if markup =~ Syntax
- @to = $1
- @from = $2
- else
- raise ::Liquid::SyntaxError.new("Syntax Error in 'session_assign' - Valid syntax: assign [var] = [source]")
+ def initialize(tag_name, markup, tokens, context)
+ if markup =~ Syntax
+ @to = $1
+ @from = $2
+ else
+ raise ::Liquid::SyntaxError.new("Syntax Error in 'session_assign' - Valid syntax: assign [var] = [source]")
+ end
+
+ super
end
- super
- end
+ def render(context)
+ controller = context.registers[:controller]
- def render(context)
- controller = context.registers[:controller]
+ controller.session[@to.to_sym] = context[@from]
+ ''
+ end
- controller.session[@to.to_sym] = context[@from]
- ''
end
+ ::Liquid::Template.register_tag('session_assign', SessionAssign)
end
-
- ::Liquid::Template.register_tag('session_assign', SessionAssign)
end
end
- end
\ No newline at end of file
+ end
locomotive/steam/liquid/tags/snippet.rb b/lib/locomotive/steam/liquid/tags/snippet.rb +51 -49
@@ @@ -1,75 +1,77 @@
module Locomotive
- module Liquid
- module Tags
+ module Steam
+ module Liquid
+ module Tags
- class Snippet < ::Liquid::Include
+ class Snippet < ::Liquid::Include
- attr_accessor :slug
- attr_accessor :partial
+ attr_accessor :slug
+ attr_accessor :partial
- def initialize(tag_name, markup, tokens, context)
- super
+ def initialize(tag_name, markup, tokens, context)
+ super
- @slug = @template_name.gsub(/['"]/o, '')
+ @slug = @template_name.gsub(/['"]/o, '')
- if @context[:snippets].present?
- (@context[:snippets] << @slug).uniq!
- else
- @context[:snippets] = [@slug]
- end
+ if @context[:snippets].present?
+ (@context[:snippets] << @slug).uniq!
+ else
+ @context[:snippets] = [@slug]
+ end
- if @context[:site].present?
- snippet = @context[:site].snippets.where(slug: @slug).first
- self.refresh(snippet) if snippet
+ if @context[:site].present?
+ snippet = @context[:site].snippets.where(slug: @slug).first
+ self.refresh(snippet) if snippet
+ end
end
- end
- def render(context)
- return '' if @partial.nil?
+ def render(context)
+ return '' if @partial.nil?
- variable = context[@variable_name || @template_name[1..-2]]
+ variable = context[@variable_name || @template_name[1..-2]]
- context.stack do
- @attributes.each do |key, value|
- context[key] = context[value]
- end
+ context.stack do
+ @attributes.each do |key, value|
+ context[key] = context[value]
+ end
- output = (if variable.is_a?(Array)
- variable.collect do |variable|
+ output = (if variable.is_a?(Array)
+ variable.collect do |variable|
+ context[@template_name[1..-2]] = variable
+ @partial.render(context)
+ end
+ else
context[@template_name[1..-2]] = variable
@partial.render(context)
- end
- else
- context[@template_name[1..-2]] = variable
- @partial.render(context)
- end)
+ end)
- output
+ output
+ end
end
- end
- def refresh(snippet, context = {})
- if snippet.destroyed?
- @snippet_id = nil
- @partial = nil
- else
- @snippet_id = snippet.id
- @partial = ::Liquid::Template.parse(snippet.template, context.merge(@context))
- @partial.root.context.clear
+ def refresh(snippet, context = {})
+ if snippet.destroyed?
+ @snippet_id = nil
+ @partial = nil
+ else
+ @snippet_id = snippet.id
+ @partial = ::Liquid::Template.parse(snippet.template, context.merge(@context))
+ @partial.root.context.clear
+ end
end
- end
- def nodelist
- if @partial
- @partial.root.nodelist
- else
- []
+ def nodelist
+ if @partial
+ @partial.root.nodelist
+ else
+ []
+ end
end
+
end
+ ::Liquid::Template.register_tag('include', Snippet)
end
-
- ::Liquid::Template.register_tag('include', Snippet)
end
end
end
locomotive/steam/liquid/tags/with_scope.rb b/lib/locomotive/steam/liquid/tags/with_scope.rb +45 -43
@@ @@ -1,65 +1,67 @@
module Locomotive
- module Liquid
- module Tags
+ module Steam
+ module Liquid
+ module Tags
- # Filter a collection
- #
- # Usage:
- #
- # {% with_scope main_developer: 'John Doe', providers.in: ['acme'], started_at.le: today, active: true %}
- # {% for project in contents.projects %}
- # {{ project.name }}
- # {% endfor %}
- # {% endwith_scope %}
- #
+ # Filter a collection
+ #
+ # Usage:
+ #
+ # {% with_scope main_developer: 'John Doe', providers.in: ['acme'], started_at.le: today, active: true %}
+ # {% for project in contents.projects %}
+ # {{ project.name }}
+ # {% endfor %}
+ # {% endwith_scope %}
+ #
- class WithScope < Solid::Block
+ class WithScope < Solid::Block
- OPERATORS = %w(all exists gt gte in lt lte ne nin size near within)
+ OPERATORS = %w(all exists gt gte in lt lte ne nin size near within)
- SYMBOL_OPERATORS_REGEXP = /(\w+\.(#{OPERATORS.join('|')})){1}\s*\:/
+ SYMBOL_OPERATORS_REGEXP = /(\w+\.(#{OPERATORS.join('|')})){1}\s*\:/
- # register the tag
- tag_name :with_scope
+ # register the tag
+ tag_name :with_scope
- def initialize(tag_name, arguments_string, tokens, context = {})
- # convert symbol operators into valid ruby code
- arguments_string.gsub!(SYMBOL_OPERATORS_REGEXP, ':"\1" =>')
+ def initialize(tag_name, arguments_string, tokens, context = {})
+ # convert symbol operators into valid ruby code
+ arguments_string.gsub!(SYMBOL_OPERATORS_REGEXP, ':"\1" =>')
- super(tag_name, arguments_string, tokens, context)
- end
+ super(tag_name, arguments_string, tokens, context)
+ end
- def display(options = {}, &block)
- current_context.stack do
- current_context['with_scope'] = self.decode(options)
- yield
+ def display(options = {}, &block)
+ current_context.stack do
+ current_context['with_scope'] = self.decode(options)
+ yield
+ end
end
- end
- protected
+ protected
- def decode(options)
- HashWithIndifferentAccess.new.tap do |hash|
- options.each do |key, value|
- _key, _operator = key.to_s.split('.')
+ def decode(options)
+ HashWithIndifferentAccess.new.tap do |hash|
+ options.each do |key, value|
+ _key, _operator = key.to_s.split('.')
- # _slug instead of _permalink
- _key = '_slug' if _key == '_permalink'
+ # _slug instead of _permalink
+ _key = '_slug' if _key == '_permalink'
- # key to h4s symbol
- _key = _key.to_s.to_sym.send(_operator.to_sym) if _operator
+ # key to h4s symbol
+ _key = _key.to_s.to_sym.send(_operator.to_sym) if _operator
- hash[_key] = (case value
- # regexp inside a string
- when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
- else
- value
- end)
+ hash[_key] = (case value
+ # regexp inside a string
+ when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
+ else
+ value
+ end)
+ end
end
end
end
- end
+ end
end
end
end
locomotive/steam/services.rb b/lib/locomotive/steam/services.rb +8 -0
@@ @@ -38,6 +38,14 @@ module Locomotive
Services::Translator.new(repositories.translation, I18n.locale)
end
+ register :external_api do
+ Services::ExternalAPI.new
+ end
+
+ register :cache do
+ Services::NoCache.new
+ end
+
register :markdown do
Services::Markdown.new
end
locomotive/steam/services/external_api.rb b/lib/locomotive/steam/services/external_api.rb +28 -14
@@ @@ -9,36 +9,50 @@ module Locomotive
include ::HTTParty
def consume(url, options = {})
- url = ::HTTParty.normalize_base_uri(url)
-
- uri = URI.parse(url)
- options[:base_uri] = "#{uri.scheme}://#{uri.host}"
- options[:base_uri] += ":#{uri.port}" if uri.port != 80
- path = uri.request_uri
+ options[:base_uri], path = extract_base_uri_and_path(url)
options.delete(:format) if options[:format] == 'default'
+ # auth ?
username, password = options.delete(:username), options.delete(:password)
options[:basic_auth] = { username: username, password: password } if username
- path ||= '/'
+ perform_request_to(path, options)
+ end
+
+ private
- # Locomotive::Common::Logger.debug "[WebService] consuming #{path}, #{options.inspect}"
+ def extract_base_uri_and_path(url)
+ url = HTTParty.normalize_base_uri(url)
- response = self.class.get(path, options)
+ uri = URI.parse(url)
+ path = uri.request_uri || '/'
+ base_uri = "#{uri.scheme}://#{uri.host}"
+ base_uri += ":#{uri.port}" if uri.port != 80
+
+ [base_uri, path]
+ end
+
+ def perform_request_to(path, options)
+ # [DEBUG] puts "[WebService] consuming #{path}, #{options.inspect}"
+
+ # sanitize the options
+ options[:format] = options[:format].gsub(/[\'\"]/, '').to_sym if options.has_key?(:format)
+ options[:headers] = { 'User-Agent' => 'LocomotiveCMS' } if options[:with_user_agent]
+
+ response = self.class.get(path, options)
+ parsed_response = response.parsed_response
if response.code == 200
- _response = response.parsed_response
- if _response.respond_to?(:underscore_keys)
- _response.underscore_keys
+ if parsed_response.respond_to?(:underscore_keys)
+ parsed_response.underscore_keys
else
- _response.collect(&:underscore_keys)
+ parsed_response.collect(&:underscore_keys)
end
else
Locomotive::Common::Logger.error "[WebService] consumed #{path}, #{options.inspect}, response = #{response.inspect}"
nil
end
-
end
end
locomotive/steam/services/no_cache.rb b/lib/locomotive/steam/services/no_cache.rb +15 -0
@@ @@ -0,0 +1,15 @@
+ module Locomotive
+ module Steam
+ module Services
+
+ class NoCache
+
+ def fetch(key, options = {}, &block)
+ block.call
+ end
+
+ end
+
+ end
+ end
+ end
spec/integration/services/external_api_spec.rb +18 -0
@@ @@ -0,0 +1,18 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Services::ExternalAPI do
+
+ let(:service) { Locomotive::Steam::Services::ExternalAPI.new }
+
+ describe '#consume' do
+
+ let(:url) { 'https://api.github.com/users/did/repos' }
+ let(:options) { { format: "'json'", with_user_agent: true } }
+
+ subject { service.consume(url, options) }
+
+ it { expect(subject.size).to_not eq 0 }
+
+ end
+
+ end
spec/support.rb +2 -1
@@ @@ -1,4 +1,5 @@
require_relative 'support/helpers'
+ require_relative 'support/liquid'
require_relative 'support/matchers/hash'
require_relative 'support/examples/matching_locale'
- require_relative 'support/examples/locale_file'
\ No newline at end of file
+ require_relative 'support/examples/locale_file'
spec/support/liquid.rb +3 -0
@@ @@ -0,0 +1,3 @@
+ def render_template(template, context)
+ ::Liquid::Template.parse(template).render(context)
+ end
spec/unit/liquid/tags/consume_spec.rb +89 -0
@@ @@ -0,0 +1,89 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Liquid::Tags::Consume do
+
+ let(:template) { '{% consume blog from "http://blog.locomotiveapp.org" %}{% endconsume %}' }
+ let(:assigns) { {} }
+ let(:services) { Locomotive::Steam::Services.build_instance }
+ let(:context) { ::Liquid::Context.new(assigns, {}, { services: services }) }
+
+ subject { render_template(template, context) }
+
+ describe 'validating syntax' do
+
+ let(:response) { nil }
+ before { allow(services.external_api).to receive(:consume).and_return(response) }
+
+ describe 'validates a basic syntax' do
+ it { expect { subject }.not_to raise_exception }
+ end
+
+ describe 'validates more complex syntax with attributes' do
+ let(:template) { '{% consume blog from "http://www.locomotiveapp.org", username: "john", password: password_from_context %}{% endconsume %}' }
+ it { expect { subject }.not_to raise_exception }
+ end
+
+ describe 'should parse the correct url with complex syntax with attributes' do
+ let(:template) { '{% consume blog from "http://www.locomotiveapp.org" username: "john", password: "easyone" %}{% endconsume %}' }
+ it { expect { subject }.not_to raise_exception }
+ end
+
+ describe 'raises an error if the syntax is incorrect' do
+ let(:template) { '{% consume blog http://www.locomotiveapp.org %}{% endconsume %}' }
+ it { expect { subject }.to raise_exception }
+ end
+
+ end
+
+ describe 'rendering' do
+
+ let(:response) { { 'title' => 'Locomotive rocks!' } }
+ before { allow(services.external_api).to receive(:consume).and_return(response) }
+
+ describe 'assign the response into the liquid variable' do
+
+ let(:template) { "{% consume blog from \"http://blog.locomotiveapp.org/api/read\" %}{{ blog.title }}{% endconsume %}" }
+ it { is_expected.to eq 'Locomotive rocks!' }
+
+ end
+
+ describe 'assign the response into the liquid variable using a url from a variable' do
+
+ let(:assigns) { { 'url' => 'http://blog.locomotiveapp.org/api/read' } }
+ let(:template) { "{% consume blog from url %}{{ blog.title }}{% endconsume %}" }
+ it { is_expected.to eq 'Locomotive rocks!' }
+
+ end
+
+ describe 'accept options for the web service' do
+
+ let(:assigns) { { 'secret_password' => 'bar' } }
+ let(:template) { "{% consume blog from \"http://blog.locomotiveapp.org/api/read\", username: 'foo', password: secret_password %}{{ blog.title }}{% endconsume %}" }
+ it { is_expected.to eq 'Locomotive rocks!' }
+
+ end
+
+ end
+
+ describe 'timeout' do
+
+ let(:response) { { 'title' => 'first response' } }
+ let(:url) { 'http://blog.locomotiveapp.org/api/read' }
+ let(:template) { %{{% consume blog from "#{url}" timeout:5.0 %}{{ blog.title }}{% endconsume %}} }
+
+ it 'should pass the timeout option to httparty' do
+ expect(services.external_api).to receive(:consume).with(url, timeout: 5.0).and_return(response)
+ subject
+ end
+
+ it 'should return the previous successful response if a timeout occurs' do
+ allow(services.external_api).to receive(:consume).and_return(response)
+ is_expected.to eq 'first response'
+
+ allow(services.external_api).to receive(:consume).and_raise(Timeout::Error)
+ is_expected.to eq 'first response'
+ end
+
+ end
+
+ end
spec/unit/services/external_api_spec.rb +58 -0
@@ @@ -0,0 +1,58 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Services::ExternalAPI do
+
+ let(:service) { Locomotive::Steam::Services::ExternalAPI.new }
+
+ describe '#consume' do
+
+ let(:url) { '' }
+ let(:options) { {} }
+ let(:response) { instance_double('Response', code: 200, parsed_response: OpenStruct.new) }
+
+ subject { service.consume(url, options) }
+
+ describe 'sets the base uri from a simple url' do
+
+ let(:url) { 'http://blog.locomotiveapp.org' }
+ it do
+ expect(service.class).to receive(:get).with('/', { base_uri: 'http://blog.locomotiveapp.org' }).and_return(response)
+ subject
+ end
+
+ end
+
+ describe 'sets the base uri from a much more complex url' do
+
+ let(:url) { 'http://free.worldweatheronline.com/feed/weather.ashx?key=secretapikey&format=json' }
+ it do
+ expect(service.class).to receive(:get).with('/feed/weather.ashx?key=secretapikey&format=json', { base_uri: 'http://free.worldweatheronline.com' }).and_return(response)
+ subject
+ end
+
+ end
+
+
+ describe 'sets both the base uri and the path from an url with parameters' do
+
+ let(:url) { 'http://blog.locomotiveapp.org/api/read/json?num=3' }
+ it do
+ expect(service.class).to receive(:get).with('/api/read/json?num=3', { base_uri: 'http://blog.locomotiveapp.org' }).and_return(response)
+ subject
+ end
+
+ end
+
+ describe 'sets auth credentials' do
+
+ let(:url) { 'http://blog.locomotiveapp.org' }
+ let(:options) { { username: 'john', password: 'foo' } }
+ it do
+ expect(service.class).to receive(:get).with('/', { base_uri: 'http://blog.locomotiveapp.org', basic_auth: { username: 'john', password: 'foo' } }).and_return(response)
+ subject
+ end
+ end
+
+ end
+
+ end