diff --git a/.rubocop.yml b/.rubocop.yml index 3675ec84..d4422e88 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -41,6 +41,8 @@ AssignmentInCondition: Enabled: false CyclomaticComplexity: Enabled: false +AbcSize: + Enabled: false HandleExceptions: Enabled: false EndAlignment: diff --git a/.travis.yml b/.travis.yml index 44cda8d5..eac90f61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,10 @@ before_install: git submodule update --init --recursive rvm: - ruby-head - jruby-19mode + - 2.2 + - 2.1.5 + - 2.1.4 + - 2.1.3 - 2.1.2 - 2.1.1 - 2.1.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 80b28be1..70d2f7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,23 @@ master * Remove old module-style extension support * Placed all `config.rb` evaluation inside the `ConfigContext` class +3.3.7 +=== +* Update new project template Gemfile to use HTTPS by default. #1372 + +3.3.6 +=== + +* Use full paths instead of relative for `listen` gem. Fixes #1374 +* Add force option to "middleman init". #1369 +* Configuration addition for compass 1 compatibility. +* Catch File read exceptions in frontmatter. +* Remove duplicate attr_accessor. Closes #1352 +* Update sass dependency to >= 3.4.0. +* Update compass dependency to >= 1.0.0, < 2.0.0 +* Accept pandoc-style YAML frontmatter. #1350 +* Add webp to image type lists. + 3.3.5 === diff --git a/Rakefile b/Rakefile index 892dc444..b06742fc 100644 --- a/Rakefile +++ b/Rakefile @@ -43,6 +43,8 @@ end desc 'Run tests for all middleman gems' task :test do + Rake::Task['rubocop'].invoke + GEM_PATHS.each do |g| Dir.chdir("#{File.join(ROOT, g)}") { sh "#{Gem.ruby} -S rake test" } end diff --git a/middleman-cli/lib/middleman-cli/templates/extension/Gemfile b/middleman-cli/lib/middleman-cli/templates/extension/Gemfile index 1acd5814..81495fe1 100644 --- a/middleman-cli/lib/middleman-cli/templates/extension/Gemfile +++ b/middleman-cli/lib/middleman-cli/templates/extension/Gemfile @@ -1,6 +1,6 @@ -# If you have OpenSSL installed, we recommend updating -# the following line to use "https" -source 'http://rubygems.org' +# If you do not have OpenSSL installed, update +# the following line to use "http://" instead +source 'https://rubygems.org' # Specify your gem's dependencies in <%= name %>.gemspec gemspec diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 3c39f833..a8853358 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -1,5 +1,5 @@ Feature: Assets get a file hash appended to their and references to them are updated - Scenario: Hashed-asset files are produced, and HTML, CSS, and JavaScript gets rewritten to reference the new files + Scenario: Hashed-asset files are produced, and HTML, CSS, JSON and JavaScript gets rewritten to reference the new files Given a successfully built app at "asset-hash-app" When I cd to "build" Then the following files should exist: @@ -8,12 +8,16 @@ Feature: Assets get a file hash appended to their and references to them are upd | favicon.ico | | images/100px-1242c368.png | | images/100px-5fd6fb90.jpg | + | images/200px-c11eb203.jpg | + | images/300px-59adce76.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | | stylesheets/site-7474cadd.css | | index.html | | subdir/index.html | | other/index.html | + | api.json | + | subdir/api.json | And the following files should not exist: | images/100px.png | | images/100px.jpg | @@ -31,11 +35,20 @@ Feature: Assets get a file hash appended to their and references to them are upd And the file "index.html" should contain 'src="javascripts/application-1d8d5276.js"' And the file "index.html" should contain 'src="images/100px-5fd6fb90.jpg"' And the file "subdir/index.html" should contain 'href="../stylesheets/site-7474cadd.css"' + And the file "index.html" should contain 'srcset="images/100px-5fd6fb90.jpg 1x, images/200px-c11eb203.jpg 2x, images/300px-59adce76.jpg 3x"' + And the file "index.html" should contain 'src="images/100px-5fd6fb90.gif"' + And the file "index.html" should contain 'src="images/100px-1242c368.png"' And the file "subdir/index.html" should contain 'src="../javascripts/application-1d8d5276.js"' And the file "subdir/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' And the file "other/index.html" should contain 'href="../stylesheets/site-7474cadd.css"' And the file "other/index.html" should contain 'src="../javascripts/application-1d8d5276.js"' And the file "other/index.html" should contain 'src="../images/100px-5fd6fb90.jpg"' + And the file "api.json" should contain 'images/100px-5fd6fb90.gif' + And the file "api.json" should contain 'images/100px-5fd6fb90.jpg' + And the file "api.json" should contain 'images/100px-1242c368.png' + And the file "subdir/api.json" should contain 'images/100px-5fd6fb90.gif' + And the file "subdir/api.json" should contain 'images/100px-5fd6fb90.jpg' + And the file "subdir/api.json" should contain 'images/100px-1242c368.png' Scenario: Hashed assets work in preview server Given the Server is running at "asset-hash-app" @@ -44,6 +57,7 @@ Feature: Assets get a file hash appended to their and references to them are upd And I should see 'href="stylesheets/site-7474cadd.css"' And I should see 'src="javascripts/application-1d8d5276.js"' And I should see 'src="images/100px-5fd6fb90.jpg"' + And I should see 'srcset="images/100px-5fd6fb90.jpg 1x, images/200px-c11eb203.jpg 2x, images/300px-59adce76.jpg 3x"' When I go to "/subdir/" Then I should see 'href="../stylesheets/site-7474cadd.css"' And I should see 'src="../javascripts/application-1d8d5276.js"' @@ -55,10 +69,15 @@ Feature: Assets get a file hash appended to their and references to them are upd When I go to "/javascripts/application-1d8d5276.js" Then I should see "img.src = '/images/100px-5fd6fb90.jpg'" When I go to "/stylesheets/site-7474cadd.css" - Then I should see: - """ - background-image: url("../images/100px-5fd6fb90.jpg") - """ + Then I should see 'background-image: url("../images/100px-5fd6fb90.jpg")' + When I go to "/api.json" + Then I should see 'images/100px-5fd6fb90.gif' + And I should see 'images/100px-5fd6fb90.jpg' + And I should see 'images/100px-1242c368.png' + When I go to "/subdir/api.json" + Then I should see 'images/100px-5fd6fb90.gif' + And I should see 'images/100px-5fd6fb90.jpg' + And I should see 'images/100px-1242c368.png' Scenario: Enabling an asset host still produces hashed files and references Given the Server is running at "asset-hash-host-app" @@ -71,9 +90,6 @@ Feature: Assets get a file hash appended to their and references to them are upd When I go to "/other/" Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' - # Asset helpers don't appear to work from Compass right now - # When I go to "/stylesheets/site-e5a31a3e.css" - # Then I should see "background-image: url('http://middlemanapp.com/images/100px-5fd6fb90.jpg')" Scenario: The asset hash should change when a SASS partial changes Given the Server is running at "asset-hash-app" @@ -138,6 +154,8 @@ Feature: Assets get a file hash appended to their and references to them are upd | index.html | | subdir/index.html | | other/index.html | + | api.json | + | subdir/api.json | And the following files should not exist: | images/100px-1242c368.png | | images/100px-5fd6fb90.jpg | diff --git a/middleman-core/features/chained_templates.feature b/middleman-core/features/chained_templates.feature index b7d4e83e..7f538b65 100644 --- a/middleman-core/features/chained_templates.feature +++ b/middleman-core/features/chained_templates.feature @@ -16,4 +16,91 @@ Feature: Templates should be chainable And the file "index.html" should contain "Title" And the file "index.html" should contain "Subtitle" - And the file "index.html" should contain "Sup" \ No newline at end of file + And the file "index.html" should contain "Sup" + + Scenario: Partials are parsed by multiple template engines: Outer template has .erb and inner .md.erb + Given a fixture app "partial-chained_templates-app" + And a template named "my_template.html.erb" with: + """ +

