Merge remote-tracking branch 'origin/3.0-stable'
Conflicts: middleman-core/lib/middleman-core/core_extensions/data.rb middleman-core/lib/middleman-core/core_extensions/front_matter.rb middleman-core/lib/middleman-core/util.rb middleman-core/middleman-core-x86-mingw32.gemspec middleman-more/lib/middleman-more/core_extensions/default_helpers.rb middleman-more/lib/middleman-more/core_extensions/i18n.rb
This commit is contained in:
commit
52c4677391
|
@ -48,11 +48,7 @@ A full set of in-depth instructional guides are available on the official websit
|
|||
|
||||
http://middlemanapp.com/
|
||||
|
||||
The community maintains its own collection of tips and tricks in the GitHub wiki:
|
||||
|
||||
https://github.com/middleman/middleman/wiki
|
||||
|
||||
Finally, up-to-date generated code documentation is available on RubyDoc:
|
||||
Additionally, up-to-date generated code documentation is available on RubyDoc:
|
||||
http://rubydoc.info/github/middleman/middleman
|
||||
|
||||
# Community
|
||||
|
|
9
Rakefile
9
Rakefile
|
@ -87,6 +87,13 @@ task :test do
|
|||
end
|
||||
end
|
||||
|
||||
desc "Run specs for all middleman gems"
|
||||
task :spec do
|
||||
GEM_PATHS.each do |g|
|
||||
sh "cd #{File.join(ROOT, g)} && #{Gem.ruby} -S rake spec"
|
||||
end
|
||||
end
|
||||
|
||||
# desc "Rune cane for all middleman gems"
|
||||
# task :cane do
|
||||
# GEM_PATHS.each do |g|
|
||||
|
@ -95,4 +102,4 @@ end
|
|||
# end
|
||||
|
||||
desc "Run tests for all middleman gems"
|
||||
task :default => :test
|
||||
task :default => :test
|
||||
|
|
|
@ -233,7 +233,7 @@ module Middleman::Cli
|
|||
|
||||
paths = ::Middleman::Util.all_files_under(@destination)
|
||||
@cleaning_queue += paths.select do |path|
|
||||
!path.to_s.match(/\/\./) || path.to_s.match(/\.htaccess|\.htpasswd/)
|
||||
path.to_s !~ /\/\./ || path.to_s =~ /\.(htaccess|htpasswd)/
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ module Middleman
|
|||
# Setup data files before anything else so they are available when
|
||||
# parsing config.rb
|
||||
def initialize
|
||||
files.changed DataStore.matcher do |file|
|
||||
data.touch_file(file) if file.match(%r{^#{config[:data_dir]}\/})
|
||||
self.files.changed DataStore.matcher do |file|
|
||||
self.data.touch_file(file) if file.start_with?("#{config[data_dir]}/")
|
||||
end
|
||||
|
||||
files.deleted DataStore.matcher do |file|
|
||||
data.remove_file(file) if file.match(%r{^#{config[data_dir]}\/})
|
||||
self.files.deleted DataStore.matcher do |file|
|
||||
self.data.remove_file(file) if file.start_with?("#{config[data_dir]}/")
|
||||
end
|
||||
|
||||
super
|
||||
|
|
|
@ -145,7 +145,8 @@ module Middleman
|
|||
# @param [Pathname] path
|
||||
# @return [Boolean]
|
||||
def ignored?(path)
|
||||
IGNORE_LIST.any? { |r| path.to_s.match(r) }
|
||||
path = path.to_s
|
||||
IGNORE_LIST.any? { |r| path =~ r }
|
||||
end
|
||||
|
||||
# Notify callbacks for a file given an array of callbacks
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require "active_support/core_ext/hash/keys"
|
||||
require 'pathname'
|
||||
|
||||
# Extensions namespace
|
||||
module Middleman::CoreExtensions
|
||||
|
@ -130,7 +131,12 @@ module Middleman::CoreExtensions
|
|||
# @param [String] path
|
||||
# @return [Array<Thor::CoreExt::HashWithIndifferentAccess, String>]
|
||||
def frontmatter_and_content(path)
|
||||
full_path = File.expand_path(File.join(@app.source_dir, path))
|
||||
full_path = if Pathname(path).relative?
|
||||
File.join(@app.source_dir, path)
|
||||
else
|
||||
path
|
||||
end
|
||||
|
||||
data = {}
|
||||
content = nil
|
||||
|
||||
|
@ -158,7 +164,7 @@ module Middleman::CoreExtensions
|
|||
end
|
||||
|
||||
def normalize_path(path)
|
||||
path.sub(@app.source_dir, "").sub(/^\//, "")
|
||||
path.sub(%r{^#{@app.source_dir}\/}, "")
|
||||
end
|
||||
|
||||
# Update the main sitemap resource list
|
||||
|
|
|
@ -246,15 +246,26 @@ module Middleman
|
|||
options = opts.merge(options_for_ext(extension))
|
||||
options[:outvar] ||= '@_out_buf'
|
||||
|
||||
template_class = Tilt[path]
|
||||
# Allow hooks to manipulate the template before render
|
||||
self.class.callbacks_for_hook(:before_render).each do |callback|
|
||||
newbody = callback.call(body, path, locs, template_class)
|
||||
body = newbody if newbody # Allow the callback to return nil to skip it
|
||||
end
|
||||
|
||||
# Read compiled template from disk or cache
|
||||
template = cache.fetch(:compiled_template, options, body) do
|
||||
::Tilt.new(path, 1, options) { body }
|
||||
end
|
||||
|
||||
# Render using Tilt
|
||||
run_hook :before_render, template.data, template
|
||||
content = template.render(context, locs, &block)
|
||||
run_hook :after_render, content, template
|
||||
content = template.render(context, path, locs, &block)
|
||||
|
||||
# Allow hooks to manipulate the result after render
|
||||
self.class.callbacks_for_hook(:after_render).each do |callback|
|
||||
content = callback.call(content, locs, template_class)
|
||||
end
|
||||
|
||||
return content
|
||||
ensure
|
||||
# Reset stored buffer
|
||||
|
@ -408,7 +419,7 @@ module Middleman
|
|||
# Find the path by searching or using the cache
|
||||
request_path = request_path.to_s
|
||||
cache.fetch(:resolve_template, request_path, options) do
|
||||
relative_path = request_path.sub(%r{^/}, "")
|
||||
relative_path = Util.strip_leading_slash(request_path)
|
||||
on_disk_path = File.expand_path(relative_path, self.source_dir)
|
||||
|
||||
# By default, any engine will do
|
||||
|
|
|
@ -194,7 +194,7 @@ module Middleman
|
|||
|
||||
paths.any? do |path|
|
||||
match_against.any? do |matcher|
|
||||
path.match(matcher)
|
||||
path =~ matcher
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,18 +25,18 @@ module Middleman
|
|||
# Setup callbacks which can exclude paths from the sitemap
|
||||
app.config.define_setting :ignored_sitemap_matchers, {
|
||||
# dotfiles and folders in the root
|
||||
:root_dotfiles => proc { |file| file.match(%r{^\.}) },
|
||||
:root_dotfiles => proc { |file| file.start_with?('.') },
|
||||
|
||||
# Files starting with an dot, but not .htaccess
|
||||
:source_dotfiles => proc { |file|
|
||||
file.match(%r{/\.}) && !file.match(%r{/\.htaccess|\.htpasswd})
|
||||
file =~ %r{/\.} && file !~ %r{/\.(htaccess|htpasswd)}
|
||||
},
|
||||
|
||||
# Files starting with an underscore, but not a double-underscore
|
||||
:partials => proc { |file| file.match(%r{/_}) && !file.match(%r{/__}) },
|
||||
:partials => proc { |file| file =~ %r{/_} && file !~ %r{/__} },
|
||||
|
||||
:layout => proc { |file|
|
||||
file.match(%r{^source/layout\.}) || file.match(%r{^source/layouts/})
|
||||
file.start_with?('source/layout.') || file.start_with?('source/layouts/')
|
||||
}
|
||||
}, 'Callbacks that can exclude paths from the sitemap'
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ module Middleman
|
|||
blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] }
|
||||
|
||||
provides_metadata.inject(blank_metadata) do |result, (callback, matcher)|
|
||||
next result if !matcher.nil? && !source_file.match(matcher)
|
||||
next result if matcher && !source_file.match(matcher)
|
||||
|
||||
metadata = callback.call(source_file)
|
||||
|
||||
|
@ -149,9 +149,9 @@ module Middleman
|
|||
@_cached_metadata[request_path] = provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)|
|
||||
case matcher
|
||||
when Regexp
|
||||
next result unless request_path.match(matcher)
|
||||
next result unless request_path =~ matcher
|
||||
when String
|
||||
next result unless File.fnmatch("/" + matcher.sub(%r{^/}, ''), "/#{request_path}")
|
||||
next result unless File.fnmatch("/" + Util.strip_leading_slash(matcher), "/#{request_path}")
|
||||
end
|
||||
|
||||
metadata = callback.call(request_path)
|
||||
|
|
|
@ -10,7 +10,8 @@ require "thor"
|
|||
# Core Pathname library used for traversal
|
||||
require "pathname"
|
||||
|
||||
require "rack"
|
||||
require "tilt"
|
||||
require "rack/mime"
|
||||
|
||||
module Middleman
|
||||
|
||||
|
@ -22,11 +23,19 @@ module Middleman
|
|||
# @return [Boolean]
|
||||
def self.binary?(filename)
|
||||
ext = File.extname(filename)
|
||||
return true if ext == '.svgz'
|
||||
return false if Tilt.registered?(ext.sub('.',''))
|
||||
|
||||
ext = ".#{ext}" unless ext.to_s[0] == ?.
|
||||
mime = ::Rack::Mime.mime_type(ext, nil)
|
||||
return false unless mime
|
||||
unless mime
|
||||
binary_bytes = [0, 1, 2, 3, 4, 5, 6, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31]
|
||||
s = File.read(filename, 4096) || ''
|
||||
s.each_byte do |c|
|
||||
return true if binary_bytes.include?(c)
|
||||
end
|
||||
return false
|
||||
end
|
||||
return false if mime.start_with?('text/')
|
||||
return false if mime.include?('xml')
|
||||
return false if mime.include?('json')
|
||||
|
@ -78,7 +87,13 @@ module Middleman
|
|||
# @return [String]
|
||||
def self.normalize_path(path)
|
||||
# The tr call works around a bug in Ruby's Unicode handling
|
||||
path.sub(/^\//, "").tr('','')
|
||||
path.sub(%r{^/}, "").tr('','')
|
||||
end
|
||||
|
||||
# This is a separate method from normalize_path in case we
|
||||
# change how we normalize paths
|
||||
def self.strip_leading_slash(path)
|
||||
path.sub(%r{^/}, "")
|
||||
end
|
||||
|
||||
# Extract the text of a Rack response as a string.
|
||||
|
|
|
@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|||
s.add_dependency("rack-test", ["~> 0.6.1"])
|
||||
|
||||
# CLI
|
||||
s.add_dependency("thor", [">= 0.15.4", "~> 0.15"])
|
||||
s.add_dependency("thor", ["~> 0.15.4"])
|
||||
|
||||
# Helpers
|
||||
s.add_dependency("activesupport", ["~> 3.2.6"])
|
||||
|
|
15
middleman-core/spec/middleman-core/binary_spec.rb
Normal file
15
middleman-core/spec/middleman-core/binary_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
require 'middleman-core/util'
|
||||
|
||||
describe "Middleman::Util#binary?" do
|
||||
%w(plain.txt unicode.txt unicode stars.svgz).each do |file|
|
||||
it "recognizes #{file} as not binary" do
|
||||
Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}")).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
%w(middleman.png middleman).each do |file|
|
||||
it "recognizes #{file} as binary" do
|
||||
Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}")).should be_true
|
||||
end
|
||||
end
|
||||
end
|
BIN
middleman-core/spec/middleman-core/binary_spec/middleman
Normal file
BIN
middleman-core/spec/middleman-core/binary_spec/middleman
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
middleman-core/spec/middleman-core/binary_spec/middleman.png
Normal file
BIN
middleman-core/spec/middleman-core/binary_spec/middleman.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
1
middleman-core/spec/middleman-core/binary_spec/plain.txt
Normal file
1
middleman-core/spec/middleman-core/binary_spec/plain.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Some plain text
|
BIN
middleman-core/spec/middleman-core/binary_spec/stars.svgz
Normal file
BIN
middleman-core/spec/middleman-core/binary_spec/stars.svgz
Normal file
Binary file not shown.
1
middleman-core/spec/middleman-core/binary_spec/unicode
Normal file
1
middleman-core/spec/middleman-core/binary_spec/unicode
Normal file
|
@ -0,0 +1 @@
|
|||
明日がある。
|
|
@ -0,0 +1 @@
|
|||
明日がある。
|
|
@ -25,3 +25,18 @@ Feature: Generate mtime-based query string for busting browser caches
|
|||
When I go to "/cache-buster.html"
|
||||
Then I should see "site.css?"
|
||||
Then I should see "blank.gif?"
|
||||
|
||||
Scenario: Rendering css with the feature and relative_assets enabled
|
||||
Given "relative_assets" feature is "enabled"
|
||||
Given "cache_buster" feature is "enabled"
|
||||
And the Server is running at "cache-buster-app"
|
||||
When I go to "/stylesheets/relative_assets.css"
|
||||
Then I should see "blank.gif?"
|
||||
|
||||
Scenario: Rendering html with the feature and relative_assets enabled
|
||||
Given "relative_assets" feature is "enabled"
|
||||
Given "cache_buster" feature is "enabled"
|
||||
And the Server is running at "cache-buster-app"
|
||||
When I go to "/cache-buster.html"
|
||||
Then I should see "site.css?"
|
||||
Then I should see "blank.gif?"
|
26
middleman-more/features/helpers_form_tag.feature
Normal file
26
middleman-more/features/helpers_form_tag.feature
Normal file
|
@ -0,0 +1,26 @@
|
|||
Feature: form_tag helper
|
||||
|
||||
Scenario: form_tag produces relative links
|
||||
Given a fixture app "indexable-app"
|
||||
And an empty file named "config.rb"
|
||||
And a file named "source/form_tag.html.erb" with:
|
||||
"""
|
||||
absolute: <% form_tag "/needs_index.html#absolute", :relative => true do %>
|
||||
<% end %>
|
||||
relative: <% form_tag "needs_index.html#relative", :relative => true do %>
|
||||
<% end %>
|
||||
"""
|
||||
And a file named "source/form_tag/sub.html.erb" with:
|
||||
"""
|
||||
absolute: <% form_tag "/needs_index.html#absolute", :relative => true do %>
|
||||
<% end %>
|
||||
relative: <% form_tag "../needs_index.html#relative", :relative => true do %>
|
||||
<% end %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/form_tag.html"
|
||||
Then I should see 'action="needs_index.html#absolute"'
|
||||
Then I should see 'action="needs_index.html#relative"'
|
||||
When I go to "/form_tag/sub.html"
|
||||
Then I should see 'action="../needs_index.html#absolute"'
|
||||
Then I should see 'action="../needs_index.html#relative"'
|
152
middleman-more/features/helpers_url_for.feature
Normal file
152
middleman-more/features/helpers_url_for.feature
Normal file
|
@ -0,0 +1,152 @@
|
|||
Feature: url_for helper
|
||||
|
||||
Scenario: url_for produces relative links
|
||||
Given a fixture app "indexable-app"
|
||||
And an empty file named "config.rb"
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html", :relative => true %>
|
||||
relative: <%= url_for "needs_index.html", :relative => true %>
|
||||
"""
|
||||
And a file named "source/url_for/sub.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html", :relative => true %>
|
||||
relative: <%= url_for "../needs_index.html", :relative => true %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for.html"
|
||||
Then I should see 'absolute: needs_index.html'
|
||||
Then I should see 'relative: needs_index.html'
|
||||
When I go to "/url_for/sub.html"
|
||||
Then I should see 'absolute: ../needs_index.html'
|
||||
Then I should see 'relative: ../needs_index.html'
|
||||
|
||||
Scenario: url_for relative works with strip_index_file
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "config.rb" with:
|
||||
"""
|
||||
set :relative_links, true
|
||||
set :strip_index_file, true
|
||||
helpers do
|
||||
def menu_items(path='url_for.html')
|
||||
sitemap.find_resource_by_destination_path(path).children
|
||||
end
|
||||
end
|
||||
"""
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
<% menu_items.each do |item| %>
|
||||
"<%= url_for(item.url) %>"
|
||||
"<%= url_for(item) %>"
|
||||
<% end %>
|
||||
"""
|
||||
And a file named "source/url_for/sub.html.erb" with:
|
||||
"""
|
||||
<% menu_items.each do |item| %>
|
||||
"<%= url_for(item.url) %>"
|
||||
"<%= url_for(item) %>"
|
||||
<% end %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for.html"
|
||||
Then I should see '"url_for/sub.html"'
|
||||
Then I should not see "/url_for/sub.html"
|
||||
When I go to "/url_for/sub.html"
|
||||
Then I should see '"sub.html"'
|
||||
Then I should not see "/url_for/sub.html"
|
||||
|
||||
Scenario: url_for produces relative links when :relative_links is set to true
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "config.rb" with:
|
||||
"""
|
||||
set :relative_links, true
|
||||
"""
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html" %>
|
||||
relative: <%= url_for "needs_index.html", :relative => false %>
|
||||
unknown: <%= url_for "foo.html" %>
|
||||
"""
|
||||
And a file named "source/url_for/sub.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html" %>
|
||||
relative: <%= url_for "../needs_index.html" %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for.html"
|
||||
Then I should see 'absolute: needs_index.html'
|
||||
Then I should see 'relative: /needs_index.html'
|
||||
Then I should see 'unknown: foo.html'
|
||||
When I go to "/url_for/sub.html"
|
||||
Then I should see 'absolute: ../needs_index.html'
|
||||
Then I should see 'relative: ../needs_index.html'
|
||||
|
||||
Scenario: url_for knows about directory indexes
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html", :relative => true %>
|
||||
relative: <%= url_for "needs_index.html", :relative => true %>
|
||||
"""
|
||||
And a file named "source/url_for/sub.html.erb" with:
|
||||
"""
|
||||
absolute: <%= url_for "/needs_index.html", :relative => true %>
|
||||
relative: <%= url_for "../needs_index.html", :relative => true %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for/"
|
||||
Then I should see 'absolute: ../needs_index/'
|
||||
Then I should see 'relative: ../needs_index/'
|
||||
When I go to "/url_for/sub/"
|
||||
Then I should see 'absolute: ../../needs_index/'
|
||||
Then I should see 'relative: ../../needs_index/'
|
||||
|
||||
Scenario: url_for can take a Resource
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
"<%= url_for sitemap.find_resource_by_path("/needs_index.html") %>"
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for/"
|
||||
Then I should see '"/needs_index/"'
|
||||
|
||||
Scenario: Setting http_prefix
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "config.rb" with:
|
||||
"""
|
||||
set :http_prefix, "/foo"
|
||||
"""
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
<%= url_for "/needs_index.html" %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for.html"
|
||||
Then I should see '/foo/needs_index.html'
|
||||
|
||||
Scenario: url_for preserves query string and anchor and isn't messed up by them
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
Needs Index Anchor <%= url_for "/needs_index.html#foo" %>
|
||||
Needs Index Query <%= url_for "/needs_index.html?foo" %>
|
||||
Needs Index Query and Anchor <%= url_for "/needs_index.html?foo#foo" %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for/"
|
||||
Then I should see 'Needs Index Anchor /needs_index/#foo'
|
||||
Then I should see 'Needs Index Query /needs_index/?foo'
|
||||
Then I should see 'Needs Index Query and Anchor /needs_index/?foo#foo'
|
||||
|
||||
Scenario: url_for accepts a :query option that appends a query string
|
||||
Given a fixture app "indexable-app"
|
||||
And a file named "source/url_for.html.erb" with:
|
||||
"""
|
||||
Needs Index String <%= url_for "/needs_index.html", :query => "foo" %>
|
||||
Needs Index Hash <%= url_for "/needs_index.html", :query => { :foo => :bar } %>
|
||||
"""
|
||||
And the Server is running at "indexable-app"
|
||||
When I go to "/url_for/"
|
||||
Then I should see 'Needs Index String /needs_index/?foo'
|
||||
Then I should see 'Needs Index Hash /needs_index/?foo=bar'
|
|
@ -103,6 +103,51 @@ Feature: i18n Preview
|
|||
Then I should see "Como Esta?"
|
||||
When I go to "/spanish/hola.html"
|
||||
Then I should see "Hola World"
|
||||
|
||||
Scenario: Running localize with a non-English mount config
|
||||
Given a fixture app "i18n-test-app"
|
||||
And a file named "config.rb" with:
|
||||
"""
|
||||
activate :i18n, :mount_at_root => :es
|
||||
"""
|
||||
Given the Server is running at "i18n-test-app"
|
||||
When I go to "/en/index.html"
|
||||
Then I should see "Howdy"
|
||||
When I go to "/en/hello.html"
|
||||
Then I should see "Hello World"
|
||||
When I go to "/"
|
||||
Then I should see "Como Esta?"
|
||||
When I go to "/hola.html"
|
||||
Then I should see "Hola World"
|
||||
When I go to "/hello.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/es/index.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/es/hola.html"
|
||||
Then I should see "File Not Found"
|
||||
|
||||
Scenario: Running localize with a non-English lang subset
|
||||
Given a fixture app "i18n-test-app"
|
||||
And a file named "config.rb" with:
|
||||
"""
|
||||
activate :i18n, :langs => :es
|
||||
"""
|
||||
Given the Server is running at "i18n-test-app"
|
||||
When I go to "/en/index.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/en/hello.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/"
|
||||
Then I should see "Como Esta?"
|
||||
When I go to "/hola.html"
|
||||
Then I should see "Hola World"
|
||||
When I go to "/hello.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/es/index.html"
|
||||
Then I should see "File Not Found"
|
||||
When I go to "/es/hola.html"
|
||||
Then I should see "File Not Found"
|
||||
|
||||
|
||||
Scenario: Running localize with the no mount config
|
||||
Given a fixture app "i18n-test-app"
|
||||
|
|
|
@ -64,7 +64,7 @@ module Middleman
|
|||
# If the basename of the request as no extension, assume we are serving a
|
||||
# directory and join index_file to the path.
|
||||
path = File.join(asset_dir, current_path)
|
||||
path = path.gsub(File.extname(path), ".#{asset_ext}")
|
||||
path = path.sub(/#{File.extname(path)}$/, ".#{asset_ext}")
|
||||
|
||||
yield path if sitemap.find_resource_by_path(path)
|
||||
end
|
||||
|
@ -74,11 +74,11 @@ module Middleman
|
|||
# @return [String]
|
||||
def page_classes
|
||||
path = current_path.dup
|
||||
path << index_file if path.match(%r{/$})
|
||||
path = path.gsub(%r{^/}, '')
|
||||
path << index_file if path.end_with?('/')
|
||||
path = Util.strip_leading_slash(path)
|
||||
|
||||
classes = []
|
||||
parts = path.split('.')[0].split('/')
|
||||
parts = path.split('.').first.split('/')
|
||||
parts.each_with_index { |path, i| classes << parts.first(i+1).join('_') }
|
||||
|
||||
classes.join(' ')
|
||||
|
@ -90,22 +90,93 @@ module Middleman
|
|||
# @param [String] source The path to the file
|
||||
# @return [String]
|
||||
def asset_path(kind, source)
|
||||
return source if source =~ /^http/
|
||||
return source if source.to_s.include?('//')
|
||||
asset_folder = case kind
|
||||
when :css then css_dir
|
||||
when :js then js_dir
|
||||
when :images then images_dir
|
||||
else kind.to_s
|
||||
end
|
||||
source = source.to_s.gsub(/\s/, '')
|
||||
source = source.to_s.tr(' ', '')
|
||||
ignore_extension = (kind == :images) # don't append extension
|
||||
source << ".#{kind}" unless ignore_extension or source =~ /\.#{kind}/
|
||||
if source =~ %r{^/} # absolute path
|
||||
asset_folder = ""
|
||||
end
|
||||
source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}")
|
||||
asset_folder = "" if source.start_with?('/') # absolute path
|
||||
|
||||
asset_url(source, asset_folder)
|
||||
end
|
||||
|
||||
# Given a source path (referenced either absolutely or relatively)
|
||||
# or a Resource, this will produce the nice URL configured for that
|
||||
# path, respecting :relative_links, directory indexes, etc.
|
||||
def url_for(path_or_resource, options={})
|
||||
# Handle Resources and other things which define their own url method
|
||||
url = path_or_resource.respond_to?(:url) ? path_or_resource.url : path_or_resource
|
||||
|
||||
begin
|
||||
uri = URI(url)
|
||||
rescue URI::InvalidURIError
|
||||
# Nothing we can do with it, it's not really a URI
|
||||
return url
|
||||
end
|
||||
|
||||
relative = options.delete(:relative)
|
||||
raise "Can't use the relative option with an external URL" if relative && uri.host
|
||||
|
||||
# Allow people to turn on relative paths for all links with
|
||||
# set :relative_links, true
|
||||
# but still override on a case by case basis with the :relative parameter.
|
||||
effective_relative = relative || false
|
||||
effective_relative = true if relative.nil? && config[:relative_links]
|
||||
|
||||
# Try to find a sitemap resource corresponding to the desired path
|
||||
this_resource = current_resource # store in a local var to save work
|
||||
if path_or_resource.is_a?(Sitemap::Resource)
|
||||
resource = path_or_resource
|
||||
resource_url = url
|
||||
elsif this_resource && uri.path
|
||||
# Handle relative urls
|
||||
url_path = Pathname(uri.path)
|
||||
current_source_dir = Pathname('/' + this_resource.path).dirname
|
||||
url_path = current_source_dir.join(url_path) if url_path.relative?
|
||||
resource = sitemap.find_resource_by_path(url_path.to_s)
|
||||
resource_url = resource.url if resource
|
||||
end
|
||||
|
||||
if resource
|
||||
# Switch to the relative path between this_resource and the given resource
|
||||
# if we've been asked to.
|
||||
if effective_relative
|
||||
# Output urls relative to the destination path, not the source path
|
||||
current_dir = Pathname('/' + this_resource.destination_path).dirname
|
||||
relative_path = Pathname(resource_url).relative_path_from(current_dir).to_s
|
||||
|
||||
# Put back the trailing slash to avoid unnecessary Apache redirects
|
||||
if resource_url.end_with?('/') && !relative_path.end_with?('/')
|
||||
relative_path << '/'
|
||||
end
|
||||
|
||||
uri.path = relative_path
|
||||
else
|
||||
uri.path = resource_url
|
||||
end
|
||||
else
|
||||
# If they explicitly asked for relative links but we can't find a resource...
|
||||
raise "No resource exists at #{url}" if relative
|
||||
end
|
||||
|
||||
# Support a :query option that can be a string or hash
|
||||
if query = options.delete(:query)
|
||||
uri.query = query.respond_to?(:to_param) ? query.to_param : query.to_s
|
||||
end
|
||||
|
||||
# Support a :fragment or :anchor option just like Padrino
|
||||
fragment = options.delete(:anchor) || options.delete(:fragment)
|
||||
uri.fragment = fragment.to_s if fragment
|
||||
|
||||
# Finally make the URL back into a string
|
||||
uri.to_s
|
||||
end
|
||||
|
||||
# Overload the regular link_to to be sitemap-aware - if you
|
||||
# reference a source path, either absolutely or relatively,
|
||||
# you'll get that resource's nice URL. Also, there is a
|
||||
|
@ -123,75 +194,27 @@ module Middleman
|
|||
url_arg_index = block_given? ? 0 : 1
|
||||
options_index = block_given? ? 1 : 2
|
||||
|
||||
if block_given? && args.size > 2
|
||||
raise ArgumentError.new("Too many arguments to link_to(url, options={}, &block)")
|
||||
end
|
||||
|
||||
if url = args[url_arg_index]
|
||||
options = args[options_index] || {}
|
||||
relative = options.delete(:relative)
|
||||
|
||||
# Handle Resources, which define their own url method
|
||||
if url.respond_to? :url
|
||||
url = args[url_arg_index] = url.url
|
||||
end
|
||||
|
||||
if url.include? '://'
|
||||
raise "Can't use the relative option with an external URL" if relative
|
||||
elsif current_resource
|
||||
# Handle relative urls
|
||||
current_source_dir = Pathname('/' + current_resource.path).dirname
|
||||
|
||||
begin
|
||||
uri = URI(url)
|
||||
url_path = uri.path
|
||||
rescue
|
||||
end
|
||||
|
||||
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_path)
|
||||
|
||||
# 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.
|
||||
effective_relative = relative || false
|
||||
if relative.nil? && config[:relative_links]
|
||||
effective_relative = true
|
||||
end
|
||||
|
||||
if resource
|
||||
if effective_relative
|
||||
resource_url = resource.url
|
||||
|
||||
# Output urls relative to the destination path, not the source path
|
||||
current_dir = Pathname('/' + current_resource.destination_path).dirname
|
||||
new_url = Pathname(resource_url).relative_path_from(current_dir).to_s
|
||||
|
||||
# Put back the trailing slash to avoid unnecessary Apache redirects
|
||||
if resource_url.end_with?('/') && !new_url.end_with?('/')
|
||||
new_url << '/'
|
||||
end
|
||||
else
|
||||
new_url = resource.url
|
||||
end
|
||||
|
||||
uri.path = new_url
|
||||
|
||||
args[url_arg_index] = uri.to_s
|
||||
else
|
||||
raise "No resource exists at #{url}" if relative
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Support a :query option that can be a string or hash
|
||||
if query = options.delete(: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
|
||||
raise ArgumentError.new("Options must be a hash") unless options.is_a?(Hash)
|
||||
|
||||
# Transform the url through our magic url_for method
|
||||
args[url_arg_index] = url_for(url, options)
|
||||
end
|
||||
|
||||
super(*args, &block)
|
||||
end
|
||||
|
||||
# Modified Padrino form_for that uses Middleman's url_for
|
||||
# to transform the URL.
|
||||
def form_tag(url, options={}, &block)
|
||||
url = url_for(url, options)
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,6 +28,7 @@ module Middleman
|
|||
@app = app
|
||||
@locales_glob = File.join(app.locales_dir, "**", "*.{rb,yml,yaml}")
|
||||
|
||||
# File.fnmatch doesn't support brackets: {rb,yml,yaml}
|
||||
regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml")
|
||||
@locales_regex = %r{^#{regex}}
|
||||
|
||||
|
@ -43,7 +44,7 @@ module Middleman
|
|||
@mount_at_root = @options.has_key?(:mount_at_root) ? @options[:mount_at_root] : langs.first
|
||||
|
||||
if !@app.build?
|
||||
logger.info "== Locales: #{langs.join(", ")}"
|
||||
logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})"
|
||||
end
|
||||
|
||||
# Don't output localizable files
|
||||
|
@ -52,15 +53,20 @@ module Middleman
|
|||
@app.sitemap.provides_metadata_for_path do |url|
|
||||
if d = get_localization_data(url)
|
||||
lang, page_id = d
|
||||
instance_vars = Proc.new {
|
||||
::I18n.locale = lang
|
||||
@lang = lang
|
||||
@page_id = page_id
|
||||
}
|
||||
{ :blocks => [instance_vars] }
|
||||
else
|
||||
{}
|
||||
# Default to the @mount_at_root lang
|
||||
page_id = nil
|
||||
lang = @mount_at_root
|
||||
end
|
||||
|
||||
instance_vars = Proc.new do
|
||||
::I18n.locale = lang
|
||||
@lang = lang
|
||||
@page_id = page_id
|
||||
end
|
||||
|
||||
locals = { :lang => lang, :page_id => page_id }
|
||||
{ :blocks => [instance_vars], :locals => locals }
|
||||
end
|
||||
|
||||
@app.sitemap.register_resource_list_manipulator(
|
||||
|
@ -73,13 +79,15 @@ module Middleman
|
|||
end
|
||||
|
||||
def on_file_changed(file)
|
||||
if @locales_regex.match(file)
|
||||
if @locales_regex =~ file
|
||||
::I18n.reload!
|
||||
end
|
||||
end
|
||||
|
||||
def langs
|
||||
@options[:langs] || begin
|
||||
if @options[:langs]
|
||||
Array(@options[:langs]).map(&:to_sym)
|
||||
else
|
||||
Dir[File.join(@app.root, @locales_glob)].map { |file|
|
||||
File.basename(file).sub(/\.ya?ml$/, "").sub(/\.rb$/, "")
|
||||
}.sort.map(&:to_sym)
|
||||
|
|
|
@ -38,7 +38,7 @@ module Middleman
|
|||
params[:alt] ||= ""
|
||||
|
||||
real_path = path
|
||||
real_path = File.join(images_dir, real_path) unless real_path =~ %r{^/}
|
||||
real_path = File.join(images_dir, real_path) unless real_path.start_with?('/')
|
||||
full_path = File.join(source_dir, real_path)
|
||||
|
||||
if File.exists?(full_path)
|
||||
|
|
|
@ -36,7 +36,7 @@ module Middleman
|
|||
path
|
||||
else
|
||||
current_dir = Pathname('/' + current_resource.destination_path)
|
||||
Pathname(path).relative_path_from(current_dir.dirname)
|
||||
Pathname(path).relative_path_from(current_dir.dirname).to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
2
vendor.yml
Normal file
2
vendor.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
- fixtures
|
||||
- templates
|
Loading…
Reference in a new issue