From 83c8f9a2ce526a113db18074378f78ef71000b22 Mon Sep 17 00:00:00 2001 From: Egor Date: Sat, 2 Feb 2013 00:26:58 +0400 Subject: [PATCH 01/22] Fix huge files regression (for undetected mime) Note that binary_bytes is an array of bytes that never never appears in text. Array taken from encoding.c source from 'file' utility (http://www.darwinsys.com/file/). --- middleman-core/lib/middleman-core/util.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 46854994..fad57ca3 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -24,7 +24,14 @@ module Middleman 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, File.stat(filename).blksize) || '' + 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') From 4e884144784eac4930992fe7b47ac65cc2ed2cea Mon Sep 17 00:00:00 2001 From: Egor Vakhromtsev Date: Wed, 6 Feb 2013 12:14:24 +0400 Subject: [PATCH 02/22] blksize was replaced with fixed value because windows issues --- middleman-core/lib/middleman-core/util.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index fad57ca3..0444be7a 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -26,7 +26,7 @@ module Middleman mime = ::Rack::Mime.mime_type(ext, nil) 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, File.stat(filename).blksize) || '' + s = File.read(filename, 4096) || '' s.each_byte do |c| return true if binary_bytes.include?(c) end From c9290c6b11d1c0164ce516e092a2a8b7bb1fad8b Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 6 Feb 2013 13:19:09 -0800 Subject: [PATCH 03/22] Allow frontmatter to be parsed on templates outside the project root --- .../middleman-core/core_extensions/front_matter.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb index cf64f37a..366cb0d7 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -1,3 +1,5 @@ +require 'pathname' + # Extensions namespace module Middleman::CoreExtensions @@ -128,7 +130,12 @@ module Middleman::CoreExtensions # @param [String] path # @return [Array] 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 @@ -156,7 +163,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 From de7e62176600dafcc54c69d3b18e76e1ee8988e1 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 8 Feb 2013 00:05:34 -0800 Subject: [PATCH 04/22] Revert the more-flexible Thor dependency since it breaks bundle install for JRuby and we will need to update Padrino when it gets upgraded anyway --- middleman-core/middleman-core-x86-mingw32.gemspec | 2 +- middleman-core/middleman-core.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/middleman-core-x86-mingw32.gemspec b/middleman-core/middleman-core-x86-mingw32.gemspec index 1ec32454..c91e80c9 100644 --- a/middleman-core/middleman-core-x86-mingw32.gemspec +++ b/middleman-core/middleman-core-x86-mingw32.gemspec @@ -27,7 +27,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"]) diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 4eb1aed0..f268f2f5 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -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"]) From 1af96fe305d95930f3728b1091d8cae45373e130 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 10:28:55 -0800 Subject: [PATCH 05/22] Fix gemspecs --- middleman-core/middleman-core-x86-mingw32.gemspec | 2 +- middleman-core/middleman-core.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/middleman-core-x86-mingw32.gemspec b/middleman-core/middleman-core-x86-mingw32.gemspec index c91e80c9..d1779828 100644 --- a/middleman-core/middleman-core-x86-mingw32.gemspec +++ b/middleman-core/middleman-core-x86-mingw32.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.add_dependency("rack-test", ["~> 0.6.1"]) # CLI - s.add_dependency("thor", [">~ 0.15.4"]) + s.add_dependency("thor", ["~> 0.15.4"]) # Helpers s.add_dependency("activesupport", ["~> 3.2.6"]) diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index f268f2f5..c366daa3 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -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"]) + s.add_dependency("thor", ["~> 0.15.4"]) # Helpers s.add_dependency("activesupport", ["~> 3.2.6"]) From 7020bdce1a0db4152e19b7284c9e0e3fe1df7555 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 12:44:37 -0800 Subject: [PATCH 06/22] Failing test for #584 "i18n fails when default locale is not english" --- middleman-more/features/i18n_preview.feature | 45 ++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/middleman-more/features/i18n_preview.feature b/middleman-more/features/i18n_preview.feature index 81360e23..bfc591ef 100644 --- a/middleman-more/features/i18n_preview.feature +++ b/middleman-more/features/i18n_preview.feature @@ -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" From afc62d5a26cf362751edbdff040288ad203283d7 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 12:34:30 -0800 Subject: [PATCH 07/22] i18n tweaks --- middleman-more/lib/middleman-more/core_extensions/i18n.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/middleman-more/lib/middleman-more/core_extensions/i18n.rb b/middleman-more/lib/middleman-more/core_extensions/i18n.rb index 534f4ad8..4f84b2b8 100644 --- a/middleman-more/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-more/lib/middleman-more/core_extensions/i18n.rb @@ -43,7 +43,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 @@ -79,7 +79,9 @@ module Middleman 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(/\.yml$/, "").sub(/\.rb$/, "") }.sort.map(&:to_sym) From fbc4d7e9c7ded08266bcc192efe5f58ad6c10ba6 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 12:40:43 -0800 Subject: [PATCH 08/22] Handle non-english default languages. Fixes #584 --- .../middleman-more/core_extensions/i18n.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/middleman-more/lib/middleman-more/core_extensions/i18n.rb b/middleman-more/lib/middleman-more/core_extensions/i18n.rb index 4f84b2b8..57eee442 100644 --- a/middleman-more/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-more/lib/middleman-more/core_extensions/i18n.rb @@ -52,15 +52,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( From 0f2dc821381000462419c46e848669e4a4e8d41b Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 15:12:35 -0800 Subject: [PATCH 09/22] Add vendor.yml to exclude our fixtures from GitHub language stats --- vendor.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 vendor.yml diff --git a/vendor.yml b/vendor.yml new file mode 100644 index 00000000..417247e2 --- /dev/null +++ b/vendor.yml @@ -0,0 +1,2 @@ +- fixtures +- templates From ed119bed7ba118e7404ee5385f7c9890d2f9cf52 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 10:15:25 -0800 Subject: [PATCH 10/22] Support .yaml files for i18n --- middleman-more/lib/middleman-more/core_extensions/i18n.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/middleman-more/lib/middleman-more/core_extensions/i18n.rb b/middleman-more/lib/middleman-more/core_extensions/i18n.rb index 57eee442..e4d5c696 100644 --- a/middleman-more/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-more/lib/middleman-more/core_extensions/i18n.rb @@ -26,9 +26,9 @@ module Middleman def initialize(app, options={}) @app = app - @locales_glob = File.join(app.locales_dir, "**", "*.{rb,yml}") + @locales_glob = File.join(app.locales_dir, "**", "*.{rb,yml,yaml}") - regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml}", "rb|yml") + regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml") @locales_regex = %r{^#{regex}} @maps = {} @@ -88,7 +88,7 @@ module Middleman Array(@options[:langs]).map(&:to_sym) else Dir[File.join(@app.root, @locales_glob)].map { |file| - File.basename(file).sub(/\.yml$/, "").sub(/\.rb$/, "") + File.basename(file).sub(/\.ya?ml$/, "").sub(/\.rb$/, "") }.sort.map(&:to_sym) end end From 923697b5178a5ddf456327188a6361f82a029802 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 00:20:37 -0800 Subject: [PATCH 11/22] Micro-optimizations around string comparisons --- .../lib/middleman-core/cli/build.rb | 2 +- .../middleman-core/core_extensions/data.rb | 4 ++-- .../core_extensions/file_watcher.rb | 3 ++- .../core_extensions/rendering.rb | 2 +- .../lib/middleman-core/preview_server.rb | 2 +- middleman-core/lib/middleman-core/sitemap.rb | 8 ++++---- .../lib/middleman-core/sitemap/store.rb | 6 +++--- middleman-core/lib/middleman-core/util.rb | 8 +++++++- .../core_extensions/default_helpers.rb | 19 +++++++++---------- .../middleman-more/core_extensions/i18n.rb | 3 ++- .../extensions/automatic_image_sizes.rb | 2 +- 11 files changed, 33 insertions(+), 26 deletions(-) diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 0e08dbdc..26680123 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -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 diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 360d953f..22f91778 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -25,11 +25,11 @@ module Middleman # parsing config.rb def initialize self.files.changed DataStore.matcher do |file| - self.data.touch_file(file) if file.match(%r{^#{self.data_dir}\/}) + self.data.touch_file(file) if file.start_with?("#{self.data_dir}/") end self.files.deleted DataStore.matcher do |file| - self.data.remove_file(file) if file.match(%r{^#{self.data_dir}\/}) + self.data.remove_file(file) if file.start_with?("#{self.data_dir}/") end super diff --git a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb index 44eb2e31..14c5b214 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -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 diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 83c5d737..f700e329 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -408,7 +408,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 diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 5f53c5ed..6308f4f2 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -185,7 +185,7 @@ module Middleman paths.any? do |path| match_against.any? do |matcher| - path.match(matcher) + path =~ matcher end end end diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index b50652b9..b3c75568 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -25,18 +25,18 @@ module Middleman # Setup callbacks which can exclude paths from the sitemap app.set :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/') } } diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index eb78088c..30f59789 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -108,7 +108,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) @@ -146,9 +146,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) diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 0444be7a..00a28e2b 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -83,7 +83,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. diff --git a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb index 4b30967c..80233244 100644 --- a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb @@ -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,19 +90,18 @@ 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 diff --git a/middleman-more/lib/middleman-more/core_extensions/i18n.rb b/middleman-more/lib/middleman-more/core_extensions/i18n.rb index e4d5c696..1ab2c019 100644 --- a/middleman-more/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-more/lib/middleman-more/core_extensions/i18n.rb @@ -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} regex = @locales_glob.sub(/\./, '\.').sub(File.join("**", "*"), ".*").sub(/\//, '\/').sub("{rb,yml,yaml}", "rb|ya?ml") @locales_regex = %r{^#{regex}} @@ -78,7 +79,7 @@ module Middleman end def on_file_changed(file) - if @locales_regex.match(file) + if @locales_regex =~ file ::I18n.reload! end end diff --git a/middleman-more/lib/middleman-more/extensions/automatic_image_sizes.rb b/middleman-more/lib/middleman-more/extensions/automatic_image_sizes.rb index 58e52f71..a83ca4cc 100644 --- a/middleman-more/lib/middleman-more/extensions/automatic_image_sizes.rb +++ b/middleman-more/lib/middleman-more/extensions/automatic_image_sizes.rb @@ -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 From 559265140d0f2cdb41d7ee9cc75c6cce9f49d66d Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 27 Oct 2012 11:47:06 -0700 Subject: [PATCH 12/22] Stub out rspec tests for public APIs: Rack and Sitemap for now --- gem_rake_helper.rb | 23 +++++++++++++++++-- .../spec/middleman-core/sitemap_spec.rb | 0 middleman-core/spec/spec_helper.rb | 0 .../spec/middleman-more/future_spec.rb | 0 middleman-more/spec/spec_helper.rb | 0 middleman/spec/middleman/future_spec.rb | 0 middleman/spec/spec_helper.rb | 0 7 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 middleman-core/spec/middleman-core/sitemap_spec.rb create mode 100644 middleman-core/spec/spec_helper.rb create mode 100644 middleman-more/spec/middleman-more/future_spec.rb create mode 100644 middleman-more/spec/spec_helper.rb create mode 100644 middleman/spec/middleman/future_spec.rb create mode 100644 middleman/spec/spec_helper.rb diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index 6353f05b..f9585479 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -1,6 +1,5 @@ require 'rubygems' unless defined?(Gem) require 'rake' -require 'cucumber/rake/task' require 'yard' require 'bundler' @@ -16,7 +15,9 @@ class Bundler::GemHelper end end -Cucumber::Rake::Task.new(:test, 'Run features that should pass') do |t| +require 'cucumber/rake/task' + +Cucumber::Rake::Task.new do |t| exempt_tags = ["--tags ~@wip"] exempt_tags << "--tags ~@nojava" if RUBY_PLATFORM == "java" exempt_tags << "--tags ~@encoding" unless Object.const_defined?(:Encoding) @@ -25,6 +26,24 @@ Cucumber::Rake::Task.new(:test, 'Run features that should pass') do |t| t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" end +Cucumber::Rake::Task.new(:cucumber_wip) do |t| + exempt_tags = ["--tags @wip"] + exempt_tags << "--tags ~@nojava" if RUBY_PLATFORM == "java" + exempt_tags << "--tags ~@encoding" unless Object.const_defined?(:Encoding) + + t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" +end + +require 'rspec/core/rake_task' +desc "Run RSpec" +RSpec::Core::RakeTask.new do |spec| + spec.pattern = 'spec/**/*_spec.rb' + spec.rspec_opts = ['--color', '--format nested'] +end + +desc "Run tests, both RSpec and Cucumber" +task :test => [:spec, :cucumber] + YARD::Rake::YardocTask.new task :default => :test diff --git a/middleman-core/spec/middleman-core/sitemap_spec.rb b/middleman-core/spec/middleman-core/sitemap_spec.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/spec/spec_helper.rb b/middleman-core/spec/spec_helper.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman-more/spec/middleman-more/future_spec.rb b/middleman-more/spec/middleman-more/future_spec.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman-more/spec/spec_helper.rb b/middleman-more/spec/spec_helper.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman/spec/middleman/future_spec.rb b/middleman/spec/middleman/future_spec.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman/spec/spec_helper.rb b/middleman/spec/spec_helper.rb new file mode 100644 index 00000000..e69de29b From 76d09a49649378e65e041c0761e69f054c943d3d Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 9 Feb 2013 15:37:08 -0800 Subject: [PATCH 13/22] Pathname issues when combining relative assets and cache buster --- middleman-more/lib/middleman-more/extensions/relative_assets.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-more/lib/middleman-more/extensions/relative_assets.rb b/middleman-more/lib/middleman-more/extensions/relative_assets.rb index 7e457cd4..0bb0a777 100644 --- a/middleman-more/lib/middleman-more/extensions/relative_assets.rb +++ b/middleman-more/lib/middleman-more/extensions/relative_assets.rb @@ -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 From 700b844e67ac8df69728910aae5aca7478984f44 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 9 Feb 2013 15:45:45 -0800 Subject: [PATCH 14/22] Add a spec for testing Middleman::Util#binary? --- Rakefile | 9 ++++++++- middleman-core/lib/middleman-core/util.rb | 3 +++ .../spec/middleman-core/binary_spec.rb | 15 +++++++++++++++ .../spec/middleman-core/binary_spec/middleman | Bin 0 -> 25282 bytes .../middleman-core/binary_spec/middleman.png | Bin 0 -> 25282 bytes .../spec/middleman-core/binary_spec/plain.txt | 1 + .../spec/middleman-core/binary_spec/stars.svgz | Bin 0 -> 33861 bytes .../spec/middleman-core/binary_spec/unicode | 1 + .../spec/middleman-core/binary_spec/unicode.txt | 1 + 9 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 middleman-core/spec/middleman-core/binary_spec.rb create mode 100644 middleman-core/spec/middleman-core/binary_spec/middleman create mode 100644 middleman-core/spec/middleman-core/binary_spec/middleman.png create mode 100644 middleman-core/spec/middleman-core/binary_spec/plain.txt create mode 100644 middleman-core/spec/middleman-core/binary_spec/stars.svgz create mode 100644 middleman-core/spec/middleman-core/binary_spec/unicode create mode 100644 middleman-core/spec/middleman-core/binary_spec/unicode.txt diff --git a/Rakefile b/Rakefile index 630c02ff..1801ea15 100644 --- a/Rakefile +++ b/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 \ No newline at end of file +task :default => :test diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 00a28e2b..0bee9661 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -10,6 +10,9 @@ require "thor" # Core Pathname library used for traversal require "pathname" +require "tilt" +require "rack/mime" + module Middleman module Util diff --git a/middleman-core/spec/middleman-core/binary_spec.rb b/middleman-core/spec/middleman-core/binary_spec.rb new file mode 100644 index 00000000..ad04efb7 --- /dev/null +++ b/middleman-core/spec/middleman-core/binary_spec.rb @@ -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 diff --git a/middleman-core/spec/middleman-core/binary_spec/middleman b/middleman-core/spec/middleman-core/binary_spec/middleman new file mode 100644 index 0000000000000000000000000000000000000000..c685e564378b038c44e51ec98454af7237d3412a GIT binary patch literal 25282 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 L44{=7_7VRBi!LVk literal 0 HcmV?d00001 diff --git a/middleman-core/spec/middleman-core/binary_spec/middleman.png b/middleman-core/spec/middleman-core/binary_spec/middleman.png new file mode 100644 index 0000000000000000000000000000000000000000..c685e564378b038c44e51ec98454af7237d3412a GIT binary patch literal 25282 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 L44{=7_7VRBi!LVk literal 0 HcmV?d00001 diff --git a/middleman-core/spec/middleman-core/binary_spec/plain.txt b/middleman-core/spec/middleman-core/binary_spec/plain.txt new file mode 100644 index 00000000..649adbeb --- /dev/null +++ b/middleman-core/spec/middleman-core/binary_spec/plain.txt @@ -0,0 +1 @@ +Some plain text diff --git a/middleman-core/spec/middleman-core/binary_spec/stars.svgz b/middleman-core/spec/middleman-core/binary_spec/stars.svgz new file mode 100644 index 0000000000000000000000000000000000000000..a54ce7ff12235e21ea2452f9dcb8ad0bd5d291b7 GIT binary patch literal 33861 zcmV(_K-9kU-}Ng_MlVv;!I{2a zhGJYXrMO%rCoW5N;zw|R;UJm;SQwB)>euI6eSohPmh+Xqu>4W z7vKETxBvd^$G`viyYA}si|)^V{r&fUeAXRJj*tJtKRZ7D_Q!9#AO7}-&KYA(HR1U9 zyMH_S;^=&{d3kbte0_aAT>D|QesTQcUyk+7@n61sHle}frU5-1)3Y_hY%@F3c#}!@ zY(1ZD=Ckg4u{rPlxcuqrboz4MeRZeX#kR0@{&hE*(2{Px=(=t(dwQfEkMxf#*7uVC zo!l(k4BoY>T^IMN>gnsNR(rjeZO)$_IcqL2TfzB!@#1_#NzL1mo4#kO)8+IMlVQH~ z)xh9C?|txmdc_CF=c~*4@$8tfk9XrAU!70a^W*uO>E+9d`8YaTwY++Iz>e6>$X>T! zo$UI#_xU~hXmVFCr>FC)n?dii-_7!-{jOlRTD@AI&d=y#J}l>(aj&+OlX1gtyLod# z--o7bYputvmhJ7jZ)WqeD>WN;O8@e$f+{|mPuG7~PiKqyax;E(XQNJ67Z>wW_F#H( zJ$*Y`YS+*Grmlotr*wO@S-sqS%dTwRUbMYhy`0eFYJKwM+@h_i zf1VuOwq2c_UClT0lx^jmy5@KEz}VraJAVJs%USd>eZc7U-J{2w(Z4yqZsJ@^llklU zay6S_&-Lo3`N@}CJC6UHv~w-C!!~W{gH=hBJSXRD&C{bV56F|dJA8i#s?$yN=^Jfqe8~8xZx0r)Rhpv< zHMww8dUm*vv-^FF%m3zBlC1r@wG;w!_IfeDzSV8gv)hhdPG8KMlwqA`?a#L2`D#6z zuXk0c{kd1QRXbxe^2L3#s@I!(bGRPmJX>9($sbn!yjtP1U{NeCo4vNOsmpH2CEsks zZ6)Ky6v3eA_A0LzOGcb*qXX+wdE|>-xKQh3UuaJrsnUvf+i`m!Z?;2DI|duu_6MhbsW<@91Kc|Bb(rpwK}vgQ(3pS-#N1`w;u*?f65pFP>i*4+S{ zeH64mJF}-F-0n229P!Ra?+*~+M*Q9ZW$bhE{MBZ&2h^8~&3wHpZU4Af@PGTg%%)f8 zql7*&59{`I_Xq(aGVNp4w&Zd#yZ7(;a{KRQz_aP);^OVe?-v`Ha(dbQZN8p%KLDvu zF6Nt!depGX7kB2fnZMagrpwcFOx(tMa=l(`_-1kmT%BC3cQAP)RFXY<;2&3unLsT) zESK9y2Yx13_8Q6Uy{A%#;$h|5worJ;Ddn

7E|t06$yn_A00A7q&&#$z^NO-khj+ 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�Is=tD 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 literal 0 HcmV?d00001 diff --git a/middleman-core/spec/middleman-core/binary_spec/unicode b/middleman-core/spec/middleman-core/binary_spec/unicode new file mode 100644 index 00000000..13dc1361 --- /dev/null +++ b/middleman-core/spec/middleman-core/binary_spec/unicode @@ -0,0 +1 @@ +明日がある。 diff --git a/middleman-core/spec/middleman-core/binary_spec/unicode.txt b/middleman-core/spec/middleman-core/binary_spec/unicode.txt new file mode 100644 index 00000000..13dc1361 --- /dev/null +++ b/middleman-core/spec/middleman-core/binary_spec/unicode.txt @@ -0,0 +1 @@ +明日がある。 From ae7f75e5cc860b3555c384d8da20dad0ed572977 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 9 Feb 2013 15:53:21 -0800 Subject: [PATCH 15/22] Relative Assets shouldn't return a Pathname sometimes, the rest of the code expects Strings --- middleman-more/features/cache_buster.feature | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/middleman-more/features/cache_buster.feature b/middleman-more/features/cache_buster.feature index 7c094f7f..11040ba5 100644 --- a/middleman-more/features/cache_buster.feature +++ b/middleman-more/features/cache_buster.feature @@ -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?" \ No newline at end of file From b94be9ed932d8669b54bb4d6ac6fd523c60bf7bb Mon Sep 17 00:00:00 2001 From: Jon Rowe Date: Sun, 10 Feb 2013 21:49:32 +1100 Subject: [PATCH 16/22] Removed outdated information. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems the wiki is no longer publicly accessible. Linking to it confuses people. --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 61866dc9..e7cc690d 100644 --- a/README.md +++ b/README.md @@ -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 From 3bdbc11db29c8ef88eaebf5f91274e90748761eb Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 10 Feb 2013 12:05:07 -0800 Subject: [PATCH 17/22] Change the behavior of before_render and after_render hooks from #761. This changes the before_render and after_render hooks so that the callbacks given to them each get to modify the template source / the rendered output in turn, instead of having to modify them in-place. It also changes the arguments provided to the callbacks - now, they are given the source/output, the template path, the locals hash, and the Tilt template *class*, wheras previously they were given the source/output and the Tilt template *instance*. The locals hash is there in case pron case hooks want to pay attention to the locals in some way. The before_render hook is also run before compiling the template and caching it, which should prevent weird data mismatches and save some template compilation effort. --- .../middleman-core/core_extensions/rendering.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index f700e329..f61079ef 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -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 From 6fa6c021c00195ebe8655c5ec89d2364d1e61dff Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 8 Feb 2013 22:22:33 -0800 Subject: [PATCH 18/22] Refactor out a url_for method --- .../core_extensions/default_helpers.rb | 138 ++++++++++-------- 1 file changed, 75 insertions(+), 63 deletions(-) diff --git a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb index 80233244..6ecedcf0 100644 --- a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb @@ -105,6 +105,78 @@ module Middleman 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? && 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 @@ -124,69 +196,9 @@ module Middleman 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? && 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 + + # Transform the url through our magic url_for method + args[url_arg_index] = url_for(url, options) end super(*args, &block) From ba035882fe1baad59e548ddec181e68b37cd8bfb Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 8 Feb 2013 22:40:27 -0800 Subject: [PATCH 19/22] Test for url_for --- .../features/helpers_url_for.feature | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 middleman-more/features/helpers_url_for.feature diff --git a/middleman-more/features/helpers_url_for.feature b/middleman-more/features/helpers_url_for.feature new file mode 100644 index 00000000..c2b5a5a8 --- /dev/null +++ b/middleman-more/features/helpers_url_for.feature @@ -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' From 3a3d5bbe3b2a4bae065e8504c360571bf5c5ff77 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 8 Feb 2013 23:00:29 -0800 Subject: [PATCH 20/22] Override form_tag to use url_for. Fixes #739 --- .../features/helpers_form_tag.feature | 26 +++++++++++++++++++ .../core_extensions/default_helpers.rb | 7 +++++ 2 files changed, 33 insertions(+) create mode 100644 middleman-more/features/helpers_form_tag.feature diff --git a/middleman-more/features/helpers_form_tag.feature b/middleman-more/features/helpers_form_tag.feature new file mode 100644 index 00000000..643ca18a --- /dev/null +++ b/middleman-more/features/helpers_form_tag.feature @@ -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"' diff --git a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb index 6ecedcf0..e980b922 100644 --- a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb @@ -203,6 +203,13 @@ module Middleman 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 From 42320ade8dfa641021653f82aa008a756343150a Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Wed, 6 Feb 2013 00:26:21 -0800 Subject: [PATCH 21/22] Force svgz to be binary --- middleman-core/lib/middleman-core/util.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 0bee9661..710b86ca 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -23,6 +23,7 @@ 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] == ?. From e4b52022380690c1b1c70068c106b3cca93964eb Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Wed, 6 Feb 2013 00:16:30 -0800 Subject: [PATCH 22/22] Provide some helpful error messages when link_to is used improperly --- .../lib/middleman-more/core_extensions/default_helpers.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb index e980b922..2da4d171 100644 --- a/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-more/lib/middleman-more/core_extensions/default_helpers.rb @@ -194,8 +194,13 @@ 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] || {} + 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)