My Template

+ + <%= partial 'my_partial' %> + """ + And a template named "my_partial.html.md.erb" with: + """ + ## My Partial + + <%= 'hello world' %> + """ + And the Server is running + When I go to "/my_template.html" + Then I should see: + """ +

My Template

+ """ + Then I should see: + """ +

My Partial

+ """ + Then I should see: + """ +

hello world

+ """ + + Scenario: Partials are parsed by multiple template engines: Outer template has .md.erb and inner .md.erb + Given a fixture app "partial-chained_templates-app" + And a template named "my_template.html.md.erb" with: + """ + # My Template + + <%= partial 'my_partial' %> + """ + And a template named "my_partial.html.md.erb" with: + """ + ## My Partial + + <%= 'hello world' %> + """ + And the Server is running + When I go to "/my_template.html" + Then I should see: + """ +

My Template

+ """ + Then I should see: + """ +

My Partial

+ """ + Then I should see: + """ +

hello world

+ """ + + Scenario: Partials are parsed by multiple template engines: Outer template has .md.erb, and inner .erb + Given a fixture app "partial-chained_templates-app" + And a template named "my_template.html.md.erb" with: + """ + # My Template + + <%= partial 'my_partial' %> + """ + And a template named "my_partial.html.erb" with: + """ +

