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 '/'