tweak the hybrid liquid tag for edge cases + fix bug with options passed to the link_to liquid tag
did
committed Feb 16, 2015
commit 86a601b7cd303ea3b34fde1b04b46b4594855c9c
Showing 8
changed files with
127 additions
and 108 deletions
locomotive/steam/liquid/drops/site.rb b/lib/locomotive/steam/liquid/drops/site.rb
+0
-1
| @@ | @@ -24,7 +24,6 @@ module Locomotive |
| conditions = @context['with_scope'] || {} | |
| conditions['slug.ne'] = '404' | |
| repository.all(conditions) | |
| - | |
| end | |
| end | |
locomotive/steam/liquid/tags/concerns/path.rb b/lib/locomotive/steam/liquid/tags/concerns/path.rb
+9
-1
| @@ | @@ -13,7 +13,7 @@ module Locomotive |
| # FIXME: the with option needs a string with quotes. | |
| # this is a hack for sites which don't follow the new syntax. | |
| - | _options.gsub!(/with: ([\w-]+)/, 'with: "\1"') if _options |
| + | make_options_compatible_with_previous_version(_options) |
| @raw_path_options = parse_options_from_string(_options) | |
| else | |
| @@ | @@ -98,6 +98,14 @@ module Locomotive |
| interpolate_options(@raw_path_options, context) | |
| end | |
| + | def make_options_compatible_with_previous_version(options) |
| + | if options |
| + | %w(with locale).each do |name| |
| + | options.gsub!(/#{name}: ([\w-]+)/, name + ': "\1"') |
| + | end |
| + | end |
| + | end |
| + | |
| end | |
| end | |
| end | |
locomotive/steam/liquid/tags/hybrid.rb b/lib/locomotive/steam/liquid/tags/hybrid.rb
+18
-29
| @@ | @@ -5,41 +5,30 @@ module Locomotive |
| class Hybrid < ::Liquid::Block | |
| - | class HybridTagDetectedException < Exception; end |
| - | |
| - | def parse_body(body, tokens) |
| - | body.parse(tokens, options) do |end_tag_name, end_tag_params| |
| - | @blank &&= body.blank? |
| - | |
| - | return false if end_tag_name == block_delimiter |
| - | unless end_tag_name |
| - | # tag never closed |
| - | raise HybridTagDetectedException.new |
| - | end |
| - | |
| - | # this tag is not registered with the system |
| - | # pass it to the current block for special handling or error reporting |
| - | unknown_tag(end_tag_name, end_tag_params, tokens) |
| - | end |
| - | |
| - | true |
| - | end |
| - | |
| def render_as_block? | |
| @render_as_block | |
| end | |
| def parse(tokens) | |
| - | @render_as_block = true |
| - | begin |
| - | cloned_tokens = tokens.dup |
| - | super(cloned_tokens) |
| - | tokens.replace(cloned_tokens) |
| - | rescue HybridTagDetectedException |
| - | @body = nil |
| - | @render_as_block = false |
| + | if @render_as_block = find_block_delimiter?(tokens) |
| + | super |
| + | else |
| + | @body = nil |
| + | @blank = false |
| + | end |
| + | end |
| + | |
| + | def find_block_delimiter?(tokens) |
| + | tokens.each do |token| |
| + | next if token.empty? |
| + | if token.start_with?(::Liquid::BlockBody::TAGSTART) |
| + | if token =~ ::Liquid::BlockBody::FullToken |
| + | return false if $1 == @tag_name |
| + | return true if $1 == block_delimiter |
| + | end |
| + | end |
| end | |
| - | @blank = false |
| + | false |
| end | |
| end | |
spec/fixtures/default/app/views/pages/filtered.liquid.haml
+14
-4
| @@ | @@ -1,10 +1,20 @@ |
| --- | |
| title: Various uses of the with_scope tag | |
| --- | |
| - | {% assign begin = '2012-06-01 00:00:00' %} |
| - | {% assign end = '2012-06-10 23:59:59' %} |
| - | {% assign prices = '5.0,5.5' | split: ',' | map: 'to_f' %} |
| + | {% assign begin_date = '2012-06-01 00:00:00' | parse_date_time %} |
| + | {% assign end_date = '2012-06-10 23:59:59' | parse_date_time %} |
| + | {% assign prices = '5.0,5.5' | split: ',' | map: 'to_f' %} |
| - | {% with_scope date.gte: begin, date.lte: end, city: /Kansas/, state.ne: 'Illinois', tags: 'awesome', tags.nin: 'bad', price.in: prices %} |
| + | {% with_scope date.gte: begin_date, date.lte: end_date, city: /Kansas/, state.ne: 'Illinois', tags: 'awesome', tags.nin: 'bad', price.in: prices, order_by: 'price.desc' %} |
| events={{ contents.events.count }}. | |
| {% endwith_scope %} | |
| + | |
| + | {% with_scope tags.in: 'awesome', order_by: 'price.desc' %} |
| + | first event={{ contents.events.first.place }}. |
| + | {% endwith_scope %} |
| + | |
| + | {% assign featured = false %} |
| + | |
| + | {% with_scope featured: featured %} |
| + | bands={{ contents.bands.count }}. |
| + | {% endwith_scope %} |
spec/integration/server/liquid_spec.rb
+49
-71
| @@ | @@ -1,87 +1,65 @@ |
| - | # require File.dirname(__FILE__) + '/../integration_helper' |
| + | require File.dirname(__FILE__) + '/../integration_helper' |
| - | # describe Locomotive::Steam::Server, pending: true do |
| + | describe Locomotive::Steam::Server do |
| - | # include Rack::Test::Methods |
| + | include Rack::Test::Methods |
| - | # def app |
| - | # run_server |
| - | # end |
| + | def app |
| + | run_server |
| + | end |
| - | # it "converts {{ page.templatized? }} => true on templatized page" do |
| - | # get '/songs/song-number-1' |
| - | # last_response.body.should =~ /templatized=.true./ |
| - | # end |
| + | it 'converts {{ page.templatized? }} => true on templatized page' do |
| + | get '/songs/song-number-1' |
| + | expect(last_response.body).to include "templatized='true'" |
| + | end |
| - | # it "converts {{ page.templatized? }} => false on regular page" do |
| - | # get '/index' |
| - | # last_response.body.should =~ /templatized=.false./ |
| - | # end |
| + | it 'converts {{ page.templatized? }} => false on regular page' do |
| + | get '/index' |
| + | expect(last_response.body).to include "templatized='false'" |
| + | end |
| - | # it "converts {{ page.listed? }} => true on listed page" do |
| - | # get '/music' |
| - | # last_response.body.should =~ /listed=.true./ |
| - | # end |
| + | it 'converts {{ page.listed? }} => true on listed page' do |
| + | get '/music' |
| + | expect(last_response.body).to include "listed='true'" |
| + | end |
| - | # it "provides an access to page's content_type collection" do |
| - | # get '/songs/song-number-1' |
| - | # last_response.body.should =~ /content_type_size=.8./ |
| - | # end |
| + | it "provides an access to page's content_type collection" do |
| + | get '/songs/song-number-1' |
| + | expect(last_response.body).to include "content_type_size='8'" |
| + | end |
| - | # it "provides count alias on collections" do |
| - | # get '/songs/song-number-1' |
| - | # last_response.body.should =~ /content_type_count=.8./ |
| - | # end |
| + | it 'provides count alias on collections' do |
| + | get '/songs/song-number-1' |
| + | expect(last_response.body).to include "content_type_count='8'" |
| + | end |
| - | # describe '.link_to' do |
| + | describe '.link_to' do |
| - | # it "writes a link to a page" do |
| - | # get '/events' |
| - | # last_response.body.should =~ /Discover: <a href="\/music">Music<\/a>/ |
| - | # end |
| + | it 'writes a link to a page' do |
| + | get '/events' |
| + | expect(last_response.body).to include 'Discover: <a href="/music">Music</a>' |
| + | end |
| - | # it "writes a localized a link" do |
| - | # get '/events' |
| - | # last_response.body.should =~ /Plus à notre sujet: <a href="\/fr\/a-notre-sujet">Qui sommes nous \?<\/a>/ |
| - | # end |
| + | it "writes a localized a link" do |
| + | get '/events' |
| + | expect(last_response.body).to include 'Plus à notre sujet: <a href="/fr/a-notre-sujet">Qui sommes nous ?</a>' |
| + | end |
| - | # it "writes a link to a page with a custom label" do |
| - | # get '/events' |
| - | # last_response.body.should =~ /More about us: <a href="\/about-us">Who are we \?<\/a>/ |
| - | # end |
| + | it "writes a link to a page with a custom label" do |
| + | get '/events' |
| + | expect(last_response.body).to include 'More about us: <a href="/about-us">Who are we ?</a>' |
| + | end |
| - | # it "writes a link to a templatized page" do |
| - | # get '/events' |
| - | # last_response.body.should =~ /<a href="\/songs\/song-number-1">Song #1<\/a>/ |
| - | # end |
| + | it "writes a link to a templatized page" do |
| + | get '/events' |
| + | expect(last_response.body).to include '<a href="/songs/song-number-1">Song #1</a>' |
| + | end |
| - | # it "writes a link to a templatized page with a different handle" do |
| - | # get '/events' |
| - | # last_response.body.should =~ /<a href="\/songs\/song-number-8">Song #8<\/a>/ |
| - | # end |
| + | it "writes a link to a templatized page with a different handle" do |
| + | get '/events' |
| + | expect(last_response.body).to include '<a href="/songs/song-number-8">Song #8</a>' |
| + | end |
| - | # end |
| + | end |
| - | # describe 'scope & assigns' do |
| - | |
| - | # it "evaluates collection when called all inside of scope" do |
| - | # get '/music' |
| - | # last_response.body.should =~ /<p class=.scoped_song.>Song #3/ |
| - | # last_response.body.should =~ /<p class=.scoped_song_link.>\s+<a href=.\/songs\/song-number-3.>Song #3/m |
| - | # end |
| - | |
| - | # it "size of evaluated unscoped collection equal to unevaluated one" do |
| - | # get '/music' |
| - | # last_response.body.should =~ /class=.collection_equality.>8=8/ |
| - | # end |
| - | |
| - | # end |
| - | |
| - | # describe 'html helpers' do |
| - | # it 'bypass url for css resource' do |
| - | # get '/' |
| - | # last_response.body.should =~ /<link href=("|')http:\/\/fonts\.googleapis\.com\/css\?family=Open\+Sans:400,700("|')/ |
| - | # end |
| - | # end |
| - | |
| - | # end |
| + | end |
spec/integration/server/with_scope_spec.rb
+28
-2
| @@ | @@ -1,6 +1,6 @@ |
| # require File.dirname(__FILE__) + '/../integration_helper' | |
| - | # describe 'Complex with_scope conditions', pending: true do |
| + | # describe 'Complex with_scope conditions' do |
| # include Rack::Test::Methods | |
| @@ | @@ -10,7 +10,33 @@ |
| # it 'returns the right number of events' do | |
| # get '/filtered' | |
| - | # last_response.body.should =~ /events=1./ |
| + | # expect(last_response.body).to include 'events=1' |
| # end | |
| + | # it 'returns the right number of bands' do |
| + | # get '/filtered' |
| + | # expect(last_response.body).to include 'bands=2' |
| + | # end |
| + | |
| + | # it 'returns the first band in the right order' do |
| + | # get '/filtered' |
| + | # expect(last_response.body).to include "first event=Browne's Market" |
| + | # end |
| + | |
| + | # # it 'returns the right number of events' do |
| + | # # get '/filtered' |
| + | # # last_response.body.should =~ /events=1./ |
| + | # # end |
| + | |
| + | # # it 'evaluates collection when called all inside of scope' do |
| + | # # get '/music' |
| + | # # expect(last_response.body).to include "<p class='scoped_song'>Song #3" |
| + | # # expect(last_response.body).to match /<p class=scoped_song_link.>\s+<a href=.\/songs\/song-number-3.>Song #3/m |
| + | # # end |
| + | |
| + | # # it 'size of evaluated unscoped collection equal to unevaluated one' do |
| + | # # get '/music' |
| + | # # expect(last_response.body).to include "class='collection_equality'>8=8" |
| + | # # end |
| + | |
| # end | |
spec/integration/services/external_api_spec.rb
+2
-0
| @@ | @@ -2,6 +2,8 @@ require 'spec_helper' |
| describe Locomotive::Steam::Services::ExternalAPI do | |
| + | pending 'API rate limit exceeded' |
| + | |
| let(:service) { Locomotive::Steam::Services::ExternalAPI.new } | |
| describe '#consume' do | |
spec/unit/liquid/tags/link_to_spec.rb
+7
-0
| @@ | @@ -60,6 +60,13 @@ describe Locomotive::Steam::Liquid::Tags::PathTo do |
| end | |
| + | context 'inside another block' do |
| + | |
| + | let(:source) { '{% block header %}My links: {% link_to index %} & {% link_to index %}here too{% endlink_to %}{% endblock %}' } |
| + | it { is_expected.to eq 'My links: <a href="/">Home</a> & <a href="/">here too</a>' } |
| + | |
| + | end |
| + | |
| end | |
| describe 'used as a block' do | |