My Partial

+ + <%= 'hello world' %> + """ + And the Server is running + When I go to "/my_template.html" + Then I should see: + """ +

My Template

+ """ + Then I should see: + """ +

My Partial

+ """ + Then I should see: + """ +

hello world

+ """ diff --git a/middleman-core/features/cli_init.feature b/middleman-core/features/cli_init.feature index 92244404..bbc453c2 100644 --- a/middleman-core/features/cli_init.feature +++ b/middleman-core/features/cli_init.feature @@ -37,21 +37,3 @@ Feature: Middleman CLI Scenario: Create a new project (alias n) When I run `middleman n MY_PROJECT` Then a directory named "MY_PROJECT" should exist - - # Scenario: Create a new HTML5 project - # When I run `middleman init MY_PROJECT --template=html5` - # Then a directory named "MY_PROJECT" should exist - # When I cd to "MY_PROJECT" - # Then the following files should exist: - # | config.rb | - # | Gemfile | - # Then the following files should not exist: - # | config.ru | - # And the file "config.rb" should contain "set :js_dir, 'js'" - # Then a directory named "source" should exist - # When I cd to "source" - # Then the following files should exist: - # | index.html.erb | - # | layouts/layout.erb | - # | humans.txt | - # | js/main.js | diff --git a/middleman-core/features/working_directory.feature b/middleman-core/features/working_directory.feature new file mode 100644 index 00000000..0ab9cf90 --- /dev/null +++ b/middleman-core/features/working_directory.feature @@ -0,0 +1,33 @@ +Feature: Honour working directory + Honour the working directory during testing + In order to support helpers which work with the current directories + + Scenario: Set working directory for helpers in tests + Given a fixture app "empty-app" + And a file named "source/index.html.erb" with: + """ + <%= Dir.getwd %> + """ + And the Server is running + When I go to "/index.html" + Then I should see: + """ + aruba + """ + + Scenario: Set working directory for config.rb in tests + Given a fixture app "empty-app" + And a file named "config.rb" with: + """ + set :my_working_directory, Dir.getwd + """ + And a file named "source/index.html.erb" with: + """ + <%= config[:my_working_directory] %> + """ + And the Server is running + When I go to "/index.html" + Then I should see: + """ + aruba + """ diff --git a/middleman-core/fixtures/asset-hash-app/source/api.json.erb b/middleman-core/fixtures/asset-hash-app/source/api.json.erb new file mode 100644 index 00000000..bc2af59a --- /dev/null +++ b/middleman-core/fixtures/asset-hash-app/source/api.json.erb @@ -0,0 +1 @@ +<%= {gif: image_path('100px.gif'), jpg: image_path('100px.jpg'), png: image_path('100px.png')}.to_json %> diff --git a/middleman-core/fixtures/asset-hash-app/source/images/200px.jpg b/middleman-core/fixtures/asset-hash-app/source/images/200px.jpg new file mode 100644 index 00000000..1a236747 Binary files /dev/null and b/middleman-core/fixtures/asset-hash-app/source/images/200px.jpg differ diff --git a/middleman-core/fixtures/asset-hash-app/source/images/300px.jpg b/middleman-core/fixtures/asset-hash-app/source/images/300px.jpg new file mode 100644 index 00000000..5a1d9e03 Binary files /dev/null and b/middleman-core/fixtures/asset-hash-app/source/images/300px.jpg differ diff --git a/middleman-core/fixtures/asset-hash-app/source/index.html.erb b/middleman-core/fixtures/asset-hash-app/source/index.html.erb index fe58ad66..59a9c54f 100644 --- a/middleman-core/fixtures/asset-hash-app/source/index.html.erb +++ b/middleman-core/fixtures/asset-hash-app/source/index.html.erb @@ -3,7 +3,7 @@ <% end %>

Image url:

- +

Ignored path:

diff --git a/middleman-core/fixtures/asset-hash-app/source/subdir/api.json.erb b/middleman-core/fixtures/asset-hash-app/source/subdir/api.json.erb new file mode 100644 index 00000000..bc2af59a --- /dev/null +++ b/middleman-core/fixtures/asset-hash-app/source/subdir/api.json.erb @@ -0,0 +1 @@ +<%= {gif: image_path('100px.gif'), jpg: image_path('100px.jpg'), png: image_path('100px.png')}.to_json %> diff --git a/middleman-core/fixtures/multiple-data-sources-app/source/index.html.erb b/middleman-core/fixtures/multiple-data-sources-app/source/index.html.erb index 98871082..c9ea3a7a 100644 --- a/middleman-core/fixtures/multiple-data-sources-app/source/index.html.erb +++ b/middleman-core/fixtures/multiple-data-sources-app/source/index.html.erb @@ -1,10 +1,5 @@ Default: <%= data.data.title %> Data 1: <%= data.data1.title %> Data 2: <%= data.data2.title %> -<<<<<<< HEAD Override in Two: <%= data.two.title %> Override in One: <%= data.one.title %> -======= -Override in One: <%= data.one.title %> -Override in Two: <%= data.two.title %> ->>>>>>> Add external command support diff --git a/middleman-core/fixtures/partial-chained_templates-app/config.rb b/middleman-core/fixtures/partial-chained_templates-app/config.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 84da0f75..42e50f77 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -163,7 +163,7 @@ module Middleman layout: proc { |file, _sitemap_app| file[:relative_path].to_s.start_with?('layout.') || - file[:relative_path].to_s.start_with?('layouts/') + file[:relative_path].to_s.start_with?('layouts/') } }, 'Callbacks that can exclude paths from the sitemap' diff --git a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb index 39019beb..0a79c3bb 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -11,7 +11,7 @@ class Padrino::Helpers::OutputHelpers::ErbHandler raw = block.call(*args) captured = template.instance_variable_get(:@_out_buf) self.output_buffer = buf_was - engine_matches?(block) ? captured : raw + engine_matches?(block) && !captured.empty? ? captured : raw end end 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 4a1f9f32..c173dccf 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -90,7 +90,14 @@ module Middleman::CoreExtensions return [data, nil] if ::Middleman::Util.binary?(full_path) - content = File.read(full_path) + # Avoid weird race condition when a file is renamed. + content = begin + File.read(full_path) + rescue ::EOFError + rescue ::IOError + rescue ::Errno::ENOENT + '' + end begin if content =~ /\A.*coding:/ diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 0788c9fa..8c2b7052 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -59,12 +59,12 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension if lang_suffix super(suffixed_partial_name) || - super(File.join(locals_dir, suffixed_partial_name)) || - super(partials_path) || - super + super(File.join(locals_dir, suffixed_partial_name)) || + super(partials_path) || + super else super(partials_path) || - super + super end end end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index fa51796d..1480091b 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -64,8 +64,8 @@ module Middleman block elsif extension_class && extension_class.ancestors.include?(::Middleman::Extension) extension_class - else - raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' + else + raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end return unless options[:auto_activate] diff --git a/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb b/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb index cc420ff4..a42f9157 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb @@ -39,7 +39,7 @@ module Middleman build_path = 'Not built' if ignored? props['Build Path'] = build_path if @resource.path != build_path props['URL'] = content_tag(:a, @resource.url, href: @resource.url) unless ignored? - props['Source File'] = @resource.source_file ? @resource.source_file[:full_path].to_s : 'Dynamic' + props['Source File'] = @resource.source_file ? @resource.source_file[:full_path].to_s.sub(/^#{Regexp.escape(ENV['MM_ROOT'] + '/')}/, '') : 'Dynamic' data = @resource.data props['Data'] = data.inspect unless data.empty? diff --git a/middleman-core/lib/middleman-core/sources.rb b/middleman-core/lib/middleman-core/sources.rb index cbe9b4ea..8819e387 100644 --- a/middleman-core/lib/middleman-core/sources.rb +++ b/middleman-core/lib/middleman-core/sources.rb @@ -84,7 +84,7 @@ module Middleman def globally_ignored?(file) @ignores.values.any? do |descriptor| ((descriptor[:type] == :all) || file[:types].include?(descriptor[:type])) && - matches?(descriptor[:validator], file) + matches?(descriptor[:validator], file) end end @@ -169,11 +169,11 @@ module Middleman Contract Symbol, String, Maybe[Bool] => Maybe[SourceFile] def find(type, path, glob=false) watchers - .lazy - .select { |d| d.type == type } - .map { |d| d.find(path, glob) } - .reject(&:nil?) - .first + .lazy + .select { |d| d.type == type } + .map { |d| d.find(path, glob) } + .reject(&:nil?) + .first end # Check if a file for a given type exists. @@ -184,9 +184,9 @@ module Middleman Contract Symbol, String => Bool def exists?(type, path) watchers - .lazy - .select { |d| d.type == type } - .any? { |d| d.exists?(path) } + .lazy + .select { |d| d.type == type } + .any? { |d| d.exists?(path) } end # Check if a file for a given type exists. @@ -197,8 +197,8 @@ module Middleman Contract SetOf[Symbol], String => Maybe[HANDLER] def watcher_for_path(types, path) watchers - .select { |d| types.include?(d.type) } - .find { |d| d.exists?(path) } + .select { |d| types.include?(d.type) } + .find { |d| d.exists?(path) } end # Manually poll all watchers for new content. diff --git a/middleman-core/lib/middleman-core/sources/source_watcher.rb b/middleman-core/lib/middleman-core/sources/source_watcher.rb index b8b2e4f3..834fa0a9 100644 --- a/middleman-core/lib/middleman-core/sources/source_watcher.rb +++ b/middleman-core/lib/middleman-core/sources/source_watcher.rb @@ -104,7 +104,6 @@ module Middleman return nil if p.absolute? && !p.to_s.start_with?(@directory.to_s) p = @directory + p if p.relative? - if glob @extensionless_files[p] else @@ -211,25 +210,25 @@ module Middleman Contract ArrayOf[Pathname], ArrayOf[Pathname] => Any def update(updated_paths, removed_paths) valid_updates = updated_paths - .lazy - .map(&method(:path_to_source_file)) - .select(&method(:valid?)) - .to_a - .each do |f| - add_file_to_cache(f) - logger.debug "== Change (#{f[:types].inspect}): #{f[:relative_path]}" - end + .lazy + .map(&method(:path_to_source_file)) + .select(&method(:valid?)) + .to_a + .each do |f| + add_file_to_cache(f) + logger.debug "== Change (#{f[:types].inspect}): #{f[:relative_path]}" + end valid_removes = removed_paths - .lazy - .select(&@files.method(:key?)) - .map(&@files.method(:[])) - .select(&method(:valid?)) - .to_a - .each do |f| - remove_file_from_cache(f) - logger.debug "== Deletion (#{f[:types].inspect}): #{f[:relative_path]}" - end + .lazy + .select(&@files.method(:key?)) + .map(&@files.method(:[])) + .select(&method(:valid?)) + .to_a + .each do |f| + remove_file_from_cache(f) + logger.debug "== Deletion (#{f[:types].inspect}): #{f[:relative_path]}" + end run_callbacks( @on_change_callbacks, @@ -240,12 +239,19 @@ module Middleman def add_file_to_cache(f) @files[f[:full_path]] = f - @extensionless_files[f[:full_path].sub_ext('.*')] = f + @extensionless_files[strip_extensions(f[:full_path])] = f end def remove_file_from_cache(f) @files.delete(f[:full_path]) - @extensionless_files.delete(f[:full_path].sub_ext('.*')) + @extensionless_files.delete(strip_extensions(f[:full_path])) + end + + def strip_extensions(p) + while ::Tilt[p.to_s] || p.extname === '.html' + p = p.sub_ext('') + end + Pathname(p.to_s + '.*') end # Check if this watcher should care about a file. @@ -255,8 +261,8 @@ module Middleman Contract IsA['Middleman::SourceFile'] => Bool def valid?(file) @validator.call(file) && - !globally_ignored?(file) && - !@ignored.call(file) + !globally_ignored?(file) && + !@ignored.call(file) end # Convert a path to a file resprentation. diff --git a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb index a2c0da39..c4ba5e9f 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -33,6 +33,7 @@ end Given /^the Server is running$/ do root_dir = File.expand_path(current_dir) + if File.exists?(File.join(root_dir, 'source')) ENV['MM_SOURCE'] = 'source' else @@ -43,12 +44,14 @@ Given /^the Server is running$/ do initialize_commands = @initialize_commands || [] - @server_inst = ::Middleman::Application.new do - config[:watcher_disable] = true - config[:show_exceptions] = false + in_current_dir do + @server_inst = ::Middleman::Application.new do + config[:watcher_disable] = true + config[:show_exceptions] = false - initialize_commands.each do |p| - instance_exec(&p) + initialize_commands.each do |p| + instance_exec(&p) + end end end @@ -61,54 +64,82 @@ Given /^the Server is running at "([^\"]*)"$/ do |app_path| step %Q{the Server is running} end +Given /^a template named "([^\"]*)" with:$/ do |name, string| + step %Q{a file named "source/#{name}" with:}, string +end + When /^I go to "([^\"]*)"$/ do |url| - @last_response = @browser.get(URI.escape(url)) + in_current_dir do + @last_response = @browser.get(URI.escape(url)) + end end Then /^going to "([^\"]*)" should not raise an exception$/ do |url| - last_response = nil - expect { - last_response = @browser.get(URI.escape(url)) - }.to_not raise_error - @last_response = last_response + in_current_dir do + last_response = nil + expect { + last_response = @browser.get(URI.escape(url)) + }.to_not raise_error + @last_response = last_response + end end Then /^the content type should be "([^\"]*)"$/ do |expected| - expect(@last_response.content_type).to start_with(expected) + in_current_dir do + expect(@last_response.content_type).to start_with(expected) + end end Then /^I should see "([^\"]*)"$/ do |expected| - expect(@last_response.body).to include(expected) + in_current_dir do + expect(@last_response.body).to include(expected) + end end Then /^I should see '([^\']*)'$/ do |expected| - expect(@last_response.body).to include(expected) + in_current_dir do + expect(@last_response.body).to include(expected) + end end Then /^I should see:$/ do |expected| - expect(@last_response.body).to include(expected) + in_current_dir do + expect(@last_response.body).to include(expected) + end end Then /^I should not see "([^\"]*)"$/ do |expected| - expect(@last_response.body).to_not include(expected) + in_current_dir do + expect(@last_response.body).to_not include(expected) + end end Then /^I should see content matching %r{(.*)}$/ do |expected| - expect(@last_response.body).to match(expected) + in_current_dir do + expect(@last_response.body).to match(expected) + end end Then /^I should not see content matching %r{(.*)}$/ do |expected| - expect(@last_response.body).to_not match(expected) + in_current_dir do + expect(@last_response.body).to_not match(expected) + end end Then /^I should not see:$/ do |expected| - expect(@browser.last_response.body).to_not include(expected.chomp) + in_current_dir do + expect(@browser.last_response.body).to_not include(expected.chomp) + end end Then /^the status code should be "([^\"]*)"$/ do |expected| - expect(@browser.last_response.status).to eq expected.to_i + in_current_dir do + expect(@browser.last_response.status).to eq expected.to_i + end end Then /^I should see "([^\"]*)" lines$/ do |lines| - expect(@last_response.body.chomp.split($/).length).to eq(lines.to_i) + in_current_dir do + expect(@last_response.body.chomp.split($/).length).to eq(lines.to_i) + end end diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 9deeccb4..5ac5aa23 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -30,7 +30,7 @@ module Middleman # @param [Middleman::Application] app # @param [Hash] locs # @param [Hash] opts - def initialize(app, locs={}.freeze, opts={}.freeze) + def initialize(app, locs={}, opts={}) @app = app @locs = locs @opts = opts @@ -114,7 +114,7 @@ module Middleman opts = options.dup locs = opts.delete(:locals) - render_file(partial_file, locs.freeze, opts.freeze, &block) + render_file(partial_file, locs, opts, &block) end end @@ -163,8 +163,28 @@ module Middleman # @return [String] The resulting content string. Contract IsA['Middleman::SourceFile'], Hash, Hash, Proc => String def render_file(file, locs, opts, &block) - file_renderer = ::Middleman::FileRenderer.new(@app, file[:relative_path].to_s) - file_renderer.render(locs, opts, self, &block) + _render_with_all_renderers(file[:relative_path].to_s, locs, self, opts, &block) + end + + def _render_with_all_renderers(path, locs, context, opts, &block) + # Keep rendering template until we've used up all extensions. This + # handles cases like `style.css.sass.erb` + content = nil + + while ::Tilt[path] + begin + opts[:template_body] = content if content + + content_renderer = ::Middleman::FileRenderer.new(@app, path) + content = content_renderer.render(locs, opts, context, &block) + + path = File.basename(path, File.extname(path)) + rescue LocalJumpError + raise "Tried to render a layout (calls yield) at #{path} like it was a template. Non-default layouts need to be in #{@app.config[:source]}/#{@app.config[:layouts_dir]}." + end + end + + content end def current_path diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 9da1fae4..34692b49 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -42,7 +42,7 @@ module Middleman # @param [Hash] opts # @return [String] Contract Hash, Hash => String - def render(locs={}, opts={}) + def render(locs={}, opts={}, &block) path = @path.dup locals = locs.dup.freeze options = opts.dup @@ -61,21 +61,7 @@ module Middleman # TODO: Only for HAML files context.init_haml_helpers if context.respond_to?(:init_haml_helpers) - # Keep rendering template until we've used up all extensions. This - # handles cases like `style.css.sass.erb` - content = nil - while ::Tilt[path] - begin - options[:template_body] = content if content - - content_renderer = ::Middleman::FileRenderer.new(@app, path) - content = content_renderer.render(locals, options, context) - - path = File.basename(path, File.extname(path)) - rescue LocalJumpError - raise "Tried to render a layout (calls yield) at #{path} like it was a template. Non-default layouts need to be in #{source}/#{@app.config[:layouts_dir]}." - end - end + content = _render_with_all_renderers(path, locs, context, opts, &block) # If we need a layout and have a layout, use it if layout_file = fetch_layout(engine, options) @@ -93,6 +79,27 @@ module Middleman protected + def _render_with_all_renderers(path, locs, context, opts, &block) + # Keep rendering template until we've used up all extensions. This + # handles cases like `style.css.sass.erb` + content = nil + + while ::Tilt[path] + begin + opts[:template_body] = content if content + + content_renderer = ::Middleman::FileRenderer.new(@app, path) + content = content_renderer.render(locs, opts, context, &block) + + path = File.basename(path, File.extname(path)) + rescue LocalJumpError + raise "Tried to render a layout (calls yield) at #{path} like it was a template. Non-default layouts need to be in #{@app.config[:source]}/#{@app.config[:layouts_dir]}." + end + end + + content + end + # Find a layout for a given engine # # @param [Symbol] engine diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 7218e281..188b32d5 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -317,7 +317,7 @@ module Middleman Contract String, String, ArrayOf[String], Proc => String def rewrite_paths(body, _path, exts, &_block) - body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| + body.dup.gsub(/([=\'\"\(,]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| opening_character = $1 asset_path = $2