implementation of the link_to liquid tag (wip)
did
committed Jul 02, 2013
commit 45d8a1fe8223539304210a8234f652884469e0d2
Showing 7
changed files with
176 additions
and 5 deletions
locomotive/wagon/liquid.rb b/lib/locomotive/wagon/liquid.rb
+1
-0
| @@ | @@ -1,6 +1,7 @@ |
| require 'liquid' | |
| require 'locomotive/mounter' | |
| require 'locomotive/wagon/liquid/drops/base' | |
| + | require 'locomotive/wagon/liquid/tags/hybrid' |
| %w{. drops tags filters}.each do |dir| | |
| Dir[File.join(File.dirname(__FILE__), 'liquid', dir, '*.rb')].each { |lib| require lib } | |
locomotive/wagon/liquid/tags/hybrid.rb b/lib/locomotive/wagon/liquid/tags/hybrid.rb
+27
-0
| @@ | @@ -0,0 +1,27 @@ |
| + | module Locomotive |
| + | module Wagon |
| + | 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 | |
locomotive/wagon/liquid/tags/link_to.rb b/lib/locomotive/wagon/liquid/tags/link_to.rb
+110
-0
| @@ | @@ -0,0 +1,110 @@ |
| + | module Locomotive |
| + | module Wagon |
| + | module Liquid |
| + | module Tags |
| + | class LinkTo < Hybrid |
| + | |
| + | 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 |
| + | end |
| + | else |
| + | raise SyntaxError.new("Syntax Error in 'link_to' - Valid syntax: link_to page_handle, locale es (locale is optional)") |
| + | end |
| + | |
| + | super |
| + | end |
| + | |
| + | def render(context) |
| + | if page = self.retrieve_page_from_handle(context) |
| + | label = self.label_from_page(page) |
| + | path = self.public_page_url(context, page) |
| + | |
| + | if @render_as_block |
| + | context.scopes.last['target'] = page |
| + | label = super.html_safe |
| + | end |
| + | |
| + | %{<a href="#{path}">#{label}</a>} |
| + | else |
| + | '' # no page found |
| + | end |
| + | end |
| + | |
| + | protected |
| + | |
| + | def retrieve_page_from_handle(context) |
| + | mounting_point = context.registers[:mounting_point] |
| + | |
| + | context.scopes.reverse_each do |scope| |
| + | handle = scope[@handle] || @handle |
| + | |
| + | page = case handle |
| + | when Locomotive::Mounter::Models::Page then handle |
| + | when String then fetch_page(mounting_point, handle) |
| + | when Locomotive::Mounter::Models::ContentEntry then fetch_page(mounting_point, handle, true) |
| + | else |
| + | nil |
| + | end |
| + | |
| + | return page unless page.nil? |
| + | end |
| + | |
| + | nil |
| + | end |
| + | |
| + | def fetch_page(mounting_point, handle, templatized = false) |
| + | ::Locomotive::Mounter.with_locale(@options['locale']) do |
| + | if templatized |
| + | page = mounting_point.pages.values.find do |_page| |
| + | _page.templatized? && |
| + | _page.content_type.slug == handle.content_type.slug && |
| + | (@options['with'].nil? || _page.handle == @options['with']) |
| + | end |
| + | |
| + | page.content_entry = handle if page |
| + | |
| + | page |
| + | else |
| + | mounting_point.pages.values.find { |_page| _page.handle == handle } |
| + | end |
| + | end |
| + | end |
| + | |
| + | def label_from_page(page) |
| + | ::Locomotive::Mounter.with_locale(@options['locale']) do |
| + | if page.templatized? |
| + | page.content_entry._label |
| + | else |
| + | page.title |
| + | end |
| + | end |
| + | end |
| + | |
| + | def public_page_url(context, page) |
| + | fullpath = page.fullpath |
| + | mounting_point = context.registers[:mounting_point] |
| + | |
| + | ::Locomotive::Mounter.with_locale(@options['locale']) do |
| + | fullpath = "#{::I18n.locale}/#{fullpath}" if ::I18n.locale.to_s != mounting_point.default_locale.to_s |
| + | end |
| + | |
| + | if page.templatized? |
| + | fullpath.gsub!('content_type_template', page.content_entry._slug) |
| + | end |
| + | |
| + | File.join('/', fullpath) |
| + | end |
| + | |
| + | end |
| + | |
| + | ::Liquid::Template.register_tag('link_to', LinkTo) |
| + | end |
| + | end |
| + | end |
| + | end |
| \ No newline at end of file | |
spec/fixtures/default/app/views/pages/about_us.liquid.haml
+1
-0
| @@ | @@ -2,6 +2,7 @@ |
| title: About Us | |
| listed: true | |
| position: 1 | |
| + | handle: about-us |
| editable_elements: | |
| 'banner/page_image': "/samples/photo_2.jpg" | |
| 'banner/pitch': "<h2>About us</h2><p>Lorem ipsum...</p>" | |
spec/fixtures/default/app/views/pages/events.liquid.haml
+8
-0
| @@ | @@ -26,4 +26,12 @@ position: 5 |
| {% endeditable_long_text %} | |
| + | %p |
| + | %strong Discover: {% link_to our-music %} |
| + | %br |
| + | %strong {% link_to about-us %}Who are we ?{% endlink_to %} |
| + | %br |
| + | {% assign song = contents.songs.first %} |
| + | %strong {% link_to song %} |
| + | |
| {% endblock %} | |
| \ No newline at end of file | |
spec/fixtures/default/app/views/pages/music.liquid.haml
+4
-1
| @@ | @@ -1,5 +1,6 @@ |
| --- | |
| listed: true | |
| + | handle: our-music |
| position: 2 | |
| --- | |
| {% extends parent %} | |
| @@ | @@ -24,5 +25,7 @@ position: 2 |
| {% for song in contents.songs offset: 4 %} | |
| {% include 'song' with song %} | |
| {% endfor %} | |
| - | #is_listed{listed: "{{ page.listed? }}"} |
| + | |
| + | #is_listed{ listed: "{{ page.listed? }}" } |
| + | |
| {% endblock %} | |
| \ No newline at end of file | |
spec/integration/server/liquid_spec.rb
+25
-4
| @@ | @@ -11,12 +11,12 @@ describe Locomotive::Wagon::Server do |
| def app | |
| run_server | |
| end | |
| - | |
| + | |
| it "converts {{ page.templatized? }} => true on templatized page" do | |
| get '/songs/song-1' | |
| last_response.body.should =~ /templatized=.true./ | |
| end | |
| - | |
| + | |
| it "converts {{ page.templatized? }} => false on regular page" do | |
| get '/index' | |
| last_response.body.should =~ /templatized=.false./ | |
| @@ | @@ -26,14 +26,35 @@ describe Locomotive::Wagon::Server do |
| get '/music' | |
| last_response.body.should =~ /listed=.true./ | |
| end | |
| - | |
| + | |
| it "provides an access to page's content_type collection" do | |
| get '/songs/song-1' | |
| last_response.body.should =~ /content_type_size=.8./ | |
| end | |
| - | |
| + | |
| it "provides count alias on collections" do | |
| get '/songs/song-1' | |
| last_response.body.should =~ /content_type_count=.8./ | |
| end | |
| + | |
| + | 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 with a custom label" do |
| + | get '/events' |
| + | last_response.body.should =~ /<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-1">Song #1<\/a>/ |
| + | end |
| + | |
| + | |
| + | |
| + | end |
| end | |
| \ No newline at end of file | |