implement the url_to tag + refactor the link_to tag
did
committed Nov 14, 2013
commit e0f184a54edc3a0c148dfee83e1b62b1005538f1
Showing 4
changed files with
139 additions
and 2 deletions
locomotive/wagon/liquid/tags/url_helper.rb b/lib/locomotive/wagon/liquid/tags/url_helper.rb
+98
-0
| @@ | @@ -0,0 +1,98 @@ |
| + | module Locomotive |
| + | module Wagon |
| + | module Liquid |
| + | module Tags |
| + | |
| + | module UrlHelper |
| + | |
| + | def render_url(context, &block) |
| + | site = context.registers[:site] |
| + | |
| + | if page = self.retrieve_page_from_handle(context) |
| + | url = self.public_page_url(context, page) |
| + | |
| + | if block_given? |
| + | block.call page, url |
| + | else |
| + | url |
| + | end |
| + | else |
| + | raise Liquid::PageNotTranslated.new(%{[link_to] Unable to find a page for the #{@handle}. Wrong handle or missing template for your content.}) |
| + | 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 Liquid::Drops::Page then handle.instance_variable_get(:@_source) |
| + | when String then fetch_page(mounting_point, handle) |
| + | when Liquid::Drops::ContentEntry then fetch_page(mounting_point, handle.instance_variable_get(:@_source), true) |
| + | 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.templatized_from_parent && |
| + | _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 public_page_url(context, page) |
| + | mounting_point = context.registers[:mounting_point] |
| + | locale = @_options['locale'] || ::I18n.locale |
| + | |
| + | if !page.translated_in?(locale) |
| + | title = page.title_translations.values.compact.first |
| + | raise Liquid::PageNotTranslated.new(%{the "#{title}" page is not translated in #{locale.upcase}}) |
| + | end |
| + | |
| + | fullpath = ::Locomotive::Mounter.with_locale(locale) do |
| + | page.fullpath.clone |
| + | end |
| + | |
| + | fullpath = "#{::I18n.locale}/#{fullpath}" if ::I18n.locale.to_s != mounting_point.default_locale.to_s |
| + | |
| + | if page.templatized? |
| + | if page.content_entry._slug.nil? |
| + | title = %{#{page.content_entry.content_type.name.singularize} "#{page.content_entry.send(page.content_entry.content_type.label_field_name)}"} |
| + | raise Liquid::ContentEntryNotTranslated.new(%{the #{title} slug is not translated in #{locale.upcase}}) |
| + | end |
| + | fullpath.gsub!(/(content[_-]type[_-]template|template)/, page.content_entry._slug) |
| + | end |
| + | |
| + | File.join('/', fullpath) |
| + | end |
| + | |
| + | end |
| + | end |
| + | |
| + | end |
| + | end |
| + | end |
| \ No newline at end of file | |
locomotive/wagon/liquid/tags/url_to.rb b/lib/locomotive/wagon/liquid/tags/url_to.rb
+36
-0
| @@ | @@ -0,0 +1,36 @@ |
| + | module Locomotive |
| + | module Wagon |
| + | module Liquid |
| + | module Tags |
| + | |
| + | class UrlTo < ::Liquid::Tag |
| + | |
| + | include UrlHelper |
| + | |
| + | 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 'url_to' - Valid syntax: url_to <page|page_handle|content_entry>(, locale: [fr|de|...], with: <page_handle>") |
| + | end |
| + | |
| + | super |
| + | end |
| + | |
| + | def render(context) |
| + | render_url(context) |
| + | end |
| + | |
| + | end |
| + | |
| + | ::Liquid::Template.register_tag('url_to', UrlTo) |
| + | end |
| + | end |
| + | end |
| + | end |
| \ No newline at end of file | |
spec/fixtures/default/app/views/pages/music.liquid.haml
+2
-0
| @@ | @@ -34,6 +34,8 @@ position: 2 |
| {% endwith_scope %} | |
| {% for s in selected_songs %} | |
| %p.scoped_song {{ s._label }} | |
| + | %p.scoped_song_link |
| + | %a{ href: "{% url_to s %}" } {{ s._label }} |
| {% endfor %} | |
| %p.collection_equality {{ contents.songs.all.size }}={{ contents.songs.size }} | |
spec/integration/server/liquid_spec.rb
+3
-2
| @@ | @@ -71,15 +71,16 @@ describe Locomotive::Wagon::Server 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-3.>Song #3/m |
| end | |
| - | it "size of evaluated unscoped collection eqaul to unevaluated one" do |
| + | 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 '/' | |