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