Merge pull request #657 from bhollis/link_to

URL not being parsed when using a link with a hash with link_to helper
This commit is contained in:
Ben Hollis 2012-12-30 19:47:15 -08:00
commit b6c33abda1
2 changed files with 72 additions and 27 deletions

View file

@ -91,3 +91,28 @@ Feature: link_to helper
When I go to "/link_to.html" When I go to "/link_to.html"
Then I should see '<a href="/foo/needs_index.html">Needs Index</a>' Then I should see '<a href="/foo/needs_index.html">Needs Index</a>'
Scenario: link_to preserves query string and anchor and isn't messed up by them
Given a fixture app "indexable-app"
And a file named "source/link_to.html.erb" with:
"""
<%= link_to "Needs Index Anchor", "/needs_index.html#foo" %>
<%= link_to "Needs Index Query", "/needs_index.html?foo" %>
<%= link_to "Needs Index Query and Anchor", "/needs_index.html?foo#foo" %>
"""
And the Server is running at "indexable-app"
When I go to "/link_to/"
Then I should see '<a href="/needs_index/#foo">Needs Index Anchor</a>'
Then I should see '<a href="/needs_index/?foo">Needs Index Query</a>'
Then I should see '<a href="/needs_index/?foo#foo">Needs Index Query and Anchor</a>'
Scenario: link_to accepts a :query option that appends a query string
Given a fixture app "indexable-app"
And a file named "source/link_to.html.erb" with:
"""
<%= link_to "Needs Index String", "/needs_index.html", :query => "foo" %>
<%= link_to "Needs Index Hash", "/needs_index.html", :query => { :foo => :bar } %>
"""
And the Server is running at "indexable-app"
When I go to "/link_to/"
Then I should see '<a href="/needs_index/?foo">Needs Index String</a>'
Then I should see '<a href="/needs_index/?foo=bar">Needs Index Hash</a>'

View file

@ -1,3 +1,5 @@
require 'active_support/core_ext/object/to_query'
module Middleman module Middleman
module CoreExtensions module CoreExtensions
# Built-in helpers # Built-in helpers
@ -113,6 +115,10 @@ module Middleman
# config[:relative_links] = true # config[:relative_links] = true
# #
# to config.rb to have all links default to relative. # to config.rb to have all links default to relative.
#
# There is also a :query option that can be used to append a
# query string, which can be expressed as either a String,
# or a Hash which will be turned into URL parameters.
def link_to(*args, &block) def link_to(*args, &block)
url_arg_index = block_given? ? 0 : 1 url_arg_index = block_given? ? 0 : 1
options_index = block_given? ? 1 : 2 options_index = block_given? ? 1 : 2
@ -130,11 +136,14 @@ module Middleman
# Handle relative urls # Handle relative urls
current_source_dir = Pathname('/' + current_resource.path).dirname current_source_dir = Pathname('/' + current_resource.path).dirname
path = Pathname(url) uri = URI(url)
url_path = uri.path
url = current_source_dir.join(path).to_s if path.relative? if url_path
path = Pathname(url_path)
url_path = current_source_dir.join(path).to_s if path.relative?
resource = sitemap.find_resource_by_path(url) resource = sitemap.find_resource_by_path(url_path)
# Allow people to turn on relative paths for all links with config[:relative_links] = true # Allow people to turn on relative paths for all links with config[:relative_links] = true
# but still override on a case by case basis with the :relative parameter. # but still override on a case by case basis with the :relative parameter.
@ -159,12 +168,23 @@ module Middleman
new_url = resource.url new_url = resource.url
end end
args[url_arg_index] = new_url uri.path = new_url
args[url_arg_index] = uri.to_s
else else
raise "No resource exists at #{url}" if relative raise "No resource exists at #{url}" if relative
end end
end end
end end
end
# Support a :query option that can be a string or hash
query = options.delete(:query)
if query
uri = URI(args[url_arg_index])
uri.query = query.respond_to?(:to_param) ? query.to_param : query.to_s
args[url_arg_index] = uri.to_s
end
super(*args, &block) super(*args, &block)
end end