From a50ca3a49d4c267b693f1c0aebc40f654812a3bd Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Fri, 11 Apr 2014 14:11:44 +0100 Subject: [PATCH 001/662] Change default IP Enables #1248 by default. --- middleman-core/lib/middleman-core/cli/server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/cli/server.rb b/middleman-core/lib/middleman-core/cli/server.rb index 782d9faf..73bd7c13 100644 --- a/middleman-core/lib/middleman-core/cli/server.rb +++ b/middleman-core/lib/middleman-core/cli/server.rb @@ -15,7 +15,7 @@ module Middleman::Cli method_option :host, :type => :string, :aliases => '-h', - :default => '0.0.0.0', + :default => Socket.ip_address_list.find(&:ipv4_private?).ip_address, :desc => 'Bind to HOST address' method_option :port, :aliases => '-p', From 0656cd6a318419fe1313941ba90f938008854ca1 Mon Sep 17 00:00:00 2001 From: Fabian Rodriguez Date: Sat, 12 Apr 2014 18:28:13 -0300 Subject: [PATCH 002/662] Fix rubocop config. Since rubycop v0.20.0 'AllCops/Excludes' and 'AllCops/Includes' where renamed to 'AllCops/Exclude' and 'AllCops/Include' --- .rubocop.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fb5fd96a..44966aac 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,10 +1,10 @@ AllCops: - Includes: + Include: - Rakefile - Gemfile - config.ru - gem_rake_helper.rb - Excludes: + Exclude: - script/** - vendor/** - bin/** From 8f75f6516debc28159914c79e9074d2c4e997a47 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 14 Apr 2014 10:34:53 -0700 Subject: [PATCH 003/662] back out IP detection --- middleman-core/lib/middleman-core/cli/server.rb | 2 +- middleman-core/lib/middleman-core/preview_server.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/cli/server.rb b/middleman-core/lib/middleman-core/cli/server.rb index 73bd7c13..782d9faf 100644 --- a/middleman-core/lib/middleman-core/cli/server.rb +++ b/middleman-core/lib/middleman-core/cli/server.rb @@ -15,7 +15,7 @@ module Middleman::Cli method_option :host, :type => :string, :aliases => '-h', - :default => Socket.ip_address_list.find(&:ipv4_private?).ip_address, + :default => '0.0.0.0', :desc => 'Bind to HOST address' method_option :port, :aliases => '-p', diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 3191e741..efb72bae 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -15,7 +15,7 @@ module Middleman # @return [void] def start(opts={}) @options = opts - @host = @options[:host] || Socket.ip_address_list.find(&:ipv4_private?).ip_address + @host = @options[:host] || '0.0.0.0' @port = @options[:port] || DEFAULT_PORT mount_instance(new_app) From 8909d9cbbf3510f9907105fea4edc41dc43c1565 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 28 Mar 2014 13:54:54 -0700 Subject: [PATCH 004/662] WIP refactor --- ...uilder.feature => i18n_v3_builder.feature} | 44 +-- ...e.feature => i18n_v3_force_locale.feature} | 4 +- .../features/i18n_v3_preview.feature | 252 ++++++++++++++++++ ...review.feature => i18n_v4_preview.feature} | 51 ++-- .../locales/en.yml | 0 .../locales/es.yml | 0 .../source/lang_data/hello.html.erb | 0 .../source/lang_data/index.html.erb | 0 .../source/layout.erb | 0 .../locales/en.yml | 0 .../locales/es.yml | 0 .../source/localizable/index.html.erb | 0 .../config.rb | 2 +- .../locales/en.yml | 0 .../locales/es.yml | 0 .../locales/fr.yml | 0 .../source/index.html.haml | 0 .../locales/en.yml | 0 .../locales/en/more.yml | 0 .../locales/es.yml | 0 .../locales/es/mucho.yml | 0 .../source/localizable/index.html.erb | 0 .../data/defaults_en.yml | 0 .../data/defaults_es.yml | 0 .../data/en_defaults.yml | 0 .../locales/en.yml | 0 .../locales/es.yml | 0 .../source/CNAME | 0 .../source/layouts/layout.erb | 0 .../source/localizable/hello.html.erb | 0 .../source/localizable/index.html.erb | 0 .../source/localizable/morning.en.html.erb | 0 .../source/localizable/morning.es.html.erb | 0 .../source/localizable/one.en.html.md | 0 .../source/localizable/one.es.html.md | 0 .../source/password.txt | 0 .../source/stylesheets/site.css | 0 .../i18n-v4-test-app/data/defaults_en.yml | 0 .../i18n-v4-test-app/data/defaults_es.yml | 0 .../i18n-v4-test-app/data/en_defaults.yml | 0 .../fixtures/i18n-v4-test-app/locales/en.yml | 4 + .../fixtures/i18n-v4-test-app/locales/es.yml | 9 + .../fixtures/i18n-v4-test-app/source/CNAME | 1 + .../i18n-v4-test-app/source/hello.html.erb | 1 + .../i18n-v4-test-app/source/index.html.erb | 1 + .../source/layouts/layout.erb | 8 + .../source/morning.en.html.erb | 1 + .../source/morning.es.html.erb | 1 + .../i18n-v4-test-app/source/one.en.html.md | 1 + .../i18n-v4-test-app/source/one.es.html.md | 1 + .../i18n-v4-test-app/source/password.txt | 1 + .../source/stylesheets/site.css | 3 + .../lib/middleman-core/core_extensions.rb | 7 +- .../core_extensions/{i18n.rb => i18n_v3.rb} | 2 +- .../middleman-core/core_extensions/i18n_v4.rb | 194 ++++++++++++++ 55 files changed, 536 insertions(+), 52 deletions(-) rename middleman-core/features/{i18n_builder.feature => i18n_v3_builder.feature} (86%) rename middleman-core/features/{i18n_force_locale.feature => i18n_v3_force_locale.feature} (80%) create mode 100644 middleman-core/features/i18n_v3_preview.feature rename middleman-core/features/{i18n_preview.feature => i18n_v4_preview.feature} (84%) rename middleman-core/fixtures/{i18n-alt-root-app => i18n-v3-alt-root-app}/locales/en.yml (100%) rename middleman-core/fixtures/{i18n-alt-root-app => i18n-v3-alt-root-app}/locales/es.yml (100%) rename middleman-core/fixtures/{i18n-alt-root-app => i18n-v3-alt-root-app}/source/lang_data/hello.html.erb (100%) rename middleman-core/fixtures/{i18n-alt-root-app => i18n-v3-alt-root-app}/source/lang_data/index.html.erb (100%) rename middleman-core/fixtures/{i18n-alt-root-app => i18n-v3-alt-root-app}/source/layout.erb (100%) rename middleman-core/fixtures/{i18n-default-app => i18n-v3-default-app}/locales/en.yml (100%) rename middleman-core/fixtures/{i18n-default-app => i18n-v3-default-app}/locales/es.yml (100%) rename middleman-core/fixtures/{i18n-default-app => i18n-v3-default-app}/source/localizable/index.html.erb (100%) rename middleman-core/fixtures/{i18n-force-locale => i18n-v3-force-locale}/config.rb (94%) rename middleman-core/fixtures/{i18n-force-locale => i18n-v3-force-locale}/locales/en.yml (100%) rename middleman-core/fixtures/{i18n-force-locale => i18n-v3-force-locale}/locales/es.yml (100%) rename middleman-core/fixtures/{i18n-force-locale => i18n-v3-force-locale}/locales/fr.yml (100%) rename middleman-core/fixtures/{i18n-force-locale => i18n-v3-force-locale}/source/index.html.haml (100%) rename middleman-core/fixtures/{i18n-nested-app => i18n-v3-nested-app}/locales/en.yml (100%) rename middleman-core/fixtures/{i18n-nested-app => i18n-v3-nested-app}/locales/en/more.yml (100%) rename middleman-core/fixtures/{i18n-nested-app => i18n-v3-nested-app}/locales/es.yml (100%) rename middleman-core/fixtures/{i18n-nested-app => i18n-v3-nested-app}/locales/es/mucho.yml (100%) rename middleman-core/fixtures/{i18n-nested-app => i18n-v3-nested-app}/source/localizable/index.html.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/data/defaults_en.yml (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/data/defaults_es.yml (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/data/en_defaults.yml (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/locales/en.yml (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/locales/es.yml (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/CNAME (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/layouts/layout.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/hello.html.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/index.html.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/morning.en.html.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/morning.es.html.erb (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/one.en.html.md (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/localizable/one.es.html.md (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/password.txt (100%) rename middleman-core/fixtures/{i18n-test-app => i18n-v3-test-app}/source/stylesheets/site.css (100%) create mode 100644 middleman-core/fixtures/i18n-v4-test-app/data/defaults_en.yml create mode 100644 middleman-core/fixtures/i18n-v4-test-app/data/defaults_es.yml create mode 100644 middleman-core/fixtures/i18n-v4-test-app/data/en_defaults.yml create mode 100644 middleman-core/fixtures/i18n-v4-test-app/locales/en.yml create mode 100644 middleman-core/fixtures/i18n-v4-test-app/locales/es.yml create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/CNAME create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/hello.html.erb create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/index.html.erb create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/layouts/layout.erb create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/morning.en.html.erb create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/morning.es.html.erb create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/one.en.html.md create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/one.es.html.md create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/password.txt create mode 100644 middleman-core/fixtures/i18n-v4-test-app/source/stylesheets/site.css rename middleman-core/lib/middleman-core/core_extensions/{i18n.rb => i18n_v3.rb} (98%) create mode 100644 middleman-core/lib/middleman-core/core_extensions/i18n_v4.rb diff --git a/middleman-core/features/i18n_builder.feature b/middleman-core/features/i18n_v3_builder.feature similarity index 86% rename from middleman-core/features/i18n_builder.feature rename to middleman-core/features/i18n_v3_builder.feature index 34a802b1..c9b41592 100644 --- a/middleman-core/features/i18n_builder.feature +++ b/middleman-core/features/i18n_v3_builder.feature @@ -1,13 +1,13 @@ -Feature: i18n Builder +Feature: i18n v3 Builder In order to preview localized html Scenario: Running localize with the default config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n + activate :i18n_v3 """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | index.html | @@ -46,12 +46,12 @@ Feature: i18n Builder And the file "password.txt" should contain "hunter2" Scenario: Running localize with the alt path config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n, :path => "/lang_:locale/" + activate :i18n_v3, :path => "/lang_:locale/" """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | index.html | @@ -66,12 +66,12 @@ Feature: i18n Builder And the file "lang_es/hola.html" should contain "Hola World" Scenario: Running localize with the alt root config - Given a fixture app "i18n-alt-root-app" + Given a fixture app "i18n-v3-alt-root-app" And a file named "config.rb" with: """ - activate :i18n, :templates_dir => "lang_data" + activate :i18n_v3, :templates_dir => "lang_data" """ - Given a successfully built app at "i18n-alt-root-app" + Given a successfully built app at "i18n-v3-alt-root-app" When I cd to "build" Then the following files should exist: | index.html | @@ -86,12 +86,12 @@ Feature: i18n Builder And the file "es/hola.html" should contain "Hola World" Scenario: Running localize with the lang map config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n, :lang_map => { :en => :english, :es => :spanish } + activate :i18n_v3, :lang_map => { :en => :english, :es => :spanish } """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | index.html | @@ -106,12 +106,12 @@ Feature: i18n Builder And the file "spanish/hola.html" should contain "Hola World" Scenario: Running localize with the no mount config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n, :mount_at_root => false + activate :i18n_v3, :mount_at_root => false """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | en/index.html | @@ -127,12 +127,12 @@ Feature: i18n Builder And the file "es/hola.html" should contain "Hola World" Scenario: Running localize with the subset config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n, :langs => [:en] + activate :i18n_v3, :langs => [:en] """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | index.html | @@ -145,13 +145,13 @@ Feature: i18n Builder And the file "hello.html" should contain "Hello World" Scenario: Running localize with relative_assets - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v3-test-app" And a file named "config.rb" with: """ - activate :i18n + activate :i18n_v3 activate :relative_assets """ - Given a successfully built app at "i18n-test-app" + Given a successfully built app at "i18n-v3-test-app" When I cd to "build" Then the following files should exist: | index.html | diff --git a/middleman-core/features/i18n_force_locale.feature b/middleman-core/features/i18n_v3_force_locale.feature similarity index 80% rename from middleman-core/features/i18n_force_locale.feature rename to middleman-core/features/i18n_v3_force_locale.feature index afe8fc3b..8d57d486 100644 --- a/middleman-core/features/i18n_force_locale.feature +++ b/middleman-core/features/i18n_v3_force_locale.feature @@ -1,7 +1,7 @@ -Feature: i18n manually setting locale +Feature: i18n v3 manually setting locale Scenario: Setting I18n.locale in a block (see issue #809) or with the :lang option - Given the Server is running at "i18n-force-locale" + Given the Server is running at "i18n-v3-force-locale" When I go to "/en/index.html" Then I should see "Hello" Then I should see "I18n.locale: en" diff --git a/middleman-core/features/i18n_v3_preview.feature b/middleman-core/features/i18n_v3_preview.feature new file mode 100644 index 00000000..47b083fa --- /dev/null +++ b/middleman-core/features/i18n_v3_preview.feature @@ -0,0 +1,252 @@ +Feature: i18n v3 Preview + In order to preview localized html + + Scenario: Running localize with the default config + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3 + """ + Given the Server is running at "i18n-v3-test-app" + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When I go to "/morning.html" + Then I should see "Good morning" + When I go to "/one.html" + Then I should see "Only one" + When I go to "/defaults_en/index.html" + Then I should see "File Not Found" + When I go to "/en/index.html" + Then I should see "File Not Found" + When I go to "/en/morning.html" + Then I should see "File Not Found" + When I go to "/defaults_es/index.html" + Then I should see "File Not Found" + When I go to "/es/index.html" + Then I should see "Como Esta?" + When I go to "/es/hola.html" + Then I should see "Hola World" + When I go to "/es/manana.html" + Then I should see "Buenos días" + When I go to "/es/una.html" + Then I should see "Solamente una" + + Scenario: A template changes i18n during preview + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3 + """ + Given the Server is running at "i18n-v3-test-app" + And the file "locales/en.yml" has the contents + """ + --- + en: + greetings: "Howdy" + hi: "Hello" + """ + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When the file "locales/en.yml" has the contents + """ + --- + en: + greetings: "How You Doin" + hi: "Sup" + """ + When I go to "/" + Then I should see "How You Doin" + When I go to "/hello.html" + Then I should see "Sup World" + + Scenario: Running localize with the alt path config + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :path => "/lang_:locale/" + """ + Given the Server is running at "i18n-v3-test-app" + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When I go to "/lang_en/index.html" + Then I should see "File Not Found" + When I go to "/lang_es/index.html" + Then I should see "Como Esta?" + When I go to "/lang_es/hola.html" + Then I should see "Hola World" + + + Scenario: Running localize with the alt root config + Given a fixture app "i18n-v3-alt-root-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :templates_dir => "lang_data" + """ + Given the Server is running at "i18n-v3-alt-root-app" + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When I go to "/en/index.html" + Then I should see "File Not Found" + When I go to "/es/index.html" + Then I should see "Como Esta?" + When I go to "/es/hola.html" + Then I should see "Hola World" + + Scenario: Running localize with the lang map config + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :lang_map => { :en => :english, :es => :spanish } + """ + Given the Server is running at "i18n-v3-test-app" + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When I go to "/english/index.html" + Then I should see "File Not Found" + When I go to "/spanish/index.html" + 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-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :mount_at_root => :es + """ + Given the Server is running at "i18n-v3-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 "/manana.html" + Then I should see "Buenos días" + When I go to "/hello.html" + Then I should see "File Not Found" + When I go to "/en/morning.html" + Then I should see "Good morning" + When I go to "/es/manana.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-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :langs => :es + """ + Given the Server is running at "i18n-v3-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-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :mount_at_root => false + """ + Given the Server is running at "i18n-v3-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 "File Not Found" + When I go to "/hello.html" + Then I should see "File Not Found" + When I go to "/es/index.html" + Then I should see "Como Esta?" + When I go to "/es/hola.html" + Then I should see "Hola World" + + Scenario: Running localize with the subset config + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :langs => [:en] + """ + Given the Server is running at "i18n-v3-test-app" + When I go to "/" + Then I should see "Howdy" + When I go to "/hello.html" + Then I should see "Hello World" + When I go to "/en/index.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 relative_assets + Given a fixture app "i18n-v3-test-app" + And a file named "config.rb" with: + """ + activate :i18n_v3 + activate :relative_assets + """ + Given the Server is running at "i18n-v3-test-app" + When I go to "/" + Then I should see '"stylesheets/site.css"' + When I go to "/hello.html" + Then I should see '"stylesheets/site.css"' + When I go to "/es/index.html" + Then I should see '"../stylesheets/site.css"' + When I go to "/es/hola.html" + Then I should see '"../stylesheets/site.css"' + + Scenario: Missing translations fall back to the default locale + Given a fixture app "i18n-v3-default-app" + And a file named "config.rb" with: + """ + activate :i18n_v3, :mount_at_root => :es + """ + Given the Server is running at "i18n-v3-default-app" + When I go to "/en/" + Then I should see "Default locale: es" + Then I should see "Current locale: en" + Then I should see "Buenos días" + Then I should see "Howdy" + + Scenario: Nested i18n yaml + Given a fixture app "i18n-v3-nested-app" + And a file named "config.rb" with: + """ + activate :i18n_v3 + """ + Given the Server is running at "i18n-v3-nested-app" + When I go to "/" + Then I should see "Howdy" + Then I should see "More" + When I go to "/es/" + Then I should see "Como Esta?" + Then I should see "Mucho" \ No newline at end of file diff --git a/middleman-core/features/i18n_preview.feature b/middleman-core/features/i18n_v4_preview.feature similarity index 84% rename from middleman-core/features/i18n_preview.feature rename to middleman-core/features/i18n_v4_preview.feature index 93c60dc1..df9bd0b0 100644 --- a/middleman-core/features/i18n_preview.feature +++ b/middleman-core/features/i18n_v4_preview.feature @@ -1,13 +1,14 @@ -Feature: i18n Preview +@wip +Feature: i18n v4 Preview In order to preview localized html Scenario: Running localize with the default config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/" Then I should see "Howdy" When I go to "/hello.html" @@ -34,12 +35,12 @@ Feature: i18n Preview Then I should see "Solamente una" Scenario: A template changes i18n during preview - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" And the file "locales/en.yml" has the contents """ --- @@ -64,12 +65,12 @@ Feature: i18n Preview Then I should see "Sup World" Scenario: Running localize with the alt path config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :path => "/lang_:locale/" """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/" Then I should see "Howdy" When I go to "/hello.html" @@ -83,12 +84,12 @@ Feature: i18n Preview Scenario: Running localize with the alt root config - Given a fixture app "i18n-alt-root-app" + Given a fixture app "i18n-v4-alt-root-app" And a file named "config.rb" with: """ activate :i18n, :templates_dir => "lang_data" """ - Given the Server is running at "i18n-alt-root-app" + Given the Server is running at "i18n-v4-alt-root-app" When I go to "/" Then I should see "Howdy" When I go to "/hello.html" @@ -101,12 +102,12 @@ Feature: i18n Preview Then I should see "Hola World" Scenario: Running localize with the lang map config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :lang_map => { :en => :english, :es => :spanish } """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/" Then I should see "Howdy" When I go to "/hello.html" @@ -119,12 +120,12 @@ Feature: i18n Preview Then I should see "Hola World" Scenario: Running localize with a non-English mount config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :mount_at_root => :es """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/en/index.html" Then I should see "Howdy" When I go to "/en/hello.html" @@ -147,12 +148,12 @@ Feature: i18n Preview Then I should see "File Not Found" Scenario: Running localize with a non-English lang subset - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :langs => :es """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/en/index.html" Then I should see "File Not Found" When I go to "/en/hello.html" @@ -170,12 +171,12 @@ Feature: i18n Preview Scenario: Running localize with the no mount config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :mount_at_root => false """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/en/index.html" Then I should see "Howdy" When I go to "/en/hello.html" @@ -190,12 +191,12 @@ Feature: i18n Preview Then I should see "Hola World" Scenario: Running localize with the subset config - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n, :langs => [:en] """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/" Then I should see "Howdy" When I go to "/hello.html" @@ -208,13 +209,13 @@ Feature: i18n Preview Then I should see "File Not Found" Scenario: Running localize with relative_assets - Given a fixture app "i18n-test-app" + Given a fixture app "i18n-v4-test-app" And a file named "config.rb" with: """ activate :i18n activate :relative_assets """ - Given the Server is running at "i18n-test-app" + Given the Server is running at "i18n-v4-test-app" When I go to "/" Then I should see '"stylesheets/site.css"' When I go to "/hello.html" @@ -225,12 +226,12 @@ Feature: i18n Preview Then I should see '"../stylesheets/site.css"' Scenario: Missing translations fall back to the default locale - Given a fixture app "i18n-default-app" + Given a fixture app "i18n-v4-default-app" And a file named "config.rb" with: """ activate :i18n, :mount_at_root => :es """ - Given the Server is running at "i18n-default-app" + Given the Server is running at "i18n-v4-default-app" When I go to "/en/" Then I should see "Default locale: es" Then I should see "Current locale: en" @@ -238,12 +239,12 @@ Feature: i18n Preview Then I should see "Howdy" Scenario: Nested i18n yaml - Given a fixture app "i18n-nested-app" + Given a fixture app "i18n-v4-nested-app" And a file named "config.rb" with: """ activate :i18n """ - Given the Server is running at "i18n-nested-app" + Given the Server is running at "i18n-v4-nested-app" When I go to "/" Then I should see "Howdy" Then I should see "More" diff --git a/middleman-core/fixtures/i18n-alt-root-app/locales/en.yml b/middleman-core/fixtures/i18n-v3-alt-root-app/locales/en.yml similarity index 100% rename from middleman-core/fixtures/i18n-alt-root-app/locales/en.yml rename to middleman-core/fixtures/i18n-v3-alt-root-app/locales/en.yml diff --git a/middleman-core/fixtures/i18n-alt-root-app/locales/es.yml b/middleman-core/fixtures/i18n-v3-alt-root-app/locales/es.yml similarity index 100% rename from middleman-core/fixtures/i18n-alt-root-app/locales/es.yml rename to middleman-core/fixtures/i18n-v3-alt-root-app/locales/es.yml diff --git a/middleman-core/fixtures/i18n-alt-root-app/source/lang_data/hello.html.erb b/middleman-core/fixtures/i18n-v3-alt-root-app/source/lang_data/hello.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-alt-root-app/source/lang_data/hello.html.erb rename to middleman-core/fixtures/i18n-v3-alt-root-app/source/lang_data/hello.html.erb diff --git a/middleman-core/fixtures/i18n-alt-root-app/source/lang_data/index.html.erb b/middleman-core/fixtures/i18n-v3-alt-root-app/source/lang_data/index.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-alt-root-app/source/lang_data/index.html.erb rename to middleman-core/fixtures/i18n-v3-alt-root-app/source/lang_data/index.html.erb diff --git a/middleman-core/fixtures/i18n-alt-root-app/source/layout.erb b/middleman-core/fixtures/i18n-v3-alt-root-app/source/layout.erb similarity index 100% rename from middleman-core/fixtures/i18n-alt-root-app/source/layout.erb rename to middleman-core/fixtures/i18n-v3-alt-root-app/source/layout.erb diff --git a/middleman-core/fixtures/i18n-default-app/locales/en.yml b/middleman-core/fixtures/i18n-v3-default-app/locales/en.yml similarity index 100% rename from middleman-core/fixtures/i18n-default-app/locales/en.yml rename to middleman-core/fixtures/i18n-v3-default-app/locales/en.yml diff --git a/middleman-core/fixtures/i18n-default-app/locales/es.yml b/middleman-core/fixtures/i18n-v3-default-app/locales/es.yml similarity index 100% rename from middleman-core/fixtures/i18n-default-app/locales/es.yml rename to middleman-core/fixtures/i18n-v3-default-app/locales/es.yml diff --git a/middleman-core/fixtures/i18n-default-app/source/localizable/index.html.erb b/middleman-core/fixtures/i18n-v3-default-app/source/localizable/index.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-default-app/source/localizable/index.html.erb rename to middleman-core/fixtures/i18n-v3-default-app/source/localizable/index.html.erb diff --git a/middleman-core/fixtures/i18n-force-locale/config.rb b/middleman-core/fixtures/i18n-v3-force-locale/config.rb similarity index 94% rename from middleman-core/fixtures/i18n-force-locale/config.rb rename to middleman-core/fixtures/i18n-v3-force-locale/config.rb index 4058360e..e0730412 100644 --- a/middleman-core/fixtures/i18n-force-locale/config.rb +++ b/middleman-core/fixtures/i18n-v3-force-locale/config.rb @@ -4,7 +4,7 @@ end proxy "/fr/index.html", "index.html", :lang => :fr -activate :i18n +activate :i18n_v3 # This is what breaks i18n, just because it adds a resource list manipulator that # forces a rebuild of the resource list. diff --git a/middleman-core/fixtures/i18n-force-locale/locales/en.yml b/middleman-core/fixtures/i18n-v3-force-locale/locales/en.yml similarity index 100% rename from middleman-core/fixtures/i18n-force-locale/locales/en.yml rename to middleman-core/fixtures/i18n-v3-force-locale/locales/en.yml diff --git a/middleman-core/fixtures/i18n-force-locale/locales/es.yml b/middleman-core/fixtures/i18n-v3-force-locale/locales/es.yml similarity index 100% rename from middleman-core/fixtures/i18n-force-locale/locales/es.yml rename to middleman-core/fixtures/i18n-v3-force-locale/locales/es.yml diff --git a/middleman-core/fixtures/i18n-force-locale/locales/fr.yml b/middleman-core/fixtures/i18n-v3-force-locale/locales/fr.yml similarity index 100% rename from middleman-core/fixtures/i18n-force-locale/locales/fr.yml rename to middleman-core/fixtures/i18n-v3-force-locale/locales/fr.yml diff --git a/middleman-core/fixtures/i18n-force-locale/source/index.html.haml b/middleman-core/fixtures/i18n-v3-force-locale/source/index.html.haml similarity index 100% rename from middleman-core/fixtures/i18n-force-locale/source/index.html.haml rename to middleman-core/fixtures/i18n-v3-force-locale/source/index.html.haml diff --git a/middleman-core/fixtures/i18n-nested-app/locales/en.yml b/middleman-core/fixtures/i18n-v3-nested-app/locales/en.yml similarity index 100% rename from middleman-core/fixtures/i18n-nested-app/locales/en.yml rename to middleman-core/fixtures/i18n-v3-nested-app/locales/en.yml diff --git a/middleman-core/fixtures/i18n-nested-app/locales/en/more.yml b/middleman-core/fixtures/i18n-v3-nested-app/locales/en/more.yml similarity index 100% rename from middleman-core/fixtures/i18n-nested-app/locales/en/more.yml rename to middleman-core/fixtures/i18n-v3-nested-app/locales/en/more.yml diff --git a/middleman-core/fixtures/i18n-nested-app/locales/es.yml b/middleman-core/fixtures/i18n-v3-nested-app/locales/es.yml similarity index 100% rename from middleman-core/fixtures/i18n-nested-app/locales/es.yml rename to middleman-core/fixtures/i18n-v3-nested-app/locales/es.yml diff --git a/middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml b/middleman-core/fixtures/i18n-v3-nested-app/locales/es/mucho.yml similarity index 100% rename from middleman-core/fixtures/i18n-nested-app/locales/es/mucho.yml rename to middleman-core/fixtures/i18n-v3-nested-app/locales/es/mucho.yml diff --git a/middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb b/middleman-core/fixtures/i18n-v3-nested-app/source/localizable/index.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-nested-app/source/localizable/index.html.erb rename to middleman-core/fixtures/i18n-v3-nested-app/source/localizable/index.html.erb diff --git a/middleman-core/fixtures/i18n-test-app/data/defaults_en.yml b/middleman-core/fixtures/i18n-v3-test-app/data/defaults_en.yml similarity index 100% rename from middleman-core/fixtures/i18n-test-app/data/defaults_en.yml rename to middleman-core/fixtures/i18n-v3-test-app/data/defaults_en.yml diff --git a/middleman-core/fixtures/i18n-test-app/data/defaults_es.yml b/middleman-core/fixtures/i18n-v3-test-app/data/defaults_es.yml similarity index 100% rename from middleman-core/fixtures/i18n-test-app/data/defaults_es.yml rename to middleman-core/fixtures/i18n-v3-test-app/data/defaults_es.yml diff --git a/middleman-core/fixtures/i18n-test-app/data/en_defaults.yml b/middleman-core/fixtures/i18n-v3-test-app/data/en_defaults.yml similarity index 100% rename from middleman-core/fixtures/i18n-test-app/data/en_defaults.yml rename to middleman-core/fixtures/i18n-v3-test-app/data/en_defaults.yml diff --git a/middleman-core/fixtures/i18n-test-app/locales/en.yml b/middleman-core/fixtures/i18n-v3-test-app/locales/en.yml similarity index 100% rename from middleman-core/fixtures/i18n-test-app/locales/en.yml rename to middleman-core/fixtures/i18n-v3-test-app/locales/en.yml diff --git a/middleman-core/fixtures/i18n-test-app/locales/es.yml b/middleman-core/fixtures/i18n-v3-test-app/locales/es.yml similarity index 100% rename from middleman-core/fixtures/i18n-test-app/locales/es.yml rename to middleman-core/fixtures/i18n-v3-test-app/locales/es.yml diff --git a/middleman-core/fixtures/i18n-test-app/source/CNAME b/middleman-core/fixtures/i18n-v3-test-app/source/CNAME similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/CNAME rename to middleman-core/fixtures/i18n-v3-test-app/source/CNAME diff --git a/middleman-core/fixtures/i18n-test-app/source/layouts/layout.erb b/middleman-core/fixtures/i18n-v3-test-app/source/layouts/layout.erb similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/layouts/layout.erb rename to middleman-core/fixtures/i18n-v3-test-app/source/layouts/layout.erb diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/hello.html.erb b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/hello.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/hello.html.erb rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/hello.html.erb diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/index.html.erb b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/index.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/index.html.erb rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/index.html.erb diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/morning.en.html.erb b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/morning.en.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/morning.en.html.erb rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/morning.en.html.erb diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/morning.es.html.erb b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/morning.es.html.erb similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/morning.es.html.erb rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/morning.es.html.erb diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/one.en.html.md b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/one.en.html.md similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/one.en.html.md rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/one.en.html.md diff --git a/middleman-core/fixtures/i18n-test-app/source/localizable/one.es.html.md b/middleman-core/fixtures/i18n-v3-test-app/source/localizable/one.es.html.md similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/localizable/one.es.html.md rename to middleman-core/fixtures/i18n-v3-test-app/source/localizable/one.es.html.md diff --git a/middleman-core/fixtures/i18n-test-app/source/password.txt b/middleman-core/fixtures/i18n-v3-test-app/source/password.txt similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/password.txt rename to middleman-core/fixtures/i18n-v3-test-app/source/password.txt diff --git a/middleman-core/fixtures/i18n-test-app/source/stylesheets/site.css b/middleman-core/fixtures/i18n-v3-test-app/source/stylesheets/site.css similarity index 100% rename from middleman-core/fixtures/i18n-test-app/source/stylesheets/site.css rename to middleman-core/fixtures/i18n-v3-test-app/source/stylesheets/site.css diff --git a/middleman-core/fixtures/i18n-v4-test-app/data/defaults_en.yml b/middleman-core/fixtures/i18n-v4-test-app/data/defaults_en.yml new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/fixtures/i18n-v4-test-app/data/defaults_es.yml b/middleman-core/fixtures/i18n-v4-test-app/data/defaults_es.yml new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/fixtures/i18n-v4-test-app/data/en_defaults.yml b/middleman-core/fixtures/i18n-v4-test-app/data/en_defaults.yml new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/fixtures/i18n-v4-test-app/locales/en.yml b/middleman-core/fixtures/i18n-v4-test-app/locales/en.yml new file mode 100644 index 00000000..91519342 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/locales/en.yml @@ -0,0 +1,4 @@ +--- +en: + greetings: "Howdy" + hi: "Hello" \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-v4-test-app/locales/es.yml b/middleman-core/fixtures/i18n-v4-test-app/locales/es.yml new file mode 100644 index 00000000..a3321546 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/locales/es.yml @@ -0,0 +1,9 @@ +--- +es: + paths: + hello: "hola" + morning: "manana" + one: "una" + + greetings: "Como Esta?" + hi: "Hola" diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/CNAME b/middleman-core/fixtures/i18n-v4-test-app/source/CNAME new file mode 100644 index 00000000..0aca0c56 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/CNAME @@ -0,0 +1 @@ +test.github.com diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/hello.html.erb b/middleman-core/fixtures/i18n-v4-test-app/source/hello.html.erb new file mode 100644 index 00000000..a226480d --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/hello.html.erb @@ -0,0 +1 @@ +<%= I18n.t(:hi) %> World \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/index.html.erb b/middleman-core/fixtures/i18n-v4-test-app/source/index.html.erb new file mode 100644 index 00000000..c39d59f5 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/index.html.erb @@ -0,0 +1 @@ +<%= I18n.t(:greetings) %> \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/layouts/layout.erb b/middleman-core/fixtures/i18n-v4-test-app/source/layouts/layout.erb new file mode 100644 index 00000000..cb465e99 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/layouts/layout.erb @@ -0,0 +1,8 @@ + + + <%= stylesheet_link_tag :site %> + + + <%= yield %> + + \ No newline at end of file diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/morning.en.html.erb b/middleman-core/fixtures/i18n-v4-test-app/source/morning.en.html.erb new file mode 100644 index 00000000..9fc8e015 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/morning.en.html.erb @@ -0,0 +1 @@ +Good morning diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/morning.es.html.erb b/middleman-core/fixtures/i18n-v4-test-app/source/morning.es.html.erb new file mode 100644 index 00000000..30d65605 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/morning.es.html.erb @@ -0,0 +1 @@ +Buenos días diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/one.en.html.md b/middleman-core/fixtures/i18n-v4-test-app/source/one.en.html.md new file mode 100644 index 00000000..2c4dcf4f --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/one.en.html.md @@ -0,0 +1 @@ +Only one diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/one.es.html.md b/middleman-core/fixtures/i18n-v4-test-app/source/one.es.html.md new file mode 100644 index 00000000..8d31bd0f --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/one.es.html.md @@ -0,0 +1 @@ +Solamente una diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/password.txt b/middleman-core/fixtures/i18n-v4-test-app/source/password.txt new file mode 100644 index 00000000..9f592eb7 --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/password.txt @@ -0,0 +1 @@ +hunter2 diff --git a/middleman-core/fixtures/i18n-v4-test-app/source/stylesheets/site.css b/middleman-core/fixtures/i18n-v4-test-app/source/stylesheets/site.css new file mode 100644 index 00000000..ee28067a --- /dev/null +++ b/middleman-core/fixtures/i18n-v4-test-app/source/stylesheets/site.css @@ -0,0 +1,3 @@ +body { + hello: world; +} \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 340ca2fd..705b76f7 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -45,8 +45,13 @@ end # Setup Optional Extensions ### +Middleman::Extensions.register :i18n_v3 do + require 'middleman-core/core_extensions/i18n_v3' + Middleman::CoreExtensions::InternationalizationV3 +end + Middleman::Extensions.register :i18n do - require 'middleman-core/core_extensions/i18n' + require 'middleman-core/core_extensions/i18n_v4' Middleman::CoreExtensions::Internationalization end diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n_v3.rb similarity index 98% rename from middleman-core/lib/middleman-core/core_extensions/i18n.rb rename to middleman-core/lib/middleman-core/core_extensions/i18n_v3.rb index f500d953..7d1cfaaf 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n_v3.rb @@ -1,4 +1,4 @@ -class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension +class Middleman::CoreExtensions::InternationalizationV3 < ::Middleman::Extension option :no_fallbacks, false, 'Disable I18n fallbacks' option :langs, nil, 'List of langs, will autodiscover by default' option :lang_map, {}, 'Language shortname map' diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n_v4.rb b/middleman-core/lib/middleman-core/core_extensions/i18n_v4.rb new file mode 100644 index 00000000..6abb1e7e --- /dev/null +++ b/middleman-core/lib/middleman-core/core_extensions/i18n_v4.rb @@ -0,0 +1,194 @@ +class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension + option :no_fallbacks, false, 'Disable I18n fallbacks' + option :langs, nil, 'List of langs, will autodiscover by default' + option :lang_map, {}, 'Language shortname map' + option :path, '/:locale/', 'URL prefix path' + option :files_glob, ["**/*.html"], 'Files to automatically localize' + option :mount_at_root, nil, 'Mount a specific language at the root of the site' + option :data, 'locales', 'The directory holding your locale configurations' + + def initialize(app, options_hash={}, &block) + super + + # See https://github.com/svenfuchs/i18n/wiki/Fallbacks + unless options[:no_fallbacks] + require 'i18n/backend/fallbacks' + ::I18n::Backend::Simple.send(:include, ::I18n::Backend::Fallbacks) + end + + app.send :include, LocaleHelpers + end + + def after_configuration + # app.files.reload_path(app.config[:locals_dir] || options[:data]) + + # @locales_glob = File.join(app.config[:locals_dir] || options[:data], '**', '*.{rb,yml,yaml}') + # @locales_regex = convert_glob_to_regex(@locales_glob) + + # @maps = {} + # @mount_at_root = options[:mount_at_root].nil? ? langs.first : options[:mount_at_root] + + # configure_i18n + + # if !app.build? + # logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})" + # end + + # app.sitemap.provides_metadata_for_path(&method(:metadata_for_path)) + # app.files.changed(&method(:on_file_changed)) + # app.files.deleted(&method(:on_file_changed)) + end + + helpers do + def t(*args) + ::I18n.t(*args) + end + end + + delegate :logger, :to => :app + + def langs + @_langs ||= get_known_languages + end + + # Update the main sitemap resource list + # @return [void] + # def manipulate_resource_list(resources) + # @_localization_data = {} + + # new_resources = [] + + # resources.each do |resource| + # # If it uses file extension localization + # if !parse_locale_extension(resource.path).nil? + # result = parse_locale_extension(resource.path) + # lang, path, page_id = result + # new_resources << build_resource(path, resource.path, page_id, lang) + # # If it's a "localizable template" + # elsif File.fnmatch?(File.join(options[:templates_dir], '**'), resource.path) + # page_id = File.basename(resource.path, File.extname(resource.path)) + # langs.each do |lang| + # # Remove folder name + # path = resource.path.sub(options[:templates_dir], '') + # new_resources << build_resource(path, resource.path, page_id, lang) + # end + # end + # end + + # resources + new_resources + # end + + private + + def on_file_changed(file) + if @locales_regex =~ file + @_langs = nil # Clear langs cache + ::I18n.reload! + end + end + + def convert_glob_to_regex(glob) + # File.fnmatch doesn't support brackets: {rb,yml,yaml} + regex = @locales_glob.sub(/\./, '\.').sub(File.join('**', '*'), '.*').sub(/\//, '\/').sub('{rb,yml,yaml}', '(rb|ya?ml)') + %r{^#{regex}} + end + + def configure_i18n + ::I18n.load_path += Dir[File.join(app.root, @locales_glob)] + ::I18n.reload! + + ::I18n.default_locale = @mount_at_root + # Reset fallbacks to fall back to our new default + if ::I18n.respond_to? :fallbacks + ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new + end + end + + def metadata_for_path(url) + if d = get_localization_data(url) + lang, page_id = d + else + # Default to the @mount_at_root lang + page_id = nil + lang = @mount_at_root + end + + { + :locals => { + :lang => lang, + :page_id => page_id + }, + :options => { :lang => lang } + } + end + + def get_known_languages + if options[:langs] + Array(options[:langs]).map(&:to_sym) + else + known_langs = app.files.known_paths.select do |p| + p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length === 2) + end.map { |p| + File.basename(p.to_s).sub(/\.ya?ml$/, '').sub(/\.rb$/, '') + }.sort.map(&:to_sym) + end + end + + def get_localization_data(path) + @_localization_data ||= {} + @_localization_data[path] + end + + # Parse locale extension filename + # @return [lang, path, basename] + # will return +nil+ if no locale extension + def parse_locale_extension(path) + path_bits = path.split('.') + return nil if path_bits.size < 3 + + lang = path_bits.delete_at(-2).to_sym + return nil unless langs.include?(lang) + + path = path_bits.join('.') + basename = File.basename(path_bits[0..-2].join('.')) + [lang, path, basename] + end + + def build_resource(path, source_path, page_id, lang) + old_locale = ::I18n.locale + ::I18n.locale = lang + localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => []) + + prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root] == nil && langs[0] == lang) + '/' + else + replacement = options[:lang_map].fetch(lang, lang) + options[:path].sub(':locale', replacement.to_s) + end + + # path needs to be changed if file has a localizable extension. (options[mount_at_root] == lang) + path = ::Middleman::Util.normalize_path( + File.join(prefix, path.sub(page_id, localized_page_id)) + ) + + path.gsub!(options[:templates_dir]+'/', '') + + @_localization_data[path] = [lang, path, localized_page_id] + + p = ::Middleman::Sitemap::Resource.new(app.sitemap, path) + p.proxy_to(source_path) + + ::I18n.locale = old_locale + p + end + + module LocaleHelpers + # Access the list of languages supported by this Middleman application + # @return [Array] + def langs + extensions[:i18n].langs + end + end +end + +Middleman::CoreExtensions::Internationalization.register(:i18n) From ffe9226aac3992c4f9afc910e039cbaf41c91019 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 28 Apr 2014 10:21:14 -0700 Subject: [PATCH 005/662] Remove root config options for minification --- CHANGELOG.md | 2 ++ middleman-core/features/minify_css.feature | 8 ++---- .../features/minify_javascript.feature | 12 +++------ .../middleman-core/extensions/minify_css.rb | 24 ++++++++--------- .../extensions/minify_javascript.rb | 27 ++++++++----------- 5 files changed, 29 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57672727..31e38c34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ master === +* Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead. +* Removed `js_compressor` setting, use `activate :minify_javascript, :compressor =>` instead. * Removed ability to server folders of content statically (non-Middleman projects). * Prevent local templates being loaded when $HOME is not set * Removed "Implied Extension feature" diff --git a/middleman-core/features/minify_css.feature b/middleman-core/features/minify_css.feature index 0c707861..e6bc948f 100644 --- a/middleman-core/features/minify_css.feature +++ b/middleman-core/features/minify_css.feature @@ -36,9 +36,7 @@ Feature: Minify CSS end end - activate :minify_css - - set :css_compressor, ::PassThrough + activate :minify_css, :compressor => ::PassThrough """ And the Server is running at "passthrough-app" When I go to "/stylesheets/site.css" @@ -71,9 +69,7 @@ Feature: Minify CSS end end - activate :minify_css, :inline => true - - set :css_compressor, ::PassThrough + activate :minify_css, :inline => true, :compressor => ::PassThrough page "/inline-css.html", :layout => false """ diff --git a/middleman-core/features/minify_javascript.feature b/middleman-core/features/minify_javascript.feature index 7d6b71ff..73e05f44 100644 --- a/middleman-core/features/minify_javascript.feature +++ b/middleman-core/features/minify_javascript.feature @@ -49,9 +49,7 @@ Feature: Minify Javascript end end - activate :minify_javascript, :inline => true - - set :js_compressor, ::PassThrough + activate :minify_javascript, :inline => true, :compressor => ::PassThrough page "/inline-js.html", :layout => false """ @@ -195,9 +193,7 @@ Feature: Minify Javascript end end - activate :minify_javascript, :inline => true - - set :js_compressor, ::PassThrough + activate :minify_javascript, :inline => true, :compressor => ::PassThrough page "/inline-coffeescript.html", :layout => false """ @@ -215,9 +211,7 @@ Feature: Minify Javascript end end - activate :minify_javascript - - set :js_compressor, ::PassThrough + activate :minify_javascript, :compressor => ::PassThrough """ And the Server is running at "passthrough-app" When I go to "/javascripts/coffee_test.js" diff --git a/middleman-core/lib/middleman-core/extensions/minify_css.rb b/middleman-core/lib/middleman-core/extensions/minify_css.rb index 1945f4c1..dcf89e91 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_css.rb @@ -1,20 +1,15 @@ # Minify CSS Extension class Middleman::Extensions::MinifyCss < ::Middleman::Extension - option :compressor, nil, 'Set the CSS compressor to use.' option :inline, false, 'Whether to minify CSS inline within HTML files' option :ignore, [], 'Patterns to avoid minifying' - - def initialize(app, options_hash={}, &block) - super - - app.config.define_setting :css_compressor, nil, 'Set the CSS compressor to use. Deprecated in favor of the :compressor option when activating :minify_css' - end + option :compressor, Proc.new { + require 'sass' + SassCompressor + }, 'Set the CSS compressor to use.' def after_configuration - chosen_compressor = app.config[:css_compressor] || options[:compressor] || SassCompressor - # Setup Rack middleware to minify CSS - app.use Rack, :compressor => chosen_compressor, + app.use Rack, :compressor => options[:compressor], :ignore => Array(options[:ignore]) + [/\.min\./], :inline => options[:inline] end @@ -36,9 +31,12 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension # @param [Hash] options def initialize(app, options={}) @app = app - @compressor = options[:compressor] - @ignore = options[:ignore] - @inline = options[:inline] + @ignore = options.fetch(:ignore) + @inline = options.fetch(:inline) + + @compressor = options.fetch(:compressor) + @compressor = @compressor.to_proc if @compressor.respond_to? :to_proc + @compressor = @compressor.call if @compressor.is_a? Proc end # Rack interface diff --git a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb index ecacae4c..240e9a5d 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb @@ -1,23 +1,15 @@ # Minify Javascript Extension class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension - option :compressor, nil, 'Set the JS compressor to use.' option :inline, false, 'Whether to minify JS inline within HTML files' option :ignore, [], 'Patterns to avoid minifying' - - def initialize(app, options_hash={}, &block) - super - - app.config.define_setting :js_compressor, nil, 'Set the JS compressor to use. Deprecated in favor of the :compressor option when activating :minify_js' - end + option :compressor, Proc.new { + require 'uglifier' + ::Uglifier.new + }, 'Set the JS compressor to use.' def after_configuration - chosen_compressor = app.config[:js_compressor] || options[:compressor] || begin - require 'uglifier' - ::Uglifier.new - end - # Setup Rack middleware to minify CSS - app.use Rack, :compressor => chosen_compressor, + app.use Rack, :compressor => options[:compressor], :ignore => Array(options[:ignore]) + [/\.min\./], :inline => options[:inline] end @@ -30,9 +22,12 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension # @param [Hash] options def initialize(app, options={}) @app = app - @compressor = options[:compressor] - @ignore = options[:ignore] - @inline = options[:inline] + @ignore = options.fetch(:ignore) + @inline = options.fetch(:inline) + + @compressor = options.fetch(:compressor) + @compressor = @compressor.to_proc if @compressor.respond_to? :to_proc + @compressor = @compressor.call if @compressor.is_a? Proc end # Rack interface From 1e43784cc2fa6585f0c6ce7265bd54156b00aeaa Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 28 Apr 2014 10:28:16 -0700 Subject: [PATCH 006/662] remove queryable api --- CHANGELOG.md | 1 + middleman-core/features/queryable.feature | 35 ---- .../step_definitions/queryable_steps.rb | 135 --------------- .../lib/middleman-core/sitemap/queryable.rb | 155 ------------------ .../lib/middleman-core/sitemap/store.rb | 3 - 5 files changed, 1 insertion(+), 328 deletions(-) delete mode 100644 middleman-core/features/queryable.feature delete mode 100644 middleman-core/features/step_definitions/queryable_steps.rb delete mode 100644 middleman-core/lib/middleman-core/sitemap/queryable.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 31e38c34..5cbd238b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* Removed Queryable Sitemap API * Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead. * Removed `js_compressor` setting, use `activate :minify_javascript, :compressor =>` instead. * Removed ability to server folders of content statically (non-Middleman projects). diff --git a/middleman-core/features/queryable.feature b/middleman-core/features/queryable.feature deleted file mode 100644 index 1382db3f..00000000 --- a/middleman-core/features/queryable.feature +++ /dev/null @@ -1,35 +0,0 @@ -Feature: Queryable Selector - Scenario: Basic Selector Tests - Then should initialize with an attribute and an operator - Then should raise an exception if the operator is not supported - Scenario: Using offset and limit - Given the Server is running at "queryable-app" - Then should limit the documents to the number specified - Then should offset the documents by the number specified - Then should support offset and limit at the same time - Then should not freak out about an offset higher than the document count - Scenario: Using where queries with an equal operator - Given the Server is running at "queryable-app" - Then should return the right documents - Then should be chainable - Then should not be confused by attributes not present in all documents - Scenario: Using where queries with a complex operator - Given the Server is running at "queryable-app" - Then with a gt operator should return the right documents - Then with a gte operator should return the right documents - Then with an in operator should return the right documents - Then with an lt operator should return the right documents - Then with an lte operator should return the right documents - Then with an include operator include should return the right documents - Then with mixed operators should return the right documents - Then using multiple constrains in one where should return the right documents - Scenario: Sorting documents - Given the Server is running at "queryable-app" - Then should support ordering by attribute ascending - Then should support ordering by attribute descending - Then should order by attribute ascending by default - Then should exclude documents that do not own the attribute - Scenario: Passing queries around - Given a simple 'where' query - When I chain a where clause onto that query - Then the original query should remain unchanged diff --git a/middleman-core/features/step_definitions/queryable_steps.rb b/middleman-core/features/step_definitions/queryable_steps.rb deleted file mode 100644 index 995c3d33..00000000 --- a/middleman-core/features/step_definitions/queryable_steps.rb +++ /dev/null @@ -1,135 +0,0 @@ -Given /^a simple 'where' query$/ do - @query = Middleman::Sitemap::Queryable::Query.new({}).where(:foo => 'bar') -end - -When /^I chain a where clause onto that query$/ do - @new_query = @query.where(:baz => 'foo') -end - -Then /^the original query should remain unchanged$/ do - @query.opts({}).should_not eql @new_query.opts({}) -end - -Then /^should initialize with an attribute and an operator$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'equal' - :author.should == selector.attribute - 'equal'.should == selector.operator -end - -Then /^should raise an exception if the operator is not supported$/ do - expect { - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :author, :operator => 'zomg' - }.to raise_error(::Middleman::Sitemap::Queryable::OperatorNotSupportedError) -end - -Then /^should limit the documents to the number specified$/ do - @server_inst.sitemap.order_by(:id).limit(2).all.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort -end - -Then /^should offset the documents by the number specified$/ do - @server_inst.sitemap.order_by(:id).offset(2).all.map { |r| r.raw_data[:id] }.sort.should == [3,4,5].sort -end - -Then /^should support offset and limit at the same time$/ do - @server_inst.sitemap.order_by(:id).offset(1).limit(2).all.map { |r| r.raw_data[:id] }.sort.should == [2,3].sort -end - -Then /^should not freak out about an offset higher than the document count$/ do - @server_inst.sitemap.order_by(:id).offset(5).all.should == [] -end - -Then /^should return the right documents$/ do - documents = @server_inst.sitemap.resources.select { |r| !r.raw_data.empty? } - document_1 = documents[0] - document_2 = documents[1] - - found_document = @server_inst.sitemap.where(:title => document_1.raw_data[:title]).first - document_1.should == found_document - - found_document = @server_inst.sitemap.where(:title => document_2.raw_data[:title]).first - document_2.should == found_document -end - -Then /^should be chainable$/ do - documents = @server_inst.sitemap.resources.select { |r| !r.raw_data.empty? } - document_1 = documents[0] - - document_proxy = @server_inst.sitemap.where(:title => document_1.raw_data[:title]) - document_proxy.where(:id => document_1.raw_data[:id]) - document_1.should == document_proxy.first -end - -Then /^should not be confused by attributes not present in all documents$/ do - result = @server_inst.sitemap.where(:seldom_attribute => 'is seldom').all - result.map { |r| r.raw_data[:id] }.should == [4] -end - -Then /^with a gt operator should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gt' - found_documents = @server_inst.sitemap.where(selector => 2).all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [5,3,4].sort -end - -Then /^with a gte operator should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gte' - found_documents = @server_inst.sitemap.where(selector => 2).all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [2,5,3,4].sort -end - -Then /^with an in operator should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'in' - found_documents = @server_inst.sitemap.where(selector => [2,3]).all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [2,3].sort -end - -Then /^with an lt operator should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lt' - found_documents = @server_inst.sitemap.where(selector => 2).all - found_documents.map { |r| r.raw_data[:id] }.should == [1] -end - -Then /^with an lte operator should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lte' - found_documents = @server_inst.sitemap.where(selector => 2).all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort -end - -Then /^with an include operator include should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :tags, :operator => 'include' - found_documents = @server_inst.sitemap.where(selector => 'ruby').all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort -end - -Then /^with mixed operators should return the right documents$/ do - in_selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'in' - gt_selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'gt' - documents_proxy = @server_inst.sitemap.where(in_selector => [2,3]) - found_documents = documents_proxy.where(gt_selector => 2).all - found_documents.map { |r| r.raw_data[:id] }.should == [3] -end - -Then /^using multiple constrains in one where should return the right documents$/ do - selector = ::Middleman::Sitemap::Queryable::Selector.new :attribute => :id, :operator => 'lte' - found_documents = @server_inst.sitemap.where(selector => 2, :status => :published).all - found_documents.map { |r| r.raw_data[:id] }.sort.should == [1,2].sort -end - -Then /^should support ordering by attribute ascending$/ do - found_documents = @server_inst.sitemap.order_by(:title => :asc).all - found_documents.map { |r| r.raw_data[:id] }.should == [2,3,1,5,4] -end - -Then /^should support ordering by attribute descending$/ do - found_documents = @server_inst.sitemap.order_by(:title => :desc).all - found_documents.map { |r| r.raw_data[:id] }.should == [4,5,1,3,2] -end - -Then /^should order by attribute ascending by default$/ do - found_documents = @server_inst.sitemap.order_by(:title).all - found_documents.map { |r| r.raw_data[:id] }.should == [2,3,1,5,4] -end - -Then /^should exclude documents that do not own the attribute$/ do - found_documents = @server_inst.sitemap.order_by(:status).all - found_documents.map { |r| r.raw_data[:id] }.to_set.should == [1,2].to_set -end diff --git a/middleman-core/lib/middleman-core/sitemap/queryable.rb b/middleman-core/lib/middleman-core/sitemap/queryable.rb deleted file mode 100644 index aab8be4e..00000000 --- a/middleman-core/lib/middleman-core/sitemap/queryable.rb +++ /dev/null @@ -1,155 +0,0 @@ -require 'active_support/core_ext/object/inclusion' - -module Middleman - module Sitemap - - # Code adapted from https://github.com/ralph/document_mapper/ - module Queryable - OPERATOR_MAPPING = { - 'equal' => :==, - 'gt' => :>, - 'gte' => :>=, - 'in' => :in?, - 'include' => :include?, - 'lt' => :<, - 'lte' => :<= - } - - VALID_OPERATORS = OPERATOR_MAPPING.keys - - FileNotFoundError = Class.new StandardError - OperatorNotSupportedError = Class.new StandardError - - module API - def select(options = {}) - documents = resources.select { |r| !r.raw_data.empty? } - options[:where].each do |selector, selector_value| - documents = documents.select do |document| - next unless document.raw_data.has_key? selector.attribute - document_value = document.raw_data[selector.attribute] - operator = OPERATOR_MAPPING[selector.operator] - document_value.send operator, selector_value - end - end - - if options[:order_by].present? - order_attribute = options[:order_by].keys.first - asc_or_desc = options[:order_by].values.first - documents = documents.select do |document| - document.raw_data.include? order_attribute - end - documents = documents.sort_by do |document| - document.raw_data[order_attribute] - end - documents.reverse! if asc_or_desc == :desc - end - - documents - end - - def where(hash) - Query.new(self).where(hash) - end - - def order_by(field) - Query.new(self).order_by(field) - end - - def offset(number) - Query.new(self).offset(number) - end - - def limit(number) - Query.new(self).limit(number) - end - end - - class Query - def initialize(model, opts={}) - @model = model - @where = opts[:where] || {} - @order_by = opts[:order_by] - @offset = opts[:offset] - @limit = opts[:limit] - end - - def where(constraints_hash) - selector_hash = constraints_hash.reject { |key, value| !key.is_a? Selector } - symbol_hash = constraints_hash.reject { |key, value| key.is_a? Selector } - symbol_hash.each do |attribute, value| - selector = Selector.new(:attribute => attribute, :operator => 'equal') - selector_hash.update({ selector => value }) - end - Query.new @model, opts(:where => @where.merge(selector_hash)) - end - - def opts new_opts - { :where => {}.merge(@where), - :order_by => @order_by, - :offset => @offset, - :limit => @limit - }.merge(new_opts) - end - - def order_by(field) - Query.new @model, opts(:order_by => field.is_a?(Symbol) ? {field => :asc} : field) - end - - def offset(number) - Query.new @model, opts(:offset => number) - end - - def limit(number) - Query.new @model, opts(:limit => number) - end - - def first - self.all.first - end - - def last - self.all.last - end - - def all - result = @model.select(:where => @where, :order_by => @order_by) - if @offset.present? - result = result.last([result.size - @offset, 0].max) - end - if @limit.present? - result = result.first(@limit) - end - result - end - end - - class Selector - attr_reader :attribute, :operator - - def initialize(opts = {}) - unless VALID_OPERATORS.include? opts[:operator] - raise OperatorNotSupportedError - end - @attribute, @operator = opts[:attribute], opts[:operator] - end - end - end - end -end - -# Add operators to symbol objects -class Symbol - Middleman::Sitemap::Queryable::VALID_OPERATORS.each do |operator| - class_eval <<-OPERATORS - def #{operator} - Middleman::Sitemap::Queryable::Selector.new(:attribute => self, :operator => '#{operator}') - end - OPERATORS - end - - unless method_defined?(:"<=>") - def <=>(other) - self.to_s <=> other.to_s - end - end -end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 217fa6c3..be067c04 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -1,7 +1,6 @@ # Used for merging results of metadata callbacks require 'active_support/core_ext/hash/deep_merge' require 'monitor' -require 'middleman-core/sitemap/queryable' # Extensions require 'middleman-core/sitemap/extensions/on_disk' @@ -26,8 +25,6 @@ module Middleman # @return [Middleman::Application] attr_accessor :app - include ::Middleman::Sitemap::Queryable::API - # Initialize with parent app # @param [Middleman::Application] app def initialize(app) From 04dc48f13df934198eeb4a71a8cc97633c6f61e9 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 28 Apr 2014 16:02:18 -0700 Subject: [PATCH 007/662] Great rubocop-ing --- .rubocop.yml | 52 +++++++++---- Gemfile | 1 - Rakefile | 56 +++----------- gem_rake_helper.rb | 4 +- middleman-core/lib/middleman-core.rb | 2 - .../lib/middleman-core/application.rb | 2 +- middleman-core/lib/middleman-core/cli.rb | 16 ++-- .../lib/middleman-core/cli/build.rb | 48 ++++++------ .../lib/middleman-core/cli/bundler.rb | 11 ++- .../lib/middleman-core/cli/console.rb | 15 ++-- .../lib/middleman-core/cli/extension.rb | 2 - middleman-core/lib/middleman-core/cli/init.rb | 55 +++++++------- .../lib/middleman-core/cli/server.rb | 69 +++++++++-------- .../lib/middleman-core/configuration.rb | 14 ++-- .../middleman-core/core_extensions/data.rb | 40 +++++----- .../core_extensions/extensions.rb | 13 ++-- .../core_extensions/external_helpers.rb | 8 +- .../core_extensions/file_watcher.rb | 16 ++-- .../core_extensions/front_matter.rb | 8 +- .../core_extensions/rendering.rb | 41 +++++----- .../middleman-core/core_extensions/request.rb | 22 +++--- .../middleman-core/core_extensions/routing.rb | 74 +++++++++---------- .../core_extensions/show_exceptions.rb | 2 - .../lib/middleman-core/extension.rb | 13 ++-- .../lib/middleman-core/extensions.rb | 10 +-- .../lib/middleman-core/load_paths.rb | 9 +-- middleman-core/lib/middleman-core/logger.rb | 4 +- .../lib/middleman-core/meta_pages.rb | 12 +-- .../middleman-core/meta_pages/sitemap_tree.rb | 2 +- .../lib/middleman-core/preview_server.rb | 7 +- .../lib/middleman-core/profiling.rb | 11 +-- .../lib/middleman-core/renderers/asciidoc.rb | 11 ++- .../middleman-core/renderers/coffee_script.rb | 4 +- .../lib/middleman-core/renderers/erb.rb | 5 +- .../lib/middleman-core/renderers/haml.rb | 4 +- .../lib/middleman-core/renderers/kramdown.rb | 3 +- .../lib/middleman-core/renderers/less.rb | 8 +- .../lib/middleman-core/renderers/liquid.rb | 6 +- .../lib/middleman-core/renderers/markdown.rb | 8 +- .../lib/middleman-core/renderers/redcarpet.rb | 24 +++--- .../lib/middleman-core/renderers/sass.rb | 9 +-- .../lib/middleman-core/renderers/slim.rb | 5 +- .../lib/middleman-core/renderers/stylus.rb | 6 +- middleman-core/lib/middleman-core/sitemap.rb | 13 +--- .../sitemap/extensions/ignores.rb | 14 +--- .../sitemap/extensions/on_disk.rb | 4 - .../sitemap/extensions/proxies.rb | 11 +-- .../sitemap/extensions/redirects.rb | 16 ++-- .../sitemap/extensions/request_endpoints.rb | 18 ++--- .../sitemap/extensions/traversal.rb | 11 +-- .../lib/middleman-core/sitemap/queryable.rb | 19 +++-- .../lib/middleman-core/sitemap/resource.rb | 22 +++--- .../lib/middleman-core/sitemap/store.rb | 15 ++-- .../lib/middleman-core/templates.rb | 4 +- .../lib/middleman-core/templates/default.rb | 13 ++-- .../lib/middleman-core/templates/empty.rb | 1 - .../templates/extension/Gemfile | 2 +- .../templates/extension/Rakefile | 2 +- .../templates/extension/lib/lib.rb | 1 - .../lib/middleman-core/templates/html5.rb | 13 ++-- .../lib/middleman-core/templates/local.rb | 3 +- .../lib/middleman-core/templates/mobile.rb | 1 - .../middleman-core/templates/shared/config.ru | 2 +- middleman-core/lib/middleman-core/util.rb | 11 ++- .../middleman-more/core_extensions/compass.rb | 1 - .../core_extensions/default_helpers.rb | 39 ++++++---- .../middleman-more/core_extensions/i18n.rb | 25 ++++--- .../middleman-more/extensions/asset_hash.rb | 8 +- .../middleman-more/extensions/asset_host.rb | 2 +- .../extensions/automatic_alt_tags.rb | 5 +- .../extensions/automatic_image_sizes.rb | 7 +- .../middleman-more/extensions/cache_buster.rb | 1 - .../lib/middleman-more/extensions/gzip.rb | 2 +- .../lib/middleman-more/extensions/lorem.rb | 16 ++-- .../middleman-more/extensions/minify_css.rb | 11 +-- .../extensions/minify_javascript.rb | 5 +- .../extensions/relative_assets.rb | 1 - .../lib/middleman-more/templates/smacss.rb | 13 ++-- 78 files changed, 457 insertions(+), 607 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 44966aac..152ea112 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,18 +1,19 @@ AllCops: Include: - - Rakefile - - Gemfile - - config.ru - - gem_rake_helper.rb + - '**/Rakefile' + - '**/Gemfile' + - '**/config.ru' + - '**/gem_rake_helper.rb' Exclude: - - script/** - - vendor/** - - bin/** - - middleman-core/lib/vendored-middleman-deps/** - - middleman-core/bin/** - - middleman-core/fixtures/** - - middleman-core/features/** - - middleman-core/spec/** + - 'script/**/*' + - 'vendor/**/*' + - '**/tmp/**/*' + - '**/bin/**/*' + - 'middleman-core/lib/middleman-core/step_definitions/**/*' + - 'middleman-core/lib/vendored-middleman-deps/**/*' + - 'middleman-core/fixtures/**/*' + - 'middleman-core/features/**/*' + - 'middleman-core/spec/**/*' LineLength: Enabled: false MethodLength: @@ -24,4 +25,29 @@ Documentation: Encoding: Enabled: false HashSyntax: - EnforcedStyle: ruby19 \ No newline at end of file + # EnforcedStyle: ruby19 + Enabled: false +SpaceAroundEqualsInParameterDefault: + EnforcedStyle: no_space +Blocks: + Enabled: false +PerlBackrefs: + Enabled: false +ClassAndModuleChildren: + Enabled: false +AssignmentInCondition: + Enabled: false +CyclomaticComplexity: + Enabled: false +HandleExceptions: + Enabled: false +EndAlignment: + AlignWith: variable +SignalException: + Enabled: false +RegexpLiteral: + Enabled: false +FormatString: + Enabled: false +CaseIndentation: + IndentWhenRelativeTo: end \ No newline at end of file diff --git a/Gemfile b/Gemfile index 34409c67..2f4e97a3 100644 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,6 @@ platforms :jruby do end # Code Quality -gem 'cane', :platforms => [:mri_19, :mri_20], :require => false gem 'coveralls', :require => false gem 'rubocop', :require => false diff --git a/Rakefile b/Rakefile index 642efee9..efae9ae9 100644 --- a/Rakefile +++ b/Rakefile @@ -14,41 +14,17 @@ def sh_rake(command) sh "#{Gem.ruby} -S rake #{command}", :verbose => true end -def say(text, color=:magenta) - n = { :bold => 1, :red => 31, :green => 32, :yellow => 33, :blue => 34, :magenta => 35 }.fetch(color, 0) - puts "\e[%dm%s\e[0m" % [n, text] -end - -desc "Run 'install' for all projects" -task :install do - GEM_PATHS.each do |dir| - Dir.chdir(dir) { sh_rake(:install) } - end -end - -desc 'Clean pkg and other stuff' -task :clean do - GEM_PATHS.each do |g| - %w[tmp pkg coverage].each { |dir| sh 'rm -rf %s' % File.join(g, dir) } - end -end - -desc 'Clean pkg and other stuff' -task :uninstall do - sh 'gem search --no-version middleman | grep middleman | xargs gem uninstall -a' -end - desc 'Displays the current version' task :version do - say "Current version: #{Middleman::VERSION}" + puts "Current version: #{Middleman::VERSION}" end desc 'Bumps the version number based on given version' -task :bump, [:version] do |t, args| +task :bump, [:version] do |_, args| raise 'Please specify version=x.x.x !' unless args.version version_path = File.dirname(__FILE__) + '/middleman-core/lib/middleman-core/version.rb' version_text = File.read(version_path).sub(/VERSION = '[\d\.\w]+'/, "VERSION = '#{args.version}'") - say "Updating Middleman to version #{args.version}" + puts "Updating Middleman to version #{args.version}" File.open(version_path, 'w') { |f| f.write version_text } sh 'git commit -a -m "Bumped version to %s"' % args.version end @@ -58,7 +34,7 @@ task :fresh => [:uninstall, :install, :clean] desc 'Pushes repository to GitHub' task :push do - say 'Pushing to github...' + puts 'Pushing to github...' sh "git tag v#{Middleman::VERSION}" sh 'git push origin master' sh "git push origin v#{Middleman::VERSION}" @@ -66,7 +42,7 @@ end desc 'Release all middleman gems' task :publish => :push do - say 'Pushing to rubygems...' + puts 'Pushing to rubygems...' GEM_PATHS.each do |dir| Dir.chdir(dir) { sh_rake('release') } end @@ -94,24 +70,10 @@ task :spec do end end -begin - require 'cane/rake_task' - desc 'Run cane to check quality metrics' - Cane::RakeTask.new(:quality) do |cane| - cane.no_style = true - cane.no_doc = true - cane.abc_glob = 'middleman*/lib/middleman*/**/*.rb' - end -rescue LoadError -end - -begin - require 'rubocop/rake_task' - desc 'Run RuboCop to check code consistency' - Rubocop::RakeTask.new(:rubocop) do |task| - task.fail_on_error = false - end -rescue LoadError +require 'rubocop/rake_task' +desc 'Run RuboCop to check code consistency' +Rubocop::RakeTask.new(:rubocop) do |task| + task.fail_on_error = false end desc 'Run tests for all middleman gems' diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index d6e78861..5dab239b 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -20,14 +20,14 @@ Cucumber::Rake::Task.new do |t| exempt_tags << '--tags ~@nojava' if RUBY_PLATFORM == 'java' exempt_tags << '--tags ~@encoding' unless Object.const_defined?(:Encoding) exempt_tags << '--tags ~@travishatesme' if ENV['TRAVIS'] == 'true' - t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" + 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'}" + t.cucumber_opts = "--color #{exempt_tags.join(' ')} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" end require 'rspec/core/rake_task' diff --git a/middleman-core/lib/middleman-core.rb b/middleman-core/lib/middleman-core.rb index be446a51..5d3dc485 100644 --- a/middleman-core/lib/middleman-core.rb +++ b/middleman-core/lib/middleman-core.rb @@ -4,10 +4,8 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) # Top-level Middleman namespace module Middleman - # Backwards compatibility namespace module Features; end - end require 'middleman-core/version' diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 9c331b4d..01027640 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -225,7 +225,7 @@ module Middleman def to_s "#" end - alias :inspect :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s + alias_method :inspect, :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s # Hooks clones _hooks from the class to the instance. # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 diff --git a/middleman-core/lib/middleman-core/cli.rb b/middleman-core/lib/middleman-core/cli.rb index 350baf35..e086e8e6 100644 --- a/middleman-core/lib/middleman-core/cli.rb +++ b/middleman-core/lib/middleman-core/cli.rb @@ -4,9 +4,7 @@ require 'thor/group' # CLI Module module Middleman - module Cli - # The base task from which everything else etends class Base < Thor class << self @@ -32,16 +30,16 @@ module Middleman # @param [Symbol, String, nil] meth # @param [Boolean] subcommand # @return [void] - def help(meth = nil, subcommand = false) + def help(meth=nil, subcommand=false) if meth && !self.respond_to?(meth) klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") - klass.start(['-h', task].compact, :shell => self.shell) + klass.start(['-h', task].compact, :shell => shell) else list = [] Thor::Util.thor_classes_in(Middleman::Cli).each do |thor_class| list += thor_class.printable_tasks(false) end - list.sort!{ |a,b| a[0] <=> b[0] } + list.sort! { |a, b| a[0] <=> b[0] } shell.say 'Tasks:' shell.print_table(list, :ident => 2, :truncate => true) @@ -54,7 +52,7 @@ module Middleman def method_missing(meth, *args) meth = meth.to_s - if self.class.map.has_key?(meth) + if self.class.map.key?(meth) meth = self.class.map[meth] end @@ -63,17 +61,17 @@ module Middleman if klass.nil? tasks_dir = File.join(Dir.pwd, 'tasks') - if File.exists?(tasks_dir) + if File.exist?(tasks_dir) Dir[File.join(tasks_dir, '**/*_task.rb')].each { |f| require f } klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") end end if klass.nil? - raise Thor::Error.new "There's no '#{meth}' command for Middleman. Try 'middleman help' for a list of commands." + raise Thor::Error, "There's no '#{meth}' command for Middleman. Try 'middleman help' for a list of commands." else args.unshift(task) if task - klass.start(args, :shell => self.shell) + klass.start(args, :shell => shell) end end end diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index b644fa90..836f3139 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -4,7 +4,7 @@ require 'set' # CLI Module module Middleman::Cli # Alias "b" to "build" - Base.map({ 'b' => 'build' }) + Base.map('b' => 'build') # The CLI Build class class Build < Thor @@ -19,31 +19,31 @@ module Middleman::Cli desc 'build [options]', 'Builds the static site for deployment' method_option :clean, - :type => :boolean, - :default => true, - :desc => 'Remove orphaned files from build (--no-clean to disable)' + :type => :boolean, + :default => true, + :desc => 'Remove orphaned files from build (--no-clean to disable)' method_option :glob, - :type => :string, - :aliases => '-g', - :default => nil, - :desc => 'Build a subset of the project' + :type => :string, + :aliases => '-g', + :default => nil, + :desc => 'Build a subset of the project' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + :type => :boolean, + :default => false, + :desc => 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + :type => :string, + :default => false, + :desc => 'Print instrument messages' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for the build' + :type => :boolean, + :default => false, + :desc => 'Generate profiling report for the build' # Core build Thor command # @return [void] def build - if !ENV['MM_ROOT'] + unless ENV['MM_ROOT'] raise Thor::Error, 'Error: Could not find a Middleman project config, perhaps you are in the wrong folder?' end @@ -62,7 +62,7 @@ module Middleman::Cli self.class.shared_instance(options['verbose'], options['instrument']) opts = {} - opts[:glob] = options['glob'] if options.has_key?('glob') + opts[:glob] = options['glob'] if options.key?('glob') opts[:clean] = options['clean'] self.class.shared_instance.run_hook :before_build, self @@ -71,15 +71,15 @@ module Middleman::Cli self.class.shared_instance.run_hook :after_build, self - if self.had_errors && !self.debugging + if had_errors && !debugging msg = 'There were errors during this build' unless options['verbose'] msg << ', re-run with `middleman build --verbose` to see the full exception.' end - self.shell.say msg, :red + shell.say msg, :red end - exit(1) if self.had_errors + exit(1) if had_errors end # Static methods @@ -129,7 +129,7 @@ module Middleman::Cli clean! if should_clean? end - protected + protected # Remove files which were not built in this cycle # @return [void] @@ -138,7 +138,7 @@ module Middleman::Cli base.remove_file f, :force => true end - Dir[@build_dir.join('**', '*')].select {|d| File.directory?(d) }.each do |d| + Dir[@build_dir.join('**', '*')].select { |d| File.directory?(d) }.each do |d| base.remove_file d, :force => true if directory_empty? d end end diff --git a/middleman-core/lib/middleman-core/cli/bundler.rb b/middleman-core/lib/middleman-core/cli/bundler.rb index 43a0d862..73bbd326 100644 --- a/middleman-core/lib/middleman-core/cli/bundler.rb +++ b/middleman-core/lib/middleman-core/cli/bundler.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # A initializing Bundler class Bundle < Thor include Thor::Actions @@ -12,7 +11,7 @@ module Middleman::Cli # The setup task def bundle - run('bundle install')#, :capture => true) + run('bundle install')# , :capture => true) end end @@ -28,13 +27,13 @@ module Middleman::Cli # The upgrade task def upgrade inside(ENV['MM_ROOT']) do - run('bundle update')#, :capture => true) + run('bundle update')# , :capture => true) end end end # Map "u" to "upgrade" - Base.map({ - 'u' => 'upgrade' - }) + Base.map( + 'u' => 'upgrade' + ) end diff --git a/middleman-core/lib/middleman-core/cli/console.rb b/middleman-core/lib/middleman-core/cli/console.rb index e75b1aa9..86b660da 100644 --- a/middleman-core/lib/middleman-core/cli/console.rb +++ b/middleman-core/lib/middleman-core/cli/console.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # A thor task for creating new projects class Console < Thor include Thor::Actions @@ -11,13 +10,13 @@ module Middleman::Cli desc 'console [options]', 'Start an interactive console in the context of your Middleman application' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + :aliases => '-e', + :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + :desc => 'The environment Middleman will run under' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + :type => :boolean, + :default => false, + :desc => 'Print debug messages' def console require 'middleman-core' require 'irb' @@ -27,7 +26,7 @@ module Middleman::Cli :debug => options['verbose'] } - @app =::Middleman::Application.server.inst do + @app = ::Middleman::Application.server.inst do if opts[:environment] set :environment, opts[:environment].to_sym end diff --git a/middleman-core/lib/middleman-core/cli/extension.rb b/middleman-core/lib/middleman-core/cli/extension.rb index 1b077f50..b4c92d81 100644 --- a/middleman-core/lib/middleman-core/cli/extension.rb +++ b/middleman-core/lib/middleman-core/cli/extension.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # A thor task for creating new projects class Extension < Thor include Thor::Actions @@ -44,6 +43,5 @@ module Middleman::Cli copy_file 'gitignore', File.join(name, '.gitignore') end } - end end diff --git a/middleman-core/lib/middleman-core/cli/init.rb b/middleman-core/lib/middleman-core/cli/init.rb index c96e29b4..e010c860 100644 --- a/middleman-core/lib/middleman-core/cli/init.rb +++ b/middleman-core/lib/middleman-core/cli/init.rb @@ -2,7 +2,6 @@ require 'middleman-core/templates' # CLI Module module Middleman::Cli - # A thor task for creating new projects class Init < Thor check_unknown_options! @@ -12,41 +11,41 @@ module Middleman::Cli desc 'init NAME [options]', 'Create new project NAME' available_templates = ::Middleman::Templates.registered.keys.join(', ') method_option 'template', - :aliases => '-T', - :default => 'default', - :desc => "Use a project template: #{available_templates}" + :aliases => '-T', + :default => 'default', + :desc => "Use a project template: #{available_templates}" method_option 'css_dir', # :default => "stylesheets", - :desc => 'The path to the css files' + :desc => 'The path to the css files' method_option 'js_dir', # :default => "javascripts", - :desc => 'The path to the javascript files' + :desc => 'The path to the javascript files' method_option 'images_dir', # :default => "images", - :desc => 'The path to the image files' + :desc => 'The path to the image files' method_option 'rack', - :type => :boolean, - :default => false, - :desc => 'Include a config.ru file' + :type => :boolean, + :default => false, + :desc => 'Include a config.ru file' method_option 'skip-gemfile', - :type => :boolean, - :default => false, - :desc => "Don't create a Gemfile" + :type => :boolean, + :default => false, + :desc => "Don't create a Gemfile" method_option 'skip-bundle', - :type => :boolean, - :aliases => '-B', - :default => false, - :desc => "Don't run bundle install" + :type => :boolean, + :aliases => '-B', + :default => false, + :desc => "Don't run bundle install" method_option 'skip-git', - :type => :boolean, - :default => false, - :desc => 'Skip Git ignores and keeps' + :type => :boolean, + :default => false, + :desc => 'Skip Git ignores and keeps' # The init task # @param [String] name - def init(name = '.') + def init(name='.') key = options[:template].to_sym - unless ::Middleman::Templates.registered.has_key?(key) - raise Thor::Error.new "Unknown project template '#{key}'" + unless ::Middleman::Templates.registered.key?(key) + raise Thor::Error, "Unknown project template '#{key}'" end thor_group = ::Middleman::Templates.registered[key] @@ -59,9 +58,9 @@ module Middleman::Cli end # Map "i", "new" and "n" to "init" - Base.map({ - 'i' => 'init', - 'new' => 'init', - 'n' => 'init' - }) + Base.map( + 'i' => 'init', + 'new' => 'init', + 'n' => 'init' + ) end diff --git a/middleman-core/lib/middleman-core/cli/server.rb b/middleman-core/lib/middleman-core/cli/server.rb index 782d9faf..e41e0333 100644 --- a/middleman-core/lib/middleman-core/cli/server.rb +++ b/middleman-core/lib/middleman-core/cli/server.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # Server thor task class Server < Thor check_unknown_options! @@ -9,54 +8,54 @@ module Middleman::Cli desc 'server [options]', 'Start the preview server' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + :aliases => '-e', + :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + :desc => 'The environment Middleman will run under' method_option :host, - :type => :string, - :aliases => '-h', - :default => '0.0.0.0', - :desc => 'Bind to HOST address' + :type => :string, + :aliases => '-h', + :default => '0.0.0.0', + :desc => 'Bind to HOST address' method_option :port, - :aliases => '-p', - :default => '4567', - :desc => 'The port Middleman will listen on' + :aliases => '-p', + :default => '4567', + :desc => 'The port Middleman will listen on' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + :type => :boolean, + :default => false, + :desc => 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + :type => :string, + :default => false, + :desc => 'Print instrument messages' method_option :disable_watcher, - :type => :boolean, - :default => false, - :desc => 'Disable the file change and delete watcher process' + :type => :boolean, + :default => false, + :desc => 'Disable the file change and delete watcher process' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for server startup' + :type => :boolean, + :default => false, + :desc => 'Generate profiling report for server startup' method_option :reload_paths, - :type => :string, - :default => false, - :desc => 'Additional paths to auto-reload when files change' + :type => :string, + :default => false, + :desc => 'Additional paths to auto-reload when files change' method_option :force_polling, - :type => :boolean, - :default => false, - :desc => 'Force file watcher into polling mode' + :type => :boolean, + :default => false, + :desc => 'Force file watcher into polling mode' method_option :latency, - :type => :numeric, - :aliases => '-l', - :default => 0.25, - :desc => 'Set file watcher latency, in seconds' + :type => :numeric, + :aliases => '-l', + :default => 0.25, + :desc => 'Set file watcher latency, in seconds' # Start the server def server require 'middleman-core' require 'middleman-core/preview_server' - if !ENV['MM_ROOT'] + unless ENV['MM_ROOT'] puts '== Could not find a Middleman project config.rb' puts '== Treating directory as a static site to be served' ENV['MM_ROOT'] = Dir.pwd @@ -85,5 +84,5 @@ module Middleman::Cli end # Map "s" to "server" - Base.map({ 's' => 'server' }) + Base.map('s' => 'server') end diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index 4340fa16..244b0603 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -39,7 +39,7 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) + def respond_to?(method, include_private=false) super || config.defines_setting?(method) end end @@ -53,7 +53,7 @@ module Middleman # @deprecated Prefer accessing settings through "config". # # @return [ConfigurationManager] - alias :settings :config + alias_method :settings, :config # Set attributes (global variables) # @@ -80,7 +80,7 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) + def respond_to?(method, include_private=false) super || config.defines_setting?(method) end end @@ -135,7 +135,7 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) + def respond_to?(method, include_private=false) super || defines_setting?(method) || (method =~ /^(\w+)=$/ && defines_setting?($1)) end @@ -143,7 +143,7 @@ module Middleman # @param [Symbol] key # @return [Boolean] def defines_setting?(key) - @settings.has_key?(key) + @settings.key?(key) end # Define a new setting, with optional default and user-friendly description. @@ -155,7 +155,7 @@ module Middleman # @return [ConfigSetting] def define_setting(key, default=nil, description=nil) raise "Setting #{key} doesn't exist" if @finalized - raise "Setting #{key} already defined" if @settings.has_key?(key) + raise "Setting #{key} already defined" if @settings.key?(key) raise 'Setting key must be a Symbol' unless key.is_a? Symbol @settings[key] = ConfigSetting.new(key, default, description) @@ -170,7 +170,7 @@ module Middleman # Deep duplicate of the configuration manager def dup - ConfigurationManager.new.tap {|c| c.load_settings(self.all_settings) } + ConfigurationManager.new.tap { |c| c.load_settings(all_settings) } end # Load in a list of settings diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 4ae83b6e..5555962c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -1,10 +1,8 @@ module Middleman module CoreExtensions - # The data extension parses YAML and JSON files in the data/ directory # and makes them available to config.rb, templates and extensions module Data - # Extension registered class << self # @private @@ -16,7 +14,7 @@ module Middleman app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' app.send :include, InstanceMethods end - alias :included :registered + alias_method :included, :registered end # Instance methods @@ -24,12 +22,12 @@ module Middleman # Setup data files before anything else so they are available when # parsing config.rb def initialize - self.files.changed DataStore.matcher do |file| - self.data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") + files.changed DataStore.matcher do |file| + data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") end - self.files.deleted DataStore.matcher do |file| - self.data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") + files.deleted DataStore.matcher do |file| + data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") end super @@ -45,10 +43,8 @@ module Middleman # The core logic behind the data extension. class DataStore - # Static methods class << self - # The regex which tells Middleman which files are for data # # @return [Regexp] @@ -137,7 +133,7 @@ module Middleman data_branch = data_branch[dir] end - data_branch.delete(basename) if data_branch.has_key?(basename) + data_branch.delete(basename) if data_branch.key?(basename) end # Get a hash from either internal static data or a callback @@ -150,10 +146,10 @@ module Middleman @@local_sources ||= {} @@callback_sources ||= {} - if self.store.has_key?(path.to_s) - response = self.store[path.to_s] - elsif self.callbacks.has_key?(path.to_s) - response = self.callbacks[path.to_s].call() + if store.key?(path.to_s) + response = store[path.to_s] + elsif callbacks.key?(path.to_s) + response = callbacks[path.to_s].call end response @@ -164,7 +160,7 @@ module Middleman # @param [String] path The namespace to search for # @return [Hash, nil] def method_missing(path) - if @local_data.has_key?(path.to_s) + if @local_data.key?(path.to_s) return @local_data[path.to_s] else result = data_for_path(path) @@ -178,8 +174,8 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) - super || has_key?(method) + def respond_to?(method, include_private=false) + super || key?(method) end # Make DataStore act like a hash. Return requested data, or @@ -188,24 +184,26 @@ module Middleman # @param [String, Symbol] key The name of the data namespace # @return [Hash, nil] def [](key) - __send__(key) if has_key?(key) + __send__(key) if key?(key) end def has_key?(key) - @local_data.has_key?(key.to_s) || !!(data_for_path(key)) + @local_data.key?(key.to_s) || !!(data_for_path(key)) end + alias_method :key?, :has_key? + # Convert all the data into a static hash # # @return [Hash] def to_h data = {} - self.store.each do |k, v| + store.each do |k, _| data[k] = data_for_path(k) end - self.callbacks.each do |k, v| + callbacks.each do |k, _| data[k] = data_for_path(k) end diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 9f7fe708..2e174d81 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -32,7 +32,6 @@ module Middleman module CoreExtensions module Extensions - # Register extension class << self # @private @@ -51,7 +50,7 @@ module Middleman app.send :include, InstanceMethods app.delegate :configure, :to => :"self.class" end - alias :included :registered + alias_method :included, :registered end # Class methods @@ -75,7 +74,7 @@ module Middleman else extend extension if extension.respond_to?(:registered) - if extension.method(:registered).arity === 1 + if extension.method(:registered).arity == 1 extension.registered(self, &block) else extension.registered(self, options, &block) @@ -157,7 +156,7 @@ module Middleman # Check for and evaluate local configuration local_config = File.join(root, 'config.rb') - if File.exists? local_config + if File.exist? local_config logger.debug '== Reading: Local config' instance_eval File.read(local_config), local_config, 1 end @@ -172,16 +171,16 @@ module Middleman # polluted with paths from other test app directories that don't # exist anymore. if ENV['TEST'] - ::I18n.load_path.delete_if {|path| path =~ %r{tmp/aruba}} + ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } ::I18n.reload! end run_hook :after_configuration logger.debug 'Loaded extensions:' - self.extensions.each do |ext, klass| + extensions.each do |ext, klass| if ext.is_a?(Hash) - ext.each do |k,_| + ext.each do |k, _| logger.debug "== Extension: #{k}" end else diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index 1a97e1a5..b63d2a10 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -2,16 +2,14 @@ module Middleman module CoreExtensions module ExternalHelpers - # Setup extension class << self - # once registered def registered(app) # Setup a default helpers paths app.config.define_setting :helpers_dir, 'helpers', 'Directory to autoload helper modules from' app.config.define_setting :helpers_filename_glob, '**.rb', 'Glob pattern for matching helper ruby files' - app.config.define_setting :helpers_filename_to_module_name_proc, Proc.new { |filename| + app.config.define_setting :helpers_filename_to_module_name_proc, proc { |filename| basename = File.basename(filename, File.extname(filename)) basename.camelcase }, 'Proc implementing the conversion from helper filename to module name' @@ -19,7 +17,7 @@ module Middleman # After config app.after_configuration do helpers_path = File.join(root, config[:helpers_dir]) - next unless File.exists?(helpers_path) + next unless File.exist?(helpers_path) Dir[File.join(helpers_path, config[:helpers_filename_glob])].each do |filename| module_name = config[:helpers_filename_to_module_name_proc].call(filename) @@ -32,7 +30,7 @@ module Middleman end end end - alias :included :registered + alias_method :included, :registered end end end 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 7cb0567a..fd618261 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -5,7 +5,6 @@ require 'set' module Middleman module CoreExtensions module FileWatcher - IGNORE_LIST = [ /^bin(\/|$)/, /^\.bundle(\/|$)/, @@ -26,7 +25,6 @@ module Middleman # Setup extension class << self - # Once registered def registered(app) app.send :include, InstanceMethods @@ -47,12 +45,11 @@ module Middleman files.reload_path('.') end end - alias :included :registered + alias_method :included, :registered end # Instance methods module InstanceMethods - # Access the file api # @return [Middleman::CoreExtensions::FileWatcher::API] def files @@ -62,7 +59,6 @@ module Middleman # Core File Change API class class API - attr_reader :app attr_reader :known_paths delegate :logger, :to => :app @@ -102,7 +98,7 @@ module Middleman path = Pathname(path) logger.debug "== File Change: #{path}" @known_paths << path - self.run_callbacks(path, :changed) + run_callbacks(path, :changed) end # Notify callbacks that a file was deleted @@ -113,7 +109,7 @@ module Middleman path = Pathname(path) logger.debug "== File Deletion: #{path}" @known_paths.delete(path) - self.run_callbacks(path, :deleted) + run_callbacks(path, :deleted) end # Manually trigger update events @@ -151,7 +147,7 @@ module Middleman def exists?(path) p = Pathname(path) - p = p.relative_path_from(Pathname(@app.root)) if !p.relative? + p = p.relative_path_from(Pathname(@app.root)) unless p.relative? @known_paths.include?(p) end @@ -163,7 +159,7 @@ module Middleman app.config[:file_watcher_ignore].any? { |r| path =~ r } end - protected + protected # Notify callbacks for a file given an array of callbacks # @@ -172,7 +168,7 @@ module Middleman # @return [void] def run_callbacks(path, callbacks_name) path = path.to_s - self.send(callbacks_name).each do |callback, matcher| + send(callbacks_name).each do |callback, matcher| next unless matcher.nil? || path.match(matcher) @app.instance_exec(path, &callback) 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 87f0f9cb..6d43c9c3 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -9,10 +9,8 @@ require 'active_support/json' # Extensions namespace module Middleman::CoreExtensions - class FrontMatter < ::Middleman::Extension - - YAML_ERRORS = [ StandardError ] + YAML_ERRORS = [StandardError] # https://github.com/tenderlove/psych/issues/23 if defined?(Psych) && defined?(Psych::SyntaxError) @@ -115,7 +113,7 @@ module Middleman::CoreExtensions @cache.delete(path) end - private + private # Parse YAML frontmatter out of a string # @param [String] content # @return [Array] @@ -147,7 +145,7 @@ module Middleman::CoreExtensions content = content.sub(json_regex, '') begin - json = ($1+$2).sub(';;;', '{').sub(';;;', '}') + json = ($1 + $2).sub(';;;', '{').sub(';;;', '}') data = ActiveSupport::JSON.decode(json).symbolize_keys rescue => e app.logger.error "JSON Exception parsing #{full_path}: #{e.message}" diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 4698ee2b..d1db2cdb 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -10,10 +10,8 @@ end module Middleman module CoreExtensions module Rendering - # Setup extension class << self - # Once registered def registered(app) # Include methods @@ -93,7 +91,7 @@ module Middleman # Clean up missing Tilt exts app.after_configuration do - Tilt.mappings.each do |key, klasses| + Tilt.mappings.each do |key, _| begin Tilt[".#{key}"] rescue LoadError, NameError @@ -103,7 +101,7 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end # Custom error class for handling @@ -112,7 +110,6 @@ module Middleman # Rendering instance methods module InstanceMethods - # Add or overwrite a default template extension # # @param [Hash] extension_map @@ -140,7 +137,7 @@ module Middleman # Use a dup of self as a context so that instance variables set within # the template don't persist for other templates. - context = self.dup + context = dup blocks.each do |block| context.instance_eval(&block) end @@ -184,7 +181,7 @@ module Middleman # @param [String, Symbol] data # @param [Hash] options # @return [String] - def render(engine, data, options={}, &block) + def render(_, data, options={}, &block) data = data.to_s locals = options[:locals] @@ -198,13 +195,13 @@ module Middleman resolve_opts[:preferred_engine] = File.extname(resource.source_file)[1..-1].to_sym # Look for partials relative to the current path - relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(self.source_dir)}/?}, ''), data) + relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), data) found_partial = resolve_template(relative_dir, resolve_opts) end # Look in the partials_dir for the partial with the current engine - if !found_partial + unless found_partial partials_path = File.join(config[:partials_dir], data) found_partial = resolve_template(partials_path, resolve_opts) end @@ -222,7 +219,7 @@ module Middleman # @param [Hash] opts # @param [Class] context # @return [String] - def render_individual_file(path, locs = {}, opts = {}, context = self, &block) + def render_individual_file(path, locs={}, opts={}, context=self, &block) path = path.to_s # Detect the remdering engine from the extension @@ -260,7 +257,7 @@ module Middleman # Read compiled template from disk or cache template = cache.fetch(:compiled_template, extension, options, body) do - ::Tilt.new(path, 1, options) { body } + ::Tilt.new(path, 1, options) { body } end # Render using Tilt @@ -317,7 +314,7 @@ module Middleman # @return [String] def fetch_layout(engine, opts) # The layout name comes from either the system default or the options - local_layout = opts.has_key?(:layout) ? opts[:layout] : config[:layout] + local_layout = opts.key?(:layout) ? opts[:layout] : config[:layout] return false unless local_layout # Look for engine-specific options @@ -325,9 +322,9 @@ module Middleman # The engine for the layout can be set in options, engine_options or passed # into this method - layout_engine = if opts.has_key?(:layout_engine) + layout_engine = if opts.key?(:layout_engine) opts[:layout_engine] - elsif engine_options.has_key?(:layout_engine) + elsif engine_options.key?(:layout_engine) engine_options[:layout_engine] else engine @@ -354,11 +351,8 @@ module Middleman # @param [Symbol] preferred_engine # @return [String] def locate_layout(name, preferred_engine=nil) - # Whether we've found the layout - layout_path = false - resolve_opts = {} - resolve_opts[:preferred_engine] = preferred_engine if !preferred_engine.nil? + resolve_opts[:preferred_engine] = preferred_engine unless preferred_engine.nil? # Check layouts folder layout_path = resolve_template(File.join(config[:layouts_dir], name.to_s), resolve_opts) @@ -377,13 +371,13 @@ module Middleman # Save current buffer for later @_out_buf, _buf_was = '', @_out_buf - layout_path = locate_layout(layout_name, self.current_engine) + layout_path = locate_layout(layout_name, current_engine) extension = File.extname(layout_path) engine = extension[1..-1].to_sym # Store last engine for later (could be inside nested renders) - self.current_engine, engine_was = engine, self.current_engine + self.current_engine, engine_was = engine, current_engine begin content = if block_given? @@ -423,15 +417,14 @@ module Middleman request_path = request_path.to_s cache.fetch(:resolve_template, request_path, options) do relative_path = Util.strip_leading_slash(request_path) - on_disk_path = File.expand_path(relative_path, self.source_dir) + on_disk_path = File.expand_path(relative_path, source_dir) # By default, any engine will do preferred_engines = ['*'] # If we're specifically looking for a preferred engine - if options.has_key?(:preferred_engine) + if options.key?(:preferred_engine) extension_class = ::Tilt[options[:preferred_engine]] - matched_exts = [] # Get a list of extensions for a preferred engine matched_exts = ::Tilt.mappings.select do |ext, engines| @@ -464,7 +457,7 @@ module Middleman # If we found one, return it and the found engine if found_path found_path - elsif File.exists?(on_disk_path) + elsif File.exist?(on_disk_path) on_disk_path else false diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index 09380ab8..a3bbe7b2 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -8,15 +8,12 @@ require 'middleman-core/util' module Middleman module CoreExtensions - # Base helper to manipulate asset paths module Request - # Extension registered class << self # @private def registered(app) - # CSSPIE HTC File ::Rack::Mime::MIME_TYPES['.htc'] = 'text/x-component' @@ -32,7 +29,7 @@ module Middleman # Include instance methods app.send :include, InstanceMethods end - alias :included :registered + alias_method :included, :registered end module ClassMethods @@ -60,9 +57,7 @@ module Middleman # @private # @param [Middleman::Application] inst # @return [void] - def inst=(inst) - @inst = inst - end + attr_writer :inst # Return built Rack app # @@ -169,10 +164,10 @@ module Middleman # @return [void] def current_path=(path) Thread.current[:current_path] = path - Thread.current[:legacy_request] = ::Thor::CoreExt::HashWithIndifferentAccess.new({ - :path => path, - :params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {} - }) + Thread.current[:legacy_request] = ::Thor::CoreExt::HashWithIndifferentAccess.new( + :path => path, + :params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {} + ) end delegate :use, :to => :"self.class" @@ -183,6 +178,7 @@ module Middleman def req Thread.current[:req] end + def req=(value) Thread.current[:req] = value end @@ -199,7 +195,7 @@ module Middleman self.req = req = ::Rack::Request.new(env) res = ::Rack::Response.new - logger.debug "== Request: #{env["PATH_INFO"]}" + logger.debug "== Request: #{env['PATH_INFO']}" # Catch :halt exceptions and use that response if given catch(:halt) do @@ -277,7 +273,7 @@ module Middleman # @param [String] value Mime type # @return [void] def mime_type(type, value) - type = ".#{type}" unless type.to_s[0] == ?. + type = ".#{type}" unless type.to_s[0] == '.' ::Rack::Mime::MIME_TYPES[type] = value end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index ea53efeb..15acbc39 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -11,14 +11,14 @@ module Middleman # # @param [String, Symbol] layout_name # @return [void] - def with_layout(layout_name, &block) - old_layout = config[:layout] + def with_layout(layout_name, &block) + old_layout = config[:layout] - config[:layout] = layout_name - instance_exec(&block) if block_given? - ensure - config[:layout] = old_layout - end + config[:layout] = layout_name + instance_exec(&block) if block_given? + ensure + config[:layout] = old_layout + end # The page method allows the layout to be set on a specific path # @@ -28,43 +28,43 @@ module Middleman # @param [String] url # @param [Hash] opts # @return [void] - def page(url, opts={}, &block) - blocks = Array(block) + def page(url, opts={}, &block) + blocks = Array(block) - # Default layout - opts[:layout] = config[:layout] if opts[:layout].nil? + # Default layout + opts[:layout] = config[:layout] if opts[:layout].nil? - # If the url is a regexp - if url.is_a?(Regexp) || url.include?('*') + # If the url is a regexp + if url.is_a?(Regexp) || url.include?('*') - # Use the metadata loop for matching against paths at runtime - sitemap.provides_metadata_for_path(url) do |_| - { :options => opts, :blocks => blocks } - end - - return - end - - # Normalized path - url = '/' + Middleman::Util.normalize_path(url) - if url.end_with?('/') || File.directory?(File.join(source_dir, url)) - url = File.join(url, config[:index_file]) - end - - # Setup proxy - if target = opts.delete(:proxy) - # TODO: deprecate proxy through page? - proxy(url, target, opts, &block) and return - elsif opts.delete(:ignore) - # TODO: deprecate ignore through page? - ignore(url) - end - - # Setup a metadata matcher for rendering those options + # Use the metadata loop for matching against paths at runtime sitemap.provides_metadata_for_path(url) do |_| { :options => opts, :blocks => blocks } end + + return end + + # Normalized path + url = '/' + Middleman::Util.normalize_path(url) + if url.end_with?('/') || File.directory?(File.join(source_dir, url)) + url = File.join(url, config[:index_file]) + end + + # Setup proxy + if target = opts.delete(:proxy) + # TODO: deprecate proxy through page? + proxy(url, target, opts, &block) and return + elsif opts.delete(:ignore) + # TODO: deprecate ignore through page? + ignore(url) + end + + # Setup a metadata matcher for rendering those options + sitemap.provides_metadata_for_path(url) do |_| + { :options => opts, :blocks => blocks } + end + end end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index 60cac3e8..f1060b32 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -5,10 +5,8 @@ require 'rack/showexceptions' module Middleman module CoreExtensions module ShowExceptions - # Setup extension class << self - # Once registered def registered(app) # Whether to catch and display exceptions diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index fb4c9ce6..6bc59f7d 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -2,7 +2,6 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' module Middleman - class Extension class_attribute :supports_multiple_instances, :instance_reader => false, :instance_writer => false class_attribute :defined_helpers, :instance_reader => false, :instance_writer => false @@ -34,10 +33,10 @@ module Middleman end def extension_name - self.ext_name || self.name.underscore.split('/').last.to_sym + ext_name || name.underscore.split('/').last.to_sym end - def register(n=self.extension_name) + def register(n=extension_name) ::Middleman::Extensions.register(n, self) end @@ -59,7 +58,7 @@ module Middleman name = instance.class.extension_name return unless @_extension_activation_callbacks && @_extension_activation_callbacks[name] @_extension_activation_callbacks[name].each do |block| - block.arity == 1 ? block.call(instance) : block.call() + block.arity == 1 ? block.call(instance) : block.call end end end @@ -91,7 +90,7 @@ module Middleman end end - protected + protected def setup_options(options_hash, &block) @options = self.class.config.dup @@ -142,7 +141,7 @@ module Middleman ext = self if ext.respond_to?(:before_build) @klass.before_build do |builder| - if ext.method(:before_build).arity === 1 + if ext.method(:before_build).arity == 1 ext.before_build(builder) else ext.before_build @@ -155,7 +154,7 @@ module Middleman ext = self if ext.respond_to?(:after_build) @klass.after_build do |builder| - if ext.method(:after_build).arity === 1 + if ext.method(:after_build).arity == 1 ext.after_build(builder) else ext.after_build diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 0c652803..6695773c 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -1,7 +1,5 @@ module Middleman - module Extensions - class << self def registered @_registered ||= {} @@ -24,7 +22,7 @@ module Middleman def register(name, namespace=nil, &block) # If we've already got a matching extension that passed the # version check, bail out. - return if registered.has_key?(name.to_sym) && + return if registered.key?(name.to_sym) && !registered[name.to_sym].is_a?(String) registered[name.to_sym] = if block_given? @@ -36,11 +34,11 @@ module Middleman def load(name) name = name.to_sym - return nil unless registered.has_key?(name) + return nil unless registered.key?(name) extension = registered[name] if extension.is_a?(Proc) - extension = extension.call() || nil + extension = extension.call || nil registered[name] = extension end @@ -92,7 +90,7 @@ module Middleman # @return [Boolean] Whether the file exists def spec_has_file?(spec, path) full_path = File.join(spec.full_gem_path, path) - File.exists?(full_path) + File.exist?(full_path) end end end diff --git a/middleman-core/lib/middleman-core/load_paths.rb b/middleman-core/lib/middleman-core/load_paths.rb index 673563f6..8e49e359 100644 --- a/middleman-core/lib/middleman-core/load_paths.rb +++ b/middleman-core/lib/middleman-core/load_paths.rb @@ -2,7 +2,6 @@ require 'pathname' module Middleman - class << self def setup_load_paths @_is_setup ||= begin @@ -20,12 +19,12 @@ module Middleman root_gemfile = File.expand_path('Gemfile', ENV['MM_ROOT']) ENV['BUNDLE_GEMFILE'] ||= root_gemfile - if !File.exists?(ENV['BUNDLE_GEMFILE']) + unless File.exist?(ENV['BUNDLE_GEMFILE']) git_gemfile = Pathname.new(__FILE__).expand_path.parent.parent.parent + 'Gemfile' ENV['BUNDLE_GEMFILE'] = git_gemfile.to_s end - if File.exists?(ENV['BUNDLE_GEMFILE']) + if File.exist?(ENV['BUNDLE_GEMFILE']) is_bundler_setup = true require 'bundler/setup' end @@ -45,12 +44,10 @@ module Middleman end # Recursive method to find config.rb - def locate_root(cwd = Pathname.new(Dir.pwd)) + def locate_root(cwd=Pathname.new(Dir.pwd)) return cwd.to_s if (cwd + 'config.rb').exist? return false if cwd.root? locate_root(cwd.parent) end - end - end diff --git a/middleman-core/lib/middleman-core/logger.rb b/middleman-core/lib/middleman-core/logger.rb index 3ab3581e..7d361946 100644 --- a/middleman-core/lib/middleman-core/logger.rb +++ b/middleman-core/lib/middleman-core/logger.rb @@ -4,10 +4,8 @@ require 'active_support/logger' require 'thread' module Middleman - # The Middleman Logger class Logger < ActiveSupport::Logger - def self.singleton(*args) if !@_logger || args.length > 0 if args.length == 1 && (args.first.is_a?(::String) || args.first.respond_to?(:write)) @@ -42,7 +40,7 @@ module Middleman return if @instrumenting.is_a?(String) && @instrumenting != 'instrument' && !message.include?(@instrumenting) evt = ActiveSupport::Notifications::Event.new(message, *args) - self.info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms" + info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms" end end end diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index b88d0215..f2eca41d 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -40,12 +40,12 @@ module Middleman end # The index page - def index(env) + def index(_) template('index.html.erb') end # Inspect the sitemap - def sitemap(env) + def sitemap(_) resources = @middleman.inst.sitemap.resources(true) sitemap_tree = SitemapTree.new @@ -58,8 +58,8 @@ module Middleman end # Inspect configuration - def config(env) - global_config = @middleman.inst.config.all_settings.map {|c| ConfigSetting.new(c) } + def config(_) + global_config = @middleman.inst.config.all_settings.map { |c| ConfigSetting.new(c) } extension_config = {} @middleman.inst.extensions.each do |ext_name, extension| @@ -96,11 +96,11 @@ module Middleman # Respond to an HTML request def response(content) - [ 200, {'Content-Type' => 'text/html'}, Array(content) ] + [200, { 'Content-Type' => 'text/html' }, Array(content)] end def extension_options(extension) - extension.options.all_settings.map {|c| ConfigSetting.new(c) } + extension.options.all_settings.map { |c| ConfigSetting.new(c) } end end end diff --git a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb index 68bae977..ab2f03d9 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb @@ -14,7 +14,7 @@ module Middleman def render content = '' - @children.keys.sort do |a,b| + @children.keys.sort do |a, b| a_subtree = @children[a] b_subtree = @children[b] if a_subtree.is_a? SitemapResource diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index efb72bae..03e117bf 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -4,7 +4,6 @@ require 'middleman-core/logger' module Middleman module PreviewServer - DEFAULT_PORT = 4567 class << self @@ -70,7 +69,7 @@ module Middleman begin app = new_app - rescue Exception => e + rescue => e logger.error "Error reloading Middleman: #{e}\n#{e.backtrace.join("\n")}" logger.info '== The Middleman is still running the application from before the error' return @@ -89,7 +88,7 @@ module Middleman @webrick.shutdown end - private + private def new_app opts = @options.dup server = ::Middleman::Application.server @@ -181,7 +180,7 @@ module Middleman begin ::WEBrick::HTTPServer.new(http_opts) rescue Errno::EADDRINUSE - logger.error "== Port #{port} is unavailable. Either close the instance of Middleman already running on #{port} or start this Middleman on a new port with: --port=#{port.to_i+1}" + logger.error "== Port #{port} is unavailable. Either close the instance of Middleman already running on #{port} or start this Middleman on a new port with: --port=#{port.to_i + 1}" exit(1) end end diff --git a/middleman-core/lib/middleman-core/profiling.rb b/middleman-core/lib/middleman-core/profiling.rb index 0e54f41e..3c8927dc 100644 --- a/middleman-core/lib/middleman-core/profiling.rb +++ b/middleman-core/lib/middleman-core/profiling.rb @@ -1,6 +1,5 @@ module Middleman module Profiling - # The profiler instance. There can only be one! def self.profiler=(prof) @profiler = prof @@ -31,11 +30,9 @@ module Middleman # A profiler that uses ruby-prof class RubyProfProfiler def initialize - begin - require 'ruby-prof' - rescue LoadError - raise "To use the --profile option, you must add the 'ruby-prof' gem to your Gemfile" - end + require 'ruby-prof' + rescue LoadError + raise "To use the --profile option, you must add the 'ruby-prof' gem to your Gemfile" end def start @@ -50,7 +47,7 @@ module Middleman outfile = (outfile + '.html') unless outfile.end_with? '.html' FileUtils.mkdir_p(File.dirname(outfile)) File.open(outfile, 'w') do |f| - printer.print(f, :min_percent=> 1) + printer.print(f, :min_percent => 1) end end end diff --git a/middleman-core/lib/middleman-core/renderers/asciidoc.rb b/middleman-core/lib/middleman-core/renderers/asciidoc.rb index 6e89df16..5be25520 100644 --- a/middleman-core/lib/middleman-core/renderers/asciidoc.rb +++ b/middleman-core/lib/middleman-core/renderers/asciidoc.rb @@ -4,7 +4,6 @@ module Middleman module Renderers module AsciiDoc class << self - def registered(app) app.config.define_setting :asciidoc, { :safe => :safe, @@ -35,11 +34,11 @@ module Middleman opts[:layout] = layout end end - opts[:layout_engine] = (doc.attr 'page-layout-engine') if (doc.attr? 'page-layout-engine') + opts[:layout_engine] = (doc.attr 'page-layout-engine') if doc.attr? 'page-layout-engine' # TODO override attributes to set docfile, docdir, docname, etc # alternative is to set :renderer_options, which get merged into options by the rendering extension - #opts[:attributes] = config[:asciidoc][:attributes].dup - #opts[:attributes].concat %W(docfile=#{path} docdir=#{File.dirname path} docname=#{(File.basename path).sub(/\.adoc$/, '')}) + # opts[:attributes] = config[:asciidoc][:attributes].dup + # opts[:attributes].concat %W(docfile=#{path} docdir=#{File.dirname path} docname=#{(File.basename path).sub(/\.adoc$/, '')}) page = {} page[:title] = doc.doctitle @@ -47,12 +46,12 @@ module Middleman # TODO grab all the author information page[:author] = (doc.attr 'author') unless (doc.attr 'author').nil? - {:options => opts, :page => ::Middleman::Util.recursively_enhance(page)} + { :options => opts, :page => ::Middleman::Util.recursively_enhance(page) } end end end - alias :included :registered + alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb index 92b30f38..047d25a4 100644 --- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb +++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb @@ -3,10 +3,8 @@ require 'coffee_script' module Middleman module Renderers - # CoffeeScript Renderer module CoffeeScript - # Setup extension class << self # Once registered @@ -20,7 +18,7 @@ module Middleman DebuggingCoffeeScriptTemplate.middleman_app = self end end - alias :included :registered + alias_method :included, :registered end # A Template for Tilt which outputs debug messages diff --git a/middleman-core/lib/middleman-core/renderers/erb.rb b/middleman-core/lib/middleman-core/renderers/erb.rb index 87f91c82..abec76f9 100644 --- a/middleman-core/lib/middleman-core/renderers/erb.rb +++ b/middleman-core/lib/middleman-core/renderers/erb.rb @@ -4,7 +4,6 @@ module Middleman module ERb # Setup extension class << self - # once registered def registered(app) app.before_configuration do @@ -16,7 +15,7 @@ module Middleman ::Tilt.prefer(Template, :erb) end end - alias :included :registered + alias_method :included, :registered end class Template < ::Tilt::ErubisTemplate @@ -26,7 +25,7 @@ module Middleman def precompiled_preamble(locals) original = super "__in_erb_template = true\n" << original - #.rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n" + # .rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n" end end end diff --git a/middleman-core/lib/middleman-core/renderers/haml.rb b/middleman-core/lib/middleman-core/renderers/haml.rb index 29c2d2fb..b160610d 100644 --- a/middleman-core/lib/middleman-core/renderers/haml.rb +++ b/middleman-core/lib/middleman-core/renderers/haml.rb @@ -13,10 +13,8 @@ end module Middleman module Renderers - # Haml Renderer module Haml - # Setup extension class << self # Once registered @@ -33,7 +31,7 @@ module Middleman init_haml_helpers end end - alias :included :registered + alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/kramdown.rb b/middleman-core/lib/middleman-core/renderers/kramdown.rb index bccfea76..898b4e25 100644 --- a/middleman-core/lib/middleman-core/renderers/kramdown.rb +++ b/middleman-core/lib/middleman-core/renderers/kramdown.rb @@ -2,7 +2,6 @@ require 'kramdown' module Middleman module Renderers - # Our own Kramdown Tilt template that simply uses our custom renderer. class KramdownTemplate < ::Tilt::KramdownTemplate def evaluate(scope, locals, &block) @@ -32,7 +31,7 @@ module Middleman mail_addr = el.attr['href'].sub(/\Amailto:/, '') href = obfuscate('mailto') << ':' << obfuscate(mail_addr) content = obfuscate(content) if content == mail_addr - return %Q{#{content}} + return %Q(#{content}) end attr = el.attr.dup diff --git a/middleman-core/lib/middleman-core/renderers/less.rb b/middleman-core/lib/middleman-core/renderers/less.rb index 2f560073..ba567635 100644 --- a/middleman-core/lib/middleman-core/renderers/less.rb +++ b/middleman-core/lib/middleman-core/renderers/less.rb @@ -2,13 +2,10 @@ require 'less' module Middleman module Renderers - # Sass renderer module Less - # Setup extension class << self - # Once registered def registered(app) # Default less options @@ -27,12 +24,11 @@ module Middleman ::Tilt.prefer(LocalLoadingLessTemplate) end - alias :included :registered + alias_method :included, :registered end # A SassTemplate for Tilt which outputs debug messages class LocalLoadingLessTemplate < ::Tilt::LessTemplate - def prepare if ::Less.const_defined? :Engine @engine = ::Less::Engine.new(data) @@ -41,9 +37,7 @@ module Middleman @engine = parser.parse(data) end end - end - end end end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index 8bbac6ec..a55dfd4b 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -3,13 +3,10 @@ require 'liquid' module Middleman module Renderers - # Liquid Renderer module Liquid - # Setup extension class << self - # Once registerd def registered(app) app.before_configuration do @@ -27,9 +24,8 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end end - end end diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index 77c3e3fd..e9118c52 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -1,12 +1,9 @@ module Middleman module Renderers - # Markdown renderer module Markdown - # Setup extension class << self - # Once registered def registered(app) # Set our preference for a markdown engine @@ -35,7 +32,7 @@ module Middleman require 'middleman-core/renderers/kramdown' ::Tilt.prefer(::Middleman::Renderers::KramdownTemplate, *markdown_exts) MiddlemanKramdownHTML.middleman_app = self - elsif !config[:markdown_engine].nil? + elsif config[:markdown_engine] # Map symbols to classes markdown_engine_klass = if config[:markdown_engine].is_a? Symbol engine = config[:markdown_engine].to_s @@ -58,9 +55,8 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end end - end end diff --git a/middleman-core/lib/middleman-core/renderers/redcarpet.rb b/middleman-core/lib/middleman-core/renderers/redcarpet.rb index 79b4f37e..f792bc28 100644 --- a/middleman-core/lib/middleman-core/renderers/redcarpet.rb +++ b/middleman-core/lib/middleman-core/renderers/redcarpet.rb @@ -2,9 +2,7 @@ require 'redcarpet' module Middleman module Renderers - class RedcarpetTemplate < ::Tilt::RedcarpetTemplate::Redcarpet2 - # because tilt has decided to convert these # in the wrong direction ALIASES = { @@ -15,7 +13,7 @@ module Middleman # Don't overload :renderer option with smartypants # Support renderer-level options def generate_renderer - return options.delete(:renderer) if options.has_key?(:renderer) + return options.delete(:renderer) if options.key?(:renderer) covert_options_to_aliases! @@ -32,8 +30,8 @@ module Middleman # Renderer Options possible_render_opts = [:filter_html, :no_images, :no_links, :no_styles, :safe_links_only, :with_toc_data, :hard_wrap, :xhtml, :prettify, :link_attributes] - render_options = possible_render_opts.inject({}) do |sum, opt| - sum[opt] = options.delete(opt) if options.has_key?(opt) + render_options = possible_render_opts.reduce({}) do |sum, opt| + sum[opt] = options.delete(opt) if options.key?(opt) sum end @@ -42,11 +40,11 @@ module Middleman private - def covert_options_to_aliases! - ALIASES.each do |aka, actual| - options[actual] = options.delete(aka) if options.has_key? aka - end + def covert_options_to_aliases! + ALIASES.each do |aka, actual| + options[actual] = options.delete(aka) if options.key? aka end + end end # Custom Redcarpet renderer that uses our helpers for images and links @@ -64,7 +62,7 @@ module Middleman middleman_app.image_tag(link, :title => title, :alt => alt_text) else link_string = link.dup - link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text + link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text %Q{![#{alt_text}](#{link_string})} end end @@ -72,12 +70,12 @@ module Middleman def link(link, title, content) if !@local_options[:no_links] attributes = { :title => title } - attributes.merge!( @local_options[:link_attributes] ) if @local_options[:link_attributes] + attributes.merge!(@local_options[:link_attributes]) if @local_options[:link_attributes] - middleman_app.link_to(content, link, attributes ) + middleman_app.link_to(content, link, attributes) else link_string = link.dup - link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text + link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text %Q{[#{content}](#{link_string})} end end diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 54e40a0e..86d83acb 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -3,13 +3,10 @@ require 'compass/import-once' module Middleman module Renderers - # Sass renderer module Sass - # Setup extension class << self - # Once registered def registered(app) # Default sass options @@ -31,16 +28,15 @@ module Middleman ::Compass::ImportOnce.activate! end - alias :included :registered + alias_method :included, :registered end # A SassTemplate for Tilt which outputs debug messages class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate - def initialize(*args, &block) super - if @options.has_key?(:context) + if @options.key?(:context) @context = @options[:context] end end @@ -87,7 +83,6 @@ module Middleman # SCSS version of the above template class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate - # Define the expected syntax for the template # @return [Symbol] def syntax diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index f9f6a28f..8130d44c 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -17,13 +17,10 @@ end module Middleman module Renderers - # Slim renderer module Slim - # Setup extension class << self - # Once registered def registered(app) app.before_configuration do @@ -50,7 +47,7 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/stylus.rb b/middleman-core/lib/middleman-core/renderers/stylus.rb index 87109104..5a929e44 100644 --- a/middleman-core/lib/middleman-core/renderers/stylus.rb +++ b/middleman-core/lib/middleman-core/renderers/stylus.rb @@ -3,13 +3,10 @@ require 'stylus/tilt' module Middleman module Renderers - # Sass renderer module Stylus - # Setup extension class << self - # Once registered def registered(app) # Default less options @@ -20,9 +17,8 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index 61f5de97..1a758011 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -9,15 +9,11 @@ require 'middleman-core/sitemap/extensions/ignores' # Core Sitemap Extensions module Middleman - module Sitemap - # Setup Extension class << self - # Once registered def registered(app) - app.register Middleman::Sitemap::Extensions::RequestEndpoints app.register Middleman::Sitemap::Extensions::Proxies app.register Middleman::Sitemap::Extensions::Ignores @@ -39,8 +35,8 @@ module Middleman # Files starting with an underscore, but not a double-underscore :partials => proc { |file| file =~ %r{/_[^_]} }, - :layout => proc { |file, app| - file.start_with?(File.join(app.config[:source], 'layout.')) || file.start_with?(File.join(app.config[:source], 'layouts/')) + :layout => proc { |file, sitemap_app| + file.start_with?(File.join(sitemap_app.config[:source], 'layout.')) || file.start_with?(File.join(sitemap_app.config[:source], 'layouts/')) } }, 'Callbacks that can exclude paths from the sitemap' @@ -52,13 +48,11 @@ module Middleman sitemap end end - alias :included :registered - + alias_method :included, :registered end # Sitemap instance methods module InstanceMethods - # Get the sitemap class instance # @return [Middleman::Sitemap::Store] def sitemap @@ -77,7 +71,6 @@ module Middleman return nil unless current_path sitemap.find_resource_by_destination_path(current_path) end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 59553626..290063f2 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -1,14 +1,9 @@ module Middleman - module Sitemap - module Extensions - module Ignores - # Setup extension class << self - # Once registered def registered(app) # Include methods @@ -17,12 +12,11 @@ module Middleman ::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods end - alias :included :registered + alias_method :included, :registered end # Helpers methods for Resources module ResourceInstanceMethods - # Whether the Resource is ignored # @return [Boolean] def ignored? @@ -61,15 +55,15 @@ module Middleman # @return [void] def ignore(path=nil, &block) if path.is_a? Regexp - @ignored_callbacks << Proc.new {|p| p =~ path } + @ignored_callbacks << proc { |p| p =~ path } elsif path.is_a? String path_clean = ::Middleman::Util.normalize_path(path) if path_clean.include?('*') # It's a glob - @ignored_callbacks << Proc.new {|p| File.fnmatch(path_clean, p) } + @ignored_callbacks << proc { |p| File.fnmatch(path_clean, p) } else # Add a specific-path ignore unless that path is already covered return if ignored?(path_clean) - @ignored_callbacks << Proc.new {|p| p == path_clean } + @ignored_callbacks << proc { |p| p == path_clean } end elsif block_given? @ignored_callbacks << block diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 824daaf4..abb917e4 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -1,13 +1,9 @@ require 'set' module Middleman - module Sitemap - module Extensions - class OnDisk - attr_accessor :sitemap attr_accessor :waiting_for_ready diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 18076943..dcd89edc 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -1,14 +1,9 @@ module Middleman - module Sitemap - module Extensions - module Proxies - # Setup extension class << self - # Once registered def registered(app) ::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods @@ -17,7 +12,7 @@ module Middleman app.send :include, InstanceMethods end - alias :included :registered + alias_method :included, :registered end module ResourceInstanceMethods @@ -38,9 +33,7 @@ module Middleman # The path of the page this page is proxied to, or nil if it's not proxied. # @return [String] - def proxied_to - @proxied_to - end + attr_reader :proxied_to # The resource for the page this page is proxied to. Throws an exception # if there is no resource. diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 9e67cd4d..86431809 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -1,21 +1,16 @@ module Middleman - module Sitemap - module Extensions - module Redirects - # Setup extension class << self - # Once registered def registered(app) # Include methods app.send :include, InstanceMethods end - alias :included :registered + alias_method :included, :registered end module InstanceMethods @@ -78,10 +73,10 @@ module Middleman end def render(*args, &block) - url = ::Middleman::Util.url_for(store.app, @request_path, { - :relative => false, - :find_resource => true - }) + url = ::Middleman::Util.url_for(store.app, @request_path, + :relative => false, + :find_resource => true + ) if output output.call(path, url) @@ -119,7 +114,6 @@ module Middleman def metadata @local_metadata.dup end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 84eee061..8562c297 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -1,21 +1,16 @@ module Middleman - module Sitemap - module Extensions - module RequestEndpoints - # Setup extension class << self - # Once registered def registered(app) # Include methods app.send :include, InstanceMethods end - alias :included :registered + alias_method :included, :registered end module InstanceMethods @@ -48,7 +43,7 @@ module Middleman if block_given? endpoint[:output] = block else - endpoint[:request_path] = opts[:path] if opts.has_key?(:path) + endpoint[:request_path] = opts[:path] if opts.key?(:path) end @endpoints[path] = endpoint @@ -65,7 +60,7 @@ module Middleman path, config[:request_path] ) - r.output = config[:output] if config.has_key?(:output) + r.output = config[:output] if config.key?(:output) r end end @@ -85,12 +80,10 @@ module Middleman end def render(*args, &block) - return self.output.call if self.output + return output.call if output end - def request_path - @request_path - end + attr_reader :request_path def binary? false @@ -107,7 +100,6 @@ module Middleman def metadata @local_metadata.dup end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index 78f8eb28..de9f7e38 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -1,9 +1,6 @@ module Middleman - module Sitemap - module Extensions - module Traversal # This resource's parent resource # @return [Middleman::Sitemap::Resource, nil] @@ -28,14 +25,14 @@ module Middleman if eponymous_directory? base_path = eponymous_directory_path - prefix = %r|^#{base_path.sub("/", "\\/")}| + prefix = %r{^#{base_path.sub("/", "\\/")}} else base_path = path.sub("#{app.index_file}", '') - prefix = %r|^#{base_path.sub("/", "\\/")}| + prefix = %r{^#{base_path.sub("/", "\\/")}} end store.resources.select do |sub_resource| - if sub_resource.path == self.path || sub_resource.path !~ prefix + if sub_resource.path == path || sub_resource.path !~ prefix false else inner_path = sub_resource.path.sub(prefix, '') @@ -72,7 +69,7 @@ module Middleman return true end full_path = File.join(app.source_dir, eponymous_directory_path) - !!(File.exists?(full_path) && File.directory?(full_path)) + !!(File.exist?(full_path) && File.directory?(full_path)) end # The path for this resource if it were a directory, and not a file diff --git a/middleman-core/lib/middleman-core/sitemap/queryable.rb b/middleman-core/lib/middleman-core/sitemap/queryable.rb index aab8be4e..d835e9cf 100644 --- a/middleman-core/lib/middleman-core/sitemap/queryable.rb +++ b/middleman-core/lib/middleman-core/sitemap/queryable.rb @@ -2,7 +2,6 @@ require 'active_support/core_ext/object/inclusion' module Middleman module Sitemap - # Code adapted from https://github.com/ralph/document_mapper/ module Queryable OPERATOR_MAPPING = { @@ -21,11 +20,11 @@ module Middleman OperatorNotSupportedError = Class.new StandardError module API - def select(options = {}) + def select(options={}) documents = resources.select { |r| !r.raw_data.empty? } options[:where].each do |selector, selector_value| documents = documents.select do |document| - next unless document.raw_data.has_key? selector.attribute + next unless document.raw_data.key? selector.attribute document_value = document.raw_data[selector.attribute] operator = OPERATOR_MAPPING[selector.operator] document_value.send operator, selector_value @@ -78,12 +77,12 @@ module Middleman symbol_hash = constraints_hash.reject { |key, value| key.is_a? Selector } symbol_hash.each do |attribute, value| selector = Selector.new(:attribute => attribute, :operator => 'equal') - selector_hash.update({ selector => value }) + selector_hash.update(selector => value) end Query.new @model, opts(:where => @where.merge(selector_hash)) end - def opts new_opts + def opts(new_opts) { :where => {}.merge(@where), :order_by => @order_by, :offset => @offset, @@ -92,7 +91,7 @@ module Middleman end def order_by(field) - Query.new @model, opts(:order_by => field.is_a?(Symbol) ? {field => :asc} : field) + Query.new @model, opts(:order_by => field.is_a?(Symbol) ? { field => :asc } : field) end def offset(number) @@ -104,11 +103,11 @@ module Middleman end def first - self.all.first + all.first end def last - self.all.last + all.last end def all @@ -126,7 +125,7 @@ module Middleman class Selector attr_reader :attribute, :operator - def initialize(opts = {}) + def initialize(opts={}) unless VALID_OPERATORS.include? opts[:operator] raise OperatorNotSupportedError end @@ -149,7 +148,7 @@ class Symbol unless method_defined?(:"<=>") def <=>(other) - self.to_s <=> other.to_s + to_s <=> other.to_s end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 3310e036..610641d6 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -2,10 +2,8 @@ require 'middleman-core/sitemap/extensions/traversal' require 'middleman-core/sitemap/extensions/content_type' module Middleman - # Sitemap namespace module Sitemap - # Sitemap Resource class class Resource include Middleman::Sitemap::Extensions::Traversal @@ -62,13 +60,13 @@ module Middleman result = store.metadata_for_path(path).dup file_meta = store.metadata_for_file(source_file).dup - if file_meta.has_key?(:blocks) + if file_meta.key?(:blocks) result[:blocks] += file_meta.delete(:blocks) end result.deep_merge!(file_meta) local_meta = @local_metadata.dup - if local_meta.has_key?(:blocks) + if local_meta.key?(:blocks) result[:blocks] += local_meta.delete(:blocks) end result.deep_merge!(local_meta) @@ -81,11 +79,11 @@ module Middleman # @param [Hash] metadata A metadata block like provides_metadata_for_path takes def add_metadata(metadata={}, &block) metadata = metadata.dup - if metadata.has_key?(:blocks) + if metadata.key?(:blocks) @local_metadata[:blocks] += metadata.delete(:blocks) end @local_metadata.deep_merge!(metadata) - @local_metadata[:blocks] += [ block ] if block_given? + @local_metadata[:blocks] += [block] if block_given? end # The output/preview URL for this resource @@ -99,13 +97,13 @@ module Middleman end def request_path - self.destination_path + destination_path end # Render this resource # @return [String] def render(opts={}, locs={}, &block) - if !template? + unless template? return app.template_data_for_file(source_file) end @@ -126,18 +124,18 @@ module Middleman locs = md[:locals].deep_merge(locs) # Forward remaining data to helpers - if md.has_key?(:page) + if md.key?(:page) app.data.store('page', md[:page]) end blocks = Array(md[:blocks]).dup blocks << block if block_given? - app.current_path ||= self.destination_path + app.current_path ||= destination_path # Certain output file types don't use layouts - if !opts.has_key?(:layout) - opts[:layout] = false if %w(.js .json .css .txt).include?(self.ext) + unless opts.key?(:layout) + opts[:layout] = false if %w(.js .json .css .txt).include?(ext) end app.render_template(source_file, locs, opts, blocks) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 190da9b7..c4fe78ae 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -4,10 +4,8 @@ require 'monitor' require 'middleman-core/sitemap/queryable' module Middleman - # Sitemap namespace module Sitemap - # The Store class # # The Store manages a collection of Resource objects, which represent @@ -15,7 +13,6 @@ module Middleman # which is the path relative to the source directory, minus any template # extensions. All "path" parameters used in this class are source paths. class Store - # @return [Middleman::Application] attr_accessor :app @@ -122,12 +119,12 @@ module Middleman def metadata_for_file(source_file) blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] } - provides_metadata.inject(blank_metadata) do |result, (callback, matcher)| + provides_metadata.reduce(blank_metadata) do |result, (callback, matcher)| next result if matcher && !source_file.match(matcher) metadata = callback.call(source_file).dup - if metadata.has_key?(:blocks) + if metadata.key?(:blocks) result[:blocks] << metadata[:blocks] metadata.delete(:blocks) end @@ -156,7 +153,7 @@ module Middleman blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] } - @_cached_metadata[request_path] = provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)| + @_cached_metadata[request_path] = provides_metadata_for_path.reduce(blank_metadata) do |result, (callback, matcher)| case matcher when Regexp next result unless request_path =~ matcher @@ -213,7 +210,7 @@ module Middleman @app.logger.debug '== Rebuilding resource list' - @resources = @resource_list_manipulators.inject([]) do |result, (_, inst)| + @resources = @resource_list_manipulators.reduce([]) do |result, (_, inst)| newres = inst.manipulate_resource_list(result) # Reset lookup cache @@ -269,9 +266,9 @@ module Middleman def find_extension(path, file) input_ext = File.extname(file) - if !input_ext.empty? + unless input_ext.empty? input_ext = input_ext.split('.').last.to_sym - if @app.template_extensions.has_key?(input_ext) + if @app.template_extensions.key?(input_ext) path << ".#{@app.template_extensions[input_ext]}" end end diff --git a/middleman-core/lib/middleman-core/templates.rb b/middleman-core/lib/middleman-core/templates.rb index 207edf6a..312e64b3 100644 --- a/middleman-core/lib/middleman-core/templates.rb +++ b/middleman-core/lib/middleman-core/templates.rb @@ -4,10 +4,8 @@ require 'thor/group' # Templates namespace module Middleman::Templates - # Static methods class << self - # Get list of registered templates and add new ones # # Middleman::Templates.register(:ext_name, klass) @@ -22,7 +20,7 @@ module Middleman::Templates end # Middleman::Templates.register(name, klass) - alias :registered :register + alias_method :registered, :register end # Base Template class. Handles basic options and paths. diff --git a/middleman-core/lib/middleman-core/templates/default.rb b/middleman-core/lib/middleman-core/templates/default.rb index 7497f98f..088f63f1 100644 --- a/middleman-core/lib/middleman-core/templates/default.rb +++ b/middleman-core/lib/middleman-core/templates/default.rb @@ -1,15 +1,14 @@ # Default Middleman template class Middleman::Templates::Default < Middleman::Templates::Base - class_option 'css_dir', - :default => 'stylesheets', - :desc => 'The path to the css files' + :default => 'stylesheets', + :desc => 'The path to the css files' class_option 'js_dir', - :default => 'javascripts', - :desc => 'The path to the javascript files' + :default => 'javascripts', + :desc => 'The path to the javascript files' class_option 'images_dir', - :default => 'images', - :desc => 'The path to the image files' + :default => 'images', + :desc => 'The path to the image files' # Template files are relative to this file # @return [String] diff --git a/middleman-core/lib/middleman-core/templates/empty.rb b/middleman-core/lib/middleman-core/templates/empty.rb index e726f1c2..1ae364c5 100644 --- a/middleman-core/lib/middleman-core/templates/empty.rb +++ b/middleman-core/lib/middleman-core/templates/empty.rb @@ -1,6 +1,5 @@ # A barebones template with nothing much in it class Middleman::Templates::Empty < Middleman::Templates::Base - # Template files are relative to this file # @return [String] def self.source_root diff --git a/middleman-core/lib/middleman-core/templates/extension/Gemfile b/middleman-core/lib/middleman-core/templates/extension/Gemfile index 6959cfc1..1acd5814 100644 --- a/middleman-core/lib/middleman-core/templates/extension/Gemfile +++ b/middleman-core/lib/middleman-core/templates/extension/Gemfile @@ -16,4 +16,4 @@ group :test do gem 'fivemat' gem 'aruba' gem 'rspec' -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/templates/extension/Rakefile b/middleman-core/lib/middleman-core/templates/extension/Rakefile index 0f786f84..1b6d06aa 100644 --- a/middleman-core/lib/middleman-core/templates/extension/Rakefile +++ b/middleman-core/lib/middleman-core/templates/extension/Rakefile @@ -11,4 +11,4 @@ require 'rake/clean' task :test => ['cucumber'] -task :default => :test \ No newline at end of file +task :default => :test diff --git a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb index 386d3d2a..8b98bf78 100644 --- a/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb +++ b/middleman-core/lib/middleman-core/templates/extension/lib/lib.rb @@ -28,7 +28,6 @@ class MyExtension < ::Middleman::Extension # def a_helper # end # end - end # Register extensions which can be activated diff --git a/middleman-core/lib/middleman-core/templates/html5.rb b/middleman-core/lib/middleman-core/templates/html5.rb index 6e8391cb..9ac75b3e 100644 --- a/middleman-core/lib/middleman-core/templates/html5.rb +++ b/middleman-core/lib/middleman-core/templates/html5.rb @@ -1,15 +1,14 @@ # HTML5 Boilerplate template class Middleman::Templates::Html5 < Middleman::Templates::Base - class_option 'css_dir', - :default => 'css', - :desc => 'The path to the css files' + :default => 'css', + :desc => 'The path to the css files' class_option 'js_dir', - :default => 'js', - :desc => 'The path to the javascript files' + :default => 'js', + :desc => 'The path to the javascript files' class_option 'images_dir', - :default => 'img', - :desc => 'The path to the image files' + :default => 'img', + :desc => 'The path to the image files' # Templates are relative to this file # @return [String] diff --git a/middleman-core/lib/middleman-core/templates/local.rb b/middleman-core/lib/middleman-core/templates/local.rb index c5ba9c79..08d35932 100644 --- a/middleman-core/lib/middleman-core/templates/local.rb +++ b/middleman-core/lib/middleman-core/templates/local.rb @@ -1,6 +1,5 @@ # Local templates class Middleman::Templates::Local < Middleman::Templates::Base - # Look for templates in ~/.middleman # @return [String] def self.source_root @@ -20,7 +19,7 @@ Dir[File.join(Middleman::Templates::Local.source_root, '*')].each do |dir| template_file = File.join(dir, 'template.rb') - if File.exists?(template_file) + if File.exist?(template_file) require template_file else Middleman::Templates.register(File.basename(dir).to_sym, Middleman::Templates::Local) diff --git a/middleman-core/lib/middleman-core/templates/mobile.rb b/middleman-core/lib/middleman-core/templates/mobile.rb index 8e7e3530..43ebf6ca 100644 --- a/middleman-core/lib/middleman-core/templates/mobile.rb +++ b/middleman-core/lib/middleman-core/templates/mobile.rb @@ -1,6 +1,5 @@ # Mobile HTML5 Boilerplate class Middleman::Templates::Mobile < Middleman::Templates::Base - # Slightly different paths class_option :css_dir, :default => 'css' class_option :js_dir, :default => 'js' diff --git a/middleman-core/lib/middleman-core/templates/shared/config.ru b/middleman-core/lib/middleman-core/templates/shared/config.ru index e091b492..9bff44ef 100644 --- a/middleman-core/lib/middleman-core/templates/shared/config.ru +++ b/middleman-core/lib/middleman-core/templates/shared/config.ru @@ -1,4 +1,4 @@ require 'rubygems' require 'middleman/rack' -run Middleman.server \ No newline at end of file +run Middleman.server diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 102b51e7..d6059e51 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -14,7 +14,6 @@ require 'rack/mime' module Middleman module Util class << self - # Whether the source file is binary. # # @param [String] filename The file to check. @@ -27,7 +26,7 @@ module Middleman return false if Tilt.registered?(ext.sub('.', '')) - dot_ext = (ext.to_s[0] == ?.) ? ext.dup : ".#{ext}" + dot_ext = (ext.to_s[0] == '.') ? ext.dup : ".#{ext}" if mime = ::Rack::Mime.mime_type(dot_ext, nil) !nonbinary_mime?(mime) @@ -69,7 +68,7 @@ module Middleman # @return [String] def normalize_path(path) # The tr call works around a bug in Ruby's Unicode handling - path.sub(%r{^/}, '').tr('','') + path.sub(%r{^/}, '').tr('', '') end # This is a separate method from normalize_path in case we @@ -85,7 +84,7 @@ module Middleman def extract_response_text(response) # The rack spec states all response bodies must respond to each result = '' - response.each do |part, s| + response.each do |part, _| result << part end result @@ -210,7 +209,7 @@ module Middleman def full_path(path, app) resource = app.sitemap.find_resource_by_destination_path(path) - if !resource + unless resource # Try it with /index.html at the end indexed_path = File.join(path.sub(%r{/$}, ''), app.config[:index_file]) resource = app.sitemap.find_resource_by_destination_path(indexed_path) @@ -223,7 +222,7 @@ module Middleman end end - private + private # Is mime type known to be non-binary? # diff --git a/middleman-core/lib/middleman-more/core_extensions/compass.rb b/middleman-core/lib/middleman-more/core_extensions/compass.rb index 75b04ab3..1d3c13c0 100644 --- a/middleman-core/lib/middleman-more/core_extensions/compass.rb +++ b/middleman-core/lib/middleman-more/core_extensions/compass.rb @@ -2,7 +2,6 @@ require 'middleman-core/renderers/sass' require 'compass' class Middleman::CoreExtensions::Compass < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb index c93b78d4..ff0a5ffe 100644 --- a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb @@ -7,7 +7,7 @@ require 'padrino-helpers' class Padrino::Helpers::OutputHelpers::ErbHandler # Force Erb capture not to use safebuffer def capture_from_template(*args, &block) - self.output_buffer, _buf_was = '', self.output_buffer + self.output_buffer, _buf_was = '', output_buffer raw = block.call(*args) captured = template.instance_variable_get(:@_out_buf) self.output_buffer = _buf_was @@ -16,7 +16,6 @@ class Padrino::Helpers::OutputHelpers::ErbHandler end class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super @@ -39,7 +38,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension helpers do # Make all block content html_safe - def content_tag(name, content = nil, options = nil, &block) + def content_tag(name, content=nil, options=nil, &block) if block_given? options = content if content.is_a?(Hash) content = capture_html(&block) @@ -108,8 +107,10 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension def auto_tag(asset_ext, asset_dir=nil) if asset_dir.nil? asset_dir = case asset_ext - when :js then js_dir - when :css then css_dir + when :js + js_dir + when :css + css_dir end end @@ -124,7 +125,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # Generate body css classes based on the current path # # @return [String] - def page_classes(path = current_path.dup, options={}) + def page_classes(path=current_path.dup, options={}) if path.is_a? Hash options = path path = current_path.dup @@ -135,7 +136,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension classes = [] parts = path.split('.').first.split('/') - parts.each_with_index { |_, i| classes << parts.first(i+1).join('_') } + parts.each_with_index { |_, i| classes << parts.first(i + 1).join('_') } prefix = options[:numeric_prefix] || 'x' classes.map do |c| @@ -155,13 +156,19 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @return [String] def asset_path(kind, source) return source if source.to_s.include?('//') || source.to_s.start_with?('data:') - asset_folder = case kind - when :css then css_dir - when :js then js_dir - when :images then images_dir - when :fonts then fonts_dir - else kind.to_s + asset_folder = case kind + when :css + css_dir + when :js + js_dir + when :images + images_dir + when :fonts + fonts_dir + else + kind.to_s end + source = source.to_s.tr(' ', '') ignore_extension = (kind == :images || kind == :fonts) # don't append extension source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") @@ -177,7 +184,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @return [String] The fully qualified asset url def asset_url(path, prefix='') # Don't touch assets which already have a full path - if path.include?('//') or path.start_with?('data:') + if path.include?('//') || path.start_with?('data:') path else # rewrite paths to use their destination path if resource = sitemap.find_resource_by_destination_path(url_for(path)) @@ -221,12 +228,12 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension options_index = block_given? ? 1 : 2 if block_given? && args.size > 2 - raise ArgumentError.new('Too many arguments to link_to(url, options={}, &block)') + raise ArgumentError, '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) + raise ArgumentError, '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) diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index 6f0b0e1c..8c733eb2 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -37,8 +37,8 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension configure_i18n - if !app.build? - logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})" + unless app.build? + logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})" end # Don't output localizable files @@ -70,10 +70,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension resources.each do |resource| # If it uses file extension localization - if !parse_locale_extension(resource.path).nil? + if parse_locale_extension(resource.path) result = parse_locale_extension(resource.path) - lang, path, page_id = result - new_resources << build_resource(path, resource.path, page_id, lang) + ext_lang, path, page_id = result + new_resources << build_resource(path, resource.path, page_id, ext_lang) # If it's a "localizable template" elsif File.fnmatch?(File.join(options[:templates_dir], '**'), resource.path) page_id = File.basename(resource.path, File.extname(resource.path)) @@ -90,7 +90,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension private - def on_file_changed(file) if @locales_regex =~ file @_langs = nil # Clear langs cache @@ -100,7 +99,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def convert_glob_to_regex(glob) # File.fnmatch doesn't support brackets: {rb,yml,yaml} - regex = @locales_glob.sub(/\./, '\.').sub(File.join('**', '*'), '.*').sub(/\//, '\/').sub('{rb,yml,yaml}', '(rb|ya?ml)') + regex = glob.sub(/\./, '\.').sub(File.join('**', '*'), '.*').sub(/\//, '\/').sub('{rb,yml,yaml}', '(rb|ya?ml)') %r{^#{regex}} end @@ -124,7 +123,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension lang = @mount_at_root end - instance_vars = Proc.new do + instance_vars = proc do @lang = lang @page_id = page_id end @@ -146,8 +145,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension Array(options[:langs]).map(&:to_sym) else known_langs = app.files.known_paths.select do |p| - p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length === 2) - end.map { |p| + p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length == 2) + end + + known_langs.map { |p| File.basename(p.to_s).sub(/\.ya?ml$/, '').sub(/\.rb$/, '') }.sort.map(&:to_sym) end @@ -178,7 +179,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n.locale = lang localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => []) - prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root] == nil && langs[0] == lang) + prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root].nil? && langs[0] == lang) '/' else replacement = options[:lang_map].fetch(lang, lang) @@ -190,7 +191,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension File.join(prefix, path.sub(page_id, localized_page_id)) ) - path.gsub!(options[:templates_dir]+'/', '') + path.gsub!(options[:templates_dir] + '/', '') @_localization_data[path] = [lang, path, localized_page_id] diff --git a/middleman-core/lib/middleman-more/extensions/asset_hash.rb b/middleman-core/lib/middleman-more/extensions/asset_hash.rb index 014364c7..5fca57ce 100644 --- a/middleman-core/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-more/extensions/asset_hash.rb @@ -44,7 +44,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension return if resource.ignored? # Render through the Rack interface so middleware and mounted apps get a shot - response = @rack_client.get(URI.escape(resource.destination_path), {}, { 'bypass_asset_hash' => 'true' }) + response = @rack_client.get(URI.escape(resource.destination_path), {}, 'bypass_asset_hash' => 'true') raise "#{resource.path} should be in the sitemap!" unless response.status == 200 digest = Digest::SHA1.hexdigest(response.body)[0..7] @@ -63,7 +63,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension @rack_app = app @exts = options[:exts] @ignore = options[:ignore] - @exts_regex_text = @exts.map {|e| Regexp.escape(e) }.join('|') + @exts_regex_text = @exts.map { |e| Regexp.escape(e) }.join('|') @middleman_app = options[:middleman_app] end @@ -85,7 +85,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension [status, headers, response] end - private + private def rewrite_paths(body, path) dirpath = Pathname.new(File.dirname(path)) @@ -111,9 +111,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension end end end - end - end # =================Temp Generate Test data============================== diff --git a/middleman-core/lib/middleman-more/extensions/asset_host.rb b/middleman-core/lib/middleman-more/extensions/asset_host.rb index 89cc49d6..194eaa85 100644 --- a/middleman-core/lib/middleman-more/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-more/extensions/asset_host.rb @@ -14,7 +14,7 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension if asset_host.is_a?(Proc) config.asset_host(&asset_host) else - config.asset_host do |asset| + config.asset_host do |_| asset_host end end diff --git a/middleman-core/lib/middleman-more/extensions/automatic_alt_tags.rb b/middleman-core/lib/middleman-more/extensions/automatic_alt_tags.rb index 95aaefee..879cecee 100644 --- a/middleman-core/lib/middleman-more/extensions/automatic_alt_tags.rb +++ b/middleman-core/lib/middleman-more/extensions/automatic_alt_tags.rb @@ -1,6 +1,5 @@ # Automatic Image alt tags from image names extension class Middleman::Extensions::AutomaticAltTags < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super end @@ -10,14 +9,14 @@ class Middleman::Extensions::AutomaticAltTags < ::Middleman::Extension # containing image name. def image_tag(path) - if !path.include?('://') + unless path.include?('://') params[:alt] ||= '' real_path = path 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) + if File.exist?(full_path) begin alt_text = File.basename(full_path, '.*') alt_text.capitalize! diff --git a/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb b/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb index 1b600e4e..4885ebeb 100644 --- a/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb +++ b/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb @@ -1,6 +1,5 @@ # Automatic Image Sizes extension class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super @@ -16,14 +15,14 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension # @param [Hash] params # @return [String] def image_tag(path, params={}) - if !params.has_key?(:width) && !params.has_key?(:height) && !path.include?('://') + if !params.key?(:width) && !params.key?(:height) && !path.include?('://') params[:alt] ||= '' real_path = path 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) + if File.exist?(full_path) begin width, height = ::FastImage.size(full_path, :raise_on_failure => true) params[:width] = width @@ -31,7 +30,7 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension rescue FastImage::UnknownImageType # No message, it's just not supported rescue - warn "Couldn't determine dimensions for image #{path}: #{$!.message}" + warn "Couldn't determine dimensions for image #{path}: #{$ERROR_INFO.message}" end end end diff --git a/middleman-core/lib/middleman-more/extensions/cache_buster.rb b/middleman-core/lib/middleman-more/extensions/cache_buster.rb index 02ded8af..98e9d647 100644 --- a/middleman-core/lib/middleman-more/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-more/extensions/cache_buster.rb @@ -1,6 +1,5 @@ # The Cache Buster extension class Middleman::Extensions::CacheBuster < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-more/extensions/gzip.rb b/middleman-core/lib/middleman-more/extensions/gzip.rb index d52e8cfc..21b40f06 100644 --- a/middleman-core/lib/middleman-more/extensions/gzip.rb +++ b/middleman-core/lib/middleman-more/extensions/gzip.rb @@ -35,7 +35,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension # Farm out gzip tasks to threads and put the results in in_queue out_queue = Queue.new - threads = num_threads.times.map do + num_threads.times.each do Thread.new do while path = in_queue.pop out_queue << gzip_file(path.to_s) diff --git a/middleman-core/lib/middleman-more/extensions/lorem.rb b/middleman-core/lib/middleman-more/extensions/lorem.rb index d13abeeb..32f1c6c1 100644 --- a/middleman-core/lib/middleman-more/extensions/lorem.rb +++ b/middleman-core/lib/middleman-more/extensions/lorem.rb @@ -94,11 +94,11 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension # Get a placeholder date # @param [String] fmt # @return [String] - def date(fmt = '%a %b %d, %Y') + def date(fmt='%a %b %d, %Y') y = rand(20) + 1990 m = rand(12) + 1 d = rand(31) + 1 - Time.local(y,m,d).strftime(fmt) + Time.local(y, m, d).strftime(fmt) end # Get a placeholder name @@ -125,16 +125,16 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension # Via http://www.kevadamson.com/talking-of-design/article/140-alternative-characters-to-lorem-ipsum # @return [String] def tweet - tweets = [ 'Far away, in a forest next to a river beneath the mountains, there lived a small purple otter called Philip. Philip likes sausages. The End.', - 'He liked the quality sausages from Marks & Spencer but due to the recession he had been forced to shop in a less desirable supermarket. End.', - 'He awoke one day to find his pile of sausages missing. Roger the greedy boar with human eyes, had skateboarded into the forest & eaten them!'] + tweets = ['Far away, in a forest next to a river beneath the mountains, there lived a small purple otter called Philip. Philip likes sausages. The End.', + 'He liked the quality sausages from Marks & Spencer but due to the recession he had been forced to shop in a less desirable supermarket. End.', + 'He awoke one day to find his pile of sausages missing. Roger the greedy boar with human eyes, had skateboarded into the forest & eaten them!'] tweets[rand(tweets.size)] end # Get a placeholder email address # @return [String] def email - delimiters = [ '_', '-', '' ] + delimiters = ['_', '-', ''] domains = %w(gmail.com yahoo.com hotmail.com email.com live.com me.com mac.com aol.com fastmail.com mail.com) username = name.gsub(/[^\w]/, delimiters[rand(delimiters.size)]) "#{username}@#{domains[rand(domains.size)]}".downcase @@ -147,7 +147,7 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension def image(size, options={}) domain = options[:domain] || 'http://placehold.it' src = "#{domain}/#{size}" - hex = %w[a b c d e f 0 1 2 3 4 5 6 7 8 9] + hex = %w(a b c d e f 0 1 2 3 4 5 6 7 8 9) background_color = options[:background_color] color = options[:color] @@ -159,7 +159,7 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension src << "/#{background_color.sub(/^#/, '')}" if background_color src << '/ccc' if background_color.nil? && color src << "/#{color.sub(/^#/, '')}" if color - src << "&text=#{Rack::Utils::escape(options[:text])}" if options[:text] + src << "&text=#{Rack::Utils.escape(options[:text])}" if options[:text] src end diff --git a/middleman-core/lib/middleman-more/extensions/minify_css.rb b/middleman-core/lib/middleman-more/extensions/minify_css.rb index 1945f4c1..e281d9b3 100644 --- a/middleman-core/lib/middleman-more/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-more/extensions/minify_css.rb @@ -20,9 +20,9 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension end class SassCompressor - def self.compress(style, options = {}) + def self.compress(style, options={}) root_node = ::Sass::SCSS::CssParser.new(style, 'middleman-css-input', 1).parse - root_node.options = { :style => :compressed } + root_node.options = options.merge(:style => :compressed) root_node.render.strip end end @@ -49,7 +49,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension if inline_html_content?(env['PATH_INFO']) minified = ::Middleman::Util.extract_response_text(response) - minified.gsub!(INLINE_CSS_REGEX) do |match| + minified.gsub!(INLINE_CSS_REGEX) do $1 << @compressor.compress($2) << $3 end @@ -65,13 +65,14 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension [status, headers, response] end - private + private + def inline_html_content?(path) (path.end_with?('.html') || path.end_with?('.php')) && @inline end def standalone_css_content?(path) - path.end_with?('.css') && @ignore.none? {|ignore| Middleman::Util.path_match(ignore, path) } + path.end_with?('.css') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) } end end end diff --git a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb index ecacae4c..f0528391 100644 --- a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb @@ -24,7 +24,6 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension # Rack middleware to look for JS and compress it class Rack - # Init # @param [Class] app # @param [Hash] options @@ -51,7 +50,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s response = [minified] - elsif path.end_with?('.js') && @ignore.none? {|ignore| Middleman::Util.path_match(ignore, path) } + elsif path.end_with?('.js') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) } uncompressed_source = ::Middleman::Util.extract_response_text(response) minified = @compressor.compress(uncompressed_source) @@ -65,7 +64,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension [status, headers, response] end - private + private def minify_inline_content(uncompressed_source) uncompressed_source.gsub(/(]*>\s*(?:\/\/(?:(?:)|(?:\]\]>)))?\s*<\/script>)/m) do |match| diff --git a/middleman-core/lib/middleman-more/extensions/relative_assets.rb b/middleman-core/lib/middleman-more/extensions/relative_assets.rb index 3e67d59d..130bffb8 100644 --- a/middleman-core/lib/middleman-more/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-more/extensions/relative_assets.rb @@ -1,6 +1,5 @@ # Relative Assets extension class Middleman::Extensions::RelativeAssets < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-more/templates/smacss.rb b/middleman-core/lib/middleman-more/templates/smacss.rb index bfe5c914..88e14d53 100644 --- a/middleman-core/lib/middleman-more/templates/smacss.rb +++ b/middleman-core/lib/middleman-more/templates/smacss.rb @@ -1,15 +1,14 @@ # SMACSS class Middleman::Templates::Smacss < Middleman::Templates::Base - class_option 'css_dir', - :default => 'stylesheets', - :desc => 'The path to the css files' + :default => 'stylesheets', + :desc => 'The path to the css files' class_option 'js_dir', - :default => 'javascripts', - :desc => 'The path to the javascript files' + :default => 'javascripts', + :desc => 'The path to the javascript files' class_option 'images_dir', - :default => 'images', - :desc => 'The path to the image files' + :default => 'images', + :desc => 'The path to the image files' # Template files are relative to this file # @return [String] From 348417601b8201c78ebf72b5c41d54f8cb3b2fc7 Mon Sep 17 00:00:00 2001 From: 747 <747.neutron+ghub@gmail.com> Date: Tue, 29 Apr 2014 22:43:33 +0900 Subject: [PATCH 008/662] quick fix for finding eponymous parents --- .../sitemap/extensions/traversal.rb | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index 78f8eb28..4e9aabee 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -9,16 +9,23 @@ module Middleman # @return [Middleman::Sitemap::Resource, nil] def parent parts = path.split('/') - parts.pop if path.include?(app.index_file) + tail = parts.pop + is_index = (tail == app.index_file) - return nil if parts.length < 1 + return nil if is_index && parts.length < 1 - parts.pop - parts << app.index_file + test_expr = parts.join('\\/') + # A makeshift for eponymous reverse-lookup + found = store.resources.find { |candidate| + candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$! + } - parent_path = '/' + parts.join('/') - - store.find_resource_by_destination_path(parent_path) + if found + return found + else + parts.pop if is_index + return store.find_resource_by_destination_path("#{parts.join('/')}/#{app.index_file}") + end end # This resource's child resources From 8eabe4d354a046f03766521faf42d589801cad36 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 29 Apr 2014 10:44:24 -0700 Subject: [PATCH 009/662] rubocop 2: the reckoning --- .rubocop.yml | 3 +- Gemfile | 28 +++---- Rakefile | 24 ++---- gem_rake_helper.rb | 4 +- middleman-core/lib/middleman-core.rb | 1 + .../lib/middleman-core/application.rb | 10 +-- middleman-core/lib/middleman-core/cli.rb | 12 ++- .../lib/middleman-core/cli/build.rb | 37 ++++----- .../lib/middleman-core/cli/bundler.rb | 2 +- .../lib/middleman-core/cli/console.rb | 20 ++--- .../lib/middleman-core/cli/extension.rb | 4 +- middleman-core/lib/middleman-core/cli/init.rb | 38 ++++----- .../lib/middleman-core/cli/server.rb | 82 +++++++++---------- .../lib/middleman-core/configuration.rb | 10 ++- .../middleman-core/core_extensions/data.rb | 14 +--- .../core_extensions/extensions.rb | 3 +- .../core_extensions/file_watcher.rb | 2 +- .../core_extensions/front_matter.rb | 3 +- .../core_extensions/rendering.rb | 7 +- .../middleman-core/core_extensions/request.rb | 17 ++-- .../middleman-core/core_extensions/routing.rb | 7 +- .../core_extensions/show_exceptions.rb | 4 +- .../lib/middleman-core/extension.rb | 17 ++-- .../lib/middleman-core/meta_pages.rb | 10 +-- .../meta_pages/config_setting.rb | 8 +- .../meta_pages/sitemap_resource.rb | 4 +- .../middleman-core/meta_pages/sitemap_tree.rb | 8 +- .../lib/middleman-core/preview_server.rb | 14 ++-- .../lib/middleman-core/profiling.rb | 5 +- .../lib/middleman-core/renderers/asciidoc.rb | 16 ++-- .../middleman-core/renderers/coffee_script.rb | 2 +- .../lib/middleman-core/renderers/erb.rb | 2 +- .../lib/middleman-core/renderers/haml.rb | 2 +- .../lib/middleman-core/renderers/kramdown.rb | 4 +- .../lib/middleman-core/renderers/less.rb | 4 +- .../lib/middleman-core/renderers/liquid.rb | 6 +- .../lib/middleman-core/renderers/markdown.rb | 10 +-- .../lib/middleman-core/renderers/redcarpet.rb | 6 +- .../lib/middleman-core/renderers/sass.rb | 15 ++-- .../lib/middleman-core/renderers/slim.rb | 12 +-- .../lib/middleman-core/renderers/stylus.rb | 2 +- middleman-core/lib/middleman-core/sitemap.rb | 8 +- .../sitemap/extensions/on_disk.rb | 6 +- .../sitemap/extensions/proxies.rb | 8 +- .../sitemap/extensions/redirects.rb | 10 +-- .../sitemap/extensions/request_endpoints.rb | 4 +- .../sitemap/extensions/traversal.rb | 2 +- .../lib/middleman-core/sitemap/queryable.rb | 32 ++++---- .../lib/middleman-core/sitemap/resource.rb | 26 ++---- .../lib/middleman-core/sitemap/store.rb | 11 ++- .../lib/middleman-core/templates.rb | 17 ++-- .../lib/middleman-core/templates/default.rb | 12 +-- .../templates/extension/Rakefile | 4 +- .../lib/middleman-core/templates/html5.rb | 12 +-- .../lib/middleman-core/templates/mobile.rb | 6 +- .../core_extensions/default_helpers.rb | 2 + .../middleman-more/core_extensions/i18n.rb | 22 ++--- .../middleman-more/extensions/asset_hash.rb | 2 +- .../extensions/automatic_image_sizes.rb | 2 +- .../middleman-more/extensions/minify_css.rb | 8 +- .../extensions/minify_javascript.rb | 6 +- .../lib/middleman-more/templates/smacss.rb | 12 +-- 62 files changed, 328 insertions(+), 363 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 152ea112..d966a685 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -25,8 +25,7 @@ Documentation: Encoding: Enabled: false HashSyntax: - # EnforcedStyle: ruby19 - Enabled: false + EnforcedStyle: ruby19 SpaceAroundEqualsInParameterDefault: EnforcedStyle: no_space Blocks: diff --git a/Gemfile b/Gemfile index 2f4e97a3..4c721ffa 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,8 @@ source 'https://rubygems.org' # Build and doc tools -gem 'rake', '~> 10.0.3', :require => false -gem 'yard', '~> 0.8.0', :require => false +gem 'rake', '~> 10.0.3', require: false +gem 'yard', '~> 0.8.0', require: false # Test tools gem 'cucumber', '~> 1.3.1' @@ -12,17 +12,17 @@ gem 'rspec', '~> 2.12' gem 'simplecov' # Optional middleman dependencies, included for tests -gem 'sinatra', :require => false -gem 'slim', :require => false -gem 'liquid', :require => false -gem 'less', '~> 2.3.0', :require => false -gem 'stylus', :require => false -gem 'asciidoctor', :require => false +gem 'sinatra', require: false +gem 'slim', require: false +gem 'liquid', require: false +gem 'less', '~> 2.3.0', require: false +gem 'stylus', require: false +gem 'asciidoctor', require: false platforms :ruby do gem 'therubyracer' gem 'redcarpet', '~> 3.1' - gem 'pry', :require => false, :group => :development + gem 'pry', require: false, group: :development end platforms :jruby do @@ -30,10 +30,10 @@ platforms :jruby do end # Code Quality -gem 'coveralls', :require => false -gem 'rubocop', :require => false +gem 'coveralls', require: false +gem 'rubocop', require: false # Middleman itself -gem 'middleman-core', :path => 'middleman-core' -gem 'middleman-sprockets', :github => 'middleman/middleman-sprockets' -gem 'middleman', :path => 'middleman' +gem 'middleman-core', path: 'middleman-core' +gem 'middleman-sprockets', github: 'middleman/middleman-sprockets' +gem 'middleman', path: 'middleman' diff --git a/Rakefile b/Rakefile index efae9ae9..05da4ae9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,4 @@ -require 'rubygems' unless defined?(Gem) -# require 'fileutils' unless defined?(FileUtils) +require 'rubygems' unless defined?(Gem) require 'rake' require File.expand_path('../middleman-core/lib/middleman-core/version.rb', __FILE__) @@ -11,7 +10,7 @@ middleman_gems = %w(middleman-core middleman) GEM_PATHS = middleman_gems.freeze def sh_rake(command) - sh "#{Gem.ruby} -S rake #{command}", :verbose => true + sh "#{Gem.ruby} -S rake #{command}", verbose: true end desc 'Displays the current version' @@ -19,19 +18,6 @@ task :version do puts "Current version: #{Middleman::VERSION}" end -desc 'Bumps the version number based on given version' -task :bump, [:version] do |_, args| - raise 'Please specify version=x.x.x !' unless args.version - version_path = File.dirname(__FILE__) + '/middleman-core/lib/middleman-core/version.rb' - version_text = File.read(version_path).sub(/VERSION = '[\d\.\w]+'/, "VERSION = '#{args.version}'") - puts "Updating Middleman to version #{args.version}" - File.open(version_path, 'w') { |f| f.write version_text } - sh 'git commit -a -m "Bumped version to %s"' % args.version -end - -desc 'Executes a fresh install removing all middleman version and then reinstall all gems' -task :fresh => [:uninstall, :install, :clean] - desc 'Pushes repository to GitHub' task :push do puts 'Pushing to github...' @@ -41,12 +27,11 @@ task :push do end desc 'Release all middleman gems' -task :publish => :push do +task publish: :push do puts 'Pushing to rubygems...' GEM_PATHS.each do |dir| Dir.chdir(dir) { sh_rake('release') } end - Rake::Task['clean'].invoke end desc 'Generate documentation for all middleman gems' @@ -61,6 +46,7 @@ task :test do GEM_PATHS.each do |g| Dir.chdir("#{File.join(ROOT, g)}") { sh "#{Gem.ruby} -S rake test" } end + Rake::Task['rubocop'].invoke end desc 'Run specs for all middleman gems' @@ -77,4 +63,4 @@ Rubocop::RakeTask.new(:rubocop) do |task| end desc 'Run tests for all middleman gems' -task :default => :test +task default: :test diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index 5dab239b..284cf5dc 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -38,8 +38,8 @@ RSpec::Core::RakeTask.new do |spec| end desc 'Run tests, both RSpec and Cucumber' -task :test => [:spec, :cucumber] +task test: [:spec, :cucumber] YARD::Rake::YardocTask.new -task :default => :test +task default: :test diff --git a/middleman-core/lib/middleman-core.rb b/middleman-core/lib/middleman-core.rb index 5d3dc485..41673aac 100644 --- a/middleman-core/lib/middleman-core.rb +++ b/middleman-core/lib/middleman-core.rb @@ -1,4 +1,5 @@ # Setup our load paths +# rubocop:disable FileName libdir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 01027640..be87608a 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -52,20 +52,20 @@ module Middleman class_eval(&block) if block_given? include(*extensions) if extensions.any? end - delegate :helpers, :to => :"self.class" + delegate :helpers, to: :"self.class" # Root project directory (overwritten in middleman build/server) # @return [String] def self.root ENV['MM_ROOT'] || Dir.pwd end - delegate :root, :to => :"self.class" + delegate :root, to: :"self.class" # Pathname-addressed root def self.root_path Pathname(root) end - delegate :root_path, :to => :"self.class" + delegate :root_path, to: :"self.class" # Name of the source directory # @return [String] @@ -195,7 +195,7 @@ module Middleman def self.cache @_cache ||= ::Tilt::Cache.new end - delegate :cache, :to => :"self.class" + delegate :cache, to: :"self.class" # Whether we're in development mode # @return [Boolean] If we're in dev mode @@ -216,7 +216,7 @@ module Middleman File.join(root, config[:source]) end - delegate :instrument, :to => ::Middleman::Util + delegate :instrument, to: ::Middleman::Util # Work around this bug: http://bugs.ruby-lang.org/issues/4521 # where Ruby will call to_s/inspect while printing exception diff --git a/middleman-core/lib/middleman-core/cli.rb b/middleman-core/lib/middleman-core/cli.rb index e086e8e6..5090351f 100644 --- a/middleman-core/lib/middleman-core/cli.rb +++ b/middleman-core/lib/middleman-core/cli.rb @@ -30,10 +30,11 @@ module Middleman # @param [Symbol, String, nil] meth # @param [Boolean] subcommand # @return [void] + # rubocop:disable UnusedMethodArgument def help(meth=nil, subcommand=false) if meth && !self.respond_to?(meth) klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") - klass.start(['-h', task].compact, :shell => shell) + klass.start(['-h', task].compact, shell: shell) else list = [] Thor::Util.thor_classes_in(Middleman::Cli).each do |thor_class| @@ -42,7 +43,7 @@ module Middleman list.sort! { |a, b| a[0] <=> b[0] } shell.say 'Tasks:' - shell.print_table(list, :ident => 2, :truncate => true) + shell.print_table(list, ident: 2, truncate: true) shell.say end end @@ -51,10 +52,7 @@ module Middleman # @param [Symbol] meth def method_missing(meth, *args) meth = meth.to_s - - if self.class.map.key?(meth) - meth = self.class.map[meth] - end + meth = self.class.map[meth] if self.class.map.key?(meth) klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") @@ -71,7 +69,7 @@ module Middleman raise Thor::Error, "There's no '#{meth}' command for Middleman. Try 'middleman help' for a list of commands." else args.unshift(task) if task - klass.start(args, :shell => shell) + klass.start(args, shell: shell) end end end diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 836f3139..1af54e5e 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -19,26 +19,26 @@ module Middleman::Cli desc 'build [options]', 'Builds the static site for deployment' method_option :clean, - :type => :boolean, - :default => true, - :desc => 'Remove orphaned files from build (--no-clean to disable)' + type: :boolean, + default: true, + desc: 'Remove orphaned files from build (--no-clean to disable)' method_option :glob, - :type => :string, - :aliases => '-g', - :default => nil, - :desc => 'Build a subset of the project' + type: :string, + aliases: '-g', + default: nil, + desc: 'Build a subset of the project' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + type: :string, + default: false, + desc: 'Print instrument messages' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for the build' + type: :boolean, + default: false, + desc: 'Generate profiling report for the build' # Core build Thor command # @return [void] @@ -135,11 +135,11 @@ module Middleman::Cli # @return [void] def clean! @to_clean.each do |f| - base.remove_file f, :force => true + base.remove_file f, force: true end Dir[@build_dir.join('**', '*')].select { |d| File.directory?(d) }.each do |d| - base.remove_file d, :force => true if directory_empty? d + base.remove_file d, force: true if directory_empty? d end end @@ -273,7 +273,6 @@ module Middleman::Cli base.say_status :error, file_name, :red if base.debugging raise e - exit(1) elsif base.options['verbose'] base.shell.say response, :red end diff --git a/middleman-core/lib/middleman-core/cli/bundler.rb b/middleman-core/lib/middleman-core/cli/bundler.rb index 73bbd326..3f025ef3 100644 --- a/middleman-core/lib/middleman-core/cli/bundler.rb +++ b/middleman-core/lib/middleman-core/cli/bundler.rb @@ -7,7 +7,7 @@ module Middleman::Cli namespace :bundle - desc 'bundle', 'Setup initial bundle', :hide => true + desc 'bundle', 'Setup initial bundle', hide: true # The setup task def bundle diff --git a/middleman-core/lib/middleman-core/cli/console.rb b/middleman-core/lib/middleman-core/cli/console.rb index 86b660da..56b9abd9 100644 --- a/middleman-core/lib/middleman-core/cli/console.rb +++ b/middleman-core/lib/middleman-core/cli/console.rb @@ -10,26 +10,24 @@ module Middleman::Cli desc 'console [options]', 'Start an interactive console in the context of your Middleman application' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + aliases: '-e', + default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + desc: 'The environment Middleman will run under' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' def console require 'middleman-core' require 'irb' opts = { - :environment => options['environment'], - :debug => options['verbose'] + environment: options['environment'], + debug: options['verbose'] } @app = ::Middleman::Application.server.inst do - if opts[:environment] - set :environment, opts[:environment].to_sym - end + set :environment, opts[:environment].to_sym if opts[:environment] ::Middleman::Logger.singleton(opts[:debug] ? 0 : 1, opts[:instrumenting] || false) end diff --git a/middleman-core/lib/middleman-core/cli/extension.rb b/middleman-core/lib/middleman-core/cli/extension.rb index b4c92d81..1065514f 100644 --- a/middleman-core/lib/middleman-core/cli/extension.rb +++ b/middleman-core/lib/middleman-core/cli/extension.rb @@ -9,7 +9,7 @@ module Middleman::Cli namespace :extension # Required path for the new project to be generated - argument :name, :type => :string + argument :name, type: :string # Template files are relative to this file # @return [String] @@ -33,7 +33,7 @@ module Middleman::Cli end # Output a .gitignore file - class_option :git, :type => :boolean, :default => true + class_option :git, type: :boolean, default: true no_tasks { # Write a .gitignore file for project diff --git a/middleman-core/lib/middleman-core/cli/init.rb b/middleman-core/lib/middleman-core/cli/init.rb index e010c860..98782807 100644 --- a/middleman-core/lib/middleman-core/cli/init.rb +++ b/middleman-core/lib/middleman-core/cli/init.rb @@ -11,35 +11,35 @@ module Middleman::Cli desc 'init NAME [options]', 'Create new project NAME' available_templates = ::Middleman::Templates.registered.keys.join(', ') method_option 'template', - :aliases => '-T', - :default => 'default', - :desc => "Use a project template: #{available_templates}" + aliases: '-T', + default: 'default', + desc: "Use a project template: #{available_templates}" method_option 'css_dir', # :default => "stylesheets", - :desc => 'The path to the css files' + desc: 'The path to the css files' method_option 'js_dir', # :default => "javascripts", - :desc => 'The path to the javascript files' + desc: 'The path to the javascript files' method_option 'images_dir', # :default => "images", - :desc => 'The path to the image files' + desc: 'The path to the image files' method_option 'rack', - :type => :boolean, - :default => false, - :desc => 'Include a config.ru file' + type: :boolean, + default: false, + desc: 'Include a config.ru file' method_option 'skip-gemfile', - :type => :boolean, - :default => false, - :desc => "Don't create a Gemfile" + type: :boolean, + default: false, + desc: "Don't create a Gemfile" method_option 'skip-bundle', - :type => :boolean, - :aliases => '-B', - :default => false, - :desc => "Don't run bundle install" + type: :boolean, + aliases: '-B', + default: false, + desc: "Don't run bundle install" method_option 'skip-git', - :type => :boolean, - :default => false, - :desc => 'Skip Git ignores and keeps' + type: :boolean, + default: false, + desc: 'Skip Git ignores and keeps' # The init task # @param [String] name def init(name='.') diff --git a/middleman-core/lib/middleman-core/cli/server.rb b/middleman-core/lib/middleman-core/cli/server.rb index e41e0333..7a41f59e 100644 --- a/middleman-core/lib/middleman-core/cli/server.rb +++ b/middleman-core/lib/middleman-core/cli/server.rb @@ -8,47 +8,47 @@ module Middleman::Cli desc 'server [options]', 'Start the preview server' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + aliases: '-e', + default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + desc: 'The environment Middleman will run under' method_option :host, - :type => :string, - :aliases => '-h', - :default => '0.0.0.0', - :desc => 'Bind to HOST address' + type: :string, + aliases: '-h', + default: '0.0.0.0', + desc: 'Bind to HOST address' method_option :port, - :aliases => '-p', - :default => '4567', - :desc => 'The port Middleman will listen on' + aliases: '-p', + default: '4567', + desc: 'The port Middleman will listen on' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + type: :string, + default: false, + desc: 'Print instrument messages' method_option :disable_watcher, - :type => :boolean, - :default => false, - :desc => 'Disable the file change and delete watcher process' + type: :boolean, + default: false, + desc: 'Disable the file change and delete watcher process' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for server startup' + type: :boolean, + default: false, + desc: 'Generate profiling report for server startup' method_option :reload_paths, - :type => :string, - :default => false, - :desc => 'Additional paths to auto-reload when files change' + type: :string, + default: false, + desc: 'Additional paths to auto-reload when files change' method_option :force_polling, - :type => :boolean, - :default => false, - :desc => 'Force file watcher into polling mode' + type: :boolean, + default: false, + desc: 'Force file watcher into polling mode' method_option :latency, - :type => :numeric, - :aliases => '-l', - :default => 0.25, - :desc => 'Set file watcher latency, in seconds' + type: :numeric, + aliases: '-l', + default: 0.25, + desc: 'Set file watcher latency, in seconds' # Start the server def server @@ -63,15 +63,15 @@ module Middleman::Cli end params = { - :port => options['port'], - :host => options['host'], - :environment => options['environment'], - :debug => options['verbose'], - :instrumenting => options['instrument'], - :disable_watcher => options['disable_watcher'], - :reload_paths => options['reload_paths'], - :force_polling => options['force_polling'], - :latency => options['latency'] + port: options['port'], + host: options['host'], + environment: options['environment'], + debug: options['verbose'], + instrumenting: options['instrument'], + disable_watcher: options['disable_watcher'], + reload_paths: options['reload_paths'], + force_polling: options['force_polling'], + latency: options['latency'] } puts '== The Middleman is loading' diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index 244b0603..6c227504 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -111,16 +111,17 @@ module Middleman # Get the value of a setting by key. Returns nil if there is no such setting. # @return [Object] def [](key) - setting = @settings[key] - setting ? setting.value : nil + setting_obj = setting(key) + setting_obj ? setting_obj.value : nil end # Set the value of a setting by key. Creates the setting if it doesn't exist. # @param [Symbol] key # @param [Object] val + # rubocop:disable UselessSetterCall def []=(key, val) - setting = @settings[key] || define_setting(key) - setting.value = val + setting_obj = setting(key) || define_setting(key) + setting_obj.value = val end # Allow configuration settings to be read and written via methods @@ -227,6 +228,7 @@ module Middleman end # Whether or not there has been a value set beyond the default + # rubocop:disable TrivialAccessors def value_set? @value_set end diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 5555962c..4f8a0e50 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -143,9 +143,6 @@ module Middleman def data_for_path(path) response = nil - @@local_sources ||= {} - @@callback_sources ||= {} - if store.key?(path.to_s) response = store[path.to_s] elsif callbacks.key?(path.to_s) @@ -164,10 +161,7 @@ module Middleman return @local_data[path.to_s] else result = data_for_path(path) - - if result - return ::Middleman::Util.recursively_enhance(result) - end + return ::Middleman::Util.recursively_enhance(result) if result end super @@ -187,11 +181,11 @@ module Middleman __send__(key) if key?(key) end - def has_key?(key) - @local_data.key?(key.to_s) || !!(data_for_path(key)) + def key?(key) + @local_data.key?(key.to_s) || data_for_path(key) end - alias_method :key?, :has_key? + alias_method :has_key?, :key? # Convert all the data into a static hash # diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 2e174d81..917f7f6c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -48,7 +48,7 @@ module Middleman app.extend ClassMethods app.send :include, InstanceMethods - app.delegate :configure, :to => :"self.class" + app.delegate :configure, to: :"self.class" end alias_method :included, :registered end @@ -95,6 +95,7 @@ module Middleman # # @param [Symbol, Module] ext Which extension to activate # @return [void] + # rubocop:disable BlockNesting def activate(ext, options={}, &block) ext_module = if ext.is_a?(Module) ext 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 fd618261..d13d6589 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -61,7 +61,7 @@ module Middleman class API attr_reader :app attr_reader :known_paths - delegate :logger, :to => :app + delegate :logger, to: :app # Initialize api and internal path cache def initialize(app) 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 6d43c9c3..b9f09647 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -43,7 +43,7 @@ module Middleman::CoreExtensions data[opt] = fmdata[opt] unless fmdata[opt].nil? end - { :options => data, :page => ::Middleman::Util.recursively_enhance(fmdata).freeze } + { options: data, page: ::Middleman::Util.recursively_enhance(fmdata).freeze } end end @@ -114,6 +114,7 @@ module Middleman::CoreExtensions end private + # Parse YAML frontmatter out of a string # @param [String] content # @return [Array] diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index d1db2cdb..f6737724 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -1,12 +1,12 @@ # Shutup Tilt Warnings # @private class Tilt::Template - def warn(*args) - # Kernel.warn(*args) + def warn(*) end end # Rendering extension +# rubocop:disable UnderscorePrefixedVariableName module Middleman module CoreExtensions module Rendering @@ -402,6 +402,7 @@ module Middleman end # The currently rendering engine + # rubocop:disable TrivialAccessors # @return [Symbol, nil] def current_engine=(v) @_current_engine = v @@ -427,7 +428,7 @@ module Middleman extension_class = ::Tilt[options[:preferred_engine]] # Get a list of extensions for a preferred engine - matched_exts = ::Tilt.mappings.select do |ext, engines| + matched_exts = ::Tilt.mappings.select do |_, engines| engines.include? extension_class end.keys diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index a3bbe7b2..e78f0ffe 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -69,15 +69,15 @@ module Middleman app.use Rack::Lint app.use Rack::Head - Array(@middleware).each do |klass, options, block| - app.use(klass, *options, &block) + Array(@middleware).each do |klass, options, middleware_block| + app.use(klass, *options, &middleware_block) end inner_app = inst(&block) app.map('/') { run inner_app } - Array(@mappings).each do |path, block| - app.map(path, &block) + Array(@mappings).each do |path, map_block| + app.map(path, &map_block) end app @@ -125,6 +125,7 @@ module Middleman # configuration can be included later without impacting # other classes and instances. # + # rubocop:disable ClassVars # @return [Class] def server(&block) @@servercounter ||= 0 @@ -165,13 +166,13 @@ module Middleman def current_path=(path) Thread.current[:current_path] = path Thread.current[:legacy_request] = ::Thor::CoreExt::HashWithIndifferentAccess.new( - :path => path, - :params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {} + path: path, + params: req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {} ) end - delegate :use, :to => :"self.class" - delegate :map, :to => :"self.class" + delegate :use, to: :"self.class" + delegate :map, to: :"self.class" # Rack request # @return [Rack::Request] diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 15acbc39..e2328a02 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -39,7 +39,7 @@ module Middleman # Use the metadata loop for matching against paths at runtime sitemap.provides_metadata_for_path(url) do |_| - { :options => opts, :blocks => blocks } + { options: opts, blocks: blocks } end return @@ -54,7 +54,8 @@ module Middleman # Setup proxy if target = opts.delete(:proxy) # TODO: deprecate proxy through page? - proxy(url, target, opts, &block) and return + proxy(url, target, opts, &block) + return elsif opts.delete(:ignore) # TODO: deprecate ignore through page? ignore(url) @@ -62,7 +63,7 @@ module Middleman # Setup a metadata matcher for rendering those options sitemap.provides_metadata_for_path(url) do |_| - { :options => opts, :blocks => blocks } + { options: opts, blocks: blocks } end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index f1060b32..5eba1c0a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -16,9 +16,7 @@ module Middleman # When in dev app.configure :development do # Include middlemare - if config[:show_exceptions] - use ::Rack::ShowExceptions - end + use ::Rack::ShowExceptions if config[:show_exceptions] end end end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 6bc59f7d..887a05fb 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -3,9 +3,9 @@ require 'active_support/core_ext/class/attribute' module Middleman class Extension - class_attribute :supports_multiple_instances, :instance_reader => false, :instance_writer => false - class_attribute :defined_helpers, :instance_reader => false, :instance_writer => false - class_attribute :ext_name, :instance_reader => false, :instance_writer => false + class_attribute :supports_multiple_instances, instance_reader: false, instance_writer: false + class_attribute :defined_helpers, instance_reader: false, instance_writer: false + class_attribute :ext_name, instance_reader: false, instance_writer: false class << self def config @@ -23,7 +23,7 @@ module Middleman def helpers(*m, &block) self.defined_helpers ||= [] - if block + if block_given? mod = Module.new mod.module_eval(&block) m = [mod] @@ -66,7 +66,7 @@ module Middleman attr_accessor :options attr_reader :app - delegate :after_extension_activated, :to => :"::Middleman::Extension" + delegate :after_extension_activated, to: :"::Middleman::Extension" def initialize(klass, options_hash={}, &block) @_helpers = [] @@ -92,7 +92,7 @@ module Middleman protected - def setup_options(options_hash, &block) + def setup_options(options_hash) @options = self.class.config.dup @options.finalize! @@ -127,10 +127,9 @@ module Middleman def bind_after_configuration ext = self @klass.after_configuration do - if ext.respond_to?(:after_configuration) - ext.after_configuration - end + ext.after_configuration if ext.respond_to?(:after_configuration) + # rubocop:disable IfUnlessModifier if ext.respond_to?(:manipulate_resource_list) ext.app.sitemap.register_resource_list_manipulator(ext.class.extension_name, ext) end diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index f2eca41d..8e1a68a7 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -19,7 +19,7 @@ module Middleman meta_pages = self @rack_app = Rack::Builder.new do # Serve assets from metadata/assets - use Rack::Static, :urls => ['/assets'], :root => File.join(File.dirname(__FILE__), 'meta_pages') + use Rack::Static, urls: ['/assets'], root: File.join(File.dirname(__FILE__), 'meta_pages') map '/' do run meta_pages.method(:index) @@ -54,7 +54,7 @@ module Middleman sitemap_tree.add_resource resource end - template('sitemap.html.erb', :sitemap_tree => sitemap_tree) + template('sitemap.html.erb', sitemap_tree: sitemap_tree) end # Inspect configuration @@ -80,9 +80,9 @@ module Middleman end template('config.html.erb', - :global_config => global_config, - :extension_config => extension_config, - :registered_extensions => Middleman::Extensions.registered.dup) + global_config: global_config, + extension_config: extension_config, + registered_extensions: Middleman::Extensions.registered.dup) end private diff --git a/middleman-core/lib/middleman-core/meta_pages/config_setting.rb b/middleman-core/lib/middleman-core/meta_pages/config_setting.rb index 3fd223e3..d10a484a 100644 --- a/middleman-core/lib/middleman-core/meta_pages/config_setting.rb +++ b/middleman-core/lib/middleman-core/meta_pages/config_setting.rb @@ -15,17 +15,17 @@ module Middleman content = '' key_classes = ['key'] key_classes << 'modified' if @setting.value_set? - content << content_tag(:span, @setting.key.pretty_inspect.strip, :class => key_classes.join(' ')) + content << content_tag(:span, @setting.key.pretty_inspect.strip, class: key_classes.join(' ')) content << ' = ' - content << content_tag(:span, @setting.value.pretty_inspect.strip, :class => 'value') + content << content_tag(:span, @setting.value.pretty_inspect.strip, class: 'value') if @setting.default && @setting.value_set? && @setting.default != @setting.value - content << content_tag(:span, :class => 'default') do + content << content_tag(:span, class: 'default') do "(Default: #{@setting.default.inspect})" end end if @setting.description - content << content_tag(:p, :class => 'description') do + content << content_tag(:p, class: 'description') do @setting.description end end 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 d16b9154..e42176df 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb @@ -14,7 +14,7 @@ module Middleman def render classes = 'resource-details' classes << ' ignored' if @resource.ignored? - content_tag :div, :class => classes do + content_tag :div, class: classes do content_tag :table do content = '' resource_properties.each do |label, value| @@ -38,7 +38,7 @@ module Middleman build_path = @resource.destination_path 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['URL'] = content_tag(:a, @resource.url, href: @resource.url) unless ignored? props['Source File'] = @resource.source_file.sub(/^#{Regexp.escape(ENV['MM_ROOT'] + '/')}/, '') data = @resource.data diff --git a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb index ab2f03d9..4ba89350 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb @@ -13,8 +13,7 @@ module Middleman end def render - content = '' - @children.keys.sort do |a, b| + sorted_children_keys = @children.keys.sort do |a, b| a_subtree = @children[a] b_subtree = @children[b] if a_subtree.is_a? SitemapResource @@ -32,7 +31,9 @@ module Middleman else a.downcase <=> b.downcase end - end.each do |path_part| + end + + sorted_children_keys.reduce('') do |content, path_part| subtree = @children[path_part] content << "
" content << '' @@ -41,7 +42,6 @@ module Middleman content << subtree.render content << '
' end - content end def css_classes diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 03e117bf..41e7d5cf 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -2,13 +2,14 @@ require 'webrick' require 'middleman-core/meta_pages' require 'middleman-core/logger' +# rubocop:disable GlobalVars module Middleman module PreviewServer DEFAULT_PORT = 4567 class << self attr_reader :app, :host, :port - delegate :logger, :to => :app + delegate :logger, to: :app # Start an instance of Middleman::Application # @return [void] @@ -89,6 +90,7 @@ module Middleman end private + def new_app opts = @options.dup server = ::Middleman::Application.server @@ -119,7 +121,7 @@ module Middleman if first_run # Watcher Library require 'listen' - @listener = Listen.to(Dir.pwd, :relative_paths => true, :force_polling => @options[:force_polling]) + @listener = Listen.to(Dir.pwd, relative_paths: true, force_polling: @options[:force_polling]) @listener.latency(@options[:latency]) end @@ -165,10 +167,10 @@ module Middleman # @return [void] def setup_webrick(is_logging) http_opts = { - :BindAddress => host, - :Port => port, - :AccessLog => [], - :DoNotReverseLookup => true + BindAddress: host, + Port: port, + AccessLog: [], + DoNotReverseLookup: true } if is_logging diff --git a/middleman-core/lib/middleman-core/profiling.rb b/middleman-core/lib/middleman-core/profiling.rb index 3c8927dc..d5b43ef4 100644 --- a/middleman-core/lib/middleman-core/profiling.rb +++ b/middleman-core/lib/middleman-core/profiling.rb @@ -1,6 +1,7 @@ module Middleman module Profiling # The profiler instance. There can only be one! + # rubocop:disable TrivialAccessors def self.profiler=(prof) @profiler = prof end @@ -23,7 +24,7 @@ module Middleman def start end - def report(report_name) + def report(_) end end @@ -47,7 +48,7 @@ module Middleman outfile = (outfile + '.html') unless outfile.end_with? '.html' FileUtils.mkdir_p(File.dirname(outfile)) File.open(outfile, 'w') do |f| - printer.print(f, :min_percent => 1) + printer.print(f, min_percent: 1) end end end diff --git a/middleman-core/lib/middleman-core/renderers/asciidoc.rb b/middleman-core/lib/middleman-core/renderers/asciidoc.rb index 5be25520..9ad14a53 100644 --- a/middleman-core/lib/middleman-core/renderers/asciidoc.rb +++ b/middleman-core/lib/middleman-core/renderers/asciidoc.rb @@ -6,13 +6,13 @@ module Middleman class << self def registered(app) app.config.define_setting :asciidoc, { - :safe => :safe, - :backend => :html5, - :attributes => %W(showtitle env=middleman env-middleman middleman-version=#{::Middleman::VERSION}) + safe: :safe, + backend: :html5, + attributes: %W(showtitle env=middleman env-middleman middleman-version=#{::Middleman::VERSION}) }, 'AsciiDoc engine options (Hash)' app.config.define_setting :asciidoc_attributes, [], 'AsciiDoc custom attributes (Array)' app.before_configuration do - template_extensions :adoc => :html + template_extensions adoc: :html end app.after_configuration do @@ -23,7 +23,7 @@ module Middleman sitemap.provides_metadata(/\.adoc$/) do |path| # read the AsciiDoc header only to set page options and data # header values can be accessed via app.data.page. in the layout - doc = Asciidoctor.load_file path, :safe => :safe, :parse_header_only => true + doc = Asciidoctor.load_file path, safe: :safe, parse_header_only: true opts = {} if doc.attr? 'page-layout' @@ -35,7 +35,7 @@ module Middleman end end opts[:layout_engine] = (doc.attr 'page-layout-engine') if doc.attr? 'page-layout-engine' - # TODO override attributes to set docfile, docdir, docname, etc + # TODO: override attributes to set docfile, docdir, docname, etc # alternative is to set :renderer_options, which get merged into options by the rendering extension # opts[:attributes] = config[:asciidoc][:attributes].dup # opts[:attributes].concat %W(docfile=#{path} docdir=#{File.dirname path} docname=#{(File.basename path).sub(/\.adoc$/, '')}) @@ -43,10 +43,10 @@ module Middleman page = {} page[:title] = doc.doctitle page[:date] = (doc.attr 'date') unless (doc.attr 'date').nil? - # TODO grab all the author information + # TODO: grab all the author information page[:author] = (doc.attr 'author') unless (doc.attr 'author').nil? - { :options => opts, :page => ::Middleman::Util.recursively_enhance(page) } + { options: opts, page: ::Middleman::Util.recursively_enhance(page) } end end end diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb index 047d25a4..aef0f0fd 100644 --- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb +++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb @@ -14,7 +14,7 @@ module Middleman ::Tilt.prefer(DebuggingCoffeeScriptTemplate) app.before_configuration do - template_extensions :coffee => :js + template_extensions coffee: :js DebuggingCoffeeScriptTemplate.middleman_app = self end end diff --git a/middleman-core/lib/middleman-core/renderers/erb.rb b/middleman-core/lib/middleman-core/renderers/erb.rb index abec76f9..9a20787e 100644 --- a/middleman-core/lib/middleman-core/renderers/erb.rb +++ b/middleman-core/lib/middleman-core/renderers/erb.rb @@ -7,7 +7,7 @@ module Middleman # once registered def registered(app) app.before_configuration do - template_extensions :erb => :html + template_extensions erb: :html end # After config diff --git a/middleman-core/lib/middleman-core/renderers/haml.rb b/middleman-core/lib/middleman-core/renderers/haml.rb index b160610d..1e63b474 100644 --- a/middleman-core/lib/middleman-core/renderers/haml.rb +++ b/middleman-core/lib/middleman-core/renderers/haml.rb @@ -20,7 +20,7 @@ module Middleman # Once registered def registered(app) app.before_configuration do - template_extensions :haml => :html + template_extensions haml: :html end # Add haml helpers to context diff --git a/middleman-core/lib/middleman-core/renderers/kramdown.rb b/middleman-core/lib/middleman-core/renderers/kramdown.rb index 898b4e25..309e6034 100644 --- a/middleman-core/lib/middleman-core/renderers/kramdown.rb +++ b/middleman-core/lib/middleman-core/renderers/kramdown.rb @@ -4,7 +4,7 @@ module Middleman module Renderers # Our own Kramdown Tilt template that simply uses our custom renderer. class KramdownTemplate < ::Tilt::KramdownTemplate - def evaluate(scope, locals, &block) + def evaluate(*) @output ||= begin output, warnings = MiddlemanKramdownHTML.convert(@engine.root, @engine.options) @engine.warnings.concat(warnings) @@ -17,7 +17,7 @@ module Middleman class MiddlemanKramdownHTML < ::Kramdown::Converter::Html cattr_accessor :middleman_app - def convert_img(el, indent) + def convert_img(el, _) attrs = el.attr.dup link = attrs.delete('src') diff --git a/middleman-core/lib/middleman-core/renderers/less.rb b/middleman-core/lib/middleman-core/renderers/less.rb index ba567635..fd840219 100644 --- a/middleman-core/lib/middleman-core/renderers/less.rb +++ b/middleman-core/lib/middleman-core/renderers/less.rb @@ -12,7 +12,7 @@ module Middleman app.config.define_setting :less, {}, 'LESS compiler options' app.before_configuration do - template_extensions :less => :css + template_extensions less: :css end app.after_configuration do @@ -33,7 +33,7 @@ module Middleman if ::Less.const_defined? :Engine @engine = ::Less::Engine.new(data) else - parser = ::Less::Parser.new(options.merge :filename => eval_file, :line => line, :paths => ['.', File.dirname(eval_file)]) + parser = ::Less::Parser.new(options.merge filename: eval_file, line: line, paths: ['.', File.dirname(eval_file)]) @engine = parser.parse(data) end end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index a55dfd4b..376a8709 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -10,7 +10,7 @@ module Middleman # Once registerd def registered(app) app.before_configuration do - template_extensions :liquid => :html + template_extensions liquid: :html end # After config, setup liquid partial paths @@ -18,8 +18,8 @@ module Middleman ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir) # Convert data object into a hash for liquid - sitemap.provides_metadata %r{\.liquid$} do |path| - { :locals => { :data => data.to_h } } + sitemap.provides_metadata %r{\.liquid$} do + { locals: { data: data.to_h } } end end end diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index e9118c52..46d22439 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -11,11 +11,11 @@ module Middleman app.config.define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines' app.before_configuration do - template_extensions :markdown => :html, - :mdown => :html, - :md => :html, - :mkd => :html, - :mkdn => :html + template_extensions markdown: :html, + mdown: :html, + md: :html, + mkd: :html, + mkdn: :html end # Once configuration is parsed diff --git a/middleman-core/lib/middleman-core/renderers/redcarpet.rb b/middleman-core/lib/middleman-core/renderers/redcarpet.rb index f792bc28..70094b53 100644 --- a/middleman-core/lib/middleman-core/renderers/redcarpet.rb +++ b/middleman-core/lib/middleman-core/renderers/redcarpet.rb @@ -6,7 +6,7 @@ module Middleman # because tilt has decided to convert these # in the wrong direction ALIASES = { - :escape_html => :filter_html + escape_html: :filter_html } # Overwrite built-in Tilt version. @@ -59,7 +59,7 @@ module Middleman def image(link, title, alt_text) if !@local_options[:no_images] - middleman_app.image_tag(link, :title => title, :alt => alt_text) + middleman_app.image_tag(link, title: title, alt: alt_text) else link_string = link.dup link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text @@ -69,7 +69,7 @@ module Middleman def link(link, title, content) if !@local_options[:no_links] - attributes = { :title => title } + attributes = { title: title } attributes.merge!(@local_options[:link_attributes]) if @local_options[:link_attributes] middleman_app.link_to(content, link, attributes) diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 86d83acb..9165db23 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -13,8 +13,8 @@ module Middleman app.config.define_setting :sass, {}, 'Sass engine options' app.before_configuration do - template_extensions :scss => :css, - :sass => :css + template_extensions scss: :css, + sass: :css end # Tell Tilt to use it as well (for inline sass blocks) @@ -36,9 +36,7 @@ module Middleman def initialize(*args, &block) super - if @options.key?(:context) - @context = @options[:context] - end + @context = @options[:context] if @options.key?(:context) end # Define the expected syntax for the template @@ -51,23 +49,22 @@ module Middleman # Add exception messaging # @param [Class] context - # @param [Hash] locals # @return [String] - def evaluate(context, locals, &block) + def evaluate(context, _) @context ||= context @engine = ::Sass::Engine.new(data, sass_options) begin @engine.render rescue ::Sass::SyntaxError => e - ::Sass::SyntaxError.exception_to_css(e, :full_exception => true) + ::Sass::SyntaxError.exception_to_css(e, full_exception: true) end end # Change Sass path, for url functions, to the build folder if we're building # @return [Hash] def sass_options - more_opts = { :filename => eval_file, :line => line, :syntax => syntax } + more_opts = { filename: eval_file, line: line, syntax: syntax } if @context.is_a?(::Middleman::Application) && file location_of_sass_file = @context.source_dir diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index 8130d44c..6a5160ab 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -24,20 +24,20 @@ module Middleman # Once registered def registered(app) app.before_configuration do - template_extensions :slim => :html + template_extensions slim: :html end # Setup Slim options to work with partials ::Slim::Engine.set_default_options( - :buffer => '@_out_buf', - :use_html_safe => true, - :generator => ::Temple::Generators::RailsOutputBuffer, - :disable_escape => true + buffer: '@_out_buf', + use_html_safe: true, + generator: ::Temple::Generators::RailsOutputBuffer, + disable_escape: true ) app.after_configuration do context_hack = { - :context => self + context: self } ::Slim::Embedded::SassEngine.disable_option_validator! diff --git a/middleman-core/lib/middleman-core/renderers/stylus.rb b/middleman-core/lib/middleman-core/renderers/stylus.rb index 5a929e44..7a4f2eb3 100644 --- a/middleman-core/lib/middleman-core/renderers/stylus.rb +++ b/middleman-core/lib/middleman-core/renderers/stylus.rb @@ -13,7 +13,7 @@ module Middleman app.set :styl, {} app.before_configuration do - template_extensions :styl => :css + template_extensions styl: :css end end diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index 1a758011..10754990 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -25,17 +25,17 @@ 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.start_with?('.') }, + root_dotfiles: proc { |file| file.start_with?('.') }, # Files starting with an dot, but not .htaccess - :source_dotfiles => proc { |file| + source_dotfiles: proc { |file| file =~ %r{/\.} && file !~ %r{/\.(htaccess|htpasswd|nojekyll)} }, # Files starting with an underscore, but not a double-underscore - :partials => proc { |file| file =~ %r{/_[^_]} }, + partials: proc { |file| file =~ %r{/_[^_]} }, - :layout => proc { |file, sitemap_app| + layout: proc { |file, sitemap_app| file.start_with?(File.join(sitemap_app.config[:source], 'layout.')) || file.start_with?(File.join(sitemap_app.config[:source], 'layouts/')) } }, 'Callbacks that can exclude paths from the sitemap' diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index abb917e4..2c51063e 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -35,13 +35,13 @@ module Middleman # Update or add an on-disk file path # @param [String] file # @return [Boolean] - def touch_file(file, rebuild=true) + def touch_file(file) return false if File.directory?(file) path = @sitemap.file_to_path(file) return false unless path - ignored = @app.config[:ignored_sitemap_matchers].any? do |name, callback| + ignored = @app.config[:ignored_sitemap_matchers].any? do |_, callback| if callback.arity == 1 callback.call(file) else @@ -67,7 +67,7 @@ module Middleman # Remove a file from the store # @param [String] file # @return [void] - def remove_file(file, rebuild=true) + def remove_file(file) if @file_paths_on_disk.delete?(file) @sitemap.rebuild_resource_list!(:removed_file) unless waiting_for_ready || @app.build? diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index dcd89edc..2ecec61a 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -17,9 +17,10 @@ module Middleman module ResourceInstanceMethods # Whether this page is a proxy + # rubocop:disable TrivialAccessors # @return [Boolean] def proxy? - !!@proxied_to + @proxied_to end # Set this page to proxy to a target path @@ -52,6 +53,7 @@ module Middleman proxy_resource end + # rubocop:disable AccessorMethodName def get_source_file if proxy? proxied_to_resource.source_file @@ -97,14 +99,14 @@ module Middleman # :locals, :ignore to hide the proxy target, :layout, and :directory_indexes. # @return [void] def proxy(path, target, opts={}, &block) - metadata = { :options => {}, :locals => {}, :blocks => [] } + metadata = { options: {}, locals: {}, blocks: [] } metadata[:blocks] << block if block_given? metadata[:locals] = opts.delete(:locals) || {} @app.ignore(target) if opts.delete(:ignore) metadata[:options] = opts - @proxy_configs << ProxyConfiguration.new(:path => path, :target => target, :metadata => metadata) + @proxy_configs << ProxyConfiguration.new(path: path, target: target, metadata: metadata) @app.sitemap.rebuild_resource_list!(:added_proxy) end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 86431809..fdf1315f 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -35,9 +35,7 @@ module Middleman # @param [String] path # @param [Hash] opts The :to value gives a target path def create_redirect(path, opts={}, &block) - if block_given? - opts[:template] = block - end + opts[:template] = block if block_given? @redirects[path] = opts @@ -72,10 +70,10 @@ module Middleman true end - def render(*args, &block) + def render(*) url = ::Middleman::Util.url_for(store.app, @request_path, - :relative => false, - :find_resource => true + relative: false, + find_resource: true ) if output diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 8562c297..08d39455 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -37,7 +37,7 @@ module Middleman # differs from the output path def create_endpoint(path, opts={}, &block) endpoint = { - :request_path => path + request_path: path } if block_given? @@ -79,7 +79,7 @@ module Middleman true end - def render(*args, &block) + def render(*) return output.call if output end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index de9f7e38..95d7658b 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -69,7 +69,7 @@ module Middleman return true end full_path = File.join(app.source_dir, eponymous_directory_path) - !!(File.exist?(full_path) && File.directory?(full_path)) + File.exist?(full_path) && File.directory?(full_path) end # The path for this resource if it were a directory, and not a file diff --git a/middleman-core/lib/middleman-core/sitemap/queryable.rb b/middleman-core/lib/middleman-core/sitemap/queryable.rb index d835e9cf..af225e5d 100644 --- a/middleman-core/lib/middleman-core/sitemap/queryable.rb +++ b/middleman-core/lib/middleman-core/sitemap/queryable.rb @@ -73,33 +73,33 @@ module Middleman end def where(constraints_hash) - selector_hash = constraints_hash.reject { |key, value| !key.is_a? Selector } - symbol_hash = constraints_hash.reject { |key, value| key.is_a? Selector } + selector_hash = constraints_hash.reject { |key, _| !key.is_a? Selector } + symbol_hash = constraints_hash.reject { |key, _| key.is_a? Selector } symbol_hash.each do |attribute, value| - selector = Selector.new(:attribute => attribute, :operator => 'equal') + selector = Selector.new(attribute: attribute, operator: 'equal') selector_hash.update(selector => value) end - Query.new @model, opts(:where => @where.merge(selector_hash)) + Query.new @model, opts(where: @where.merge(selector_hash)) end def opts(new_opts) - { :where => {}.merge(@where), - :order_by => @order_by, - :offset => @offset, - :limit => @limit + { where: {}.merge(@where), + order_by: @order_by, + offset: @offset, + limit: @limit }.merge(new_opts) end def order_by(field) - Query.new @model, opts(:order_by => field.is_a?(Symbol) ? { field => :asc } : field) + Query.new @model, opts(order_by: field.is_a?(Symbol) ? { field => :asc } : field) end def offset(number) - Query.new @model, opts(:offset => number) + Query.new @model, opts(offset: number) end def limit(number) - Query.new @model, opts(:limit => number) + Query.new @model, opts(limit: number) end def first @@ -111,13 +111,9 @@ module Middleman end def all - result = @model.select(:where => @where, :order_by => @order_by) - if @offset.present? - result = result.last([result.size - @offset, 0].max) - end - if @limit.present? - result = result.first(@limit) - end + result = @model.select(where: @where, order_by: @order_by) + result = result.last([result.size - @offset, 0].max) if @offset.present? + result = result.first(@limit) if @limit.present? result end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 610641d6..e86449d7 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -11,7 +11,7 @@ module Middleman # @return [Middleman::Application] attr_reader :app - delegate :logger, :instrument, :to => :app + delegate :logger, :instrument, to: :app # @return [Middleman::Sitemap::Store] attr_reader :store @@ -44,7 +44,7 @@ module Middleman @source_file = source_file @destination_path = @path - @local_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] } + @local_metadata = { options: {}, locals: {}, page: {}, blocks: [] } end # Whether this resource has a template file @@ -60,15 +60,11 @@ module Middleman result = store.metadata_for_path(path).dup file_meta = store.metadata_for_file(source_file).dup - if file_meta.key?(:blocks) - result[:blocks] += file_meta.delete(:blocks) - end + result[:blocks] += file_meta.delete(:blocks) if file_meta.key?(:blocks) result.deep_merge!(file_meta) local_meta = @local_metadata.dup - if local_meta.key?(:blocks) - result[:blocks] += local_meta.delete(:blocks) - end + result[:blocks] += local_meta.delete(:blocks) if local_meta.key?(:blocks) result.deep_merge!(local_meta) result[:blocks] = result[:blocks].flatten.compact @@ -79,9 +75,7 @@ module Middleman # @param [Hash] metadata A metadata block like provides_metadata_for_path takes def add_metadata(metadata={}, &block) metadata = metadata.dup - if metadata.key?(:blocks) - @local_metadata[:blocks] += metadata.delete(:blocks) - end + @local_metadata[:blocks] += metadata.delete(:blocks) if metadata.key?(:blocks) @local_metadata.deep_merge!(metadata) @local_metadata[:blocks] += [block] if block_given? end @@ -103,13 +97,11 @@ module Middleman # Render this resource # @return [String] def render(opts={}, locs={}, &block) - unless template? - return app.template_data_for_file(source_file) - end + return app.template_data_for_file(source_file) unless template? relative_source = Pathname(source_file).relative_path_from(Pathname(app.root)) - instrument 'render.resource', :path => relative_source, :destination_path => destination_path do + instrument 'render.resource', path: relative_source, destination_path: destination_path do md = metadata.dup opts = md[:options].deep_merge(opts) @@ -124,9 +116,7 @@ module Middleman locs = md[:locals].deep_merge(locs) # Forward remaining data to helpers - if md.key?(:page) - app.data.store('page', md[:page]) - end + app.data.store('page', md[:page]) if md.key?(:page) blocks = Array(md[:blocks]).dup blocks << block if block_given? diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index c4fe78ae..6fbb8b68 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -49,12 +49,13 @@ module Middleman # @param [Symbol] name Name of the manipulator for debugging # @param [Class, Module] inst Abstract namespace which can update the resource list # @return [void] - def register_resource_list_manipulator(name, inst, unused=true) + def register_resource_list_manipulator(name, inst, *) @resource_list_manipulators << [name, inst] rebuild_resource_list!(:registered_new) end # Rebuild the list of resources from scratch, using registed manipulators + # rubocop:disable UnusedMethodArgument # @return [void] def rebuild_resource_list!(reason=nil) @lock.synchronize do @@ -117,7 +118,7 @@ module Middleman # @param [String] source_file # @return [Hash] def metadata_for_file(source_file) - blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] } + blank_metadata = { options: {}, locals: {}, page: {}, blocks: [] } provides_metadata.reduce(blank_metadata) do |result, (callback, matcher)| next result if matcher && !source_file.match(matcher) @@ -151,7 +152,7 @@ module Middleman def metadata_for_path(request_path) return @_cached_metadata[request_path] if @_cached_metadata[request_path] - blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] } + blank_metadata = { options: {}, locals: {}, page: {}, blocks: [] } @_cached_metadata[request_path] = provides_metadata_for_path.reduce(blank_metadata) do |result, (callback, matcher)| case matcher @@ -252,9 +253,7 @@ module Middleman if @app.respond_to? :langs path_bits = path.split('.') lang = path_bits.last - if @app.langs.include?(lang.to_sym) - return path_bits[0..-2].join('.') - end + return path_bits[0..-2].join('.') if @app.langs.include?(lang.to_sym) end path diff --git a/middleman-core/lib/middleman-core/templates.rb b/middleman-core/lib/middleman-core/templates.rb index 312e64b3..2f321608 100644 --- a/middleman-core/lib/middleman-core/templates.rb +++ b/middleman-core/lib/middleman-core/templates.rb @@ -39,13 +39,13 @@ module Middleman::Templates end # Required path for the new project to be generated - argument :location, :type => :string + argument :location, type: :string # Name of the template being used to generate the project. - class_option :template, :default => 'default' + class_option :template, default: 'default' # Output a config.ru file for Rack if --rack is passed - class_option :rack, :type => :boolean, :default => false + class_option :rack, type: :boolean, default: false # Write a Rack config.ru file for project # @return [void] @@ -54,8 +54,8 @@ module Middleman::Templates template 'shared/config.ru', File.join(location, 'config.ru') end - class_option :'skip-bundle', :type => :boolean, :default => false - class_option :'skip-gemfile', :type => :boolean, :default => false + class_option :'skip-bundle', type: :boolean, default: false + class_option :'skip-gemfile', type: :boolean, default: false # Write a Bundler Gemfile file for project # @return [void] @@ -70,7 +70,7 @@ module Middleman::Templates end # Output a .gitignore file - class_option :'skip-git', :type => :boolean, :default => false + class_option :'skip-git', type: :boolean, default: false # Write a .gitignore file for project # @return [void] @@ -94,9 +94,8 @@ require 'middleman-core/templates/mobile' require 'middleman-more/templates/smacss' # Local templates -if ENV['HOME'] # Sometimes HOME doesn't exist, in which case there's no point to local templates - require 'middleman-core/templates/local' -end +# Sometimes HOME doesn't exist, in which case there's no point to local templates +require 'middleman-core/templates/local' if ENV['HOME'] # Barebones template require 'middleman-core/templates/empty' diff --git a/middleman-core/lib/middleman-core/templates/default.rb b/middleman-core/lib/middleman-core/templates/default.rb index 088f63f1..6eea9b44 100644 --- a/middleman-core/lib/middleman-core/templates/default.rb +++ b/middleman-core/lib/middleman-core/templates/default.rb @@ -1,14 +1,14 @@ # Default Middleman template class Middleman::Templates::Default < Middleman::Templates::Base class_option 'css_dir', - :default => 'stylesheets', - :desc => 'The path to the css files' + default: 'stylesheets', + desc: 'The path to the css files' class_option 'js_dir', - :default => 'javascripts', - :desc => 'The path to the javascript files' + default: 'javascripts', + desc: 'The path to the javascript files' class_option 'images_dir', - :default => 'images', - :desc => 'The path to the image files' + default: 'images', + desc: 'The path to the image files' # Template files are relative to this file # @return [String] diff --git a/middleman-core/lib/middleman-core/templates/extension/Rakefile b/middleman-core/lib/middleman-core/templates/extension/Rakefile index 1b6d06aa..7910cf22 100644 --- a/middleman-core/lib/middleman-core/templates/extension/Rakefile +++ b/middleman-core/lib/middleman-core/templates/extension/Rakefile @@ -9,6 +9,6 @@ end require 'rake/clean' -task :test => ['cucumber'] +task test: ['cucumber'] -task :default => :test +task default: :test diff --git a/middleman-core/lib/middleman-core/templates/html5.rb b/middleman-core/lib/middleman-core/templates/html5.rb index 9ac75b3e..56422032 100644 --- a/middleman-core/lib/middleman-core/templates/html5.rb +++ b/middleman-core/lib/middleman-core/templates/html5.rb @@ -1,14 +1,14 @@ # HTML5 Boilerplate template class Middleman::Templates::Html5 < Middleman::Templates::Base class_option 'css_dir', - :default => 'css', - :desc => 'The path to the css files' + default: 'css', + desc: 'The path to the css files' class_option 'js_dir', - :default => 'js', - :desc => 'The path to the javascript files' + default: 'js', + desc: 'The path to the javascript files' class_option 'images_dir', - :default => 'img', - :desc => 'The path to the image files' + default: 'img', + desc: 'The path to the image files' # Templates are relative to this file # @return [String] diff --git a/middleman-core/lib/middleman-core/templates/mobile.rb b/middleman-core/lib/middleman-core/templates/mobile.rb index 43ebf6ca..8137c0dd 100644 --- a/middleman-core/lib/middleman-core/templates/mobile.rb +++ b/middleman-core/lib/middleman-core/templates/mobile.rb @@ -1,9 +1,9 @@ # Mobile HTML5 Boilerplate class Middleman::Templates::Mobile < Middleman::Templates::Base # Slightly different paths - class_option :css_dir, :default => 'css' - class_option :js_dir, :default => 'js' - class_option :images_dir, :default => 'img' + class_option :css_dir, default: 'css' + class_option :js_dir, default: 'js' + class_option :images_dir, default: 'img' # Template files are relative to this file # @return [String] diff --git a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb index ff0a5ffe..4b60bb65 100644 --- a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb @@ -6,6 +6,7 @@ require 'padrino-helpers' class Padrino::Helpers::OutputHelpers::ErbHandler # Force Erb capture not to use safebuffer + # rubocop:disable UnderscorePrefixedVariableName def capture_from_template(*args, &block) self.output_buffer, _buf_was = '', output_buffer raw = block.call(*args) @@ -38,6 +39,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension helpers do # Make all block content html_safe + # rubocop:disable Semicolon def content_tag(name, content=nil, options=nil, &block) if block_given? options = content if content.is_a?(Hash) diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index 8c733eb2..f581f64c 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -55,10 +55,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - delegate :logger, :to => :app + delegate :logger, to: :app def langs - @_langs ||= get_known_languages + @_langs ||= known_languages end # Update the main sitemap resource list @@ -115,7 +115,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def metadata_for_path(url) - if d = get_localization_data(url) + if d = localization_data(url) lang, page_id = d else # Default to the @mount_at_root lang @@ -129,18 +129,18 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end locals = { - :lang => lang, - :page_id => page_id + lang: lang, + page_id: page_id } { - :blocks => [instance_vars], - :locals => locals, - :options => { :lang => lang } + blocks: [instance_vars], + locals: locals, + options: { lang: lang } } end - def get_known_languages + def known_languages if options[:langs] Array(options[:langs]).map(&:to_sym) else @@ -154,7 +154,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - def get_localization_data(path) + def localization_data(path) @_localization_data ||= {} @_localization_data[path] end @@ -177,7 +177,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def build_resource(path, source_path, page_id, lang) old_locale = ::I18n.locale ::I18n.locale = lang - localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => []) + localized_page_id = ::I18n.t("paths.#{page_id}", default: page_id, fallback: []) prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root].nil? && langs[0] == lang) '/' diff --git a/middleman-core/lib/middleman-more/extensions/asset_hash.rb b/middleman-core/lib/middleman-more/extensions/asset_hash.rb index 5fca57ce..b087cff2 100644 --- a/middleman-core/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-more/extensions/asset_hash.rb @@ -16,7 +16,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension # Allow specifying regexes to ignore, plus always ignore apple touch icons @ignore = Array(options.ignore) + [/^apple-touch-icon/] - app.use Middleware, :exts => options.exts, :middleman_app => app, :ignore => @ignore + app.use Middleware, exts: options.exts, middleman_app: app, ignore: @ignore end # Update the main sitemap resource list diff --git a/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb b/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb index 4885ebeb..594e374a 100644 --- a/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb +++ b/middleman-core/lib/middleman-more/extensions/automatic_image_sizes.rb @@ -24,7 +24,7 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension if File.exist?(full_path) begin - width, height = ::FastImage.size(full_path, :raise_on_failure => true) + width, height = ::FastImage.size(full_path, raise_on_failure: true) params[:width] = width params[:height] = height rescue FastImage::UnknownImageType diff --git a/middleman-core/lib/middleman-more/extensions/minify_css.rb b/middleman-core/lib/middleman-more/extensions/minify_css.rb index e281d9b3..91cbf29a 100644 --- a/middleman-core/lib/middleman-more/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-more/extensions/minify_css.rb @@ -14,15 +14,15 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension chosen_compressor = app.config[:css_compressor] || options[:compressor] || SassCompressor # Setup Rack middleware to minify CSS - app.use Rack, :compressor => chosen_compressor, - :ignore => Array(options[:ignore]) + [/\.min\./], - :inline => options[:inline] + app.use Rack, compressor: chosen_compressor, + ignore: Array(options[:ignore]) + [/\.min\./], + inline: options[:inline] end class SassCompressor def self.compress(style, options={}) root_node = ::Sass::SCSS::CssParser.new(style, 'middleman-css-input', 1).parse - root_node.options = options.merge(:style => :compressed) + root_node.options = options.merge(style: :compressed) root_node.render.strip end end diff --git a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb index f0528391..d51d864f 100644 --- a/middleman-core/lib/middleman-more/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-more/extensions/minify_javascript.rb @@ -17,9 +17,9 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension end # Setup Rack middleware to minify CSS - app.use Rack, :compressor => chosen_compressor, - :ignore => Array(options[:ignore]) + [/\.min\./], - :inline => options[:inline] + app.use Rack, compressor: chosen_compressor, + ignore: Array(options[:ignore]) + [/\.min\./], + inline: options[:inline] end # Rack middleware to look for JS and compress it diff --git a/middleman-core/lib/middleman-more/templates/smacss.rb b/middleman-core/lib/middleman-more/templates/smacss.rb index 88e14d53..ecb314d0 100644 --- a/middleman-core/lib/middleman-more/templates/smacss.rb +++ b/middleman-core/lib/middleman-more/templates/smacss.rb @@ -1,14 +1,14 @@ # SMACSS class Middleman::Templates::Smacss < Middleman::Templates::Base class_option 'css_dir', - :default => 'stylesheets', - :desc => 'The path to the css files' + default: 'stylesheets', + desc: 'The path to the css files' class_option 'js_dir', - :default => 'javascripts', - :desc => 'The path to the javascript files' + default: 'javascripts', + desc: 'The path to the javascript files' class_option 'images_dir', - :default => 'images', - :desc => 'The path to the image files' + default: 'images', + desc: 'The path to the image files' # Template files are relative to this file # @return [String] From 147b0a6626986a4d14fcd785a1f2b82520bb8059 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 29 Apr 2014 10:48:40 -0700 Subject: [PATCH 010/662] rubocopening master --- .rubocop.yml | 56 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 7789d6c2..7078560c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,19 +1,19 @@ AllCops: - Includes: - - Rakefile - - Gemfile - - config.ru - - gem_rake_helper.rb - Excludes: - - script/** - - vendor/** - - bin/** - - middleman-core/lib/vendored-middleman-deps/** - - middleman-core/bin/** - - middleman-core/fixtures/** - - middleman-core/features/** - - middleman-core/spec/** - - middleman-templates/lib/middleman-templates/** + Include: + - '**/Rakefile' + - '**/Gemfile' + - '**/config.ru' + - '**/gem_rake_helper.rb' + Exclude: + - 'script/**/*' + - 'vendor/**/*' + - '**/tmp/**/*' + - '**/bin/**/*' + - 'middleman-core/lib/middleman-core/step_definitions/**/*' + - 'middleman-templates/lib/middleman-templates/**/*' + - 'middleman-core/fixtures/**/*' + - 'middleman-core/features/**/*' + - 'middleman-core/spec/**/*' LineLength: Enabled: false MethodLength: @@ -25,4 +25,28 @@ Documentation: Encoding: Enabled: false HashSyntax: - EnforcedStyle: ruby19 \ No newline at end of file + EnforcedStyle: ruby19 +SpaceAroundEqualsInParameterDefault: + EnforcedStyle: no_space +Blocks: + Enabled: false +PerlBackrefs: + Enabled: false +ClassAndModuleChildren: + Enabled: false +AssignmentInCondition: + Enabled: false +CyclomaticComplexity: + Enabled: false +HandleExceptions: + Enabled: false +EndAlignment: + AlignWith: variable +SignalException: + Enabled: false +RegexpLiteral: + Enabled: false +FormatString: + Enabled: false +CaseIndentation: + IndentWhenRelativeTo: end From 6760d855bc53261d9016a6567552c40f0a4a7abd Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 29 Apr 2014 10:50:21 -0700 Subject: [PATCH 011/662] hashrocket killa --- .rubocop.yml | 1 + Rakefile | 12 +-- gem_rake_helper.rb | 8 +- middleman-cli/lib/middleman-cli.rb | 16 ++-- middleman-cli/lib/middleman-cli/build.rb | 52 +++++------ middleman-cli/lib/middleman-cli/console.rb | 20 ++--- middleman-cli/lib/middleman-cli/extension.rb | 12 ++- middleman-cli/lib/middleman-cli/init.rb | 47 +++++----- middleman-cli/lib/middleman-cli/server.rb | 87 +++++++++---------- .../middleman-cli/templates/extension/Gemfile | 2 +- .../templates/extension/Rakefile | 4 +- .../templates/extension/lib/lib.rb | 1 - middleman-core/lib/middleman-core.rb | 2 - .../lib/middleman-core/application.rb | 12 +-- .../lib/middleman-core/config_context.rb | 6 +- .../lib/middleman-core/configuration.rb | 10 +-- .../middleman-core/core_extensions/compass.rb | 1 - .../middleman-core/core_extensions/data.rb | 36 ++++---- .../core_extensions/default_helpers.rb | 9 +- .../core_extensions/extensions.rb | 11 ++- .../core_extensions/external_helpers.rb | 4 +- .../core_extensions/file_watcher.rb | 16 ++-- .../core_extensions/front_matter.rb | 10 +-- .../middleman-core/core_extensions/i18n.rb | 23 +++-- .../core_extensions/rendering.rb | 3 - .../middleman-core/core_extensions/request.rb | 15 ++-- .../middleman-core/core_extensions/routing.rb | 5 +- .../lib/middleman-core/extension.rb | 13 ++- .../lib/middleman-core/extensions.rb | 14 ++- .../middleman-core/extensions/asset_hash.rb | 10 +-- .../extensions/automatic_alt_tags.rb | 5 +- .../extensions/automatic_image_sizes.rb | 9 +- .../middleman-core/extensions/cache_buster.rb | 1 - .../lib/middleman-core/extensions/lorem.rb | 16 ++-- .../middleman-core/extensions/minify_css.rb | 16 ++-- .../extensions/minify_javascript.rb | 13 ++- .../extensions/relative_assets.rb | 1 - .../lib/middleman-core/file_renderer.rb | 10 +-- .../lib/middleman-core/load_paths.rb | 9 +- middleman-core/lib/middleman-core/logger.rb | 4 +- .../lib/middleman-core/meta_pages.rb | 16 ++-- .../meta_pages/config_setting.rb | 8 +- .../meta_pages/sitemap_resource.rb | 4 +- .../middleman-core/meta_pages/sitemap_tree.rb | 2 +- .../lib/middleman-core/preview_server.rb | 20 ++--- .../lib/middleman-core/profiling.rb | 11 +-- .../middleman-core/renderers/coffee_script.rb | 4 +- .../lib/middleman-core/renderers/erb.rb | 5 +- .../lib/middleman-core/renderers/haml.rb | 5 +- .../lib/middleman-core/renderers/kramdown.rb | 3 +- .../lib/middleman-core/renderers/less.rb | 10 +-- .../lib/middleman-core/renderers/liquid.rb | 8 +- .../lib/middleman-core/renderers/markdown.rb | 8 +- .../lib/middleman-core/renderers/redcarpet.rb | 30 +++---- .../lib/middleman-core/renderers/sass.rb | 13 +-- .../lib/middleman-core/renderers/slim.rb | 15 ++-- .../lib/middleman-core/renderers/stylus.rb | 6 +- middleman-core/lib/middleman-core/sitemap.rb | 13 +-- .../sitemap/extensions/ignores.rb | 12 +-- .../sitemap/extensions/on_disk.rb | 4 - .../sitemap/extensions/proxies.rb | 11 +-- .../sitemap/extensions/redirects.rb | 12 +-- .../sitemap/extensions/request_endpoints.rb | 16 ++-- .../sitemap/extensions/traversal.rb | 11 +-- .../lib/middleman-core/sitemap/resource.rb | 18 ++-- .../lib/middleman-core/sitemap/store.rb | 17 ++-- .../lib/middleman-core/template_context.rb | 10 +-- .../lib/middleman-core/template_renderer.rb | 18 ++-- middleman-core/lib/middleman-core/util.rb | 34 ++++---- .../lib/middleman-templates.rb | 6 +- 70 files changed, 385 insertions(+), 511 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 7078560c..955ec1b6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,6 +10,7 @@ AllCops: - '**/tmp/**/*' - '**/bin/**/*' - 'middleman-core/lib/middleman-core/step_definitions/**/*' + - 'middleman-core/lib/vendored-middleman-deps/**/*' - 'middleman-templates/lib/middleman-templates/**/*' - 'middleman-core/fixtures/**/*' - 'middleman-core/features/**/*' diff --git a/Rakefile b/Rakefile index 4c71d31e..cf67d269 100644 --- a/Rakefile +++ b/Rakefile @@ -11,11 +11,11 @@ middleman_gems = %w(middleman-core middleman-templates middleman-cli middleman) GEM_PATHS = middleman_gems.freeze def sh_rake(command) - sh "#{Gem.ruby} -S rake #{command}", :verbose => true + sh "#{Gem.ruby} -S rake #{command}", verbose: true end def say(text, color=:magenta) - n = { :bold => 1, :red => 31, :green => 32, :yellow => 33, :blue => 34, :magenta => 35 }.fetch(color, 0) + n = { bold: 1, red: 31, green: 32, yellow: 33, blue: 34, magenta: 35 }.fetch(color, 0) puts "\e[%dm%s\e[0m" % [n, text] end @@ -29,7 +29,7 @@ end desc 'Clean pkg and other stuff' task :clean do GEM_PATHS.each do |g| - %w[tmp pkg coverage].each { |dir| sh 'rm -rf %s' % File.join(g, dir) } + %w(tmp pkg coverage).each { |dir| sh 'rm -rf %s' % File.join(g, dir) } end end @@ -54,7 +54,7 @@ task :bump, [:version] do |t, args| end desc 'Executes a fresh install removing all middleman version and then reinstall all gems' -task :fresh => [:uninstall, :install, :clean] +task fresh: [:uninstall, :install, :clean] desc 'Pushes repository to GitHub' task :push do @@ -65,7 +65,7 @@ task :push do end desc 'Release all middleman gems' -task :publish => :push do +task publish: :push do say 'Pushing to rubygems...' GEM_PATHS.each do |dir| Dir.chdir(dir) { sh_rake('release') } @@ -115,4 +115,4 @@ rescue LoadError end desc 'Run tests for all middleman gems' -task :default => :test +task default: :test diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index d6e78861..284cf5dc 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -20,14 +20,14 @@ Cucumber::Rake::Task.new do |t| exempt_tags << '--tags ~@nojava' if RUBY_PLATFORM == 'java' exempt_tags << '--tags ~@encoding' unless Object.const_defined?(:Encoding) exempt_tags << '--tags ~@travishatesme' if ENV['TRAVIS'] == 'true' - t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" + 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'}" + t.cucumber_opts = "--color #{exempt_tags.join(' ')} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" end require 'rspec/core/rake_task' @@ -38,8 +38,8 @@ RSpec::Core::RakeTask.new do |spec| end desc 'Run tests, both RSpec and Cucumber' -task :test => [:spec, :cucumber] +task test: [:spec, :cucumber] YARD::Rake::YardocTask.new -task :default => :test +task default: :test diff --git a/middleman-cli/lib/middleman-cli.rb b/middleman-cli/lib/middleman-cli.rb index 3ddbc72b..8907de3f 100644 --- a/middleman-cli/lib/middleman-cli.rb +++ b/middleman-cli/lib/middleman-cli.rb @@ -8,9 +8,7 @@ require 'thor/group' # CLI Module module Middleman - module Cli - # The base task from which everything else extends class Base < Thor class << self @@ -36,19 +34,19 @@ module Middleman # @param [Symbol, String, nil] meth # @param [Boolean] subcommand # @return [void] - def help(meth = nil, subcommand = false) + def help(meth=nil, subcommand=false) if meth && !self.respond_to?(meth) klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") - klass.start(['-h', task].compact, :shell => self.shell) + klass.start(['-h', task].compact, shell: shell) else list = [] Thor::Util.thor_classes_in(Middleman::Cli).each do |thor_class| list += thor_class.printable_tasks(false) end - list.sort!{ |a,b| a[0] <=> b[0] } + list.sort! { |a, b| a[0] <=> b[0] } shell.say 'Tasks:' - shell.print_table(list, :ident => 2, :truncate => true) + shell.print_table(list, ident: 2, truncate: true) shell.say %(\nSee 'middleman help ' for more information on specific command.) shell.say end @@ -59,7 +57,7 @@ module Middleman def method_missing(meth, *args) meth = meth.to_s - if self.class.map.has_key?(meth) + if self.class.map.key?(meth) meth = self.class.map[meth] end @@ -68,7 +66,7 @@ module Middleman if klass.nil? tasks_dir = File.join(Dir.pwd, 'tasks') - if File.exists?(tasks_dir) + if File.exist?(tasks_dir) Dir[File.join(tasks_dir, '**/*_task.rb')].each { |f| require f } klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}") end @@ -78,7 +76,7 @@ module Middleman raise Thor::Error.new "There's no '#{meth}' command for Middleman. Try 'middleman help' for a list of commands." else args.unshift(task) if task - klass.start(args, :shell => self.shell) + klass.start(args, shell: shell) end end end diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 0e5d902f..579cac72 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -4,7 +4,7 @@ require 'set' # CLI Module module Middleman::Cli # Alias "b" to "build" - Base.map({ 'b' => 'build' }) + Base.map('b' => 'build') # The CLI Build class class Build < Thor @@ -19,31 +19,31 @@ module Middleman::Cli desc 'build [options]', 'Builds the static site for deployment' method_option :clean, - :type => :boolean, - :default => true, - :desc => 'Remove orphaned files from build (--no-clean to disable)' + type: :boolean, + default: true, + desc: 'Remove orphaned files from build (--no-clean to disable)' method_option :glob, - :type => :string, - :aliases => '-g', - :default => nil, - :desc => 'Build a subset of the project' + type: :string, + aliases: '-g', + default: nil, + desc: 'Build a subset of the project' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + type: :string, + default: false, + desc: 'Print instrument messages' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for the build' + type: :boolean, + default: false, + desc: 'Generate profiling report for the build' # Core build Thor command # @return [void] def build - if !ENV['MM_ROOT'] + unless ENV['MM_ROOT'] raise Thor::Error, 'Error: Could not find a Middleman project config, perhaps you are in the wrong folder?' end @@ -61,7 +61,7 @@ module Middleman::Cli self.class.shared_instance(options['verbose'], options['instrument']) opts = {} - opts[:glob] = options['glob'] if options.has_key?('glob') + opts[:glob] = options['glob'] if options.key?('glob') opts[:clean] = options['clean'] self.class.shared_instance.run_hook :before_build, self @@ -71,15 +71,15 @@ module Middleman::Cli self.class.shared_instance.run_hook :after_build, self self.class.shared_instance.config_context.execute_after_build_callbacks(self) - if self.had_errors && !self.debugging + if had_errors && !debugging msg = 'There were errors during this build' unless options['verbose'] msg << ', re-run with `middleman build --verbose` to see the full exception.' end - self.shell.say msg, :red + shell.say msg, :red end - exit(1) if self.had_errors + exit(1) if had_errors end # Static methods @@ -129,17 +129,17 @@ module Middleman::Cli clean! if should_clean? end - protected + protected # Remove files which were not built in this cycle # @return [void] def clean! @to_clean.each do |f| - base.remove_file f, :force => true + base.remove_file f, force: true end - Dir[@build_dir.join('**', '*')].select {|d| File.directory?(d) }.each do |d| - base.remove_file d, :force => true if directory_empty? d + Dir[@build_dir.join('**', '*')].select { |d| File.directory?(d) }.each do |d| + base.remove_file d, force: true if directory_empty? d end end diff --git a/middleman-cli/lib/middleman-cli/console.rb b/middleman-cli/lib/middleman-cli/console.rb index a165b835..0326be38 100644 --- a/middleman-cli/lib/middleman-cli/console.rb +++ b/middleman-cli/lib/middleman-cli/console.rb @@ -1,7 +1,7 @@ # CLI Module module Middleman::Cli # Alias "c" to "console" - Base.map({ 'c' => 'console' }) + Base.map('c' => 'console') # The CLI Console class class Console < Thor @@ -13,23 +13,23 @@ module Middleman::Cli desc 'console [options]', 'Start an interactive console in the context of your Middleman application' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + aliases: '-e', + default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + desc: 'The environment Middleman will run under' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' def console require 'middleman-core' require 'irb' opts = { - :environment => options['environment'], - :debug => options['verbose'] + environment: options['environment'], + debug: options['verbose'] } - @app =::Middleman::Application.server.inst do + @app = ::Middleman::Application.server.inst do if opts[:environment] config[:environment] = opts[:environment].to_sym end diff --git a/middleman-cli/lib/middleman-cli/extension.rb b/middleman-cli/lib/middleman-cli/extension.rb index 5d9b9de9..ff0eda28 100644 --- a/middleman-cli/lib/middleman-cli/extension.rb +++ b/middleman-cli/lib/middleman-cli/extension.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # A thor task for creating new projects class Extension < Thor include Thor::Actions @@ -10,7 +9,7 @@ module Middleman::Cli namespace :extension # Required path for the new project to be generated - argument :name, :type => :string + argument :name, type: :string # Template files are relative to this file # @return [String] @@ -20,9 +19,9 @@ module Middleman::Cli desc 'extension [options]', 'Create Middleman extension scaffold NAME' method_option 'skip-git', - :type => :boolean, - :default => false, - :desc => 'Skip Git ignores and keeps' + type: :boolean, + default: false, + desc: 'Skip Git ignores and keeps' # The extension task # @param [String] name @@ -38,7 +37,6 @@ module Middleman::Cli end # Output a .gitignore file - class_option :git, :type => :boolean, :default => true - + class_option :git, type: :boolean, default: true end end diff --git a/middleman-cli/lib/middleman-cli/init.rb b/middleman-cli/lib/middleman-cli/init.rb index 4376db2a..c22a89c0 100644 --- a/middleman-cli/lib/middleman-cli/init.rb +++ b/middleman-cli/lib/middleman-cli/init.rb @@ -2,7 +2,6 @@ require 'middleman-templates' # CLI Module module Middleman::Cli - # A thor task for creating new projects class Init < Thor check_unknown_options! @@ -12,36 +11,36 @@ module Middleman::Cli desc 'init NAME [options]', 'Create new project NAME' available_templates = ::Middleman::Templates.registered.keys.join(', ') method_option 'template', - :aliases => '-T', - :default => 'default', - :desc => "Use a project template: #{available_templates}" + aliases: '-T', + default: 'default', + desc: "Use a project template: #{available_templates}" method_option 'css_dir', # :default => "stylesheets", - :desc => 'The path to the css files' + desc: 'The path to the css files' method_option 'js_dir', # :default => "javascripts", - :desc => 'The path to the javascript files' + desc: 'The path to the javascript files' method_option 'images_dir', # :default => "images", - :desc => 'The path to the image files' + desc: 'The path to the image files' method_option 'rack', - :type => :boolean, - :default => false, - :desc => 'Include a config.ru file' + type: :boolean, + default: false, + desc: 'Include a config.ru file' method_option 'skip-bundle', - :type => :boolean, - :aliases => '-B', - :default => false, - :desc => "Don't run bundle install" + type: :boolean, + aliases: '-B', + default: false, + desc: "Don't run bundle install" method_option 'skip-git', - :type => :boolean, - :default => false, - :desc => 'Skip Git ignores and keeps' + type: :boolean, + default: false, + desc: 'Skip Git ignores and keeps' # The init task # @param [String] name - def init(name = '.') + def init(name='.') key = options[:template].to_sym - unless ::Middleman::Templates.registered.has_key?(key) + unless ::Middleman::Templates.registered.key?(key) raise Thor::Error.new "Unknown project template '#{key}'" end @@ -55,9 +54,9 @@ module Middleman::Cli end # Map "i", "new" and "n" to "init" - Base.map({ - 'i' => 'init', - 'new' => 'init', - 'n' => 'init' - }) + Base.map( + 'i' => 'init', + 'new' => 'init', + 'n' => 'init' + ) end diff --git a/middleman-cli/lib/middleman-cli/server.rb b/middleman-cli/lib/middleman-cli/server.rb index 18da26b1..71d0e779 100644 --- a/middleman-cli/lib/middleman-cli/server.rb +++ b/middleman-cli/lib/middleman-cli/server.rb @@ -1,6 +1,5 @@ # CLI Module module Middleman::Cli - # Server thor task class Server < Thor check_unknown_options! @@ -9,68 +8,68 @@ module Middleman::Cli desc 'server [options]', 'Start the preview server' method_option :environment, - :aliases => '-e', - :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', - :desc => 'The environment Middleman will run under' + aliases: '-e', + default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + desc: 'The environment Middleman will run under' method_option :host, - :type => :string, - :aliases => '-h', - :default => '0.0.0.0', - :desc => 'Bind to HOST address' + type: :string, + aliases: '-h', + default: '0.0.0.0', + desc: 'Bind to HOST address' method_option :port, - :aliases => '-p', - :default => '4567', - :desc => 'The port Middleman will listen on' + aliases: '-p', + default: '4567', + desc: 'The port Middleman will listen on' method_option :verbose, - :type => :boolean, - :default => false, - :desc => 'Print debug messages' + type: :boolean, + default: false, + desc: 'Print debug messages' method_option :instrument, - :type => :string, - :default => false, - :desc => 'Print instrument messages' + type: :string, + default: false, + desc: 'Print instrument messages' method_option :disable_watcher, - :type => :boolean, - :default => false, - :desc => 'Disable the file change and delete watcher process' + type: :boolean, + default: false, + desc: 'Disable the file change and delete watcher process' method_option :profile, - :type => :boolean, - :default => false, - :desc => 'Generate profiling report for server startup' + type: :boolean, + default: false, + desc: 'Generate profiling report for server startup' method_option :reload_paths, - :type => :string, - :default => false, - :desc => 'Additional paths to auto-reload when files change' + type: :string, + default: false, + desc: 'Additional paths to auto-reload when files change' method_option :force_polling, - :type => :boolean, - :default => false, - :desc => 'Force file watcher into polling mode' + type: :boolean, + default: false, + desc: 'Force file watcher into polling mode' method_option :latency, - :type => :numeric, - :aliases => '-l', - :default => 0.25, - :desc => 'Set file watcher latency, in seconds' + type: :numeric, + aliases: '-l', + default: 0.25, + desc: 'Set file watcher latency, in seconds' # Start the server def server require 'middleman-core' require 'middleman-core/preview_server' - if !ENV['MM_ROOT'] + unless ENV['MM_ROOT'] puts '== Could not find a Middleman project config.rb' exit end params = { - :port => options['port'], - :host => options['host'], - :environment => options['environment'], - :debug => options['verbose'], - :instrumenting => options['instrument'], - :disable_watcher => options['disable_watcher'], - :reload_paths => options['reload_paths'], - :force_polling => options['force_polling'], - :latency => options['latency'] + port: options['port'], + host: options['host'], + environment: options['environment'], + debug: options['verbose'], + instrumenting: options['instrument'], + disable_watcher: options['disable_watcher'], + reload_paths: options['reload_paths'], + force_polling: options['force_polling'], + latency: options['latency'] } puts '== The Middleman is loading' @@ -83,5 +82,5 @@ module Middleman::Cli end # Map "s" to "server" - Base.map({ 's' => 'server' }) + Base.map('s' => 'server') end diff --git a/middleman-cli/lib/middleman-cli/templates/extension/Gemfile b/middleman-cli/lib/middleman-cli/templates/extension/Gemfile index 6959cfc1..1acd5814 100644 --- a/middleman-cli/lib/middleman-cli/templates/extension/Gemfile +++ b/middleman-cli/lib/middleman-cli/templates/extension/Gemfile @@ -16,4 +16,4 @@ group :test do gem 'fivemat' gem 'aruba' gem 'rspec' -end \ No newline at end of file +end diff --git a/middleman-cli/lib/middleman-cli/templates/extension/Rakefile b/middleman-cli/lib/middleman-cli/templates/extension/Rakefile index 0f786f84..7910cf22 100644 --- a/middleman-cli/lib/middleman-cli/templates/extension/Rakefile +++ b/middleman-cli/lib/middleman-cli/templates/extension/Rakefile @@ -9,6 +9,6 @@ end require 'rake/clean' -task :test => ['cucumber'] +task test: ['cucumber'] -task :default => :test \ No newline at end of file +task default: :test diff --git a/middleman-cli/lib/middleman-cli/templates/extension/lib/lib.rb b/middleman-cli/lib/middleman-cli/templates/extension/lib/lib.rb index 386d3d2a..8b98bf78 100644 --- a/middleman-cli/lib/middleman-cli/templates/extension/lib/lib.rb +++ b/middleman-cli/lib/middleman-cli/templates/extension/lib/lib.rb @@ -28,7 +28,6 @@ class MyExtension < ::Middleman::Extension # def a_helper # end # end - end # Register extensions which can be activated diff --git a/middleman-core/lib/middleman-core.rb b/middleman-core/lib/middleman-core.rb index be446a51..5d3dc485 100644 --- a/middleman-core/lib/middleman-core.rb +++ b/middleman-core/lib/middleman-core.rb @@ -4,10 +4,8 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) # Top-level Middleman namespace module Middleman - # Backwards compatibility namespace module Features; end - end require 'middleman-core/version' diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 91eab8c7..85b4a559 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -52,13 +52,13 @@ module Middleman def self.root ENV['MM_ROOT'] || Dir.pwd end - delegate :root, :to => :"self.class" + delegate :root, to: :"self.class" # Pathname-addressed root def self.root_path Pathname(root) end - delegate :root_path, :to => :"self.class" + delegate :root_path, to: :"self.class" # Name of the source directory # @return [String] @@ -165,7 +165,7 @@ module Middleman attr_reader :template_context_class attr_reader :generic_template_context - delegate :link_to, :image_tag, :asset_path, :to => :generic_template_context + delegate :link_to, :image_tag, :asset_path, to: :generic_template_context # Initialize the Middleman project def initialize(&block) @@ -210,7 +210,7 @@ module Middleman end def add_to_instance(name, &func) - self.define_singleton_method(name, &func) + define_singleton_method(name, &func) end def add_to_config_context(name, &func) @@ -236,7 +236,7 @@ module Middleman File.join(root, config[:source]) end - delegate :instrument, :to => ::Middleman::Util + delegate :instrument, to: ::Middleman::Util # Work around this bug: http://bugs.ruby-lang.org/issues/4521 # where Ruby will call to_s/inspect while printing exception @@ -245,7 +245,7 @@ module Middleman def to_s "#" end - alias :inspect :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s + alias_method :inspect, :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s # Hooks clones _hooks from the class to the instance. # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 944ff2fb..248184f9 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -6,7 +6,7 @@ module Middleman attr_reader :app # Whitelist methods that can reach out. - delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :root, :to => :app + delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :root, to: :app def initialize(app, template_context_class) @app = app @@ -51,7 +51,7 @@ module Middleman instance_exec(*args, &b) end end - + def after_configuration(&block) @after_configuration_callbacks << block end @@ -79,4 +79,4 @@ module Middleman @app.config[key] = block_given? ? block : default end end -end \ No newline at end of file +end diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index ea6d9037..376cb2f8 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -5,7 +5,7 @@ module Middleman module Global def self.included(app) app.send :extend, ClassMethods - app.send :delegate, :config, :to => :"self.class" + app.send :delegate, :config, to: :"self.class" end module ClassMethods @@ -67,7 +67,7 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) + def respond_to?(method, include_private=false) super || defines_setting?(method) || (method =~ /^(\w+)=$/ && defines_setting?($1)) end @@ -75,7 +75,7 @@ module Middleman # @param [Symbol] key # @return [Boolean] def defines_setting?(key) - @settings.has_key?(key) + @settings.key?(key) end # Define a new setting, with optional default and user-friendly description. @@ -87,7 +87,7 @@ module Middleman # @return [ConfigSetting] def define_setting(key, default=nil, description=nil) raise "Setting #{key} doesn't exist" if @finalized - raise "Setting #{key} already defined" if @settings.has_key?(key) + raise "Setting #{key} already defined" if @settings.key?(key) raise 'Setting key must be a Symbol' unless key.is_a? Symbol @settings[key] = ConfigSetting.new(key, default, description) @@ -102,7 +102,7 @@ module Middleman # Deep duplicate of the configuration manager def dup - ConfigurationManager.new.tap {|c| c.load_settings(self.all_settings) } + ConfigurationManager.new.tap { |c| c.load_settings(all_settings) } end # Load in a list of settings diff --git a/middleman-core/lib/middleman-core/core_extensions/compass.rb b/middleman-core/lib/middleman-core/core_extensions/compass.rb index 75b04ab3..1d3c13c0 100644 --- a/middleman-core/lib/middleman-core/core_extensions/compass.rb +++ b/middleman-core/lib/middleman-core/core_extensions/compass.rb @@ -2,7 +2,6 @@ require 'middleman-core/renderers/sass' require 'compass' class Middleman::CoreExtensions::Compass < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 21961f5c..9577c2cb 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -1,10 +1,8 @@ module Middleman module CoreExtensions - # The data extension parses YAML and JSON files in the data/ directory # and makes them available to config.rb, templates and extensions module Data - # Extension registered class << self # @private @@ -23,12 +21,12 @@ module Middleman # Setup data files before anything else so they are available when # parsing config.rb def initialize - self.files.changed DataStore.matcher do |file| - self.data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") + files.changed DataStore.matcher do |file| + data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") end - self.files.deleted DataStore.matcher do |file| - self.data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") + files.deleted DataStore.matcher do |file| + data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") end super @@ -44,10 +42,8 @@ module Middleman # The core logic behind the data extension. class DataStore - # Static methods class << self - # The regex which tells Middleman which files are for data # # @return [Regexp] @@ -136,7 +132,7 @@ module Middleman data_branch = data_branch[dir] end - data_branch.delete(basename) if data_branch.has_key?(basename) + data_branch.delete(basename) if data_branch.key?(basename) end # Get a hash from either internal static data or a callback @@ -149,10 +145,10 @@ module Middleman @@local_sources ||= {} @@callback_sources ||= {} - if self.store.has_key?(path.to_s) - response = self.store[path.to_s] - elsif self.callbacks.has_key?(path.to_s) - response = self.callbacks[path.to_s].call() + if store.key?(path.to_s) + response = store[path.to_s] + elsif callbacks.key?(path.to_s) + response = callbacks[path.to_s].call end response @@ -163,7 +159,7 @@ module Middleman # @param [String] path The namespace to search for # @return [Hash, nil] def method_missing(path) - if @local_data.has_key?(path.to_s) + if @local_data.key?(path.to_s) return @local_data[path.to_s] else result = data_for_path(path) @@ -177,8 +173,8 @@ module Middleman end # Needed so that method_missing makes sense - def respond_to?(method, include_private = false) - super || has_key?(method) + def respond_to?(method, include_private=false) + super || key?(method) end # Make DataStore act like a hash. Return requested data, or @@ -187,11 +183,11 @@ module Middleman # @param [String, Symbol] key The name of the data namespace # @return [Hash, nil] def [](key) - __send__(key) if has_key?(key) + __send__(key) if key?(key) end def has_key?(key) - @local_data.has_key?(key.to_s) || !!(data_for_path(key)) + @local_data.key?(key.to_s) || !!(data_for_path(key)) end # Convert all the data into a static hash @@ -200,11 +196,11 @@ module Middleman def to_h data = {} - self.store.each do |k, v| + store.each do |k, v| data[k] = data_for_path(k) end - self.callbacks.each do |k, v| + callbacks.each do |k, v| data[k] = data_for_path(k) end 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 7b297936..66fac767 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -7,7 +7,7 @@ require 'padrino-helpers' class Padrino::Helpers::OutputHelpers::ErbHandler # Force Erb capture not to use safebuffer def capture_from_template(*args, &block) - self.output_buffer, _buf_was = '', self.output_buffer + self.output_buffer, _buf_was = '', output_buffer raw = block.call(*args) captured = template.instance_variable_get(:@_out_buf) self.output_buffer = _buf_was @@ -16,7 +16,6 @@ class Padrino::Helpers::OutputHelpers::ErbHandler end class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super @@ -39,7 +38,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension helpers do # Make all block content html_safe - def content_tag(name, content = nil, options = nil, &block) + def content_tag(name, content=nil, options=nil, &block) # safe_content_tag(name, content, options, &block) if block_given? options = content if content.is_a?(Hash) @@ -133,7 +132,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # Generate body css classes based on the current path # # @return [String] - def page_classes(path = current_path.dup, options={}) + def page_classes(path=current_path.dup, options={}) if path.is_a? Hash options = path path = current_path.dup @@ -144,7 +143,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension classes = [] parts = path.split('.').first.split('/') - parts.each_with_index { |_, i| classes << parts.first(i+1).join('_') } + parts.each_with_index { |_, i| classes << parts.first(i + 1).join('_') } prefix = options[:numeric_prefix] || 'x' classes.map do |c| diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index cdb0ed87..0f6b0f88 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -32,7 +32,6 @@ module Middleman module CoreExtensions module Extensions - # Register extension class << self # @private @@ -49,7 +48,7 @@ module Middleman app.extend ClassMethods app.send :include, InstanceMethods - app.delegate :configure, :to => :"self.class" + app.delegate :configure, to: :"self.class" end end @@ -123,7 +122,7 @@ module Middleman # Check for and evaluate local configuration local_config = File.join(root, 'config.rb') - if File.exists? local_config + if File.exist? local_config logger.debug '== Reading: Local config' config_context.instance_eval File.read(local_config), local_config, 1 end @@ -145,7 +144,7 @@ module Middleman # polluted with paths from other test app directories that don't # exist anymore. if ENV['TEST'] - ::I18n.load_path.delete_if {|path| path =~ %r{tmp/aruba}} + ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } ::I18n.reload! end @@ -153,9 +152,9 @@ module Middleman config_context.execute_after_configuration_callbacks logger.debug 'Loaded extensions:' - self.extensions.each do |ext, klass| + extensions.each do |ext, klass| if ext.is_a?(Hash) - ext.each do |k,_| + ext.each do |k, _| logger.debug "== Extension: #{k}" end else diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index 8cc5022e..e4b41772 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -7,7 +7,7 @@ module Middleman # Setup a default helpers paths app.config.define_setting :helpers_dir, 'helpers', 'Directory to autoload helper modules from' app.config.define_setting :helpers_filename_glob, '**.rb', 'Glob pattern for matching helper ruby files' - app.config.define_setting :helpers_filename_to_module_name_proc, Proc.new { |filename| + app.config.define_setting :helpers_filename_to_module_name_proc, proc { |filename| basename = File.basename(filename, File.extname(filename)) basename.camelcase }, 'Proc implementing the conversion from helper filename to module name' @@ -15,7 +15,7 @@ module Middleman # After config app.after_configuration do helpers_path = File.join(root, config[:helpers_dir]) - next unless File.exists?(helpers_path) + next unless File.exist?(helpers_path) Dir[File.join(helpers_path, config[:helpers_filename_glob])].each do |filename| module_name = config[:helpers_filename_to_module_name_proc].call(filename) 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 c5575a9c..03b25241 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -2,7 +2,6 @@ module Middleman module CoreExtensions module FileWatcher - IGNORE_LIST = [ /^bin(\/|$)/, /^\.bundle(\/|$)/, @@ -23,7 +22,6 @@ module Middleman # Setup extension class << self - # Once registered def included(app) require 'pathname' @@ -51,7 +49,6 @@ module Middleman # Instance methods module InstanceMethods - # Access the file api # @return [Middleman::CoreExtensions::FileWatcher::API] def files @@ -61,10 +58,9 @@ module Middleman # Core File Change API class class API - attr_reader :app attr_reader :known_paths - delegate :logger, :to => :app + delegate :logger, to: :app # Initialize api and internal path cache def initialize(app) @@ -101,7 +97,7 @@ module Middleman path = Pathname(path) logger.debug "== File Change: #{path}" @known_paths << path - self.run_callbacks(path, :changed) + run_callbacks(path, :changed) end # Notify callbacks that a file was deleted @@ -112,7 +108,7 @@ module Middleman path = Pathname(path) logger.debug "== File Deletion: #{path}" @known_paths.delete(path) - self.run_callbacks(path, :deleted) + run_callbacks(path, :deleted) end # Manually trigger update events @@ -150,7 +146,7 @@ module Middleman def exists?(path) p = Pathname(path) - p = p.relative_path_from(Pathname(@app.root)) if !p.relative? + p = p.relative_path_from(Pathname(@app.root)) unless p.relative? @known_paths.include?(p) end @@ -162,7 +158,7 @@ module Middleman app.config[:file_watcher_ignore].any? { |r| path =~ r } end - protected + protected # Notify callbacks for a file given an array of callbacks # @@ -171,7 +167,7 @@ module Middleman # @return [void] def run_callbacks(path, callbacks_name) path = path.to_s - self.send(callbacks_name).each do |callback, matcher| + send(callbacks_name).each do |callback, matcher| next unless matcher.nil? || path.match(matcher) @app.instance_exec(path, &callback) 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 41ec27ac..1105f2a0 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -9,10 +9,8 @@ require 'active_support/json' # Extensions namespace module Middleman::CoreExtensions - class FrontMatter < ::Middleman::Extension - - YAML_ERRORS = [ StandardError ] + YAML_ERRORS = [StandardError] # https://github.com/tenderlove/psych/issues/23 if defined?(Psych) && defined?(Psych::SyntaxError) @@ -52,7 +50,7 @@ module Middleman::CoreExtensions end end - { :options => data } + { options: data } end end @@ -120,7 +118,7 @@ module Middleman::CoreExtensions @cache.delete(path) end - private + private # Parse YAML frontmatter out of a string # @param [String] content # @return [Array] @@ -152,7 +150,7 @@ module Middleman::CoreExtensions content = content.sub(json_regex, '') begin - json = ($1+$2).sub(';;;', '{').sub(';;;', '}') + json = ($1 + $2).sub(';;;', '{').sub(';;;', '}') data = ActiveSupport::JSON.decode(json).symbolize_keys rescue => e app.logger.error "JSON Exception parsing #{full_path}: #{e.message}" diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index f500d953..423ce074 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -37,8 +37,8 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension configure_i18n - if !app.build? - logger.info "== Locales: #{langs.join(", ")} (Default #{@mount_at_root})" + unless app.build? + logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})" end # Don't output localizable files @@ -55,7 +55,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - delegate :logger, :to => :app + delegate :logger, to: :app def langs @_langs ||= get_known_languages @@ -70,7 +70,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension resources.each do |resource| # If it uses file extension localization - if !parse_locale_extension(resource.path).nil? + if parse_locale_extension(resource.path) result = parse_locale_extension(resource.path) lang, path, page_id = result new_resources << build_resource(path, resource.path, page_id, lang) @@ -90,7 +90,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension private - def on_file_changed(file) if @locales_regex =~ file @_langs = nil # Clear langs cache @@ -125,11 +124,11 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end { - :locals => { - :lang => lang, - :page_id => page_id + locals: { + lang: lang, + page_id: page_id }, - :options => { :lang => lang } + options: { lang: lang } } end @@ -168,9 +167,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def build_resource(path, source_path, page_id, lang) old_locale = ::I18n.locale ::I18n.locale = lang - localized_page_id = ::I18n.t("paths.#{page_id}", :default => page_id, :fallback => []) + localized_page_id = ::I18n.t("paths.#{page_id}", default: page_id, fallback: []) - prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root] == nil && langs[0] == lang) + prefix = if (options[:mount_at_root] == lang) || (options[:mount_at_root].nil? && langs[0] == lang) '/' else replacement = options[:lang_map].fetch(lang, lang) @@ -182,7 +181,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension File.join(prefix, path.sub(page_id, localized_page_id)) ) - path.gsub!(options[:templates_dir]+'/', '') + path.gsub!(options[:templates_dir] + '/', '') @_localization_data[path] = [lang, path, localized_page_id] diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index c61f2f2d..08ed81a6 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -2,13 +2,10 @@ require 'middleman-core/template_context' # Rendering extension module Middleman - module CoreExtensions module Rendering - # Setup extension class << self - # Once registered def included(app) app.define_hook :before_render diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index 8a001b91..0263d4a2 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -9,10 +9,8 @@ require 'middleman-core/template_renderer' module Middleman module CoreExtensions - # Base helper to manipulate asset paths module Request - # Extension registered class << self # @private @@ -60,9 +58,7 @@ module Middleman # @private # @param [Middleman::Application] inst # @return [void] - def inst=(inst) - @inst = inst - end + attr_writer :inst # Return built Rack app # @@ -152,9 +148,8 @@ module Middleman # Methods to be mixed-in to Middleman::Application module InstanceMethods - - delegate :use, :to => :"self.class" - delegate :map, :to => :"self.class" + delegate :use, to: :"self.class" + delegate :map, to: :"self.class" def call(env) dup.call!(env) @@ -168,7 +163,7 @@ module Middleman req = ::Rack::Request.new(env) res = ::Rack::Response.new - logger.debug "== Request: #{env["PATH_INFO"]}" + logger.debug "== Request: #{env['PATH_INFO']}" # Catch :halt exceptions and use that response if given catch(:halt) do @@ -239,7 +234,7 @@ module Middleman # @param [String] value Mime type # @return [void] def mime_type(type, value) - type = ".#{type}" unless type.to_s[0] == ?. + type = ".#{type}" unless type.to_s[0] == '.' ::Rack::Mime::MIME_TYPES[type] = value end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 8b9a58d6..633ecc57 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -2,7 +2,6 @@ module Middleman module CoreExtensions module Routing - # Sandboxed layout to implement temporary overriding of layout. class LayoutBlock attr_reader :scope @@ -17,7 +16,7 @@ module Middleman @scope.page(url, opts) end - delegate :proxy, :to => :scope + delegate :proxy, to: :scope end # Takes a block which allows many pages to have the same layout @@ -46,7 +45,7 @@ module Middleman # Default layout options[:layout] = @app.config[:layout] if options[:layout].nil? - metadata = { :options => options, :locals => options.delete(:locals) || {} } + metadata = { options: options, locals: options.delete(:locals) || {} } # If the url is a regexp unless url.is_a?(Regexp) || url.include?('*') diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 6219f258..4a3c3702 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -2,11 +2,10 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' module Middleman - class Extension - class_attribute :supports_multiple_instances, :instance_reader => false, :instance_writer => false - class_attribute :defined_helpers, :instance_reader => false, :instance_writer => false - class_attribute :ext_name, :instance_reader => false, :instance_writer => false + class_attribute :supports_multiple_instances, instance_reader: false, instance_writer: false + class_attribute :defined_helpers, instance_reader: false, instance_writer: false + class_attribute :ext_name, instance_reader: false, instance_writer: false class << self def config @@ -51,7 +50,7 @@ module Middleman name = instance.class.ext_name return unless @_extension_activation_callbacks && @_extension_activation_callbacks[name] @_extension_activation_callbacks[name].each do |block| - block.arity == 1 ? block.call(instance) : block.call() + block.arity == 1 ? block.call(instance) : block.call end end end @@ -59,7 +58,7 @@ module Middleman attr_accessor :options attr_reader :app - delegate :after_extension_activated, :to => :"::Middleman::Extension" + delegate :after_extension_activated, to: :"::Middleman::Extension" def initialize(klass, options_hash={}, &block) @_helpers = [] @@ -86,7 +85,7 @@ module Middleman end end - protected + protected def setup_options(options_hash, &block) @options = self.class.config.dup diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index c147230d..bb033481 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -1,7 +1,5 @@ module Middleman - module Extensions - class << self def registered @_registered ||= {} @@ -32,7 +30,7 @@ module Middleman # extension is activated. def register(name, namespace=nil, &block) # If we've already got an extension registered under this name, bail out - if registered.has_key?(name.to_sym) + if registered.key?(name.to_sym) raise "There is already an extension registered with the name '#{name}'" end @@ -41,7 +39,7 @@ module Middleman elsif namespace && namespace.ancestors.include?(::Middleman::Extension) namespace else - raise "You must provide a Middleman::Extension or a block that returns a Middleman::Extension" + raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end end @@ -49,17 +47,17 @@ module Middleman def load(name) name = name.to_sym - unless registered.has_key?(name) + unless registered.key?(name) raise "Unknown Extension: #{name}. Check the name and make sure you have referenced the extension's gem in your Gemfile." end extension = registered[name] if extension.is_a?(Proc) - extension = extension.call() + extension = extension.call registered[name] = extension end - if !extension.ancestors.include?(::Middleman::Extension) + unless extension.ancestors.include?(::Middleman::Extension) raise "Tried to activate old-style extension: #{name}. They are no longer supported." end @@ -116,7 +114,7 @@ module Middleman # @return [Boolean] Whether the file exists def spec_has_file?(spec, path) full_path = File.join(spec.full_gem_path, path) - File.exists?(full_path) + File.exist?(full_path) end end end diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index 6673fec6..a1089d9e 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -18,7 +18,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension # Allow specifying regexes to ignore, plus always ignore apple touch icons @ignore = Array(options.ignore) + [/^apple-touch-icon/] - app.use Middleware, :exts => options.exts, :middleman_app => app, :ignore => @ignore + app.use Middleware, exts: options.exts, middleman_app: app, ignore: @ignore end # Update the main sitemap resource list @@ -64,7 +64,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension def hashed_filename(resource) # Render through the Rack interface so middleware and mounted apps get a shot - response = @rack_client.get(URI.escape(resource.destination_path), { 'bypass_asset_hash' => 'true' }) + response = @rack_client.get(URI.escape(resource.destination_path), 'bypass_asset_hash' => 'true') raise "#{resource.path} should be in the sitemap!" unless response.status == 200 digest = Digest::SHA1.hexdigest(response.body)[0..7] @@ -93,7 +93,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension @rack_app = app @exts = options[:exts] @ignore = options[:ignore] - @exts_regex_text = @exts.map {|e| Regexp.escape(e) }.join('|') + @exts_regex_text = @exts.map { |e| Regexp.escape(e) }.join('|') @middleman_app = options[:middleman_app] end @@ -115,7 +115,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension [status, headers, response] end - private + private def rewrite_paths(body, path) dirpath = Pathname.new(File.dirname(path)) @@ -141,9 +141,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension end end end - end - end # =================Temp Generate Test data============================== diff --git a/middleman-core/lib/middleman-core/extensions/automatic_alt_tags.rb b/middleman-core/lib/middleman-core/extensions/automatic_alt_tags.rb index 95aaefee..879cecee 100644 --- a/middleman-core/lib/middleman-core/extensions/automatic_alt_tags.rb +++ b/middleman-core/lib/middleman-core/extensions/automatic_alt_tags.rb @@ -1,6 +1,5 @@ # Automatic Image alt tags from image names extension class Middleman::Extensions::AutomaticAltTags < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super end @@ -10,14 +9,14 @@ class Middleman::Extensions::AutomaticAltTags < ::Middleman::Extension # containing image name. def image_tag(path) - if !path.include?('://') + unless path.include?('://') params[:alt] ||= '' real_path = path 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) + if File.exist?(full_path) begin alt_text = File.basename(full_path, '.*') alt_text.capitalize! diff --git a/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb b/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb index 2fb37abb..86311be7 100644 --- a/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb +++ b/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb @@ -1,6 +1,5 @@ # Automatic Image Sizes extension class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super @@ -16,22 +15,22 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension # @param [Hash] params # @return [String] def image_tag(path, params={}) - if !params.has_key?(:width) && !params.has_key?(:height) && !path.include?('://') + if !params.key?(:width) && !params.key?(:height) && !path.include?('://') params[:alt] ||= '' real_path = path real_path = File.join(config[:images_dir], real_path) unless real_path.start_with?('/') full_path = File.join(source_dir, real_path) - if File.exists?(full_path) + if File.exist?(full_path) begin - width, height = ::FastImage.size(full_path, :raise_on_failure => true) + width, height = ::FastImage.size(full_path, raise_on_failure: true) params[:width] = width params[:height] = height rescue FastImage::UnknownImageType # No message, it's just not supported rescue - warn "Couldn't determine dimensions for image #{path}: #{$!.message}" + warn "Couldn't determine dimensions for image #{path}: #{$ERROR_INFO.message}" end end end diff --git a/middleman-core/lib/middleman-core/extensions/cache_buster.rb b/middleman-core/lib/middleman-core/extensions/cache_buster.rb index 44652888..7036d5fc 100644 --- a/middleman-core/lib/middleman-core/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-core/extensions/cache_buster.rb @@ -1,6 +1,5 @@ # The Cache Buster extension class Middleman::Extensions::CacheBuster < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-core/extensions/lorem.rb b/middleman-core/lib/middleman-core/extensions/lorem.rb index d13abeeb..32f1c6c1 100644 --- a/middleman-core/lib/middleman-core/extensions/lorem.rb +++ b/middleman-core/lib/middleman-core/extensions/lorem.rb @@ -94,11 +94,11 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension # Get a placeholder date # @param [String] fmt # @return [String] - def date(fmt = '%a %b %d, %Y') + def date(fmt='%a %b %d, %Y') y = rand(20) + 1990 m = rand(12) + 1 d = rand(31) + 1 - Time.local(y,m,d).strftime(fmt) + Time.local(y, m, d).strftime(fmt) end # Get a placeholder name @@ -125,16 +125,16 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension # Via http://www.kevadamson.com/talking-of-design/article/140-alternative-characters-to-lorem-ipsum # @return [String] def tweet - tweets = [ 'Far away, in a forest next to a river beneath the mountains, there lived a small purple otter called Philip. Philip likes sausages. The End.', - 'He liked the quality sausages from Marks & Spencer but due to the recession he had been forced to shop in a less desirable supermarket. End.', - 'He awoke one day to find his pile of sausages missing. Roger the greedy boar with human eyes, had skateboarded into the forest & eaten them!'] + tweets = ['Far away, in a forest next to a river beneath the mountains, there lived a small purple otter called Philip. Philip likes sausages. The End.', + 'He liked the quality sausages from Marks & Spencer but due to the recession he had been forced to shop in a less desirable supermarket. End.', + 'He awoke one day to find his pile of sausages missing. Roger the greedy boar with human eyes, had skateboarded into the forest & eaten them!'] tweets[rand(tweets.size)] end # Get a placeholder email address # @return [String] def email - delimiters = [ '_', '-', '' ] + delimiters = ['_', '-', ''] domains = %w(gmail.com yahoo.com hotmail.com email.com live.com me.com mac.com aol.com fastmail.com mail.com) username = name.gsub(/[^\w]/, delimiters[rand(delimiters.size)]) "#{username}@#{domains[rand(domains.size)]}".downcase @@ -147,7 +147,7 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension def image(size, options={}) domain = options[:domain] || 'http://placehold.it' src = "#{domain}/#{size}" - hex = %w[a b c d e f 0 1 2 3 4 5 6 7 8 9] + hex = %w(a b c d e f 0 1 2 3 4 5 6 7 8 9) background_color = options[:background_color] color = options[:color] @@ -159,7 +159,7 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension src << "/#{background_color.sub(/^#/, '')}" if background_color src << '/ccc' if background_color.nil? && color src << "/#{color.sub(/^#/, '')}" if color - src << "&text=#{Rack::Utils::escape(options[:text])}" if options[:text] + src << "&text=#{Rack::Utils.escape(options[:text])}" if options[:text] src end diff --git a/middleman-core/lib/middleman-core/extensions/minify_css.rb b/middleman-core/lib/middleman-core/extensions/minify_css.rb index dcf89e91..000bcebf 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_css.rb @@ -2,22 +2,22 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension option :inline, false, 'Whether to minify CSS inline within HTML files' option :ignore, [], 'Patterns to avoid minifying' - option :compressor, Proc.new { + option :compressor, proc { require 'sass' SassCompressor }, 'Set the CSS compressor to use.' def after_configuration # Setup Rack middleware to minify CSS - app.use Rack, :compressor => options[:compressor], - :ignore => Array(options[:ignore]) + [/\.min\./], - :inline => options[:inline] + app.use Rack, compressor: options[:compressor], + ignore: Array(options[:ignore]) + [/\.min\./], + inline: options[:inline] end class SassCompressor - def self.compress(style, options = {}) + def self.compress(style, options={}) root_node = ::Sass::SCSS::CssParser.new(style, 'middleman-css-input', 1).parse - root_node.options = { :style => :compressed } + root_node.options = { style: :compressed } root_node.render.strip end end @@ -63,13 +63,13 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension [status, headers, response] end - private + private def inline_html_content?(path) (path.end_with?('.html') || path.end_with?('.php')) && @inline end def standalone_css_content?(path) - path.end_with?('.css') && @ignore.none? {|ignore| Middleman::Util.path_match(ignore, path) } + path.end_with?('.css') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) } end end end diff --git a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb index 240e9a5d..5a03671b 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb @@ -2,21 +2,20 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension option :inline, false, 'Whether to minify JS inline within HTML files' option :ignore, [], 'Patterns to avoid minifying' - option :compressor, Proc.new { + option :compressor, proc { require 'uglifier' ::Uglifier.new }, 'Set the JS compressor to use.' def after_configuration # Setup Rack middleware to minify CSS - app.use Rack, :compressor => options[:compressor], - :ignore => Array(options[:ignore]) + [/\.min\./], - :inline => options[:inline] + app.use Rack, compressor: options[:compressor], + ignore: Array(options[:ignore]) + [/\.min\./], + inline: options[:inline] end # Rack middleware to look for JS and compress it class Rack - # Init # @param [Class] app # @param [Hash] options @@ -46,7 +45,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension headers['Content-Length'] = ::Rack::Utils.bytesize(minified).to_s response = [minified] - elsif path.end_with?('.js') && @ignore.none? {|ignore| Middleman::Util.path_match(ignore, path) } + elsif path.end_with?('.js') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) } uncompressed_source = ::Middleman::Util.extract_response_text(response) minified = @compressor.compress(uncompressed_source) @@ -60,7 +59,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension [status, headers, response] end - private + private def minify_inline_content(uncompressed_source) uncompressed_source.gsub(/(]*>\s*(?:\/\/(?:(?:)|(?:\]\]>)))?\s*<\/script>)/m) do |match| diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index 61e54881..ec7d3cf0 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -1,6 +1,5 @@ # Relative Assets extension class Middleman::Extensions::RelativeAssets < ::Middleman::Extension - def initialize(app, options_hash={}, &block) super diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index 6d3e4dd1..79da5773 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -2,14 +2,12 @@ require 'tilt' require 'active_support/core_ext/string/output_safety' module Middleman - class FileRenderer - def self.cache @_cache ||= ::Tilt::Cache.new end - delegate :cache, :to => :"self.class" + delegate :cache, to: :"self.class" def initialize(app, path) @app = app @@ -22,7 +20,7 @@ module Middleman # @param [Hash] opts # @param [Class] context # @return [String] - def render(locs = {}, opts = {}, context, &block) + def render(locs={}, opts={}, context, &block) path = @path.dup # Detect the remdering engine from the extension @@ -60,7 +58,7 @@ module Middleman # Read compiled template from disk or cache template = cache.fetch(:compiled_template, extension, options, body) do - ::Tilt.new(path, 1, options) { body } + ::Tilt.new(path, 1, options) { body } end # Render using Tilt @@ -91,7 +89,7 @@ module Middleman end end - protected + protected # Get a hash of configuration options for a given file extension, from # config.rb diff --git a/middleman-core/lib/middleman-core/load_paths.rb b/middleman-core/lib/middleman-core/load_paths.rb index 968e61ec..68defc69 100644 --- a/middleman-core/lib/middleman-core/load_paths.rb +++ b/middleman-core/lib/middleman-core/load_paths.rb @@ -2,7 +2,6 @@ require 'pathname' module Middleman - class << self def setup_load_paths @_is_setup ||= begin @@ -31,11 +30,11 @@ module Middleman def setup_bundler ENV['BUNDLE_GEMFILE'] ||= findup('Gemfile', ENV['MM_ROOT']) - if !File.exists?(ENV['BUNDLE_GEMFILE']) + unless File.exist?(ENV['BUNDLE_GEMFILE']) ENV['BUNDLE_GEMFILE'] = File.expand_path('../../../../Gemfile', __FILE__) end - if File.exists?(ENV['BUNDLE_GEMFILE']) + if File.exist?(ENV['BUNDLE_GEMFILE']) require 'bundler/setup' Bundler.require else @@ -44,12 +43,10 @@ module Middleman end # Recursive method to find a file in parent directories - def findup(filename, cwd = Pathname.new(Dir.pwd)) + def findup(filename, cwd=Pathname.new(Dir.pwd)) return cwd.to_s if (cwd + filename).exist? return false if cwd.root? findup(filename, cwd.parent) end - end - end diff --git a/middleman-core/lib/middleman-core/logger.rb b/middleman-core/lib/middleman-core/logger.rb index 3ab3581e..7d361946 100644 --- a/middleman-core/lib/middleman-core/logger.rb +++ b/middleman-core/lib/middleman-core/logger.rb @@ -4,10 +4,8 @@ require 'active_support/logger' require 'thread' module Middleman - # The Middleman Logger class Logger < ActiveSupport::Logger - def self.singleton(*args) if !@_logger || args.length > 0 if args.length == 1 && (args.first.is_a?(::String) || args.first.respond_to?(:write)) @@ -42,7 +40,7 @@ module Middleman return if @instrumenting.is_a?(String) && @instrumenting != 'instrument' && !message.include?(@instrumenting) evt = ActiveSupport::Notifications::Event.new(message, *args) - self.info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms" + info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms" end end end diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index b88d0215..79ac13a9 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -19,7 +19,7 @@ module Middleman meta_pages = self @rack_app = Rack::Builder.new do # Serve assets from metadata/assets - use Rack::Static, :urls => ['/assets'], :root => File.join(File.dirname(__FILE__), 'meta_pages') + use Rack::Static, urls: ['/assets'], root: File.join(File.dirname(__FILE__), 'meta_pages') map '/' do run meta_pages.method(:index) @@ -54,12 +54,12 @@ module Middleman sitemap_tree.add_resource resource end - template('sitemap.html.erb', :sitemap_tree => sitemap_tree) + template('sitemap.html.erb', sitemap_tree: sitemap_tree) end # Inspect configuration def config(env) - global_config = @middleman.inst.config.all_settings.map {|c| ConfigSetting.new(c) } + global_config = @middleman.inst.config.all_settings.map { |c| ConfigSetting.new(c) } extension_config = {} @middleman.inst.extensions.each do |ext_name, extension| @@ -80,9 +80,9 @@ module Middleman end template('config.html.erb', - :global_config => global_config, - :extension_config => extension_config, - :registered_extensions => Middleman::Extensions.registered.dup) + global_config: global_config, + extension_config: extension_config, + registered_extensions: Middleman::Extensions.registered.dup) end private @@ -96,11 +96,11 @@ module Middleman # Respond to an HTML request def response(content) - [ 200, {'Content-Type' => 'text/html'}, Array(content) ] + [200, { 'Content-Type' => 'text/html' }, Array(content)] end def extension_options(extension) - extension.options.all_settings.map {|c| ConfigSetting.new(c) } + extension.options.all_settings.map { |c| ConfigSetting.new(c) } end end end diff --git a/middleman-core/lib/middleman-core/meta_pages/config_setting.rb b/middleman-core/lib/middleman-core/meta_pages/config_setting.rb index 3fd223e3..d10a484a 100644 --- a/middleman-core/lib/middleman-core/meta_pages/config_setting.rb +++ b/middleman-core/lib/middleman-core/meta_pages/config_setting.rb @@ -15,17 +15,17 @@ module Middleman content = '' key_classes = ['key'] key_classes << 'modified' if @setting.value_set? - content << content_tag(:span, @setting.key.pretty_inspect.strip, :class => key_classes.join(' ')) + content << content_tag(:span, @setting.key.pretty_inspect.strip, class: key_classes.join(' ')) content << ' = ' - content << content_tag(:span, @setting.value.pretty_inspect.strip, :class => 'value') + content << content_tag(:span, @setting.value.pretty_inspect.strip, class: 'value') if @setting.default && @setting.value_set? && @setting.default != @setting.value - content << content_tag(:span, :class => 'default') do + content << content_tag(:span, class: 'default') do "(Default: #{@setting.default.inspect})" end end if @setting.description - content << content_tag(:p, :class => 'description') do + content << content_tag(:p, class: 'description') do @setting.description end end 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 d16b9154..e42176df 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb @@ -14,7 +14,7 @@ module Middleman def render classes = 'resource-details' classes << ' ignored' if @resource.ignored? - content_tag :div, :class => classes do + content_tag :div, class: classes do content_tag :table do content = '' resource_properties.each do |label, value| @@ -38,7 +38,7 @@ module Middleman build_path = @resource.destination_path 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['URL'] = content_tag(:a, @resource.url, href: @resource.url) unless ignored? props['Source File'] = @resource.source_file.sub(/^#{Regexp.escape(ENV['MM_ROOT'] + '/')}/, '') data = @resource.data diff --git a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb index 68bae977..ab2f03d9 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_tree.rb @@ -14,7 +14,7 @@ module Middleman def render content = '' - @children.keys.sort do |a,b| + @children.keys.sort do |a, b| a_subtree = @children[a] b_subtree = @children[b] if a_subtree.is_a? SitemapResource diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index a90d2bab..0502bcac 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -4,12 +4,11 @@ require 'middleman-core/logger' module Middleman module PreviewServer - DEFAULT_PORT = 4567 class << self attr_reader :app, :host, :port - delegate :logger, :to => :app + delegate :logger, to: :app # Start an instance of Middleman::Application # @return [void] @@ -70,7 +69,7 @@ module Middleman begin app = new_app - rescue Exception => e + rescue => e logger.error "Error reloading Middleman: #{e}\n#{e.backtrace.join("\n")}" logger.info '== The Middleman is still running the application from before the error' return @@ -89,7 +88,7 @@ module Middleman @webrick.shutdown end - private + private def new_app opts = @options.dup server = ::Middleman::Application.server @@ -120,7 +119,7 @@ module Middleman if first_run # Watcher Library require 'listen' - @listener = Listen.to(Dir.pwd, :relative_paths => true, :force_polling => @options[:force_polling]) + @listener = Listen.to(Dir.pwd, relative_paths: true, force_polling: @options[:force_polling]) @listener.latency(@options[:latency]) end @@ -166,10 +165,10 @@ module Middleman # @return [void] def setup_webrick(is_logging) http_opts = { - :BindAddress => host, - :Port => port, - :AccessLog => [], - :DoNotReverseLookup => true + BindAddress: host, + Port: port, + AccessLog: [], + DoNotReverseLookup: true } if is_logging @@ -181,7 +180,7 @@ module Middleman begin ::WEBrick::HTTPServer.new(http_opts) rescue Errno::EADDRINUSE - logger.error "== Port #{port} is unavailable. Either close the instance of Middleman already running on #{port} or start this Middleman on a new port with: --port=#{port.to_i+1}" + logger.error "== Port #{port} is unavailable. Either close the instance of Middleman already running on #{port} or start this Middleman on a new port with: --port=#{port.to_i + 1}" exit(1) end end @@ -236,7 +235,6 @@ module Middleman host = (@host == '0.0.0.0') ? 'localhost' : @host URI("http://#{host}:#{@port}") end - end class FilteredWebrickLog < ::WEBrick::Log diff --git a/middleman-core/lib/middleman-core/profiling.rb b/middleman-core/lib/middleman-core/profiling.rb index 0e54f41e..5bcb7bd8 100644 --- a/middleman-core/lib/middleman-core/profiling.rb +++ b/middleman-core/lib/middleman-core/profiling.rb @@ -1,6 +1,5 @@ module Middleman module Profiling - # The profiler instance. There can only be one! def self.profiler=(prof) @profiler = prof @@ -31,11 +30,9 @@ module Middleman # A profiler that uses ruby-prof class RubyProfProfiler def initialize - begin - require 'ruby-prof' - rescue LoadError - raise "To use the --profile option, you must add the 'ruby-prof' gem to your Gemfile" - end + require 'ruby-prof' + rescue LoadError + raise "To use the --profile option, you must add the 'ruby-prof' gem to your Gemfile" end def start @@ -50,7 +47,7 @@ module Middleman outfile = (outfile + '.html') unless outfile.end_with? '.html' FileUtils.mkdir_p(File.dirname(outfile)) File.open(outfile, 'w') do |f| - printer.print(f, :min_percent=> 1) + printer.print(f, min_percent: 1) end end end diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb index 3f87d1fa..e6f57cb4 100644 --- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb +++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb @@ -3,10 +3,8 @@ require 'coffee_script' module Middleman module Renderers - # CoffeeScript Renderer module CoffeeScript - # Setup extension class << self # Once registered @@ -19,7 +17,7 @@ module Middleman DebuggingCoffeeScriptTemplate.middleman_app = self end end - alias :included :registered + alias_method :included, :registered end # A Template for Tilt which outputs debug messages diff --git a/middleman-core/lib/middleman-core/renderers/erb.rb b/middleman-core/lib/middleman-core/renderers/erb.rb index 89f93bac..a3a1239c 100644 --- a/middleman-core/lib/middleman-core/renderers/erb.rb +++ b/middleman-core/lib/middleman-core/renderers/erb.rb @@ -4,7 +4,6 @@ module Middleman module ERb # Setup extension class << self - # once registered def registered(app) # After config @@ -12,7 +11,7 @@ module Middleman ::Tilt.prefer(Template, :erb) end end - alias :included :registered + alias_method :included, :registered end class Template < ::Tilt::ErubisTemplate @@ -22,7 +21,7 @@ module Middleman def precompiled_preamble(locals) original = super "__in_erb_template = true\n" << original - #.rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n" + # .rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n" end end end diff --git a/middleman-core/lib/middleman-core/renderers/haml.rb b/middleman-core/lib/middleman-core/renderers/haml.rb index fc450417..e90e5b8c 100644 --- a/middleman-core/lib/middleman-core/renderers/haml.rb +++ b/middleman-core/lib/middleman-core/renderers/haml.rb @@ -13,7 +13,6 @@ end module Middleman module Renderers - # Haml precompiles filters before the scope is even available, # thus making it impossible to pass our Middleman instance # in. So we have to resort to heavy hackery :( @@ -24,7 +23,7 @@ module Middleman def evaluate(scope, locals, &block) ::Middleman::Renderers::Haml.last_haml_scope = scope - options = @options.merge(:filename => eval_file, :line => line) + options = @options.merge(filename: eval_file, line: line) @engine = ::Haml::Engine.new(data, options) output = @engine.render(scope, locals, &block) @@ -47,7 +46,7 @@ module Middleman # Add haml helpers to context ::Middleman::TemplateContext.send :include, ::Haml::Helpers end - alias :included :registered + alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/kramdown.rb b/middleman-core/lib/middleman-core/renderers/kramdown.rb index d5e5757c..669e315e 100644 --- a/middleman-core/lib/middleman-core/renderers/kramdown.rb +++ b/middleman-core/lib/middleman-core/renderers/kramdown.rb @@ -2,7 +2,6 @@ require 'kramdown' module Middleman module Renderers - # Our own Kramdown Tilt template that simply uses our custom renderer. class KramdownTemplate < ::Tilt::KramdownTemplate def evaluate(scope, locals, &block) @@ -34,7 +33,7 @@ module Middleman mail_addr = el.attr['href'].sub(/\Amailto:/, '') href = obfuscate('mailto') << ':' << obfuscate(mail_addr) content = obfuscate(content) if content == mail_addr - return %Q{#{content}} + return %Q(#{content}) end attr = el.attr.dup diff --git a/middleman-core/lib/middleman-core/renderers/less.rb b/middleman-core/lib/middleman-core/renderers/less.rb index d09e1ac9..db097298 100644 --- a/middleman-core/lib/middleman-core/renderers/less.rb +++ b/middleman-core/lib/middleman-core/renderers/less.rb @@ -2,13 +2,10 @@ require 'less' module Middleman module Renderers - # Sass renderer module Less - # Setup extension class << self - # Once registered def registered(app) # Default less options @@ -23,23 +20,20 @@ module Middleman ::Tilt.prefer(LocalLoadingLessTemplate) end - alias :included :registered + alias_method :included, :registered end # A SassTemplate for Tilt which outputs debug messages class LocalLoadingLessTemplate < ::Tilt::LessTemplate - def prepare if ::Less.const_defined? :Engine @engine = ::Less::Engine.new(data) else - parser = ::Less::Parser.new(options.merge :filename => eval_file, :line => line, :paths => ['.', File.dirname(eval_file)]) + parser = ::Less::Parser.new(options.merge filename: eval_file, line: line, paths: ['.', File.dirname(eval_file)]) @engine = parser.parse(data) end end - end - end end end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index 3596432e..c4d2581c 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -3,13 +3,10 @@ require 'liquid' module Middleman module Renderers - # Liquid Renderer module Liquid - # Setup extension class << self - # Once registerd def registered(app) # After config, setup liquid partial paths @@ -18,14 +15,13 @@ module Middleman # Convert data object into a hash for liquid sitemap.provides_metadata %r{\.liquid$} do |path| - { :locals => { :data => data.to_h } } + { locals: { data: data.to_h } } end end end - alias :included :registered + alias_method :included, :registered end end - end end diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index 90889edb..c60c4030 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -1,12 +1,9 @@ module Middleman module Renderers - # Markdown renderer module Markdown - # Setup extension class << self - # Once registered def registered(app) # Set our preference for a markdown engine @@ -25,7 +22,7 @@ module Middleman elsif config[:markdown_engine] == :kramdown require 'middleman-core/renderers/kramdown' ::Tilt.prefer(::Middleman::Renderers::KramdownTemplate, *markdown_exts) - elsif !config[:markdown_engine].nil? + elsif config[:markdown_engine] # Map symbols to classes markdown_engine_klass = if config[:markdown_engine].is_a? Symbol engine = config[:markdown_engine].to_s @@ -48,9 +45,8 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end end - end end diff --git a/middleman-core/lib/middleman-core/renderers/redcarpet.rb b/middleman-core/lib/middleman-core/renderers/redcarpet.rb index e5ead89e..5181bd41 100644 --- a/middleman-core/lib/middleman-core/renderers/redcarpet.rb +++ b/middleman-core/lib/middleman-core/renderers/redcarpet.rb @@ -2,20 +2,18 @@ require 'redcarpet' module Middleman module Renderers - class RedcarpetTemplate < ::Tilt::RedcarpetTemplate::Redcarpet2 - # because tilt has decided to convert these # in the wrong direction ALIASES = { - :escape_html => :filter_html + escape_html: :filter_html } # Overwrite built-in Tilt version. # Don't overload :renderer option with smartypants # Support renderer-level options def generate_renderer - return options.delete(:renderer) if options.has_key?(:renderer) + return options.delete(:renderer) if options.key?(:renderer) covert_options_to_aliases! @@ -32,8 +30,8 @@ module Middleman # Renderer Options possible_render_opts = [:filter_html, :no_images, :no_links, :no_styles, :safe_links_only, :with_toc_data, :hard_wrap, :xhtml, :prettify, :link_attributes] - render_options = possible_render_opts.inject({}) do |sum, opt| - sum[opt] = options.delete(opt) if options.has_key?(opt) + render_options = possible_render_opts.reduce({}) do |sum, opt| + sum[opt] = options.delete(opt) if options.key?(opt) sum end @@ -50,11 +48,11 @@ module Middleman private - def covert_options_to_aliases! - ALIASES.each do |aka, actual| - options[actual] = options.delete(aka) if options.has_key? aka - end + def covert_options_to_aliases! + ALIASES.each do |aka, actual| + options[actual] = options.delete(aka) if options.key? aka end + end end # Custom Redcarpet renderer that uses our helpers for images and links @@ -69,23 +67,23 @@ module Middleman def image(link, title, alt_text) if !@local_options[:no_images] - scope.image_tag(link, :title => title, :alt => alt_text) + scope.image_tag(link, title: title, alt: alt_text) else link_string = link.dup - link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text + link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text %Q{![#{alt_text}](#{link_string})} end end def link(link, title, content) if !@local_options[:no_links] - attributes = { :title => title } - attributes.merge!( @local_options[:link_attributes] ) if @local_options[:link_attributes] + attributes = { title: title } + attributes.merge!(@local_options[:link_attributes]) if @local_options[:link_attributes] - scope.link_to(content, link, attributes ) + scope.link_to(content, link, attributes) else link_string = link.dup - link_string << %Q{"#{title}"} if title && title.length > 0 && title != alt_text + link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text %Q{[#{content}](#{link_string})} end end diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index a1d5c411..e1d41b65 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -3,13 +3,10 @@ require 'compass/import-once' module Middleman module Renderers - # Sass renderer module Sass - # Setup extension class << self - # Once registered def registered(app) # Default sass options @@ -26,16 +23,15 @@ module Middleman ::Compass::ImportOnce.activate! end - alias :included :registered + alias_method :included, :registered end # A SassTemplate for Tilt which outputs debug messages class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate - def initialize(*args, &block) super - if @options.has_key?(:context) + if @options.key?(:context) @context = @options[:context] end end @@ -59,14 +55,14 @@ module Middleman begin @engine.render rescue ::Sass::SyntaxError => e - ::Sass::SyntaxError.exception_to_css(e, :full_exception => true) + ::Sass::SyntaxError.exception_to_css(e, full_exception: true) end end # Change Sass path, for url functions, to the build folder if we're building # @return [Hash] def sass_options - more_opts = { :filename => eval_file, :line => line, :syntax => syntax } + more_opts = { filename: eval_file, line: line, syntax: syntax } if @context.is_a?(::Middleman::TemplateContext) && file location_of_sass_file = @context.source_dir @@ -82,7 +78,6 @@ module Middleman # SCSS version of the above template class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate - # Define the expected syntax for the template # @return [Symbol] def syntax diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index c10727ef..16bf2f25 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -17,26 +17,23 @@ end module Middleman module Renderers - # Slim renderer module Slim - # Setup extension class << self - # Once registered def registered(app) # Setup Slim options to work with partials ::Slim::Engine.set_default_options( - :buffer => '@_out_buf', - :use_html_safe => true, - :generator => ::Temple::Generators::RailsOutputBuffer, - :disable_escape => true + buffer: '@_out_buf', + use_html_safe: true, + generator: ::Temple::Generators::RailsOutputBuffer, + disable_escape: true ) app.after_configuration do context_hack = { - :context => self + context: self } ::Slim::Embedded::SassEngine.disable_option_validator! @@ -46,7 +43,7 @@ module Middleman end end - alias :included :registered + alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/stylus.rb b/middleman-core/lib/middleman-core/renderers/stylus.rb index 6fbdb455..7c7989e2 100644 --- a/middleman-core/lib/middleman-core/renderers/stylus.rb +++ b/middleman-core/lib/middleman-core/renderers/stylus.rb @@ -3,22 +3,18 @@ require 'stylus/tilt' module Middleman module Renderers - # Sass renderer module Stylus - # Setup extension class << self - # Once registered def registered(app) # Default stylus options app.config.define_setting :styl, {}, 'Stylus config options' end - alias :included :registered + alias_method :included, :registered end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index 658dc7c5..a939a727 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -1,30 +1,27 @@ # Core Sitemap Extensions module Middleman module Sitemap - # Setup Extension class << self - # Once registered def included(app) - # Set to automatically convert some characters into a directory app.config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory' # 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.start_with?('.') }, + root_dotfiles: proc { |file| file.start_with?('.') }, # Files starting with an dot, but not .htaccess - :source_dotfiles => proc { |file| + source_dotfiles: proc { |file| file =~ %r{/\.} && file !~ %r{/\.(htaccess|htpasswd|nojekyll)} }, # Files starting with an underscore, but not a double-underscore - :partials => proc { |file| file =~ %r{/_[^_]} }, + partials: proc { |file| file =~ %r{/_[^_]} }, - :layout => proc { |file, app| + layout: proc { |file, app| file.start_with?(File.join(app.config[:source], 'layout.')) || file.start_with?(File.join(app.config[:source], 'layouts/')) } }, 'Callbacks that can exclude paths from the sitemap' @@ -32,7 +29,6 @@ module Middleman # Include instance methods ::Middleman::TemplateContext.send :include, InstanceMethods end - end # Sitemap instance methods @@ -53,7 +49,6 @@ module Middleman return nil unless current_path sitemap.find_resource_by_destination_path(current_path) end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 3c5d3872..414cd7e9 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -1,9 +1,6 @@ module Middleman - module Sitemap - module Extensions - # Class to handle managing ignores class Ignores def initialize(sitemap) @@ -23,15 +20,15 @@ module Middleman # @return [void] def create_ignore(path=nil, &block) if path.is_a? Regexp - @ignored_callbacks << Proc.new {|p| p =~ path } + @ignored_callbacks << proc { |p| p =~ path } elsif path.is_a? String path_clean = ::Middleman::Util.normalize_path(path) if path_clean.include?('*') # It's a glob - @ignored_callbacks << Proc.new {|p| File.fnmatch(path_clean, p) } + @ignored_callbacks << proc { |p| File.fnmatch(path_clean, p) } else # Add a specific-path ignore unless that path is already covered return if ignored?(path_clean) - @ignored_callbacks << Proc.new {|p| p == path_clean } + @ignored_callbacks << proc { |p| p == path_clean } end elsif block_given? @ignored_callbacks << block @@ -48,10 +45,9 @@ module Middleman @ignored_callbacks.any? { |b| b.call(path_clean) } end end - + # Helpers methods for Resources module IgnoreResourceInstanceMethods - # Whether the Resource is ignored # @return [Boolean] def ignored? diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 824daaf4..abb917e4 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -1,13 +1,9 @@ require 'set' module Middleman - module Sitemap - module Extensions - class OnDisk - attr_accessor :sitemap attr_accessor :waiting_for_ready diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 55a0a371..131ecbe5 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -1,9 +1,6 @@ module Middleman - module Sitemap - module Extensions - # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations class Proxies @@ -26,13 +23,13 @@ module Middleman def create_proxy(path, target, opts={}) options = opts.dup - metadata = { :options => {}, :locals => {} } + metadata = { options: {}, locals: {} } metadata[:locals] = options.delete(:locals) || {} @app.ignore(target) if options.delete(:ignore) metadata[:options] = options - @proxy_configs << ProxyConfiguration.new(:path => path, :target => target, :metadata => metadata) + @proxy_configs << ProxyConfiguration.new(path: path, target: target, metadata: metadata) @app.sitemap.rebuild_resource_list!(:added_proxy) end @@ -106,9 +103,7 @@ module Middleman # The path of the page this page is proxied to, or nil if it's not proxied. # @return [String] - def proxied_to - @proxied_to - end + attr_reader :proxied_to # The resource for the page this page is proxied to. Throws an exception # if there is no resource. diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 6dfdb2b0..8717cfc7 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -1,11 +1,8 @@ require 'middleman-core/sitemap/resource' module Middleman - module Sitemap - module Extensions - # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations class Redirects @@ -58,10 +55,10 @@ module Middleman end def render(*args, &block) - url = ::Middleman::Util.url_for(store.app, @request_path, { - :relative => false, - :find_resource => true - }) + url = ::Middleman::Util.url_for(store.app, @request_path, + relative: false, + find_resource: true + ) if output output.call(path, url) @@ -99,7 +96,6 @@ module Middleman def metadata @local_metadata.dup end - end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index ba3ad732..ad92a23d 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -1,11 +1,7 @@ module Middleman - module Sitemap - module Extensions - class RequestEndpoints - # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations def initialize(sitemap) @@ -21,13 +17,13 @@ module Middleman # differs from the output path def create_endpoint(path, opts={}, &block) endpoint = { - :request_path => path + request_path: path } if block_given? endpoint[:output] = block else - endpoint[:request_path] = opts[:path] if opts.has_key?(:path) + endpoint[:request_path] = opts[:path] if opts.key?(:path) end @endpoints[path] = endpoint @@ -44,7 +40,7 @@ module Middleman path, config[:request_path] ) - r.output = config[:output] if config.has_key?(:output) + r.output = config[:output] if config.key?(:output) r end end @@ -64,12 +60,10 @@ module Middleman end def render(*args, &block) - return self.output.call if self.output + return output.call if output end - def request_path - @request_path - end + attr_reader :request_path def binary? false diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index e1920f12..e24bd464 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -1,9 +1,6 @@ module Middleman - module Sitemap - module Extensions - module Traversal # This resource's parent resource # @return [Middleman::Sitemap::Resource, nil] @@ -28,14 +25,14 @@ module Middleman if eponymous_directory? base_path = eponymous_directory_path - prefix = %r|^#{base_path.sub("/", "\\/")}| + prefix = %r{^#{base_path.sub("/", "\\/")}} else base_path = path.sub("#{app.config[:index_file]}", '') - prefix = %r|^#{base_path.sub("/", "\\/")}| + prefix = %r{^#{base_path.sub("/", "\\/")}} end store.resources.select do |sub_resource| - if sub_resource.path == self.path || sub_resource.path !~ prefix + if sub_resource.path == path || sub_resource.path !~ prefix false else inner_path = sub_resource.path.sub(prefix, '') @@ -72,7 +69,7 @@ module Middleman return true end full_path = File.join(app.source_dir, eponymous_directory_path) - !!(File.exists?(full_path) && File.directory?(full_path)) + !!(File.exist?(full_path) && File.directory?(full_path)) end # The path for this resource if it were a directory, and not a file diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index f69429c8..03056fdd 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -4,10 +4,8 @@ require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' module Middleman - # Sitemap namespace module Sitemap - # Sitemap Resource class class Resource include Middleman::Sitemap::Extensions::Traversal @@ -15,7 +13,7 @@ module Middleman # @return [Middleman::Application] attr_reader :app - delegate :logger, :instrument, :to => :app + delegate :logger, :instrument, to: :app # @return [Middleman::Sitemap::Store] attr_reader :store @@ -48,7 +46,7 @@ module Middleman @source_file = source_file @destination_path = @path - @local_metadata = { :options => {}, :locals => {} } + @local_metadata = { options: {}, locals: {} } end # Whether this resource has a template file @@ -89,27 +87,27 @@ module Middleman end def request_path - self.destination_path + destination_path end # Render this resource # @return [String] def render(opts={}, locs={}) - if !template? + unless template? return ::Middleman::FileRenderer.new(@app, source_file).get_template_data_for_file end relative_source = Pathname(source_file).relative_path_from(Pathname(app.root)) - instrument 'render.resource', :path => relative_source, :destination_path => destination_path do + instrument 'render.resource', path: relative_source, destination_path: destination_path do md = metadata.dup opts = md[:options].deep_merge(opts) locs = md[:locals].deep_merge(locs) - locs[:current_path] ||= self.destination_path + locs[:current_path] ||= destination_path # Certain output file types don't use layouts - if !opts.has_key?(:layout) - opts[:layout] = false if %w(.js .json .css .txt).include?(self.ext) + unless opts.key?(:layout) + opts[:layout] = false if %w(.js .json .css .txt).include?(ext) end renderer = ::Middleman::TemplateRenderer.new(@app, source_file) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index be067c04..f5189a9b 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -10,10 +10,8 @@ require 'middleman-core/sitemap/extensions/proxies' require 'middleman-core/sitemap/extensions/ignores' module Middleman - # Sitemap namespace module Sitemap - # The Store class # # The Store manages a collection of Resource objects, which represent @@ -21,7 +19,6 @@ module Middleman # which is the path relative to the source directory, minus any template # extensions. All "path" parameters used in this class are source paths. class Store - # @return [Middleman::Application] attr_accessor :app @@ -33,7 +30,7 @@ module Middleman @_cached_metadata = {} @resource_list_manipulators = [] @needs_sitemap_rebuild = true - + @lock = Monitor.new reset_lookup_cache! @@ -57,7 +54,7 @@ module Middleman register_resource_list_manipulator(k, m.new(self)) end - app.config_context.class.send :delegate, :sitemap, :to => :app + app.config_context.class.send :delegate, :sitemap, to: :app end # Register a klass which can manipulate the main site map list. Best to register @@ -134,9 +131,9 @@ module Middleman # @param [String] source_file # @return [Hash] def metadata_for_file(source_file) - blank_metadata = { :options => {}, :locals => {} } + blank_metadata = { options: {}, locals: {} } - provides_metadata.inject(blank_metadata) do |result, (callback, matcher)| + provides_metadata.reduce(blank_metadata) do |result, (callback, matcher)| next result if matcher && !source_file.match(matcher) metadata = callback.call(source_file).dup @@ -162,9 +159,9 @@ module Middleman def metadata_for_path(request_path) return @_cached_metadata[request_path] if @_cached_metadata[request_path] - blank_metadata = { :options => {}, :locals => {} } + blank_metadata = { options: {}, locals: {} } - @_cached_metadata[request_path] = provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)| + @_cached_metadata[request_path] = provides_metadata_for_path.reduce(blank_metadata) do |result, (callback, matcher)| case matcher when Regexp next result unless request_path =~ matcher @@ -215,7 +212,7 @@ module Middleman @app.logger.debug '== Rebuilding resource list' - @resources = @resource_list_manipulators.inject([]) do |result, (_, inst)| + @resources = @resource_list_manipulators.reduce([]) do |result, (_, inst)| newres = inst.manipulate_resource_list(result) # Reset lookup cache diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index d06ca5f0..93d66090 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -6,7 +6,7 @@ module Middleman attr_reader :app attr_accessor :current_engine - delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, :to => :app + delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, to: :app def initialize(app, locs={}, opts={}) @app = app @@ -30,13 +30,13 @@ module Middleman # Save current buffer for later _buf_was = save_buffer - layout_path = ::Middleman::TemplateRenderer.locate_layout(@app, layout_name, self.current_engine) + layout_path = ::Middleman::TemplateRenderer.locate_layout(@app, layout_name, current_engine) extension = File.extname(layout_path) engine = extension[1..-1].to_sym # Store last engine for later (could be inside nested renders) - self.current_engine, engine_was = engine, self.current_engine + self.current_engine, engine_was = engine, current_engine begin content = if block_given? @@ -76,12 +76,12 @@ module Middleman resolve_opts[:preferred_engine] = File.extname(resource.source_file)[1..-1].to_sym # Look for partials relative to the current path - relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(self.source_dir)}/?}, ''), data) + relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), data) found_partial = ::Middleman::TemplateRenderer.resolve_template(@app, relative_dir, resolve_opts) end - if !found_partial + unless found_partial partials_path = File.join(@app.config[:partials_dir], data) found_partial = ::Middleman::TemplateRenderer.resolve_template(@app, partials_path, resolve_opts) end diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 3b0e4c02..cb3f1194 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -4,14 +4,12 @@ require 'middleman-core/template_context' require 'middleman-core/file_renderer' module Middleman - class TemplateRenderer - def self.cache @_cache ||= ::Tilt::Cache.new end - delegate :cache, :to => :"self.class" + delegate :cache, to: :"self.class" # Custom error class for handling class TemplateNotFound < RuntimeError; end @@ -73,7 +71,7 @@ module Middleman ::I18n.locale = old_locale if defined?(::I18n) end - protected + protected # Find a layout for a given engine # @@ -82,7 +80,7 @@ module Middleman # @return [String] def fetch_layout(engine, opts) # The layout name comes from either the system default or the options - local_layout = opts.has_key?(:layout) ? opts[:layout] : @app.config[:layout] + local_layout = opts.key?(:layout) ? opts[:layout] : @app.config[:layout] return false unless local_layout # Look for engine-specific options @@ -90,9 +88,9 @@ module Middleman # The engine for the layout can be set in options, engine_options or passed # into this method - layout_engine = if opts.has_key?(:layout_engine) + layout_engine = if opts.key?(:layout_engine) opts[:layout_engine] - elsif engine_options.has_key?(:layout_engine) + elsif engine_options.key?(:layout_engine) engine_options[:layout_engine] else engine @@ -131,7 +129,7 @@ module Middleman layout_path = false resolve_opts = {} - resolve_opts[:preferred_engine] = preferred_engine if !preferred_engine.nil? + resolve_opts[:preferred_engine] = preferred_engine unless preferred_engine.nil? # Check layouts folder layout_path = resolve_template(app, File.join(app.config[:layouts_dir], name.to_s), resolve_opts) @@ -167,7 +165,7 @@ module Middleman preferred_engines = ['*'] # If we're specifically looking for a preferred engine - if options.has_key?(:preferred_engine) + if options.key?(:preferred_engine) extension_class = ::Tilt[options[:preferred_engine]] matched_exts = [] @@ -202,7 +200,7 @@ module Middleman # If we found one, return it if found_path found_path - elsif File.exists?(on_disk_path) + elsif File.exist?(on_disk_path) on_disk_path else false diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 51b0965d..3a06db02 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -14,7 +14,6 @@ require 'rack/mime' module Middleman module Util class << self - # Whether the source file is binary. # # @param [String] filename The file to check. @@ -27,7 +26,7 @@ module Middleman return false if Tilt.registered?(ext.sub('.', '')) - dot_ext = (ext.to_s[0] == ?.) ? ext.dup : ".#{ext}" + dot_ext = (ext.to_s[0] == '.') ? ext.dup : ".#{ext}" if mime = ::Rack::Mime.mime_type(dot_ext, nil) !nonbinary_mime?(mime) @@ -69,7 +68,7 @@ module Middleman # @return [String] def normalize_path(path) # The tr call works around a bug in Ruby's Unicode handling - path.sub(%r{^/}, '').tr('','') + path.sub(%r{^/}, '').tr('', '') end # This is a separate method from normalize_path in case we @@ -210,7 +209,7 @@ module Middleman def full_path(path, app) resource = app.sitemap.find_resource_by_destination_path(path) - if !resource + unless resource # Try it with /index.html at the end indexed_path = File.join(path.sub(%r{/$}, ''), app.config[:index_file]) resource = app.sitemap.find_resource_by_destination_path(indexed_path) @@ -294,7 +293,6 @@ module Middleman # hash.foo? #=> true # class HashWithIndifferentAccess < ::Hash #:nodoc: - def initialize(hash={}) super() hash.each do |key, value| @@ -315,7 +313,7 @@ module Middleman end def values_at(*indices) - indices.collect { |key| self[convert_key(key)] } + indices.map { |key| self[convert_key(key)] } end def merge(other) @@ -336,9 +334,9 @@ module Middleman protected - def convert_key(key) - key.is_a?(Symbol) ? key.to_s : key - end + def convert_key(key) + key.is_a?(Symbol) ? key.to_s : key + end # Magic predicates. For instance: # @@ -346,18 +344,18 @@ module Middleman # options.shebang # => "/usr/lib/local/ruby" # options.test_framework?(:rspec) # => options[:test_framework] == :rspec # - def method_missing(method, *args, &block) - method = method.to_s - if method =~ /^(\w+)\?$/ - if args.empty? - !!self[$1] - else - self[$1] == args.first - end + def method_missing(method, *args, &block) + method = method.to_s + if method =~ /^(\w+)\?$/ + if args.empty? + !!self[$1] else - self[method] + self[$1] == args.first end + else + self[method] end + end end end end diff --git a/middleman-templates/lib/middleman-templates.rb b/middleman-templates/lib/middleman-templates.rb index 65ca0a43..2179db6e 100644 --- a/middleman-templates/lib/middleman-templates.rb +++ b/middleman-templates/lib/middleman-templates.rb @@ -18,7 +18,7 @@ module Middleman # @param [Symbol] name The name of the template # @param [Class] klass The class to be executed for this template # @return [Hash] List of registered templates - def register(name = nil, klass = nil) + def register(name=nil, klass=nil) @_template_mappings ||= {} @_template_mappings[name] = klass if name && klass @_template_mappings @@ -97,10 +97,10 @@ if ENV['HOME'] # If a template.rb file is found require it (therefore registering the template) # else register the folder as a Local template (which when built, just copies the folder) - if File.exists?(template_file) + if File.exist?(template_file) require template_file else Middleman::Templates.register(File.basename(dir).to_sym, Middleman::Templates::Local) end end -end \ No newline at end of file +end From 113b352474afa28e7f4668d3bcdb4ecb613760fc Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 29 Apr 2014 11:59:10 -0700 Subject: [PATCH 012/662] have travis install rubocop --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 8921e505..c2d1da66 100644 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,7 @@ end # Code Quality gem 'coveralls', require: false -gem 'rubocop', require: false, group: :development +gem 'rubocop', require: false # Middleman itself gem 'middleman-core', path: 'middleman-core' From 2dd87bab746e44f09a9aef18eb5806659e3d2a06 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 1 May 2014 10:01:45 -0700 Subject: [PATCH 013/662] Fix combo of compass-import-once and sass-globs. Closes middleman/middleman-sprockets#56 --- .../lib/middleman-core/renderers/sass.rb | 29 +++++++++++++++++++ middleman/middleman.gemspec | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 9165db23..bf1578b7 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -1,6 +1,35 @@ require 'sass' require 'compass/import-once' +GLOB = /\*|\[.+\]/ + +# Hack around broken sass globs when combined with import-once +# Targets compass-import-once 1.0.4 +# Tracking issue: https://github.com/chriseppstein/compass/issues/1529 +module Compass + module ImportOnce + module Importer + def find_relative(uri, base, options, *args) + if uri =~ GLOB + force_import = true + else + uri, force_import = handle_force_import(uri) + end + maybe_replace_with_dummy_engine(super(uri, base, options, *args), options, force_import) + end + + def find(uri, options, *args) + if uri =~ GLOB + force_import = true + else + uri, force_import = handle_force_import(uri) + end + maybe_replace_with_dummy_engine(super(uri, options, *args), options, force_import) + end + end + end +end + module Middleman module Renderers # Sass renderer diff --git a/middleman/middleman.gemspec b/middleman/middleman.gemspec index 2e176267..506fc640 100644 --- a/middleman/middleman.gemspec +++ b/middleman/middleman.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| s.add_dependency("middleman-sprockets", ">= 3.1.2") s.add_dependency("haml", [">= 4.0.5"]) s.add_dependency("sass", [">= 3.2.17", "< 4.0"]) - s.add_dependency("compass-import-once", ["~> 1.0.4"]) + s.add_dependency("compass-import-once", ["1.0.4"]) s.add_dependency("compass", [">= 0.12.4"]) s.add_dependency("uglifier", ["~> 2.5"]) s.add_dependency("coffee-script", ["~> 2.2.0"]) From d1d3e8dba65a22bef736efde644f7ebd4aa8501d Mon Sep 17 00:00:00 2001 From: 747 <747.neutron+ghub@gmail.com> Date: Fri, 2 May 2014 05:53:59 +0900 Subject: [PATCH 014/662] add tests on eponymous parent traversal --- middleman-core/features/more-sitemap_traversal.feature | 10 ++++++++++ middleman-core/features/sitemap_traversal.feature | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/middleman-core/features/more-sitemap_traversal.feature b/middleman-core/features/more-sitemap_traversal.feature index 224c2b8a..f935fbf0 100644 --- a/middleman-core/features/more-sitemap_traversal.feature +++ b/middleman-core/features/more-sitemap_traversal.feature @@ -71,3 +71,13 @@ Feature: Step through sitemap as a tree (more) Then I should see "Child: directory-indexed/sibling2.html" Then I should see "Child: directory-indexed/sub2/index.html" Then I should see "Sibling: root.html" + + Scenario: Child pages can see their parent and siblings too in named directory + Given the Server is running at "more-traversal-app" + When I go to "/directory-indexed/sibling" + Then I should see "Path: directory-indexed/sibling.html" + Then I should see "Parent: directory-indexed.html" + Then I should see "Sibling: directory-indexed/fake.html" + Then I should see "Sibling: directory-indexed/fake2.html" + Then I should see "Sibling: directory-indexed/sibling2.html" + Then I should see "Sibling: directory-indexed/sub2/index.html" diff --git a/middleman-core/features/sitemap_traversal.feature b/middleman-core/features/sitemap_traversal.feature index 828a2507..d2fe581c 100644 --- a/middleman-core/features/sitemap_traversal.feature +++ b/middleman-core/features/sitemap_traversal.feature @@ -71,3 +71,13 @@ Feature: Step through sitemap as a tree Then I should see "Child: directory-indexed/sibling2.html" Then I should see "Child: directory-indexed/sub2/index.html" Then I should see "Sibling: root.html" + + Scenario: Child pages can see their parent and siblings too in named directory + Given the Server is running at "traversal-app" + When I go to "/directory-indexed/sibling.html" + Then I should see "Path: directory-indexed/sibling.html" + Then I should see "Parent: directory-indexed.html" + Then I should see "Sibling: directory-indexed/fake.html" + Then I should see "Sibling: directory-indexed/fake2.html" + Then I should see "Sibling: directory-indexed/sibling2.html" + Then I should see "Sibling: directory-indexed/sub2/index.html" From ab238c32e56b2d55cbda797caf077b2f82a8b8af Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 19:37:48 -0700 Subject: [PATCH 015/662] Don't use data.page.title. This was a regression from 3.x --- .../default/source/layouts/layout.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb b/middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb index 365985b7..fffa9ad9 100644 --- a/middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb +++ b/middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb @@ -2,18 +2,18 @@ - + - + - <%= data.page.title || "The Middleman" %> - + <%= current_page.data.title || "The Middleman" %> + <%= stylesheet_link_tag "normalize", "all" %> <%= javascript_include_tag "all" %> - + <%= yield %> - \ No newline at end of file + From 5fc5e159758acab6b96ea5625c65c436818e5b33 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 19:06:51 -0700 Subject: [PATCH 016/662] Move methods for handling automatic extension discovery and rubygems enumeration into their own file. --- .../lib/middleman-core/auto_gem_extensions.rb | 55 ++++++++++++++++++ .../lib/middleman-core/extensions.rb | 57 ++----------------- .../lib/middleman-core/load_paths.rb | 1 + 3 files changed, 62 insertions(+), 51 deletions(-) create mode 100644 middleman-core/lib/middleman-core/auto_gem_extensions.rb diff --git a/middleman-core/lib/middleman-core/auto_gem_extensions.rb b/middleman-core/lib/middleman-core/auto_gem_extensions.rb new file mode 100644 index 00000000..430106b2 --- /dev/null +++ b/middleman-core/lib/middleman-core/auto_gem_extensions.rb @@ -0,0 +1,55 @@ +# Add module methods to the Middleman module that allow automatically loading +# extensions defined in gems based on the existance of a special file. This also +# adds a method for iterating over all the Gems on a system. +module Middleman + class << self + # Where to look in gems for extensions to auto-register. Since most extensions are + # called out in a Gemfile, this is really only useful for template extensions that get + # used by "middleman init". + EXTENSION_FILE = File.join('lib', 'middleman_extension.rb') unless const_defined?(:EXTENSION_FILE) + + # Automatically load extensions from available RubyGems + # which contain the EXTENSION_FILE + # + # @private + def load_extensions_in_path + require 'rubygems' + + extensions = rubygems_latest_specs.select do |spec| + spec_has_file?(spec, EXTENSION_FILE) + end + + extensions.each do |spec| + require spec.name + end + end + + # Backwards compatible means of finding all the latest gemspecs + # available on the system + # + # @private + # @return [Array] Array of latest Gem::Specification + def rubygems_latest_specs + # If newer Rubygems + if ::Gem::Specification.respond_to? :latest_specs + ::Gem::Specification.latest_specs(true) + else + ::Gem.source_index.latest_specs + end + end + + private + + # Where a given Gem::Specification has a specific file. Used + # to discover extensions. + # + # @private + # @param [Gem::Specification] spec + # @param [String] path Path to look for + # @return [Boolean] Whether the file exists + def spec_has_file?(spec, path) + full_path = File.join(spec.full_gem_path, path) + File.exist?(full_path) + end + end +end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index f775b99e..47157122 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -1,4 +1,10 @@ +require 'middleman-core/extension' + module Middleman + # The Extensions module is used to handle global registration and loading of Middleman Extensions. + # + # The application-facing extension API (activate, etc) is in Middleman::CoreExtensions::Extensions in + # middleman-core/core_extensions/extensions.rb. module Extensions class << self def registered @@ -66,55 +72,4 @@ module Middleman end end end - - # Where to look in gems for extensions to auto-register. Since most extensions are - # called out in a Gemfile, this is really only useful for template extensions that get - # used by "middleman init". - EXTENSION_FILE = File.join('lib', 'middleman_extension.rb') unless const_defined?(:EXTENSION_FILE) - - class << self - # Automatically load extensions from available RubyGems - # which contain the EXTENSION_FILE - # - # @private - def load_extensions_in_path - require 'rubygems' - - extensions = rubygems_latest_specs.select do |spec| - spec_has_file?(spec, EXTENSION_FILE) - end - - extensions.each do |spec| - require spec.name - end - end - - # Backwards compatible means of finding all the latest gemspecs - # available on the system - # - # @private - # @return [Array] Array of latest Gem::Specification - def rubygems_latest_specs - # If newer Rubygems - if ::Gem::Specification.respond_to? :latest_specs - ::Gem::Specification.latest_specs(true) - else - ::Gem.source_index.latest_specs - end - end - - # Where a given Gem::Specification has a specific file. Used - # to discover extensions. - # - # @private - # @param [Gem::Specification] spec - # @param [String] path Path to look for - # @return [Boolean] Whether the file exists - def spec_has_file?(spec, path) - full_path = File.join(spec.full_gem_path, path) - File.exist?(full_path) - end - end end - -require 'middleman-core/extension' diff --git a/middleman-core/lib/middleman-core/load_paths.rb b/middleman-core/lib/middleman-core/load_paths.rb index 68defc69..36c32704 100644 --- a/middleman-core/lib/middleman-core/load_paths.rb +++ b/middleman-core/lib/middleman-core/load_paths.rb @@ -1,5 +1,6 @@ # Core Pathname library used for traversal require 'pathname' +require 'middleman-core/auto_gem_extensions' module Middleman class << self From d179343ce7259f7682170a7bec188dc2332dc7e4 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 19:33:57 -0700 Subject: [PATCH 017/662] Remove unused "activate" class method from Extension --- middleman-core/lib/middleman-core/extension.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 80865c3a..28ff8fcb 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -32,10 +32,6 @@ module Middleman self.defined_helpers += m end - def activate - new(::Middleman::Application) - end - def clear_after_extension_callbacks @_extension_activation_callbacks = {} end @@ -155,6 +151,7 @@ module Middleman end end end + end end end From ef9da685de9620b95bd6c351f364189bb8aa25cf Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 19:37:04 -0700 Subject: [PATCH 018/662] Do away with InstanceMethods for CoreExtensions::Extensions --- .../core_extensions/extensions.rb | 183 +++++++++--------- 1 file changed, 90 insertions(+), 93 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index b48175c4..12d6cc7f 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -47,7 +47,6 @@ module Middleman app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] app.extend ClassMethods - app.send :include, InstanceMethods app.delegate :configure, to: :"self.class" end end @@ -56,121 +55,119 @@ module Middleman module ClassMethods # Add a callback to run in a specific environment # - # @param [String, Symbol] env The environment to run in + # @param [String, Symbol] env The environment to run in (:build, :development) # @return [void] def configure(env, &block) send("#{env}_config", &block) end end - # Instance methods - module InstanceMethods - # This method is available in the project's `config.rb`. - # It takes a underscore-separated symbol, finds the appropriate - # feature module and includes it. - # - # activate :lorem - # - # @param [Symbol, Module] ext Which extension to activate - # @return [void] - # rubocop:disable BlockNesting - def activate(ext, options={}, &block) - extension = ::Middleman::Extensions.load(ext) - logger.debug "== Activating: #{ext}" + # This method is available in the project's `config.rb`. + # It takes a underscore-separated symbol, finds the appropriate + # feature module and includes it. + # + # activate :lorem + # + # @param [Symbol, Module] ext Which extension to activate + # @return [void] + # rubocop:disable BlockNesting + def activate(ext, options={}, &block) + extension = ::Middleman::Extensions.load(ext) + logger.debug "== Activating: #{ext}" - if extension.supports_multiple_instances? - extensions[ext] ||= {} - key = "instance_#{extensions[ext].keys.length}" - extensions[ext][key] = extension.new(self.class, options, &block) + if extension.supports_multiple_instances? + extensions[ext] ||= {} + key = "instance_#{extensions[ext].keys.length}" + extensions[ext][key] = extension.new(self.class, options, &block) + else + if extensions[ext] + raise "#{ext} has already been activated and cannot be re-activated." else - if extensions[ext] - raise "#{ext} has already been activated and cannot be re-activated." - else - extensions[ext] = extension.new(self.class, options, &block) - end + extensions[ext] = extension.new(self.class, options, &block) + end + end + end + + # Access activated extensions + # + # @return [Hash] + def extensions + @extensions ||= {} + end + + # Load features before starting server + def initialize + super + + self.class.inst = self + + # Search the root of the project for required files + $LOAD_PATH.unshift(root) + + ::Middleman::Extension.clear_after_extension_callbacks + + if config[:autoload_sprockets] + begin + require 'middleman-sprockets' + activate(:sprockets) + rescue LoadError end end - # Access activated extensions - # - # @return [Hash] - def extensions - @extensions ||= {} + run_hook :initialized + + run_hook :before_configuration + + # Check for and evaluate local configuration + local_config = File.join(root, 'config.rb') + if File.exist? local_config + logger.debug '== Reading: Local config' + config_context.instance_eval File.read(local_config), local_config, 1 end - # Load features before starting server - def initialize - super + if build? + run_hook :build_config + config_context.execute_configure_callbacks(:build) + end - self.class.inst = self + if development? + run_hook :development_config + config_context.execute_configure_callbacks(:development) + end - # Search the root of the project for required files - $LOAD_PATH.unshift(root) + run_hook :instance_available - ::Middleman::Extension.clear_after_extension_callbacks + # This is for making the tests work - since the tests + # don't completely reload middleman, I18n.load_path can get + # polluted with paths from other test app directories that don't + # exist anymore. + if ENV['TEST'] + ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } + ::I18n.reload! + end - if config[:autoload_sprockets] - begin - require 'middleman-sprockets' - activate(:sprockets) - rescue LoadError + run_hook :after_configuration + config_context.execute_after_configuration_callbacks + + logger.debug 'Loaded extensions:' + extensions.each do |ext, klass| + if ext.is_a?(Hash) + ext.each do |k, _| + logger.debug "== Extension: #{k}" end + else + logger.debug "== Extension: #{ext}" end - run_hook :initialized - - run_hook :before_configuration - - # Check for and evaluate local configuration - local_config = File.join(root, 'config.rb') - if File.exist? local_config - logger.debug '== Reading: Local config' - config_context.instance_eval File.read(local_config), local_config, 1 - end - - if build? - run_hook :build_config - config_context.execute_configure_callbacks(:build) - end - - if development? - run_hook :development_config - config_context.execute_configure_callbacks(:development) - end - - run_hook :instance_available - - # This is for making the tests work - since the tests - # don't completely reload middleman, I18n.load_path can get - # polluted with paths from other test app directories that don't - # exist anymore. - if ENV['TEST'] - ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } - ::I18n.reload! - end - - run_hook :after_configuration - config_context.execute_after_configuration_callbacks - - logger.debug 'Loaded extensions:' - extensions.each do |ext, klass| - if ext.is_a?(Hash) - ext.each do |k, _| - logger.debug "== Extension: #{k}" - end - else - logger.debug "== Extension: #{ext}" + if klass.is_a?(::Middleman::Extension) + # Forward Extension helpers to TemplateContext + (klass.class.defined_helpers || []).each do |m| + @template_context_class.send(:include, m) end - if klass.is_a?(::Middleman::Extension) - # Forward Extension helpers to TemplateContext - (klass.class.defined_helpers || []).each do |m| - @template_context_class.send(:include, m) - end - - ::Middleman::Extension.activated_extension(klass) - end + ::Middleman::Extension.activated_extension(klass) end + end end end From 6515f018003635108915d0a6e19c354494e92659 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 20:16:37 -0700 Subject: [PATCH 019/662] Extension setup methods should be private, not protected --- middleman-core/lib/middleman-core/extension.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 28ff8fcb..627712f3 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -81,7 +81,7 @@ module Middleman end end - protected + private def setup_options(options_hash) @options = self.class.config.dup @@ -151,7 +151,6 @@ module Middleman end end end - end end end From b79a74b35b1de6a6b7c666ab410a34c58b7858a7 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 23:47:04 -0700 Subject: [PATCH 020/662] Improve documentation for Middleman::Extension --- .yardopts | 3 +- middleman-cli/.yardopts | 3 +- middleman-core/.yardopts | 3 +- .../lib/middleman-core/configuration.rb | 8 +- .../core_extensions/extensions.rb | 31 ---- .../middleman-core/core_extensions/request.rb | 3 - .../lib/middleman-core/extension.rb | 166 +++++++++++++++++- .../lib/middleman-core/sitemap/store.rb | 13 +- .../lib/middleman-core/template_context.rb | 1 - middleman-templates/.yardopts | 3 +- 10 files changed, 179 insertions(+), 55 deletions(-) diff --git a/.yardopts b/.yardopts index 980f0e4c..8a5eba70 100644 --- a/.yardopts +++ b/.yardopts @@ -7,4 +7,5 @@ middleman-*/lib/**/*.rb --exclude middleman-cli/lib/middleman-cli/templates/shared/ --exclude middleman-cli/lib/middleman-cli/templates/extension/ --no-private ---hide-void-return \ No newline at end of file +--hide-void-return +--markup=markdown \ No newline at end of file diff --git a/middleman-cli/.yardopts b/middleman-cli/.yardopts index 47ae041b..b816052e 100644 --- a/middleman-cli/.yardopts +++ b/middleman-cli/.yardopts @@ -5,4 +5,5 @@ lib/**/*.rb --exclude lib/middleman-cli/templates/shared/ --exclude lib/middleman-cli/templates/extension/ --no-private ---hide-void-return \ No newline at end of file +--hide-void-return +--markup=markdown \ No newline at end of file diff --git a/middleman-core/.yardopts b/middleman-core/.yardopts index 29455a55..ee16b7ac 100644 --- a/middleman-core/.yardopts +++ b/middleman-core/.yardopts @@ -2,4 +2,5 @@ lib/**/*.rb --exclude lib/vendored-middleman-deps/ --exclude lib/middleman-core/step_definitions --no-private ---hide-void-return \ No newline at end of file +--hide-void-return +--markup=markdown \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index dce449e8..7c39a405 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -82,9 +82,11 @@ module Middleman # Define a new setting, with optional default and user-friendly description. # Once the configuration manager is finalized, no new settings may be defined. # - # @param [Symbol] key - # @param [Object] default - # @param [String] description + # @example + # config.define_setting :compress, false, 'Whether to compress the output' + # @param [Symbol] key The name of the option + # @param [Object] default The default value for the option + # @param [String] description A human-readable description of what the option does # @return [ConfigSetting] def define_setting(key, default=nil, description=nil) raise "Setting #{key} doesn't exist" if @finalized diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 12d6cc7f..8aad51f9 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -1,34 +1,3 @@ -# Middleman provides an extension API which allows you to hook into the -# lifecycle of a page request, or static build, and manipulate the output. -# Internal to Middleman, these extensions are called "features," but we use -# the exact same API as is made available to the public. -# -# A Middleman extension looks like this: -# -# module MyExtension -# class << self -# def registered(app) -# # My Code -# end -# end -# end -# -# In your `config.rb`, you must load your extension (if it is not defined in -# that file) and call `activate`. -# -# require "my_extension" -# activate MyExtension -# -# This will call the `registered` method in your extension and provide you -# with the `app` parameter which is a Middleman::Application context. From here -# you can choose to respond to requests for certain paths or simply attach -# Rack middleware to the stack. -# -# The built-in features cover a wide range of functions. Some provide helper -# methods to use in your views. Some modify the output on-the-fly. And some -# apply computationally-intensive changes to your final build files. - -# Namespace extensions module module Middleman module CoreExtensions module Extensions diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index c8155198..3e822715 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -56,8 +56,6 @@ module Middleman # Set the shared instance # # @private - # @param [Middleman::Application] inst - # @return [void] attr_writer :inst # Return built Rack app @@ -188,7 +186,6 @@ module Middleman # message. # # @param env - # @param [Rack::Request] req # @param [Rack::Response] res def process_request(env, _, res) start_time = Time.now diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 627712f3..f4248657 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -2,60 +2,179 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' module Middleman + # Middleman's Extension API provides the ability to add functionality to Middleman + # and to customize existing features. Internally, most features in Middleman are + # implemented as extensions. A good way to figure out how to write your own extension + # is to look at the source of the built-in extensions or popular extension gems like + # `middleman-blog` or `middleman-syntax`. + # + # The most basic extension looks like: + # + # class MyFeature < Middleman::Extension + # def initialize(app, options_hash={}, &block) + # super + # end + # end + # ::Middleman::Extensions.register(:my_feature, MyFeature) + # + # A more complicated example might look like: + # + # class MyFeature < Middleman::Extension + # option :my_option, 'cool', 'A very cool option' + # + # def initialize(app, options_hash={}, &block) + # super + # puts "My option is #{options.my_option}" + # end + # + # def after_configuration + # puts "The project has been configured" + # end + # + # def manipulate_resource_list(resources) + # resources.each do |resource| + # # Make all .jpg's get built or served with a .jpeg extension. + # if resource.ext == '.jpg' + # resource.destination_path = resource.destination_path.sub('.jpg', '.jpeg') + # end + # end + # end + # end + # + # ::Middleman::Extensions.register :my_feature do + # MyFeature + # end + # + # Extensions can add helpers (via {Extension.helpers}), add to the sitemap or change it (via {#manipulate_resource_list}), or run + # arbitrary code at different parts of the Middleman application's lifecycle. They can have options (defined via {Extension.option} and accessed via {#options}). + # + # Common lifecycle events can be handled by extensions simply by implementing an appropriately-named method: + # + # * {#after_configuration} + # * {#after_build} + # * {#before_build} + # * {#instance_available} + # + # There are also some less common hooks that can be listened to from within an extension's `initialize` method: + # + # * `app.before_render {|body, path, locs, template_class| ... }` - Manipulate template sources before they are rendered. + # * `app.after_render {|content, path, locs, template_class| ... }` - Manipulate output text after a template has been rendered. It is also common to install a Rack middleware to do this instead. + # * `app.ready { ... }` - Run code once Middleman is ready to serve or build files (after `after_configuration`). + # * `app.compass_config { |compass_config| ... }` - Manipulate the Compass configuration after it has been set up. + # + # @see http://middlemanapp.com/advanced/custom/ Middleman Custom Extensions Documentation class Extension + # @!attribute supports_multiple_instances + # @!scope class + # @return [Boolean] whether or not an extension can be activated multiple times, generating multiple instances of the extension. + # By default extensions can only be activated once in a project. This is an advanced option. class_attribute :supports_multiple_instances, instance_reader: false, instance_writer: false + + # @!attribute defined_helpers + # @!scope class + # @api private + # @return [Array] a list of all the helper modules this extension provides. Set these using {#helpers}. class_attribute :defined_helpers, instance_reader: false, instance_writer: false + + # @!attribute ext_name + # @!scope class + # @return [Symbol] the name this extension is registered under. This is the symbol used to activate the extension. class_attribute :ext_name, instance_reader: false, instance_writer: false class << self + # @api private + # @return [Middleman::Configuration::ConfigurationManager] The defined options for this extension. def config @_config ||= ::Middleman::Configuration::ConfigurationManager.new end + # Add an option to this extension. + # @see Middleman::Configuration::ConfigurationManager#define_setting + # @example + # option :compress, false, 'Whether to compress the output' + # @param [Symbol] key The name of the option + # @param [Object] default The default value for the option + # @param [String] description A human-readable description of what the option does def option(key, default=nil, description=nil) config.define_setting(key, default, description) end - # Add helpers to the global Middleman application. + # Declare helpers to be added the global Middleman application. # This accepts either a list of modules to add on behalf # of this extension, or a block whose contents will all # be used as helpers in a new module. - def helpers(*m, &block) + # @example With a block: + # helpers do + # def my_helper + # "I helped!" + # end + # end + # @example With modules: + # helpers FancyHelpers, PlainHelpers + # @param [Array] modules An optional list of modules to add as helpers + # @param [Proc] block A block which will be evaluated to create a new helper module + # @return [void] + def helpers(*modules, &block) self.defined_helpers ||= [] if block_given? mod = Module.new mod.module_eval(&block) - m = [mod] + modules = [mod] end - self.defined_helpers += m + self.defined_helpers += modules end + # Reset all {Extension.after_extension_activated} callbacks. + # @api private + # @return [void] def clear_after_extension_callbacks @_extension_activation_callbacks = {} end + # Register to run a block after a named extension is activated. + # @param [Symbol] name The name the extension was registered under + # @param [Proc] block A callback to run when the named extension is activated + # @return [void] def after_extension_activated(name, &block) @_extension_activation_callbacks ||= {} @_extension_activation_callbacks[name] ||= [] @_extension_activation_callbacks[name] << block if block_given? end + # Notify that a particular extension has been activated and run all + # registered {Extension.after_extension_activated} callbacks. + # @api private + # @param [Middleman::Extension] instance Activated extension instance + # @return [void] def activated_extension(instance) name = instance.class.ext_name - return unless @_extension_activation_callbacks && @_extension_activation_callbacks[name] + return unless @_extension_activation_callbacks && @_extension_activation_callbacks.has_key?(name) @_extension_activation_callbacks[name].each do |block| block.arity == 1 ? block.call(instance) : block.call end end end - attr_accessor :options + # @return [Middleman::Configuration::ConfigurationManager] options for this extension instance. + attr_reader :options + + # @return [Middleman::Application] the Middleman application instance. attr_reader :app + # @!method after_extension_activated(name, &block) + # Register to run a block after a named extension is activated. + # @param [Symbol] name The name the extension was registered under + # @param [Proc] block A callback to run when the named extension is activated + # @return [void] delegate :after_extension_activated, to: :"::Middleman::Extension" + # Extensions are instantiated when they are activated. + # @param [Class] klass The Middleman::Application class + # @param [Hash] options_hash The raw options hash. Subclasses should not manipulate this directly - it will be turned into {#options}. + # @yield An optional block that can be used to customize options before the extension is activated. + # @yieldparam [Middleman::Configuration::ConfigurationManager] options Extension options def initialize(klass, options_hash={}, &block) @_helpers = [] @klass = klass @@ -70,6 +189,39 @@ module Middleman bind_after_build end + # @!method before_configuration + # Respond to the `before_configuration` event. + # If a `before_configuration` method is implemented, that method will be run before `config.rb` is run. + # @note Because most extensions are activated from within `config.rb`, they *will not run* any `before_configuration` hook. + + # @!method after_configuration + # Respond to the `after_configuration` event. + # If an `after_configuration` method is implemented, that method will be run before `config.rb` is run. + + # @!method before_build + # Respond to the `before_build` event. + # If an `before_build` method is implemented, that method will be run before the builder runs. + + # @!method after_build + # Respond to the `after_build` event. + # If an `after_build` method is implemented, that method will be run after the builder runs. + + # @!method instance_available + # Respond to the `instance_available` event. + # If an `instance_available` method is implemented, that method will be run after `config.rb` is run and after environment-specific config blocks have been run, but before any `after_configuration` callbacks. + + # @!method manipulate_resource_list(resources) + # Manipulate the resource list by transforming or adding {Sitemap::Resource}s. + # Sitemap manipulation is a powerful way of interacting with a project, since it can modify each {Sitemap::Resource} or generate new {Sitemap::Resources}. This method is used in a pipeline where each sitemap manipulator is run in turn, with each one being fed the output of the previous manipulator. See the source of built-in Middleman extensions like {Middleman::Extensions::DirectoryIndexes} and {Middleman::Extensions::AssetHash} for examples of how to use this. + # @note This method *must* return the full set of resources, because its return value will be used as the new sitemap. + # @see http://middlemanapp.com/advanced/sitemap/ Sitemap Documentation + # @see Sitemap::Store + # @see Sitemap::Resource + # @param [Array] resources A list of all the resources known to the sitemap. + # @return [Array] The transformed list of resources. + + # Assign the app instance. Used internally. + # @api private def app=(app) @app = app @@ -83,6 +235,8 @@ module Middleman private + # @yield An optional block that can be used to customize options before the extension is activated. + # @yieldparam Middleman::Configuration::ConfigurationManager] options Extension options def setup_options(options_hash) @options = self.class.config.dup @options.finalize! diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index a987843c..816d94d5 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -57,21 +57,20 @@ module Middleman app.config_context.class.send :delegate, :sitemap, to: :app end - # Register a klass which can manipulate the main site map list. Best to register - # these in a before_configuration or after_configuration hook. + # Register an object which can transform the sitemap resource list. Best to register + # these in a `before_configuration` or `after_configuration` hook. # # @param [Symbol] name Name of the manipulator for debugging - # @param [Class, Module] inst Abstract namespace which can update the resource list + # @param [#manipulate_resource_list] manipulator Resource list manipulator # @return [void] - def register_resource_list_manipulator(name, inst, *) - @resource_list_manipulators << [name, inst] + def register_resource_list_manipulator(name, manipulator, *) + @resource_list_manipulators << [name, manipulator] rebuild_resource_list!(:registered_new) end # Rebuild the list of resources from scratch, using registed manipulators - # rubocop:disable UnusedMethodArgument # @return [void] - def rebuild_resource_list!(reason=nil) + def rebuild_resource_list!(_=nil) @lock.synchronize do @needs_sitemap_rebuild = true end diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index f2d4a4fb..81d405a8 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -60,7 +60,6 @@ module Middleman # Sinatra/Padrino compatible render method signature referenced by some view # helpers. Especially partials. # - # @param [String, Symbol] engine # @param [String, Symbol] data # @param [Hash] options # @return [String] diff --git a/middleman-templates/.yardopts b/middleman-templates/.yardopts index 72efde46..fcefc936 100644 --- a/middleman-templates/.yardopts +++ b/middleman-templates/.yardopts @@ -1,4 +1,5 @@ lib/**/*.rb --exclude lib/middleman-templates --no-private ---hide-void-return \ No newline at end of file +--hide-void-return +--markup=markdown \ No newline at end of file From 3f0373adf268298c99a64a7f5f614705c3d0d92f Mon Sep 17 00:00:00 2001 From: bootstraponline Date: Sun, 11 May 2014 13:44:58 -0400 Subject: [PATCH 021/662] Fix after_render Example usage from config.rb: after_render do |content, path, locs, template_class| # restore character entities such as &#96; content ||= '' content.gsub! '&', '&' content end --- .../lib/middleman-core/core_extensions/rendering.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index f6737724..98c0b600 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -265,7 +265,12 @@ module Middleman # Allow hooks to manipulate the result after render self.class.callbacks_for_hook(:after_render).each do |callback| - content = callback.call(content, path, locs, template_class) + # Uber::Options::Value doesn't respond to call + if callback.respond_to?(:call) + content = callback.call(content, path, locs, template_class) + elsif callback.respond_to?(:evaluate) + content = callback.evaluate(self, content, path, locs, template_class) + end end output = ::ActiveSupport::SafeBuffer.new '' From 2312f875e6997c5b35c84d18e413ddf948b81ab0 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 12 May 2014 00:05:22 -0700 Subject: [PATCH 022/662] Revert "Add :format and :keep_original options to :asset_hash. Closes #1257" This reverts commit 1f98d0f4f01cde226df3e1f06d25b839fc34d753. Conflicts: middleman-core/lib/middleman-core/extensions/asset_hash.rb --- CHANGELOG.md | 1 - middleman-core/features/asset_hash.feature | 54 ------------------- .../middleman-core/extensions/asset_hash.rb | 48 +++-------------- 3 files changed, 8 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cbd238b..124421f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,6 @@ master * Remove deprecated `request` instance * Remove old module-style extension support * Placed all `config.rb` evaluation inside the `ConfigContext` class -* Add :format and :keep_original options to :asset_hash 3.3.0-3.3.2 === diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 936126e4..59c92d29 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -34,60 +34,6 @@ Feature: Assets get a file hash appended to their and references to them are upd 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"' - Scenario: Keep Originals - Given a fixture app "asset-hash-app" - And a file named "config.rb" with: - """ - activate :asset_hash, :keep_original => true - """ - And a successfully built app at "asset-hash-app" - When I cd to "build" - Then the following files should exist: - | images/100px-1242c368.png | - | images/100px-5fd6fb90.jpg | - | images/100px-5fd6fb90.gif | - | javascripts/application-1d8d5276.js | - | stylesheets/site-171eb3c0.css | - | images/100px.png | - | images/100px.jpg | - | images/100px.gif | - | javascripts/application.js | - | stylesheets/site.css | - - Scenario: Custom format - Given a fixture app "asset-hash-app" - And a file named "config.rb" with: - """ - activate :asset_hash, :format => ':basename-.-:digest.:ext' - activate :directory_indexes - """ - And a successfully built app at "asset-hash-app" - When I cd to "build" - Then the following files should exist: - | images/100px-.-1242c368.png | - | images/100px-.-5fd6fb90.jpg | - | images/100px-.-5fd6fb90.gif | - | javascripts/application-.-1d8d5276.js | - | stylesheets/site-.-171eb3c0.css | - And the following files should not exist: - | images/100px.png | - | images/100px.jpg | - | images/100px.gif | - | javascripts/application.js | - | stylesheets/site.css | - - And the file "javascripts/application-.-1d8d5276.js" should contain "img.src = '/images/100px-.-5fd6fb90.jpg'" - And the file "stylesheets/site-.-171eb3c0.css" should contain "background-image: url('/images/100px-.-5fd6fb90.jpg')" - And the file "index.html" should contain 'href="/stylesheets/site-.-171eb3c0.css"' - 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-.-171eb3c0.css"' - 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-.-171eb3c0.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"' - Scenario: Hashed assets work in preview server Given the Server is running at "asset-hash-app" When I go to "/" diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index 3a440cf0..f8aee261 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -3,8 +3,6 @@ require 'middleman-core/util' class Middleman::Extensions::AssetHash < ::Middleman::Extension option :exts, %w(.jpg .jpeg .png .gif .js .css .otf .woff .eot .ttf .svg), 'List of extensions that get asset hashes appended to them.' option :ignore, [], 'Regexes of filenames to skip adding asset hashes to' - option :format, ':basename-:digest.:ext', 'Format of renamed file.' - option :keep_original, false, 'Whether the original file name should exist along side the hashed version.' def initialize(app, options_hash={}, &block) super @@ -26,12 +24,10 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension def manipulate_resource_list(resources) @rack_client = ::Rack::MockRequest.new(app.class.to_rack_app) - proxied_renames = [] - # Process resources in order: binary images and fonts, then SVG, then JS/CSS. # This is so by the time we get around to the text files (which may reference # images and fonts) the static assets' hashes are already calculated. - sorted_resources = resources.sort_by do |a| + resources.sort_by do |a| if %w(.svg).include? a.ext 0 elsif %w(.js .css).include? a.ext @@ -39,49 +35,21 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension else -1 end - end - - sorted_resources.each do |resource| - next unless options.exts.include?(resource.ext) - next if ignored_resource?(resource) - next if resource.ignored? - - new_name = hashed_filename(resource) - - if options.keep_original - p = ::Middleman::Sitemap::Resource.new( - app.sitemap, - new_name - ) - p.proxy_to(resource.path) - - proxied_renames << p - else - resource.destination_path = new_name - end - end - - sorted_resources + proxied_renames + end.each(&method(:manipulate_single_resource)) end - def hashed_filename(resource) + def manipulate_single_resource(resource) + return unless options.exts.include?(resource.ext) + return if ignored_resource?(resource) + return if resource.ignored? + # Render through the Rack interface so middleware and mounted apps get a shot response = @rack_client.get(URI.escape(resource.destination_path), 'bypass_asset_hash' => 'true') raise "#{resource.path} should be in the sitemap!" unless response.status == 200 digest = Digest::SHA1.hexdigest(response.body)[0..7] - file_name = File.basename(resource.destination_path) - path = resource.destination_path.split(file_name).first - - ext_without_leading_period = resource.ext.sub(/^\./, '') - - base_name = File.basename(file_name, resource.ext) - - path + options.format.dup - .gsub(/:basename/, base_name) - .gsub(/:digest/, digest) - .gsub(/:ext/, ext_without_leading_period) + resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } end def ignored_resource?(resource) From 6b10d9d428b6b3073e18434917712a2de8fd9c06 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 12 May 2014 00:00:53 -0700 Subject: [PATCH 023/662] Add the ability to set a priority order for sitemap resource list manipulators. This allows us to do things like forcing :directory_indexes to always run last, alleviating the problem of the sitemap output differing depending on when you activate your extensions. --- middleman-core/lib/middleman-core/extension.rb | 10 ++++++++-- .../extensions/directory_indexes.rb | 4 ++++ .../lib/middleman-core/sitemap/store.rb | 18 ++++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index f4248657..cff75105 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -81,6 +81,12 @@ module Middleman # @return [Symbol] the name this extension is registered under. This is the symbol used to activate the extension. class_attribute :ext_name, instance_reader: false, instance_writer: false + # @!attribute resource_list_manipulator_priority + # @!scope class + # @return [Numeric] the priority for this extension's `manipulate_resource_list` method, if it has one. + # @see Middleman::Sitemap::Store#register_resource_list_manipulator + class_attribute :resource_list_manipulator_priority, instance_reader: false, instance_writer: false + class << self # @api private # @return [Middleman::Configuration::ConfigurationManager] The defined options for this extension. @@ -150,7 +156,7 @@ module Middleman # @return [void] def activated_extension(instance) name = instance.class.ext_name - return unless @_extension_activation_callbacks && @_extension_activation_callbacks.has_key?(name) + return unless @_extension_activation_callbacks && @_extension_activation_callbacks.key?(name) @_extension_activation_callbacks[name].each do |block| block.arity == 1 ? block.call(instance) : block.call end @@ -276,7 +282,7 @@ module Middleman # rubocop:disable IfUnlessModifier if ext.respond_to?(:manipulate_resource_list) - ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext) + ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext, ext.class.resource_list_manipulator_priority) end end end diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 5c14f723..68e9f958 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -1,5 +1,9 @@ # Directory Indexes extension class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension + # This should run after most other sitemap manipulators so that it + # gets a chance to modify any new resources that get added. + self.resource_list_manipulator_priority = 100 + # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 816d94d5..992cae00 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -62,9 +62,19 @@ module Middleman # # @param [Symbol] name Name of the manipulator for debugging # @param [#manipulate_resource_list] manipulator Resource list manipulator + # @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators. # @return [void] - def register_resource_list_manipulator(name, manipulator, *) - @resource_list_manipulators << [name, manipulator] + def register_resource_list_manipulator(name, manipulator, priority=50) + # The third argument used to be a boolean - handle those who still pass one + priority = 50 unless priority.is_a? Numeric + @resource_list_manipulators << [name, manipulator, priority] + # The index trick is used so that the sort is stable - manipulators with the same priority + # will always be ordered in the same order as they were registered. + n = 0 + @resource_list_manipulators = @resource_list_manipulators.sort_by do |m| + n += 1 + [m[2], n] + end rebuild_resource_list!(:registered_new) end @@ -212,8 +222,8 @@ module Middleman @app.logger.debug '== Rebuilding resource list' - @resources = @resource_list_manipulators.reduce([]) do |result, (_, inst)| - newres = inst.manipulate_resource_list(result) + @resources = @resource_list_manipulators.reduce([]) do |result, (_, manipulator, _)| + newres = manipulator.manipulate_resource_list(result) # Reset lookup cache reset_lookup_cache! From 9887fe510ce46662356c76c18880d2f9653850ee Mon Sep 17 00:00:00 2001 From: adamjonas Date: Thu, 15 May 2014 11:51:42 -0400 Subject: [PATCH 024/662] update rspec should syntax to expect --- middleman-core/spec/middleman-core/binary_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/spec/middleman-core/binary_spec.rb b/middleman-core/spec/middleman-core/binary_spec.rb index 1643bd93..79944331 100644 --- a/middleman-core/spec/middleman-core/binary_spec.rb +++ b/middleman-core/spec/middleman-core/binary_spec.rb @@ -3,13 +3,13 @@ require 'middleman-core/util' describe "Middleman::Util#binary?" do %w(plain.txt unicode.txt unicode).each do |file| it "recognizes #{file} as not binary" do - Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}")).should be_false + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_false end end %w(middleman.png middleman stars.svgz).each do |file| it "recognizes #{file} as binary" do - Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}")).should be_true + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_true end end end From 82636e3596ac9cd7e932a3b70077cc6565f335b6 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 15 May 2014 23:30:49 -0700 Subject: [PATCH 025/662] Fixes to deal with Padrino 0.12.2 release --- middleman-core/features/helpers_select_tag.feature | 14 ++++++-------- .../lib/middleman-core/renderers/haml.rb | 5 ++++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/middleman-core/features/helpers_select_tag.feature b/middleman-core/features/helpers_select_tag.feature index 54bf1e54..fff51c74 100644 --- a/middleman-core/features/helpers_select_tag.feature +++ b/middleman-core/features/helpers_select_tag.feature @@ -9,11 +9,9 @@ Feature: select_tag helper """ And the Server is running at "indexable-app" When I go to "/select_tag.html" - Then I should see: - """ - - """ + Then I should see '' diff --git a/middleman-core/lib/middleman-core/renderers/haml.rb b/middleman-core/lib/middleman-core/renderers/haml.rb index 8eb3a868..fc75a4e8 100644 --- a/middleman-core/lib/middleman-core/renderers/haml.rb +++ b/middleman-core/lib/middleman-core/renderers/haml.rb @@ -1,6 +1,9 @@ # Require gem require 'haml' +# Require padrino-helpers now so that we get a chance to replace their renderer with ours in Tilt. +require 'padrino-helpers' + module SafeTemplate def render(*) super.html_safe @@ -41,7 +44,7 @@ module Middleman class << self # Once registered def registered(_) - ::Tilt.prefer(::Middleman::Renderers::HamlTemplate, 'haml') + ::Tilt.prefer(::Middleman::Renderers::HamlTemplate, :haml) # Add haml helpers to context ::Middleman::TemplateContext.send :include, ::Haml::Helpers From f29994e25aca7d6240fa3708e80e581b17d8d30b Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 15 May 2014 23:30:49 -0700 Subject: [PATCH 026/662] Fix tests after Padrino 0.12.2 release --- middleman-core/features/helpers_select_tag.feature | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/middleman-core/features/helpers_select_tag.feature b/middleman-core/features/helpers_select_tag.feature index 54bf1e54..fff51c74 100644 --- a/middleman-core/features/helpers_select_tag.feature +++ b/middleman-core/features/helpers_select_tag.feature @@ -9,11 +9,9 @@ Feature: select_tag helper """ And the Server is running at "indexable-app" When I go to "/select_tag.html" - Then I should see: - """ - - """ + Then I should see '' From dc33f6b3fade71b26bbc3c7b1cb56f2d3abb45a1 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 15 May 2014 23:55:39 -0700 Subject: [PATCH 027/662] Fix before_render after change to hooks-0.4.0. Related to #1278. --- .../lib/middleman-core/core_extensions/rendering.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 98c0b600..2b5347a9 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -251,7 +251,12 @@ module Middleman 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) + # Uber::Options::Value doesn't respond to call + newbody = if callback.respond_to?(:call) + callback.call(body, path, locs, template_class) + elsif callback.respond_to?(:evaluate) + callback.evaluate(self, body, path, locs, template_class) + end body = newbody if newbody # Allow the callback to return nil to skip it end @@ -266,11 +271,12 @@ module Middleman # Allow hooks to manipulate the result after render self.class.callbacks_for_hook(:after_render).each do |callback| # Uber::Options::Value doesn't respond to call - if callback.respond_to?(:call) + newcontent = if callback.respond_to?(:call) content = callback.call(content, path, locs, template_class) elsif callback.respond_to?(:evaluate) content = callback.evaluate(self, content, path, locs, template_class) end + content = newcontent if newcontent # Allow the callback to return nil to skip it end output = ::ActiveSupport::SafeBuffer.new '' From 1a7da200d1590cb98239c0c2ca5d4cb05bf189bf Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 15 May 2014 23:58:50 -0700 Subject: [PATCH 028/662] Fix before_render after change to hooks-0.4.0. Related to #1278. --- middleman-core/lib/middleman-core/file_renderer.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index e103fcd1..f3ee6d73 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -53,7 +53,11 @@ module Middleman template_class = ::Tilt[path] # Allow hooks to manipulate the template before render @app.class.callbacks_for_hook(:before_render).each do |callback| - newbody = callback.call(body, path, locs, template_class) + newbody = if callback.respond_to?(:call) + callback.call(body, path, locs, template_class) + elsif callback.respond_to?(:evaluate) + callback.evaluate(self, body, path, locs, template_class) + end body = newbody if newbody # Allow the callback to return nil to skip it end @@ -68,11 +72,12 @@ module Middleman # Allow hooks to manipulate the result after render @app.class.callbacks_for_hook(:after_render).each do |callback| # Uber::Options::Value doesn't respond to call - if callback.respond_to?(:call) - content = callback.call(content, path, locs, template_class) + newcontent = if callback.respond_to?(:call) + callback.call(content, path, locs, template_class) elsif callback.respond_to?(:evaluate) - content = callback.evaluate(self, content, path, locs, template_class) + callback.evaluate(self, content, path, locs, template_class) end + content = newcontent if newcontent # Allow the callback to return nil to skip it end output = ::ActiveSupport::SafeBuffer.new '' From 610716ee805c642879679991138fd73fb756ecc7 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 22 May 2014 19:20:43 +0900 Subject: [PATCH 029/662] Work around possible mutable data issue #501 --- .../lib/middleman-core/core_extensions/rendering.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 2b5347a9..a6b21fdd 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -222,6 +222,10 @@ module Middleman def render_individual_file(path, locs={}, opts={}, context=self, &block) path = path.to_s + # Mutability is FUN! + # Try to work around: https://github.com/middleman/middleman/issues/501 + locs = locs.dup + # Detect the remdering engine from the extension extension = File.extname(path) engine = extension[1..-1].to_sym From f60a49d2ce70a9b09534474b65cd057cc12a71a0 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 22 May 2014 21:48:37 -0700 Subject: [PATCH 030/662] Improve documentation and variable naming for Middleman::Extensions --- .../lib/middleman-core/extensions.rb | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 47157122..70d3026c 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -3,72 +3,80 @@ require 'middleman-core/extension' module Middleman # The Extensions module is used to handle global registration and loading of Middleman Extensions. # - # The application-facing extension API (activate, etc) is in Middleman::CoreExtensions::Extensions in - # middleman-core/core_extensions/extensions.rb. + # The application-facing extension API ({Middleman::CoreExtensions::Extensions#activate activate}, etc) is in {Middleman::CoreExtensions::Extensions} in + # `middleman-core/core_extensions/extensions.rb`. module Extensions + @registered = {} + class << self - def registered - @_registered ||= {} - end + # A hash of all registered extensions. Registered extensions are not necessarily active - this + # is the set of all extensions that are known to Middleman. + # @return [Hash{Symbol => Class, Proc}] A directory of known extensions indexed by the name they were registered under. The value may be a Proc, which can be lazily called to return an extension class. + attr_reader :registered # Register a new extension. Choose a name which will be - # used to activate the extension in config.rb, like this: + # used to activate the extension in `config.rb`, like this: # # activate :my_extension # - # Provide your extension module either as the namespace - # parameter: + # Provide your extension class either as the second parameter: # # Middleman::Extensions.register(:my_extension, MyExtension) # - # Or return it from a block: + # Or better, return it from a block, which allows you to lazily require the implementation: # - # Middleman::Extensions.register(:my_extension) do + # Middleman::Extensions.register :my_extension do # require 'my_extension' # MyExtension # end # # @param [Symbol] name The name of the extension - # @param [Module] namespace The extension module + # @param [Class] extension_class The extension class (Must inherit from {Middleman::Extension}) # @yield Instead of passing a module in namespace, you can provide - # a block which returns your extension module. This gives + # a block which returns your extension class. This gives # you the ability to require other files only when the - # extension is activated. - def register(name, namespace=nil, &block) + # extension is first activated. + # @return [void] + def register(name, extension_class=nil, &block) + raise "Extension name must be a symbol" unless name.is_a?(Symbol) # If we've already got an extension registered under this name, bail out - raise "There is already an extension registered with the name '#{name}'" if registered.key?(name.to_sym) + raise "There is already an extension registered with the name '#{name}'" if registered.key?(name) - registered[name.to_sym] = if block_given? + registered[name] = if block_given? block - elsif namespace && namespace.ancestors.include?(::Middleman::Extension) - namespace + 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' end end - # Load an extension by name, evaluating block definition if necessary. + # @api private + # Load an extension by name, lazily evaluating the block provided to {#register} if necessary. + # @param [Symbol] name The name of the extension + # @return [Class] A {Middleman::Extension} class implementing the extension + # def load(name) - name = name.to_sym + raise "Extension name must be a symbol" unless name.is_a?(Symbol) unless registered.key?(name) raise "Unknown Extension: #{name}. Check the name and make sure you have referenced the extension's gem in your Gemfile." end - extension = registered[name] - if extension.is_a?(Proc) - extension = extension.call - registered[name] = extension + extension_class = registered[name] + if extension_class.is_a?(Proc) + extension_class = extension_class.call + registered[name] = extension_class end - unless extension.ancestors.include?(::Middleman::Extension) + unless extension_class.ancestors.include?(::Middleman::Extension) raise "Tried to activate old-style extension: #{name}. They are no longer supported." end # Set the extension's name to whatever it was registered as. - extension.ext_name = name + extension_class.ext_name = name - extension + extension_class end end end From 18da7bb6920d603fde71726a70dd86383989caf9 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 22 May 2014 22:36:01 -0700 Subject: [PATCH 031/662] Improve documentation and mildly clean up core_extensions/extensions.rb --- .../core_extensions/extensions.rb | 91 +++++++++++-------- .../lib/middleman-core/extensions.rb | 4 +- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 8aad51f9..104e060a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -1,28 +1,34 @@ module Middleman module CoreExtensions + # The Extensions core module provides basic configurability to Middleman projects: + # + # * It loads and evaluates `config.rb`. + # * It defines lifecycle hooks for extensions and `config.rb` to use. + # * It provides the {#activate} method for use in `config.rb`. module Extensions - # Register extension - class << self - # @private - def included(app) - app.define_hook :initialized - app.define_hook :instance_available - app.define_hook :after_configuration - app.define_hook :before_configuration - app.define_hook :build_config - app.define_hook :development_config + def self.included(app) + app.define_hook :initialized + app.define_hook :instance_available + app.define_hook :after_configuration + app.define_hook :before_configuration + app.define_hook :build_config + app.define_hook :development_config - app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' - app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] + app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' + app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - app.extend ClassMethods - app.delegate :configure, to: :"self.class" - end + app.extend ClassMethods + app.delegate :configure, to: :"self.class" end - # Class methods module ClassMethods - # Add a callback to run in a specific environment + # Register a block to run only in a specific environment. + # + # @example + # # Only minify when building + # configure :build do + # activate :minify_javascript + # end # # @param [String, Symbol] env The environment to run in (:build, :development) # @return [void] @@ -31,47 +37,55 @@ module Middleman end end - # This method is available in the project's `config.rb`. - # It takes a underscore-separated symbol, finds the appropriate - # feature module and includes it. + # Activate an extension, optionally passing in options. + # This method is typically used from a project's `config.rb`. # + # @example Activate an extension with no options # activate :lorem # - # @param [Symbol, Module] ext Which extension to activate + # @example Activate an extension, with options + # activate :minify_javascript, inline: true + # + # @example Use a block to configure extension options + # activate :minify_javascript do |opts| + # opts.ignore += ['*-test.js'] + # end + # + # @param [Symbol] ext_name The name of thed extension to activate + # @param [Hash] options Options to pass to the extension + # @yield [Middleman::Configuration::ConfigurationManager] Extension options that can be modified before the extension is initialized. # @return [void] - # rubocop:disable BlockNesting - def activate(ext, options={}, &block) - extension = ::Middleman::Extensions.load(ext) - logger.debug "== Activating: #{ext}" + def activate(ext_name, options={}, &block) + extension = ::Middleman::Extensions.load(ext_name) + logger.debug "== Activating: #{ext_name}" if extension.supports_multiple_instances? - extensions[ext] ||= {} - key = "instance_#{extensions[ext].keys.length}" - extensions[ext][key] = extension.new(self.class, options, &block) + extensions[ext_name] ||= {} + key = "instance_#{extensions[ext_name].keys.length}" + extensions[ext_name][key] = extension.new(self.class, options, &block) + elsif extensions.key?(ext_name) + raise "#{ext_name} has already been activated and cannot be re-activated." else - if extensions[ext] - raise "#{ext} has already been activated and cannot be re-activated." - else - extensions[ext] = extension.new(self.class, options, &block) - end + extensions[ext_name] = extension.new(self.class, options, &block) end end - # Access activated extensions + # A hash of all activated extensions, indexed by their name. If an extension supports multiple + # instances, it will be stored as a hash of instances instead of just the instance. # - # @return [Hash] + # @return [Hash{Symbol => Middleman::Extension, Hash{String => Middleman::Extension}}] def extensions @extensions ||= {} end - # Load features before starting server + # Override application initialization to load `config.rb` and to call lifecycle hooks. def initialize super self.class.inst = self # Search the root of the project for required files - $LOAD_PATH.unshift(root) + $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) ::Middleman::Extension.clear_after_extension_callbacks @@ -87,7 +101,7 @@ module Middleman run_hook :before_configuration - # Check for and evaluate local configuration + # Check for and evaluate local configuration in `config.rb` local_config = File.join(root, 'config.rb') if File.exist? local_config logger.debug '== Reading: Local config' @@ -136,7 +150,6 @@ module Middleman ::Middleman::Extension.activated_extension(klass) end - end end end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 70d3026c..b7df7822 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -38,7 +38,7 @@ module Middleman # extension is first activated. # @return [void] def register(name, extension_class=nil, &block) - raise "Extension name must be a symbol" unless name.is_a?(Symbol) + raise 'Extension name must be a symbol' unless name.is_a?(Symbol) # If we've already got an extension registered under this name, bail out raise "There is already an extension registered with the name '#{name}'" if registered.key?(name) @@ -57,7 +57,7 @@ module Middleman # @return [Class] A {Middleman::Extension} class implementing the extension # def load(name) - raise "Extension name must be a symbol" unless name.is_a?(Symbol) + raise 'Extension name must be a symbol' unless name.is_a?(Symbol) unless registered.key?(name) raise "Unknown Extension: #{name}. Check the name and make sure you have referenced the extension's gem in your Gemfile." From dd7f06968a90259f2b15dd70d4d6645138b49c34 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 22 May 2014 23:05:15 -0700 Subject: [PATCH 032/662] Clean up extension activation, helper registration, and sprockets autoload --- .../core_extensions/extensions.rb | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 104e060a..41b43f2b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -14,9 +14,6 @@ module Middleman app.define_hook :build_config app.define_hook :development_config - app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' - app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - app.extend ClassMethods app.delegate :configure, to: :"self.class" end @@ -89,11 +86,12 @@ module Middleman ::Middleman::Extension.clear_after_extension_callbacks - if config[:autoload_sprockets] + if ENV['AUTOLOAD_SPROCKETS'] != 'false' begin require 'middleman-sprockets' - activate(:sprockets) + activate :sprockets rescue LoadError + # It's OK if somebody is using middleman-core without middleman-sprockets end end @@ -132,24 +130,27 @@ module Middleman run_hook :after_configuration config_context.execute_after_configuration_callbacks + extension_instances = [] logger.debug 'Loaded extensions:' - extensions.each do |ext, klass| + extensions.each do |ext_name, ext| if ext.is_a?(Hash) - ext.each do |k, _| - logger.debug "== Extension: #{k}" + ext.each do |instance_key, instance| + logger.debug "== Extension: #{ext_name} #{instance_key}" + extension_instances << instance end else - logger.debug "== Extension: #{ext}" + logger.debug "== Extension: #{ext_name}" + extension_instances << ext + end + end + + extension_instances.each do |ext| + # Forward Extension helpers to TemplateContext + Array(ext.class.defined_helpers).each do |m| + @template_context_class.send(:include, m) end - if klass.is_a?(::Middleman::Extension) - # Forward Extension helpers to TemplateContext - (klass.class.defined_helpers || []).each do |m| - @template_context_class.send(:include, m) - end - - ::Middleman::Extension.activated_extension(klass) - end + ::Middleman::Extension.activated_extension(ext) end end end From 9a3f9fe488e0b2ed0690c89c5fd045b004f1b7a2 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 24 May 2014 00:22:09 -0700 Subject: [PATCH 033/662] Clean up some Rubocop warnings that were previously suppressed. --- .../core_extensions/default_helpers.rb | 24 +++++---------- .../middleman-core/core_extensions/request.rb | 7 ++--- .../lib/middleman-core/extension.rb | 1 - .../lib/middleman-core/file_renderer.rb | 5 ++-- .../lib/middleman-core/preview_server.rb | 13 ++++----- .../lib/middleman-core/profiling.rb | 29 +++++++++---------- .../lib/middleman-core/template_context.rb | 13 ++++----- 7 files changed, 39 insertions(+), 53 deletions(-) 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 31b8dbcd..aeaaf500 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -6,12 +6,11 @@ require 'padrino-helpers' class Padrino::Helpers::OutputHelpers::ErbHandler # Force Erb capture not to use safebuffer - # rubocop:disable UnderscorePrefixedVariableName def capture_from_template(*args, &block) - self.output_buffer, _buf_was = '', output_buffer + self.output_buffer, buf_was = '', output_buffer raw = block.call(*args) captured = template.instance_variable_get(:@_out_buf) - self.output_buffer = _buf_was + self.output_buffer = buf_was engine_matches?(block) ? captured : raw end end @@ -39,7 +38,6 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension helpers do # Make all block content html_safe - # rubocop:disable Semicolon def content_tag(name, content=nil, options=nil, &block) # safe_content_tag(name, content, options, &block) if block_given? @@ -53,7 +51,10 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension output.safe_concat "<#{name}#{attributes}>" if content.respond_to?(:each) && !content.is_a?(String) - content.each { |c| output.safe_concat c; output.safe_concat ::Padrino::Helpers::TagHelpers::NEWLINE } + content.each do |c| + output.safe_concat c + output.safe_concat ::Padrino::Helpers::TagHelpers::NEWLINE + end else output.safe_concat "#{content}" end @@ -72,17 +73,10 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension ActiveSupport::SafeBuffer.new.safe_concat(result) end - # rubocop:disable MultilineBlockChain, UnusedBlockArgument def auto_find_proper_handler(&block) if block_given? engine = File.extname(block.source_location[0])[1..-1].to_sym - ::Padrino::Helpers::OutputHelpers.handlers.select do |e, h| - e == engine - end.values.map do |h| - h.new(self) - end.find do |h| - h.engine_matches?(block) - end + ::Padrino::Helpers::OutputHelpers.handlers.select { |e, _| e == engine }.values.map { |h| h.new(self) }.find { |h| h.engine_matches?(block) } else find_proper_handler end @@ -195,10 +189,8 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # # @param [String] path The path (such as "photo.jpg") # @param [String] prefix The type prefix (such as "images") - # @param [Hash] options Data to pass through. # @return [String] The fully qualified asset url - # rubocop:disable UnusedMethodArgument - def asset_url(path, prefix='', options={}) + def asset_url(path, prefix='', _) # Don't touch assets which already have a full path if path.include?('//') || path.start_with?('data:') path diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index 3e822715..bd182fd6 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -124,12 +124,11 @@ module Middleman # configuration can be included later without impacting # other classes and instances. # - # rubocop:disable ClassVars # @return [Class] def server(&block) - @@servercounter ||= 0 - @@servercounter += 1 - const_set("MiddlemanApplication#{@@servercounter}", Class.new(Middleman::Application, &block)) + @servercounter ||= 0 + @servercounter += 1 + const_set("MiddlemanApplication#{@servercounter}", Class.new(Middleman::Application, &block)) end end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index cff75105..89f4e613 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -280,7 +280,6 @@ module Middleman @klass.after_configuration do ext.after_configuration if ext.respond_to?(:after_configuration) - # rubocop:disable IfUnlessModifier if ext.respond_to?(:manipulate_resource_list) ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext, ext.class.resource_list_manipulator_priority) end diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index f3ee6d73..b55cb48e 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -20,7 +20,6 @@ module Middleman # @param [Hash] opts # @param [Class] context # @return [String] - # rubocop:disable UnderscorePrefixedVariableName def render(locs={}, opts={}, context, &block) path = @path.dup @@ -32,7 +31,7 @@ module Middleman context.current_engine, engine_was = engine, context.current_engine # Save current buffer for later - _buf_was = context.save_buffer + buf_was = context.save_buffer # Read from disk or cache the contents of the file body = if opts[:template_body] @@ -85,7 +84,7 @@ module Middleman output ensure # Reset stored buffer - context.restore_buffer(_buf_was) + context.restore_buffer(buf_was) context.current_engine = engine_was end diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 070b3a37..b855777f 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -2,7 +2,6 @@ require 'webrick' require 'middleman-core/meta_pages' require 'middleman-core/logger' -# rubocop:disable GlobalVars module Middleman module PreviewServer DEFAULT_PORT = 4567 @@ -35,12 +34,12 @@ module Middleman loop do @webrick.start - # $mm_shutdown is set by the signal handler - if $mm_shutdown + # @mm_shutdown is set by the signal handler + if @mm_shutdown shutdown exit - elsif $mm_reload - $mm_reload = false + elsif @mm_reload + @mm_reload = false reload end end @@ -130,7 +129,7 @@ module Middleman # See if the changed file is config.rb or lib/*.rb if needs_to_reload?(added_and_modified + removed) - $mm_reload = true + @mm_reload = true @webrick.stop else added_and_modified.each do |path| @@ -156,7 +155,7 @@ module Middleman if Signal.list[sig] Signal.trap(sig) do # Do as little work as possible in the signal context - $mm_shutdown = true + @mm_shutdown = true @webrick.stop end end diff --git a/middleman-core/lib/middleman-core/profiling.rb b/middleman-core/lib/middleman-core/profiling.rb index d5b43ef4..d7f89bd4 100644 --- a/middleman-core/lib/middleman-core/profiling.rb +++ b/middleman-core/lib/middleman-core/profiling.rb @@ -1,22 +1,21 @@ module Middleman module Profiling - # The profiler instance. There can only be one! - # rubocop:disable TrivialAccessors - def self.profiler=(prof) - @profiler = prof - end - def self.profiler - @profiler ||= NullProfiler.new - end + class << self + # The profiler instance. There can only be one! + attr_writer :profiler + def profiler + @profiler ||= NullProfiler.new + end - # Start the profiler - def self.start - profiler.start - end + # Start the profiler + def start + profiler.start + end - # Stop the profiler and generate a report. Make sure to call start first - def self.report(report_name) - profiler.report(report_name) + # Stop the profiler and generate a report. Make sure to call start first + def report(report_name) + profiler.report(report_name) + end end # A profiler that does nothing. The default. diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 81d405a8..e321753c 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -1,7 +1,6 @@ require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' -# rubocop:disable UnderscorePrefixedVariableName module Middleman class TemplateContext attr_reader :app @@ -16,13 +15,13 @@ module Middleman end def save_buffer - @_out_buf, _buf_was = '', @_out_buf - _buf_was + @_out_buf, buf_was = '', @_out_buf + buf_was end # rubocop:disable TrivialAccessors - def restore_buffer(_buf_was) - @_out_buf = _buf_was + def restore_buffer(buf_was) + @_out_buf = buf_was end # Allow layouts to be wrapped in the contents of other layouts @@ -30,7 +29,7 @@ module Middleman # @return [void] def wrap_layout(layout_name, &block) # Save current buffer for later - _buf_was = save_buffer + buf_was = save_buffer layout_path = ::Middleman::TemplateRenderer.locate_layout(@app, layout_name, current_engine) @@ -48,7 +47,7 @@ module Middleman end ensure # Reset stored buffer - restore_buffer(_buf_was) + restore_buffer(buf_was) end file_renderer = ::Middleman::FileRenderer.new(@app, layout_path) From dc150063404705349bb387cfb1c84a7ab147dd60 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 24 May 2014 18:51:18 +0900 Subject: [PATCH 034/662] We are semver --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index a90e252f..4bb81bad 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,22 @@ The best way to get quick responses to your issues and swift fixes to your bugs [Click here to lend your support to Middleman](https://spacebox.io/s/4dXbHBorC3) +## Versioning + +This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations +of this scheme should be reported as bugs. Specifically, if a minor or patch +version is released that breaks backward compatibility, that version should be +immediately yanked and/or a new version should be immediately released that +restores compatibility. Breaking changes to the public API will only be +introduced with new major versions. As a result of this policy, you can (and +should) specify a dependency on this gem using the [Pessimistic Version +Constraint][pvc] with two digits of precision. For example: + + spec.add_dependency 'middleman-core', '~> 3.0' + +[semver]: http://semver.org/ +[pvc]: http://docs.rubygems.org/read/chapter/16#page74 + ## License Copyright (c) 2010-2013 Thomas Reynolds. MIT Licensed, see [LICENSE] for details. From 72b945682a9dde08b3105135fb964ec25977df4d Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 24 May 2014 19:18:12 +0900 Subject: [PATCH 035/662] Fix threadsafety issue with assignment. Fixes #501. Also, WTF? --- middleman-core/lib/middleman-core/core_extensions/rendering.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index a6b21fdd..091a0e85 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -143,7 +143,8 @@ module Middleman end # Store current locs/opts for later - @current_locs = locs, @current_opts = opts + @current_locs = locs + @current_opts = opts # Keep rendering template until we've used up all extensions. This # handles cases like `style.css.sass.erb` From 1a461154b6767be9f8de13ab12c87a4619c32495 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 24 May 2014 19:27:56 +0900 Subject: [PATCH 036/662] prep --- CHANGELOG.md | 9 +++++++++ middleman-core/lib/middleman-core/version.rb | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ad318d7..f5811746 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ master === +3.3.3 +=== + +* Fix thread-safety issue #501 which could cause excepts when livereloading. +* Update to support Hooks 0.4.x dep. +* Update to support Padrino 0.12.2+ dep. +* Fix `after_render` manipulation of content. #1278 +* Fix combo of compass-import-once and sass-globs. middleman/middleman-sprockets#56 + 3.3.0-3.3.2 === diff --git a/middleman-core/lib/middleman-core/version.rb b/middleman-core/lib/middleman-core/version.rb index 33ea61f6..fa5be3d0 100644 --- a/middleman-core/lib/middleman-core/version.rb +++ b/middleman-core/lib/middleman-core/version.rb @@ -1,5 +1,5 @@ module Middleman # Current Version # @return [String] - VERSION = '3.3.2' unless const_defined?(:VERSION) + VERSION = '3.3.3' unless const_defined?(:VERSION) end From 4ab88e6577f170a10fd9aa9583467d5781431f95 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sun, 25 May 2014 11:59:21 +0900 Subject: [PATCH 037/662] Document and cleanup TemplateContext class. --- middleman-core/lib/middleman-core/sitemap.rb | 2 +- .../lib/middleman-core/template_context.rb | 130 +++++++++++++----- 2 files changed, 98 insertions(+), 34 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index a5f2c8f7..3a66cebb 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -34,7 +34,7 @@ module Middleman # Sitemap instance methods module InstanceMethods def current_path - @current_locs[:current_path] + @locs[:current_path] end # Get the resource object for the current path diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index e321753c..d6c78be9 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -1,95 +1,159 @@ +require 'pathname' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' module Middleman + # The TemplateContext Class + # + # A clean context, separate from Application, in which templates can be executed. + # All helper methods and values available in a template, but be accessible here. + # Also implements two helpers: wrap_layout & render (used by padrino's partial method). + # A new context is created for each render of a path, but that context is shared through + # the request, passed from template, to layouts and partials. class TemplateContext + # Allow templates to directly access the current app instance. + # @return [Middleman::Application] attr_reader :app + + # Required for Padrino's rendering attr_accessor :current_engine + # Shorthand references to global values on the app instance. delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, to: :app + # Initialize a context with the current app and predefined locals and options hashes. + # + # @param [Middleman::Application] app + # @param [Hash] locs + # @param [Hash] opts def initialize(app, locs={}, opts={}) @app = app - @current_locs = locs - @current_opts = opts + @locs = locs.dup.freeze + @opts = opts.dup.freeze end + # Return the current buffer to the caller and clear the value internally. + # Used when moving between templates when rendering layouts or partials. + # + # @api private + # @return [String] The old buffer. def save_buffer @_out_buf, buf_was = '', @_out_buf buf_was end + # Restore a previously saved buffer. + # + # @api private + # @param [String] buf_was + # @return [void] # rubocop:disable TrivialAccessors def restore_buffer(buf_was) @_out_buf = buf_was end - # Allow layouts to be wrapped in the contents of other layouts + # Allow layouts to be wrapped in the contents of other layouts. + # # @param [String, Symbol] layout_name # @return [void] def wrap_layout(layout_name, &block) # Save current buffer for later buf_was = save_buffer + # Find a layout for this file layout_path = ::Middleman::TemplateRenderer.locate_layout(@app, layout_name, current_engine) + # Get the layout engine extension = File.extname(layout_path) engine = extension[1..-1].to_sym # Store last engine for later (could be inside nested renders) self.current_engine, engine_was = engine, current_engine + # By default, no content is captured + content = '' + + # Attempt to capture HTML from block begin - content = if block_given? - capture_html(&block) - else - '' - end + content = capture_html(&block) if block_given? ensure - # Reset stored buffer + # Reset stored buffer, regardless of success restore_buffer(buf_was) end - - file_renderer = ::Middleman::FileRenderer.new(@app, layout_path) - concat_safe_content file_renderer.render(@current_locs || {}, @current_opts || {}, self) { content } + # Render the layout, with the contents of the block inside. + concat_safe_content render_file(layout_path, @locs, @opts) { content } ensure + # Reset engine back to template's value, regardless of success self.current_engine = engine_was end # Sinatra/Padrino compatible render method signature referenced by some view # helpers. Especially partials. # - # @param [String, Symbol] data + # @param [] _ Unused parameter. + # @param [String, Symbol] name The partial to render. # @param [Hash] options # @return [String] - def render(_, data, options={}, &block) - data = data.to_s + def render(_, name, options={}, &block) + name = name.to_s - locals = options[:locals] + partial_path = locate_partial_relative(name) || locate_partial_in_partials_dir(name) - found_partial = false - resolve_opts = { try_without_underscore: true } + raise ::Middleman::TemplateRenderer::TemplateNotFound, "Could not locate partial: #{name}" unless partial_path - # If the path is known to the sitemap - if resource = sitemap.find_resource_by_path(current_path) - current_dir = File.dirname(resource.source_file) - resolve_opts[:preferred_engine] = File.extname(resource.source_file)[1..-1].to_sym + opts = options.dup + locs = opts.delete(:locals) - # Look for partials relative to the current path - relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), data) + render_file(partial_path, locs.freeze, opts.freeze, &block) + end - found_partial = ::Middleman::TemplateRenderer.resolve_template(@app, relative_dir, resolve_opts) - end + protected - unless found_partial - partials_path = File.join(@app.config[:partials_dir], data) - found_partial = ::Middleman::TemplateRenderer.resolve_template(@app, partials_path, resolve_opts) - end + # Locate a partial reltive to the current path, given a name. + # + # @api private + # @param [String] name + # @return [String] + def locate_partial_relative(name) + return unless resource = sitemap.find_resource_by_path(current_path) - raise ::Middleman::TemplateRenderer::TemplateNotFound, "Could not locate partial: #{data}" unless found_partial + # Look for partials relative to the current path + current_dir = File.dirname(resource.source_file) + relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), name) - file_renderer = ::Middleman::FileRenderer.new(@app, found_partial) - file_renderer.render(locals, options, self, &block) + ::Middleman::TemplateRenderer.resolve_template( + @app, + relative_dir, + try_without_underscore: true, + preferred_engine: File.extname(resource.source_file)[1..-1].to_sym + ) + end + + # Locate a partial reltive to the partials dir, given a name. + # + # @api private + # @param [String] name + # @return [String] + def locate_partial_in_partials_dir(name) + partials_path = File.join(@app.config[:partials_dir], name) + ::Middleman::TemplateRenderer.resolve_template( + @app, + partials_path, + try_without_underscore: true + ) + end + + # Render a path with locs, opts and contents block. + # + # @api private + # @param [String] path The file path. + # @param [Hash] locs Template locals. + # @param [Hash] opts Template options. + # @param [Proc] block A block will be evaluated to return internal contents. + # @return [String] The resulting content string. + def render_file(path, locs, opts, &block) + file_renderer = ::Middleman::FileRenderer.new(@app, path) + file_renderer.render(locs, opts, self, &block) end end end From f89a76747e58b7a4bcc16ad631a247cee4a738a0 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sun, 25 May 2014 12:23:00 +0900 Subject: [PATCH 038/662] Removed wrap_layout --- CHANGELOG.md | 1 + .../features/custom_layouts.feature | 12 -------- .../step_definitions/page_layout_steps.rb | 9 ------ .../fixtures/auto-css-app/config.rb | 18 +++++------ middleman-core/fixtures/auto-js-app/config.rb | 18 +++++------ .../fixtures/basic-data-app/config.rb | 6 ++-- .../fixtures/capture-html-app/config.rb | 8 ++--- .../fixtures/content-for-app/config.rb | 8 ++--- .../fixtures/generator-test/config.rb | 5 ---- .../fixtures/large-build-app/config.rb | 4 +-- .../fixtures/page-classes-app/config.rb | 6 ++-- .../lib/middleman-core/config_context.rb | 2 +- .../middleman-core/core_extensions/routing.rb | 30 ------------------- .../lib/middleman-templates/shared/config.tt | 5 ---- 14 files changed, 29 insertions(+), 103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 124421f3..ac1e3077 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* Removed `with_layout`. Use loops of `page` instead. * Removed Queryable Sitemap API * Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead. * Removed `js_compressor` setting, use `activate :minify_javascript, :compressor =>` instead. diff --git a/middleman-core/features/custom_layouts.feature b/middleman-core/features/custom_layouts.feature index 32feaa99..09c7faa1 100644 --- a/middleman-core/features/custom_layouts.feature +++ b/middleman-core/features/custom_layouts.feature @@ -7,18 +7,6 @@ Feature: Custom layouts When I go to "/custom-layout.html" Then I should see "Custom Layout" - Scenario: Using with_layout block - Given "/custom-layout.html" with_layout block has layout "custom" - And the Server is running at "custom-layout-app2" - When I go to "/custom-layout.html" - Then I should see "Custom Layout" - - Scenario: Using with_layout block with globs - Given "/custom-*" with_layout block has layout "custom" - And the Server is running at "custom-layout-app2" - When I go to "/custom-layout.html" - Then I should see "Custom Layout" - Scenario: Using custom :layout attribute with folders Given page "/custom-layout-dir/" has layout "custom" And the Server is running at "custom-layout-app2" diff --git a/middleman-core/features/step_definitions/page_layout_steps.rb b/middleman-core/features/step_definitions/page_layout_steps.rb index 9456d4cf..311b4d4d 100644 --- a/middleman-core/features/step_definitions/page_layout_steps.rb +++ b/middleman-core/features/step_definitions/page_layout_steps.rb @@ -4,12 +4,3 @@ Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout| page(url, :layout => layout.to_sym) } end - -Given /^"([^\"]*)" with_layout block has layout "([^\"]*)"$/ do |url, layout| - @initialize_commands ||= [] - @initialize_commands << lambda { - with_layout(layout.to_sym) do - page(url) - end - } -end diff --git a/middleman-core/fixtures/auto-css-app/config.rb b/middleman-core/fixtures/auto-css-app/config.rb index 10ff8ae6..154cfd92 100644 --- a/middleman-core/fixtures/auto-css-app/config.rb +++ b/middleman-core/fixtures/auto-css-app/config.rb @@ -1,11 +1,9 @@ -with_layout false do - %w{ - /auto-css.html - /auto-css - /auto-css/ - /auto-css/auto-css.html - /auto-css/sub/auto-css.html - }.each do |path| - page path - end +%w{ + /auto-css.html + /auto-css + /auto-css/ + /auto-css/auto-css.html + /auto-css/sub/auto-css.html +}.each do |path| + page path, layout: false end diff --git a/middleman-core/fixtures/auto-js-app/config.rb b/middleman-core/fixtures/auto-js-app/config.rb index 31d649c2..cf40d463 100644 --- a/middleman-core/fixtures/auto-js-app/config.rb +++ b/middleman-core/fixtures/auto-js-app/config.rb @@ -1,11 +1,9 @@ -with_layout false do - %w{ - /auto-js.html - /auto-js - /auto-js/ - /auto-js/auto-js.html - /auto-js/sub/auto-js.html - }.each do |path| - page path - end +%w{ + /auto-js.html + /auto-js + /auto-js/ + /auto-js/auto-js.html + /auto-js/sub/auto-js.html +}.each do |path| + page path, layout: false end diff --git a/middleman-core/fixtures/basic-data-app/config.rb b/middleman-core/fixtures/basic-data-app/config.rb index 8d9a6629..7a6d8ba1 100644 --- a/middleman-core/fixtures/basic-data-app/config.rb +++ b/middleman-core/fixtures/basic-data-app/config.rb @@ -1,4 +1,2 @@ -with_layout false do - page "/data.html" - page "/data3.html" -end +page "/data.html", layout: false +page "/data3.html", layout: false diff --git a/middleman-core/fixtures/capture-html-app/config.rb b/middleman-core/fixtures/capture-html-app/config.rb index c0621cbe..da6dc3ae 100644 --- a/middleman-core/fixtures/capture-html-app/config.rb +++ b/middleman-core/fixtures/capture-html-app/config.rb @@ -1,7 +1,5 @@ require "slim" -with_layout :capture_html do - page "/capture_html_erb.html" - page "/capture_html_haml.html" - page "/capture_html_slim.html" -end +page "/capture_html_erb.html", layout: :capture_html +page "/capture_html_haml.html", layout: :capture_html +page "/capture_html_slim.html", layout: :capture_html diff --git a/middleman-core/fixtures/content-for-app/config.rb b/middleman-core/fixtures/content-for-app/config.rb index 229347fb..1e5daaae 100644 --- a/middleman-core/fixtures/content-for-app/config.rb +++ b/middleman-core/fixtures/content-for-app/config.rb @@ -1,7 +1,5 @@ require "slim" -with_layout :content_for do - page "/content_for_erb.html" - page "/content_for_haml.html" - page "/content_for_slim.html" -end +page "/content_for_erb.html", layout: :content_for +page "/content_for_haml.html", layout: :content_for +page "/content_for_slim.html", layout: :content_for diff --git a/middleman-core/fixtures/generator-test/config.rb b/middleman-core/fixtures/generator-test/config.rb index 74ab3a21..e753409f 100644 --- a/middleman-core/fixtures/generator-test/config.rb +++ b/middleman-core/fixtures/generator-test/config.rb @@ -22,11 +22,6 @@ # # With alternative layout # page "/path/to/file.html", :layout => :otherlayout -# -# A path which all have the same layout -# with_layout :admin do -# page "/admin/*" -# end # Proxy (fake) files # page "/this-page-has-no-template.html", :proxy => "/template-file.html" do diff --git a/middleman-core/fixtures/large-build-app/config.rb b/middleman-core/fixtures/large-build-app/config.rb index 77df0b3c..ae596127 100644 --- a/middleman-core/fixtures/large-build-app/config.rb +++ b/middleman-core/fixtures/large-build-app/config.rb @@ -1,3 +1 @@ -with_layout false do - page "/spaces in file.html" -end +page "/spaces in file.html", layout: false diff --git a/middleman-core/fixtures/page-classes-app/config.rb b/middleman-core/fixtures/page-classes-app/config.rb index 05be0d07..ac693f9b 100644 --- a/middleman-core/fixtures/page-classes-app/config.rb +++ b/middleman-core/fixtures/page-classes-app/config.rb @@ -1,4 +1,2 @@ -with_layout false do - page "/sub1/page-classes.html" - page "/sub1/sub2/page-classes.html" -end +page "/sub1/page-classes.html", layout: false +page "/sub1/sub2/page-classes.html", layout: false diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 248184f9..3d46b88b 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -1,6 +1,6 @@ module Middleman class ConfigContext - # with_layout and page routing + # page routing include Middleman::CoreExtensions::Routing attr_reader :app diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 633ecc57..9d695d6a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -2,36 +2,6 @@ module Middleman module CoreExtensions module Routing - # Sandboxed layout to implement temporary overriding of layout. - class LayoutBlock - attr_reader :scope - - def initialize(scope, layout_name) - @scope = scope - @layout_name = layout_name - end - - def page(url, opts={}) - opts[:layout] ||= @layout_name - @scope.page(url, opts) - end - - delegate :proxy, to: :scope - end - - # Takes a block which allows many pages to have the same layout - # - # with_layout :admin do - # page "/admin/" - # page "/admin/login.html" - # end - # - # @param [String, Symbol] layout_name - # @return [void] - def with_layout(layout_name, &block) - LayoutBlock.new(self, layout_name).instance_eval(&block) - end - # The page method allows the layout to be set on a specific path # # page "/about.html", :layout => false diff --git a/middleman-templates/lib/middleman-templates/shared/config.tt b/middleman-templates/lib/middleman-templates/shared/config.tt index f6d586a1..27673596 100755 --- a/middleman-templates/lib/middleman-templates/shared/config.tt +++ b/middleman-templates/lib/middleman-templates/shared/config.tt @@ -20,11 +20,6 @@ page '/*.txt', layout: false # # With alternative layout # page "/path/to/file.html", :layout => :otherlayout -# -# A path which all have the same layout -# with_layout :admin do -# page "/admin/*" -# end # Proxy pages (http://middlemanapp.com/basics/dynamic-pages/) # proxy "/this-page-has-no-template.html", "/template-file.html", :locals => { From 5d4cae2a0607006c1facad45ffc6c8a6e785a2da Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 22 May 2014 23:05:42 -0700 Subject: [PATCH 039/662] Allow extensions to optionally register to be automatically activated before configuration. --- .../core_extensions/extensions.rb | 4 ++++ .../lib/middleman-core/extensions.rb | 20 ++++++++++++++++++- .../lib/middleman-core/meta_pages.rb | 6 +++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 41b43f2b..42d12465 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -86,6 +86,10 @@ module Middleman ::Middleman::Extension.clear_after_extension_callbacks + ::Middleman::Extensions.auto_activate_before_configuration.each do |ext_name| + activate ext_name + end + if ENV['AUTOLOAD_SPROCKETS'] != 'false' begin require 'middleman-sprockets' diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index b7df7822..34be436b 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -1,4 +1,5 @@ require 'middleman-core/extension' +require 'set' module Middleman # The Extensions module is used to handle global registration and loading of Middleman Extensions. @@ -7,13 +8,19 @@ module Middleman # `middleman-core/core_extensions/extensions.rb`. module Extensions @registered = {} + @auto_activate_before_configuration = Set.new class << self + # @api private # A hash of all registered extensions. Registered extensions are not necessarily active - this # is the set of all extensions that are known to Middleman. # @return [Hash{Symbol => Class, Proc}] A directory of known extensions indexed by the name they were registered under. The value may be a Proc, which can be lazily called to return an extension class. attr_reader :registered + # @api private + # A list of extensions that should be automatically loaded before `config.rb` is loaded and before the `:before_configuration` hook is run. Only internal, built-in Middleman extensions should be listed here. + attr_reader :auto_activate_before_configuration + # Register a new extension. Choose a name which will be # used to activate the extension in `config.rb`, like this: # @@ -32,16 +39,25 @@ module Middleman # # @param [Symbol] name The name of the extension # @param [Class] extension_class The extension class (Must inherit from {Middleman::Extension}) + # @option options [Boolean] :auto_activate_before_configuration If set to true, this extension will be automatically + # activated before `config.rb` is loaded and before the `:before_configuration` hook is run. + # This is intended for use with built-in Middleman extensions and should not be used by third-party extensions. # @yield Instead of passing a module in namespace, you can provide # a block which returns your extension class. This gives # you the ability to require other files only when the # extension is first activated. # @return [void] - def register(name, extension_class=nil, &block) + def register(name, extension_class=nil, options={}, &block) raise 'Extension name must be a symbol' unless name.is_a?(Symbol) # If we've already got an extension registered under this name, bail out raise "There is already an extension registered with the name '#{name}'" if registered.key?(name) + # If the extension is defined with a block, grab options out of the "extension_class" parameter. + if extension_class && block_given? && options.empty? && extension_class.is_a?(Hash) + options = extension_class + extension_class = nil + end + registered[name] = if block_given? block elsif extension_class && extension_class.ancestors.include?(::Middleman::Extension) @@ -49,6 +65,8 @@ module Middleman else raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end + + @auto_activate_before_configuration << name if options[:auto_activate_before_configuration] end # @api private diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index 8e1a68a7..5783670b 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -63,6 +63,8 @@ module Middleman extension_config = {} @middleman.inst.extensions.each do |ext_name, extension| + next if ::Middleman::Extension.auto_activate_before_configuration.include? ext_name + if extension.is_a?(Hash) # Multiple instance extension if extension.size == 1 @@ -72,10 +74,8 @@ module Middleman extension_config["#{ext_name} (#{inst})"] = extension_options(ext) end end - elsif extension.is_a?(::Middleman::Extension) - extension_config[ext_name] = extension_options(extension) else - extension_config[ext_name] = nil + extension_config[ext_name] = extension_options(extension) end end From 67bb394852356c69f6a3f9f2db9c379b90fdaa7e Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 23 May 2014 23:55:34 -0700 Subject: [PATCH 040/662] Move some explicitly activated extensions to be auto activate --- .../lib/middleman-core/application.rb | 24 ++++++++----------- .../lib/middleman-core/config_context.rb | 2 ++ .../lib/middleman-core/core_extensions.rb | 22 +++++------------ .../core_extensions/extensions.rb | 5 +++- .../core_extensions/rendering.rb | 1 - 5 files changed, 22 insertions(+), 32 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 85b4a559..dda5e265 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -25,6 +25,15 @@ require 'middleman-core/config_context' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' +# Rack Request +require 'middleman-core/core_extensions/request' + +# Custom Extension API and config.rb handling +require 'middleman-core/core_extensions/extensions' + +# Catch and show exceptions at the Rack level +require 'middleman-core/core_extensions/show_exceptions' + # Core Middleman Class module Middleman class Application @@ -168,7 +177,7 @@ module Middleman delegate :link_to, :image_tag, :asset_path, to: :generic_template_context # Initialize the Middleman project - def initialize(&block) + def initialize @template_context_class = Class.new(Middleman::TemplateContext) @generic_template_context = @template_context_class.new(self) @config_context = ConfigContext.new(self, @template_context_class) @@ -193,19 +202,6 @@ module Middleman config[:source] = ENV['MM_SOURCE'] if ENV['MM_SOURCE'] - # Built-in extensions - activate :default_helpers - activate :lorem - - begin - activate :compass - rescue LoadError - # Compass is not available, don't complain about it - end - - # Evaluate a passed block if given - @config_context.instance_exec(&block) if block_given? - super end diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 3d46b88b..ff5ffa76 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -1,3 +1,5 @@ +require 'middleman-core/core_extensions/routing' + module Middleman class ConfigContext # page routing diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 340ca2fd..179b83bb 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -1,12 +1,6 @@ -# Rack Request -require 'middleman-core/core_extensions/request' - # File Change Notifier require 'middleman-core/core_extensions/file_watcher' -# Custom Feature API -require 'middleman-core/core_extensions/extensions' - # Data looks at the data/ folder for YAML files and makes them available # to dynamic requests. require 'middleman-core/core_extensions/data' @@ -23,22 +17,18 @@ require 'middleman-core/core_extensions/external_helpers' # Extended version of Padrino's rendering require 'middleman-core/core_extensions/rendering' -# Pass custom options to views -require 'middleman-core/core_extensions/routing' - -# Catch and show exceptions at the Rack level -require 'middleman-core/core_extensions/show_exceptions' - # Setup default helpers -Middleman::Extensions.register :default_helpers do +Middleman::Extensions.register :default_helpers, auto_activate_before_configuration: true do require 'middleman-core/core_extensions/default_helpers' Middleman::CoreExtensions::DefaultHelpers end # Compass framework -Middleman::Extensions.register :compass do +begin require 'middleman-core/core_extensions/compass' - Middleman::CoreExtensions::Compass + Middleman::Extensions.register :compass, Middleman::CoreExtensions::Compass, auto_activate_before_configuration: true +rescue LoadError + # Compass is not available, don't complain about it end ### @@ -105,7 +95,7 @@ end # Lorem provides a handful of helpful prototyping methods to generate # words, paragraphs, fake images, names and email addresses. -Middleman::Extensions.register :lorem do +Middleman::Extensions.register :lorem, auto_activate_before_configuration: true do require 'middleman-core/extensions/lorem' Middleman::Extensions::Lorem end diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 42d12465..ea91c8cf 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -76,7 +76,7 @@ module Middleman end # Override application initialization to load `config.rb` and to call lifecycle hooks. - def initialize + def initialize(&block) super self.class.inst = self @@ -99,6 +99,9 @@ module Middleman end end + # Evaluate a passed block if given + config_context.instance_exec(&block) if block_given? + run_hook :initialized run_hook :before_configuration diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 9b3c492a..53f72265 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -1,7 +1,6 @@ require 'middleman-core/template_context' # Rendering extension -# rubocop:disable UnderscorePrefixedVariableName module Middleman module CoreExtensions module Rendering From e649bc28098858673a5eda9486d742d674a52138 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 25 May 2014 18:03:37 -0700 Subject: [PATCH 041/662] Convert FileWatcher to a real extension --- .../lib/middleman-core/application.rb | 4 +- .../lib/middleman-core/core_extensions.rb | 5 +- .../core_extensions/file_watcher.rb | 49 +++++++++---------- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index dda5e265..c3ea9b89 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -142,9 +142,6 @@ module Middleman # Handle exceptions include Middleman::CoreExtensions::ShowExceptions - # Add Watcher Callbacks - include Middleman::CoreExtensions::FileWatcher - # Activate Data package include Middleman::CoreExtensions::Data @@ -191,6 +188,7 @@ module Middleman # Parse YAML from templates. Must be before sitemap so sitemap # extensions see updated frontmatter! activate :front_matter + activate :file_watcher # Initialize the Sitemap @sitemap = ::Middleman::Sitemap::Store.new(self) diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 179b83bb..237893eb 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -1,5 +1,8 @@ # File Change Notifier -require 'middleman-core/core_extensions/file_watcher' +Middleman::Extensions.register :file_watcher do + require 'middleman-core/core_extensions/file_watcher' + Middleman::CoreExtensions::FileWatcher +end # Data looks at the data/ folder for YAML files and makes them available # to dynamic requests. 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 03b25241..8de7805c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -1,7 +1,11 @@ -# API for watching file change events +require 'pathname' +require 'set' + module Middleman module CoreExtensions - module FileWatcher + # API for watching file change events + class FileWatcher < Extension + # Regexes in this list will filter out filenames of files that shouldn't cause file change notifications. IGNORE_LIST = [ /^bin(\/|$)/, /^\.bundle(\/|$)/, @@ -20,39 +24,30 @@ module Middleman /^tmp\// ] - # Setup extension - class << self - # Once registered - def included(app) - require 'pathname' - require 'set' + def initialize(app, options_hash={}, &block) + super - app.send :include, InstanceMethods + app.config.define_setting :file_watcher_ignore, IGNORE_LIST, 'Regexes for paths that should be ignored when they change.' - app.config.define_setting :file_watcher_ignore, IGNORE_LIST, 'Regexes for paths that should be ignored when they change.' - - # Before parsing config, load the data/ directory - app.before_configuration do - files.reload_path(config[:data_dir]) - end - - app.after_configuration do - config[:file_watcher_ignore] << %r{^#{config[:build_dir]}(\/|$)} - end - - # After config, load everything else - app.ready do - files.reload_path('.') - end - end + # Directly include the #files method instead of using helpers so that this is available immediately + app.send :include, InstanceMethods + end + + # Before parsing config, load the data/ directory + def before_configuration + app.files.reload_path(app.config[:data_dir]) + end + + def after_configuration + app.config[:file_watcher_ignore] << %r{^#{app.config[:build_dir]}(\/|$)} + app.files.reload_path('.') end - # Instance methods module InstanceMethods # Access the file api # @return [Middleman::CoreExtensions::FileWatcher::API] def files - @_files_api ||= API.new(self) + @files_api ||= API.new(self) end end From fed95f9c5e70d4b7df04008d9f394436f8b26d1f Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 25 May 2014 18:43:49 -0700 Subject: [PATCH 042/662] Convert external data to a real extension --- .../lib/middleman-core/application.rb | 4 +- .../lib/middleman-core/core_extensions.rb | 5 +- .../middleman-core/core_extensions/data.rb | 74 ++++++++----------- 3 files changed, 36 insertions(+), 47 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index c3ea9b89..94e8c23f 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -142,9 +142,6 @@ module Middleman # Handle exceptions include Middleman::CoreExtensions::ShowExceptions - # Activate Data package - include Middleman::CoreExtensions::Data - # Setup custom rendering include Middleman::CoreExtensions::Rendering @@ -188,6 +185,7 @@ module Middleman # Parse YAML from templates. Must be before sitemap so sitemap # extensions see updated frontmatter! activate :front_matter + activate :data activate :file_watcher # Initialize the Sitemap diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 237893eb..64be17ef 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -6,7 +6,10 @@ end # Data looks at the data/ folder for YAML files and makes them available # to dynamic requests. -require 'middleman-core/core_extensions/data' +Middleman::Extensions.register :data do + require 'middleman-core/core_extensions/data' + Middleman::CoreExtensions::Data +end # Parse YAML from templates Middleman::Extensions.register :front_matter do diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index df332f42..8fac7911 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -1,37 +1,35 @@ +require 'yaml' +require 'active_support/json' + module Middleman module CoreExtensions - # The data extension parses YAML and JSON files in the data/ directory - # and makes them available to config.rb, templates and extensions - module Data - # Extension registered - class << self - # @private - def included(app) - # Data formats - require 'yaml' - require 'active_support/json' + # The data extension parses YAML and JSON files in the `data/` directory + # and makes them available to `config.rb`, templates and extensions + class Data < Extension + # The regex which tells Middleman which files are for data + MATCHER = /[\w-]+\.(yml|yaml|json)$/ - app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' - app.send :include, InstanceMethods + def initialize(app, options_hash={}, &block) + super + app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' + + # Directly include the #data method instead of using helpers so that this is available immediately + app.send :include, InstanceMethods + end + + def before_configuration + # Setup data files before anything else so they are available when + # parsing config.rb + app.files.changed MATCHER do |file| + data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") + end + + app.files.deleted MATCHER do |file| + data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") end end - # Instance methods module InstanceMethods - # 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.start_with?("#{config[:data_dir]}/") - end - - files.deleted DataStore.matcher do |file| - data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") - end - - super - end - # The data object # # @return [DataStore] @@ -42,25 +40,14 @@ module Middleman # The core logic behind the data extension. class DataStore - # Static methods - class << self - # The regex which tells Middleman which files are for data - # - # @return [Regexp] - def matcher - %r{[\w-]+\.(yml|yaml|json)$} - end - end - # Store static data hash # # @param [Symbol] name Name of the data, used for namespacing # @param [Hash] content The content for this data # @return [Hash] def store(name=nil, content=nil) - @_local_sources ||= {} - @_local_sources[name.to_s] = content unless name.nil? || content.nil? - @_local_sources + @local_sources[name.to_s] = content unless name.nil? || content.nil? + @local_sources end # Store callback-based data @@ -69,9 +56,8 @@ module Middleman # @param [Proc] proc The callback which will return data # @return [Hash] def callbacks(name=nil, proc=nil) - @_callback_sources ||= {} - @_callback_sources[name.to_s] = proc unless name.nil? || proc.nil? - @_callback_sources + @callback_sources[name.to_s] = proc unless name.nil? || proc.nil? + @callback_sources end # Setup data store @@ -80,6 +66,8 @@ module Middleman def initialize(app) @app = app @local_data = {} + @local_sources = {} + @callback_sources = {} end # Update the internal cache for a given file path From 70b3b8790558fd752d06e2a4c01b0827c9c12730 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 25 May 2014 20:05:29 -0700 Subject: [PATCH 043/662] Move ExternalHelpers into a real extension --- .../lib/middleman-core/application.rb | 3 --- .../lib/middleman-core/core_extensions.rb | 5 +++- .../core_extensions/external_helpers.rb | 23 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 94e8c23f..d30e1625 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -148,9 +148,6 @@ module Middleman # Sitemap Config options and public api include Middleman::Sitemap - # Setup external helpers - include Middleman::CoreExtensions::ExternalHelpers - # Reference to Logger singleton def logger ::Middleman::Logger.singleton diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 64be17ef..1e3e738a 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -18,7 +18,10 @@ Middleman::Extensions.register :front_matter do end # External helpers looks in the helpers/ folder for helper modules -require 'middleman-core/core_extensions/external_helpers' +Middleman::Extensions.register :external_helpers, auto_activate_before_configuration: true do + require 'middleman-core/core_extensions/external_helpers' + Middleman::CoreExtensions::ExternalHelpers +end # Extended version of Padrino's rendering require 'middleman-core/core_extensions/rendering' diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index e4b41772..6b755df5 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -1,9 +1,10 @@ -# Load helpers in helpers/ module Middleman module CoreExtensions - module ExternalHelpers - # once registered - def self.included(app) + # Load helpers in `helpers/` + class ExternalHelpers < Extension + def initialize(app, options_hash={}, &block) + super + # Setup a default helpers paths app.config.define_setting :helpers_dir, 'helpers', 'Directory to autoload helper modules from' app.config.define_setting :helpers_filename_glob, '**.rb', 'Glob pattern for matching helper ruby files' @@ -11,20 +12,20 @@ module Middleman basename = File.basename(filename, File.extname(filename)) basename.camelcase }, 'Proc implementing the conversion from helper filename to module name' + end - # After config - app.after_configuration do - helpers_path = File.join(root, config[:helpers_dir]) - next unless File.exist?(helpers_path) + def after_configuration + helpers_path = File.join(app.root, app.config[:helpers_dir]) - Dir[File.join(helpers_path, config[:helpers_filename_glob])].each do |filename| - module_name = config[:helpers_filename_to_module_name_proc].call(filename) + if File.exist?(helpers_path) + Dir[File.join(helpers_path, app.config[:helpers_filename_glob])].each do |filename| + module_name = app.config[:helpers_filename_to_module_name_proc].call(filename) next unless module_name require filename next unless Object.const_defined?(module_name.to_sym) - @template_context_class.send :include, Object.const_get(module_name.to_sym) + app.template_context_class.send :include, Object.const_get(module_name.to_sym) end end end From 6561fea2960041e7fdd71ac9ceec339fab2b2d69 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 25 May 2014 21:06:25 -0700 Subject: [PATCH 044/662] Change the auto activated extension feature to allow specifying different lifecycle events to activate at, allowing more extensions to auto activate. --- .../lib/middleman-core/application.rb | 8 ++-- .../lib/middleman-core/core_extensions.rb | 48 +++++++++---------- .../core_extensions/extensions.rb | 2 +- .../lib/middleman-core/extensions.rb | 26 +++++++--- .../lib/middleman-core/meta_pages.rb | 2 +- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index d30e1625..64ce952e 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -179,11 +179,9 @@ module Middleman # Setup the default values from calls to set before initialization self.class.config.load_settings(self.class.superclass.config.all_settings) - # Parse YAML from templates. Must be before sitemap so sitemap - # extensions see updated frontmatter! - activate :front_matter - activate :data - activate :file_watcher + ::Middleman::Extensions.auto_activate[:before_sitemap].each do |ext_name| + activate ext_name + end # Initialize the Sitemap @sitemap = ::Middleman::Sitemap::Store.new(self) diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 1e3e738a..729ebdc3 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -1,24 +1,24 @@ -# File Change Notifier -Middleman::Extensions.register :file_watcher do - require 'middleman-core/core_extensions/file_watcher' - Middleman::CoreExtensions::FileWatcher -end - -# Data looks at the data/ folder for YAML files and makes them available -# to dynamic requests. -Middleman::Extensions.register :data do - require 'middleman-core/core_extensions/data' - Middleman::CoreExtensions::Data -end - # Parse YAML from templates -Middleman::Extensions.register :front_matter do +Middleman::Extensions.register :front_matter, auto_activate: :before_sitemap do require 'middleman-core/core_extensions/front_matter' Middleman::CoreExtensions::FrontMatter end +# Data looks at the data/ folder for YAML files and makes them available +# to dynamic requests. +Middleman::Extensions.register :data, auto_activate: :before_sitemap do + require 'middleman-core/core_extensions/data' + Middleman::CoreExtensions::Data +end + +# File Change Notifier +Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do + require 'middleman-core/core_extensions/file_watcher' + Middleman::CoreExtensions::FileWatcher +end + # External helpers looks in the helpers/ folder for helper modules -Middleman::Extensions.register :external_helpers, auto_activate_before_configuration: true do +Middleman::Extensions.register :external_helpers, auto_activate: :before_configuration do require 'middleman-core/core_extensions/external_helpers' Middleman::CoreExtensions::ExternalHelpers end @@ -27,7 +27,7 @@ end require 'middleman-core/core_extensions/rendering' # Setup default helpers -Middleman::Extensions.register :default_helpers, auto_activate_before_configuration: true do +Middleman::Extensions.register :default_helpers, auto_activate: :before_configuration do require 'middleman-core/core_extensions/default_helpers' Middleman::CoreExtensions::DefaultHelpers end @@ -35,11 +35,18 @@ end # Compass framework begin require 'middleman-core/core_extensions/compass' - Middleman::Extensions.register :compass, Middleman::CoreExtensions::Compass, auto_activate_before_configuration: true + Middleman::Extensions.register :compass, Middleman::CoreExtensions::Compass, auto_activate: :before_configuration rescue LoadError # Compass is not available, don't complain about it end +# Lorem provides a handful of helpful prototyping methods to generate +# words, paragraphs, fake images, names and email addresses. +Middleman::Extensions.register :lorem, auto_activate: :before_configuration do + require 'middleman-core/extensions/lorem' + Middleman::Extensions::Lorem +end + ### # Setup Optional Extensions ### @@ -102,13 +109,6 @@ Middleman::Extensions.register :directory_indexes do Middleman::Extensions::DirectoryIndexes end -# Lorem provides a handful of helpful prototyping methods to generate -# words, paragraphs, fake images, names and email addresses. -Middleman::Extensions.register :lorem, auto_activate_before_configuration: true do - require 'middleman-core/extensions/lorem' - Middleman::Extensions::Lorem -end - # AutomaticImageSizes inspects the images used in your dynamic templates # and automatically adds width and height attributes to their HTML # elements. diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index ea91c8cf..b6efa1d7 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -86,7 +86,7 @@ module Middleman ::Middleman::Extension.clear_after_extension_callbacks - ::Middleman::Extensions.auto_activate_before_configuration.each do |ext_name| + ::Middleman::Extensions.auto_activate[:before_configuration].each do |ext_name| activate ext_name end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 34be436b..519493be 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -1,5 +1,4 @@ require 'middleman-core/extension' -require 'set' module Middleman # The Extensions module is used to handle global registration and loading of Middleman Extensions. @@ -8,7 +7,12 @@ module Middleman # `middleman-core/core_extensions/extensions.rb`. module Extensions @registered = {} - @auto_activate_before_configuration = Set.new + @auto_activate = { + # Activate before the Sitemap is instantiated + before_sitemap: [], + # Activate the extension before `config.rb` and the `:before_configuration` hook. + before_configuration: [] + } class << self # @api private @@ -18,8 +22,10 @@ module Middleman attr_reader :registered # @api private - # A list of extensions that should be automatically loaded before `config.rb` is loaded and before the `:before_configuration` hook is run. Only internal, built-in Middleman extensions should be listed here. - attr_reader :auto_activate_before_configuration + # A list of extensions that should be automatically loaded at different points in the application startup lifecycle. + # Only internal, built-in Middleman extensions should be listed here. + # @return [Hash{Symbol => Symbol}] A hash from event name to extension name. + attr_reader :auto_activate # Register a new extension. Choose a name which will be # used to activate the extension in `config.rb`, like this: @@ -39,8 +45,7 @@ module Middleman # # @param [Symbol] name The name of the extension # @param [Class] extension_class The extension class (Must inherit from {Middleman::Extension}) - # @option options [Boolean] :auto_activate_before_configuration If set to true, this extension will be automatically - # activated before `config.rb` is loaded and before the `:before_configuration` hook is run. + # @option options [Boolean] :auto_activate If this is set to a lifecycle event (:before_configuration or :before_sitemap), this extension will be automatically activated at that point. # This is intended for use with built-in Middleman extensions and should not be used by third-party extensions. # @yield Instead of passing a module in namespace, you can provide # a block which returns your extension class. This gives @@ -66,7 +71,7 @@ module Middleman raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end - @auto_activate_before_configuration << name if options[:auto_activate_before_configuration] + @auto_activate[options[:auto_activate]] << name if options[:auto_activate] end # @api private @@ -96,6 +101,13 @@ module Middleman extension_class end + + # @api private + # A flattened list of all extensions which are automatically activated + # @return [Array] A list of extension names which are automatically activated. + def auto_activated + @auto_activate.values.flatten + end end end end diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index 5783670b..c21f25d7 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -63,7 +63,7 @@ module Middleman extension_config = {} @middleman.inst.extensions.each do |ext_name, extension| - next if ::Middleman::Extension.auto_activate_before_configuration.include? ext_name + next if ::Middleman::Extension.auto_activated.include? ext_name if extension.is_a?(Hash) # Multiple instance extension From ce914e508abb087b1bf04eed123d41f63b899676 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 26 May 2014 16:53:23 -0700 Subject: [PATCH 045/662] Make rubocop TrivialAccessors warnings less annoying --- .rubocop.yml | 2 ++ middleman-core/lib/middleman-core/configuration.rb | 1 - middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb | 1 - middleman-core/lib/middleman-core/template_context.rb | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 955ec1b6..4ac61fa8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -51,3 +51,5 @@ FormatString: Enabled: false CaseIndentation: IndentWhenRelativeTo: end +TrivialAccessors: + ExactNameMatch: true \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index 7c39a405..dd3fe8f7 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -162,7 +162,6 @@ module Middleman end # Whether or not there has been a value set beyond the default - # rubocop:disable TrivialAccessors def value_set? @value_set end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index bc3e20c9..4c4ca5d2 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -88,7 +88,6 @@ module Middleman module ProxyResourceInstanceMethods # Whether this page is a proxy # @return [Boolean] - # rubocop:disable TrivialAccessors def proxy? @proxied_to end diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index d6c78be9..48ccad41 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -47,7 +47,6 @@ module Middleman # @api private # @param [String] buf_was # @return [void] - # rubocop:disable TrivialAccessors def restore_buffer(buf_was) @_out_buf = buf_was end From b48a7675956fe2b1495f0a4ee5ed5ed5816a0a65 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 26 Apr 2014 12:56:50 -0700 Subject: [PATCH 046/662] Use alias_method instead of defining an alias method for current_page --- middleman-core/lib/middleman-core/sitemap.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb index 3a66cebb..c320369c 100644 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ b/middleman-core/lib/middleman-core/sitemap.rb @@ -37,18 +37,13 @@ module Middleman @locs[:current_path] end - # Get the resource object for the current path - # @return [Middleman::Sitemap::Resource] - def current_page - current_resource - end - # Get the resource object for the current path # @return [Middleman::Sitemap::Resource] def current_resource return nil unless current_path sitemap.find_resource_by_destination_path(current_path) end + alias_method :current_page, :current_resource end end end From 7a5865a4073bde576355d76c86f4227db17e97d4 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 23:05:18 -0700 Subject: [PATCH 047/662] gsub to sub --- middleman-core/lib/middleman-core/core_extensions/i18n.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index bf7033b3..e83f7cfc 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -183,7 +183,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension File.join(prefix, path.sub(page_id, localized_page_id)) ) - path.gsub!(options[:templates_dir] + '/', '') + path = path.sub(options[:templates_dir] + '/', '') @_localization_data[path] = [lang, path, localized_page_id] From c2512e909360d6c700d7057611885ea3c739a3b9 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 26 May 2014 17:58:35 -0700 Subject: [PATCH 048/662] update more files to non-hashrocket syntax --- middleman-cli/lib/middleman-cli/console.rb | 2 +- middleman-cli/lib/middleman-cli/init.rb | 9 ++-- middleman-core/features/asset_hash.feature | 2 +- middleman-core/features/asset_host.feature | 4 +- middleman-core/features/content_type.feature | 4 +- .../features/helpers_content_tag.feature | 4 +- .../features/helpers_form_tag.feature | 8 ++-- .../features/helpers_link_to.feature | 22 ++++----- .../features/helpers_url_for.feature | 22 ++++----- middleman-core/features/i18n_builder.feature | 10 ++-- middleman-core/features/i18n_preview.feature | 16 +++---- .../features/markdown_kramdown.feature | 2 +- .../features/markdown_redcarpet.feature | 46 +++++++++---------- middleman-core/features/minify_css.feature | 12 ++--- .../features/minify_javascript.feature | 18 ++++---- middleman-core/features/mount_rack.feature | 4 +- middleman-core/features/redirects.feature | 12 ++--- .../step_definitions/page_layout_steps.rb | 2 +- .../fixtures/asset-hash-app/config.rb | 2 - .../clean-app/config-complications.rb | 8 ++-- middleman-core/fixtures/clean-app/config.rb | 8 ++-- .../fixtures/custom-layout-app/config.rb | 2 +- middleman-core/fixtures/data-app/config.rb | 2 +- .../fixtures/dynamic-pages-app/config.rb | 40 ++++++++-------- .../fixtures/external-helpers/config.rb | 2 +- .../fixtures/feature-params-app/config.rb | 2 +- .../frontmatter-settings-app/config.rb | 4 +- .../config.rb | 4 +- .../fixtures/generator-test/config.rb | 6 +-- middleman-core/fixtures/glob-app/config.rb | 2 +- .../fixtures/i18n-force-locale/config.rb | 4 +- .../fixtures/indexable-app/config.rb | 4 +- .../fixtures/manual-layout-override/config.rb | 2 +- .../fixtures/markdown-app/config.rb | 2 +- .../config.rb | 2 +- .../more-frontmatter-settings-app/config.rb | 2 +- .../fixtures/more-traversal-app/config.rb | 8 ++-- .../source/former_padrino_test.html.erb | 6 +-- .../2-starts-with-numeric-custom.html.erb | 2 +- .../page-helper-layout-block-app/config.rb | 2 +- .../partials-app/source/locals.html.erb | 2 +- .../fixtures/proxy-pages-app/config.rb | 24 +++++----- .../fixtures/traversal-app/config.rb | 8 ++-- .../fixtures/wildcard-app/config.rb | 2 +- .../wildcard-directory-index-app/config.rb | 2 +- .../middleman-core/core_extensions/routing.rb | 4 +- .../lib/middleman-templates/shared/Gemfile.tt | 2 +- .../lib/middleman-templates/shared/config.tt | 6 +-- 48 files changed, 180 insertions(+), 185 deletions(-) diff --git a/middleman-cli/lib/middleman-cli/console.rb b/middleman-cli/lib/middleman-cli/console.rb index 31a824e5..79bf2cfe 100644 --- a/middleman-cli/lib/middleman-cli/console.rb +++ b/middleman-cli/lib/middleman-cli/console.rb @@ -1,7 +1,7 @@ # CLI Module module Middleman::Cli # Alias "c" to "console" - Base.map('c' => 'console') + Base.map(c: 'console') # The CLI Console class class Console < Thor diff --git a/middleman-cli/lib/middleman-cli/init.rb b/middleman-cli/lib/middleman-cli/init.rb index 901f00cf..444f4c6b 100644 --- a/middleman-cli/lib/middleman-cli/init.rb +++ b/middleman-cli/lib/middleman-cli/init.rb @@ -15,13 +15,10 @@ module Middleman::Cli default: 'default', desc: "Use a project template: #{available_templates}" method_option 'css_dir', - # :default => "stylesheets", desc: 'The path to the css files' method_option 'js_dir', - # :default => "javascripts", desc: 'The path to the javascript files' method_option 'images_dir', - # :default => "images", desc: 'The path to the image files' method_option 'rack', type: :boolean, @@ -55,8 +52,8 @@ module Middleman::Cli # Map "i", "new" and "n" to "init" Base.map( - 'i' => 'init', - 'new' => 'init', - 'n' => 'init' + 'i' => 'init', + 'new' => 'init', + 'n' => 'init' ) end diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 59c92d29..ec4d7b95 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -109,7 +109,7 @@ Feature: Assets get a file hash appended to their and references to them are upd Given a fixture app "asset-hash-app" And a file named "config.rb" with: """ - activate :asset_hash, :ignore => [%r(javascripts/*), 'images/*'] + activate :asset_hash, ignore: [%r(javascripts/*), 'images/*'] activate :relative_assets activate :directory_indexes """ diff --git a/middleman-core/features/asset_host.feature b/middleman-core/features/asset_host.feature index 30746473..eb82f43b 100644 --- a/middleman-core/features/asset_host.feature +++ b/middleman-core/features/asset_host.feature @@ -33,7 +33,7 @@ Feature: Alternate between multiple asset hosts Given a fixture app "asset-host-app" And a file named "config.rb" with: """ - activate :asset_host, :host => "http://assets1.example.com" + activate :asset_host, host: "http://assets1.example.com" """ And the Server is running When I go to "/asset_host.html" @@ -45,7 +45,7 @@ Feature: Alternate between multiple asset hosts Given a fixture app "asset-host-app" And a file named "config.rb" with: """ - activate :asset_host, :host => Proc.new { |asset| + activate :asset_host, host: Proc.new { |asset| "http://assets%d.example.com" % (asset.hash % 4) } """ diff --git a/middleman-core/features/content_type.feature b/middleman-core/features/content_type.feature index 175361d8..96c88ccc 100644 --- a/middleman-core/features/content_type.feature +++ b/middleman-core/features/content_type.feature @@ -17,8 +17,8 @@ Feature: Setting the right content type for files Given a fixture app "content-type-app" And a file named "config.rb" with: """ - page "README", :content_type => 'text/awesome' - proxy "bar", "index.html", :content_type => 'text/custom' + page "README", content_type: 'text/awesome' + proxy "bar", "index.html", content_type: 'text/custom' proxy "foo", "README" # auto-delegate to target content type """ And the Server is running at "content-type-app" diff --git a/middleman-core/features/helpers_content_tag.feature b/middleman-core/features/helpers_content_tag.feature index 4c54aae7..16d57957 100644 --- a/middleman-core/features/helpers_content_tag.feature +++ b/middleman-core/features/helpers_content_tag.feature @@ -5,8 +5,8 @@ Feature: content_tag helper And an empty file named "config.rb" And a file named "source/index.html.erb" with: """ - <%= content_tag :div, "world", :class => 'one' %> - <% content_tag :where, :class => 'the hell is' do %> + <%= content_tag :div, "world", class: 'one' %> + <% content_tag :where, class: 'the hell is' do %> damn croissant <% end %> """ diff --git a/middleman-core/features/helpers_form_tag.feature b/middleman-core/features/helpers_form_tag.feature index 643ca18a..f1abaf5f 100644 --- a/middleman-core/features/helpers_form_tag.feature +++ b/middleman-core/features/helpers_form_tag.feature @@ -5,16 +5,16 @@ Feature: form_tag helper 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 %> + absolute: <% form_tag "/needs_index.html#absolute", relative: true do %> <% end %> - relative: <% form_tag "needs_index.html#relative", :relative => true do %> + 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 %> + absolute: <% form_tag "/needs_index.html#absolute", relative: true do %> <% end %> - relative: <% form_tag "../needs_index.html#relative", :relative => true do %> + relative: <% form_tag "../needs_index.html#relative", relative: true do %> <% end %> """ And the Server is running at "indexable-app" diff --git a/middleman-core/features/helpers_link_to.feature b/middleman-core/features/helpers_link_to.feature index 162c1e8a..18d0c497 100644 --- a/middleman-core/features/helpers_link_to.feature +++ b/middleman-core/features/helpers_link_to.feature @@ -20,13 +20,13 @@ Feature: link_to helper And an empty file named "config.rb" And a file named "source/link_to.html.erb" with: """ - absolute: <%= link_to "Needs Index", "/needs_index.html", :relative => true %> - relative: <%= link_to "Relative", "needs_index.html", :relative => true %> + absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %> + relative: <%= link_to "Relative", "needs_index.html", relative: true %> """ And a file named "source/link_to/sub.html.erb" with: """ - absolute: <%= link_to "Needs Index", "/needs_index.html", :relative => true %> - relative: <%= link_to "Relative", "../needs_index.html", :relative => true %> + absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %> + relative: <%= link_to "Relative", "../needs_index.html", relative: true %> """ And the Server is running at "indexable-app" When I go to "/link_to.html" @@ -79,7 +79,7 @@ Feature: link_to helper And a file named "source/link_to.html.erb" with: """ absolute: <%= link_to "Needs Index", "/needs_index.html" %> - relative: <%= link_to "Relative", "needs_index.html", :relative => false %> + relative: <%= link_to "Relative", "needs_index.html", relative: false %> unknown: <%= link_to "Unknown", "foo.html" %> """ And a file named "source/link_to/sub.html.erb" with: @@ -100,13 +100,13 @@ Feature: link_to helper Given a fixture app "indexable-app" And a file named "source/link_to.html.erb" with: """ - absolute: <%= link_to "Needs Index", "/needs_index.html", :relative => true %> - relative: <%= link_to "Relative", "needs_index.html", :relative => true %> + absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %> + relative: <%= link_to "Relative", "needs_index.html", relative: true %> """ And a file named "source/link_to/sub.html.erb" with: """ - absolute: <%= link_to "Needs Index", "/needs_index.html", :relative => true %> - relative: <%= link_to "Relative", "../needs_index.html", :relative => true %> + absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %> + relative: <%= link_to "Relative", "../needs_index.html", relative: true %> """ And the Server is running at "indexable-app" When I go to "/link_to/" @@ -158,8 +158,8 @@ Feature: link_to helper Given a fixture app "indexable-app" And a file named "source/link_to.html.erb" with: """ - <%= link_to "Needs Index String", "/needs_index.html", :query => "foo" %> - <%= link_to "Needs Index Hash", "/needs_index.html", :query => { :foo => :bar } %> + <%= link_to "Needs Index String", "/needs_index.html", query: "foo" %> + <%= link_to "Needs Index Hash", "/needs_index.html", query: { foo: :bar } %> """ And the Server is running at "indexable-app" When I go to "/link_to/" diff --git a/middleman-core/features/helpers_url_for.feature b/middleman-core/features/helpers_url_for.feature index c2b5a5a8..840dcc9d 100644 --- a/middleman-core/features/helpers_url_for.feature +++ b/middleman-core/features/helpers_url_for.feature @@ -5,13 +5,13 @@ Feature: url_for helper 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 %> + 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 %> + 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" @@ -64,7 +64,7 @@ Feature: url_for helper And a file named "source/url_for.html.erb" with: """ absolute: <%= url_for "/needs_index.html" %> - relative: <%= url_for "needs_index.html", :relative => false %> + relative: <%= url_for "needs_index.html", relative: false %> unknown: <%= url_for "foo.html" %> """ And a file named "source/url_for/sub.html.erb" with: @@ -85,13 +85,13 @@ Feature: url_for helper 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 %> + 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 %> + 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/" @@ -143,8 +143,8 @@ Feature: url_for helper 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 } %> + 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/" diff --git a/middleman-core/features/i18n_builder.feature b/middleman-core/features/i18n_builder.feature index 34a802b1..6129f250 100644 --- a/middleman-core/features/i18n_builder.feature +++ b/middleman-core/features/i18n_builder.feature @@ -49,7 +49,7 @@ Feature: i18n Builder Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :path => "/lang_:locale/" + activate :i18n, path: "/lang_:locale/" """ Given a successfully built app at "i18n-test-app" When I cd to "build" @@ -69,7 +69,7 @@ Feature: i18n Builder Given a fixture app "i18n-alt-root-app" And a file named "config.rb" with: """ - activate :i18n, :templates_dir => "lang_data" + activate :i18n, templates_dir: "lang_data" """ Given a successfully built app at "i18n-alt-root-app" When I cd to "build" @@ -89,7 +89,7 @@ Feature: i18n Builder Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :lang_map => { :en => :english, :es => :spanish } + activate :i18n, lang_map: { en: :english, es: :spanish } """ Given a successfully built app at "i18n-test-app" When I cd to "build" @@ -109,7 +109,7 @@ Feature: i18n Builder Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :mount_at_root => false + activate :i18n, mount_at_root: false """ Given a successfully built app at "i18n-test-app" When I cd to "build" @@ -130,7 +130,7 @@ Feature: i18n Builder Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :langs => [:en] + activate :i18n, langs: [:en] """ Given a successfully built app at "i18n-test-app" When I cd to "build" diff --git a/middleman-core/features/i18n_preview.feature b/middleman-core/features/i18n_preview.feature index 93c60dc1..4b96efcf 100644 --- a/middleman-core/features/i18n_preview.feature +++ b/middleman-core/features/i18n_preview.feature @@ -67,7 +67,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :path => "/lang_:locale/" + activate :i18n, path: "/lang_:locale/" """ Given the Server is running at "i18n-test-app" When I go to "/" @@ -86,7 +86,7 @@ Feature: i18n Preview Given a fixture app "i18n-alt-root-app" And a file named "config.rb" with: """ - activate :i18n, :templates_dir => "lang_data" + activate :i18n, templates_dir: "lang_data" """ Given the Server is running at "i18n-alt-root-app" When I go to "/" @@ -104,7 +104,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :lang_map => { :en => :english, :es => :spanish } + activate :i18n, lang_map: { en: :english, es: :spanish } """ Given the Server is running at "i18n-test-app" When I go to "/" @@ -122,7 +122,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :mount_at_root => :es + activate :i18n, mount_at_root: :es """ Given the Server is running at "i18n-test-app" When I go to "/en/index.html" @@ -150,7 +150,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :langs => :es + activate :i18n, langs: :es """ Given the Server is running at "i18n-test-app" When I go to "/en/index.html" @@ -173,7 +173,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :mount_at_root => false + activate :i18n, mount_at_root: false """ Given the Server is running at "i18n-test-app" When I go to "/en/index.html" @@ -193,7 +193,7 @@ Feature: i18n Preview Given a fixture app "i18n-test-app" And a file named "config.rb" with: """ - activate :i18n, :langs => [:en] + activate :i18n, langs: [:en] """ Given the Server is running at "i18n-test-app" When I go to "/" @@ -228,7 +228,7 @@ Feature: i18n Preview Given a fixture app "i18n-default-app" And a file named "config.rb" with: """ - activate :i18n, :mount_at_root => :es + activate :i18n, mount_at_root: :es """ Given the Server is running at "i18n-default-app" When I go to "/en/" diff --git a/middleman-core/features/markdown_kramdown.feature b/middleman-core/features/markdown_kramdown.feature index 3f64a44c..667aa58f 100644 --- a/middleman-core/features/markdown_kramdown.feature +++ b/middleman-core/features/markdown_kramdown.feature @@ -6,7 +6,7 @@ Feature: Markdown (Kramdown) support And a file named "config.rb" with: """ set :markdown_engine, :kramdown - set :markdown, :smartypants => true + set :markdown, smartypants: true """ Given the Server is running at "markdown-app" When I go to "/smarty_pants.html" diff --git a/middleman-core/features/markdown_redcarpet.feature b/middleman-core/features/markdown_redcarpet.feature index 7eec709b..947e59b1 100644 --- a/middleman-core/features/markdown_redcarpet.feature +++ b/middleman-core/features/markdown_redcarpet.feature @@ -7,14 +7,14 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :no_intra_emphasis => true, - :tables => true, - :fenced_code_blocks => true, - :autolink => true, - :strikethrough => true, - :space_after_headers => true, - :superscript => true, - :lax_spacing => true + set :markdown, no_intra_emphasis: true, + tables: true, + fenced_code_blocks: true, + autolink: true, + strikethrough: true, + space_after_headers: true, + superscript: true, + lax_spacing: true """ Given the Server is running at "markdown-app" @@ -42,9 +42,9 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :underline => true, - :highlight => true, - :disable_indented_code_blocks => true + set :markdown, underline: true, + highlight: true, + disable_indented_code_blocks: true """ Given the Server is running at "markdown-app" When I go to "/underline.html" @@ -59,7 +59,7 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :smartypants => true + set :markdown, smartypants: true """ Given the Server is running at "markdown-app" When I go to "/smarty_pants.html" @@ -70,13 +70,13 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :filter_html => true, - :no_images => true, - :no_links => true, - :with_toc_data => true, - :hard_wrap => true, - :safe_links_only => true, - :prettify => true + set :markdown, filter_html: true, + no_images: true, + no_links: true, + with_toc_data: true, + hard_wrap: true, + safe_links_only: true, + prettify: true """ Given the Server is running at "markdown-app" @@ -103,7 +103,7 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :link_attributes => { :target => "_blank" } + set :markdown, link_attributes: { target: "_blank" } """ And a file named "source/link.html.markdown" with: """ @@ -118,8 +118,8 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :xhtml => true, - :hard_wrap => true + set :markdown, xhtml: true, + hard_wrap: true """ Given the Server is running at "markdown-app" When I go to "/hard_wrap.html" @@ -130,7 +130,7 @@ Feature: Markdown (Redcarpet) support And a file named "config.rb" with: """ set :markdown_engine, :redcarpet - set :markdown, :smartypants => true + set :markdown, smartypants: true """ Given the Server is running at "markdown-frontmatter-options-app" When I go to "/smarty_pants-default.html" diff --git a/middleman-core/features/minify_css.feature b/middleman-core/features/minify_css.feature index e6bc948f..87238eb4 100644 --- a/middleman-core/features/minify_css.feature +++ b/middleman-core/features/minify_css.feature @@ -36,7 +36,7 @@ Feature: Minify CSS end end - activate :minify_css, :compressor => ::PassThrough + activate :minify_css, compressor: ::PassThrough """ And the Server is running at "passthrough-app" When I go to "/stylesheets/site.css" @@ -69,9 +69,9 @@ Feature: Minify CSS end end - activate :minify_css, :inline => true, :compressor => ::PassThrough + activate :minify_css, inline: true, compressor: ::PassThrough - page "/inline-css.html", :layout => false + page "/inline-css.html", layout: false """ And the Server is running at "passthrough-app" When I go to "/inline-css.html" @@ -94,9 +94,9 @@ Feature: Minify CSS end end - activate :minify_css, :inline => true, :compressor => ::HelloCompressor + activate :minify_css, inline: true, compressor: ::HelloCompressor - page "/inline-css.html", :layout => false + page "/inline-css.html", layout: false """ And the Server is running at "passthrough-app" When I go to "/inline-css.html" @@ -111,7 +111,7 @@ Feature: Minify CSS Given a fixture app "minify-css-app" And a file named "config.rb" with: """ - activate :minify_css, :inline => true + activate :minify_css, inline: true """ And the Server is running at "minify-css-app" When I go to "/inline-css.html" diff --git a/middleman-core/features/minify_javascript.feature b/middleman-core/features/minify_javascript.feature index 73e05f44..1a4f0c49 100644 --- a/middleman-core/features/minify_javascript.feature +++ b/middleman-core/features/minify_javascript.feature @@ -49,9 +49,9 @@ Feature: Minify Javascript end end - activate :minify_javascript, :inline => true, :compressor => ::PassThrough + activate :minify_javascript, inline: true, compressor: ::PassThrough - page "/inline-js.html", :layout => false + page "/inline-js.html", layout: false """ And the Server is running at "passthrough-app" When I go to "/inline-js.html" @@ -96,9 +96,9 @@ Feature: Minify Javascript end end - activate :minify_javascript, :inline => true, :compressor => ::HelloCompressor + activate :minify_javascript, inline: true, compressor: ::HelloCompressor - page "/inline-js.html", :layout => false + page "/inline-js.html", layout: false """ And the Server is running at "passthrough-app" When I go to "/inline-js.html" @@ -124,7 +124,7 @@ Feature: Minify Javascript Given a fixture app "minify-js-app" And a file named "config.rb" with: """ - activate :minify_javascript, :inline => true + activate :minify_javascript, inline: true """ And the Server is running at "minify-js-app" When I go to "/inline-js.html" @@ -167,7 +167,7 @@ Feature: Minify Javascript Given a fixture app "minify-js-app" And a file named "config.rb" with: """ - activate :minify_javascript, :inline => true + activate :minify_javascript, inline: true """ And the Server is running at "minify-js-app" When I go to "/inline-coffeescript.html" @@ -193,9 +193,9 @@ Feature: Minify Javascript end end - activate :minify_javascript, :inline => true, :compressor => ::PassThrough + activate :minify_javascript, inline: true, compressor: ::PassThrough - page "/inline-coffeescript.html", :layout => false + page "/inline-coffeescript.html", layout: false """ And the Server is running at "passthrough-app" When I go to "/inline-coffeescript.html" @@ -211,7 +211,7 @@ Feature: Minify Javascript end end - activate :minify_javascript, :compressor => ::PassThrough + activate :minify_javascript, compressor: ::PassThrough """ And the Server is running at "passthrough-app" When I go to "/javascripts/coffee_test.js" diff --git a/middleman-core/features/mount_rack.feature b/middleman-core/features/mount_rack.feature index b2dbe5a0..ab105021 100644 --- a/middleman-core/features/mount_rack.feature +++ b/middleman-core/features/mount_rack.feature @@ -48,10 +48,10 @@ Feature: Support Rack apps mounted using map end configure :build do - endpoint "sinatra/index2.html", :path => "/sinatra/" + endpoint "sinatra/index2.html", path: "/sinatra/" end - endpoint "dedoo.html", :path => "/sinatra/derp.html" + endpoint "dedoo.html", path: "/sinatra/derp.html" endpoint "hello.html" do "world" diff --git a/middleman-core/features/redirects.feature b/middleman-core/features/redirects.feature index bcbe3baf..242be842 100644 --- a/middleman-core/features/redirects.feature +++ b/middleman-core/features/redirects.feature @@ -4,7 +4,7 @@ Feature: Meta redirects Given a fixture app "large-build-app" And a file named "config.rb" with: """ - redirect "hello.html", :to => "world.html" + redirect "hello.html", to: "world.html" """ And the Server is running at "large-build-app" When I go to "/hello.html" @@ -14,7 +14,7 @@ Feature: Meta redirects Given a fixture app "large-build-app" And a file named "config.rb" with: """ - redirect "hello.html", :to => "http://example.com" + redirect "hello.html", to: "http://example.com" """ And the Server is running at "large-build-app" When I go to "/hello.html" @@ -26,7 +26,7 @@ Feature: Meta redirects """ ready do r = sitemap.find_resource_by_path("static.html") - redirect "hello.html", :to => r + redirect "hello.html", to: r end """ And the Server is running at "large-build-app" @@ -38,8 +38,8 @@ Feature: Meta redirects And a file named "config.rb" with: """ activate :directory_indexes - redirect "hello.html", :to => "link_test.html" - redirect "hello2.html", :to => "services/index.html" + redirect "hello.html", to: "link_test.html" + redirect "hello2.html", to: "services/index.html" """ And the Server is running at "large-build-app" When I go to "/hello/index.html" @@ -51,7 +51,7 @@ Feature: Meta redirects Given a fixture app "large-build-app" And a file named "config.rb" with: """ - redirect "hello.html", :to => "world.html" do |from, to| + redirect "hello.html", to: "world.html" do |from, to| "#{from} to #{to}" end """ diff --git a/middleman-core/features/step_definitions/page_layout_steps.rb b/middleman-core/features/step_definitions/page_layout_steps.rb index 311b4d4d..46a27026 100644 --- a/middleman-core/features/step_definitions/page_layout_steps.rb +++ b/middleman-core/features/step_definitions/page_layout_steps.rb @@ -1,6 +1,6 @@ Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout| @initialize_commands ||= [] @initialize_commands << lambda { - page(url, :layout => layout.to_sym) + page(url, layout: layout.to_sym) } end diff --git a/middleman-core/fixtures/asset-hash-app/config.rb b/middleman-core/fixtures/asset-hash-app/config.rb index cee0d36f..1327d8f0 100644 --- a/middleman-core/fixtures/asset-hash-app/config.rb +++ b/middleman-core/fixtures/asset-hash-app/config.rb @@ -4,5 +4,3 @@ activate :asset_hash activate :relative_assets activate :directory_indexes - -#page '/foo.html', :directory_index => false diff --git a/middleman-core/fixtures/clean-app/config-complications.rb b/middleman-core/fixtures/clean-app/config-complications.rb index 14d6c328..a958bf5a 100644 --- a/middleman-core/fixtures/clean-app/config-complications.rb +++ b/middleman-core/fixtures/clean-app/config-complications.rb @@ -1,11 +1,11 @@ -page "/fake.html", :proxy => "/real.html", :layout => false +page "/fake.html", proxy: "/real.html", layout: false ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", :ignore => true -page "/target_ignore.html", :proxy => "/should_be_ignored3.html", :ignore => true +page "/should_be_ignored2.html", ignore: true +page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true %w(one two).each do |num| - page "/fake/#{num}.html", :proxy => "/real/index.html" do + page "/fake/#{num}.html", proxy: "/real/index.html" do @num = num end end diff --git a/middleman-core/fixtures/clean-app/config.rb b/middleman-core/fixtures/clean-app/config.rb index 14d6c328..a958bf5a 100644 --- a/middleman-core/fixtures/clean-app/config.rb +++ b/middleman-core/fixtures/clean-app/config.rb @@ -1,11 +1,11 @@ -page "/fake.html", :proxy => "/real.html", :layout => false +page "/fake.html", proxy: "/real.html", layout: false ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", :ignore => true -page "/target_ignore.html", :proxy => "/should_be_ignored3.html", :ignore => true +page "/should_be_ignored2.html", ignore: true +page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true %w(one two).each do |num| - page "/fake/#{num}.html", :proxy => "/real/index.html" do + page "/fake/#{num}.html", proxy: "/real/index.html" do @num = num end end diff --git a/middleman-core/fixtures/custom-layout-app/config.rb b/middleman-core/fixtures/custom-layout-app/config.rb index 3eba9c4e..d8a232b3 100644 --- a/middleman-core/fixtures/custom-layout-app/config.rb +++ b/middleman-core/fixtures/custom-layout-app/config.rb @@ -1 +1 @@ -set :erb, :layout_engine => :str +set :erb, layout_engine: :str diff --git a/middleman-core/fixtures/data-app/config.rb b/middleman-core/fixtures/data-app/config.rb index 137883e2..1d0d0ba7 100644 --- a/middleman-core/fixtures/data-app/config.rb +++ b/middleman-core/fixtures/data-app/config.rb @@ -1,3 +1,3 @@ data.pages.each do |p| - page p.from, :proxy => p.to + page p.from, proxy: p.to end diff --git a/middleman-core/fixtures/dynamic-pages-app/config.rb b/middleman-core/fixtures/dynamic-pages-app/config.rb index 8f62dd0a..db5990d8 100644 --- a/middleman-core/fixtures/dynamic-pages-app/config.rb +++ b/middleman-core/fixtures/dynamic-pages-app/config.rb @@ -1,30 +1,30 @@ # -*- coding: utf-8 -*- -page "/fake.html", :proxy => "/real.html", :layout => false -page "fake2.html", :proxy => "/real.html", :layout => false -page "fake3.html", :proxy => "real.html", :layout => false -page "/fake4.html", :proxy => "real.html", :layout => false +page "/fake.html", proxy: "/real.html", layout: false +page "fake2.html", proxy: "/real.html", layout: false +page "fake3.html", proxy: "real.html", layout: false +page "/fake4.html", proxy: "real.html", layout: false ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", :ignore => true -page "/target_ignore.html", :proxy => "/should_be_ignored3.html", :ignore => true +page "/should_be_ignored2.html", ignore: true +page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true ignore "should_be_ignored4.html" -page "should_be_ignored5.html", :ignore => true -page "target_ignore2.html", :proxy => "/should_be_ignored6.html", :ignore => true -page "target_ignore3.html", :proxy => "should_be_ignored7.html", :ignore => true -page "/target_ignore4.html", :proxy => "should_be_ignored8.html", :ignore => true +page "should_be_ignored5.html", ignore: true +page "target_ignore2.html", proxy: "/should_be_ignored6.html", ignore: true +page "target_ignore3.html", proxy: "should_be_ignored7.html", ignore: true +page "/target_ignore4.html", proxy: "should_be_ignored8.html", ignore: true %w(one two).each do |num| - page "/fake/#{num}.html", :proxy => "/real/index.html", :ignore => true, :locals => { :num => num } - page "fake2/#{num}.html", :proxy => "/real/index.html", :ignore => true, :locals => { :num => num } - page "fake3/#{num}.html", :proxy => "real/index.html", :ignore => true, :locals => { :num => num } - page "/fake4/#{num}.html", :proxy => "real/index.html", :ignore => true, :locals => { :num => num } + page "/fake/#{num}.html", proxy: "/real/index.html", ignore: true, locals: { num: num } + page "fake2/#{num}.html", proxy: "/real/index.html", ignore: true, locals: { num: num } + page "fake3/#{num}.html", proxy: "real/index.html", ignore: true, locals: { num: num } + page "/fake4/#{num}.html", proxy: "real/index.html", ignore: true, locals: { num: num } end -page "明日がある.html", :proxy => "/real.html", :layout => false +page "明日がある.html", proxy: "/real.html", layout: false -page "f*/*", :locals => { :all_glob => "I am all glob" } -page "fake/*", :locals => { :glob_var => "I am one glob" } -page "fake2/*", :locals => { :glob_var => "I am two glob" } -page "fake3/*", :locals => { :glob_var => "I am three glob" } -page "fake4/*", :locals => { :glob_var => "I am four glob" } +page "f*/*", locals: { all_glob: "I am all glob" } +page "fake/*", locals: { glob_var: "I am one glob" } +page "fake2/*", locals: { glob_var: "I am two glob" } +page "fake3/*", locals: { glob_var: "I am three glob" } +page "fake4/*", locals: { glob_var: "I am four glob" } diff --git a/middleman-core/fixtures/external-helpers/config.rb b/middleman-core/fixtures/external-helpers/config.rb index ed4da581..a3786e29 100644 --- a/middleman-core/fixtures/external-helpers/config.rb +++ b/middleman-core/fixtures/external-helpers/config.rb @@ -1,4 +1,4 @@ require "lib/hello_helper" helpers HelloHelper -page "/", :layout => false +page "/", layout: false diff --git a/middleman-core/fixtures/feature-params-app/config.rb b/middleman-core/fixtures/feature-params-app/config.rb index 7e2bc2ef..bd114b94 100644 --- a/middleman-core/fixtures/feature-params-app/config.rb +++ b/middleman-core/fixtures/feature-params-app/config.rb @@ -13,4 +13,4 @@ end Middleman::Extensions.register :extension_a, ExtensionA -activate :extension_a, :hello => "world", :hola => "mundo" +activate :extension_a, hello: "world", hola: "mundo" diff --git a/middleman-core/fixtures/frontmatter-settings-app/config.rb b/middleman-core/fixtures/frontmatter-settings-app/config.rb index 74cda623..7e6a7bf9 100644 --- a/middleman-core/fixtures/frontmatter-settings-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-app/config.rb @@ -1,4 +1,4 @@ # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', :proxy => 'ignored.html' -page 'override_layout.html', :layout => :alternate +page 'proxied.html', proxy: 'ignored.html' +page 'override_layout.html', layout: :alternate page 'page_mentioned.html' diff --git a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb index 74cda623..7e6a7bf9 100644 --- a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb @@ -1,4 +1,4 @@ # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', :proxy => 'ignored.html' -page 'override_layout.html', :layout => :alternate +page 'proxied.html', proxy: 'ignored.html' +page 'override_layout.html', layout: :alternate page 'page_mentioned.html' diff --git a/middleman-core/fixtures/generator-test/config.rb b/middleman-core/fixtures/generator-test/config.rb index e753409f..9fc9561c 100644 --- a/middleman-core/fixtures/generator-test/config.rb +++ b/middleman-core/fixtures/generator-test/config.rb @@ -18,13 +18,13 @@ # Per-page layout changes: # # With no layout -# page "/path/to/file.html", :layout => false +# page "/path/to/file.html", layout: false # # With alternative layout -# page "/path/to/file.html", :layout => :otherlayout +# page "/path/to/file.html", layout: :otherlayout # Proxy (fake) files -# page "/this-page-has-no-template.html", :proxy => "/template-file.html" do +# page "/this-page-has-no-template.html", proxy: "/template-file.html" do # @which_fake_page = "Rendering a fake page with a variable" # end diff --git a/middleman-core/fixtures/glob-app/config.rb b/middleman-core/fixtures/glob-app/config.rb index 8bd82176..6ed9b403 100644 --- a/middleman-core/fixtures/glob-app/config.rb +++ b/middleman-core/fixtures/glob-app/config.rb @@ -1 +1 @@ -page "/index.html", :layout => false +page "/index.html", layout: false diff --git a/middleman-core/fixtures/i18n-force-locale/config.rb b/middleman-core/fixtures/i18n-force-locale/config.rb index 4058360e..574a9fd5 100644 --- a/middleman-core/fixtures/i18n-force-locale/config.rb +++ b/middleman-core/fixtures/i18n-force-locale/config.rb @@ -1,8 +1,8 @@ [:en, :es].each do |locale| - proxy "/#{locale}/index.html", "index.html", :ignore => true, :lang => locale + proxy "/#{locale}/index.html", "index.html", ignore: true, lang: locale end -proxy "/fr/index.html", "index.html", :lang => :fr +proxy "/fr/index.html", "index.html", lang: :fr activate :i18n diff --git a/middleman-core/fixtures/indexable-app/config.rb b/middleman-core/fixtures/indexable-app/config.rb index 54b79b5c..fdccfcbb 100644 --- a/middleman-core/fixtures/indexable-app/config.rb +++ b/middleman-core/fixtures/indexable-app/config.rb @@ -1,4 +1,4 @@ activate :directory_indexes -page "/leave_me_alone.html", :directory_index => false +page "/leave_me_alone.html", directory_index: false -page "/wildcard*", :directory_index => false +page "/wildcard*", directory_index: false diff --git a/middleman-core/fixtures/manual-layout-override/config.rb b/middleman-core/fixtures/manual-layout-override/config.rb index 352071ff..cb14059b 100644 --- a/middleman-core/fixtures/manual-layout-override/config.rb +++ b/middleman-core/fixtures/manual-layout-override/config.rb @@ -1,3 +1,3 @@ set :layout, :custom -page "/", :layout => :another +page "/", layout: :another diff --git a/middleman-core/fixtures/markdown-app/config.rb b/middleman-core/fixtures/markdown-app/config.rb index 55b36b24..01b533a6 100644 --- a/middleman-core/fixtures/markdown-app/config.rb +++ b/middleman-core/fixtures/markdown-app/config.rb @@ -1 +1 @@ -set :markdown, :smartypants => true +set :markdown, smartypants: true diff --git a/middleman-core/fixtures/markdown-frontmatter-options-app/config.rb b/middleman-core/fixtures/markdown-frontmatter-options-app/config.rb index 55b36b24..01b533a6 100644 --- a/middleman-core/fixtures/markdown-frontmatter-options-app/config.rb +++ b/middleman-core/fixtures/markdown-frontmatter-options-app/config.rb @@ -1 +1 @@ -set :markdown, :smartypants => true +set :markdown, smartypants: true diff --git a/middleman-core/fixtures/more-frontmatter-settings-app/config.rb b/middleman-core/fixtures/more-frontmatter-settings-app/config.rb index 3c393758..f0a890d2 100644 --- a/middleman-core/fixtures/more-frontmatter-settings-app/config.rb +++ b/middleman-core/fixtures/more-frontmatter-settings-app/config.rb @@ -1,4 +1,4 @@ activate :directory_indexes # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', :proxy => 'ignored.html' +page 'proxied.html', proxy: 'ignored.html' diff --git a/middleman-core/fixtures/more-traversal-app/config.rb b/middleman-core/fixtures/more-traversal-app/config.rb index c031e945..051a262d 100644 --- a/middleman-core/fixtures/more-traversal-app/config.rb +++ b/middleman-core/fixtures/more-traversal-app/config.rb @@ -1,7 +1,7 @@ activate :directory_indexes -page "/sub/fake.html", :proxy => "/proxied.html", :ignore => true -page "/sub/fake2.html", :proxy => "/proxied.html", :ignore => true +page "/sub/fake.html", proxy: "/proxied.html", ignore: true +page "/sub/fake2.html", proxy: "/proxied.html", ignore: true -page "/directory-indexed/fake.html", :proxy => "/proxied.html", :ignore => true -page "/directory-indexed/fake2.html", :proxy => "/proxied.html", :ignore => true +page "/directory-indexed/fake.html", proxy: "/proxied.html", ignore: true +page "/directory-indexed/fake2.html", proxy: "/proxied.html", ignore: true diff --git a/middleman-core/fixtures/padrino-helpers-app/source/former_padrino_test.html.erb b/middleman-core/fixtures/padrino-helpers-app/source/former_padrino_test.html.erb index 9276ff21..a70e26a2 100644 --- a/middleman-core/fixtures/padrino-helpers-app/source/former_padrino_test.html.erb +++ b/middleman-core/fixtures/padrino-helpers-app/source/former_padrino_test.html.erb @@ -1,6 +1,6 @@ <%= stylesheet_link_tag "test1" %> <%= javascript_include_tag "test1" %> -<%= image_tag "test2.png", :alt => "alt" %> -<%= image_tag "100px.png", :alt => "alt" %> -<%= link_to "Has param", "test2.com", :class => "test" %> +<%= image_tag "test2.png", alt: "alt" %> +<%= image_tag "100px.png", alt: "alt" %> +<%= link_to "Has param", "test2.com", class: "test" %> <%= number_to_human_size(1024) %> diff --git a/middleman-core/fixtures/page-classes-app/source/2-starts-with-numeric-custom.html.erb b/middleman-core/fixtures/page-classes-app/source/2-starts-with-numeric-custom.html.erb index 63ce41f8..5c0aaaa6 100644 --- a/middleman-core/fixtures/page-classes-app/source/2-starts-with-numeric-custom.html.erb +++ b/middleman-core/fixtures/page-classes-app/source/2-starts-with-numeric-custom.html.erb @@ -1 +1 @@ -<%= page_classes :numeric_prefix => "haaaaay" %> \ No newline at end of file +<%= page_classes numeric_prefix: "haaaaay" %> \ No newline at end of file diff --git a/middleman-core/fixtures/page-helper-layout-block-app/config.rb b/middleman-core/fixtures/page-helper-layout-block-app/config.rb index d6bf4d20..4f17759a 100644 --- a/middleman-core/fixtures/page-helper-layout-block-app/config.rb +++ b/middleman-core/fixtures/page-helper-layout-block-app/config.rb @@ -1,4 +1,4 @@ -page "/path/*", :layout => "alt" +page "/path/*", layout: "alt" # Doesn't work, and shouldn't # page "/path/*" do diff --git a/middleman-core/fixtures/partials-app/source/locals.html.erb b/middleman-core/fixtures/partials-app/source/locals.html.erb index 23f7e2a4..389ef2a5 100644 --- a/middleman-core/fixtures/partials-app/source/locals.html.erb +++ b/middleman-core/fixtures/partials-app/source/locals.html.erb @@ -1 +1 @@ -<%= partial 'locals', :locals => { :foo => 'bar' } %> +<%= partial 'locals', locals: { :foo => 'bar' } %> diff --git a/middleman-core/fixtures/proxy-pages-app/config.rb b/middleman-core/fixtures/proxy-pages-app/config.rb index 26afbc7a..c3cdbcb2 100644 --- a/middleman-core/fixtures/proxy-pages-app/config.rb +++ b/middleman-core/fixtures/proxy-pages-app/config.rb @@ -1,18 +1,18 @@ # -*- coding: utf-8 -*- -proxy "/fake.html", "/real.html", :layout => false -proxy "fake2.html", "/real.html", :layout => false -proxy "fake3.html", "real.html", :layout => false -proxy "/fake4.html", "real.html", :layout => false +proxy "/fake.html", "/real.html", layout: false +proxy "fake2.html", "/real.html", layout: false +proxy "fake3.html", "real.html", layout: false +proxy "/fake4.html", "real.html", layout: false -proxy "/target_ignore.html", "/should_be_ignored3.html", :ignore => true -proxy "target_ignore2.html", "/should_be_ignored6.html", :ignore => true -proxy "target_ignore3.html", "should_be_ignored7.html", :ignore => true -proxy "/target_ignore4.html", "should_be_ignored8.html", :ignore => true +proxy "/target_ignore.html", "/should_be_ignored3.html", ignore: true +proxy "target_ignore2.html", "/should_be_ignored6.html", ignore: true +proxy "target_ignore3.html", "should_be_ignored7.html", ignore: true +proxy "/target_ignore4.html", "should_be_ignored8.html", ignore: true %w(one two).each do |num| - proxy "/fake/#{num}.html", "/real/index.html", :ignore => true, :locals => { :num => num } - proxy "fake2/#{num}.html", "/real/index.html", :ignore => true, :locals => { :num => num } - proxy "fake3/#{num}.html", "real/index.html", :ignore => true, :locals => { :num => num } + proxy "/fake/#{num}.html", "/real/index.html", ignore: true, locals: { num: num } + proxy "fake2/#{num}.html", "/real/index.html", ignore: true, locals: { num: num } + proxy "fake3/#{num}.html", "real/index.html", ignore: true, locals: { num: num } end -proxy "明日がある.html", "/real.html", :layout => false +proxy "明日がある.html", "/real.html", layout: false diff --git a/middleman-core/fixtures/traversal-app/config.rb b/middleman-core/fixtures/traversal-app/config.rb index 3e86b158..5d030e02 100644 --- a/middleman-core/fixtures/traversal-app/config.rb +++ b/middleman-core/fixtures/traversal-app/config.rb @@ -1,5 +1,5 @@ -page "/sub/fake.html", :proxy => "/proxied.html", :ignore => true -page "/sub/fake2.html", :proxy => "/proxied.html", :ignore => true +page "/sub/fake.html", proxy: "/proxied.html", ignore: true +page "/sub/fake2.html", proxy: "/proxied.html", ignore: true -page "/directory-indexed/fake.html", :proxy => "/proxied.html", :ignore => true -page "/directory-indexed/fake2.html", :proxy => "/proxied.html", :ignore => true +page "/directory-indexed/fake.html", proxy: "/proxied.html", ignore: true +page "/directory-indexed/fake2.html", proxy: "/proxied.html", ignore: true diff --git a/middleman-core/fixtures/wildcard-app/config.rb b/middleman-core/fixtures/wildcard-app/config.rb index fc59362b..8801921f 100644 --- a/middleman-core/fixtures/wildcard-app/config.rb +++ b/middleman-core/fixtures/wildcard-app/config.rb @@ -1 +1 @@ -page "/admin/*", :layout => :admin +page "/admin/*", layout: :admin diff --git a/middleman-core/fixtures/wildcard-directory-index-app/config.rb b/middleman-core/fixtures/wildcard-directory-index-app/config.rb index ee130120..7c9e3767 100644 --- a/middleman-core/fixtures/wildcard-directory-index-app/config.rb +++ b/middleman-core/fixtures/wildcard-directory-index-app/config.rb @@ -1,2 +1,2 @@ activate :directory_indexes -page "/admin/*", :layout => :admin +page "/admin/*", layout: :admin diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 9d695d6a..04f05197 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -4,8 +4,8 @@ module Middleman module Routing # The page method allows the layout to be set on a specific path # - # page "/about.html", :layout => false - # page "/", :layout => :homepage_layout + # page "/about.html", layout: false + # page "/", layout: :homepage_layout # # @param [String] url # @param [Hash] opts diff --git a/middleman-templates/lib/middleman-templates/shared/Gemfile.tt b/middleman-templates/lib/middleman-templates/shared/Gemfile.tt index ec8e0fc9..4e69427e 100644 --- a/middleman-templates/lib/middleman-templates/shared/Gemfile.tt +++ b/middleman-templates/lib/middleman-templates/shared/Gemfile.tt @@ -8,7 +8,7 @@ gem "middleman", "~><%= Middleman::VERSION %>" gem "middleman-livereload", "~> 3.1.0" # For faster file watcher updates on Windows: -gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw] +gem "wdm", "~> 0.1.0", platforms: [:mswin, :mingw] # Windows does not come with time zone data gem "tzinfo-data", platforms: [:mswin, :mingw] diff --git a/middleman-templates/lib/middleman-templates/shared/config.tt b/middleman-templates/lib/middleman-templates/shared/config.tt index 27673596..3d3a007f 100755 --- a/middleman-templates/lib/middleman-templates/shared/config.tt +++ b/middleman-templates/lib/middleman-templates/shared/config.tt @@ -19,11 +19,11 @@ page '/*.json', layout: false page '/*.txt', layout: false # # With alternative layout -# page "/path/to/file.html", :layout => :otherlayout +# page "/path/to/file.html", layout: :otherlayout # Proxy pages (http://middlemanapp.com/basics/dynamic-pages/) -# proxy "/this-page-has-no-template.html", "/template-file.html", :locals => { -# :which_fake_page => "Rendering a fake page with a local variable" } +# proxy "/this-page-has-no-template.html", "/template-file.html", locals: { +# which_fake_page: "Rendering a fake page with a local variable" } ### # Helpers From 00bbdfa254169fb61f3c21ca2eb80381e9a1ace5 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 26 May 2014 18:00:39 -0700 Subject: [PATCH 049/662] unvendor fastimage --- .../extensions/automatic_image_sizes.rb | 2 +- .../lib/vendored-middleman-deps/fastimage.rb | 287 ------------------ middleman-core/middleman-core.gemspec | 3 + 3 files changed, 4 insertions(+), 288 deletions(-) delete mode 100644 middleman-core/lib/vendored-middleman-deps/fastimage.rb diff --git a/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb b/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb index 86311be7..0f5ef31d 100644 --- a/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb +++ b/middleman-core/lib/middleman-core/extensions/automatic_image_sizes.rb @@ -4,7 +4,7 @@ class Middleman::Extensions::AutomaticImageSizes < ::Middleman::Extension super # Include 3rd-party fastimage library - require 'vendored-middleman-deps/fastimage' + require 'fastimage' end helpers do diff --git a/middleman-core/lib/vendored-middleman-deps/fastimage.rb b/middleman-core/lib/vendored-middleman-deps/fastimage.rb deleted file mode 100644 index a1d0da26..00000000 --- a/middleman-core/lib/vendored-middleman-deps/fastimage.rb +++ /dev/null @@ -1,287 +0,0 @@ -# FastImage finds the size or type of an image given its uri. -# It is careful to only fetch and parse as much of the image as is needed to determine the result. -# It does this by using a feature of Net::HTTP that yields strings from the resource being fetched -# as soon as the packets arrive. -# -# No external libraries such as ImageMagick are used here, this is a very lightweight solution to -# finding image information. -# -# FastImage knows about GIF, JPEG, BMP and PNG files. -# -# FastImage can also read files from the local filesystem by supplying the path instead of a uri. -# In this case FastImage uses the open-uri library to read the file in chunks of 256 bytes until -# it has enough. This is possibly a useful bandwidth-saving feature if the file is on a network -# attached disk rather than truly local. -# -# === Examples -# require 'fastimage' -# -# FastImage.size("http://stephensykes.com/images/ss.com_x.gif") -# => [266, 56] -# FastImage.type("http://stephensykes.com/images/pngimage") -# => :png -# FastImage.type("/some/local/file.gif") -# => :gif -# -# === References -# * http://snippets.dzone.com/posts/show/805 -# * http://www.anttikupila.com/flash/getting-jpg-dimensions-with-as3-without-loading-the-entire-file/ -# * http://pennysmalls.com/2008/08/19/find-jpeg-dimensions-fast-in-ruby/ -# * http://imagesize.rubyforge.org/ -# -require 'net/https' -require 'open-uri' - -class FastImage - attr_reader :size, :type - - class FastImageException < StandardError # :nodoc: - end - class MoreCharsNeeded < FastImageException # :nodoc: - end - class UnknownImageType < FastImageException # :nodoc: - end - class ImageFetchFailure < FastImageException # :nodoc: - end - class SizeNotFound < FastImageException # :nodoc: - end - - DefaultTimeout = 2 - - LocalFileChunkSize = 256 - - # Returns an array containing the width and height of the image. - # It will return nil if the image could not be fetched, or if the image type was not recognised. - # - # By default there is a timeout of 2 seconds for opening and reading from a remote server. - # This can be changed by passing a :timeout => number_of_seconds in the options. - # - # If you wish FastImage to raise if it cannot size the image for any reason, then pass - # :raise_on_failure => true in the options. - # - # FastImage knows about GIF, JPEG, BMP and PNG files. - # - # === Example - # - # require 'fastimage' - # - # FastImage.size("http://stephensykes.com/images/ss.com_x.gif") - # => [266, 56] - # FastImage.size("http://stephensykes.com/images/pngimage") - # => [16, 16] - # FastImage.size("http://farm4.static.flickr.com/3023/3047236863_9dce98b836.jpg") - # => [500, 375] - # FastImage.size("http://www-ece.rice.edu/~wakin/images/lena512.bmp") - # => [512, 512] - # FastImage.size("test/fixtures/test.jpg") - # => [882, 470] - # FastImage.size("http://pennysmalls.com/does_not_exist") - # => nil - # FastImage.size("http://pennysmalls.com/does_not_exist", :raise_on_failure=>true) - # => raises FastImage::ImageFetchFailure - # FastImage.size("http://stephensykes.com/favicon.ico", :raise_on_failure=>true) - # => raises FastImage::UnknownImageType - # FastImage.size("http://stephensykes.com/favicon.ico", :raise_on_failure=>true, :timeout=>0.01) - # => raises FastImage::ImageFetchFailure - # FastImage.size("http://stephensykes.com/images/faulty.jpg", :raise_on_failure=>true) - # => raises FastImage::SizeNotFound - # - # === Supported options - # [:timeout] - # Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection. - # [:raise_on_failure] - # If set to true causes an exception to be raised if the image size cannot be found for any reason. - # - def self.size(uri, options={}) - new(uri, options).size - end - - # Returns an symbol indicating the image type fetched from a uri. - # It will return nil if the image could not be fetched, or if the image type was not recognised. - # - # By default there is a timeout of 2 seconds for opening and reading from a remote server. - # This can be changed by passing a :timeout => number_of_seconds in the options. - # - # If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass - # :raise_on_failure => true in the options. - # - # === Example - # - # require 'fastimage' - # - # FastImage.type("http://stephensykes.com/images/ss.com_x.gif") - # => :gif - # FastImage.type("http://stephensykes.com/images/pngimage") - # => :png - # FastImage.type("http://farm4.static.flickr.com/3023/3047236863_9dce98b836.jpg") - # => :jpeg - # FastImage.type("http://www-ece.rice.edu/~wakin/images/lena512.bmp") - # => :bmp - # FastImage.type("test/fixtures/test.jpg") - # => :jpeg - # FastImage.type("http://pennysmalls.com/does_not_exist") - # => nil - # - # === Supported options - # [:timeout] - # Overrides the default timeout of 2 seconds. Applies both to reading from and opening the http connection. - # [:raise_on_failure] - # If set to true causes an exception to be raised if the image type cannot be found for any reason. - # - def self.type(uri, options={}) - new(uri, options.merge(:type_only=>true)).type - end - - def initialize(uri, options={}) - @property = options[:type_only] ? :type : :size - @timeout = options[:timeout] || DefaultTimeout - @uri = uri - begin - @parsed_uri = URI.parse(uri) - rescue URI::InvalidURIError - fetch_using_open_uri - else - if @parsed_uri.scheme == "http" || @parsed_uri.scheme == "https" - fetch_using_http - else - fetch_using_open_uri - end - end - raise SizeNotFound if options[:raise_on_failure] && @property == :size && !@size - rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET, - ImageFetchFailure, Net::HTTPBadResponse, EOFError, Errno::ENOENT - raise ImageFetchFailure if options[:raise_on_failure] - rescue NoMethodError # 1.8.7p248 can raise this due to a net/http bug - raise ImageFetchFailure if options[:raise_on_failure] - rescue UnknownImageType - raise UnknownImageType if options[:raise_on_failure] - end - - private - - def fetch_using_http - setup_http - @http.request_get(@parsed_uri.request_uri) do |res| - raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess) - res.read_body do |str| - break if parse_packet(str) - end - end - end - - def setup_http - @http = Net::HTTP.new(@parsed_uri.host, @parsed_uri.port) - @http.use_ssl = (@parsed_uri.scheme == "https") - @http.verify_mode = OpenSSL::SSL::VERIFY_NONE - @http.open_timeout = @timeout - @http.read_timeout = @timeout - end - - def fetch_using_open_uri - open(@uri) do |s| - while str = s.read(LocalFileChunkSize) - break if parse_packet(str) - end - end - end - - # returns true once result is achieved - # - def parse_packet(str) - @str = (@unused_str || "") + str - @strpos = 0 - begin - result = send("parse_#{@property}") - if result - instance_variable_set("@#{@property}", result) - true - end - rescue MoreCharsNeeded - false - end - end - - def parse_size - @type = parse_type unless @type - @strpos = 0 - send("parse_size_for_#{@type}") - end - - def get_chars(n) - if @strpos + n - 1 >= @str.size - @unused_str = @str[@strpos..-1] - raise MoreCharsNeeded - else - result = @str[@strpos..(@strpos + n - 1)] - @strpos += n - result - end - end - - def get_byte - get_chars(1).unpack("C")[0] - end - - def read_int(str) - size_bytes = str.unpack("CC") - (size_bytes[0] << 8) + size_bytes[1] - end - - def parse_type - case get_chars(2) - when "BM" - :bmp - when "GI" - :gif - when 0xff.chr + 0xd8.chr - :jpeg - when 0x89.chr + "P" - :png - else - raise UnknownImageType - end - end - - def parse_size_for_gif - get_chars(11)[6..10].unpack('SS') - end - - def parse_size_for_png - get_chars(25)[16..24].unpack('NN') - end - - def parse_size_for_jpeg - loop do - @state = case @state - when nil - get_chars(2) - :started - when :started - get_byte == 0xFF ? :sof : :started - when :sof - c = get_byte - if (0xe0..0xef).include?(c) - :skipframe - elsif [0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF].detect {|r| r.include? c} - :readsize - else - :skipframe - end - when :skipframe - @skip_chars = read_int(get_chars(2)) - 2 - :do_skip - when :do_skip - get_chars(@skip_chars) - :started - when :readsize - s = get_chars(7) - return [read_int(s[5..6]), read_int(s[3..4])] - end - end - end - - def parse_size_for_bmp - d = get_chars(29)[14..28] - d.unpack("C")[0] == 40 ? d[4..-1].unpack('LL') : d[4..8].unpack('SS') - end -end diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index cdf70080..070339ab 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -34,4 +34,7 @@ Gem::Specification.new do |s| # i18n s.add_dependency('i18n', ['~> 0.6.9']) + + # Automatic Image Sizes + s.add_dependency('fastimage', ['~> 1.6.2']) end From ba01a0a72b734d97b83e983c2f61b591702ae141 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 26 May 2014 18:44:11 -0700 Subject: [PATCH 050/662] more templates back into cli --- .rubocop.yml | 2 +- Gemfile | 1 - Rakefile | 2 +- .../lib/middleman-templates.rb | 0 .../lib/middleman-templates/default.rb | 0 .../default/source/images/background.png | Bin .../default/source/images/middleman.png | Bin .../default/source/index.html.erb | 0 .../default/source/javascripts/all.js | 0 .../default/source/layouts/layout.erb | 0 .../default/source/stylesheets/all.css | 0 .../default/source/stylesheets/normalize.css | 0 .../lib/middleman-templates/empty.rb | 0 .../lib/middleman-templates/html5.rb | 0 .../html5/source/.htaccess | 0 .../middleman-templates/html5/source/404.html | 0 .../html5/source/CHANGELOG.md | 0 .../html5/source/CONTRIBUTING.md | 0 .../html5/source/LICENSE.md | 0 .../html5/source/README.md | 0 .../source/apple-touch-icon-precomposed.png | Bin .../html5/source/crossdomain.xml | 0 .../html5/source/css/main.css | 0 .../html5/source/css/normalize.css | 0 .../html5/source/favicon.ico | Bin .../html5/source/humans.txt | 0 .../html5/source/img/.gitignore | 0 .../html5/source/index.html.erb | 0 .../html5/source/js/main.js | 0 .../html5/source/js/plugins.js | 0 .../source/js/vendor/jquery-1.11.0.min.js | 0 .../source/js/vendor/modernizr-2.7.1.min.js | 0 .../html5/source/layouts/layout.erb | 0 .../html5/source/robots.txt | 0 .../lib/middleman-templates/local.rb | 0 .../lib/middleman-templates/mobile.rb | 0 .../mobile/source/404.html | 0 .../mobile/source/README.markdown | 0 .../mobile/source/crossdomain.xml | 0 .../mobile/source/css/style.css | 0 .../mobile/source/humans.txt | 0 .../mobile/source/img/h/apple-touch-icon.png | Bin .../mobile/source/img/h/splash.png | Bin .../img/l/apple-touch-icon-precomposed.png | Bin .../mobile/source/img/l/apple-touch-icon.png | Bin .../mobile/source/img/l/splash.png | Bin .../mobile/source/img/m/apple-touch-icon.png | Bin .../mobile/source/index.html | 0 .../mobile/source/js/libs/modernizr-custom.js | 0 .../mobile/source/js/libs/respond.min.js | 0 .../mobile/source/js/mylibs/helper.js | 0 .../mobile/source/js/plugins.js | 0 .../mobile/source/js/script.js | 0 .../mobile/source/robots.txt | 0 .../mobile/source/sitemap.xml | 0 .../mobile/source/test/index.html | 0 .../mobile/source/test/qunit/qunit.css | 0 .../mobile/source/test/qunit/qunit.js | 0 .../mobile/source/test/tests.js | 0 .../tools/googleanalyticsformobile/Readme.PDF | Bin .../aspx/aspx1.snippet | 0 .../aspx/aspx2.snippet | 0 .../googleanalyticsformobile/aspx/ga.aspx | 0 .../googleanalyticsformobile/aspx/sample.aspx | 0 .../tools/googleanalyticsformobile/jsp/ga.jsp | 0 .../googleanalyticsformobile/jsp/jsp1.snippet | 0 .../googleanalyticsformobile/jsp/jsp2.snippet | 0 .../googleanalyticsformobile/jsp/sample.jsp | 0 .../tools/googleanalyticsformobile/php/ga.php | 0 .../googleanalyticsformobile/php/php1.snippet | 0 .../googleanalyticsformobile/php/php2.snippet | 0 .../googleanalyticsformobile/php/sample.php | 0 .../tools/googleanalyticsformobile/pl/ga.pl | 0 .../googleanalyticsformobile/pl/perl1.snippet | 0 .../googleanalyticsformobile/pl/perl2.snippet | 0 .../googleanalyticsformobile/pl/sample.pl | 0 .../tools/mobile-bookmark-bubble/COPYING | 0 .../mobile-bookmark-bubble/bookmark_bubble.js | 0 .../example/example.html | 0 .../mobile-bookmark-bubble/example/example.js | 0 .../mobile-bookmark-bubble/images/arrow.png | Bin .../mobile-bookmark-bubble/images/close.png | Bin .../images/generate_base64_images | 0 .../images/icon_calendar.png | Bin .../mobile/source/tools/wspl/README | 0 .../source/tools/wspl/databasefactory.js | 0 .../mobile/source/tools/wspl/dbworker.js | 0 .../source/tools/wspl/dbworker_test.html | 0 .../source/tools/wspl/dbworkerstarter.js | 0 .../source/tools/wspl/dbwrapper_gears.js | 0 .../tools/wspl/dbwrapper_gears_test.html | 0 .../source/tools/wspl/dbwrapper_html5.js | 0 .../tools/wspl/dbwrapper_html5_test.html | 0 .../mobile/source/tools/wspl/dbwrapperapi.js | 0 .../source/tools/wspl/dbwrapperapi_test.html | 0 .../source/tools/wspl/gears_resultset.js | 0 .../tools/wspl/gears_resultset_test.html | 0 .../source/tools/wspl/gears_transaction.js | 0 .../tools/wspl/gears_transaction_test.html | 0 .../mobile/source/tools/wspl/gearsutils.js | 0 .../source/tools/wspl/gearsutils_test.html | 0 .../source/tools/wspl/global_functions.js | 0 .../source/tools/wspl/simplenotes/index.html | 0 .../tools/wspl/simplenotes/simplenotes.js | 0 .../source/tools/wspl/simplenotes/styles.css | 0 .../source/tools/wspl/simplenotes/template.js | 0 .../lib/middleman-templates/shared/Gemfile.tt | 0 .../lib/middleman-templates/shared/config.ru | 0 .../lib/middleman-templates/shared/config.tt | 0 .../lib/middleman-templates/shared/gitignore | 0 middleman-cli/middleman-cli.gemspec | 3 +++ middleman-templates/.gemtest | 0 middleman-templates/.simplecov | 5 ---- middleman-templates/.yardopts | 5 ---- middleman-templates/Rakefile | 4 --- middleman-templates/features/.gitkeep | 0 middleman-templates/fixtures/.gitkeep | 0 .../middleman-templates.gemspec | 23 ------------------ middleman-templates/spec/middleman/.gitkeep | 1 - middleman-templates/spec/spec_helper.rb | 0 middleman/middleman.gemspec | 1 - 121 files changed, 5 insertions(+), 42 deletions(-) rename {middleman-templates => middleman-cli}/lib/middleman-templates.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/images/background.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/images/middleman.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/index.html.erb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/javascripts/all.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/layouts/layout.erb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/stylesheets/all.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/default/source/stylesheets/normalize.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/empty.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/.htaccess (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/404.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/CHANGELOG.md (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/CONTRIBUTING.md (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/LICENSE.md (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/README.md (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/crossdomain.xml (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/css/main.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/css/normalize.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/favicon.ico (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/humans.txt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/img/.gitignore (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/index.html.erb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/js/main.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/js/plugins.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/layouts/layout.erb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/html5/source/robots.txt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/local.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile.rb (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/404.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/README.markdown (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/crossdomain.xml (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/css/style.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/humans.txt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/h/splash.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/l/splash.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/index.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/js/libs/respond.min.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/js/mylibs/helper.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/js/plugins.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/js/script.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/robots.txt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/sitemap.xml (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/test/index.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/test/qunit/qunit.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/test/qunit/qunit.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/test/tests.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/README (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/shared/Gemfile.tt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/shared/config.ru (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/shared/config.tt (100%) rename {middleman-templates => middleman-cli}/lib/middleman-templates/shared/gitignore (100%) delete mode 100644 middleman-templates/.gemtest delete mode 100644 middleman-templates/.simplecov delete mode 100644 middleman-templates/.yardopts delete mode 100644 middleman-templates/Rakefile delete mode 100644 middleman-templates/features/.gitkeep delete mode 100644 middleman-templates/fixtures/.gitkeep delete mode 100644 middleman-templates/middleman-templates.gemspec delete mode 100644 middleman-templates/spec/middleman/.gitkeep delete mode 100644 middleman-templates/spec/spec_helper.rb diff --git a/.rubocop.yml b/.rubocop.yml index 4ac61fa8..100c188c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,7 +11,7 @@ AllCops: - '**/bin/**/*' - 'middleman-core/lib/middleman-core/step_definitions/**/*' - 'middleman-core/lib/vendored-middleman-deps/**/*' - - 'middleman-templates/lib/middleman-templates/**/*' + - 'middleman-cli/lib/middleman-templates/**/*' - 'middleman-core/fixtures/**/*' - 'middleman-core/features/**/*' - 'middleman-core/spec/**/*' diff --git a/Gemfile b/Gemfile index c2d1da66..37505ff9 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,5 @@ gem 'rubocop', require: false # Middleman itself gem 'middleman-core', path: 'middleman-core' gem 'middleman-cli', path: 'middleman-cli' -gem 'middleman-templates', path: 'middleman-templates' gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false gem 'middleman', path: 'middleman' diff --git a/Rakefile b/Rakefile index 357bc7aa..b48c1b51 100644 --- a/Rakefile +++ b/Rakefile @@ -6,7 +6,7 @@ require File.expand_path('../middleman-core/lib/middleman-core/version.rb', __FI ROOT = File.expand_path(File.dirname(__FILE__)) GEM_NAME = 'middleman' -middleman_gems = %w(middleman-core middleman-templates middleman-cli middleman) +middleman_gems = %w(middleman-core middleman-cli middleman) GEM_PATHS = middleman_gems.freeze def sh_rake(command) diff --git a/middleman-templates/lib/middleman-templates.rb b/middleman-cli/lib/middleman-templates.rb similarity index 100% rename from middleman-templates/lib/middleman-templates.rb rename to middleman-cli/lib/middleman-templates.rb diff --git a/middleman-templates/lib/middleman-templates/default.rb b/middleman-cli/lib/middleman-templates/default.rb similarity index 100% rename from middleman-templates/lib/middleman-templates/default.rb rename to middleman-cli/lib/middleman-templates/default.rb diff --git a/middleman-templates/lib/middleman-templates/default/source/images/background.png b/middleman-cli/lib/middleman-templates/default/source/images/background.png similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/images/background.png rename to middleman-cli/lib/middleman-templates/default/source/images/background.png diff --git a/middleman-templates/lib/middleman-templates/default/source/images/middleman.png b/middleman-cli/lib/middleman-templates/default/source/images/middleman.png similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/images/middleman.png rename to middleman-cli/lib/middleman-templates/default/source/images/middleman.png diff --git a/middleman-templates/lib/middleman-templates/default/source/index.html.erb b/middleman-cli/lib/middleman-templates/default/source/index.html.erb similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/index.html.erb rename to middleman-cli/lib/middleman-templates/default/source/index.html.erb diff --git a/middleman-templates/lib/middleman-templates/default/source/javascripts/all.js b/middleman-cli/lib/middleman-templates/default/source/javascripts/all.js similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/javascripts/all.js rename to middleman-cli/lib/middleman-templates/default/source/javascripts/all.js diff --git a/middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb b/middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/layouts/layout.erb rename to middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb diff --git a/middleman-templates/lib/middleman-templates/default/source/stylesheets/all.css b/middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/stylesheets/all.css rename to middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css diff --git a/middleman-templates/lib/middleman-templates/default/source/stylesheets/normalize.css b/middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css similarity index 100% rename from middleman-templates/lib/middleman-templates/default/source/stylesheets/normalize.css rename to middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css diff --git a/middleman-templates/lib/middleman-templates/empty.rb b/middleman-cli/lib/middleman-templates/empty.rb similarity index 100% rename from middleman-templates/lib/middleman-templates/empty.rb rename to middleman-cli/lib/middleman-templates/empty.rb diff --git a/middleman-templates/lib/middleman-templates/html5.rb b/middleman-cli/lib/middleman-templates/html5.rb similarity index 100% rename from middleman-templates/lib/middleman-templates/html5.rb rename to middleman-cli/lib/middleman-templates/html5.rb diff --git a/middleman-templates/lib/middleman-templates/html5/source/.htaccess b/middleman-cli/lib/middleman-templates/html5/source/.htaccess similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/.htaccess rename to middleman-cli/lib/middleman-templates/html5/source/.htaccess diff --git a/middleman-templates/lib/middleman-templates/html5/source/404.html b/middleman-cli/lib/middleman-templates/html5/source/404.html similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/404.html rename to middleman-cli/lib/middleman-templates/html5/source/404.html diff --git a/middleman-templates/lib/middleman-templates/html5/source/CHANGELOG.md b/middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/CHANGELOG.md rename to middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md diff --git a/middleman-templates/lib/middleman-templates/html5/source/CONTRIBUTING.md b/middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/CONTRIBUTING.md rename to middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md diff --git a/middleman-templates/lib/middleman-templates/html5/source/LICENSE.md b/middleman-cli/lib/middleman-templates/html5/source/LICENSE.md similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/LICENSE.md rename to middleman-cli/lib/middleman-templates/html5/source/LICENSE.md diff --git a/middleman-templates/lib/middleman-templates/html5/source/README.md b/middleman-cli/lib/middleman-templates/html5/source/README.md similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/README.md rename to middleman-cli/lib/middleman-templates/html5/source/README.md diff --git a/middleman-templates/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png b/middleman-cli/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png rename to middleman-cli/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png diff --git a/middleman-templates/lib/middleman-templates/html5/source/crossdomain.xml b/middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/crossdomain.xml rename to middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml diff --git a/middleman-templates/lib/middleman-templates/html5/source/css/main.css b/middleman-cli/lib/middleman-templates/html5/source/css/main.css similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/css/main.css rename to middleman-cli/lib/middleman-templates/html5/source/css/main.css diff --git a/middleman-templates/lib/middleman-templates/html5/source/css/normalize.css b/middleman-cli/lib/middleman-templates/html5/source/css/normalize.css similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/css/normalize.css rename to middleman-cli/lib/middleman-templates/html5/source/css/normalize.css diff --git a/middleman-templates/lib/middleman-templates/html5/source/favicon.ico b/middleman-cli/lib/middleman-templates/html5/source/favicon.ico similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/favicon.ico rename to middleman-cli/lib/middleman-templates/html5/source/favicon.ico diff --git a/middleman-templates/lib/middleman-templates/html5/source/humans.txt b/middleman-cli/lib/middleman-templates/html5/source/humans.txt similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/humans.txt rename to middleman-cli/lib/middleman-templates/html5/source/humans.txt diff --git a/middleman-templates/lib/middleman-templates/html5/source/img/.gitignore b/middleman-cli/lib/middleman-templates/html5/source/img/.gitignore similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/img/.gitignore rename to middleman-cli/lib/middleman-templates/html5/source/img/.gitignore diff --git a/middleman-templates/lib/middleman-templates/html5/source/index.html.erb b/middleman-cli/lib/middleman-templates/html5/source/index.html.erb similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/index.html.erb rename to middleman-cli/lib/middleman-templates/html5/source/index.html.erb diff --git a/middleman-templates/lib/middleman-templates/html5/source/js/main.js b/middleman-cli/lib/middleman-templates/html5/source/js/main.js similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/js/main.js rename to middleman-cli/lib/middleman-templates/html5/source/js/main.js diff --git a/middleman-templates/lib/middleman-templates/html5/source/js/plugins.js b/middleman-cli/lib/middleman-templates/html5/source/js/plugins.js similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/js/plugins.js rename to middleman-cli/lib/middleman-templates/html5/source/js/plugins.js diff --git a/middleman-templates/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js b/middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js rename to middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js diff --git a/middleman-templates/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js b/middleman-cli/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js rename to middleman-cli/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js diff --git a/middleman-templates/lib/middleman-templates/html5/source/layouts/layout.erb b/middleman-cli/lib/middleman-templates/html5/source/layouts/layout.erb similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/layouts/layout.erb rename to middleman-cli/lib/middleman-templates/html5/source/layouts/layout.erb diff --git a/middleman-templates/lib/middleman-templates/html5/source/robots.txt b/middleman-cli/lib/middleman-templates/html5/source/robots.txt similarity index 100% rename from middleman-templates/lib/middleman-templates/html5/source/robots.txt rename to middleman-cli/lib/middleman-templates/html5/source/robots.txt diff --git a/middleman-templates/lib/middleman-templates/local.rb b/middleman-cli/lib/middleman-templates/local.rb similarity index 100% rename from middleman-templates/lib/middleman-templates/local.rb rename to middleman-cli/lib/middleman-templates/local.rb diff --git a/middleman-templates/lib/middleman-templates/mobile.rb b/middleman-cli/lib/middleman-templates/mobile.rb similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile.rb rename to middleman-cli/lib/middleman-templates/mobile.rb diff --git a/middleman-templates/lib/middleman-templates/mobile/source/404.html b/middleman-cli/lib/middleman-templates/mobile/source/404.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/404.html rename to middleman-cli/lib/middleman-templates/mobile/source/404.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/README.markdown b/middleman-cli/lib/middleman-templates/mobile/source/README.markdown similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/README.markdown rename to middleman-cli/lib/middleman-templates/mobile/source/README.markdown diff --git a/middleman-templates/lib/middleman-templates/mobile/source/crossdomain.xml b/middleman-cli/lib/middleman-templates/mobile/source/crossdomain.xml similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/crossdomain.xml rename to middleman-cli/lib/middleman-templates/mobile/source/crossdomain.xml diff --git a/middleman-templates/lib/middleman-templates/mobile/source/css/style.css b/middleman-cli/lib/middleman-templates/mobile/source/css/style.css similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/css/style.css rename to middleman-cli/lib/middleman-templates/mobile/source/css/style.css diff --git a/middleman-templates/lib/middleman-templates/mobile/source/humans.txt b/middleman-cli/lib/middleman-templates/mobile/source/humans.txt similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/humans.txt rename to middleman-cli/lib/middleman-templates/mobile/source/humans.txt diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png b/middleman-cli/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/h/splash.png b/middleman-cli/lib/middleman-templates/mobile/source/img/h/splash.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/h/splash.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/h/splash.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png b/middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png b/middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/l/splash.png b/middleman-cli/lib/middleman-templates/mobile/source/img/l/splash.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/l/splash.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/l/splash.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png b/middleman-cli/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png rename to middleman-cli/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/index.html b/middleman-cli/lib/middleman-templates/mobile/source/index.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/index.html rename to middleman-cli/lib/middleman-templates/mobile/source/index.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js b/middleman-cli/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js rename to middleman-cli/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/js/libs/respond.min.js b/middleman-cli/lib/middleman-templates/mobile/source/js/libs/respond.min.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/js/libs/respond.min.js rename to middleman-cli/lib/middleman-templates/mobile/source/js/libs/respond.min.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/js/mylibs/helper.js b/middleman-cli/lib/middleman-templates/mobile/source/js/mylibs/helper.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/js/mylibs/helper.js rename to middleman-cli/lib/middleman-templates/mobile/source/js/mylibs/helper.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/js/plugins.js b/middleman-cli/lib/middleman-templates/mobile/source/js/plugins.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/js/plugins.js rename to middleman-cli/lib/middleman-templates/mobile/source/js/plugins.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/js/script.js b/middleman-cli/lib/middleman-templates/mobile/source/js/script.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/js/script.js rename to middleman-cli/lib/middleman-templates/mobile/source/js/script.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/robots.txt b/middleman-cli/lib/middleman-templates/mobile/source/robots.txt similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/robots.txt rename to middleman-cli/lib/middleman-templates/mobile/source/robots.txt diff --git a/middleman-templates/lib/middleman-templates/mobile/source/sitemap.xml b/middleman-cli/lib/middleman-templates/mobile/source/sitemap.xml similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/sitemap.xml rename to middleman-cli/lib/middleman-templates/mobile/source/sitemap.xml diff --git a/middleman-templates/lib/middleman-templates/mobile/source/test/index.html b/middleman-cli/lib/middleman-templates/mobile/source/test/index.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/test/index.html rename to middleman-cli/lib/middleman-templates/mobile/source/test/index.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/test/qunit/qunit.css b/middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.css similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/test/qunit/qunit.css rename to middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.css diff --git a/middleman-templates/lib/middleman-templates/mobile/source/test/qunit/qunit.js b/middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/test/qunit/qunit.js rename to middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/test/tests.js b/middleman-cli/lib/middleman-templates/mobile/source/test/tests.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/test/tests.js rename to middleman-cli/lib/middleman-templates/mobile/source/test/tests.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl b/middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl rename to middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png b/middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png rename to middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/README b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/README similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/README rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/README diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css diff --git a/middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js b/middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js similarity index 100% rename from middleman-templates/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js rename to middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js diff --git a/middleman-templates/lib/middleman-templates/shared/Gemfile.tt b/middleman-cli/lib/middleman-templates/shared/Gemfile.tt similarity index 100% rename from middleman-templates/lib/middleman-templates/shared/Gemfile.tt rename to middleman-cli/lib/middleman-templates/shared/Gemfile.tt diff --git a/middleman-templates/lib/middleman-templates/shared/config.ru b/middleman-cli/lib/middleman-templates/shared/config.ru similarity index 100% rename from middleman-templates/lib/middleman-templates/shared/config.ru rename to middleman-cli/lib/middleman-templates/shared/config.ru diff --git a/middleman-templates/lib/middleman-templates/shared/config.tt b/middleman-cli/lib/middleman-templates/shared/config.tt similarity index 100% rename from middleman-templates/lib/middleman-templates/shared/config.tt rename to middleman-cli/lib/middleman-templates/shared/config.tt diff --git a/middleman-templates/lib/middleman-templates/shared/gitignore b/middleman-cli/lib/middleman-templates/shared/gitignore similarity index 100% rename from middleman-templates/lib/middleman-templates/shared/gitignore rename to middleman-cli/lib/middleman-templates/shared/gitignore diff --git a/middleman-cli/middleman-cli.gemspec b/middleman-cli/middleman-cli.gemspec index 05f5c456..8102ed15 100644 --- a/middleman-cli/middleman-cli.gemspec +++ b/middleman-cli/middleman-cli.gemspec @@ -21,4 +21,7 @@ Gem::Specification.new do |s| # CLI s.add_dependency('thor', ['>= 0.17.0', '< 2.0']) + + # Templates + s.add_dependency('octokit', ['~> 3.1']) end diff --git a/middleman-templates/.gemtest b/middleman-templates/.gemtest deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-templates/.simplecov b/middleman-templates/.simplecov deleted file mode 100644 index 3720cc52..00000000 --- a/middleman-templates/.simplecov +++ /dev/null @@ -1,5 +0,0 @@ -SimpleCov.start do - add_filter '/fixtures/' - add_filter '/features/' - add_filter '/spec/' -end \ No newline at end of file diff --git a/middleman-templates/.yardopts b/middleman-templates/.yardopts deleted file mode 100644 index fcefc936..00000000 --- a/middleman-templates/.yardopts +++ /dev/null @@ -1,5 +0,0 @@ -lib/**/*.rb ---exclude lib/middleman-templates ---no-private ---hide-void-return ---markup=markdown \ No newline at end of file diff --git a/middleman-templates/Rakefile b/middleman-templates/Rakefile deleted file mode 100644 index 7fc3d2c0..00000000 --- a/middleman-templates/Rakefile +++ /dev/null @@ -1,4 +0,0 @@ -# coding:utf-8 -RAKE_ROOT = __FILE__ -GEM_NAME = 'middleman-templates' -require File.expand_path(File.dirname(__FILE__) + '/../gem_rake_helper') diff --git a/middleman-templates/features/.gitkeep b/middleman-templates/features/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-templates/fixtures/.gitkeep b/middleman-templates/fixtures/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-templates/middleman-templates.gemspec b/middleman-templates/middleman-templates.gemspec deleted file mode 100644 index ee0bcde0..00000000 --- a/middleman-templates/middleman-templates.gemspec +++ /dev/null @@ -1,23 +0,0 @@ -# -*- encoding: utf-8 -*- -$LOAD_PATH.push File.expand_path('../lib', __FILE__) -require File.expand_path('../../middleman-core/lib/middleman-core/version', __FILE__) - -Gem::Specification.new do |s| - s.name = 'middleman-templates' - s.version = Middleman::VERSION - s.platform = Gem::Platform::RUBY - s.license = 'MIT' - s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Karl Freeman'] - s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'karlfreeman@gmail.com'] - s.homepage = 'http://middlemanapp.com' - s.summary = 'Hand-crafted frontend development' - s.description = 'A static site generator. Provides dozens of templating languages (Haml, Sass, Compass, Slim, CoffeeScript, and more). Makes minification, compression, cache busting, Yaml data (and more) an easy part of your development cycle.' - - s.files = `git ls-files -z`.split("\0") - s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0") - s.require_path = 'lib' - s.required_ruby_version = '>= 1.9.3' - - # Templates - s.add_dependency('thor', ['>= 0.17.0', '< 2.0']) -end diff --git a/middleman-templates/spec/middleman/.gitkeep b/middleman-templates/spec/middleman/.gitkeep deleted file mode 100644 index 45adbb22..00000000 --- a/middleman-templates/spec/middleman/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -.gitkeep \ No newline at end of file diff --git a/middleman-templates/spec/spec_helper.rb b/middleman-templates/spec/spec_helper.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman/middleman.gemspec b/middleman/middleman.gemspec index bdb77455..e0268027 100644 --- a/middleman/middleman.gemspec +++ b/middleman/middleman.gemspec @@ -20,7 +20,6 @@ Gem::Specification.new do |s| s.add_dependency('middleman-core', Middleman::VERSION) s.add_dependency('middleman-cli', Middleman::VERSION) - s.add_dependency('middleman-templates', Middleman::VERSION) s.add_dependency('middleman-sprockets', '>= 3.1.2') s.add_dependency('haml', ['>= 4.0.5']) s.add_dependency('sass', ['>= 3.3.4']) From 927a1758ba53e56eed81feb3b3668ac872931b5c Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 15 Apr 2014 15:16:52 -0700 Subject: [PATCH 051/662] Rack-based HTML rewriter --- middleman-core/features/asset_hash.feature | 2 +- .../middleman-core/extensions/asset_hash.rb | 101 +++++------------- .../middleware/inline_url_rewriter.rb | 67 ++++++++++++ middleman-core/lib/middleman-core/util.rb | 13 +++ 4 files changed, 110 insertions(+), 73 deletions(-) create mode 100644 middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index ec4d7b95..18abf3f9 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -94,7 +94,7 @@ Feature: Assets get a file hash appended to their and references to them are upd activate :relative_assets activate :directory_indexes require 'lib/middleware.rb' - use Middleware + use ::Middleware """ Given the Server is running at "asset-hash-app" When I go to "/" diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index f8aee261..c0f531d9 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -10,13 +10,37 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension require 'digest/sha1' require 'rack/mock' require 'uri' + require 'middleman-core/middleware/inline_url_rewriter' end def after_configuration # Allow specifying regexes to ignore, plus always ignore apple touch icons @ignore = Array(options.ignore) + [/^apple-touch-icon/] - app.use Middleware, exts: options.exts, middleman_app: app, ignore: @ignore + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :asset_hash, + :url_extensions => options.exts, + :source_extensions => %w(.htm .html .php .css .js), + :ignore => @ignore, + :middleman_app => app, + :proc => method(:rewrite_url) + end + + def rewrite_url(asset_path, dirpath) + relative_path = Pathname.new(asset_path).relative? + + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path + end + + if asset_page = app.sitemap.find_resource_by_path(full_asset_path) + replacement_path = "/#{asset_page.destination_path}" + replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path + + replacement_path + end end # Update the main sitemap resource list @@ -44,7 +68,10 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension return if resource.ignored? # Render through the Rack interface so middleware and mounted apps get a shot - response = @rack_client.get(URI.escape(resource.destination_path), 'bypass_asset_hash' => 'true') + response = @rack_client.get(URI.escape(resource.destination_path), { + 'bypass_inline_url_rewriter_asset_hash' => 'true' + }) + raise "#{resource.path} should be in the sitemap!" unless response.status == 200 digest = Digest::SHA1.hexdigest(response.body)[0..7] @@ -55,74 +82,4 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension def ignored_resource?(resource) @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) } end - - # The asset hash middleware is responsible for rewriting references to - # assets to include their new, hashed name. - class Middleware - def initialize(app, options={}) - @rack_app = app - @exts = options[:exts] - @ignore = options[:ignore] - @exts_regex_text = @exts.map { |e| Regexp.escape(e) }.join('|') - @middleman_app = options[:middleman_app] - end - - def call(env) - status, headers, response = @rack_app.call(env) - - # We don't want to use this middleware when rendering files to figure out their hash! - return [status, headers, response] if env['bypass_asset_hash'] == 'true' - - path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app) - - if path =~ /(^\/$)|(\.(htm|html|php|css|js)$)/ - body = ::Middleman::Util.extract_response_text(response) - if body - status, headers, response = Rack::Response.new(rewrite_paths(body, path), status, headers).finish - end - end - - [status, headers, response] - end - - private - - def rewrite_paths(body, path) - dirpath = Pathname.new(File.dirname(path)) - - # TODO: This regex will change some paths in plan HTML (not in a tag) - is that OK? - body.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{@exts_regex_text}))/) do |match| - opening_character = $1 - asset_path = $2 - - relative_path = Pathname.new(asset_path).relative? - - asset_path = dirpath.join(asset_path).to_s if relative_path - - if @ignore.any? { |r| asset_path.match(r) } - match - elsif asset_page = @middleman_app.sitemap.find_resource_by_path(asset_path) - replacement_path = "/#{asset_page.destination_path}" - replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path - - "#{opening_character}#{replacement_path}" - else - match - end - end - end - end end - -# =================Temp Generate Test data============================== -# ["jpg", "png", "gif"].each do |ext| -# [["

", "

"], ["

"], ["

background-image:url(", ");

"]].each do |outer| -# [["",""], ["'", "'"], ['"','"']].each do |inner| -# [["", ""], ["/", ""], ["../", ""], ["../../", ""], ["../../../", ""], ["http://example.com/", ""], ["a","a"], ["1","1"], [".", "."], ["-","-"], ["_","_"]].each do |path_parts| -# name = 'images/100px.' -# puts outer[0] + inner[0] + path_parts[0] + name + ext + path_parts[1] + inner[1] + outer[1] -# end -# end -# end -# puts "


" -# end diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb new file mode 100644 index 00000000..6b12f23e --- /dev/null +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -0,0 +1,67 @@ +require 'middleman-core/util' +require 'rack' +require 'rack/response' + +module Middleman + module Middleware + class InlineURLRewriter + def initialize(app, options={}) + @rack_app = app + @middleman_app = options[:middleman_app] + + @uid = options[:id] + @proc = options[:proc] + + raise "InlineURLRewriter requires a :proc to call with inline URL results" unless @proc + + @exts = options[:url_extensions] + + @source_exts = options[:source_extensions] + @source_exts_regex_text = Regexp.union(@source_exts).to_s + + @ignore = options[:ignore] + end + + def call(env) + status, headers, response = @rack_app.call(env) + + # Allow upstream request to skip all rewriting + return [status, headers, response] if env['bypass_inline_url_rewriter'] == 'true' + + # Allow upstream request to skip this specific rewriting + if @uid + uid_key = "bypass_inline_url_rewriter_#{@uid}" + return [status, headers, response] if env[uid_key] == 'true' + end + + path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app) + + if path =~ /(^\/$)|(#{@source_exts_regex_text}$)/ + if body = ::Middleman::Util.extract_response_text(response) + dirpath = Pathname.new(File.dirname(path)) + + rewritten = ::Middleman::Util.rewrite_paths(body, path, @exts) do |asset_path| + relative_path = Pathname.new(asset_path).relative? + + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path + end + + @ignore.none? { |r| full_asset_path.match(r) } && @proc.call(asset_path, dirpath) + end + + status, headers, response = ::Rack::Response.new( + rewritten, + status, + headers + ).finish + end + end + + [status, headers, response] + end + end + end +end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 2621cee9..03c06e05 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -222,6 +222,19 @@ module Middleman end end + def rewrite_paths(body, path, exts, &block) + body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| + opening_character = $1 + asset_path = $2 + + if result = yield(asset_path) + "#{opening_character}#{result}" + else + match + end + end + end + private # Is mime type known to be non-binary? From 3879be0f23a7f999a184ce12001b4694e589cd38 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 2 Jun 2014 15:56:07 -0700 Subject: [PATCH 052/662] Add proc as a means of defining a rewriter ignore. Closes #1289 --- middleman-core/features/asset_hash.feature | 11 ++++++++--- .../middleware/inline_url_rewriter.rb | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 18abf3f9..27362377 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -109,7 +109,12 @@ Feature: Assets get a file hash appended to their and references to them are upd Given a fixture app "asset-hash-app" And a file named "config.rb" with: """ - activate :asset_hash, ignore: [%r(javascripts/*), 'images/*'] + is_stylesheet = proc { |path| path.start_with? 'stylesheets' } + activate :asset_hash, ignore: [ + %r(javascripts/*), + 'images/*', + is_stylesheet + ] activate :relative_assets activate :directory_indexes """ @@ -123,7 +128,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px.jpg | | images/100px.gif | | javascripts/application.js | - | stylesheets/site-50eaa978.css | + | stylesheets/site.css | | index.html | | subdir/index.html | | other/index.html | @@ -132,7 +137,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | - | stylesheets/site.css | + | stylesheets/site-50eaa978.css | # @wip Currently broken, we should move all asset-host functionality out of Compass and into something more similar to asset_hash with Rack-based rewrites # Scenario: Enabling an asset host and referencing assets in CSS with URL fragments are rewritten correctly diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index 6b12f23e..4617b07d 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -49,7 +49,7 @@ module Middleman asset_path end - @ignore.none? { |r| full_asset_path.match(r) } && @proc.call(asset_path, dirpath) + @ignore.none? { |r| should_ignore?(r, full_asset_path) } && @proc.call(asset_path, dirpath) end status, headers, response = ::Rack::Response.new( @@ -62,6 +62,21 @@ module Middleman [status, headers, response] end + + def should_ignore?(validator, value) + if validator.is_a? Regexp + # Treat as Regexp + value.match(validator) + elsif validator.respond_to? :call + # Treat as proc + validator.call(value) + elsif validator.is_a? String + # Treat as glob + File.fnmatch(value, validator) + else + # If some unknown thing, don't ignore + end + end end end end From 29bf25ace64793f423224da52eef5ad7c822a927 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 7 Apr 2014 12:43:16 -0700 Subject: [PATCH 053/662] Extract compass support into extension, rewrite all features that rely on it to be pure Ruby --- Gemfile | 3 + Rakefile | 14 ++- middleman-cli/lib/middleman-cli/build.rb | 4 +- middleman-compass/.gitignore | 10 ++ middleman-compass/.travis.yml | 16 +++ middleman-compass/CONTRIBUTING.md | 43 +++++++ middleman-compass/Gemfile | 17 +++ middleman-compass/LICENSE.md | 20 +++ middleman-compass/README.md | 59 +++++++++ middleman-compass/Rakefile | 20 +++ .../features/compass-sprites.feature | 0 .../features/fonts.feature | 0 middleman-compass/features/support/env.rb | 8 ++ .../fixtures/compass-sprites-app/config.rb | 2 + .../source/images/icon/arrow_down.png | Bin .../source/images/icon/arrow_left.png | Bin .../source/images/icon/arrow_right.png | Bin .../source/images/icon/arrow_up.png | Bin .../source/stylesheets/site.css.scss | 0 .../fixtures/fonts-app}/config.rb | 0 .../fonts-app/source/fonts/StMarie-Thin.otf | Bin 0 -> 197044 bytes .../fonts-app/source/fonts/blank/blank.otf | 0 .../source/stylesheets/fonts.css.sass | 0 middleman-compass/lib/middleman-compass.rb | 6 + .../lib/middleman-compass/extension.rb | 63 ++++++++++ .../lib/middleman-compass/version.rb | 5 + middleman-compass/middleman-compass.gemspec | 20 +++ middleman-core/features/asset_hash.feature | 40 +++--- middleman-core/features/asset_host.feature | 48 +++---- middleman-core/features/cache_buster.feature | 2 +- middleman-core/features/minify_css.feature | 4 +- .../features/relative_assets.feature | 76 ++++-------- middleman-core/features/slim.feature | 2 + middleman-core/features/support/env.rb | 3 +- .../fixtures/asset-hash-host-app/config.rb | 4 +- .../asset-host-app/source/asset_host.html.erb | 21 +++- .../source/stylesheets/asset_host.css.sass | 49 +++++++- .../stylesheets/relative_assets.css.sass | 1 - .../source/stylesheets/site.css.sass | 4 +- .../source/stylesheets/fonts.css.scss | 6 + .../source/stylesheets/site.css.sass | 4 +- .../source/stylesheets/site.css.sass | 6 +- .../stylesheets/relative_assets.css.sass | 3 +- .../source/javascripts/application.js | 8 ++ .../stylesheets/relative_assets.css.sass | 3 +- .../source/stylesheets/site_scss.css.scss | 4 +- .../lib/middleman-core/core_extensions.rb | 8 -- .../middleman-core/core_extensions/compass.rb | 74 ----------- .../core_extensions/default_helpers.rb | 40 +----- .../core_extensions/extensions.rb | 17 ++- .../middleman-core/extensions/asset_hash.rb | 2 +- .../middleman-core/extensions/asset_host.rb | 64 ++++------ .../middleman-core/extensions/cache_buster.rb | 62 +++------- .../extensions/relative_assets.rb | 44 ++++--- .../middleware/inline_url_rewriter.rb | 2 +- .../lib/middleman-core/renderers/sass.rb | 25 +++- .../renderers/sass_functions.rb | 117 ++++++++++++++++++ .../lib/middleman-core/renderers/slim.rb | 2 +- .../step_definitions/server_steps.rb | 8 ++ .../lib/middleman-core/template_renderer.rb | 1 + middleman-core/lib/middleman-core/util.rb | 49 ++++++++ middleman-core/middleman-core.gemspec | 10 ++ middleman/middleman.gemspec | 6 +- 63 files changed, 766 insertions(+), 363 deletions(-) create mode 100644 middleman-compass/.gitignore create mode 100644 middleman-compass/.travis.yml create mode 100644 middleman-compass/CONTRIBUTING.md create mode 100644 middleman-compass/Gemfile create mode 100644 middleman-compass/LICENSE.md create mode 100644 middleman-compass/README.md create mode 100644 middleman-compass/Rakefile rename {middleman-core => middleman-compass}/features/compass-sprites.feature (100%) rename {middleman-core => middleman-compass}/features/fonts.feature (100%) create mode 100644 middleman-compass/features/support/env.rb create mode 100644 middleman-compass/fixtures/compass-sprites-app/config.rb rename {middleman-core => middleman-compass}/fixtures/compass-sprites-app/source/images/icon/arrow_down.png (100%) rename {middleman-core => middleman-compass}/fixtures/compass-sprites-app/source/images/icon/arrow_left.png (100%) rename {middleman-core => middleman-compass}/fixtures/compass-sprites-app/source/images/icon/arrow_right.png (100%) rename {middleman-core => middleman-compass}/fixtures/compass-sprites-app/source/images/icon/arrow_up.png (100%) rename {middleman-core => middleman-compass}/fixtures/compass-sprites-app/source/stylesheets/site.css.scss (100%) rename {middleman-core/fixtures/compass-sprites-app => middleman-compass/fixtures/fonts-app}/config.rb (100%) create mode 100755 middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf rename .gitmodules => middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf (100%) rename {middleman-core => middleman-compass}/fixtures/fonts-app/source/stylesheets/fonts.css.sass (100%) create mode 100644 middleman-compass/lib/middleman-compass.rb create mode 100644 middleman-compass/lib/middleman-compass/extension.rb create mode 100644 middleman-compass/lib/middleman-compass/version.rb create mode 100644 middleman-compass/middleman-compass.gemspec create mode 100644 middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss create mode 100644 middleman-core/fixtures/relative-assets-app/source/javascripts/application.js delete mode 100644 middleman-core/lib/middleman-core/core_extensions/compass.rb create mode 100644 middleman-core/lib/middleman-core/renderers/sass_functions.rb diff --git a/Gemfile b/Gemfile index 37505ff9..04f5ee70 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,8 @@ platforms :ruby do gem 'therubyracer' gem 'redcarpet', '~> 3.1' gem 'pry', require: false, group: :development + # gem 'pry-debugger', require: false, group: :development + # gem 'pry-stack_explorer', require: false, group: :development end platforms :jruby do @@ -35,5 +37,6 @@ gem 'rubocop', require: false # Middleman itself gem 'middleman-core', path: 'middleman-core' gem 'middleman-cli', path: 'middleman-cli' +gem 'middleman-compass', path: 'middleman-compass', require: false gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false gem 'middleman', path: 'middleman' diff --git a/Rakefile b/Rakefile index b48c1b51..16b61bd1 100644 --- a/Rakefile +++ b/Rakefile @@ -46,7 +46,6 @@ task :test do GEM_PATHS.each do |g| Dir.chdir("#{File.join(ROOT, g)}") { sh "#{Gem.ruby} -S rake test" } end - Rake::Task['rubocop'].invoke end desc 'Run specs for all middleman gems' @@ -56,10 +55,15 @@ task :spec do end end -require 'rubocop/rake_task' -desc 'Run RuboCop to check code consistency' -Rubocop::RakeTask.new(:rubocop) do |task| - task.fail_on_error = false +begin + require 'rubocop/rake_task' + if defined?(Rubocop) + desc 'Run RuboCop to check code consistency' + Rubocop::RakeTask.new(:rubocop) do |task| + task.fail_on_error = false + end + end +rescue LoadError end desc 'Run tests for all middleman gems' diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 621e7d26..7b105629 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -187,9 +187,9 @@ module Middleman::Cli resource.ext == '.css' end.each(&method(:build_resource)) - logger.debug '== Checking for Compass sprites' + logger.debug '== Checking for generated images' - # Double-check for compass sprites + # Double-check for generated images @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) @app.sitemap.ensure_resource_list_updated! diff --git a/middleman-compass/.gitignore b/middleman-compass/.gitignore new file mode 100644 index 00000000..be83c767 --- /dev/null +++ b/middleman-compass/.gitignore @@ -0,0 +1,10 @@ +.DS_Store +Gemfile.lock +Gemfile-v4.lock +tmp +.rbenv-* +.sass-cache +pkg +build +.ruby-version +.cache diff --git a/middleman-compass/.travis.yml b/middleman-compass/.travis.yml new file mode 100644 index 00000000..a032273c --- /dev/null +++ b/middleman-compass/.travis.yml @@ -0,0 +1,16 @@ +rvm: + - 1.9.3 + - 2.0.0 + - 2.1.1 + - jruby-19mode + +gemfile: + - Gemfile + - Gemfile-v4 + +script: "bundle exec rake test" + +env: TEST=true + +matrix: + fast_finish: true \ No newline at end of file diff --git a/middleman-compass/CONTRIBUTING.md b/middleman-compass/CONTRIBUTING.md new file mode 100644 index 00000000..97bdc981 --- /dev/null +++ b/middleman-compass/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing +In the spirit of [free software][free-sw], **everyone** is encouraged to help +improve this project. + +[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html + +Here are some ways *you* can contribute: + +* by using alpha, beta, and prerelease versions +* by reporting bugs +* by suggesting new features +* by writing or editing documentation +* by writing specifications +* by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace ) +* by refactoring code +* by closing [issues][] +* by reviewing patches + +[issues]: https://github.com/middleman/middleman-compass/issues + +## Submitting an Issue +We use the [GitHub issue tracker][issues] to track bugs and features. Before +submitting a bug report or feature request, check to make sure it hasn't +already been submitted. When submitting a bug report, please include a [Gist][] +that includes a stack trace and any details that may be necessary to reproduce +the bug, including your gem version, Ruby version, and operating system. +Ideally, a bug report should include a pull request with failing specs. + +[gist]: https://gist.github.com/ + +## Submitting a Pull Request +1. [Fork the repository.][fork] +2. [Create a topic branch.][branch] +3. Add specs for your unimplemented feature or bug fix. +4. Run `bundle exec rake test`. If your specs pass, return to step 3. +5. Implement your feature or bug fix. +6. Run `bundle exec rake test`. If your specs fail, return to step 5. +7. Add, commit, and push your changes. +8. [Submit a pull request.][pr] + +[fork]: http://help.github.com/fork-a-repo/ +[branch]: http://learn.github.com/p/branching.html +[pr]: http://help.github.com/send-pull-requests/ diff --git a/middleman-compass/Gemfile b/middleman-compass/Gemfile new file mode 100644 index 00000000..e3a01e2e --- /dev/null +++ b/middleman-compass/Gemfile @@ -0,0 +1,17 @@ +source "https://rubygems.org" + +gem "middleman-cli", :github => "middleman/middleman", :branch => "master" +gem "middleman-core", :github => "middleman/middleman", :branch => "master" + +# Specify your gem's dependencies in middleman-sprockets.gemspec +gemspec + +gem "rake", "~> 10.0.3", :require => false +gem "yard", "~> 0.8.0", :require => false + +# Test tools +gem "cucumber" +gem "fivemat", "~> 1.2.1" +gem "aruba" +gem "rspec", "~> 2.14" +gem "builder", "~> 3.0" diff --git a/middleman-compass/LICENSE.md b/middleman-compass/LICENSE.md new file mode 100644 index 00000000..8ffe042d --- /dev/null +++ b/middleman-compass/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2012-2013 Thomas Reynolds + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-compass/README.md b/middleman-compass/README.md new file mode 100644 index 00000000..c4d23d97 --- /dev/null +++ b/middleman-compass/README.md @@ -0,0 +1,59 @@ +# Middleman-compass + +`middleman-compass` is an extension for the [Middleman] static site generator that allows support for [Compass](http://compass-style.org) in your assets. + +## Installation + +If you're just getting started, install the `middleman` gem and generate a new project: + +``` +gem install middleman +middleman init MY_PROJECT +``` + +If you already have a Middleman project: Add `gem "middleman-compass"` to your `Gemfile` and run `bundle install` + +## Configuration + +``` +activate :compass +``` + +## Build & Dependency Status + +[![Gem Version](https://badge.fury.io/rb/middleman-compass.png)][gem] +[![Build Status](https://travis-ci.org/middleman/middleman-compass.png)][travis] +[![Dependency Status](https://gemnasium.com/middleman/middleman-compass.png?travis)][gemnasium] +[![Code Quality](https://codeclimate.com/github/middleman/middleman-compass.png)][codeclimate] + +## Community + +The official community forum is available at: http://forum.middlemanapp.com + +## Bug Reports + +Github Issues are used for managing bug reports and feature requests. If you run into issues, please search the issues and submit new problems: https://github.com/middleman/middleman-compass/issues + +The best way to get quick responses to your issues and swift fixes to your bugs is to submit detailed bug reports, include test cases and respond to developer questions in a timely manner. Even better, if you know Ruby, you can submit [Pull Requests](https://help.github.com/articles/using-pull-requests) containing Cucumber Features which describe how your feature should work or exploit the bug you are submitting. + +## How to Run Cucumber Tests + +1. Checkout Repository: `git clone https://github.com/middleman/middleman-compass.git` +2. Install Bundler: `gem install bundler` +3. Run `bundle install` inside the project root to install the gem dependencies. +4. Run test cases: `bundle exec rake test` + +## Donate + +[Click here to lend your support to Middleman](https://spacebox.io/s/4dXbHBorC3) + +## License + +Copyright (c) 2012-2013 Thomas Reynolds. MIT Licensed, see [LICENSE] for details. + +[middleman]: http://middlemanapp.com +[gem]: https://rubygems.org/gems/middleman-compass +[travis]: http://travis-ci.org/middleman/middleman-compass +[gemnasium]: https://gemnasium.com/middleman/middleman-compass +[codeclimate]: https://codeclimate.com/github/middleman/middleman-compass +[LICENSE]: https://github.com/middleman/middleman-compass/blob/master/LICENSE.md \ No newline at end of file diff --git a/middleman-compass/Rakefile b/middleman-compass/Rakefile new file mode 100644 index 00000000..e23e477b --- /dev/null +++ b/middleman-compass/Rakefile @@ -0,0 +1,20 @@ +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'cucumber/rake/task' + +require 'middleman-core/version' + +Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t| + exempt_tags = ["--tags ~@wip"] + t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" +end + +require 'rake/clean' + +task :test => [:cucumber] + +desc "Build HTML documentation" +task :doc do + sh 'bundle exec yard' +end diff --git a/middleman-core/features/compass-sprites.feature b/middleman-compass/features/compass-sprites.feature similarity index 100% rename from middleman-core/features/compass-sprites.feature rename to middleman-compass/features/compass-sprites.feature diff --git a/middleman-core/features/fonts.feature b/middleman-compass/features/fonts.feature similarity index 100% rename from middleman-core/features/fonts.feature rename to middleman-compass/features/fonts.feature diff --git a/middleman-compass/features/support/env.rb b/middleman-compass/features/support/env.rb new file mode 100644 index 00000000..4494e443 --- /dev/null +++ b/middleman-compass/features/support/env.rb @@ -0,0 +1,8 @@ +PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) +ENV['TEST'] = 'true' +ENV["AUTOLOAD_COMPASS"] = "true" +require "middleman-core" +require "middleman-core/step_definitions" +require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-compass') +require "erubis" + diff --git a/middleman-compass/fixtures/compass-sprites-app/config.rb b/middleman-compass/fixtures/compass-sprites-app/config.rb new file mode 100644 index 00000000..6347d3ab --- /dev/null +++ b/middleman-compass/fixtures/compass-sprites-app/config.rb @@ -0,0 +1,2 @@ +require 'middleman-compass' +activate :compass \ No newline at end of file diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_down.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_down.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_left.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_left.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_right.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_right.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_up.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/images/icon/arrow_up.png rename to middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png diff --git a/middleman-core/fixtures/compass-sprites-app/source/stylesheets/site.css.scss b/middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/source/stylesheets/site.css.scss rename to middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss diff --git a/middleman-core/fixtures/compass-sprites-app/config.rb b/middleman-compass/fixtures/fonts-app/config.rb similarity index 100% rename from middleman-core/fixtures/compass-sprites-app/config.rb rename to middleman-compass/fixtures/fonts-app/config.rb diff --git a/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf b/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf new file mode 100755 index 0000000000000000000000000000000000000000..aa601879134eefe4ac115bb2e5a1d355ee952977 GIT binary patch literal 197044 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 Y@^^{JY`^>Fv(M$4&;9+j$dCJ?0Fs|@m;e9( literal 0 HcmV?d00001 diff --git a/.gitmodules b/middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf similarity index 100% rename from .gitmodules rename to middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf diff --git a/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.sass b/middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass similarity index 100% rename from middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.sass rename to middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass diff --git a/middleman-compass/lib/middleman-compass.rb b/middleman-compass/lib/middleman-compass.rb new file mode 100644 index 00000000..8b3ff674 --- /dev/null +++ b/middleman-compass/lib/middleman-compass.rb @@ -0,0 +1,6 @@ +require "middleman-core" + +Middleman::Extensions.register(:compass) do + require "middleman-compass/extension" + Middleman::CompassExtension +end diff --git a/middleman-compass/lib/middleman-compass/extension.rb b/middleman-compass/lib/middleman-compass/extension.rb new file mode 100644 index 00000000..17fe4dc4 --- /dev/null +++ b/middleman-compass/lib/middleman-compass/extension.rb @@ -0,0 +1,63 @@ +module Middleman + class CompassExtension < Extension + def initialize(app, options_hash={}, &block) + require 'middleman-core/renderers/sass' + require 'compass' + + super + + # Hooks to manually update the compass config after we're + # done with it + app.define_hook :compass_config end + + def after_configuration + ::Compass.configuration do |compass_config| + compass_config.project_path = app.source_dir + compass_config.environment = :development + compass_config.cache = false + compass_config.sass_dir = app.config[:css_dir] + compass_config.css_dir = app.config[:css_dir] + compass_config.javascripts_dir = app.config[:js_dir] + compass_config.fonts_dir = app.config[:fonts_dir] + compass_config.images_dir = app.config[:images_dir] + compass_config.http_path = app.config[:http_prefix] + + # Disable this initially, the cache_buster extension will + # re-enable it if requested. + compass_config.asset_cache_buster { |_| nil } + + # Disable this initially, the relative_assets extension will + + compass_config.relative_assets = false + + # Default output style + compass_config.output_style = :nested + end + + # Call hook + app.run_hook_for :compass_config, app, ::Compass.configuration + + # Tell Tilt to use it as well (for inline sass blocks) + ::Tilt.register 'sass', CompassSassTemplate + ::Tilt.prefer(CompassSassTemplate) + + # Tell Tilt to use it as well (for inline scss blocks) + ::Tilt.register 'scss', CompassScssTemplate + ::Tilt.prefer(CompassScssTemplate) + end + + # A Compass Sass template for Tilt, adding our options in + class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate + def sass_options + super.merge(::Compass.configuration.to_sass_engine_options) + end + end + + # A Compass Scss template for Tilt, adding our options in + class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate + def sass_options + super.merge(::Compass.configuration.to_sass_engine_options) + end + end + end +end \ No newline at end of file diff --git a/middleman-compass/lib/middleman-compass/version.rb b/middleman-compass/lib/middleman-compass/version.rb new file mode 100644 index 00000000..fcc5622e --- /dev/null +++ b/middleman-compass/lib/middleman-compass/version.rb @@ -0,0 +1,5 @@ +module Middleman + module Compass + VERSION = "4.0.0" + end +end diff --git a/middleman-compass/middleman-compass.gemspec b/middleman-compass/middleman-compass.gemspec new file mode 100644 index 00000000..ad108349 --- /dev/null +++ b/middleman-compass/middleman-compass.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "middleman-compass/version" + +Gem::Specification.new do |s| + s.name = "middleman-compass" + s.version = Middleman::Compass::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Karl Freeman'] + s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'karlfreeman@gmail.com'] + s.homepage = "https://github.com/middleman/middleman-compass" + s.summary = %q{Compass support for Middleman} + s.description = %q{Compass support for Middleman} + s.license = "MIT" + s.files = `git ls-files -z`.split("\0") + s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0") + s.require_paths = ["lib"] + s.add_dependency("middleman-core")#, [">= 4.0.0"]) + s.add_dependency('compass', ['>= 1.0.0.alpha.19']) +end diff --git a/middleman-core/features/asset_hash.feature b/middleman-core/features/asset_hash.feature index 27362377..3c39f833 100644 --- a/middleman-core/features/asset_hash.feature +++ b/middleman-core/features/asset_hash.feature @@ -10,7 +10,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | - | stylesheets/site-50eaa978.css | + | stylesheets/site-7474cadd.css | | index.html | | subdir/index.html | | other/index.html | @@ -22,15 +22,18 @@ Feature: Assets get a file hash appended to their and references to them are upd | stylesheets/site.css | And the file "javascripts/application-1d8d5276.js" should contain "img.src = '/images/100px-5fd6fb90.jpg'" - And the file "stylesheets/site-50eaa978.css" should contain "background-image: url('../images/100px-5fd6fb90.jpg')" + And the file "stylesheets/site-7474cadd.css" should contain: + """ + background-image: url("../images/100px-5fd6fb90.jpg") + """ And the file "index.html" should contain 'href="apple-touch-icon.png"' - And the file "index.html" should contain 'href="stylesheets/site-50eaa978.css"' + And the file "index.html" should contain 'href="stylesheets/site-7474cadd.css"' 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-50eaa978.css"' + And the file "subdir/index.html" should contain 'href="../stylesheets/site-7474cadd.css"' 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-50eaa978.css"' + 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"' @@ -38,32 +41,35 @@ Feature: Assets get a file hash appended to their and references to them are upd Given the Server is running at "asset-hash-app" When I go to "/" Then I should see 'href="apple-touch-icon.png"' - And I should see 'href="stylesheets/site-50eaa978.css"' + 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"' When I go to "/subdir/" - Then I should see 'href="../stylesheets/site-50eaa978.css"' + Then 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"' When I go to "/other/" - Then I should see 'href="../stylesheets/site-50eaa978.css"' + Then 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"' When I go to "/javascripts/application-1d8d5276.js" Then I should see "img.src = '/images/100px-5fd6fb90.jpg'" - When I go to "/stylesheets/site-50eaa978.css" - Then I should see "background-image: url('../images/100px-5fd6fb90.jpg')" + When I go to "/stylesheets/site-7474cadd.css" + Then I should see: + """ + background-image: url("../images/100px-5fd6fb90.jpg") + """ Scenario: Enabling an asset host still produces hashed files and references Given the Server is running at "asset-hash-host-app" When I go to "/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' When I go to "/subdir/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + Then I should see 'href="http://middlemanapp.com/stylesheets/site-1fdf4fb5.css"' And I should see 'src="http://middlemanapp.com/images/100px-5fd6fb90.jpg"' When I go to "/other/" - Then I should see 'href="http://middlemanapp.com/stylesheets/site-54baaf3a.css"' + 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" @@ -98,11 +104,11 @@ Feature: Assets get a file hash appended to their and references to them are upd """ Given the Server is running at "asset-hash-app" When I go to "/" - Then I should see 'href="stylesheets/site-5770af52.css' - When I go to "stylesheets/site-5770af52.css" + Then I should see 'href="stylesheets/site-ac2166fd.css' + When I go to "stylesheets/site-ac2166fd.css" Then I should see 'background-image' Then I should see 'Added by Rack filter' - When I go to "stylesheets/site-50eaa978.css" + When I go to "stylesheets/site-7474cadd.css" Then I should see 'Not Found' Scenario: Hashed-asset files are not produced for ignored paths @@ -137,7 +143,7 @@ Feature: Assets get a file hash appended to their and references to them are upd | images/100px-5fd6fb90.jpg | | images/100px-5fd6fb90.gif | | javascripts/application-1d8d5276.js | - | stylesheets/site-50eaa978.css | + | stylesheets/site-7474cadd.css | # @wip Currently broken, we should move all asset-host functionality out of Compass and into something more similar to asset_hash with Rack-based rewrites # Scenario: Enabling an asset host and referencing assets in CSS with URL fragments are rewritten correctly diff --git a/middleman-core/features/asset_host.feature b/middleman-core/features/asset_host.feature index eb82f43b..19c6b14d 100644 --- a/middleman-core/features/asset_host.feature +++ b/middleman-core/features/asset_host.feature @@ -2,34 +2,6 @@ Feature: Alternate between multiple asset hosts In order to speed up page loading Scenario: Set single host globally - Given a fixture app "asset-host-app" - And a file named "config.rb" with: - """ - activate :asset_host - set :asset_host, "http://assets1.example.com" - """ - And the Server is running - When I go to "/asset_host.html" - Then I should see "http://assets1" - When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets1" - - Scenario: Set proc host globally - Given a fixture app "asset-host-app" - And a file named "config.rb" with: - """ - activate :asset_host - set :asset_host do |asset| - "http://assets%d.example.com" % (asset.hash % 4) - end - """ - And the Server is running - When I go to "/asset_host.html" - Then I should see "http://assets" - When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets" - - Scenario: Set single host with inline-option Given a fixture app "asset-host-app" And a file named "config.rb" with: """ @@ -41,6 +13,20 @@ Feature: Alternate between multiple asset hosts When I go to "/stylesheets/asset_host.css" Then I should see "http://assets1" + Scenario: Set single host with inline-option + Given a fixture app "asset-host-app" + And a file named "config.rb" with: + """ + activate :asset_host, host: "http://assets1.example.com" + """ + And the Server is running + When I go to "/asset_host.html" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} + When I go to "/stylesheets/asset_host.css" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} + Scenario: Set proc host with inline-option Given a fixture app "asset-host-app" And a file named "config.rb" with: @@ -51,6 +37,8 @@ Feature: Alternate between multiple asset hosts """ And the Server is running When I go to "/asset_host.html" - Then I should see "http://assets" + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} When I go to "/stylesheets/asset_host.css" - Then I should see "http://assets" \ No newline at end of file + Then I should see content matching %r{http://assets1.example.com/} + Then I should not see content matching %r{http://assets1.example.com//} \ No newline at end of file diff --git a/middleman-core/features/cache_buster.feature b/middleman-core/features/cache_buster.feature index 11040ba5..d452234e 100644 --- a/middleman-core/features/cache_buster.feature +++ b/middleman-core/features/cache_buster.feature @@ -5,7 +5,7 @@ Feature: Generate mtime-based query string for busting browser caches Given "cache_buster" feature is "disabled" And the Server is running at "cache-buster-app" When I go to "/stylesheets/relative_assets.css" - Then I should see "blank.gif'" + Then I should see 'blank.gif"' Scenario: Rendering html with the feature disabled Given "cache_buster" feature is "disabled" diff --git a/middleman-core/features/minify_css.feature b/middleman-core/features/minify_css.feature index 87238eb4..066eb530 100644 --- a/middleman-core/features/minify_css.feature +++ b/middleman-core/features/minify_css.feature @@ -8,7 +8,7 @@ Feature: Minify CSS """ And the Server is running at "minify-css-app" When I go to "/stylesheets/site.css" - Then I should see "50" lines + Then I should see "7" lines And I should see "only screen and (device-width" Scenario: Rendering external css with the feature enabled @@ -40,7 +40,7 @@ Feature: Minify CSS """ And the Server is running at "passthrough-app" When I go to "/stylesheets/site.css" - Then I should see "46" lines + Then I should see "5" lines Scenario: Rendering inline css with the feature disabled Given a fixture app "minify-css-app" diff --git a/middleman-core/features/relative_assets.feature b/middleman-core/features/relative_assets.feature index 1ebafdfa..05c069ce 100644 --- a/middleman-core/features/relative_assets.feature +++ b/middleman-core/features/relative_assets.feature @@ -6,7 +6,7 @@ Feature: Relative Assets And the Server is running at "relative-assets-app" When I go to "/stylesheets/relative_assets.css" Then I should not see "url('../" - And I should see "/images/blank.gif')" + And I should see '/images/blank.gif")' Scenario: Building css with the feature disabled Given a fixture app "relative-assets-app" @@ -15,7 +15,7 @@ Feature: Relative Assets """ Given a successfully built app at "relative-assets-app" When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('/images/blank.gif')" + Then the file "stylesheets/relative_assets.css" should contain 'url("/images/blank.gif")' Scenario: Rendering html with the feature disabled Given "relative_assets" feature is "disabled" @@ -27,7 +27,9 @@ Feature: Relative Assets Given "relative_assets" feature is "enabled" And the Server is running at "relative-assets-app" When I go to "/stylesheets/relative_assets.css" - Then I should see "url('../images/blank.gif" + Then I should see 'url("../images/blank.gif' + When I go to "/javascripts/application.js" + Then I should not see "../" Scenario: Building css with the feature enabled Given a fixture app "relative-assets-app" @@ -37,7 +39,8 @@ Feature: Relative Assets """ Given a successfully built app at "relative-assets-app" When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('../images/blank.gif')" + Then the file "stylesheets/relative_assets.css" should contain 'url("../images/blank.gif")' + Then the file "javascripts/application.js" should not contain "../" Scenario: Relative css reference with directory indexes Given a fixture app "relative-assets-app" @@ -57,48 +60,18 @@ Feature: Relative Assets Then I should not see "/images/blank.gif" And I should see "images/blank.gif" - Scenario: Rendering css with a custom images_dir - Given "relative_assets" feature is "enabled" - And "images_dir" is set to "img" - And the Server is running at "relative-assets-app" - When I go to "/stylesheets/relative_assets.css" - Then I should see "url('../img/blank.gif')" - - Scenario: Building css with a custom images_dir - Given a fixture app "relative-assets-app" - And a file named "config.rb" with: - """ - set :images_dir, "img" - activate :relative_assets - """ - Given a successfully built app at "relative-assets-app" - When I cd to "build" - Then the file "stylesheets/relative_assets.css" should contain "url('../img/blank.gif')" - - Scenario: Rendering html with a custom images_dir - Given "relative_assets" feature is "enabled" - And "images_dir" is set to "img" - And the Server is running at "relative-assets-app" - When I go to "/relative_image.html" - Then I should not see "/images/blank.gif" - Then I should not see "/img/blank.gif" - And I should see "img/blank.gif" - Scenario: Rendering scss with the feature enabled Given "relative_assets" feature is "enabled" And the Server is running at "fonts-app" When I go to "/stylesheets/fonts.css" - Then I should see "url('../fonts/StMarie-Thin.otf" - And I should see "url('../fonts/blank/blank.otf" - - Scenario: Rendering scss with the feature enabled and a custom fonts_dir - Given "relative_assets" feature is "enabled" - And "fonts_dir" is set to "otf" - And the Server is running at "fonts-app" - When I go to "/stylesheets/fonts.css" - Then I should not see "url('../fonts/StMarie-Thin.otf" - And I should see "url('../otf/StMarie-Thin.otf" - And I should see "url('../otf/blank/blank.otf" + Then I should see: + """ + url("../fonts/StMarie-Thin.otf" + """ + And I should see: + """ + url("../fonts/blank/blank.otf" + """ Scenario: Building scss with the feature enabled Given a fixture app "fonts-app" @@ -108,21 +81,14 @@ Feature: Relative Assets """ Given a successfully built app at "fonts-app" When I cd to "build" - Then the file "stylesheets/fonts.css" should contain "url('../fonts/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../fonts/blank/blank.otf')" - - Scenario: Building scss with the feature enabled and a custom fonts_dir - Given a fixture app "fonts-app" - And a file named "config.rb" with: + Then the file "stylesheets/fonts.css" should contain: """ - set :fonts_dir, "otf" - activate :relative_assets + url("../fonts/StMarie-Thin.otf") + """ + And the file "stylesheets/fonts.css" should contain: + """ + url("../fonts/blank/blank.otf") """ - Given a successfully built app at "fonts-app" - When I cd to "build" - Then the file "stylesheets/fonts.css" should not contain "url('../fonts/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../otf/StMarie-Thin.otf')" - And the file "stylesheets/fonts.css" should contain "url('../otf/blank/blank.otf')" Scenario: Relative assets via image_tag Given a fixture app "relative-assets-app" diff --git a/middleman-core/features/slim.feature b/middleman-core/features/slim.feature index acf8b82c..02663f3a 100644 --- a/middleman-core/features/slim.feature +++ b/middleman-core/features/slim.feature @@ -24,6 +24,8 @@ Feature: Support slim templating language Given an empty app And a file named "config.rb" with: """ + require 'middleman-compass' + activate :compass """ And a file named "source/scss.html.slim" with: """ diff --git a/middleman-core/features/support/env.rb b/middleman-core/features/support/env.rb index ba524651..59bea134 100644 --- a/middleman-core/features/support/env.rb +++ b/middleman-core/features/support/env.rb @@ -1,5 +1,6 @@ ENV["TEST"] = "true" -ENV["AUTOLOAD_SPROCKETS"] = "false" +ENV["AUTOLOAD_SPROCKETS"] ||= "false" +ENV["AUTOLOAD_COMPASS"] ||= "false" require 'simplecov' SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/../..')) diff --git a/middleman-core/fixtures/asset-hash-host-app/config.rb b/middleman-core/fixtures/asset-hash-host-app/config.rb index f40e1c63..085caeb7 100644 --- a/middleman-core/fixtures/asset-hash-host-app/config.rb +++ b/middleman-core/fixtures/asset-hash-host-app/config.rb @@ -1,6 +1,4 @@ activate :asset_hash activate :directory_indexes -activate :asset_host - -set :asset_host, 'http://middlemanapp.com' +activate :asset_host, host: 'http://middlemanapp.com' diff --git a/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb b/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb index fb441334..dbef372a 100755 --- a/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb +++ b/middleman-core/fixtures/asset-host-app/source/asset_host.html.erb @@ -1 +1,20 @@ -<%= image_tag "blank.gif" %> \ No newline at end of file +<%= image_tag "blank0.gif" %> +<%= image_tag "blank1.gif" %> +<%= image_tag "blank2.gif" %> +<%= image_tag "blank3.gif" %> +<%= image_tag "blank4.gif" %> +<%= image_tag "blank10.gif" %> +<%= image_tag "blank21.gif" %> +<%= image_tag "blank32.gif" %> +<%= image_tag "blank43.gif" %> +<%= image_tag "blank54.gif" %> +<%= image_tag "blank20.gif" %> +<%= image_tag "blank21.gif" %> +<%= image_tag "blank22.gif" %> +<%= image_tag "blank23.gif" %> +<%= image_tag "blank24.gif" %> +<%= image_tag "blank30.gif" %> +<%= image_tag "blank31.gif" %> +<%= image_tag "blank32.gif" %> +<%= image_tag "blank33.gif" %> +<%= image_tag "blank34.gif" %> \ No newline at end of file diff --git a/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass b/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass index 5a67f373..874297d9 100644 --- a/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass +++ b/middleman-core/fixtures/asset-host-app/source/stylesheets/asset_host.css.sass @@ -1,3 +1,48 @@ -@import "compass" h1 - background: image-url("blank.gif") \ No newline at end of file + background: image-url("blank1.gif") +h2 + background: image-url("blank2.gif") +h3 + background: image-url("blank3.gif") +h4 + background: image-url("blank4.gif") +h5 + background: image-url("blank5.gif") +h6 + background: image-url("blank6.gif") +h7 + background: image-url("blank7.gif") +h8 + background: image-url("blank8.gif") +h11 + background: image-url("blank11.gif") +h12 + background: image-url("blank21.gif") +h13 + background: image-url("blank31.gif") +h14 + background: image-url("blank41.gif") +h15 + background: image-url("blank51.gif") +h16 + background: image-url("blank61.gif") +h17 + background: image-url("blank71.gif") +h18 + background: image-url("blank81.gif") +h21 + background: image-url("blank12.gif") +h22 + background: image-url("blank22.gif") +h23 + background: image-url("blank32.gif") +h24 + background: image-url("blank42.gif") +h25 + background: image-url("blank52.gif") +h26 + background: image-url("blank62.gif") +h27 + background: image-url("blank72.gif") +h28 + background: image-url("blank82.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass index 5a67f373..1ed5fcad 100755 --- a/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/cache-buster-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 background: image-url("blank.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass index d143e05e..0ddfd8be 100755 --- a/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/cache-buster-app/source/stylesheets/site.css.sass @@ -1 +1,3 @@ -@import "compass/reset" \ No newline at end of file +body { + background: white; +} \ No newline at end of file diff --git a/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss b/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss new file mode 100644 index 00000000..19075547 --- /dev/null +++ b/middleman-core/fixtures/fonts-app/source/stylesheets/fonts.css.scss @@ -0,0 +1,6 @@ +@font-face { + font-family: "St Marie"; + src: url("/fonts/StMarie-Thin.otf") format('opentype'); } +@font-face { + font-family: "St Marie"; + src: url("/fonts/blank/blank.otf") format('opentype'); } diff --git a/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass index 0cf9e7da..afb9ffdb 100755 --- a/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/minify-css-app/source/stylesheets/site.css.sass @@ -1,4 +1,6 @@ -@import "compass/reset" +body + margin: 0px + padding: 0px @media handheld, only screen and (device-width: 768px) body diff --git a/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass b/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass index d143e05e..47a66dce 100755 --- a/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass +++ b/middleman-core/fixtures/passthrough-app/source/stylesheets/site.css.sass @@ -1 +1,5 @@ -@import "compass/reset" \ No newline at end of file +body + padding: 0px + margin: 0 + div + background: white \ No newline at end of file diff --git a/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass index 5a67f373..77fd4605 100755 --- a/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/relative-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 - background: image-url("blank.gif") \ No newline at end of file + background: url("images/blank.gif") \ No newline at end of file diff --git a/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js b/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js new file mode 100644 index 00000000..7402bc83 --- /dev/null +++ b/middleman-core/fixtures/relative-assets-app/source/javascripts/application.js @@ -0,0 +1,8 @@ +function foo() { + var img = document.createElement('img'); + img.src = '/images/100px.jpg'; + var body = document.getElementsByTagName('body')[0]; + body.insertBefore(img, body.firstChild); +} + +window.onload = foo; \ No newline at end of file diff --git a/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass b/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass index 3c10c7cf..8aec4c51 100755 --- a/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass +++ b/middleman-core/fixtures/relative-assets-app/source/stylesheets/relative_assets.css.sass @@ -1,3 +1,2 @@ -@import "compass" h1 - background: image-url("blank.gif") + background: url("/images/blank.gif") diff --git a/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss b/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss index 0cc04182..a44b6e67 100755 --- a/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss +++ b/middleman-core/fixtures/scss-app/source/stylesheets/site_scss.css.scss @@ -1 +1,3 @@ -@import "compass/reset"; \ No newline at end of file +html, body { + width: 100%; +} \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 729ebdc3..9fd5f985 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -32,14 +32,6 @@ Middleman::Extensions.register :default_helpers, auto_activate: :before_configur Middleman::CoreExtensions::DefaultHelpers end -# Compass framework -begin - require 'middleman-core/core_extensions/compass' - Middleman::Extensions.register :compass, Middleman::CoreExtensions::Compass, auto_activate: :before_configuration -rescue LoadError - # Compass is not available, don't complain about it -end - # Lorem provides a handful of helpful prototyping methods to generate # words, paragraphs, fake images, names and email addresses. Middleman::Extensions.register :lorem, auto_activate: :before_configuration do diff --git a/middleman-core/lib/middleman-core/core_extensions/compass.rb b/middleman-core/lib/middleman-core/core_extensions/compass.rb deleted file mode 100644 index 1d3c13c0..00000000 --- a/middleman-core/lib/middleman-core/core_extensions/compass.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'middleman-core/renderers/sass' -require 'compass' - -class Middleman::CoreExtensions::Compass < ::Middleman::Extension - def initialize(app, options_hash={}, &block) - super - - # Hooks to manually update the compass config after we're - # done with it - app.define_hook :compass_config - - # Location of SASS/SCSS files external to source directory. - # @return [Array] - # config[:sass_assets_paths] = ["#{root}/assets/sass/", "/path/2/external/sass/repository/"] - app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' - end - - def after_configuration - ::Compass.configuration do |compass_config| - compass_config.project_path = app.source_dir - compass_config.environment = :development - compass_config.cache = false - compass_config.sass_dir = app.config[:css_dir] - compass_config.css_dir = app.config[:css_dir] - compass_config.javascripts_dir = app.config[:js_dir] - compass_config.fonts_dir = app.config[:fonts_dir] - compass_config.images_dir = app.config[:images_dir] - compass_config.http_path = app.config[:http_prefix] - - app.config[:sass_assets_paths].each do |path| - compass_config.add_import_path path - end - - # Disable this initially, the cache_buster extension will - # re-enable it if requested. - compass_config.asset_cache_buster { |_| nil } - - # Disable this initially, the relative_assets extension will - - compass_config.relative_assets = false - - # Default output style - compass_config.output_style = :nested - - # No line-comments in test mode (changing paths mess with sha1) - compass_config.line_comments = false if ENV['TEST'] - end - - # Call hook - app.run_hook_for :compass_config, app, ::Compass.configuration - - # Tell Tilt to use it as well (for inline sass blocks) - ::Tilt.register 'sass', CompassSassTemplate - ::Tilt.prefer(CompassSassTemplate) - - # Tell Tilt to use it as well (for inline scss blocks) - ::Tilt.register 'scss', CompassScssTemplate - ::Tilt.prefer(CompassScssTemplate) - end - - # A Compass Sass template for Tilt, adding our options in - class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end - - # A Compass Scss template for Tilt, adding our options in - class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end -end 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 aeaaf500..0388f7f7 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -162,27 +162,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @param [Hash] options Data to pass through. # @return [String] def asset_path(kind, source, options={}) - return source if source.to_s.include?('//') || source.to_s.start_with?('data:') - - asset_folder = case kind - when :css - config[:css_dir] - when :js - config[:js_dir] - when :images - config[:images_dir] - when :fonts - config[:fonts_dir] - else - kind.to_s - end - - source = source.to_s.tr(' ', '') - ignore_extension = (kind == :images || kind == :fonts) # don't append extension - source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") - asset_folder = '' if source.start_with?('/') # absolute path - - asset_url(source, asset_folder, options) + ::Middleman::Util.asset_path(app, kind, source, options) end # Get the URL of an asset given a type/prefix @@ -190,22 +170,8 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @param [String] path The path (such as "photo.jpg") # @param [String] prefix The type prefix (such as "images") # @return [String] The fully qualified asset url - def asset_url(path, prefix='', _) - # Don't touch assets which already have a full path - if path.include?('//') || path.start_with?('data:') - path - else # rewrite paths to use their destination path - if resource = sitemap.find_resource_by_destination_path(url_for(path)) - resource.url - else - path = File.join(prefix, path) - if resource = sitemap.find_resource_by_path(path) - resource.url - else - File.join(config[:http_prefix], path) - end - end - end + def asset_url(path, prefix='', options={}) + ::Middleman::Util.asset_url(app, prefix, options) end # Given a source path (referenced either absolutely or relatively) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index b6efa1d7..9db3a667 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -14,6 +14,12 @@ module Middleman app.define_hook :build_config app.define_hook :development_config + app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' + app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] + + app.config.define_setting :autoload_compass, true, 'Automatically load compass at startup?' + app.config[:autoload_compass] = (ENV['AUTOLOAD_COMPASS'] == 'true') if ENV['AUTOLOAD_COMPASS'] + app.extend ClassMethods app.delegate :configure, to: :"self.class" end @@ -90,7 +96,7 @@ module Middleman activate ext_name end - if ENV['AUTOLOAD_SPROCKETS'] != 'false' + if config[:autoload_sprockets] begin require 'middleman-sprockets' activate :sprockets @@ -99,6 +105,15 @@ module Middleman end end + if config[:autoload_compass] + begin + require 'middleman-compass' + activate :compass + rescue LoadError + # Compass is not available, don't complain about it + end + end + # Evaluate a passed block if given config_context.instance_exec(&block) if block_given? diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index c0f531d9..ab8f4fac 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -26,7 +26,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension :proc => method(:rewrite_url) end - def rewrite_url(asset_path, dirpath) + def rewrite_url(asset_path, dirpath, request_path) relative_path = Pathname.new(asset_path).relative? full_asset_path = if relative_path diff --git a/middleman-core/lib/middleman-core/extensions/asset_host.rb b/middleman-core/lib/middleman-core/extensions/asset_host.rb index 2234bdcf..f9f67cc0 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_host.rb @@ -1,51 +1,41 @@ - # Asset Host module class Middleman::Extensions::AssetHost < ::Middleman::Extension - option :host, nil, 'The asset host to use, or false for no asset host, or a Proc to determine asset host' + option :host, nil, 'The asset host to use or a Proc to determine asset host' + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .php .css .js), 'List of extensions that are searched for bustable assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' def initialize(app, options_hash={}, &block) super - # Backwards compatible API - app.config.define_setting :asset_host, nil, 'The asset host to use, or false for no asset host, or a Proc to determine asset host' - - app.compass_config do |config| - if asset_host = extensions[:asset_host].host - if asset_host.is_a?(Proc) - config.asset_host(&asset_host) - else - config.asset_host do |_| - asset_host - end - end - end - end if app.respond_to?(:compass_config) + require 'middleman-core/middleware/inline_url_rewriter' end - def host - app.config[:asset_host] || options[:host] + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :asset_host, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) end - helpers do - # Override default asset url helper to include asset hosts - # - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - # @return [String] - def asset_url(path, prefix='', options={}) - controller = extensions[:asset_host] + def rewrite_url(asset_path, dirpath, request_path) + relative_path = Pathname.new(asset_path).relative? - original_output = super - return original_output unless controller.host - - asset_prefix = if controller.host.is_a?(Proc) - controller.host.call(original_output) - elsif controller.host.is_a?(String) - controller.host - end - - File.join(asset_prefix, original_output) + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path end + + asset_prefix = if options[:host].is_a?(Proc) + options[:host].call(full_asset_path) + elsif options[:host].is_a?(String) + options[:host] + end + + File.join(asset_prefix, full_asset_path) end end diff --git a/middleman-core/lib/middleman-core/extensions/cache_buster.rb b/middleman-core/lib/middleman-core/extensions/cache_buster.rb index 7036d5fc..b6ffd1d9 100644 --- a/middleman-core/lib/middleman-core/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-core/extensions/cache_buster.rb @@ -1,56 +1,26 @@ # The Cache Buster extension class Middleman::Extensions::CacheBuster < ::Middleman::Extension + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .php .css .js), 'List of extensions that are searched for bustable assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' + def initialize(app, options_hash={}, &block) super - # After compass is setup, make it use the registered cache buster - app.compass_config do |config| - config.asset_cache_buster do |path, real_path| - real_path = real_path.path if real_path.is_a? File - real_path = real_path.gsub(File.join(app.root, app.config[:build_dir]), app.config[:source]) - if File.readable?(real_path) - File.mtime(real_path).strftime('%s') - else - logger.warn "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}" - end - end - end if app.respond_to?(:compass_config) + require 'middleman-core/middleware/inline_url_rewriter' end - helpers do - # asset_url override if we're using cache busting - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - def asset_url(path, prefix='', options={}) - http_path = super + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :cache_buster, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) + end - if http_path.include?('://') || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path)) - http_path - else - if respond_to?(:http_images_path) && prefix == http_images_path - prefix = images_dir - end - - real_path_static = File.join(prefix, path) - - if build? - real_path_dynamic = File.join(config[:build_dir], prefix, path) - real_path_dynamic = File.expand_path(real_path_dynamic, root) - http_path << '?' + File.mtime(real_path_dynamic).strftime('%s') if File.readable?(real_path_dynamic) - elsif resource = sitemap.find_resource_by_path(real_path_static) - if !resource.template? - http_path << '?' + File.mtime(resource.source_file).strftime('%s') - else - # It's a template, possible with partials. We can't really - # know when it's updated, so generate fresh cache buster every - # time during developement - http_path << '?' + Time.now.strftime('%s') - end - end - - http_path - end - end + def rewrite_url(asset_path, dirpath, request_path) + asset_path + '?' + Time.now.strftime('%s') end end diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index ec7d3cf0..474f914a 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -1,31 +1,37 @@ # Relative Assets extension class Middleman::Extensions::RelativeAssets < ::Middleman::Extension + option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif .ttf .otf .woff), 'List of extensions that get cache busters strings appended to them.' + option :sources, %w(.htm .html .css), 'List of extensions that are searched for relative assets.' + option :ignore, [], 'Regexes of filenames to skip adding query strings to' + def initialize(app, options_hash={}, &block) super - # After compass is setup, make it use the registered cache buster - app.compass_config do |config| - config.relative_assets = true - end if app.respond_to?(:compass_config) + require 'middleman-core/middleware/inline_url_rewriter' end - helpers do - # asset_url override for relative assets - # @param [String] path - # @param [String] prefix - # @param [Hash] options Data to pass through. - # @return [String] - def asset_url(path, prefix='', options={}) - path = super + def after_configuration + app.use ::Middleman::Middleware::InlineURLRewriter, + :id => :asset_hash, + :url_extensions => options.exts, + :source_extensions => options.sources, + :ignore => options.ignore, + :middleman_app => app, + :proc => method(:rewrite_url) + end - requested_resource = options[:current_resource] || current_resource + def rewrite_url(asset_path, dirpath, request_path) + relative_path = Pathname.new(asset_path).relative? - if path.include?('//') || path.start_with?('data:') || !requested_resource - path - else - current_dir = Pathname('/' + requested_resource.destination_path) - Pathname(path).relative_path_from(current_dir.dirname).to_s - end + full_asset_path = if relative_path + dirpath.join(asset_path).to_s + else + asset_path + end + + if !full_asset_path.include?('//') && !asset_path.start_with?('data:') + current_dir = Pathname('/' + request_path).dirname + Pathname(full_asset_path).relative_path_from(current_dir).to_s end end end diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index 4617b07d..d0fbc115 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -49,7 +49,7 @@ module Middleman asset_path end - @ignore.none? { |r| should_ignore?(r, full_asset_path) } && @proc.call(asset_path, dirpath) + @ignore.none? { |r| should_ignore?(r, full_asset_path) } && @proc.call(asset_path, dirpath, path) end status, headers, response = ::Rack::Response.new( diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 9c7a237a..3baf2872 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -38,8 +38,13 @@ module Middleman class << self # Once registered def registered(app) + opts = { output_style: :nested } + opts[:line_comments] = false if ENV['TEST'] + # Default sass options - app.config.define_setting :sass, {}, 'Sass engine options' + app.config.define_setting :sass, opts, 'Sass engine options' + + app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' # Tell Tilt to use it as well (for inline sass blocks) ::Tilt.register 'sass', SassPlusCSSFilenameTemplate @@ -50,6 +55,8 @@ module Middleman ::Tilt.prefer(ScssPlusCSSFilenameTemplate) ::Compass::ImportOnce.activate! + + require 'middleman-core/renderers/sass_functions' end alias_method :included, :registered @@ -88,14 +95,22 @@ module Middleman # Change Sass path, for url functions, to the build folder if we're building # @return [Hash] def sass_options - more_opts = { filename: eval_file, line: line, syntax: syntax } + ctx = ::Middleman::Renderers::Haml.last_haml_scope || @context - if @context.is_a?(::Middleman::TemplateContext) && file - location_of_sass_file = @context.source_dir + more_opts = { + load_paths: ctx.config[:sass_assets_paths], + filename: eval_file, + line: line, + syntax: syntax, + custom: { middleman_context: ctx.app } + } + + if ctx.is_a?(::Middleman::TemplateContext) && file + location_of_sass_file = ctx.source_dir parts = basename.split('.') parts.pop - more_opts[:css_filename] = File.join(location_of_sass_file, @context.config[:css_dir], parts.join('.')) + more_opts[:css_filename] = File.join(location_of_sass_file, ctx.config[:css_dir], parts.join('.')) end options.merge(more_opts) diff --git a/middleman-core/lib/middleman-core/renderers/sass_functions.rb b/middleman-core/lib/middleman-core/renderers/sass_functions.rb new file mode 100644 index 00000000..e7d955ac --- /dev/null +++ b/middleman-core/lib/middleman-core/renderers/sass_functions.rb @@ -0,0 +1,117 @@ +module Sprockets + module Sass + module Functions + + # Using Middleman::Util#asset_path, return the full path + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # background: url(image-path("image.jpg")); // background: url("/assets/image.jpg"); + # background: url(image-path("image.jpg", $digest: true)); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); + # + def image_path(source, options = {}) + p = ::Middleman::Util.asset_path(middleman_context, :images, source.value, map_options(options)) + ::Sass::Script::String.new p.to_s, :string + end + + # Using Middleman::Util#asset_path, return the url CSS + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # background: image-url("image.jpg"); // background: url("/assets/image.jpg"); + # background: image-url("image.jpg", $digest: true); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); + # + def image_url(source, options = {}, cache_buster = nil) + # Work with the Compass #image_url API + if options.respond_to? :value + case options.value + when true + return image_path source + else + options = {} + end + end + ::Sass::Script::String.new "url(#{image_path(source, options)})" + end + + # Using Middleman::Util#asset_path, return the full path + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # src: url(font-path("font.ttf")); // src: url("/assets/font.ttf"); + # src: url(font-path("font.ttf", $digest: true)); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); + # + def font_path(source, options = {}) + p = ::Middleman::Util.asset_path(middleman_context, :fonts, source.value, map_options(options)) + ::Sass::Script::String.new p.to_s, :string + end + + # Using Middleman::Util#asset_path, return the url CSS + # for the given +source+ as a Sass String. This supports keyword + # arguments that mirror the +options+. + # + # === Examples + # + # src: font-url("font.ttf"); // src: url("/assets/font.ttf"); + # src: font-url("image.jpg", $digest: true); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); + # + def font_url(source, options = {}) + # Work with the Compass #font_url API + if options.respond_to? :value + case options.value + when true + return font_path source + else + options = {} + end + end + ::Sass::Script::String.new "url(#{font_path(source, options)})" + end + + protected + + # Returns a reference to Middleman's context through + # the importer. + def middleman_context # :nodoc: + options[:custom][:middleman_context] + end + + # Returns an options hash where the keys are symbolized + # and the values are unwrapped Sass literals. + def map_options(options = {}) # :nodoc: + ::Sass::Util.map_hash(options) do |key, value| + [key.to_sym, value.respond_to?(:value) ? value.value : value] + end + end + end + end +end + +module Sass::Script::Functions + include Sprockets::Sass::Functions + + # Hack to ensure previous API declarations (by Compass or whatever) + # don't take precedence. + [:asset_path, :asset_url, :image_path, :image_url, :font_path, :font_url, :asset_data_uri].each do |method| + defined?(@signatures) && @signatures.delete(method) + end + + declare :asset_path, [:source], :var_kwargs => true + declare :asset_path, [:source, :kind] + declare :asset_url, [:source], :var_kwargs => true + declare :asset_url, [:source, :kind] + declare :image_path, [:source], :var_kwargs => true + declare :image_url, [:source], :var_kwargs => true + declare :image_url, [:source, :only_path] + declare :image_url, [:source, :only_path, :cache_buster] + declare :font_path, [:source], :var_kwargs => true + declare :font_url, [:source], :var_kwargs => true + declare :font_url, [:source, :only_path] + declare :asset_data_uri, [:source] +end diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index 16bf2f25..46ecaa08 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -33,7 +33,7 @@ module Middleman app.after_configuration do context_hack = { - context: self + context: self.template_context_class.new(self) } ::Slim::Embedded::SassEngine.disable_option_validator! 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 52394f89..0009e67a 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -97,6 +97,14 @@ Then /^I should not see "([^\"]*)"$/ do |expected| @last_response.body.should_not include(expected) end +Then /^I should see content matching %r{(.*)}$/ do |expected| + @last_response.body.should match(expected) +end + +Then /^I should not see content matching %r{(.*)}$/ do |expected| + @last_response.body.should_not match(expected) +end + Then /^I should see "([^\"]*)" lines$/ do |lines| @last_response.body.chomp.split($/).length.should == lines.to_i end diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index a9f7c22c..1b47db05 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -37,6 +37,7 @@ module Middleman # Sandboxed class for template eval context = @app.template_context_class.new(@app, locs, opts) + # 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 diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 03c06e05..80800ac2 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -135,6 +135,55 @@ module Middleman end end + # Get the path of a file of a given type + # + # @param [Symbol] kind The type of file + # @param [String] source The path to the file + # @param [Hash] options Data to pass through. + # @return [String] + def asset_path(app, kind, source, options={}) + return source if source.to_s.include?('//') || source.to_s.start_with?('data:') + + asset_folder = case kind + when :css then app.config[:css_dir] + when :js then app.config[:js_dir] + when :images then app.config[:images_dir] + when :fonts then app.config[:fonts_dir] + else kind.to_s + end + + source = source.to_s.tr(' ', '') + ignore_extension = (kind == :images || kind == :fonts) # don't append extension + source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") + asset_folder = '' if source.start_with?('/') # absolute path + + asset_url(app, source, asset_folder, options) + end + + # Get the URL of an asset given a type/prefix + # + # @param [String] path The path (such as "photo.jpg") + # @param [String] prefix The type prefix (such as "images") + # @param [Hash] options Data to pass through. + # @return [String] The fully qualified asset url + def asset_url(app, path, prefix='', options={}) + # Don't touch assets which already have a full path + if path.include?('//') or path.start_with?('data:') + path + else # rewrite paths to use their destination path + if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) + resource.url + else + path = File.join(prefix, path) + if resource = app.sitemap.find_resource_by_path(path) + resource.url + else + File.join(app.config[:http_prefix], path) + end + end + end + 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. diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 070339ab..9da9f039 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -37,4 +37,14 @@ Gem::Specification.new do |s| # Automatic Image Sizes s.add_dependency('fastimage', ['~> 1.6.2']) + + # Minify CSS + s.add_dependency('sass', ['>= 3.3.4']) + + # Work around Sass performance + s.add_dependency('compass-import-once', ['~> 1.0.4']) + + # Minify JS + s.add_dependency('uglifier', ['~> 2.5']) + s.add_dependency('execjs', ['~> 2.0']) end diff --git a/middleman/middleman.gemspec b/middleman/middleman.gemspec index e0268027..045919b9 100644 --- a/middleman/middleman.gemspec +++ b/middleman/middleman.gemspec @@ -21,12 +21,8 @@ Gem::Specification.new do |s| s.add_dependency('middleman-core', Middleman::VERSION) s.add_dependency('middleman-cli', Middleman::VERSION) s.add_dependency('middleman-sprockets', '>= 3.1.2') + s.add_dependency('middleman-compass', '~> 4.0.0') s.add_dependency('haml', ['>= 4.0.5']) - s.add_dependency('sass', ['>= 3.3.4']) - s.add_dependency("compass-import-once", ["1.0.4"]) - s.add_dependency('compass', ['>= 1.0.0.alpha.19']) - s.add_dependency('uglifier', ['~> 2.5']) s.add_dependency('coffee-script', ['~> 2.2.0']) - s.add_dependency('execjs', ['~> 2.0']) s.add_dependency('kramdown', ['~> 1.2']) end From d1c71e473d14ea186d7569c738a857babe36f225 Mon Sep 17 00:00:00 2001 From: Ian MacLeod Date: Mon, 9 Jun 2014 17:34:33 -0700 Subject: [PATCH 054/662] `Rubocop` is now `RuboCop` See https://github.com/bbatsov/rubocop/commit/ff167d8f202baf7a68955db0aaf0dc29afb7e7ee --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 05da4ae9..5176f04e 100644 --- a/Rakefile +++ b/Rakefile @@ -58,7 +58,7 @@ end require 'rubocop/rake_task' desc 'Run RuboCop to check code consistency' -Rubocop::RakeTask.new(:rubocop) do |task| +RuboCop::RakeTask.new(:rubocop) do |task| task.fail_on_error = false end From ee1d89fe553abfdca7ff05b3a2a33e8081f72367 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 9 Jun 2014 14:02:46 -0700 Subject: [PATCH 055/662] fix whitespace --- middleman-compass/features/support/env.rb | 1 - middleman-compass/lib/middleman-compass.rb | 2 +- .../lib/middleman-compass/extension.rb | 29 ++++++++++--------- middleman-core/features/support/env.rb | 1 - .../core_extensions/extensions.rb | 12 -------- .../middleman-core/extensions/asset_host.rb | 9 ++---- 6 files changed, 18 insertions(+), 36 deletions(-) diff --git a/middleman-compass/features/support/env.rb b/middleman-compass/features/support/env.rb index 4494e443..12233ac0 100644 --- a/middleman-compass/features/support/env.rb +++ b/middleman-compass/features/support/env.rb @@ -1,6 +1,5 @@ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) ENV['TEST'] = 'true' -ENV["AUTOLOAD_COMPASS"] = "true" require "middleman-core" require "middleman-core/step_definitions" require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-compass') diff --git a/middleman-compass/lib/middleman-compass.rb b/middleman-compass/lib/middleman-compass.rb index 8b3ff674..66f0db45 100644 --- a/middleman-compass/lib/middleman-compass.rb +++ b/middleman-compass/lib/middleman-compass.rb @@ -1,6 +1,6 @@ require "middleman-core" -Middleman::Extensions.register(:compass) do +Middleman::Extensions.register :compass, auto_activate: :before_configuration do require "middleman-compass/extension" Middleman::CompassExtension end diff --git a/middleman-compass/lib/middleman-compass/extension.rb b/middleman-compass/lib/middleman-compass/extension.rb index 17fe4dc4..c7e93a3f 100644 --- a/middleman-compass/lib/middleman-compass/extension.rb +++ b/middleman-compass/lib/middleman-compass/extension.rb @@ -8,30 +8,31 @@ module Middleman # Hooks to manually update the compass config after we're # done with it - app.define_hook :compass_config end + app.define_hook :compass_config + end def after_configuration - ::Compass.configuration do |compass_config| - compass_config.project_path = app.source_dir - compass_config.environment = :development - compass_config.cache = false - compass_config.sass_dir = app.config[:css_dir] - compass_config.css_dir = app.config[:css_dir] - compass_config.javascripts_dir = app.config[:js_dir] - compass_config.fonts_dir = app.config[:fonts_dir] - compass_config.images_dir = app.config[:images_dir] - compass_config.http_path = app.config[:http_prefix] + ::Compass.configuration do |compass| + compass.project_path = app.source_dir + compass.environment = :development + compass.cache = false + compass.sass_dir = app.config[:css_dir] + compass.css_dir = app.config[:css_dir] + compass.javascripts_dir = app.config[:js_dir] + compass.fonts_dir = app.config[:fonts_dir] + compass.images_dir = app.config[:images_dir] + compass.http_path = app.config[:http_prefix] # Disable this initially, the cache_buster extension will # re-enable it if requested. - compass_config.asset_cache_buster { |_| nil } + compass.asset_cache_buster { |_| nil } # Disable this initially, the relative_assets extension will - compass_config.relative_assets = false + compass.relative_assets = false # Default output style - compass_config.output_style = :nested + compass.output_style = :nested end # Call hook diff --git a/middleman-core/features/support/env.rb b/middleman-core/features/support/env.rb index 59bea134..08e3442a 100644 --- a/middleman-core/features/support/env.rb +++ b/middleman-core/features/support/env.rb @@ -1,6 +1,5 @@ ENV["TEST"] = "true" ENV["AUTOLOAD_SPROCKETS"] ||= "false" -ENV["AUTOLOAD_COMPASS"] ||= "false" require 'simplecov' SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/../..')) diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 9db3a667..475024a1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -17,9 +17,6 @@ module Middleman app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - app.config.define_setting :autoload_compass, true, 'Automatically load compass at startup?' - app.config[:autoload_compass] = (ENV['AUTOLOAD_COMPASS'] == 'true') if ENV['AUTOLOAD_COMPASS'] - app.extend ClassMethods app.delegate :configure, to: :"self.class" end @@ -105,15 +102,6 @@ module Middleman end end - if config[:autoload_compass] - begin - require 'middleman-compass' - activate :compass - rescue LoadError - # Compass is not available, don't complain about it - end - end - # Evaluate a passed block if given config_context.instance_exec(&block) if block_given? diff --git a/middleman-core/lib/middleman-core/extensions/asset_host.rb b/middleman-core/lib/middleman-core/extensions/asset_host.rb index f9f67cc0..9a872b5d 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_host.rb @@ -1,16 +1,11 @@ -# Asset Host module +require 'middleman-core/middleware/inline_url_rewriter' + class Middleman::Extensions::AssetHost < ::Middleman::Extension option :host, nil, 'The asset host to use or a Proc to determine asset host' option :exts, %w(.css .png .jpg .jpeg .svg .svgz .js .gif), 'List of extensions that get cache busters strings appended to them.' option :sources, %w(.htm .html .php .css .js), 'List of extensions that are searched for bustable assets.' option :ignore, [], 'Regexes of filenames to skip adding query strings to' - def initialize(app, options_hash={}, &block) - super - - require 'middleman-core/middleware/inline_url_rewriter' - end - def after_configuration app.use ::Middleman::Middleware::InlineURLRewriter, :id => :asset_host, From 7840ebf98a6e405606fbbc8d92a3ae3dc12841e9 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 11 Jun 2014 09:25:59 -0700 Subject: [PATCH 056/662] move compass ext out of the main repo --- Gemfile | 2 +- middleman-compass/.gitignore | 10 --- middleman-compass/.travis.yml | 16 ----- middleman-compass/CONTRIBUTING.md | 43 ------------ middleman-compass/Gemfile | 17 ----- middleman-compass/LICENSE.md | 20 ------ middleman-compass/README.md | 59 ---------------- middleman-compass/Rakefile | 20 ------ .../features/compass-sprites.feature | 6 -- middleman-compass/features/fonts.feature | 15 ---- middleman-compass/features/support/env.rb | 7 -- .../fixtures/compass-sprites-app/config.rb | 2 - .../source/images/icon/arrow_down.png | Bin 379 -> 0 bytes .../source/images/icon/arrow_left.png | Bin 345 -> 0 bytes .../source/images/icon/arrow_right.png | Bin 349 -> 0 bytes .../source/images/icon/arrow_up.png | Bin 372 -> 0 bytes .../source/stylesheets/site.css.scss | 3 - .../fixtures/fonts-app/config.rb | 0 .../fonts-app/source/fonts/StMarie-Thin.otf | Bin 197044 -> 0 bytes .../fonts-app/source/fonts/blank/blank.otf | 0 .../source/stylesheets/fonts.css.sass | 5 -- middleman-compass/lib/middleman-compass.rb | 6 -- .../lib/middleman-compass/extension.rb | 64 ------------------ .../lib/middleman-compass/version.rb | 5 -- middleman-compass/middleman-compass.gemspec | 20 ------ middleman-core/features/slim.feature | 50 -------------- 26 files changed, 1 insertion(+), 369 deletions(-) delete mode 100644 middleman-compass/.gitignore delete mode 100644 middleman-compass/.travis.yml delete mode 100644 middleman-compass/CONTRIBUTING.md delete mode 100644 middleman-compass/Gemfile delete mode 100644 middleman-compass/LICENSE.md delete mode 100644 middleman-compass/README.md delete mode 100644 middleman-compass/Rakefile delete mode 100644 middleman-compass/features/compass-sprites.feature delete mode 100644 middleman-compass/features/fonts.feature delete mode 100644 middleman-compass/features/support/env.rb delete mode 100644 middleman-compass/fixtures/compass-sprites-app/config.rb delete mode 100755 middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png delete mode 100755 middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png delete mode 100755 middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png delete mode 100755 middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png delete mode 100644 middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss delete mode 100644 middleman-compass/fixtures/fonts-app/config.rb delete mode 100755 middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf delete mode 100644 middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf delete mode 100644 middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass delete mode 100644 middleman-compass/lib/middleman-compass.rb delete mode 100644 middleman-compass/lib/middleman-compass/extension.rb delete mode 100644 middleman-compass/lib/middleman-compass/version.rb delete mode 100644 middleman-compass/middleman-compass.gemspec diff --git a/Gemfile b/Gemfile index 04f5ee70..504273be 100644 --- a/Gemfile +++ b/Gemfile @@ -37,6 +37,6 @@ gem 'rubocop', require: false # Middleman itself gem 'middleman-core', path: 'middleman-core' gem 'middleman-cli', path: 'middleman-cli' -gem 'middleman-compass', path: 'middleman-compass', require: false +gem 'middleman-compass', github: 'middleman/middleman-compass', require: false gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false gem 'middleman', path: 'middleman' diff --git a/middleman-compass/.gitignore b/middleman-compass/.gitignore deleted file mode 100644 index be83c767..00000000 --- a/middleman-compass/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -Gemfile.lock -Gemfile-v4.lock -tmp -.rbenv-* -.sass-cache -pkg -build -.ruby-version -.cache diff --git a/middleman-compass/.travis.yml b/middleman-compass/.travis.yml deleted file mode 100644 index a032273c..00000000 --- a/middleman-compass/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -rvm: - - 1.9.3 - - 2.0.0 - - 2.1.1 - - jruby-19mode - -gemfile: - - Gemfile - - Gemfile-v4 - -script: "bundle exec rake test" - -env: TEST=true - -matrix: - fast_finish: true \ No newline at end of file diff --git a/middleman-compass/CONTRIBUTING.md b/middleman-compass/CONTRIBUTING.md deleted file mode 100644 index 97bdc981..00000000 --- a/middleman-compass/CONTRIBUTING.md +++ /dev/null @@ -1,43 +0,0 @@ -# Contributing -In the spirit of [free software][free-sw], **everyone** is encouraged to help -improve this project. - -[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html - -Here are some ways *you* can contribute: - -* by using alpha, beta, and prerelease versions -* by reporting bugs -* by suggesting new features -* by writing or editing documentation -* by writing specifications -* by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace ) -* by refactoring code -* by closing [issues][] -* by reviewing patches - -[issues]: https://github.com/middleman/middleman-compass/issues - -## Submitting an Issue -We use the [GitHub issue tracker][issues] to track bugs and features. Before -submitting a bug report or feature request, check to make sure it hasn't -already been submitted. When submitting a bug report, please include a [Gist][] -that includes a stack trace and any details that may be necessary to reproduce -the bug, including your gem version, Ruby version, and operating system. -Ideally, a bug report should include a pull request with failing specs. - -[gist]: https://gist.github.com/ - -## Submitting a Pull Request -1. [Fork the repository.][fork] -2. [Create a topic branch.][branch] -3. Add specs for your unimplemented feature or bug fix. -4. Run `bundle exec rake test`. If your specs pass, return to step 3. -5. Implement your feature or bug fix. -6. Run `bundle exec rake test`. If your specs fail, return to step 5. -7. Add, commit, and push your changes. -8. [Submit a pull request.][pr] - -[fork]: http://help.github.com/fork-a-repo/ -[branch]: http://learn.github.com/p/branching.html -[pr]: http://help.github.com/send-pull-requests/ diff --git a/middleman-compass/Gemfile b/middleman-compass/Gemfile deleted file mode 100644 index e3a01e2e..00000000 --- a/middleman-compass/Gemfile +++ /dev/null @@ -1,17 +0,0 @@ -source "https://rubygems.org" - -gem "middleman-cli", :github => "middleman/middleman", :branch => "master" -gem "middleman-core", :github => "middleman/middleman", :branch => "master" - -# Specify your gem's dependencies in middleman-sprockets.gemspec -gemspec - -gem "rake", "~> 10.0.3", :require => false -gem "yard", "~> 0.8.0", :require => false - -# Test tools -gem "cucumber" -gem "fivemat", "~> 1.2.1" -gem "aruba" -gem "rspec", "~> 2.14" -gem "builder", "~> 3.0" diff --git a/middleman-compass/LICENSE.md b/middleman-compass/LICENSE.md deleted file mode 100644 index 8ffe042d..00000000 --- a/middleman-compass/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2012-2013 Thomas Reynolds - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/middleman-compass/README.md b/middleman-compass/README.md deleted file mode 100644 index c4d23d97..00000000 --- a/middleman-compass/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Middleman-compass - -`middleman-compass` is an extension for the [Middleman] static site generator that allows support for [Compass](http://compass-style.org) in your assets. - -## Installation - -If you're just getting started, install the `middleman` gem and generate a new project: - -``` -gem install middleman -middleman init MY_PROJECT -``` - -If you already have a Middleman project: Add `gem "middleman-compass"` to your `Gemfile` and run `bundle install` - -## Configuration - -``` -activate :compass -``` - -## Build & Dependency Status - -[![Gem Version](https://badge.fury.io/rb/middleman-compass.png)][gem] -[![Build Status](https://travis-ci.org/middleman/middleman-compass.png)][travis] -[![Dependency Status](https://gemnasium.com/middleman/middleman-compass.png?travis)][gemnasium] -[![Code Quality](https://codeclimate.com/github/middleman/middleman-compass.png)][codeclimate] - -## Community - -The official community forum is available at: http://forum.middlemanapp.com - -## Bug Reports - -Github Issues are used for managing bug reports and feature requests. If you run into issues, please search the issues and submit new problems: https://github.com/middleman/middleman-compass/issues - -The best way to get quick responses to your issues and swift fixes to your bugs is to submit detailed bug reports, include test cases and respond to developer questions in a timely manner. Even better, if you know Ruby, you can submit [Pull Requests](https://help.github.com/articles/using-pull-requests) containing Cucumber Features which describe how your feature should work or exploit the bug you are submitting. - -## How to Run Cucumber Tests - -1. Checkout Repository: `git clone https://github.com/middleman/middleman-compass.git` -2. Install Bundler: `gem install bundler` -3. Run `bundle install` inside the project root to install the gem dependencies. -4. Run test cases: `bundle exec rake test` - -## Donate - -[Click here to lend your support to Middleman](https://spacebox.io/s/4dXbHBorC3) - -## License - -Copyright (c) 2012-2013 Thomas Reynolds. MIT Licensed, see [LICENSE] for details. - -[middleman]: http://middlemanapp.com -[gem]: https://rubygems.org/gems/middleman-compass -[travis]: http://travis-ci.org/middleman/middleman-compass -[gemnasium]: https://gemnasium.com/middleman/middleman-compass -[codeclimate]: https://codeclimate.com/github/middleman/middleman-compass -[LICENSE]: https://github.com/middleman/middleman-compass/blob/master/LICENSE.md \ No newline at end of file diff --git a/middleman-compass/Rakefile b/middleman-compass/Rakefile deleted file mode 100644 index e23e477b..00000000 --- a/middleman-compass/Rakefile +++ /dev/null @@ -1,20 +0,0 @@ -require 'bundler' -Bundler::GemHelper.install_tasks - -require 'cucumber/rake/task' - -require 'middleman-core/version' - -Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t| - exempt_tags = ["--tags ~@wip"] - t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" -end - -require 'rake/clean' - -task :test => [:cucumber] - -desc "Build HTML documentation" -task :doc do - sh 'bundle exec yard' -end diff --git a/middleman-compass/features/compass-sprites.feature b/middleman-compass/features/compass-sprites.feature deleted file mode 100644 index 871c277a..00000000 --- a/middleman-compass/features/compass-sprites.feature +++ /dev/null @@ -1,6 +0,0 @@ -Feature: Compass sprites should be generated on build and copied - Scenario: Building a clean site with sprites - Given a successfully built app at "compass-sprites-app" - When I cd to "build" - Then the following files should exist: - | images/icon-s0de2218f58.png | \ No newline at end of file diff --git a/middleman-compass/features/fonts.feature b/middleman-compass/features/fonts.feature deleted file mode 100644 index 7cc9f8a1..00000000 --- a/middleman-compass/features/fonts.feature +++ /dev/null @@ -1,15 +0,0 @@ -Feature: Web Fonts - - Scenario: Checking built folder for content - Given a successfully built app at "fonts-app" - When I cd to "build" - Then the following files should exist: - | stylesheets/fonts.css | - And the file "stylesheets/fonts.css" should contain "/fonts/StMarie-Thin.otf" - And the file "stylesheets/fonts.css" should contain "/fonts/blank/blank.otf" - - Scenario: Rendering scss - Given the Server is running at "fonts-app" - When I go to "/stylesheets/fonts.css" - Then I should see "/fonts/StMarie-Thin.otf" - And I should see "/fonts/blank/blank.otf" diff --git a/middleman-compass/features/support/env.rb b/middleman-compass/features/support/env.rb deleted file mode 100644 index 12233ac0..00000000 --- a/middleman-compass/features/support/env.rb +++ /dev/null @@ -1,7 +0,0 @@ -PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) -ENV['TEST'] = 'true' -require "middleman-core" -require "middleman-core/step_definitions" -require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-compass') -require "erubis" - diff --git a/middleman-compass/fixtures/compass-sprites-app/config.rb b/middleman-compass/fixtures/compass-sprites-app/config.rb deleted file mode 100644 index 6347d3ab..00000000 --- a/middleman-compass/fixtures/compass-sprites-app/config.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'middleman-compass' -activate :compass \ No newline at end of file diff --git a/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_down.png deleted file mode 100755 index 2c4e279377bf348f9cf53894e76bb673ccf067bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^zbpD<_bdda}R zAX(xXQ4*Y=R#Ki=l*-_klAn~S;F+74o*I;zm{M7IGS!BGfsxnK#WBR<^wP=p-pqjl zN1h)M$rSCJvvpBZJ=Z}Gt&4h(zIV9p`r#-dee}Iz#Epm>oMnQ^ie=08S6lD?t+Vd( z?v|KswTJs>-Zl5^5&V26>FVJJOU09W3`%E6t?PR~+32p5=z+Tz<6b?;Sjx)a$Xr>6EXEGLlS|nYL>P+OpO`9nC}gnpw*?$;WMS<6knvT?L(jEk7oU^c1&-N| z7JQMPb9c_R*}ZBnxJ+GVY&cTi@b2r$<|m)7MCCOuTcCaEs)+U9vpK7`|FaMkD6-_2 z++TMrd4>3L6;8Il%QC*Nw_B-o`QX!c*|XNYoh@nCws`x)w;Ahwru$?){&w`(<{;_! j<@4J^XQkY;`p;yevi*3*-5uf#3=9mOu6{1-oD!M<7Qv!R diff --git a/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_left.png deleted file mode 100755 index 5dc696781e6135d37b5bf2e98e46fd94f020c48d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 345 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^zbpD<_bdda}R zAX(xXQ4*Y=R#Ki=l*-_klAn~S;F+74o*I;zm{M7IGS!BGf#J2Mi(`nz>Eu8E|JyUG zHgq;R8JytJu$_34?Z|FV!v@yg`mgWj?>AZ^ae$+nb-`Kjqc>H){QL9s@P`k7o!jE= z>y7{XVm!28qK?UM#=pLV<|lez;!{%^v+OjFX{}p+VC|6)&+p5#N#v!>pi}DK=-A_2WU(nzopr0L@vM A0RR91 diff --git a/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_right.png deleted file mode 100755 index b1a1819238c6de8f9e50988f4151261fa6ba64ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 349 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^zbpD<_bdda}R zAX(xXQ4*Y=R#Ki=l*-_klAn~S;F+74o*I;zm{M7IGS!BGf#JQUi(`nz>Eu8E|JyUG zHgq;R864r^nDKPu?d(ay(l^=u{Q7wM+4Jx5;S-NaIBpE6QWBOCt^fZg^~dMm{D{lj~O;n04GIwr%8X(E$Setdmxe)#O|?Rs;w_AlVSbePHbq}PpU58vA_VEq5@ zz{mId>l=TVAAVo&@JC$jTl>S))7Mu;MP{k5_uZX(j%l;x5`lG+D_)pKe9UM0E3Wwc z_4oV<+VzKH8H&FBYp>pDCH*4ZV0L$Nw_{LH*Tb)?uk&orzq7ZX`kbwFg@gbz57$=R z2C+BnxBhUfh@AT*V#kI0uPgzd9T#Mm8YU&SJZEL#cz(eAZqAwu3=9kmp00i_>zopr E06PhqnE(I) diff --git a/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png b/middleman-compass/fixtures/compass-sprites-app/source/images/icon/arrow_up.png deleted file mode 100755 index 1ebb193243780b8eb1919a51ef27c2a0d36ccec2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 372 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7SkfJR9T^zbpD<_bdda}R zAX(xXQ4*Y=R#Ki=l*-_klAn~S;F+74o*I;zm{M7IGS!BGfsxJA#WBR<^wP=p`YeGW zN6&AX*^-fNx=HY2mg*bzi5+e_(Oml`b@_NqTfu2ORimY&t*rgUp7Q^;Q`3^!^8Kp) z>nxw&yA#I2=xY*aerNwp%`*Mp;eic%U%%bG#dh}`wYm2mBt71C>blhWf(iUW!Mpt@ zpL_J@4AU8&{-?}wr>?83#aYFiUSZbQ#n+nZ=c1@KL1D(MIc%1%CM~`kFI=1epUS5Aq3{?mV-6hq_GL`TOyt@Q!C1uTY* zY_0u_Km6IWooA~g2+z>m^SFbh?||0X@&w0&^OPA+8A!}fVR|5W^CD*pt5%o&|3md( YSzin7N>cN?4GLEVPgg&ebxsLQ0RM`VV*mgE diff --git a/middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss b/middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss deleted file mode 100644 index 25a6f535..00000000 --- a/middleman-compass/fixtures/compass-sprites-app/source/stylesheets/site.css.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import "compass"; -@import "icon/*.png"; -@include all-icon-sprites; \ No newline at end of file diff --git a/middleman-compass/fixtures/fonts-app/config.rb b/middleman-compass/fixtures/fonts-app/config.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf b/middleman-compass/fixtures/fonts-app/source/fonts/StMarie-Thin.otf deleted file mode 100755 index aa601879134eefe4ac115bb2e5a1d355ee952977..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 197044 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 Y@^^{JY`^>Fv(M$4&;9+j$dCJ?0Fs|@m;e9( diff --git a/middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf b/middleman-compass/fixtures/fonts-app/source/fonts/blank/blank.otf deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass b/middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass deleted file mode 100644 index dd1aea7e..00000000 --- a/middleman-compass/fixtures/fonts-app/source/stylesheets/fonts.css.sass +++ /dev/null @@ -1,5 +0,0 @@ -@import "compass/css3/font-face" - -+font-face("St Marie", font-files("StMarie-Thin.otf", opentype)) -+font-face("St Marie", font-files("blank/blank.otf", opentype)) - diff --git a/middleman-compass/lib/middleman-compass.rb b/middleman-compass/lib/middleman-compass.rb deleted file mode 100644 index 66f0db45..00000000 --- a/middleman-compass/lib/middleman-compass.rb +++ /dev/null @@ -1,6 +0,0 @@ -require "middleman-core" - -Middleman::Extensions.register :compass, auto_activate: :before_configuration do - require "middleman-compass/extension" - Middleman::CompassExtension -end diff --git a/middleman-compass/lib/middleman-compass/extension.rb b/middleman-compass/lib/middleman-compass/extension.rb deleted file mode 100644 index c7e93a3f..00000000 --- a/middleman-compass/lib/middleman-compass/extension.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Middleman - class CompassExtension < Extension - def initialize(app, options_hash={}, &block) - require 'middleman-core/renderers/sass' - require 'compass' - - super - - # Hooks to manually update the compass config after we're - # done with it - app.define_hook :compass_config - end - - def after_configuration - ::Compass.configuration do |compass| - compass.project_path = app.source_dir - compass.environment = :development - compass.cache = false - compass.sass_dir = app.config[:css_dir] - compass.css_dir = app.config[:css_dir] - compass.javascripts_dir = app.config[:js_dir] - compass.fonts_dir = app.config[:fonts_dir] - compass.images_dir = app.config[:images_dir] - compass.http_path = app.config[:http_prefix] - - # Disable this initially, the cache_buster extension will - # re-enable it if requested. - compass.asset_cache_buster { |_| nil } - - # Disable this initially, the relative_assets extension will - - compass.relative_assets = false - - # Default output style - compass.output_style = :nested - end - - # Call hook - app.run_hook_for :compass_config, app, ::Compass.configuration - - # Tell Tilt to use it as well (for inline sass blocks) - ::Tilt.register 'sass', CompassSassTemplate - ::Tilt.prefer(CompassSassTemplate) - - # Tell Tilt to use it as well (for inline scss blocks) - ::Tilt.register 'scss', CompassScssTemplate - ::Tilt.prefer(CompassScssTemplate) - end - - # A Compass Sass template for Tilt, adding our options in - class CompassSassTemplate < ::Middleman::Renderers::Sass::SassPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end - - # A Compass Scss template for Tilt, adding our options in - class CompassScssTemplate < ::Middleman::Renderers::Sass::ScssPlusCSSFilenameTemplate - def sass_options - super.merge(::Compass.configuration.to_sass_engine_options) - end - end - end -end \ No newline at end of file diff --git a/middleman-compass/lib/middleman-compass/version.rb b/middleman-compass/lib/middleman-compass/version.rb deleted file mode 100644 index fcc5622e..00000000 --- a/middleman-compass/lib/middleman-compass/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Middleman - module Compass - VERSION = "4.0.0" - end -end diff --git a/middleman-compass/middleman-compass.gemspec b/middleman-compass/middleman-compass.gemspec deleted file mode 100644 index ad108349..00000000 --- a/middleman-compass/middleman-compass.gemspec +++ /dev/null @@ -1,20 +0,0 @@ -# -*- encoding: utf-8 -*- -$:.push File.expand_path("../lib", __FILE__) -require "middleman-compass/version" - -Gem::Specification.new do |s| - s.name = "middleman-compass" - s.version = Middleman::Compass::VERSION - s.platform = Gem::Platform::RUBY - s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Karl Freeman'] - s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'karlfreeman@gmail.com'] - s.homepage = "https://github.com/middleman/middleman-compass" - s.summary = %q{Compass support for Middleman} - s.description = %q{Compass support for Middleman} - s.license = "MIT" - s.files = `git ls-files -z`.split("\0") - s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0") - s.require_paths = ["lib"] - s.add_dependency("middleman-core")#, [">= 4.0.0"]) - s.add_dependency('compass', ['>= 1.0.0.alpha.19']) -end diff --git a/middleman-core/features/slim.feature b/middleman-core/features/slim.feature index 02663f3a..62471060 100644 --- a/middleman-core/features/slim.feature +++ b/middleman-core/features/slim.feature @@ -19,53 +19,3 @@ Feature: Support slim templating language And the Server is running at "empty_app" When I go to "/slim.html" Then I should see "

Welcome to Slim

" - - Scenario: Rendering Scss in a Slim filter - Given an empty app - And a file named "config.rb" with: - """ - require 'middleman-compass' - activate :compass - """ - And a file named "source/scss.html.slim" with: - """ - doctype 5 - html lang='en' - head - meta charset="utf-8" - scss: - @import "compass"; - @include global-reset; - body - h1 Welcome to Slim - """ - And a file named "source/sass.html.slim" with: - """ - doctype 5 - html lang='en' - head - meta charset="utf-8" - sass: - @import "compass" - +global-reset - body - h1 Welcome to Slim - """ - And a file named "source/error.html.slim" with: - """ - doctype 5 - html lang='en' - head - meta charset="utf-8" - scss: - +global-reset - body - h1 Welcome to Slim - """ - And the Server is running at "empty_app" - When I go to "/scss.html" - Then I should see "html, body, div" - When I go to "/sass.html" - Then I should see "html, body, div" - When I go to "/error.html" - Then I should see "Syntax error" \ No newline at end of file From c3b22fe325df319f2808f25c5be1ec3407837650 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 11 Jun 2014 10:19:10 -0700 Subject: [PATCH 057/662] sass renderer shouldn't explode if haml isn't available --- middleman-core/lib/middleman-core/renderers/sass.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 3baf2872..b5642655 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -95,7 +95,11 @@ module Middleman # Change Sass path, for url functions, to the build folder if we're building # @return [Hash] def sass_options - ctx = ::Middleman::Renderers::Haml.last_haml_scope || @context + ctx = if defined?(::Middleman::Renderers::Haml) + ::Middleman::Renderers::Haml.last_haml_scope || @context + else + @context + end more_opts = { load_paths: ctx.config[:sass_assets_paths], From d035b449eaec6d778d73d7b712aed5f10ca83298 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 11 Jun 2014 10:23:33 -0700 Subject: [PATCH 058/662] Rename Rubocop --- Rakefile | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Rakefile b/Rakefile index 16b61bd1..892dc444 100644 --- a/Rakefile +++ b/Rakefile @@ -46,6 +46,8 @@ task :test do GEM_PATHS.each do |g| Dir.chdir("#{File.join(ROOT, g)}") { sh "#{Gem.ruby} -S rake test" } end + + Rake::Task['rubocop'].invoke end desc 'Run specs for all middleman gems' @@ -55,15 +57,10 @@ task :spec do end end -begin - require 'rubocop/rake_task' - if defined?(Rubocop) - desc 'Run RuboCop to check code consistency' - Rubocop::RakeTask.new(:rubocop) do |task| - task.fail_on_error = false - end - end -rescue LoadError +require 'rubocop/rake_task' +desc 'Run RuboCop to check code consistency' +RuboCop::RakeTask.new(:rubocop) do |task| + task.fail_on_error = false end desc 'Run tests for all middleman gems' From a21dca025ef7748ba36dcfe140f386b36abe5273 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 6 Jun 2014 15:32:00 -0700 Subject: [PATCH 059/662] Separate Environments from Modes --- CHANGELOG.md | 1 + middleman-cli/lib/middleman-cli/build.rb | 36 ++++++++++--------- middleman-core/features/mount_rack.feature | 4 +-- middleman-core/fixtures/env-app/config.rb | 0 .../env-app/environments/development.rb | 1 + .../env-app/environments/production.rb | 2 ++ .../fixtures/env-app/source/index.html.erb | 3 ++ .../env-app/source/stylesheets/site.css.scss | 3 ++ .../fixtures/generator-test/config.rb | 4 +-- .../lib/middleman-core/application.rb | 34 +++++++++--------- .../lib/middleman-core/config_context.rb | 10 +++++- .../lib/middleman-core/core_extensions.rb | 6 ++++ .../core_extensions/extensions.rb | 34 ++++++++---------- .../middleman-core/core_extensions/i18n.rb | 4 +-- .../core_extensions/show_exceptions.rb | 23 +++++------- .../lib/middleman-core/extensions.rb | 27 +++++++++----- .../middleman-core/renderers/coffee_script.rb | 2 +- .../step_definitions/server_steps.rb | 14 +++----- .../lib/middleman-core/template_context.rb | 2 +- 19 files changed, 113 insertions(+), 97 deletions(-) create mode 100644 middleman-core/fixtures/env-app/config.rb create mode 100644 middleman-core/fixtures/env-app/environments/development.rb create mode 100644 middleman-core/fixtures/env-app/environments/production.rb create mode 100644 middleman-core/fixtures/env-app/source/index.html.erb create mode 100644 middleman-core/fixtures/env-app/source/stylesheets/site.css.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f4e8962..df41d316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* Add support for `environments` with the `-e` CLI flag. Loads additional config from `environments/envname.rb`. Removed `development?` helper in favor of `environment?(:development)`. Added `server?` helper to differentiate between build and server mode. * Removed `with_layout`. Use loops of `page` instead. * Removed Queryable Sitemap API * Removed `css_compressor` setting, use `activate :minify_css, :compressor =>` instead. diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 7b105629..60538431 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -18,6 +18,10 @@ module Middleman::Cli namespace :build desc 'build [options]', 'Builds the static site for deployment' + method_option :environment, + aliases: '-e', + default: ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + desc: 'The environment Middleman will run under' method_option :clean, type: :boolean, default: true, @@ -58,18 +62,26 @@ module Middleman::Cli @debugging = Middleman::Cli::Base.respond_to?(:debugging) && Middleman::Cli::Base.debugging self.had_errors = false - self.class.shared_instance(options['verbose'], options['instrument']) + env = options['environment'].to_sym + verbose = options['verbose'] ? 0 : 1 + instrument = options['instrument'] + + app = ::Middleman::Application.server.inst do + config[:mode] = :build + config[:environment] = env + ::Middleman::Logger.singleton(verbose, instrument) + end opts = {} opts[:glob] = options['glob'] if options.key?('glob') opts[:clean] = options['clean'] - self.class.shared_instance.run_hook :before_build, self + app.run_hook :before_build, self - action BuildAction.new(self, opts) + action BuildAction.new(self, app, opts) - self.class.shared_instance.run_hook :after_build, self - self.class.shared_instance.config_context.execute_after_build_callbacks(self) + app.run_hook :after_build, self + app.config_context.execute_after_build_callbacks(self) if had_errors && !debugging msg = 'There were errors during this build' @@ -87,16 +99,6 @@ module Middleman::Cli def exit_on_failure? true end - - # Middleman::Application singleton - # - # @return [Middleman::Application] - def shared_instance(verbose=false, instrument=false) - @_shared_instance ||= ::Middleman::Application.server.inst do - config[:environment] = :build - ::Middleman::Logger.singleton(verbose ? 0 : 1, instrument) - end - end end end @@ -109,8 +111,8 @@ module Middleman::Cli # # @param [Middleman::Cli::Build] base # @param [Hash] config - def initialize(base, config={}) - @app = base.class.shared_instance + def initialize(base, app, config={}) + @app = app @source_dir = Pathname(@app.source_dir) @build_dir = Pathname(@app.config[:build_dir]) @to_clean = Set.new diff --git a/middleman-core/features/mount_rack.feature b/middleman-core/features/mount_rack.feature index ab105021..dcb83146 100644 --- a/middleman-core/features/mount_rack.feature +++ b/middleman-core/features/mount_rack.feature @@ -47,9 +47,7 @@ Feature: Support Rack apps mounted using map run MySinatra end - configure :build do - endpoint "sinatra/index2.html", path: "/sinatra/" - end + endpoint "sinatra/index2.html", path: "/sinatra/" endpoint "dedoo.html", path: "/sinatra/derp.html" diff --git a/middleman-core/fixtures/env-app/config.rb b/middleman-core/fixtures/env-app/config.rb new file mode 100644 index 00000000..e69de29b diff --git a/middleman-core/fixtures/env-app/environments/development.rb b/middleman-core/fixtures/env-app/environments/development.rb new file mode 100644 index 00000000..bce85faf --- /dev/null +++ b/middleman-core/fixtures/env-app/environments/development.rb @@ -0,0 +1 @@ +set :api_key, "dev1" diff --git a/middleman-core/fixtures/env-app/environments/production.rb b/middleman-core/fixtures/env-app/environments/production.rb new file mode 100644 index 00000000..1f217266 --- /dev/null +++ b/middleman-core/fixtures/env-app/environments/production.rb @@ -0,0 +1,2 @@ +set :api_key, "prod2" +activate :minify_css diff --git a/middleman-core/fixtures/env-app/source/index.html.erb b/middleman-core/fixtures/env-app/source/index.html.erb new file mode 100644 index 00000000..4b6d6950 --- /dev/null +++ b/middleman-core/fixtures/env-app/source/index.html.erb @@ -0,0 +1,3 @@ + diff --git a/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss b/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss new file mode 100644 index 00000000..bcb115c5 --- /dev/null +++ b/middleman-core/fixtures/env-app/source/stylesheets/site.css.scss @@ -0,0 +1,3 @@ +body { + backgroud: red; +} diff --git a/middleman-core/fixtures/generator-test/config.rb b/middleman-core/fixtures/generator-test/config.rb index 9fc9561c..f3b6a505 100644 --- a/middleman-core/fixtures/generator-test/config.rb +++ b/middleman-core/fixtures/generator-test/config.rb @@ -51,8 +51,8 @@ # Change the images directory # set :images_dir, "alternative_image_directory" -# Build-specific configuration -configure :build do +# Production build configuration +configure :production do # For example, change the Compass output style for deployment # activate :minify_css diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 64ce952e..e264ea09 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -31,9 +31,6 @@ require 'middleman-core/core_extensions/request' # Custom Extension API and config.rb handling require 'middleman-core/core_extensions/extensions' -# Catch and show exceptions at the Rack level -require 'middleman-core/core_extensions/show_exceptions' - # Core Middleman Class module Middleman class Application @@ -73,9 +70,13 @@ module Middleman # @return [String] config.define_setting :source, 'source', 'Name of the source directory' - # Middleman environment. Defaults to :development, set to :build by the build process + # Middleman mode. Defaults to :server, set to :build by the build process # @return [String] - config.define_setting :environment, ((ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :development), 'Middleman environment. Defaults to :development, set to :build by the build process' + config.define_setting :mode, ((ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :server), 'Middleman mode. Defaults to :server' + + # Middleman environment. Defaults to :development + # @return [String] + config.define_setting :environment, :development, 'Middleman environment. Defaults to :development' # Which file should be used for directory indexes # @return [String] @@ -139,9 +140,6 @@ module Middleman # Basic Rack Request Handling include Middleman::CoreExtensions::Request - # Handle exceptions - include Middleman::CoreExtensions::ShowExceptions - # Setup custom rendering include Middleman::CoreExtensions::Rendering @@ -179,9 +177,7 @@ module Middleman # Setup the default values from calls to set before initialization self.class.config.load_settings(self.class.superclass.config.all_settings) - ::Middleman::Extensions.auto_activate[:before_sitemap].each do |ext_name| - activate ext_name - end + ::Middleman::Extensions.auto_activate(:before_sitemap, self) # Initialize the Sitemap @sitemap = ::Middleman::Sitemap::Store.new(self) @@ -204,16 +200,22 @@ module Middleman @config_context.define_singleton_method(name, &func) end - # Whether we're in development mode + # Whether we're in server mode # @return [Boolean] If we're in dev mode - def development? - config[:environment] == :development + def server? + config[:mode] == :server end # Whether we're in build mode - # @return [Boolean] If we're in build mode + # @return [Boolean] If we're in dev mode def build? - config[:environment] == :build + config[:mode] == :build + end + + # Whether we're in a specific environment + # @return [Boolean] + def environment?(key) + config[:environment] == key end # The full path to the source directory diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index ff5ffa76..96f30d1d 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -8,7 +8,7 @@ module Middleman attr_reader :app # Whitelist methods that can reach out. - delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :root, to: :app + delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :files, :root, to: :app def initialize(app, template_context_class) @app = app @@ -34,6 +34,14 @@ module Middleman end end + def include_environment(name) + path = File.dirname(__FILE__) + other_config = File.join(path, name.to_s) + if File.exist? other_config + instance_eval File.read(other_config), other_config, 1 + end + end + def ready(&block) @ready_callbacks << block end diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 9fd5f985..e85afac3 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -11,6 +11,12 @@ Middleman::Extensions.register :data, auto_activate: :before_sitemap do Middleman::CoreExtensions::Data end +# Catch and show exceptions at the Rack level +Middleman::Extensions.register :show_exceptions, auto_activate: :before_configuration, modes: [:server] do + require 'middleman-core/core_extensions/show_exceptions' + Middleman::CoreExtensions::ShowExceptions +end + # File Change Notifier Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do require 'middleman-core/core_extensions/file_watcher' diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 475024a1..7a76776c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -11,8 +11,6 @@ module Middleman app.define_hook :instance_available app.define_hook :after_configuration app.define_hook :before_configuration - app.define_hook :build_config - app.define_hook :development_config app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] @@ -26,11 +24,11 @@ module Middleman # # @example # # Only minify when building - # configure :build do + # configure :production do # activate :minify_javascript # end # - # @param [String, Symbol] env The environment to run in (:build, :development) + # @param [String, Symbol] env The environment to run in # @return [void] def configure(env, &block) send("#{env}_config", &block) @@ -80,18 +78,19 @@ module Middleman # Override application initialization to load `config.rb` and to call lifecycle hooks. def initialize(&block) - super - self.class.inst = self # Search the root of the project for required files $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) + # Evaluate a passed block if given + config_context.instance_exec(&block) if block_given? + + super + ::Middleman::Extension.clear_after_extension_callbacks - ::Middleman::Extensions.auto_activate[:before_configuration].each do |ext_name| - activate ext_name - end + ::Middleman::Extensions.auto_activate(:before_configuration, self) if config[:autoload_sprockets] begin @@ -102,9 +101,6 @@ module Middleman end end - # Evaluate a passed block if given - config_context.instance_exec(&block) if block_given? - run_hook :initialized run_hook :before_configuration @@ -112,19 +108,17 @@ module Middleman # Check for and evaluate local configuration in `config.rb` local_config = File.join(root, 'config.rb') if File.exist? local_config - logger.debug '== Reading: Local config' + logger.debug '== Reading: Local config' config_context.instance_eval File.read(local_config), local_config, 1 end - if build? - run_hook :build_config - config_context.execute_configure_callbacks(:build) + env_config = File.join(root, 'environments', "#{config[:environment]}.rb") + if File.exist? env_config + logger.debug "== Reading: #{config[:environment]} config" + config_context.instance_eval File.read(env_config), env_config, 1 end - if development? - run_hook :development_config - config_context.execute_configure_callbacks(:development) - end + config_context.execute_configure_callbacks(config[:environment]) run_hook :instance_available diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index e83f7cfc..41e2ba0f 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -37,9 +37,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension configure_i18n - unless app.build? - logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})" - end + logger.info "== Locales: #{langs.join(', ')} (Default #{@mount_at_root})" # Don't output localizable files app.ignore File.join(options[:templates_dir], '**') diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index 67fad3c3..3f039ca6 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -1,21 +1,14 @@ # Support rack/showexceptions during development -module Middleman - module CoreExtensions - module ShowExceptions - def self.included(app) - # Require lib - require 'rack/showexceptions' +module Middleman::CoreExtensions + class ShowExceptions < ::Middleman::Extension + def initialize(app, options_hash={}, &block) + super - # Whether to catch and display exceptions - # @return [Boolean] - app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions' + require 'rack/showexceptions' + end - # When in dev - app.configure :development do - # Include middlemare - use ::Rack::ShowExceptions if config[:show_exceptions] - end - end + def after_configuration + app.use ::Rack::ShowExceptions end end end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 519493be..a33bf203 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -14,6 +14,8 @@ module Middleman before_configuration: [] } + AutoActivation = Struct.new(:name, :modes) + class << self # @api private # A hash of all registered extensions. Registered extensions are not necessarily active - this @@ -21,12 +23,6 @@ module Middleman # @return [Hash{Symbol => Class, Proc}] A directory of known extensions indexed by the name they were registered under. The value may be a Proc, which can be lazily called to return an extension class. attr_reader :registered - # @api private - # A list of extensions that should be automatically loaded at different points in the application startup lifecycle. - # Only internal, built-in Middleman extensions should be listed here. - # @return [Hash{Symbol => Symbol}] A hash from event name to extension name. - attr_reader :auto_activate - # Register a new extension. Choose a name which will be # used to activate the extension in `config.rb`, like this: # @@ -71,7 +67,10 @@ module Middleman raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end - @auto_activate[options[:auto_activate]] << name if options[:auto_activate] + if options[:auto_activate] + descriptor = AutoActivation.new(name, options[:modes] || :all) + @auto_activate[options[:auto_activate]] << descriptor + end end # @api private @@ -106,7 +105,19 @@ module Middleman # A flattened list of all extensions which are automatically activated # @return [Array] A list of extension names which are automatically activated. def auto_activated - @auto_activate.values.flatten + @auto_activate.values.map(&:name).flatten + end + + # @api private + # Load autoactivatable extensions for the given env. + # @param [Symbol] group The name of the auto_activation group. + # @param [Middleman::Application] app An instance of the app. + def auto_activate(group, app) + @auto_activate[group].each do |descriptor| + if descriptor[:modes] == :all || descriptor[:modes].include?(app.config[:mode]) + app.activate descriptor[:name] + end + end end end end diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb index e6f57cb4..b8519845 100644 --- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb +++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb @@ -30,7 +30,7 @@ module Middleman # @param [Hash] locals # @return [String] def evaluate(context, locals, &block) - return super if middleman_app.build? + return super unless middleman_app.server? begin super 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 0009e67a..eee447ca 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -29,10 +29,6 @@ Given /^"([^\"]*)" is set to "([^\"]*)"$/ do |variable, value| } end -Given /^current environment is "([^\"]*)"$/ do |env| - @current_env = env.to_sym -end - Given /^the Server is running$/ do root_dir = File.expand_path(current_dir) @@ -45,14 +41,12 @@ Given /^the Server is running$/ do ENV['MM_ROOT'] = root_dir initialize_commands = @initialize_commands || [] - initialize_commands.unshift lambda { - config[:environment] = @current_env || :development - config[:show_exceptions] = false - } @server_inst = Middleman::Application.server.inst do - initialize_commands.each do |p| - instance_exec(&p) + app.initialized do + initialize_commands.each do |p| + config_context.instance_exec(&p) + end end end diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 48ccad41..a81db78b 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -19,7 +19,7 @@ module Middleman attr_accessor :current_engine # Shorthand references to global values on the app instance. - delegate :config, :logger, :sitemap, :build?, :development?, :data, :extensions, :source_dir, :root, to: :app + delegate :config, :logger, :sitemap, :server?, :build?, :environment?, :data, :extensions, :source_dir, :root, to: :app # Initialize a context with the current app and predefined locals and options hashes. # From 449d38bcd287a4fe8858cba29b1ab83904f933a1 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 11 Jun 2014 13:39:40 -0700 Subject: [PATCH 060/662] Update to rspec 3 --- Gemfile | 8 ++++---- gem_rake_helper.rb | 2 +- .../step_definitions/builder_steps.rb | 2 +- .../step_definitions/server_steps.rb | 20 +++++++++---------- .../spec/middleman-core/binary_spec.rb | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 504273be..c1d05994 100644 --- a/Gemfile +++ b/Gemfile @@ -5,10 +5,10 @@ gem 'rake', '~> 10.0.3', require: false gem 'yard', '~> 0.8.0', require: false # Test tools -gem 'cucumber', '~> 1.3.1' -gem 'fivemat', '~> 1.2.1' -gem 'aruba', '~> 0.5.1' -gem 'rspec', '~> 2.12' +gem 'cucumber', '~> 1.3.15' +gem 'fivemat', '~> 1.3.1' +gem 'aruba', '~> 0.5.4' +gem 'rspec', '~> 3.0' gem 'simplecov' # Optional middleman dependencies, included for tests diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index 284cf5dc..7b4a8990 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -34,7 +34,7 @@ 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'] + spec.rspec_opts = ['--color', '--format documentation'] end desc 'Run tests, both RSpec and Cucumber' diff --git a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb index eda6467b..d0478d6a 100644 --- a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb @@ -64,7 +64,7 @@ end Then /^the file "([^\"]*)" should not have been updated$/ do |file| target = File.join(current_dir, file) - File.mtime(target).should == @modification_times[target] + expect(File.mtime(target)).to eq(@modification_times[target]) end # Provide this Aruba overload in case we're matching something with quotes in it 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 0009e67a..c72d8712 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -71,40 +71,40 @@ end Then /^going to "([^\"]*)" should not raise an exception$/ do |url| last_response = nil - lambda { + expect { last_response = @browser.get(URI.escape(url)) - }.should_not raise_exception + }.to_not raise_error @last_response = last_response end Then /^the content type should be "([^\"]*)"$/ do |expected| - @last_response.content_type.should start_with(expected) + expect(@last_response.content_type).to start_with(expected) end Then /^I should see "([^\"]*)"$/ do |expected| - @last_response.body.should include(expected) + expect(@last_response.body).to include(expected) end Then /^I should see '([^\']*)'$/ do |expected| - @last_response.body.should include(expected) + expect(@last_response.body).to include(expected) end Then /^I should see:$/ do |expected| - @last_response.body.should include(expected) + expect(@last_response.body).to include(expected) end Then /^I should not see "([^\"]*)"$/ do |expected| - @last_response.body.should_not include(expected) + expect(@last_response.body).to_not include(expected) end Then /^I should see content matching %r{(.*)}$/ do |expected| - @last_response.body.should match(expected) + expect(@last_response.body).to match(expected) end Then /^I should not see content matching %r{(.*)}$/ do |expected| - @last_response.body.should_not match(expected) + expect(@last_response.body).to_not match(expected) end Then /^I should see "([^\"]*)" lines$/ do |lines| - @last_response.body.chomp.split($/).length.should == lines.to_i + expect(@last_response.body.chomp.split($/).length).to eq(lines.to_i) end diff --git a/middleman-core/spec/middleman-core/binary_spec.rb b/middleman-core/spec/middleman-core/binary_spec.rb index 79944331..4f8d11d2 100644 --- a/middleman-core/spec/middleman-core/binary_spec.rb +++ b/middleman-core/spec/middleman-core/binary_spec.rb @@ -3,13 +3,13 @@ require 'middleman-core/util' describe "Middleman::Util#binary?" do %w(plain.txt unicode.txt unicode).each do |file| it "recognizes #{file} as not binary" do - expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_false + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be false end end %w(middleman.png middleman stars.svgz).each do |file| it "recognizes #{file} as binary" do - expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_true + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be true end end end From 69396d34c1fdbdc2cf6b0ae0934f925bf39b80c8 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 21:54:53 -0700 Subject: [PATCH 061/662] Start gutting the provides_metadata methods and move some of frontmatter over --- .../core_extensions/front_matter.rb | 47 ++++++++------ .../lib/middleman-core/sitemap/resource.rb | 12 +++- .../lib/middleman-core/sitemap/store.rb | 62 +------------------ 3 files changed, 39 insertions(+), 82 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 5310d37e..0d90a577 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -29,29 +29,36 @@ module Middleman::CoreExtensions app.files.deleted { |file| ext.clear_data(file) } end + # Modify each resource to add data & options from frontmatter. + def manipulate_resource_list(resources) + resources.each do |resource| + fmdata = data(resource.path).first + + # Copy over special options + opts = fmdata.extract!(:layout, :layout_engine, :renderer_options) + if opts.has_key?(:renderer_options) + opts[:renderer_options].symbolize_keys! + end + + ignored = fmdata.delete(:ignored) + + # TODO: Enhance data? NOOOO + # TODO: stringify-keys? immutable/freeze? + + resource.add_metadata options: opts, page: fmdata + + # TODO: resource.ignore! if ignored + + # TODO: Save new template here somewhere? + end + end + def after_configuration app.ignore %r{\.frontmatter$} + # TODO: Add to file watcher ignore? - ::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods - - app.sitemap.provides_metadata do |path| - fmdata = data(path).first - - data = {} - - [:layout, :layout_engine].each do |opt| - data[opt] = fmdata[opt] unless fmdata[opt].nil? - end - - if fmdata[:renderer_options] - data[:renderer_options] = {} - fmdata[:renderer_options].each do |k, v| - data[:renderer_options][k.to_sym] = v - end - end - - { options: data } - end + # TODO: Replace all of this functionality + #::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods end module ResourceInstanceMethods diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 4a68d3fa..0c42c059 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -46,7 +46,11 @@ module Middleman @source_file = source_file @destination_path = @path - @local_metadata = { options: {}, locals: {} } + # Options are generally rendering/sitemap options + # Locals are local variables for rendering this resource's template + # Page are data that is exposed through this resource's data member. + # Note: It is named 'page' for backwards compatibility with older MM. + @local_metadata = { options: {}, locals: {}, page: {} } end # Whether this resource has a template file @@ -70,6 +74,12 @@ module Middleman result end + # Data about this resource, populated from frontmatter or extensions. + # @return [HashWithIndifferentAccess] + def data + metadata[:page] + end + # Merge in new metadata specific to this resource. # @param [Hash] meta A metadata block like provides_metadata_for_path takes def add_metadata(meta={}) diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 992cae00..eab6291d 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -19,9 +19,6 @@ module Middleman # which is the path relative to the source directory, minus any template # extensions. All "path" parameters used in this class are source paths. class Store - # @return [Middleman::Application] - attr_accessor :app - # Initialize with parent app # @param [Middleman::Application] app def initialize(app) @@ -54,7 +51,7 @@ module Middleman register_resource_list_manipulator(k, m.new(self)) end - app.config_context.class.send :delegate, :sitemap, to: :app + @app.config_context.class.send :delegate, :sitemap, to: :app end # Register an object which can transform the sitemap resource list. Best to register @@ -128,63 +125,6 @@ module Middleman @resources_not_ignored = nil end - # Register a handler to provide metadata on a file path - # @param [Regexp] matcher - # @return [Array>] - def provides_metadata(matcher=nil, &block) - @_provides_metadata ||= [] - @_provides_metadata << [block, matcher] if block_given? - @_provides_metadata - end - - # Get the metadata for a specific file - # @param [String] source_file - # @return [Hash] - def metadata_for_file(source_file) - blank_metadata = { options: {}, locals: {} } - - provides_metadata.reduce(blank_metadata) do |result, (callback, matcher)| - next result if matcher && !source_file.match(matcher) - - metadata = callback.call(source_file).dup - result.deep_merge(metadata) - end - end - - # Register a handler to provide metadata on a url path - # @param [Regexp] matcher - # @return [Array>] - def provides_metadata_for_path(matcher=nil, &block) - @_provides_metadata_for_path ||= [] - if block_given? - @_provides_metadata_for_path << [block, matcher] - @_cached_metadata = {} - end - @_provides_metadata_for_path - end - - # Get the metadata for a specific URL - # @param [String] request_path - # @return [Hash] - def metadata_for_path(request_path) - return @_cached_metadata[request_path] if @_cached_metadata[request_path] - - blank_metadata = { options: {}, locals: {} } - - @_cached_metadata[request_path] = provides_metadata_for_path.reduce(blank_metadata) do |result, (callback, matcher)| - case matcher - when Regexp - next result unless request_path =~ matcher - when String - next result unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{request_path}") - end - - metadata = callback.call(request_path).dup - - result.deep_merge(metadata) - end - end - # Get the URL path for an on-disk file # @param [String] file # @return [String] From c285848866c48c3f98d92f891d828104be8e8811 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 22:24:27 -0700 Subject: [PATCH 062/662] Clean up i18n a bit, stake out some territory around routing and resource --- .../core_extensions/front_matter.rb | 1 - .../middleman-core/core_extensions/i18n.rb | 37 ++++--------------- .../middleman-core/core_extensions/routing.rb | 5 +++ .../lib/middleman-core/sitemap/resource.rb | 31 ++++++---------- 4 files changed, 24 insertions(+), 50 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 0d90a577..5685cc3b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -55,7 +55,6 @@ module Middleman::CoreExtensions def after_configuration app.ignore %r{\.frontmatter$} - # TODO: Add to file watcher ignore? # TODO: Replace all of this functionality #::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 41e2ba0f..6b2d46ff 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -42,7 +42,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # Don't output localizable files app.ignore File.join(options[:templates_dir], '**') - app.sitemap.provides_metadata_for_path(&method(:metadata_for_path)) app.files.changed(&method(:on_file_changed)) app.files.deleted(&method(:on_file_changed)) end @@ -56,14 +55,12 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension delegate :logger, to: :app def langs - @_langs ||= known_languages + @langs ||= known_languages end # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) - @_localization_data = {} - new_resources = [] resources.each do |resource| @@ -81,6 +78,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension new_resources << build_resource(path, resource.path, page_id, lang) end end + + # This is for backwards compatibility with the old provides_metadata-based code + # that used to be in this extension, but I don't know how much sense it makes. + resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } end resources + new_resources @@ -90,7 +91,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def on_file_changed(file) if @locales_regex =~ file - @_langs = nil # Clear langs cache + @langs = nil # Clear langs cache ::I18n.reload! end end @@ -112,24 +113,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - def metadata_for_path(url) - if d = localization_data(url) - lang, page_id = d - else - # Default to the @mount_at_root lang - page_id = nil - lang = @mount_at_root - end - - { - locals: { - lang: lang, - page_id: page_id - }, - options: { lang: lang } - } - end - def known_languages if options[:langs] Array(options[:langs]).map(&:to_sym) @@ -144,11 +127,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - def localization_data(path) - @_localization_data ||= {} - @_localization_data[path] - end - # Parse locale extension filename # @return [lang, path, basename] # will return +nil+ if no locale extension @@ -183,10 +161,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension path = path.sub(options[:templates_dir] + '/', '') - @_localization_data[path] = [lang, path, localized_page_id] - p = ::Middleman::Sitemap::Resource.new(app.sitemap, path) p.proxy_to(source_path) + p.add_metadata locals: { lang: lang, page_id: path }, options: { lang: lang } ::I18n.locale = old_locale p diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 04f05197..cc4d3e3c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -14,7 +14,9 @@ module Middleman options = opts.dup # Default layout + # TODO: This seems wrong options[:layout] = @app.config[:layout] if options[:layout].nil? + # TODO: You can set options and locals, but not data metadata = { options: options, locals: options.delete(:locals) || {} } # If the url is a regexp @@ -37,6 +39,9 @@ module Middleman end # Setup a metadata matcher for rendering those options + # TODO: How to get rid of this? Perhaps a separate extension that manipulates + # in this sort of data? + # This is harder because sitemap isn't available. @app.sitemap.provides_metadata_for_path(url) { |_| metadata } end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 0c42c059..c80a90b4 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -11,12 +11,8 @@ module Middleman include Middleman::Sitemap::Extensions::Traversal include Middleman::Sitemap::Extensions::ContentType - # @return [Middleman::Application] - attr_reader :app - delegate :logger, :instrument, to: :app - # @return [Middleman::Sitemap::Store] - attr_reader :store + #attr_reader :store # The source path of this resource (relative to the source directory, # without template extensions) @@ -29,9 +25,8 @@ module Middleman # Set the on-disk source file for this resource # @return [String] - # attr_reader :source_file - def source_file + # TODO: Make this work when get_source_file doesn't exist @source_file || get_source_file end @@ -63,9 +58,10 @@ module Middleman # Get the metadata for both the current source_file and the current path # @return [Hash] def metadata - result = store.metadata_for_path(path).dup + # TODO: Get rid of all this + result = @store.metadata_for_path(path).dup - file_meta = store.metadata_for_file(source_file).dup + file_meta = @store.metadata_for_file(source_file).dup result.deep_merge!(file_meta) local_meta = @local_metadata.dup @@ -77,6 +73,7 @@ module Middleman # Data about this resource, populated from frontmatter or extensions. # @return [HashWithIndifferentAccess] def data + # TODO: Upconvert/freeze at this point? metadata[:page] end @@ -96,18 +93,14 @@ module Middleman File.extname(path) end - def request_path - destination_path - end - # Render this resource # @return [String] def render(opts={}, locs={}) return ::Middleman::FileRenderer.new(@app, source_file).template_data_for_file unless template? - relative_source = Pathname(source_file).relative_path_from(Pathname(app.root)) + relative_source = Pathname(source_file).relative_path_from(Pathname(@app.root)) - instrument 'render.resource', path: relative_source, destination_path: destination_path do + @app.instrument 'render.resource', path: relative_source, destination_path: destination_path do md = metadata.dup opts = md[:options].deep_merge(opts) locs = md[:locals].deep_merge(locs) @@ -128,11 +121,11 @@ module Middleman # @return [String] def url url_path = destination_path - if app.config[:strip_index_file] - url_path = url_path.sub(/(^|\/)#{Regexp.escape(app.config[:index_file])}$/, - app.config[:trailing_slash] ? '/' : '') + if @app.config[:strip_index_file] + url_path = url_path.sub(/(^|\/)#{Regexp.escape(@app.config[:index_file])}$/, + @app.config[:trailing_slash] ? '/' : '') end - File.join(app.config[:http_prefix], url_path) + File.join(@app.config[:http_prefix], url_path) end # Whether the source file is binary. From d83d6e077c3fbcbb5f5cffa3c51911c006b8921f Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 22:50:19 -0700 Subject: [PATCH 063/662] Extensionize liquid, bring back provides_metadata_for_path --- .../core_extensions/rendering.rb | 3 +- .../lib/middleman-core/renderers/liquid.rb | 24 ++++++------- .../lib/middleman-core/sitemap/resource.rb | 15 ++++---- .../lib/middleman-core/sitemap/store.rb | 36 +++++++++++++++++++ 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 53f72265..d045f1a4 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -48,7 +48,8 @@ module Middleman # Liquid Support begin require 'middleman-core/renderers/liquid' - app.send :include, Middleman::Renderers::Liquid + Middleman::Extensions.register :liquid, Middleman::Renderers::Liquid + activate :liquid rescue LoadError end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index 4fc93204..7f9f5157 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -4,23 +4,19 @@ require 'liquid' module Middleman module Renderers # Liquid Renderer - module Liquid - # Setup extension - class << self - # Once registerd - def registered(app) - # After config, setup liquid partial paths - app.after_configuration do - ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir) + class Liquid < Middleman::Extension + # After config, setup liquid partial paths + def after_configuration + ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir) + end - # Convert data object into a hash for liquid - sitemap.provides_metadata %r{\.liquid$} do - { locals: { data: data.to_h } } - end + def manipulate_resource_list(resources) + resources.each do |resource| + # Convert data object into a hash for liquid + if resource.source_file =~ %r{\.liquid$} + resource.add_metadata locals: { data: app.data.to_h } end end - - alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index c80a90b4..345b0360 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -11,15 +11,12 @@ module Middleman include Middleman::Sitemap::Extensions::Traversal include Middleman::Sitemap::Extensions::ContentType - # @return [Middleman::Sitemap::Store] - #attr_reader :store - # The source path of this resource (relative to the source directory, # without template extensions) # @return [String] attr_reader :path - # The output path for this resource + # The output path in the build directory for this resource # @return [String] attr_accessor :destination_path @@ -78,15 +75,15 @@ module Middleman end # Merge in new metadata specific to this resource. - # @param [Hash] meta A metadata block like provides_metadata_for_path takes + # @param [Hash] meta A metadata block with keys :options, :locals, :page. + # Options are generally rendering/sitemap options + # Locals are local variables for rendering this resource's template + # Page are data that is exposed through this resource's data member. + # Note: It is named 'page' for backwards compatibility with older MM. def add_metadata(meta={}) @local_metadata.deep_merge!(meta.dup) end - # The output/preview URL for this resource - # @return [String] - attr_accessor :destination_path - # Extension of the path (i.e. '.js') # @return [String] def ext diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index eab6291d..882698de 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -25,8 +25,10 @@ module Middleman @app = app @resources = [] @_cached_metadata = {} + # TODO: Should this be a set or hash? @resource_list_manipulators = [] @needs_sitemap_rebuild = true + @provides_metadata_for_path = Set.new @lock = Monitor.new reset_lookup_cache! @@ -125,6 +127,40 @@ module Middleman @resources_not_ignored = nil end + # Register a handler to provide metadata on a url path + # Extensions authors should prefer adding metadata to Resources via a + # sitemap manipulator and Resource#add_metadata. + # + # @param [Regexp, String] matcher or glob string + def provides_metadata_for_path(matcher=nil, &block) + if block_given? + @provides_metadata_for_path << [block, matcher] + @_cached_metadata = {} + end + nil + end + + # Get the metadata for a specific source path + # @param [String] path Source path of a resource + # @return [Hash] + def metadata_for_path(path) + return @_cached_metadata[path] if @_cached_metadata.has_key?(path) + + blank_metadata = { options: {}, locals: {}, page: {} } + + @_cached_metadata[path] = @provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)| + case matcher + when Regexp + next result unless path =~ matcher + when String + next result unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{path}") + end + + metadata = callback.call(path) + result.deep_merge(metadata) + end + end + # Get the URL path for an on-disk file # @param [String] file # @return [String] From 5c04c2f42bb5355c946a86cc14dcc0113b6fc8a2 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 23:02:20 -0700 Subject: [PATCH 064/662] More trimming --- .../lib/middleman-core/sitemap/resource.rb | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 345b0360..ee907023 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -55,16 +55,8 @@ module Middleman # Get the metadata for both the current source_file and the current path # @return [Hash] def metadata - # TODO: Get rid of all this - result = @store.metadata_for_path(path).dup - - file_meta = @store.metadata_for_file(source_file).dup - result.deep_merge!(file_meta) - - local_meta = @local_metadata.dup - result.deep_merge!(local_meta) - - result + # TODO: The only reason we call metadata_for_page is to power the "page" DSL + @store.metadata_for_path(path).deep_merge @local_metadata end # Data about this resource, populated from frontmatter or extensions. @@ -81,7 +73,7 @@ module Middleman # Page are data that is exposed through this resource's data member. # Note: It is named 'page' for backwards compatibility with older MM. def add_metadata(meta={}) - @local_metadata.deep_merge!(meta.dup) + @local_metadata.deep_merge!(meta) end # Extension of the path (i.e. '.js') @@ -98,7 +90,7 @@ module Middleman relative_source = Pathname(source_file).relative_path_from(Pathname(@app.root)) @app.instrument 'render.resource', path: relative_source, destination_path: destination_path do - md = metadata.dup + md = metadata opts = md[:options].deep_merge(opts) locs = md[:locals].deep_merge(locs) locs[:current_path] ||= destination_path From adfad92f8f2b90c975a1db771e664ef5453d1cec Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 23:21:12 -0700 Subject: [PATCH 065/662] Get rid of raw_data --- .../core_extensions/front_matter.rb | 39 ++----------------- .../extensions/directory_indexes.rb | 7 +--- .../sitemap/extensions/content_type.rb | 4 +- .../sitemap/extensions/ignores.rb | 10 +++-- .../sitemap/extensions/redirects.rb | 8 ---- .../sitemap/extensions/request_endpoints.rb | 6 --- .../lib/middleman-core/sitemap/resource.rb | 33 +++++++++++----- 7 files changed, 36 insertions(+), 71 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 5685cc3b..e37163e8 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -35,7 +35,9 @@ module Middleman::CoreExtensions fmdata = data(resource.path).first # Copy over special options - opts = fmdata.extract!(:layout, :layout_engine, :renderer_options) + # TODO: Should we make people put these under "options" instead of having + # special known keys? + opts = fmdata.extract!(:layout, :layout_engine, :renderer_options, :directory_index, :content_type) if opts.has_key?(:renderer_options) opts[:renderer_options].symbolize_keys! end @@ -55,41 +57,6 @@ module Middleman::CoreExtensions def after_configuration app.ignore %r{\.frontmatter$} - - # TODO: Replace all of this functionality - #::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods - end - - module ResourceInstanceMethods - def ignored? - if !proxy? && raw_data[:ignored] == true - true - else - super - end - end - - # This page's frontmatter without being enhanced for access by either symbols or strings. - # Used internally - # @private - # @return [Hash] - def raw_data - app.extensions[:front_matter].data(source_file).first - end - - # This page's frontmatter - # @return [Hash] - def data - @enhanced_data ||= ::Middleman::Util.recursively_enhance(raw_data).freeze - end - - # Override Resource#content_type to take into account frontmatter - def content_type - # Allow setting content type in frontmatter too - raw_data.fetch :content_type do - super - end - end end # Get the template data from a path diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index 68e9f958..b63eb64e 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -16,11 +16,8 @@ class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension resource.destination_path.end_with?(new_index_path) || File.extname(index_file) != resource.ext - # Check if frontmatter turns directory_index off - next if resource.raw_data[:directory_index] == false - - # Check if file metadata (options set by "page" in config.rb) turns directory_index off - next if resource.metadata[:options][:directory_index] == false + # Check if file metadata (options set by "page" in config.rb or frontmatter) turns directory_index off + next if resource.options[:directory_index] == false resource.destination_path = resource.destination_path.chomp(File.extname(index_file)) + new_index_path end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb b/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb index 619ec225..23325012 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb @@ -5,8 +5,8 @@ module Middleman::Sitemap::Extensions module ContentType # The preferred MIME content type for this resource def content_type - # Allow explcitly setting content type from page/proxy options - meta_type = metadata[:options][:content_type] + # Allow explcitly setting content type from page/proxy options or frontmatter + meta_type = options[:content_type] return meta_type if meta_type # Look up mime type based on extension diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 414cd7e9..0edb3bd6 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -51,10 +51,12 @@ module Middleman # Whether the Resource is ignored # @return [Boolean] def ignored? - @app.sitemap.ignored?(path) || - (!proxy? && - @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) - ) + # Check frontmatter/data + return true if !proxy? && data[:ignored] == true + # Ignore based on the source path (without template extensions) + return true if @app.sitemap.ignored?(path) + # This allows files to be ignored by their source file name (with template extensions) + !proxy? && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index cfff4197..dec6d825 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -75,18 +75,10 @@ module Middleman end end - # def request_path - # @request_path - # end - def binary? false end - def raw_data - {} - end - def ignored? false end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 7c4b85c3..265c5d92 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -63,16 +63,10 @@ module Middleman return output.call if output end - attr_reader :request_path - def binary? false end - def raw_data - {} - end - def ignored? false end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index ee907023..5b039cc6 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -52,6 +52,16 @@ module Middleman !::Tilt[source_file].nil? end + # Merge in new metadata specific to this resource. + # @param [Hash] meta A metadata block with keys :options, :locals, :page. + # Options are generally rendering/sitemap options + # Locals are local variables for rendering this resource's template + # Page are data that is exposed through this resource's data member. + # Note: It is named 'page' for backwards compatibility with older MM. + def add_metadata(meta={}) + @local_metadata.deep_merge!(meta) + end + # Get the metadata for both the current source_file and the current path # @return [Hash] def metadata @@ -62,18 +72,21 @@ module Middleman # Data about this resource, populated from frontmatter or extensions. # @return [HashWithIndifferentAccess] def data - # TODO: Upconvert/freeze at this point? - metadata[:page] + # TODO: Should this really be a HashWithIndifferentAccess? + ::Middleman::Util.recursively_enhance(metadata[:page]).freeze end - # Merge in new metadata specific to this resource. - # @param [Hash] meta A metadata block with keys :options, :locals, :page. - # Options are generally rendering/sitemap options - # Locals are local variables for rendering this resource's template - # Page are data that is exposed through this resource's data member. - # Note: It is named 'page' for backwards compatibility with older MM. - def add_metadata(meta={}) - @local_metadata.deep_merge!(meta) + # Options about how this resource is rendered, such as its :layout, + # :renderer_options, and whether or not to use :directory_indexes. + # @return [Hash] + def options + metadata[:options] + end + + # Local variable mappings that are used when rendering the template for this resource. + # @return [Hash] + def locals + metadata[:locals] end # Extension of the path (i.e. '.js') From d687677e38e845f28d9b893053979ed8c5580b8d Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 27 Apr 2014 23:25:10 -0700 Subject: [PATCH 066/662] Mess around with liquid --- middleman-core/lib/middleman-core/core_extensions/rendering.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index d045f1a4..42854825 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -48,8 +48,7 @@ module Middleman # Liquid Support begin require 'middleman-core/renderers/liquid' - Middleman::Extensions.register :liquid, Middleman::Renderers::Liquid - activate :liquid + Middleman::Extensions.register :liquid, Middleman::Renderers::Liquid, auto_activate: :before_configuration rescue LoadError end From 78b7bbb92aa23385c759fb0d6ee98619c3f50c5a Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 10 May 2014 18:03:56 -0700 Subject: [PATCH 067/662] TODO metadata for path extension --- .../sitemap/extensions/metadata_for_path.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb b/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb new file mode 100644 index 00000000..10463cab --- /dev/null +++ b/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb @@ -0,0 +1,17 @@ +module Middleman + module Sitemap + module Extensions + + # Add metadata to Resources based on path matchers. This exists + # entirely to support the "page" method in config.rb. + + # TODO: This requires the concept of priority for sitemap manipulators + # in order for it to always run after all other manipulators. + class MetadataForPath + def initialize(sitemap) + @app = sitemap.app + end + end + end + end +end From 213c67296906076029823fd087e0cae8c4490b9a Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Tue, 27 May 2014 23:05:37 -0700 Subject: [PATCH 068/662] Fix a lot of breakage caused by removing/hiding accessors --- middleman-cli/lib/middleman-cli/build.rb | 2 +- .../lib/middleman-core/renderers/liquid.rb | 2 +- .../middleman-core/sitemap/extensions/ignores.rb | 8 ++++---- .../middleman-core/sitemap/extensions/on_disk.rb | 4 ++-- .../middleman-core/sitemap/extensions/proxies.rb | 8 ++++---- .../sitemap/extensions/redirects.rb | 8 ++++++-- .../sitemap/extensions/request_endpoints.rb | 4 ++-- .../sitemap/extensions/traversal.rb | 16 ++++++++-------- .../lib/middleman-core/sitemap/store.rb | 15 +++++++++------ 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 60538431..80916a02 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -254,7 +254,7 @@ module Middleman::Cli FileUtils.cp(resource.source_file, output_file) else begin - response = @rack.get(URI.escape(resource.request_path)) + response = @rack.get(URI.escape(resource.destination_path)) if response.status == 200 base.create_file(output_file, binary_encode(response.body)) diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index 7f9f5157..a6fb2ef8 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -7,7 +7,7 @@ module Middleman class Liquid < Middleman::Extension # After config, setup liquid partial paths def after_configuration - ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir) + ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(app.source_dir) end def manipulate_resource_list(resources) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 0edb3bd6..5a4f36b1 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -3,15 +3,15 @@ module Middleman module Extensions # Class to handle managing ignores class Ignores - def initialize(sitemap) - @app = sitemap.app + def initialize(app, sitemap) + @app = app @app.add_to_config_context :ignore, &method(:create_ignore) - @app.define_singleton_method(:ignore, &method(:create_ignore)) + @app.define_singleton_method :ignore, &method(:create_ignore) # Array of callbacks which can ass ignored @ignored_callbacks = [] - sitemap.define_singleton_method(:ignored?, &method(:ignored?)) + sitemap.define_singleton_method :ignored?, &method(:ignored?) ::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 2c51063e..b259c43e 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -7,9 +7,9 @@ module Middleman attr_accessor :sitemap attr_accessor :waiting_for_ready - def initialize(sitemap) + def initialize(app, sitemap) @sitemap = sitemap - @app = @sitemap.app + @app = app @file_paths_on_disk = Set.new scoped_self = self diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 4c4ca5d2..37f76894 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -4,8 +4,8 @@ module Middleman # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations class Proxies - def initialize(sitemap) - @app = sitemap.app + def initialize(app) + @app = app @app.add_to_config_context :proxy, &method(:create_proxy) @app.define_singleton_method(:proxy, &method(:create_proxy)) @@ -109,10 +109,10 @@ module Middleman # if there is no resource. # @return [Sitemap::Resource] def proxied_to_resource - proxy_resource = store.find_resource_by_path(proxied_to) + proxy_resource = @store.find_resource_by_path(proxied_to) unless proxy_resource - raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}" + raise "Path #{path} proxies to unknown file #{proxied_to}:#{@store.resources.map(&:path)}" end if proxy_resource.proxy? diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index dec6d825..058595f2 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -6,8 +6,8 @@ module Middleman # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations class Redirects - def initialize(sitemap) - @app = sitemap.app + def initialize(app) + @app = app @app.add_to_config_context :redirect, &method(:create_redirect) @redirects = {} @@ -86,6 +86,10 @@ module Middleman def metadata @local_metadata.dup end + + def get_source_file + '' + end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 265c5d92..cc980879 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -4,8 +4,8 @@ module Middleman class RequestEndpoints # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations - def initialize(sitemap) - @app = sitemap.app + def initialize(app) + @app = app @app.add_to_config_context :endpoint, &method(:create_endpoint) @endpoints = {} diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index 50a0df6f..140d8f74 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -7,7 +7,7 @@ module Middleman def parent parts = path.split('/') tail = parts.pop - is_index = (tail == app.config[:index_file]) + is_index = (tail == @app.config[:index_file]) return nil if is_index && parts.length < 1 @@ -21,7 +21,7 @@ module Middleman found else parts.pop if is_index - store.find_resource_by_destination_path("#{parts.join('/')}/#{app.config[:index_file]}") + store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}") end end @@ -34,11 +34,11 @@ module Middleman base_path = eponymous_directory_path prefix = %r{^#{base_path.sub("/", "\\/")}} else - base_path = path.sub("#{app.config[:index_file]}", '') + base_path = path.sub("#{@app.config[:index_file]}", '') prefix = %r{^#{base_path.sub("/", "\\/")}} end - store.resources.select do |sub_resource| + @store.resources.select do |sub_resource| if sub_resource.path == path || sub_resource.path !~ prefix false else @@ -47,7 +47,7 @@ module Middleman if parts.length == 1 true elsif parts.length == 2 - parts.last == app.config[:index_file] + parts.last == @app.config[:index_file] else false end @@ -65,17 +65,17 @@ module Middleman # Whether this resource is either a directory index, or has the same name as an existing directory in the source # @return [Boolean] def directory_index? - path.include?(app.config[:index_file]) || path =~ /\/$/ || eponymous_directory? + path.include?(@app.config[:index_file]) || path =~ /\/$/ || eponymous_directory? end # Whether the resource has the same name as a directory in the source # (e.g., if the resource is named 'gallery.html' and a path exists named 'gallery/', this would return true) # @return [Boolean] def eponymous_directory? - if !path.end_with?("/#{app.config[:index_file]}") && destination_path.end_with?("/#{app.config[:index_file]}") + if !path.end_with?("/#{@app.config[:index_file]}") && destination_path.end_with?("/#{@app.config[:index_file]}") return true end - full_path = File.join(app.source_dir, eponymous_directory_path) + full_path = File.join(@app.source_dir, eponymous_directory_path) File.exist?(full_path) && File.directory?(full_path) end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 882698de..2de8ecf5 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -19,6 +19,9 @@ module Middleman # which is the path relative to the source directory, minus any template # extensions. All "path" parameters used in this class are source paths. class Store + # @return [Middleman::Application] + attr_reader :app + # Initialize with parent app # @param [Middleman::Application] app def initialize(app) @@ -34,23 +37,23 @@ module Middleman reset_lookup_cache! # Handle ignore commands - Middleman::Sitemap::Extensions::Ignores.new(self) + Middleman::Sitemap::Extensions::Ignores.new(@app, self) # Extensions { # Register classes which can manipulate the main site map list - on_disk: Middleman::Sitemap::Extensions::OnDisk, + on_disk: Middleman::Sitemap::Extensions::OnDisk.new(@app, self), # Request Endpoints - request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints, + request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints.new(@app), # Proxies - proxies: Middleman::Sitemap::Extensions::Proxies, + proxies: Middleman::Sitemap::Extensions::Proxies.new(@app), # Redirects - redirects: Middleman::Sitemap::Extensions::Redirects + redirects: Middleman::Sitemap::Extensions::Redirects.new(@app) }.each do |k, m| - register_resource_list_manipulator(k, m.new(self)) + register_resource_list_manipulator(k, m) end @app.config_context.class.send :delegate, :sitemap, to: :app From bf8f02d5631b2eb7e547202f36f041a9784d607b Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Wed, 28 May 2014 00:00:36 -0700 Subject: [PATCH 069/662] Turn routing into an extension --- .../lib/middleman-core/config_context.rb | 5 -- .../lib/middleman-core/core_extensions.rb | 6 ++ .../core_extensions/extensions.rb | 3 + .../middleman-core/core_extensions/routing.rb | 73 ++++++++++++++----- .../sitemap/extensions/metadata_for_path.rb | 17 ----- .../sitemap/extensions/redirects.rb | 6 +- .../sitemap/extensions/request_endpoints.rb | 4 +- .../lib/middleman-core/sitemap/resource.rb | 11 +-- .../lib/middleman-core/sitemap/store.rb | 36 --------- 9 files changed, 70 insertions(+), 91 deletions(-) delete mode 100644 middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 96f30d1d..90922ea9 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -1,10 +1,5 @@ -require 'middleman-core/core_extensions/routing' - module Middleman class ConfigContext - # page routing - include Middleman::CoreExtensions::Routing - attr_reader :app # Whitelist methods that can reach out. diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index e85afac3..4ff25339 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -45,6 +45,12 @@ Middleman::Extensions.register :lorem, auto_activate: :before_configuration do Middleman::Extensions::Lorem end +Middleman::Extensions.register :routing, auto_activate: :before_configuration do + require 'middleman-core/core_extensions/routing' + Middleman::CoreExtensions::Routing +end + + ### # Setup Optional Extensions ### diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 7a76776c..2cfb6c41 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -105,6 +105,9 @@ module Middleman run_hook :before_configuration + # Evaluate a passed block if given + config_context.instance_exec(&block) if block_given? + # Check for and evaluate local configuration in `config.rb` local_config = File.join(root, 'config.rb') if File.exist? local_config diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index cc4d3e3c..07150f7e 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -1,16 +1,55 @@ # Routing extension module Middleman module CoreExtensions - module Routing - # The page method allows the layout to be set on a specific path + class Routing < Extension + # This should always run late, but not as late as :directory_indexes, + # so it can add metadata to any pages generated by other extensions + self.resource_list_manipulator_priority = 90 + + def initialize(app, options_hash={}, &block) + super + + @page_configs = [] + end + + def before_configuration + app.add_to_config_context :page, &method(:page) + end + + def manipulate_resource_list(resources) + resources.each do |resource| + @page_configs.each do |matcher, metadata| + case matcher + when Regexp + next unless resource.path =~ matcher + when String + next unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{resource.path}") + end + + resource.add_metadata metadata + end + end + end + + # The page method allows options to be set for a given source path, regex, or glob. + # Options that may be set include layout, locals, proxy, andx ignore. # - # page "/about.html", layout: false - # page "/", layout: :homepage_layout + # @example + # page '/about.html', layout: false + # @example + # page '/index.html', layout: :homepage_layout + # @example + # page '/foo.html', locals: { foo: 'bar' } # - # @param [String] url - # @param [Hash] opts + # @param [String, Regexp] path A source path, or a Regexp/glob that can match multiple resources. + # @params [Hash] opts Options to apply to all matching resources. Undocumented options are passed on as page metadata to be used by extensions. + # @option opts [Symbol, Boolean, String] layout The layout name to use (e.g. `:article`) or `false` to disable layout. + # @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths. + # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. + # @option opts [String] proxy The source path for a template to proxy this path to. Only valid when a single path is provided. Prefer using the `proxy` method to do this. + # @option opts [Boolean] ignore Set to `true` to ignore the provided path(s). Only valid when a single path is provided. Prefer using the `ignore` method to do this. # @return [void] - def page(url, opts={}) + def page(path, opts={}) options = opts.dup # Default layout @@ -19,30 +58,26 @@ module Middleman # TODO: You can set options and locals, but not data metadata = { options: options, locals: options.delete(:locals) || {} } - # If the url is a regexp - unless url.is_a?(Regexp) || url.include?('*') + # If the path is a regexp + unless path.is_a?(Regexp) || path.include?('*') # Normalized path - url = '/' + Middleman::Util.normalize_path(url) - if url.end_with?('/') || File.directory?(File.join(@app.source_dir, url)) - url = File.join(url, @app.config[:index_file]) + path = '/' + Middleman::Util.normalize_path(path) + if path.end_with?('/') || File.directory?(File.join(@app.source_dir, path)) + path = File.join(path, @app.config[:index_file]) end # Setup proxy if target = options.delete(:proxy) # TODO: deprecate proxy through page? - @app.proxy(url, target, opts.dup) + @app.proxy(path, target, opts.dup) return elsif options.delete(:ignore) # TODO: deprecate ignore through page? - @app.ignore(url) + @app.ignore(path) end end - # Setup a metadata matcher for rendering those options - # TODO: How to get rid of this? Perhaps a separate extension that manipulates - # in this sort of data? - # This is harder because sitemap isn't available. - @app.sitemap.provides_metadata_for_path(url) { |_| metadata } + @page_configs << [path, metadata] end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb b/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb deleted file mode 100644 index 10463cab..00000000 --- a/middleman-core/lib/middleman-core/sitemap/extensions/metadata_for_path.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Middleman - module Sitemap - module Extensions - - # Add metadata to Resources based on path matchers. This exists - # entirely to support the "page" method in config.rb. - - # TODO: This requires the concept of priority for sitemap manipulators - # in order for it to always run after all other manipulators. - class MetadataForPath - def initialize(sitemap) - @app = sitemap.app - end - end - end - end -end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 058595f2..60e5bdbb 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -53,7 +53,7 @@ module Middleman end def render(*) - url = ::Middleman::Util.url_for(store.app, @request_path, + url = ::Middleman::Util.url_for(@store.app, @request_path, relative: false, find_resource: true ) @@ -83,10 +83,6 @@ module Middleman false end - def metadata - @local_metadata.dup - end - def get_source_file '' end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index cc980879..18bc996e 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -71,8 +71,8 @@ module Middleman false end - def metadata - @local_metadata.dup + def get_source_file + '' end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 5b039cc6..16ac10f0 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -42,7 +42,7 @@ module Middleman # Locals are local variables for rendering this resource's template # Page are data that is exposed through this resource's data member. # Note: It is named 'page' for backwards compatibility with older MM. - @local_metadata = { options: {}, locals: {}, page: {} } + @metadata = { options: {}, locals: {}, page: {} } end # Whether this resource has a template file @@ -59,15 +59,12 @@ module Middleman # Page are data that is exposed through this resource's data member. # Note: It is named 'page' for backwards compatibility with older MM. def add_metadata(meta={}) - @local_metadata.deep_merge!(meta) + @metadata.deep_merge!(meta) end - # Get the metadata for both the current source_file and the current path + # The metadata for this resource # @return [Hash] - def metadata - # TODO: The only reason we call metadata_for_page is to power the "page" DSL - @store.metadata_for_path(path).deep_merge @local_metadata - end + attr_reader :metadata # Data about this resource, populated from frontmatter or extensions. # @return [HashWithIndifferentAccess] diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 2de8ecf5..c12a1e6f 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -27,11 +27,9 @@ module Middleman def initialize(app) @app = app @resources = [] - @_cached_metadata = {} # TODO: Should this be a set or hash? @resource_list_manipulators = [] @needs_sitemap_rebuild = true - @provides_metadata_for_path = Set.new @lock = Monitor.new reset_lookup_cache! @@ -130,40 +128,6 @@ module Middleman @resources_not_ignored = nil end - # Register a handler to provide metadata on a url path - # Extensions authors should prefer adding metadata to Resources via a - # sitemap manipulator and Resource#add_metadata. - # - # @param [Regexp, String] matcher or glob string - def provides_metadata_for_path(matcher=nil, &block) - if block_given? - @provides_metadata_for_path << [block, matcher] - @_cached_metadata = {} - end - nil - end - - # Get the metadata for a specific source path - # @param [String] path Source path of a resource - # @return [Hash] - def metadata_for_path(path) - return @_cached_metadata[path] if @_cached_metadata.has_key?(path) - - blank_metadata = { options: {}, locals: {}, page: {} } - - @_cached_metadata[path] = @provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)| - case matcher - when Regexp - next result unless path =~ matcher - when String - next result unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{path}") - end - - metadata = callback.call(path) - result.deep_merge(metadata) - end - end - # Get the URL path for an on-disk file # @param [String] file # @return [String] From 096f5ee35657d8e3c683896f0dbe53dbc1aa81db Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 21:50:10 -0700 Subject: [PATCH 070/662] Use source file, not path, to look up frontmatter data --- .../lib/middleman-core/core_extensions/front_matter.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 e37163e8..8b0cbb11 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -32,7 +32,9 @@ module Middleman::CoreExtensions # Modify each resource to add data & options from frontmatter. def manipulate_resource_list(resources) resources.each do |resource| - fmdata = data(resource.path).first + next if resource.source_file.blank? + + fmdata = data(resource.source_file).first.dup # Copy over special options # TODO: Should we make people put these under "options" instead of having @@ -76,6 +78,8 @@ module Middleman::CoreExtensions data = external_data.deep_merge(data) end + + [data, content] end end From 0309753561469817041882ffb578c74e3e388437 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 22:04:32 -0700 Subject: [PATCH 071/662] Change when file listeners are registered in order to make cache invalidation work --- .../middleman-core/sitemap/extensions/on_disk.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index b259c43e..de9569ce 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -15,14 +15,16 @@ module Middleman scoped_self = self @waiting_for_ready = true - # Register file change callback - @app.files.changed do |file| - scoped_self.touch_file(file) - end + @app.before_configuration do + # Register file change callback + files.changed do |file| + scoped_self.touch_file(file) + end - # Register file delete callback - @app.files.deleted do |file| - scoped_self.remove_file(file) + # Register file delete callback + files.deleted do |file| + scoped_self.remove_file(file) + end end @app.ready do From 5760d64ef9e6417efc5b09f453cce7b5833e6076 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 22:22:24 -0700 Subject: [PATCH 072/662] More ignores --- .../lib/middleman-core/core_extensions/front_matter.rb | 3 +++ .../lib/middleman-core/sitemap/extensions/ignores.rb | 9 +++++++-- 2 files changed, 10 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 8b0cbb11..faf0bb12 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -52,6 +52,9 @@ module Middleman::CoreExtensions resource.add_metadata options: opts, page: fmdata # TODO: resource.ignore! if ignored + # TODO: This doesn't really work because resources can't themselves be ignored / when + # an ignore rule is in place it's forever + resource.ignore! if ignored == true && !resource.proxy? # TODO: Save new template here somewhere? end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 5a4f36b1..b12e6c73 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -48,11 +48,16 @@ module Middleman # Helpers methods for Resources module IgnoreResourceInstanceMethods + # Ignore a resource directly, without going through the whole + # ignore filter stuff. + def ignore! + @ignored = true + end + # Whether the Resource is ignored # @return [Boolean] def ignored? - # Check frontmatter/data - return true if !proxy? && data[:ignored] == true + return true if @ignored # Ignore based on the source path (without template extensions) return true if @app.sitemap.ignored?(path) # This allows files to be ignored by their source file name (with template extensions) From b0ea4e7608ecb347a0c3c732583304a502bf5bf1 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 22:32:39 -0700 Subject: [PATCH 073/662] Tweak resource manipulator order --- .../lib/middleman-core/core_extensions/front_matter.rb | 3 +++ middleman-core/lib/middleman-core/core_extensions/routing.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) 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 faf0bb12..42e8ee98 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -10,6 +10,9 @@ require 'active_support/json' # Extensions namespace module Middleman::CoreExtensions class FrontMatter < ::Middleman::Extension + # Try to run after routing but before directory_indexes + self.resource_list_manipulator_priority = 90 + YAML_ERRORS = [StandardError] # https://github.com/tenderlove/psych/issues/23 diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 07150f7e..9769c943 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -4,7 +4,7 @@ module Middleman class Routing < Extension # This should always run late, but not as late as :directory_indexes, # so it can add metadata to any pages generated by other extensions - self.resource_list_manipulator_priority = 90 + self.resource_list_manipulator_priority = 80 def initialize(app, options_hash={}, &block) super From 2beb774eb96070f7ba5960d6ed352796686fa127 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 22:46:15 -0700 Subject: [PATCH 074/662] Put back request_path, I get it now --- middleman-cli/lib/middleman-cli/build.rb | 2 +- .../middleman-core/sitemap/extensions/request_endpoints.rb | 7 ++++--- middleman-core/lib/middleman-core/sitemap/resource.rb | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 80916a02..60538431 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -254,7 +254,7 @@ module Middleman::Cli FileUtils.cp(resource.source_file, output_file) else begin - response = @rack.get(URI.escape(resource.destination_path)) + response = @rack.get(URI.escape(resource.request_path)) if response.status == 200 base.create_file(output_file, binary_encode(response.body)) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 18bc996e..b89ec083 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -49,12 +49,13 @@ module Middleman class EndpointResource < ::Middleman::Sitemap::Resource attr_accessor :output - def initialize(store, path, source_file) - @request_path = ::Middleman::Util.normalize_path(source_file) - + def initialize(store, path, request_path) super(store, path) + @request_path = ::Middleman::Util.normalize_path(request_path) end + attr_reader :request_path + def template? true end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 16ac10f0..62551ad5 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -20,6 +20,11 @@ module Middleman # @return [String] attr_accessor :destination_path + # The path to use when requesting this resource. Normally it's + # the same as {#destination_path} but it can be overridden in subclasses. + # @return [String] + alias_method :request_path, :destination_path + # Set the on-disk source file for this resource # @return [String] def source_file From cb2b13778e1c7253a61b279817b6a0e1bab2f78a Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 23:03:42 -0700 Subject: [PATCH 075/662] Fix i18n --- middleman-core/lib/middleman-core/core_extensions/i18n.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 6b2d46ff..6f4f0012 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -27,9 +27,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def after_configuration - app.files.reload_path(app.config[:locals_dir] || options[:data]) + app.files.reload_path(app.config[:locales_dir] || options[:data]) - @locales_glob = File.join(app.config[:locals_dir] || options[:data], '**', '*.{rb,yml,yaml}') + @locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}') @locales_regex = convert_glob_to_regex(@locales_glob) @maps = {} @@ -81,7 +81,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # This is for backwards compatibility with the old provides_metadata-based code # that used to be in this extension, but I don't know how much sense it makes. - resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } + #resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } end resources + new_resources From 85cebdb7e94ab901ab2db975e98db96aebff3625 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 23:19:33 -0700 Subject: [PATCH 076/662] rubocop --- middleman-core/lib/middleman-core/core_extensions.rb | 1 - .../lib/middleman-core/core_extensions/front_matter.rb | 9 +-------- .../lib/middleman-core/core_extensions/i18n.rb | 4 +++- .../lib/middleman-core/sitemap/extensions/redirects.rb | 1 + .../sitemap/extensions/request_endpoints.rb | 1 + 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 4ff25339..1177eefe 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -50,7 +50,6 @@ Middleman::Extensions.register :routing, auto_activate: :before_configuration do Middleman::CoreExtensions::Routing end - ### # Setup Optional Extensions ### 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 42e8ee98..234e5a01 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -43,9 +43,7 @@ module Middleman::CoreExtensions # TODO: Should we make people put these under "options" instead of having # special known keys? opts = fmdata.extract!(:layout, :layout_engine, :renderer_options, :directory_index, :content_type) - if opts.has_key?(:renderer_options) - opts[:renderer_options].symbolize_keys! - end + opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options) ignored = fmdata.delete(:ignored) @@ -54,9 +52,6 @@ module Middleman::CoreExtensions resource.add_metadata options: opts, page: fmdata - # TODO: resource.ignore! if ignored - # TODO: This doesn't really work because resources can't themselves be ignored / when - # an ignore rule is in place it's forever resource.ignore! if ignored == true && !resource.proxy? # TODO: Save new template here somewhere? @@ -84,8 +79,6 @@ module Middleman::CoreExtensions data = external_data.deep_merge(data) end - - [data, content] end end diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 6f4f0012..c6284226 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -81,7 +81,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # This is for backwards compatibility with the old provides_metadata-based code # that used to be in this extension, but I don't know how much sense it makes. - #resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } + unless resource.options[:lang] + resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } + end end resources + new_resources diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 60e5bdbb..3f4dafd1 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -83,6 +83,7 @@ module Middleman false end + # rubocop:disable AccessorMethodName def get_source_file '' end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index b89ec083..4f5a646e 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -72,6 +72,7 @@ module Middleman false end + # rubocop:disable AccessorMethodName def get_source_file '' end From e6ec5f31de38130e2a2c7676f459c19e3171393e Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 23:32:48 -0700 Subject: [PATCH 077/662] Fix meta pages --- .../lib/middleman-core/meta_pages/sitemap_resource.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 e42176df..27fc03fa 100644 --- a/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb +++ b/middleman-core/lib/middleman-core/meta_pages/sitemap_resource.rb @@ -44,11 +44,10 @@ module Middleman data = @resource.data props['Data'] = data.inspect unless data.empty? - meta = @resource.metadata - options = meta[:options] + options = @resource.options props['Options'] = options.inspect unless options.empty? - locals = meta[:locals].keys + locals = @resource.locals.keys props['Locals'] = locals.join(', ') unless locals.empty? props From 416428444c8d607d69f4c2a41fb1aaf74deb3e9e Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Fri, 30 May 2014 23:32:58 -0700 Subject: [PATCH 078/662] Let users add metadata via #page --- middleman-core/lib/middleman-core/core_extensions/routing.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 9769c943..004fdc2c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -46,6 +46,7 @@ module Middleman # @option opts [Symbol, Boolean, String] layout The layout name to use (e.g. `:article`) or `false` to disable layout. # @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths. # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. + # @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}. # @option opts [String] proxy The source path for a template to proxy this path to. Only valid when a single path is provided. Prefer using the `proxy` method to do this. # @option opts [Boolean] ignore Set to `true` to ignore the provided path(s). Only valid when a single path is provided. Prefer using the `ignore` method to do this. # @return [void] @@ -56,7 +57,7 @@ module Middleman # TODO: This seems wrong options[:layout] = @app.config[:layout] if options[:layout].nil? # TODO: You can set options and locals, but not data - metadata = { options: options, locals: options.delete(:locals) || {} } + metadata = { options: options, locals: options.delete(:locals) || {}, page: options.delete(:data) || {} } # If the path is a regexp unless path.is_a?(Regexp) || path.include?('*') From f07bed4ecfb239148ee788658f5599fcb3180c50 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 14 Jun 2014 12:38:44 -0700 Subject: [PATCH 079/662] Fix custom layouts tests --- .../features/custom_layouts.feature | 34 ++++++++++++++----- .../step_definitions/page_layout_steps.rb | 6 ---- .../core_extensions/extensions.rb | 3 -- 3 files changed, 25 insertions(+), 18 deletions(-) delete mode 100644 middleman-core/features/step_definitions/page_layout_steps.rb diff --git a/middleman-core/features/custom_layouts.feature b/middleman-core/features/custom_layouts.feature index 09c7faa1..27f7df08 100644 --- a/middleman-core/features/custom_layouts.feature +++ b/middleman-core/features/custom_layouts.feature @@ -1,14 +1,22 @@ Feature: Custom layouts In order easily switch between relative and absolute paths - + Scenario: Using custom :layout attribute - Given page "/custom-layout.html" has layout "custom" + Given a fixture app "custom-layout-app2" + And a file named "config.rb" with: + """ + page '/custom-layout.html', layout: :custom + """ And the Server is running at "custom-layout-app2" When I go to "/custom-layout.html" Then I should see "Custom Layout" - + Scenario: Using custom :layout attribute with folders - Given page "/custom-layout-dir/" has layout "custom" + Given a fixture app "custom-layout-app2" + And a file named "config.rb" with: + """ + page '/custom-layout-dir/', layout: :custom + """ And the Server is running at "custom-layout-app2" When I go to "/custom-layout-dir" Then I should see "Custom Layout" @@ -16,9 +24,13 @@ Feature: Custom layouts Then I should see "Custom Layout" When I go to "/custom-layout-dir/index.html" Then I should see "Custom Layout" - + Scenario: Using custom :layout attribute with folders - Given page "/custom-layout-dir" has layout "custom" + Given a fixture app "custom-layout-app2" + And a file named "config.rb" with: + """ + page '/custom-layout-dir', layout: :custom + """ And the Server is running at "custom-layout-app2" When I go to "/custom-layout-dir" Then I should see "Custom Layout" @@ -26,9 +38,13 @@ Feature: Custom layouts Then I should see "Custom Layout" When I go to "/custom-layout-dir/index.html" Then I should see "Custom Layout" - + Scenario: Using custom :layout attribute with folders - Given page "/custom-layout-dir/index.html" has layout "custom" + Given a fixture app "custom-layout-app2" + And a file named "config.rb" with: + """ + page '/custom-layout-dir/index.html', layout: :custom + """ And the Server is running at "custom-layout-app2" When I go to "/custom-layout-dir" Then I should see "Custom Layout" @@ -36,7 +52,7 @@ Feature: Custom layouts Then I should see "Custom Layout" When I go to "/custom-layout-dir/index.html" Then I should see "Custom Layout" - + Scenario: Setting layout inside a matching page block Given the Server is running at "page-helper-layout-block-app" When I go to "/index.html" diff --git a/middleman-core/features/step_definitions/page_layout_steps.rb b/middleman-core/features/step_definitions/page_layout_steps.rb deleted file mode 100644 index 46a27026..00000000 --- a/middleman-core/features/step_definitions/page_layout_steps.rb +++ /dev/null @@ -1,6 +0,0 @@ -Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout| - @initialize_commands ||= [] - @initialize_commands << lambda { - page(url, layout: layout.to_sym) - } -end diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 2cfb6c41..dbe8715b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -83,9 +83,6 @@ module Middleman # Search the root of the project for required files $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) - # Evaluate a passed block if given - config_context.instance_exec(&block) if block_given? - super ::Middleman::Extension.clear_after_extension_callbacks From f63feaf017173eaffbf34d63a44845ce8614e78d Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 14 Jun 2014 13:05:32 -0700 Subject: [PATCH 080/662] Do not use ShowExceptions during tests, it confuses things --- .../lib/middleman-core/core_extensions/show_exceptions.rb | 6 ++++-- .../lib/middleman-core/step_definitions/server_steps.rb | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index 3f039ca6..a28e6a7f 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -1,14 +1,16 @@ +require 'rack/showexceptions' + # Support rack/showexceptions during development module Middleman::CoreExtensions class ShowExceptions < ::Middleman::Extension def initialize(app, options_hash={}, &block) super - require 'rack/showexceptions' + app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions' end def after_configuration - app.use ::Rack::ShowExceptions + app.use ::Rack::ShowExceptions if app.config[:show_exceptions] end end end 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 4ea87dc8..94905abe 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -41,12 +41,11 @@ Given /^the Server is running$/ do ENV['MM_ROOT'] = root_dir initialize_commands = @initialize_commands || [] + initialize_commands.unshift lambda { config[:show_exceptions] = false } @server_inst = Middleman::Application.server.inst do - app.initialized do - initialize_commands.each do |p| - config_context.instance_exec(&p) - end + initialize_commands.each do |p| + instance_exec(&p) end end From 2ef842a730628b4f3dab9e77a4c1ef381ec7b78f Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 14 Jun 2014 13:08:03 -0700 Subject: [PATCH 081/662] Fix references to store in traversal --- .../lib/middleman-core/sitemap/extensions/traversal.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index 140d8f74..fe0dfb55 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -13,7 +13,7 @@ module Middleman test_expr = parts.join('\\/') # eponymous reverse-lookup - found = store.resources.find do |candidate| + found = @store.resources.find do |candidate| candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$! end @@ -21,7 +21,7 @@ module Middleman found else parts.pop if is_index - store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}") + @store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}") end end From c6543b7c27226f1298858677fd2776fcf6896937 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 16 Jun 2014 08:57:56 -0700 Subject: [PATCH 082/662] Add to 404 so Livereload can add its script to the page --- middleman-core/lib/middleman-core/core_extensions/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index bd182fd6..b4c59f1a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -238,7 +238,7 @@ module Middleman # Halt request and return 404 def not_found(res, path) res.status = 404 - res.write "

File Not Found

#{path}

" + res.write "

File Not Found

#{path}

" res.finish end From fe5247d9d9482858f6753531ad1e135afe6366b5 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 16 Jun 2014 08:57:56 -0700 Subject: [PATCH 083/662] Add to 404 so Livereload can add its script to the page --- middleman-core/lib/middleman-core/core_extensions/request.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index e78f0ffe..aabb708e 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -281,7 +281,7 @@ module Middleman # Halt request and return 404 def not_found(res, path) res.status = 404 - res.write "

File Not Found

#{path}

" + res.write "

File Not Found

#{path}

" res.finish end From 8989e27769c94a20647bec2e2959c040b5c8ce47 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 16 Jun 2014 09:05:24 -0700 Subject: [PATCH 084/662] Rubocop auto fix --- .../core_extensions/default_helpers.rb | 2 +- .../middleman-core/extensions/asset_hash.rb | 20 ++++++++-------- .../middleman-core/extensions/asset_host.rb | 14 +++++------ .../middleman-core/extensions/cache_buster.rb | 14 +++++------ .../extensions/relative_assets.rb | 12 +++++----- .../middleware/inline_url_rewriter.rb | 4 ++-- .../renderers/sass_functions.rb | 23 +++++++++---------- .../lib/middleman-core/renderers/slim.rb | 2 +- .../sitemap/extensions/traversal.rb | 2 +- middleman-core/lib/middleman-core/util.rb | 4 ++-- 10 files changed, 48 insertions(+), 49 deletions(-) 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 0388f7f7..99120528 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -170,7 +170,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # @param [String] path The path (such as "photo.jpg") # @param [String] prefix The type prefix (such as "images") # @return [String] The fully qualified asset url - def asset_url(path, prefix='', options={}) + def asset_url(_path, prefix='', options={}) ::Middleman::Util.asset_url(app, prefix, options) end diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index ab8f4fac..1fd9426d 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -18,15 +18,15 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension @ignore = Array(options.ignore) + [/^apple-touch-icon/] app.use ::Middleman::Middleware::InlineURLRewriter, - :id => :asset_hash, - :url_extensions => options.exts, - :source_extensions => %w(.htm .html .php .css .js), - :ignore => @ignore, - :middleman_app => app, - :proc => method(:rewrite_url) + id: :asset_hash, + url_extensions: options.exts, + source_extensions: %w(.htm .html .php .css .js), + ignore: @ignore, + middleman_app: app, + proc: method(:rewrite_url) end - def rewrite_url(asset_path, dirpath, request_path) + def rewrite_url(asset_path, dirpath, _request_path) relative_path = Pathname.new(asset_path).relative? full_asset_path = if relative_path @@ -68,9 +68,9 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension return if resource.ignored? # Render through the Rack interface so middleware and mounted apps get a shot - response = @rack_client.get(URI.escape(resource.destination_path), { - 'bypass_inline_url_rewriter_asset_hash' => 'true' - }) + response = @rack_client.get(URI.escape(resource.destination_path), + 'bypass_inline_url_rewriter_asset_hash' => 'true' + ) raise "#{resource.path} should be in the sitemap!" unless response.status == 200 diff --git a/middleman-core/lib/middleman-core/extensions/asset_host.rb b/middleman-core/lib/middleman-core/extensions/asset_host.rb index 9a872b5d..ff687895 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_host.rb @@ -8,15 +8,15 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension def after_configuration app.use ::Middleman::Middleware::InlineURLRewriter, - :id => :asset_host, - :url_extensions => options.exts, - :source_extensions => options.sources, - :ignore => options.ignore, - :middleman_app => app, - :proc => method(:rewrite_url) + id: :asset_host, + url_extensions: options.exts, + source_extensions: options.sources, + ignore: options.ignore, + middleman_app: app, + proc: method(:rewrite_url) end - def rewrite_url(asset_path, dirpath, request_path) + def rewrite_url(asset_path, dirpath, _request_path) relative_path = Pathname.new(asset_path).relative? full_asset_path = if relative_path diff --git a/middleman-core/lib/middleman-core/extensions/cache_buster.rb b/middleman-core/lib/middleman-core/extensions/cache_buster.rb index b6ffd1d9..f1d22610 100644 --- a/middleman-core/lib/middleman-core/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-core/extensions/cache_buster.rb @@ -12,15 +12,15 @@ class Middleman::Extensions::CacheBuster < ::Middleman::Extension def after_configuration app.use ::Middleman::Middleware::InlineURLRewriter, - :id => :cache_buster, - :url_extensions => options.exts, - :source_extensions => options.sources, - :ignore => options.ignore, - :middleman_app => app, - :proc => method(:rewrite_url) + id: :cache_buster, + url_extensions: options.exts, + source_extensions: options.sources, + ignore: options.ignore, + middleman_app: app, + proc: method(:rewrite_url) end - def rewrite_url(asset_path, dirpath, request_path) + def rewrite_url(asset_path, _dirpath, _request_path) asset_path + '?' + Time.now.strftime('%s') end end diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index 474f914a..f8666924 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -12,12 +12,12 @@ class Middleman::Extensions::RelativeAssets < ::Middleman::Extension def after_configuration app.use ::Middleman::Middleware::InlineURLRewriter, - :id => :asset_hash, - :url_extensions => options.exts, - :source_extensions => options.sources, - :ignore => options.ignore, - :middleman_app => app, - :proc => method(:rewrite_url) + id: :asset_hash, + url_extensions: options.exts, + source_extensions: options.sources, + ignore: options.ignore, + middleman_app: app, + proc: method(:rewrite_url) end def rewrite_url(asset_path, dirpath, request_path) diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index d0fbc115..88142b4a 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -12,7 +12,7 @@ module Middleman @uid = options[:id] @proc = options[:proc] - raise "InlineURLRewriter requires a :proc to call with inline URL results" unless @proc + raise 'InlineURLRewriter requires a :proc to call with inline URL results' unless @proc @exts = options[:url_extensions] @@ -35,7 +35,7 @@ module Middleman end path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app) - + if path =~ /(^\/$)|(#{@source_exts_regex_text}$)/ if body = ::Middleman::Util.extract_response_text(response) dirpath = Pathname.new(File.dirname(path)) diff --git a/middleman-core/lib/middleman-core/renderers/sass_functions.rb b/middleman-core/lib/middleman-core/renderers/sass_functions.rb index e7d955ac..90583aee 100644 --- a/middleman-core/lib/middleman-core/renderers/sass_functions.rb +++ b/middleman-core/lib/middleman-core/renderers/sass_functions.rb @@ -1,7 +1,6 @@ module Sprockets module Sass module Functions - # Using Middleman::Util#asset_path, return the full path # for the given +source+ as a Sass String. This supports keyword # arguments that mirror the +options+. @@ -11,7 +10,7 @@ module Sprockets # background: url(image-path("image.jpg")); // background: url("/assets/image.jpg"); # background: url(image-path("image.jpg", $digest: true)); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); # - def image_path(source, options = {}) + def image_path(source, options={}) p = ::Middleman::Util.asset_path(middleman_context, :images, source.value, map_options(options)) ::Sass::Script::String.new p.to_s, :string end @@ -25,7 +24,7 @@ module Sprockets # background: image-url("image.jpg"); // background: url("/assets/image.jpg"); # background: image-url("image.jpg", $digest: true); // background: url("/assets/image-27a8f1f96afd8d4c67a59eb9447f45bd.jpg"); # - def image_url(source, options = {}, cache_buster = nil) + def image_url(source, options={}, _cache_buster=nil) # Work with the Compass #image_url API if options.respond_to? :value case options.value @@ -47,7 +46,7 @@ module Sprockets # src: url(font-path("font.ttf")); // src: url("/assets/font.ttf"); # src: url(font-path("font.ttf", $digest: true)); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); # - def font_path(source, options = {}) + def font_path(source, options={}) p = ::Middleman::Util.asset_path(middleman_context, :fonts, source.value, map_options(options)) ::Sass::Script::String.new p.to_s, :string end @@ -61,7 +60,7 @@ module Sprockets # src: font-url("font.ttf"); // src: url("/assets/font.ttf"); # src: font-url("image.jpg", $digest: true); // src: url("/assets/font-27a8f1f96afd8d4c67a59eb9447f45bd.ttf"); # - def font_url(source, options = {}) + def font_url(source, options={}) # Work with the Compass #font_url API if options.respond_to? :value case options.value @@ -84,7 +83,7 @@ module Sprockets # Returns an options hash where the keys are symbolized # and the values are unwrapped Sass literals. - def map_options(options = {}) # :nodoc: + def map_options(options={}) # :nodoc: ::Sass::Util.map_hash(options) do |key, value| [key.to_sym, value.respond_to?(:value) ? value.value : value] end @@ -102,16 +101,16 @@ module Sass::Script::Functions defined?(@signatures) && @signatures.delete(method) end - declare :asset_path, [:source], :var_kwargs => true + declare :asset_path, [:source], var_kwargs: true declare :asset_path, [:source, :kind] - declare :asset_url, [:source], :var_kwargs => true + declare :asset_url, [:source], var_kwargs: true declare :asset_url, [:source, :kind] - declare :image_path, [:source], :var_kwargs => true - declare :image_url, [:source], :var_kwargs => true + declare :image_path, [:source], var_kwargs: true + declare :image_url, [:source], var_kwargs: true declare :image_url, [:source, :only_path] declare :image_url, [:source, :only_path, :cache_buster] - declare :font_path, [:source], :var_kwargs => true - declare :font_url, [:source], :var_kwargs => true + declare :font_path, [:source], var_kwargs: true + declare :font_url, [:source], var_kwargs: true declare :font_url, [:source, :only_path] declare :asset_data_uri, [:source] end diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index 46ecaa08..d3ec7541 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -33,7 +33,7 @@ module Middleman app.after_configuration do context_hack = { - context: self.template_context_class.new(self) + context: template_context_class.new(self) } ::Slim::Embedded::SassEngine.disable_option_validator! diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index fe0dfb55..3b409765 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -14,7 +14,7 @@ module Middleman test_expr = parts.join('\\/') # eponymous reverse-lookup found = @store.resources.find do |candidate| - candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$! + candidate.path =~ %r{^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$} end if found diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 80800ac2..6e65e818 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -166,7 +166,7 @@ module Middleman # @param [String] prefix The type prefix (such as "images") # @param [Hash] options Data to pass through. # @return [String] The fully qualified asset url - def asset_url(app, path, prefix='', options={}) + def asset_url(app, path, prefix='', _options={}) # Don't touch assets which already have a full path if path.include?('//') or path.start_with?('data:') path @@ -271,7 +271,7 @@ module Middleman end end - def rewrite_paths(body, path, exts, &block) + def rewrite_paths(body, _path, exts, &_block) body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| opening_character = $1 asset_path = $2 From ad4b441dc3bedde909ea072ae5f55300bb63bd4b Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 16 Jun 2014 21:43:14 -0700 Subject: [PATCH 085/662] Fixed implementation of Middleman::Util#path_match, added tests for it --- middleman-core/lib/middleman-core/util.rb | 12 ++++-- .../spec/middleman-core/path_match_spec.rb | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 middleman-core/spec/middleman-core/path_match_spec.rb diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 6e65e818..912c7ae3 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -96,13 +96,17 @@ module Middleman # to #match or #call, and returns whether or not the # given path matches that matcher. # - # @param matcher A matcher string/regexp/proc/etc - # @param path A path as a string + # @param [String, #match, #call] matcher A matcher String, RegExp, Proc, etc. + # @param [String] path A path as a string # @return [Boolean] Whether the path matches the matcher def path_match(matcher, path) - case + !!case when matcher.is_a?(String) - path.match(matcher) + if matcher.include? '*' + File.fnmatch(matcher, path) + else + path == matcher + end when matcher.respond_to?(:match) matcher.match(path) when matcher.respond_to?(:call) diff --git a/middleman-core/spec/middleman-core/path_match_spec.rb b/middleman-core/spec/middleman-core/path_match_spec.rb new file mode 100644 index 00000000..6bba18e9 --- /dev/null +++ b/middleman-core/spec/middleman-core/path_match_spec.rb @@ -0,0 +1,37 @@ +require 'middleman-core/util' + +describe "Middleman::Util#path_match" do + it "matches a literal string" do + expect(Middleman::Util.path_match '/index.html', '/index.html').to be true + end + + it "won't match a wrong string" do + expect(Middleman::Util.path_match '/foo.html', '/index.html').to be false + end + + it "won't match a partial string" do + expect(Middleman::Util.path_match 'ind', '/index.html').to be false + end + + it "works with a regex" do + expect(Middleman::Util.path_match /\.html$/, '/index.html').to be true + expect(Middleman::Util.path_match /\.js$/, '/index.html').to be false + end + + it "works with a proc" do + matcher = lambda {|p| p.length > 5 } + + expect(Middleman::Util.path_match matcher, '/index.html').to be true + expect(Middleman::Util.path_match matcher, '/i').to be false + end + + it "works with globs" do + expect(Middleman::Util.path_match '/foo/*.html', '/foo/index.html').to be true + expect(Middleman::Util.path_match '/foo/*.html', '/foo/index.js').to be false + expect(Middleman::Util.path_match '/bar/*.html', '/foo/index.js').to be false + + expect(Middleman::Util.path_match '/foo/*', '/foo/bar/index.html').to be true + expect(Middleman::Util.path_match '/foo/**/*', '/foo/bar/index.html').to be true + expect(Middleman::Util.path_match '/foo/**', '/foo/bar/index.html').to be true + end +end From 434d55b1ae0165a58c9c2955011b23132dea4b89 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 20 Jun 2014 14:09:51 -0700 Subject: [PATCH 086/662] See if code climate hooks work --- .travis.yml | 2 +- Gemfile | 1 + middleman-core/features/support/env.rb | 3 +++ middleman-core/spec/spec_helper.rb | 3 +++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e360e9a5..f8af4876 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ matrix: - rvm: jruby - rvm: jruby-19mode - rvm: rbx-2 -env: TEST=true +env: TEST=true CODECLIMATE_REPO_TOKEN=81787f7b1c3bfa937edadcafbc94f807bf5af5c1142c7b793f2d9969a271de1f before_install: git submodule update --init --recursive script: bundle exec rake test notifications: diff --git a/Gemfile b/Gemfile index c1d05994..72609e69 100644 --- a/Gemfile +++ b/Gemfile @@ -31,6 +31,7 @@ platforms :jruby do end # Code Quality +gem 'codeclimate-test-reporter', group: :test, require: nil gem 'coveralls', require: false gem 'rubocop', require: false diff --git a/middleman-core/features/support/env.rb b/middleman-core/features/support/env.rb index 08e3442a..61891d8b 100644 --- a/middleman-core/features/support/env.rb +++ b/middleman-core/features/support/env.rb @@ -7,6 +7,9 @@ SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/../..')) require 'coveralls' Coveralls.wear! +require 'codeclimate-test-reporter' +CodeClimate::TestReporter.start + PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core') require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core', 'step_definitions') diff --git a/middleman-core/spec/spec_helper.rb b/middleman-core/spec/spec_helper.rb index a9d71768..fefcf9a6 100644 --- a/middleman-core/spec/spec_helper.rb +++ b/middleman-core/spec/spec_helper.rb @@ -3,3 +3,6 @@ SimpleCov.root(File.expand_path(File.dirname(__FILE__) + '/..')) require 'coveralls' Coveralls.wear! + +require 'codeclimate-test-reporter' +CodeClimate::TestReporter.start \ No newline at end of file From c4dac7803f69e5ebdf2f4c090c9f5aadf96fc5f3 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 14 Jun 2014 17:29:12 -0700 Subject: [PATCH 087/662] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index df41d316..c36dc6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* The `page` command in `config.rb` can now be used to add data to the page via the `data` argument. It is accessed the same way as frontmatter data, via `current_resource.data`. * Add support for `environments` with the `-e` CLI flag. Loads additional config from `environments/envname.rb`. Removed `development?` helper in favor of `environment?(:development)`. Added `server?` helper to differentiate between build and server mode. * Removed `with_layout`. Use loops of `page` instead. * Removed Queryable Sitemap API From 5c991ba4dc8d2af9cf373b90df2eb1ecc92f2993 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 22 Jun 2014 20:46:39 -0700 Subject: [PATCH 088/662] Add a protective require --- middleman-core/lib/middleman-core/extension.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 887a05fb..48653bef 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' +require 'middleman-core/configuration' module Middleman class Extension From 13ba9dae62f46b850cbd8565b85c9d197a4f020a Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Tue, 24 Jun 2014 13:34:24 -0700 Subject: [PATCH 089/662] Make option documentation consistent. --- middleman-core/lib/middleman-more/extensions/asset_hash.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-more/extensions/asset_hash.rb b/middleman-core/lib/middleman-more/extensions/asset_hash.rb index b087cff2..3f915033 100644 --- a/middleman-core/lib/middleman-more/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-more/extensions/asset_hash.rb @@ -2,7 +2,7 @@ require 'middleman-core/util' class Middleman::Extensions::AssetHash < ::Middleman::Extension option :exts, %w(.jpg .jpeg .png .gif .js .css .otf .woff .eot .ttf .svg), 'List of extensions that get asset hashes appended to them.' - option :ignore, [], 'Regexes of filenames to skip adding asset hashes to' + option :ignore, [], 'Patterns to avoid adding asset hashes to' def initialize(app, options_hash={}, &block) super From b819d383588dd45d02874b279ed50f1372ccedda Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Fri, 2 May 2014 10:19:18 -0700 Subject: [PATCH 090/662] Test gzip extensions option. --- middleman-core/features/gzip.feature | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/middleman-core/features/gzip.feature b/middleman-core/features/gzip.feature index 93ae2cf5..9240b05b 100644 --- a/middleman-core/features/gzip.feature +++ b/middleman-core/features/gzip.feature @@ -3,12 +3,12 @@ Feature: GZIP assets during build Scenario: Built assets should be gzipped Given a successfully built app at "gzip-app" Then the following files should exist: - | build/javascripts/test.js.gz | - | build/stylesheets/test.css.gz | + | build/index.html | | build/index.html.gz | | build/javascripts/test.js | + | build/javascripts/test.js.gz | | build/stylesheets/test.css | - | build/index.html | + | build/stylesheets/test.css.gz | When I run `file build/javascripts/test.js.gz` Then the output should contain "gzip" @@ -18,4 +18,19 @@ Feature: GZIP assets during build Then I should see "test_function" When I go to "/stylesheets/test.css" Then I should see "test_selector" - \ No newline at end of file + + Scenario: Only specified extensions should be gzipped + Given a fixture app "gzip-app" + And a file named "config.rb" with: + """ + activate :gzip, exts: %w(.js .html .htm) + """ + And a successfully built app at "gzip-app" + Then the following files should exist: + | build/index.html | + | build/index.html.gz | + | build/javascripts/test.js | + | build/javascripts/test.js.gz | + | build/stylesheets/test.css | + And the following files should not exist: + | build/stylesheets/test.css.gz | From 429e7d64bd306c5139748ad578c47616bc4dfef2 Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Fri, 2 May 2014 11:41:59 -0700 Subject: [PATCH 091/662] Accept list of paths to exclude from gzipping. --- middleman-core/features/gzip.feature | 16 ++++++++++++++++ .../lib/middleman-more/extensions/gzip.rb | 12 +++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/middleman-core/features/gzip.feature b/middleman-core/features/gzip.feature index 9240b05b..5a5a4265 100644 --- a/middleman-core/features/gzip.feature +++ b/middleman-core/features/gzip.feature @@ -34,3 +34,19 @@ Feature: GZIP assets during build | build/stylesheets/test.css | And the following files should not exist: | build/stylesheets/test.css.gz | + + Scenario: Gzipped files are not produced for ignored paths + Given a fixture app "gzip-app" + And a file named "config.rb" with: + """ + activate :gzip, ignore: ['index.html', %r(javascripts/.*)] + """ + And a successfully built app at "gzip-app" + Then the following files should exist: + | build/index.html | + | build/javascripts/test.js | + | build/stylesheets/test.css | + | build/stylesheets/test.css.gz | + And the following files should not exist: + | build/index.html.gz | + | build/javascripts/test.js.gz | diff --git a/middleman-core/lib/middleman-more/extensions/gzip.rb b/middleman-core/lib/middleman-more/extensions/gzip.rb index 21b40f06..ed875d19 100644 --- a/middleman-core/lib/middleman-more/extensions/gzip.rb +++ b/middleman-core/lib/middleman-more/extensions/gzip.rb @@ -11,6 +11,7 @@ # class Middleman::Extensions::Gzip < ::Middleman::Extension option :exts, %w(.js .css .html .htm), 'File extensions to Gzip when building.' + option :ignore, [], 'Patterns to avoid gzipping' def initialize(app, options_hash={}) super @@ -29,7 +30,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension # Fill a queue with inputs in_queue = Queue.new paths.each do |path| - in_queue << path if options.exts.include?(path.extname) + in_queue << path if should_gzip?(path) end num_paths = in_queue.size @@ -93,4 +94,13 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension [output_filename, old_size, new_size] end + + private + + # Whether a path should be gzipped + # @param [Pathname] path A destination path + # @return [Boolean] + def should_gzip?(path) + options.exts.include?(path.extname) && options.ignore.none? { |ignore| Middleman::Util.path_match(ignore, path.to_s) } + end end From 838e25085abd07de3f1b04df1c3b6536facebfa9 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 28 Jun 2014 21:00:59 -0700 Subject: [PATCH 092/662] Munge build path so that path_match works against it in gzip extension --- middleman-core/lib/middleman-core/extensions/gzip.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/middleman-core/lib/middleman-core/extensions/gzip.rb b/middleman-core/lib/middleman-core/extensions/gzip.rb index 915b40b3..bb009ece 100644 --- a/middleman-core/lib/middleman-core/extensions/gzip.rb +++ b/middleman-core/lib/middleman-core/extensions/gzip.rb @@ -105,6 +105,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension # @param [Pathname] path A destination path # @return [Boolean] def should_gzip?(path) + path = path.sub app.config[:build_dir] + '/', '' options.exts.include?(path.extname) && options.ignore.none? { |ignore| Middleman::Util.path_match(ignore, path.to_s) } end end From dfecfebc692857a1e72e6f80f9f325fee5b9be22 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 16 Jun 2014 21:44:14 -0700 Subject: [PATCH 093/662] Remove options to proxy or ignore through `page`, and use Middleman::Util#path_match for matchers to allow a wider set of matchers. --- .../clean-app/config-complications.rb | 10 ++--- middleman-core/fixtures/clean-app/config.rb | 11 ------ middleman-core/fixtures/data-app/config.rb | 2 +- .../fixtures/dynamic-pages-app/config.rb | 30 +++++++-------- .../frontmatter-settings-app/config.rb | 2 +- .../config.rb | 2 +- .../more-frontmatter-settings-app/config.rb | 2 +- .../fixtures/more-traversal-app/config.rb | 8 ++-- .../fixtures/traversal-app/config.rb | 8 ++-- .../middleman-core/core_extensions/routing.rb | 37 ++++++------------- .../sitemap/extensions/proxies.rb | 21 +++++++---- 11 files changed, 56 insertions(+), 77 deletions(-) diff --git a/middleman-core/fixtures/clean-app/config-complications.rb b/middleman-core/fixtures/clean-app/config-complications.rb index a958bf5a..1326120c 100644 --- a/middleman-core/fixtures/clean-app/config-complications.rb +++ b/middleman-core/fixtures/clean-app/config-complications.rb @@ -1,11 +1,9 @@ -page "/fake.html", proxy: "/real.html", layout: false +proxy "/fake.html", "/real.html", layout: false ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", ignore: true -page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true +ignore "/should_be_ignored2.html" +proxy "/target_ignore.html", "/should_be_ignored3.html", ignore: true %w(one two).each do |num| - page "/fake/#{num}.html", proxy: "/real/index.html" do - @num = num - end + proxy "/fake/#{num}.html", "/real/index.html", locals: { num: num } end diff --git a/middleman-core/fixtures/clean-app/config.rb b/middleman-core/fixtures/clean-app/config.rb index a958bf5a..e69de29b 100644 --- a/middleman-core/fixtures/clean-app/config.rb +++ b/middleman-core/fixtures/clean-app/config.rb @@ -1,11 +0,0 @@ -page "/fake.html", proxy: "/real.html", layout: false - -ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", ignore: true -page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true - -%w(one two).each do |num| - page "/fake/#{num}.html", proxy: "/real/index.html" do - @num = num - end -end diff --git a/middleman-core/fixtures/data-app/config.rb b/middleman-core/fixtures/data-app/config.rb index 1d0d0ba7..2aa77658 100644 --- a/middleman-core/fixtures/data-app/config.rb +++ b/middleman-core/fixtures/data-app/config.rb @@ -1,3 +1,3 @@ data.pages.each do |p| - page p.from, proxy: p.to + proxy p.from, p.to end diff --git a/middleman-core/fixtures/dynamic-pages-app/config.rb b/middleman-core/fixtures/dynamic-pages-app/config.rb index db5990d8..75fab5e0 100644 --- a/middleman-core/fixtures/dynamic-pages-app/config.rb +++ b/middleman-core/fixtures/dynamic-pages-app/config.rb @@ -1,27 +1,27 @@ # -*- coding: utf-8 -*- -page "/fake.html", proxy: "/real.html", layout: false -page "fake2.html", proxy: "/real.html", layout: false -page "fake3.html", proxy: "real.html", layout: false -page "/fake4.html", proxy: "real.html", layout: false +proxy "/fake.html", "/real.html", layout: false +proxy "fake2.html", "/real.html", layout: false +proxy "fake3.html", "real.html", layout: false +proxy "/fake4.html", "real.html", layout: false ignore "/should_be_ignored.html" -page "/should_be_ignored2.html", ignore: true -page "/target_ignore.html", proxy: "/should_be_ignored3.html", ignore: true +ignore "/should_be_ignored2.html" +proxy "/target_ignore.html", "/should_be_ignored3.html", ignore: true ignore "should_be_ignored4.html" -page "should_be_ignored5.html", ignore: true -page "target_ignore2.html", proxy: "/should_be_ignored6.html", ignore: true -page "target_ignore3.html", proxy: "should_be_ignored7.html", ignore: true -page "/target_ignore4.html", proxy: "should_be_ignored8.html", ignore: true +ignore "should_be_ignored5.html" +proxy "target_ignore2.html", "/should_be_ignored6.html", ignore: true +proxy "target_ignore3.html", "should_be_ignored7.html", ignore: true +proxy "/target_ignore4.html", "should_be_ignored8.html", ignore: true %w(one two).each do |num| - page "/fake/#{num}.html", proxy: "/real/index.html", ignore: true, locals: { num: num } - page "fake2/#{num}.html", proxy: "/real/index.html", ignore: true, locals: { num: num } - page "fake3/#{num}.html", proxy: "real/index.html", ignore: true, locals: { num: num } - page "/fake4/#{num}.html", proxy: "real/index.html", ignore: true, locals: { num: num } + proxy "/fake/#{num}.html", "/real/index.html", ignore: true, locals: { num: num } + proxy "fake2/#{num}.html", "/real/index.html", ignore: true, locals: { num: num } + proxy "fake3/#{num}.html", "real/index.html", ignore: true, locals: { num: num } + proxy "/fake4/#{num}.html", "real/index.html", ignore: true, locals: { num: num } end -page "明日がある.html", proxy: "/real.html", layout: false +proxy "明日がある.html", "/real.html", layout: false page "f*/*", locals: { all_glob: "I am all glob" } page "fake/*", locals: { glob_var: "I am one glob" } diff --git a/middleman-core/fixtures/frontmatter-settings-app/config.rb b/middleman-core/fixtures/frontmatter-settings-app/config.rb index 7e6a7bf9..a5e8129a 100644 --- a/middleman-core/fixtures/frontmatter-settings-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-app/config.rb @@ -1,4 +1,4 @@ # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', proxy: 'ignored.html' +proxy 'proxied.html', 'ignored.html' page 'override_layout.html', layout: :alternate page 'page_mentioned.html' diff --git a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb index 7e6a7bf9..a5e8129a 100644 --- a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb @@ -1,4 +1,4 @@ # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', proxy: 'ignored.html' +proxy 'proxied.html', 'ignored.html' page 'override_layout.html', layout: :alternate page 'page_mentioned.html' diff --git a/middleman-core/fixtures/more-frontmatter-settings-app/config.rb b/middleman-core/fixtures/more-frontmatter-settings-app/config.rb index f0a890d2..c5c9fb86 100644 --- a/middleman-core/fixtures/more-frontmatter-settings-app/config.rb +++ b/middleman-core/fixtures/more-frontmatter-settings-app/config.rb @@ -1,4 +1,4 @@ activate :directory_indexes # Proxy ignored.html, which should ignore itself through a frontmatter -page 'proxied.html', proxy: 'ignored.html' +proxy 'proxied.html', 'ignored.html' diff --git a/middleman-core/fixtures/more-traversal-app/config.rb b/middleman-core/fixtures/more-traversal-app/config.rb index 051a262d..e484ea5d 100644 --- a/middleman-core/fixtures/more-traversal-app/config.rb +++ b/middleman-core/fixtures/more-traversal-app/config.rb @@ -1,7 +1,7 @@ activate :directory_indexes -page "/sub/fake.html", proxy: "/proxied.html", ignore: true -page "/sub/fake2.html", proxy: "/proxied.html", ignore: true +proxy "/sub/fake.html", "/proxied.html", ignore: true +proxy "/sub/fake2.html", "/proxied.html", ignore: true -page "/directory-indexed/fake.html", proxy: "/proxied.html", ignore: true -page "/directory-indexed/fake2.html", proxy: "/proxied.html", ignore: true +proxy "/directory-indexed/fake.html", "/proxied.html", ignore: true +proxy "/directory-indexed/fake2.html", "/proxied.html", ignore: true diff --git a/middleman-core/fixtures/traversal-app/config.rb b/middleman-core/fixtures/traversal-app/config.rb index 5d030e02..4ad23bcc 100644 --- a/middleman-core/fixtures/traversal-app/config.rb +++ b/middleman-core/fixtures/traversal-app/config.rb @@ -1,5 +1,5 @@ -page "/sub/fake.html", proxy: "/proxied.html", ignore: true -page "/sub/fake2.html", proxy: "/proxied.html", ignore: true +proxy "/sub/fake.html", "/proxied.html", ignore: true +proxy "/sub/fake2.html", "/proxied.html", ignore: true -page "/directory-indexed/fake.html", proxy: "/proxied.html", ignore: true -page "/directory-indexed/fake2.html", proxy: "/proxied.html", ignore: true +proxy "/directory-indexed/fake.html", "/proxied.html", ignore: true +proxy "/directory-indexed/fake2.html", "/proxied.html", ignore: true diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 004fdc2c..da0cead6 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -19,14 +19,7 @@ module Middleman def manipulate_resource_list(resources) resources.each do |resource| @page_configs.each do |matcher, metadata| - case matcher - when Regexp - next unless resource.path =~ matcher - when String - next unless File.fnmatch('/' + Util.strip_leading_slash(matcher), "/#{resource.path}") - end - - resource.add_metadata metadata + resource.add_metadata(metadata) if Middleman::Util.path_match(matcher, "/#{resource.path}") end end end @@ -47,8 +40,6 @@ module Middleman # @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths. # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. # @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}. - # @option opts [String] proxy The source path for a template to proxy this path to. Only valid when a single path is provided. Prefer using the `proxy` method to do this. - # @option opts [Boolean] ignore Set to `true` to ignore the provided path(s). Only valid when a single path is provided. Prefer using the `ignore` method to do this. # @return [void] def page(path, opts={}) options = opts.dup @@ -56,26 +47,22 @@ module Middleman # Default layout # TODO: This seems wrong options[:layout] = @app.config[:layout] if options[:layout].nil? - # TODO: You can set options and locals, but not data - metadata = { options: options, locals: options.delete(:locals) || {}, page: options.delete(:data) || {} } + metadata = { + options: options, + locals: options.delete(:locals) || {}, + page: options.delete(:data) || {} + } - # If the path is a regexp - unless path.is_a?(Regexp) || path.include?('*') - # Normalized path - path = '/' + Middleman::Util.normalize_path(path) + if path.is_a?(String) && !path.include?('*') + # Normalize path + path = Middleman::Util.normalize_path(path) if path.end_with?('/') || File.directory?(File.join(@app.source_dir, path)) path = File.join(path, @app.config[:index_file]) end + end - # Setup proxy - if target = options.delete(:proxy) - # TODO: deprecate proxy through page? - @app.proxy(path, target, opts.dup) - return - elsif options.delete(:ignore) - # TODO: deprecate ignore through page? - @app.ignore(path) - end + if path.is_a?(String) + path = '/' + Util.strip_leading_slash(path) end @page_configs << [path, metadata] diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 37f76894..acba2eb7 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -15,19 +15,24 @@ module Middleman end # Setup a proxy from a path to a target - # @param [String] path - # @param [String] target - # @param [Hash] opts options to apply to the proxy, including things like - # :locals, :ignore to hide the proxy target, :layout, and :directory_indexes. + # @param [String] path The new, proxied path to create + # @param [String] target The existing path that should be proxied to. This must be a real resource, not another proxy. + # @option opts [Boolean] ignore Ignore the target from the sitemap (so only the new, proxy resource ends up in the output) + # @option opts [Symbol, Boolean, String] layout The layout name to use (e.g. `:article`) or `false` to disable layout. + # @option opts [Boolean] directory_indexes Whether or not the `:directory_indexes` extension applies to these paths. + # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. + # @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}. # @return [void] def create_proxy(path, target, opts={}) options = opts.dup - metadata = { options: {}, locals: {} } - metadata[:locals] = options.delete(:locals) || {} - @app.ignore(target) if options.delete(:ignore) - metadata[:options] = options + + metadata = { + options: options, + locals: options.delete(:locals) || {}, + page: options.delete(:data) || {} + } @proxy_configs << ProxyConfiguration.new(path: path, target: target, metadata: metadata) From f6dd2f6e529458749cd48753014b12e8ed7af8fe Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sat, 28 Jun 2014 21:33:28 -0700 Subject: [PATCH 094/662] Update CHANGELOG to mention proxy and ignore are gone from page --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c36dc6f7..08751a8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* Removed the `proxy` and `ignore` options for the `page` command in `config.rb`. Use the `proxy` and `ignore` commands instead of passing these options to `page`. * The `page` command in `config.rb` can now be used to add data to the page via the `data` argument. It is accessed the same way as frontmatter data, via `current_resource.data`. * Add support for `environments` with the `-e` CLI flag. Loads additional config from `environments/envname.rb`. Removed `development?` helper in favor of `environment?(:development)`. Added `server?` helper to differentiate between build and server mode. * Removed `with_layout`. Use loops of `page` instead. From 6678decd29c1cd00c7380ec24c56e48cf1a75dbc Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Wed, 2 Jul 2014 12:57:01 +0100 Subject: [PATCH 095/662] Update listen gem --- middleman-core/middleman-core.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index f516c88b..33408f7b 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -36,7 +36,7 @@ Gem::Specification.new do |s| s.add_dependency("padrino-helpers", ["~> 0.12.1"]) # Watcher - s.add_dependency("listen", ["~> 1.1"]) + s.add_dependency("listen", [">= 2.7.9", "< 3.0"]) # i18n s.add_dependency("i18n", ["~> 0.6.9"]) From 7b85a44afb162aec6f212cdeab5d3c9a762be602 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 2 Jul 2014 10:11:52 -0700 Subject: [PATCH 096/662] rubocoping --- middleman-core/lib/middleman-core.rb | 3 +- .../lib/middleman-core/cli/build.rb | 26 +++++----- .../lib/middleman-core/cli/bundler.rb | 4 +- middleman-core/lib/middleman-core/cli/init.rb | 6 +-- .../core_extensions/extensions.rb | 4 +- .../middleman-core/core_extensions/routing.rb | 34 ++++++------- .../lib/middleman-core/extension.rb | 36 ++++++------- .../lib/middleman-core/preview_server.rb | 51 +++++++++---------- .../lib/middleman-core/renderers/redcarpet.rb | 9 ++-- .../sitemap/extensions/on_disk.rb | 23 ++++----- .../sitemap/extensions/traversal.rb | 11 ++-- .../middleman-more/core_extensions/i18n.rb | 13 +++-- .../lib/middleman-more/extensions/gzip.rb | 10 ++-- 13 files changed, 109 insertions(+), 121 deletions(-) diff --git a/middleman-core/lib/middleman-core.rb b/middleman-core/lib/middleman-core.rb index 41673aac..3aec5990 100644 --- a/middleman-core/lib/middleman-core.rb +++ b/middleman-core/lib/middleman-core.rb @@ -1,5 +1,6 @@ -# Setup our load paths # rubocop:disable FileName + +# Setup our load paths libdir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) diff --git a/middleman-core/lib/middleman-core/cli/build.rb b/middleman-core/lib/middleman-core/cli/build.rb index 1af54e5e..b56ab320 100644 --- a/middleman-core/lib/middleman-core/cli/build.rb +++ b/middleman-core/lib/middleman-core/cli/build.rb @@ -168,10 +168,10 @@ module Middleman::Cli path.to_s !~ /\/\./ || path.to_s =~ /\.(htaccess|htpasswd)/ end - if RUBY_PLATFORM =~ /darwin/ - # handle UTF-8-MAC filename on MacOS - @to_clean = @to_clean.map { |path| path.to_s.encode('UTF-8', 'UTF-8-MAC') } - end + return unless RUBY_PLATFORM =~ /darwin/ + + # handle UTF-8-MAC filename on MacOS + @to_clean = @to_clean.map { |path| path.to_s.encode('UTF-8', 'UTF-8-MAC') } end # Actually build the app @@ -220,14 +220,14 @@ module Middleman::Cli output_path = render_to_file(resource) - if should_clean? && output_path.exist? - if RUBY_PLATFORM =~ /darwin/ - # handle UTF-8-MAC filename on MacOS + return unless should_clean? && output_path.exist? - @to_clean.delete(output_path.realpath.to_s.encode('UTF-8', 'UTF-8-MAC')) - else - @to_clean.delete(output_path.realpath) - end + if RUBY_PLATFORM =~ /darwin/ + # handle UTF-8-MAC filename on MacOS + + @to_clean.delete(output_path.realpath.to_s.encode('UTF-8', 'UTF-8-MAC')) + else + @to_clean.delete(output_path.realpath) end end @@ -279,9 +279,7 @@ module Middleman::Cli end def binary_encode(string) - if string.respond_to?(:force_encoding) - string.force_encoding('ascii-8bit') - end + string.force_encoding('ascii-8bit') if string.respond_to?(:force_encoding) string end end diff --git a/middleman-core/lib/middleman-core/cli/bundler.rb b/middleman-core/lib/middleman-core/cli/bundler.rb index 3f025ef3..27e461ce 100644 --- a/middleman-core/lib/middleman-core/cli/bundler.rb +++ b/middleman-core/lib/middleman-core/cli/bundler.rb @@ -11,7 +11,7 @@ module Middleman::Cli # The setup task def bundle - run('bundle install')# , :capture => true) + run('bundle install') # , :capture => true) end end @@ -27,7 +27,7 @@ module Middleman::Cli # The upgrade task def upgrade inside(ENV['MM_ROOT']) do - run('bundle update')# , :capture => true) + run('bundle update') # , :capture => true) end end end diff --git a/middleman-core/lib/middleman-core/cli/init.rb b/middleman-core/lib/middleman-core/cli/init.rb index 98782807..d9541161 100644 --- a/middleman-core/lib/middleman-core/cli/init.rb +++ b/middleman-core/lib/middleman-core/cli/init.rb @@ -15,13 +15,13 @@ module Middleman::Cli default: 'default', desc: "Use a project template: #{available_templates}" method_option 'css_dir', - # :default => "stylesheets", + # :default => "stylesheets", desc: 'The path to the css files' method_option 'js_dir', - # :default => "javascripts", + # :default => "javascripts", desc: 'The path to the javascript files' method_option 'images_dir', - # :default => "images", + # :default => "images", desc: 'The path to the image files' method_option 'rack', type: :boolean, diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index 917f7f6c..28674999 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -188,9 +188,7 @@ module Middleman logger.debug "== Extension: #{ext}" end - if klass.is_a?(::Middleman::Extension) - ::Middleman::Extension.activated_extension(klass) - end + ::Middleman::Extension.activated_extension(klass) if klass.is_a?(::Middleman::Extension) end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index e2328a02..0be0e8a1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -2,15 +2,15 @@ module Middleman module CoreExtensions module Routing - # Takes a block which allows many pages to have the same layout - # - # with_layout :admin do - # page "/admin/" - # page "/admin/login.html" - # end - # - # @param [String, Symbol] layout_name - # @return [void] + # Takes a block which allows many pages to have the same layout + # + # with_layout :admin do + # page "/admin/" + # page "/admin/login.html" + # end + # + # @param [String, Symbol] layout_name + # @return [void] def with_layout(layout_name, &block) old_layout = config[:layout] @@ -20,14 +20,14 @@ module Middleman config[:layout] = old_layout end - # The page method allows the layout to be set on a specific path - # - # page "/about.html", :layout => false - # page "/", :layout => :homepage_layout - # - # @param [String] url - # @param [Hash] opts - # @return [void] + # The page method allows the layout to be set on a specific path + # + # page "/about.html", :layout => false + # page "/", :layout => :homepage_layout + # + # @param [String] url + # @param [Hash] opts + # @return [void] def page(url, opts={}, &block) blocks = Array(block) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 48653bef..3a21000c 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -118,10 +118,10 @@ module Middleman def bind_before_configuration ext = self - if ext.respond_to?(:before_configuration) - @klass.before_configuration do - ext.before_configuration - end + return unless ext.respond_to?(:before_configuration) + + @klass.before_configuration do + ext.before_configuration end end @@ -139,26 +139,26 @@ module Middleman def bind_before_build ext = self - if ext.respond_to?(:before_build) - @klass.before_build do |builder| - if ext.method(:before_build).arity == 1 - ext.before_build(builder) - else - ext.before_build - end + return unless ext.respond_to?(:before_build) + + @klass.before_build do |builder| + if ext.method(:before_build).arity == 1 + ext.before_build(builder) + else + ext.before_build end end end def bind_after_build ext = self - if ext.respond_to?(:after_build) - @klass.after_build do |builder| - if ext.method(:after_build).arity == 1 - ext.after_build(builder) - else - ext.after_build - end + return unless ext.respond_to?(:after_build) + + @klass.after_build do |builder| + if ext.method(:after_build).arity == 1 + ext.after_build(builder) + else + ext.after_build end end end diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 41e7d5cf..d93b98a6 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -23,26 +23,25 @@ module Middleman logger.info "== Inspect your site configuration at http://#{host}:#{port}/__middleman/" @initialized ||= false - unless @initialized - @initialized = true + return if @initialized + @initialized = true - register_signal_handlers + register_signal_handlers - # Save the last-used @options so it may be re-used when - # reloading later on. - ::Middleman::Profiling.report('server_start') + # Save the last-used @options so it may be re-used when + # reloading later on. + ::Middleman::Profiling.report('server_start') - loop do - @webrick.start + loop do + @webrick.start - # $mm_shutdown is set by the signal handler - if $mm_shutdown - shutdown - exit - elsif $mm_reload - $mm_reload = false - reload - end + # $mm_shutdown is set by the signal handler + if $mm_shutdown + shutdown + exit + elsif $mm_reload + $mm_reload = false + reload end end end @@ -107,9 +106,7 @@ module Middleman opts[:instrumenting] || false ) - if opts[:environment] - config[:environment] = opts[:environment].to_sym - end + config[:environment] = opts[:environment].to_sym if opts[:environment] end end @@ -153,12 +150,12 @@ module Middleman # @return [void] def register_signal_handlers %w(INT HUP TERM QUIT).each do |sig| - if Signal.list[sig] - Signal.trap(sig) do - # Do as little work as possible in the signal context - $mm_shutdown = true - @webrick.stop - end + next unless Signal.list[sig] + + Signal.trap(sig) do + # Do as little work as possible in the signal context + $mm_shutdown = true + @webrick.stop end end end @@ -234,9 +231,7 @@ module Middleman class FilteredWebrickLog < ::WEBrick::Log def log(level, data) - unless data =~ %r{Could not determine content-length of response body.} - super(level, data) - end + super(level, data) unless data =~ %r{Could not determine content-length of response body.} end end end diff --git a/middleman-core/lib/middleman-core/renderers/redcarpet.rb b/middleman-core/lib/middleman-core/renderers/redcarpet.rb index 70094b53..a9e72221 100644 --- a/middleman-core/lib/middleman-core/renderers/redcarpet.rb +++ b/middleman-core/lib/middleman-core/renderers/redcarpet.rb @@ -20,8 +20,8 @@ module Middleman # Pick a renderer renderer = MiddlemanRedcarpetHTML - # Support SmartyPants if options.delete(:smartypants) + # Support SmartyPants renderer = Class.new(renderer) do include ::Redcarpet::Render::SmartyPants end @@ -30,9 +30,8 @@ module Middleman # Renderer Options possible_render_opts = [:filter_html, :no_images, :no_links, :no_styles, :safe_links_only, :with_toc_data, :hard_wrap, :xhtml, :prettify, :link_attributes] - render_options = possible_render_opts.reduce({}) do |sum, opt| + render_options = possible_render_opts.each_with_object({}) do |opt, sum| sum[opt] = options.delete(opt) if options.key?(opt) - sum end renderer.new(render_options) @@ -63,7 +62,7 @@ module Middleman else link_string = link.dup link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text - %Q{![#{alt_text}](#{link_string})} + "![#{alt_text}](#{link_string})" end end @@ -76,7 +75,7 @@ module Middleman else link_string = link.dup link_string << %Q("#{title}") if title && title.length > 0 && title != alt_text - %Q{[#{content}](#{link_string})} + "[#{content}](#{link_string})" end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 2c51063e..3347f373 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -57,25 +57,22 @@ module Middleman # whether or not it belongs in the sitemap (like a partial) @sitemap.rebuild_resource_list!(:touched_file) - unless waiting_for_ready || @app.build? - # Force sitemap rebuild so the next request is ready to go. - # Skip this during build because the builder will control sitemap refresh. - @sitemap.ensure_resource_list_updated! - end + # Force sitemap rebuild so the next request is ready to go. + # Skip this during build because the builder will control sitemap refresh. + @sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? end # Remove a file from the store # @param [String] file # @return [void] def remove_file(file) - if @file_paths_on_disk.delete?(file) - @sitemap.rebuild_resource_list!(:removed_file) - unless waiting_for_ready || @app.build? - # Force sitemap rebuild so the next request is ready to go. - # Skip this during build because the builder will control sitemap refresh. - @sitemap.ensure_resource_list_updated! - end - end + return unless @file_paths_on_disk.delete?(file) + + @sitemap.rebuild_resource_list!(:removed_file) + + # Force sitemap rebuild so the next request is ready to go. + # Skip this during build because the builder will control sitemap refresh. + @sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? end # Update the main sitemap resource list diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb index ae661c90..729a6204 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb @@ -13,15 +13,15 @@ module Middleman test_expr = parts.join('\\/') # A makeshift for eponymous reverse-lookup - found = store.resources.find { |candidate| - candidate.path =~ %r!^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$! - } + found = store.resources.find do |candidate| + candidate.path =~ %r{^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$} + end if found - return found + found else parts.pop if is_index - return store.find_resource_by_destination_path("#{parts.join('/')}/#{app.index_file}") + store.find_resource_by_destination_path("#{parts.join('/')}/#{app.index_file}") end end @@ -75,6 +75,7 @@ module Middleman if !path.end_with?("/#{app.index_file}") && destination_path.end_with?("/#{app.index_file}") return true end + full_path = File.join(app.source_dir, eponymous_directory_path) File.exist?(full_path) && File.directory?(full_path) end diff --git a/middleman-core/lib/middleman-more/core_extensions/i18n.rb b/middleman-core/lib/middleman-more/core_extensions/i18n.rb index f581f64c..0148f944 100644 --- a/middleman-core/lib/middleman-more/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-more/core_extensions/i18n.rb @@ -91,10 +91,10 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension private def on_file_changed(file) - if @locales_regex =~ file - @_langs = nil # Clear langs cache - ::I18n.reload! - end + return unless @locales_regex =~ file + + @_langs = nil # Clear langs cache + ::I18n.reload! end def convert_glob_to_regex(glob) @@ -108,10 +108,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n.reload! ::I18n.default_locale = @mount_at_root + # Reset fallbacks to fall back to our new default - if ::I18n.respond_to? :fallbacks - ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new - end + ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new if ::I18n.respond_to?(:fallbacks) end def metadata_for_path(url) diff --git a/middleman-core/lib/middleman-more/extensions/gzip.rb b/middleman-core/lib/middleman-more/extensions/gzip.rb index ed875d19..77b03285 100644 --- a/middleman-core/lib/middleman-more/extensions/gzip.rb +++ b/middleman-core/lib/middleman-more/extensions/gzip.rb @@ -55,11 +55,11 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension num_paths.times do output_filename, old_size, new_size = out_queue.pop - if output_filename - total_savings += (old_size - new_size) - size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger' - builder.say_status :gzip, "#{output_filename} (#{app.number_to_human_size((old_size - new_size).abs)} #{size_change_word})" - end + next unless output_filename + + total_savings += (old_size - new_size) + size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger' + builder.say_status :gzip, "#{output_filename} (#{app.number_to_human_size((old_size - new_size).abs)} #{size_change_word})" end builder.say_status :gzip, "Total gzip savings: #{app.number_to_human_size(total_savings)}", :blue From d8f84fa97bbe21467f91fce5f9dbcedd93609e0d Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Wed, 2 Jul 2014 18:26:18 +0100 Subject: [PATCH 097/662] Update listen code --- .../lib/middleman-core/preview_server.rb | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index d93b98a6..d848fda9 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -111,18 +111,15 @@ module Middleman end def start_file_watcher - return if @options[:disable_watcher] + return if @listener or @options[:disable_watcher] - first_run = !@listener + # Watcher Library + require 'listen' - if first_run - # Watcher Library - require 'listen' - @listener = Listen.to(Dir.pwd, relative_paths: true, force_polling: @options[:force_polling]) - @listener.latency(@options[:latency]) - end + options = {force_polling: @options[:force_polling]} + options[:latency] = @options[:latency] if @options[:latency] - @listener.change do |modified, added, removed| + @listener = Listen.to(Dir.pwd, options) do |modified, added, removed| added_and_modified = (modified + added) # See if the changed file is config.rb or lib/*.rb @@ -131,19 +128,21 @@ module Middleman @webrick.stop else added_and_modified.each do |path| - next if app.files.ignored?(path) - app.files.did_change(path) + relative_path = Pathname(path).relative_path_from(Pathname(Dir.pwd)).to_s + next if app.files.ignored?(relative_path) + app.files.did_change(relative_path) end removed.each do |path| - next if app.files.ignored?(path) - app.files.did_delete(path) + relative_path = Pathname(path).relative_path_from(Pathname(Dir.pwd)).to_s + next if app.files.ignored?(relative_path) + app.files.did_delete(relative_path) end end end # Don't block this thread - @listener.start if first_run + @listener.start end # Trap some interupt signals and shut down smoothly From 6bb9673630075fe8a9640f1ae25f97ed686715f0 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 2 Jul 2014 11:05:57 -0700 Subject: [PATCH 098/662] final copping --- .../lib/middleman-core/config_context.rb | 7 +++--- .../core_extensions/external_helpers.rb | 16 ++++++------- .../middleman-core/core_extensions/i18n.rb | 6 ++--- .../middleman-core/core_extensions/routing.rb | 4 +--- .../lib/middleman-core/extension.rb | 9 ++++---- .../lib/middleman-core/extensions.rb | 14 +++++------ .../middleman-core/extensions/asset_hash.rb | 9 ++++---- .../extensions/relative_assets.rb | 8 +++---- .../lib/middleman-core/preview_server.rb | 6 +++-- .../lib/middleman-core/renderers/liquid.rb | 6 ++--- middleman-core/lib/middleman-core/util.rb | 23 +++++++++++-------- 11 files changed, 57 insertions(+), 51 deletions(-) diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 90922ea9..e02232c4 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -32,9 +32,10 @@ module Middleman def include_environment(name) path = File.dirname(__FILE__) other_config = File.join(path, name.to_s) - if File.exist? other_config - instance_eval File.read(other_config), other_config, 1 - end + + return unless File.exist? other_config + + instance_eval File.read(other_config), other_config, 1 end def ready(&block) diff --git a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb index 6b755df5..3934f11f 100644 --- a/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/external_helpers.rb @@ -17,16 +17,16 @@ module Middleman def after_configuration helpers_path = File.join(app.root, app.config[:helpers_dir]) - if File.exist?(helpers_path) - Dir[File.join(helpers_path, app.config[:helpers_filename_glob])].each do |filename| - module_name = app.config[:helpers_filename_to_module_name_proc].call(filename) - next unless module_name + return unless File.exist?(helpers_path) - require filename - next unless Object.const_defined?(module_name.to_sym) + Dir[File.join(helpers_path, app.config[:helpers_filename_glob])].each do |filename| + module_name = app.config[:helpers_filename_to_module_name_proc].call(filename) + next unless module_name - app.template_context_class.send :include, Object.const_get(module_name.to_sym) - end + require filename + next unless Object.const_defined?(module_name.to_sym) + + app.template_context_class.send :include, Object.const_get(module_name.to_sym) end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index cba2ffe6..c90e3263 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -81,9 +81,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # This is for backwards compatibility with the old provides_metadata-based code # that used to be in this extension, but I don't know how much sense it makes. - unless resource.options[:lang] - resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } - end + next if resource.options[:lang] + + resource.add_metadata options: { lang: @mount_at_root }, locals: { lang: @mount_at_root } end resources + new_resources diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index da0cead6..b7f4ee52 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -61,9 +61,7 @@ module Middleman end end - if path.is_a?(String) - path = '/' + Util.strip_leading_slash(path) - end + path = '/' + Util.strip_leading_slash(path) if path.is_a?(String) @page_configs << [path, metadata] end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index ea19e601..734d8123 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -233,10 +233,11 @@ module Middleman @app = app ext = self - if ext.respond_to?(:instance_available) - @klass.instance_available do - ext.instance_available - end + + return unless ext.respond_to?(:instance_available) + + @klass.instance_available do + ext.instance_available end end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index a33bf203..dac9ea75 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -67,10 +67,10 @@ module Middleman raise 'You must provide a Middleman::Extension or a block that returns a Middleman::Extension' end - if options[:auto_activate] - descriptor = AutoActivation.new(name, options[:modes] || :all) - @auto_activate[options[:auto_activate]] << descriptor - end + return unless options[:auto_activate] + + descriptor = AutoActivation.new(name, options[:modes] || :all) + @auto_activate[options[:auto_activate]] << descriptor end # @api private @@ -114,9 +114,9 @@ module Middleman # @param [Middleman::Application] app An instance of the app. def auto_activate(group, app) @auto_activate[group].each do |descriptor| - if descriptor[:modes] == :all || descriptor[:modes].include?(app.config[:mode]) - app.activate descriptor[:name] - end + next unless descriptor[:modes] == :all || descriptor[:modes].include?(app.config[:mode]) + + app.activate descriptor[:name] end end end diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index 1fd9426d..3fa5e9ea 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -35,12 +35,11 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension asset_path end - if asset_page = app.sitemap.find_resource_by_path(full_asset_path) - replacement_path = "/#{asset_page.destination_path}" - replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path + return unless asset_page = app.sitemap.find_resource_by_path(full_asset_path) - replacement_path - end + replacement_path = "/#{asset_page.destination_path}" + replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path + replacement_path end # Update the main sitemap resource list diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index f8666924..3820b8f8 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -29,9 +29,9 @@ class Middleman::Extensions::RelativeAssets < ::Middleman::Extension asset_path end - if !full_asset_path.include?('//') && !asset_path.start_with?('data:') - current_dir = Pathname('/' + request_path).dirname - Pathname(full_asset_path).relative_path_from(current_dir).to_s - end + return unless !full_asset_path.include?('//') && !asset_path.start_with?('data:') + + current_dir = Pathname('/' + request_path).dirname + Pathname(full_asset_path).relative_path_from(current_dir).to_s end end diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 4695fb6c..e7d82335 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -2,6 +2,7 @@ require 'webrick' require 'middleman-core/meta_pages' require 'middleman-core/logger' +# rubocop:disable GlobalVars module Middleman module PreviewServer DEFAULT_PORT = 4567 @@ -110,12 +111,12 @@ module Middleman end def start_file_watcher - return if @listener or @options[:disable_watcher] + return if @listener || @options[:disable_watcher] # Watcher Library require 'listen' - options = {force_polling: @options[:force_polling]} + options = { force_polling: @options[:force_polling] } options[:latency] = @options[:latency] if @options[:latency] @listener = Listen.to(Dir.pwd, options) do |modified, added, removed| @@ -153,6 +154,7 @@ module Middleman Signal.trap(sig) do # Do as little work as possible in the signal context $mm_shutdown = true + @webrick.stop end end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index a6fb2ef8..2085d939 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -12,10 +12,10 @@ module Middleman def manipulate_resource_list(resources) resources.each do |resource| + next unless resource.source_file =~ %r{\.liquid$} + # Convert data object into a hash for liquid - if resource.source_file =~ %r{\.liquid$} - resource.add_metadata locals: { data: app.data.to_h } - end + resource.add_metadata locals: { data: app.data.to_h } end end end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 912c7ae3..3620259e 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -100,15 +100,15 @@ module Middleman # @param [String] path A path as a string # @return [Boolean] Whether the path matches the matcher def path_match(matcher, path) - !!case + case when matcher.is_a?(String) if matcher.include? '*' File.fnmatch(matcher, path) else path == matcher - end + end when matcher.respond_to?(:match) - matcher.match(path) + !matcher.match(path).nil? when matcher.respond_to?(:call) matcher.call(path) else @@ -149,11 +149,16 @@ module Middleman return source if source.to_s.include?('//') || source.to_s.start_with?('data:') asset_folder = case kind - when :css then app.config[:css_dir] - when :js then app.config[:js_dir] - when :images then app.config[:images_dir] - when :fonts then app.config[:fonts_dir] - else kind.to_s + when :css + app.config[:css_dir] + when :js + app.config[:js_dir] + when :images + app.config[:images_dir] + when :fonts + app.config[:fonts_dir] + else + kind.to_s end source = source.to_s.tr(' ', '') @@ -172,7 +177,7 @@ module Middleman # @return [String] The fully qualified asset url def asset_url(app, path, prefix='', _options={}) # Don't touch assets which already have a full path - if path.include?('//') or path.start_with?('data:') + if path.include?('//') || path.start_with?('data:') path else # rewrite paths to use their destination path if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) From e2e3c1e3fb2a7903f1b25aadeb7cd8c8610bc62c Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Thu, 3 Jul 2014 20:13:22 +0100 Subject: [PATCH 099/662] fix specs on windows --- Gemfile | 2 +- gem_rake_helper.rb | 4 +++- middleman-core/features/gzip.feature | 1 + .../features/more-implied_extensions.feature | 8 +------- .../features/twitter-bootstrap-compile.feature | 8 ++++---- .../source/stylesheets/style3.less | 4 ---- .../lib/middleman-core/step_definitions.rb | 16 ++++++++++++---- .../spec/middleman-core/binary_spec.rb | 4 ++-- 8 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 middleman-core/fixtures/more-implied-extensions-app/source/stylesheets/style3.less diff --git a/Gemfile b/Gemfile index 4c721ffa..84394d93 100644 --- a/Gemfile +++ b/Gemfile @@ -17,11 +17,11 @@ gem 'slim', require: false gem 'liquid', require: false gem 'less', '~> 2.3.0', require: false gem 'stylus', require: false +gem 'redcarpet', '~> 3.1', require: false gem 'asciidoctor', require: false platforms :ruby do gem 'therubyracer' - gem 'redcarpet', '~> 3.1' gem 'pry', require: false, group: :development end diff --git a/gem_rake_helper.rb b/gem_rake_helper.rb index 284cf5dc..5f95c90e 100644 --- a/gem_rake_helper.rb +++ b/gem_rake_helper.rb @@ -19,6 +19,7 @@ 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) + exempt_tags << '--tags ~@nowindows' if Gem.win_platform? exempt_tags << '--tags ~@travishatesme' if ENV['TRAVIS'] == 'true' t.cucumber_opts = "--color #{exempt_tags.join(' ')} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" end @@ -27,6 +28,7 @@ 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) + exempt_tags << '--tags ~@nowindows' if Gem.win_platform? t.cucumber_opts = "--color #{exempt_tags.join(' ')} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}" end @@ -34,7 +36,7 @@ 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'] + spec.rspec_opts = ['--color', '--format documentation'] end desc 'Run tests, both RSpec and Cucumber' diff --git a/middleman-core/features/gzip.feature b/middleman-core/features/gzip.feature index 5a5a4265..93955a49 100644 --- a/middleman-core/features/gzip.feature +++ b/middleman-core/features/gzip.feature @@ -1,3 +1,4 @@ +@nowindows Feature: GZIP assets during build Scenario: Built assets should be gzipped diff --git a/middleman-core/features/more-implied_extensions.feature b/middleman-core/features/more-implied_extensions.feature index 31567443..10ee5b20 100644 --- a/middleman-core/features/more-implied_extensions.feature +++ b/middleman-core/features/more-implied_extensions.feature @@ -19,10 +19,7 @@ Feature: More default extensions When I go to "/stylesheets/style2.css" Then I should see "section" Then I should not see "I am in the layout" - When I go to "/stylesheets/style3.css" - Then I should see "color" - Then I should not see "I am in the layout" - + Scenario: Default extensions build Given a fixture app "more-implied-extensions-app" And a successfully built app at "more-implied-extensions-app" @@ -35,7 +32,6 @@ Feature: More default extensions | javascripts/app.js | | stylesheets/style.css | | stylesheets/style2.css | - | stylesheets/style3.css | And the file "test.html" should contain "Hello" And the file "test2.html" should contain "World" And the file "test3.html" should contain "Howdy" @@ -46,5 +42,3 @@ Feature: More default extensions And the file "stylesheets/style.css" should not contain "I am in the layout" And the file "stylesheets/style2.css" should contain "section" And the file "stylesheets/style2.css" should not contain "I am in the layout" - And the file "stylesheets/style3.css" should contain "color" - And the file "stylesheets/style3.css" should not contain "I am in the layout" \ No newline at end of file diff --git a/middleman-core/features/twitter-bootstrap-compile.feature b/middleman-core/features/twitter-bootstrap-compile.feature index 994cf11c..04ffc0ce 100644 --- a/middleman-core/features/twitter-bootstrap-compile.feature +++ b/middleman-core/features/twitter-bootstrap-compile.feature @@ -1,6 +1,6 @@ -@nojava -Feature: Compile a complicated Twitter bootstrap app +@nojava @nowindows +Feature: Compile a complicated Twitter bootstrap app Scenario: User drops Twitter Bootstrap source into an app - - Given a successfully built app at "twitter-bootstrap-app" \ No newline at end of file + + Given a successfully built app at "twitter-bootstrap-app" diff --git a/middleman-core/fixtures/more-implied-extensions-app/source/stylesheets/style3.less b/middleman-core/fixtures/more-implied-extensions-app/source/stylesheets/style3.less deleted file mode 100644 index 420d50d4..00000000 --- a/middleman-core/fixtures/more-implied-extensions-app/source/stylesheets/style3.less +++ /dev/null @@ -1,4 +0,0 @@ -@base: #f938ab; -.box { - color: @base; -} \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/step_definitions.rb b/middleman-core/lib/middleman-core/step_definitions.rb index 4c14b091..95245f14 100644 --- a/middleman-core/lib/middleman-core/step_definitions.rb +++ b/middleman-core/lib/middleman-core/step_definitions.rb @@ -1,13 +1,21 @@ -MIDDLEMAN_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__))) -MIDDLEMAN_BIN_PATH = File.join(MIDDLEMAN_ROOT_PATH, 'bin') -ENV['PATH'] = "#{MIDDLEMAN_BIN_PATH}#{File::PATH_SEPARATOR}#{ENV['PATH']}" - require 'aruba/cucumber' require 'aruba/jruby' require 'middleman-core/step_definitions/middleman_steps' require 'middleman-core/step_definitions/builder_steps' require 'middleman-core/step_definitions/server_steps' +# Monkeypatch for windows support +module ArubaMonkeypatch + def detect_ruby(cmd) + if cmd.start_with?('middleman ') && Gem.win_platform? + "#{current_ruby} #{Dir.pwd}/bin/#{cmd}" + else + cmd.sub(/^ruby(?= )/, current_ruby) + end + end +end +World(ArubaMonkeypatch) + Before do @aruba_timeout_seconds = RUBY_PLATFORM == 'java' ? 120 : 60 end diff --git a/middleman-core/spec/middleman-core/binary_spec.rb b/middleman-core/spec/middleman-core/binary_spec.rb index 79944331..4f8d11d2 100644 --- a/middleman-core/spec/middleman-core/binary_spec.rb +++ b/middleman-core/spec/middleman-core/binary_spec.rb @@ -3,13 +3,13 @@ require 'middleman-core/util' describe "Middleman::Util#binary?" do %w(plain.txt unicode.txt unicode).each do |file| it "recognizes #{file} as not binary" do - expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_false + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be false end end %w(middleman.png middleman stars.svgz).each do |file| it "recognizes #{file} as binary" do - expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be_true + expect(Middleman::Util.binary?(File.join(File.dirname(__FILE__), "binary_spec/#{file}"))).to be true end end end From 1bd7dab1a3316acb4d516a1b7256d861c3a04644 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 4 Jul 2014 10:38:25 -0700 Subject: [PATCH 100/662] Make a ProxyResource which extends Resource, rather than injecting methods into Resource --- .../core_extensions/front_matter.rb | 2 +- .../middleman-core/core_extensions/i18n.rb | 3 +- .../sitemap/extensions/ignores.rb | 4 +- .../sitemap/extensions/proxies.rb | 96 +++++++++---------- .../lib/middleman-core/sitemap/resource.rb | 16 ++-- 5 files changed, 59 insertions(+), 62 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 234e5a01..13bb3361 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -52,7 +52,7 @@ module Middleman::CoreExtensions resource.add_metadata options: opts, page: fmdata - resource.ignore! if ignored == true && !resource.proxy? + resource.ignore! if ignored == true && !resource.is_a?(::Middleman::Sitemap::ProxyResource) # TODO: Save new template here somewhere? end diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index c90e3263..e707f612 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -162,8 +162,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension path = path.sub(options[:templates_dir] + '/', '') - p = ::Middleman::Sitemap::Resource.new(app.sitemap, path) - p.proxy_to(source_path) + p = ::Middleman::Sitemap::ProxyResource.new(app.sitemap, path, source_path) p.add_metadata locals: { lang: lang, page_id: path }, options: { lang: lang } ::I18n.locale = old_locale diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index b12e6c73..9ca344a2 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -58,10 +58,12 @@ module Middleman # @return [Boolean] def ignored? return true if @ignored + # Ignore based on the source path (without template extensions) return true if @app.sitemap.ignored?(path) + # This allows files to be ignored by their source file name (with template extensions) - !proxy? && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) + @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index acba2eb7..b9abe44e 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -10,8 +10,6 @@ module Middleman @app.define_singleton_method(:proxy, &method(:create_proxy)) @proxy_configs = Set.new - - ::Middleman::Sitemap::Resource.send :include, ProxyResourceInstanceMethods end # Setup a proxy from a path to a target @@ -43,11 +41,11 @@ module Middleman # @return [void] def manipulate_resource_list(resources) resources + @proxy_configs.map do |config| - p = ::Middleman::Sitemap::Resource.new( + p = ProxyResource.new( @app.sitemap, - config.path + config.path, + config.target ) - p.proxy_to(config.target) p.add_metadata(config.metadata) p @@ -89,63 +87,59 @@ module Middleman path.hash end end + end - module ProxyResourceInstanceMethods - # Whether this page is a proxy - # @return [Boolean] - def proxy? - @proxied_to + class ProxyResource < ::Middleman::Sitemap::Resource + # Initialize resource with parent store and URL + # @param [Middleman::Sitemap::Store] store + # @param [String] path + # @param [String] source_file + def initialize(store, path, target) + super(store, path) + + target = ::Middleman::Util.normalize_path(target) + raise "You can't proxy #{path} to itself!" if target == path + @target = target + end + + # The resource for the page this page is proxied to. Throws an exception + # if there is no resource. + # @return [Sitemap::Resource] + def target_resource + resource = @store.find_resource_by_path(@target) + + unless resource + raise "Path #{path} proxies to unknown file #{@target}:#{@store.resources.map(&:path)}" end - # Set this page to proxy to a target path - # @param [String] target - # @return [void] - def proxy_to(target) - target = ::Middleman::Util.normalize_path(target) - raise "You can't proxy #{path} to itself!" if target == path - @proxied_to = target + if resource.is_a? ProxyResource + raise "You can't proxy #{path} to #{@target} which is itself a proxy." end - # The path of the page this page is proxied to, or nil if it's not proxied. - # @return [String] - attr_reader :proxied_to + resource + end - # The resource for the page this page is proxied to. Throws an exception - # if there is no resource. - # @return [Sitemap::Resource] - def proxied_to_resource - proxy_resource = @store.find_resource_by_path(proxied_to) + # rubocop:disable AccessorMethodName + def get_source_file + target_resource.source_file + end - unless proxy_resource - raise "Path #{path} proxies to unknown file #{proxied_to}:#{@store.resources.map(&:path)}" - end + def content_type + mime_type = super + return mime_type if mime_type - if proxy_resource.proxy? - raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy." - end + target_resource.content_type + end - proxy_resource - end + # Whether the Resource is ignored + # @return [Boolean] + def ignored? + return true if @ignored - # rubocop:disable AccessorMethodName - def get_source_file - if proxy? - proxied_to_resource.source_file - else - super - end - end + # Ignore based on the source path (without template extensions) + return true if @app.sitemap.ignored?(path) - def content_type - mime_type = super - return mime_type if mime_type - - if proxy? - proxied_to_resource.content_type - else - nil - end - end + false end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 62551ad5..41d45edf 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -2,12 +2,14 @@ require 'middleman-core/sitemap/extensions/traversal' require 'middleman-core/sitemap/extensions/content_type' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' +require 'hamster/immutable' module Middleman # Sitemap namespace module Sitemap # Sitemap Resource class class Resource + # include ::Hamster::Immutable include Middleman::Sitemap::Extensions::Traversal include Middleman::Sitemap::Extensions::ContentType @@ -25,13 +27,6 @@ module Middleman # @return [String] alias_method :request_path, :destination_path - # Set the on-disk source file for this resource - # @return [String] - def source_file - # TODO: Make this work when get_source_file doesn't exist - @source_file || get_source_file - end - # Initialize resource with parent store and URL # @param [Middleman::Sitemap::Store] store # @param [String] path @@ -50,6 +45,13 @@ module Middleman @metadata = { options: {}, locals: {}, page: {} } end + # Set the on-disk source file for this resource + # @return [String] + def source_file + # TODO: Make this work when get_source_file doesn't exist + @source_file || get_source_file + end + # Whether this resource has a template file # @return [Boolean] def template? From 3a2cab4775e50a35f08c84c944a4aca72f9e8ba9 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 4 Jul 2014 10:41:25 -0700 Subject: [PATCH 101/662] Whoops, leftover include --- middleman-core/lib/middleman-core/sitemap/resource.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 41d45edf..97b4e832 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -2,14 +2,12 @@ require 'middleman-core/sitemap/extensions/traversal' require 'middleman-core/sitemap/extensions/content_type' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' -require 'hamster/immutable' module Middleman # Sitemap namespace module Sitemap # Sitemap Resource class class Resource - # include ::Hamster::Immutable include Middleman::Sitemap::Extensions::Traversal include Middleman::Sitemap::Extensions::ContentType From 5897c4c4a47d89d0bcd41ebdebe6e1b9f6f2cb69 Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Sat, 5 Jul 2014 02:19:51 +0100 Subject: [PATCH 102/662] update gemfile --- Gemfile | 46 +++++++++---------- .../step_definitions/server_steps.rb | 14 +++--- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Gemfile b/Gemfile index 84394d93..230b683f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,39 +1,37 @@ source 'https://rubygems.org' # Build and doc tools -gem 'rake', '~> 10.0.3', require: false -gem 'yard', '~> 0.8.0', require: false +gem 'rake', '~> 10.3', require: false +gem 'yard', '~> 0.8', require: false # Test tools -gem 'cucumber', '~> 1.3.1' -gem 'fivemat', '~> 1.2.1' -gem 'aruba', '~> 0.5.1' -gem 'rspec', '~> 2.12' -gem 'simplecov' +gem 'pry', '~> 0.10', group: :development +gem 'aruba', '~> 0.6' +gem 'rspec', '~> 3.0' +gem 'fivemat', '~> 1.3' +gem 'cucumber', '~> 1.3' # Optional middleman dependencies, included for tests -gem 'sinatra', require: false -gem 'slim', require: false -gem 'liquid', require: false -gem 'less', '~> 2.3.0', require: false -gem 'stylus', require: false -gem 'redcarpet', '~> 3.1', require: false -gem 'asciidoctor', require: false +gem 'less', '2.3.0', require: false +gem 'slim', '~> 2.0', require: false +gem 'liquid', '~> 2.6', require: false +gem 'stylus', '~> 1.0', require: false +gem 'sinatra','~> 1.4', require: false +gem 'asciidoctor', '~> 0.1', require: false -platforms :ruby do - gem 'therubyracer' - gem 'pry', require: false, group: :development -end +# For less, since it doesn't use ExecJS (which also means less wont work on windows) +gem 'therubyracer', platforms: :ruby +gem 'therubyrhino', platforms: :jruby -platforms :jruby do - gem 'therubyrhino' -end +# Redcarpet doesn't work on JRuby +gem 'redcarpet', '~> 3.1', require: false unless RUBY_ENGINE == 'jruby' # Code Quality -gem 'coveralls', require: false -gem 'rubocop', require: false +gem 'rubocop', '~> 0.24', require: false +gem 'simplecov', '0.7.1', require: false +gem 'coveralls', '~> 0.7', require: false # Middleman itself +gem 'middleman', path: 'middleman' gem 'middleman-core', path: 'middleman-core' gem 'middleman-sprockets', github: 'middleman/middleman-sprockets' -gem 'middleman', path: 'middleman' 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 0dda0772..30098760 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -68,29 +68,29 @@ When /^I go to "([^\"]*)"$/ do |url| end Then /^going to "([^\"]*)" should not raise an exception$/ do |url| - lambda { @browser.get(URI.escape(url)) }.should_not raise_exception + expect(lambda { @browser.get(URI.escape(url)) }).to_not raise_exception end Then /^the content type should be "([^\"]*)"$/ do |expected| - @browser.last_response.content_type.should start_with(expected) + expect(@browser.last_response.content_type).to start_with(expected) end Then /^I should see "([^\"]*)"$/ do |expected| - @browser.last_response.body.should include(expected) + expect(@browser.last_response.body).to include(expected) end Then /^I should see '([^\']*)'$/ do |expected| - @browser.last_response.body.should include(expected) + expect(@browser.last_response.body).to include(expected) end Then /^I should see:$/ do |expected| - @browser.last_response.body.should include(expected) + expect(@browser.last_response.body).to include(expected) end Then /^I should not see "([^\"]*)"$/ do |expected| - @browser.last_response.body.should_not include(expected) + expect(@browser.last_response.body).to_not include(expected) end Then /^I should see "([^\"]*)" lines$/ do |lines| - @browser.last_response.body.chomp.split($/).length.should == lines.to_i + expect(@browser.last_response.body.chomp.split($/).length).to eq(lines.to_i) end From 3a19cc668da9f9b559155fd7ab7c6aee6b3ebedf Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 10:42:03 -0700 Subject: [PATCH 103/662] move Sitemap into application, it's core to the entire system --- .../lib/middleman-core/application.rb | 25 ++++++++-- middleman-core/lib/middleman-core/sitemap.rb | 49 ------------------- .../lib/middleman-core/template_context.rb | 12 +++++ 3 files changed, 33 insertions(+), 53 deletions(-) delete mode 100644 middleman-core/lib/middleman-core/sitemap.rb diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index e264ea09..90dbb65f 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -15,7 +15,6 @@ require 'hooks' # Our custom logger require 'middleman-core/logger' -require 'middleman-core/sitemap' require 'middleman-core/sitemap/store' require 'middleman-core/configuration' @@ -134,6 +133,27 @@ module Middleman # @return [Boolean] config.define_setting :protect_from_csrf, false, 'Should Padrino include CRSF tag' + # Set to automatically convert some characters into a directory + config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory' + + # Setup callbacks which can exclude paths from the sitemap + config.define_setting :ignored_sitemap_matchers, { + # dotfiles and folders in the root + root_dotfiles: proc { |file| file.start_with?('.') }, + + # Files starting with an dot, but not .htaccess + source_dotfiles: proc { |file| + file =~ %r{/\.} && file !~ %r{/\.(htaccess|htpasswd|nojekyll)} + }, + + # Files starting with an underscore, but not a double-underscore + partials: proc { |file| file =~ %r{/_[^_]} }, + + layout: proc { |file, sitemap_app| + file.start_with?(File.join(sitemap_app.config[:source], 'layout.')) || file.start_with?(File.join(sitemap_app.config[:source], 'layouts/')) + } + }, 'Callbacks that can exclude paths from the sitemap' + # Activate custom features and extensions include Middleman::CoreExtensions::Extensions @@ -143,9 +163,6 @@ module Middleman # Setup custom rendering include Middleman::CoreExtensions::Rendering - # Sitemap Config options and public api - include Middleman::Sitemap - # Reference to Logger singleton def logger ::Middleman::Logger.singleton diff --git a/middleman-core/lib/middleman-core/sitemap.rb b/middleman-core/lib/middleman-core/sitemap.rb deleted file mode 100644 index c320369c..00000000 --- a/middleman-core/lib/middleman-core/sitemap.rb +++ /dev/null @@ -1,49 +0,0 @@ -# Core Sitemap Extensions -module Middleman - module Sitemap - # Setup Extension - class << self - # Once registered - def included(app) - # Set to automatically convert some characters into a directory - app.config.define_setting :automatic_directory_matcher, nil, 'Set to automatically convert some characters into a directory' - - # 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.start_with?('.') }, - - # Files starting with an dot, but not .htaccess - source_dotfiles: proc { |file| - file =~ %r{/\.} && file !~ %r{/\.(htaccess|htpasswd|nojekyll)} - }, - - # Files starting with an underscore, but not a double-underscore - partials: proc { |file| file =~ %r{/_[^_]} }, - - layout: proc { |file, sitemap_app| - file.start_with?(File.join(sitemap_app.config[:source], 'layout.')) || file.start_with?(File.join(sitemap_app.config[:source], 'layouts/')) - } - }, 'Callbacks that can exclude paths from the sitemap' - - # Include instance methods - ::Middleman::TemplateContext.send :include, InstanceMethods - end - end - - # Sitemap instance methods - module InstanceMethods - def current_path - @locs[:current_path] - end - - # Get the resource object for the current path - # @return [Middleman::Sitemap::Resource] - def current_resource - return nil unless current_path - sitemap.find_resource_by_destination_path(current_path) - end - alias_method :current_page, :current_resource - end - end -end diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index a81db78b..01b55fa5 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -154,5 +154,17 @@ module Middleman file_renderer = ::Middleman::FileRenderer.new(@app, path) file_renderer.render(locs, opts, self, &block) end + + def current_path + @locs[:current_path] + end + + # Get the resource object for the current path + # @return [Middleman::Sitemap::Resource] + def current_resource + return nil unless current_path + sitemap.find_resource_by_destination_path(current_path) + end + alias_method :current_page, :current_resource end end From 336b80cbbde4a81efc07bc384469c2aaf83955d2 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 11:17:41 -0700 Subject: [PATCH 104/662] Switch from ActiveSupports delegate method to Ruby 1.9+ def_delegator --- middleman-core/lib/middleman-core/application.rb | 14 +++++++------- .../lib/middleman-core/config_context.rb | 4 +++- middleman-core/lib/middleman-core/configuration.rb | 2 +- .../middleman-core/core_extensions/extensions.rb | 2 +- .../middleman-core/core_extensions/file_watcher.rb | 5 ++++- .../lib/middleman-core/core_extensions/i18n.rb | 2 +- .../lib/middleman-core/core_extensions/request.rb | 5 +++-- middleman-core/lib/middleman-core/extension.rb | 5 +++-- middleman-core/lib/middleman-core/file_renderer.rb | 4 +++- .../lib/middleman-core/preview_server.rb | 4 +++- middleman-core/lib/middleman-core/sitemap/store.rb | 2 +- .../lib/middleman-core/template_context.rb | 6 ++++-- .../lib/middleman-core/template_renderer.rb | 4 +++- 13 files changed, 37 insertions(+), 22 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 90dbb65f..1ad45f2b 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -33,6 +33,8 @@ require 'middleman-core/core_extensions/extensions' # Core Middleman Class module Middleman class Application + extend Forwardable + # Global configuration include Configuration::Global @@ -57,13 +59,13 @@ module Middleman def self.root ENV['MM_ROOT'] || Dir.pwd end - delegate :root, to: :"self.class" + def_delegator :"self.class", :root # Pathname-addressed root def self.root_path Pathname(root) end - delegate :root_path, to: :"self.class" + def_delegator :"self.class", :root_path # Name of the source directory # @return [String] @@ -180,7 +182,7 @@ module Middleman attr_reader :template_context_class attr_reader :generic_template_context - delegate :link_to, :image_tag, :asset_path, to: :generic_template_context + def_delegators :@generic_template_context, :link_to, :image_tag, :asset_path # Initialize the Middleman project def initialize @@ -242,7 +244,7 @@ module Middleman File.join(root, config[:source]) end - delegate :instrument, to: ::Middleman::Util + def_delegator ::Middleman::Util, :instrument # Work around this bug: http://bugs.ruby-lang.org/issues/4521 # where Ruby will call to_s/inspect while printing exception @@ -256,8 +258,6 @@ module Middleman # Hooks clones _hooks from the class to the instance. # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 # Middleman expects the same list of hooks for class and instance hooks: - def _hooks - self.class._hooks - end + def_delegator :"self.class", :_hooks end end diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index e02232c4..92368760 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -1,9 +1,11 @@ module Middleman class ConfigContext + extend Forwardable + attr_reader :app # Whitelist methods that can reach out. - delegate :config, :logger, :activate, :use, :map, :mime_type, :data, :files, :root, to: :app + def_delegators :@app, :config, :logger, :activate, :use, :map, :mime_type, :data, :files, :root def initialize(app, template_context_class) @app = app diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index dd3fe8f7..9678801d 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -5,7 +5,7 @@ module Middleman module Global def self.included(app) app.send :extend, ClassMethods - app.send :delegate, :config, to: :"self.class" + app.send :def_delegator, :"self.class", :config end module ClassMethods diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb index dbe8715b..9c62edf6 100644 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/extensions.rb @@ -16,7 +16,7 @@ module Middleman app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] app.extend ClassMethods - app.delegate :configure, to: :"self.class" + app.def_delegator :"self.class", :configure end module ClassMethods 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 8de7805c..2b4e7002 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -53,9 +53,12 @@ module Middleman # Core File Change API class class API + extend Forwardable + attr_reader :app attr_reader :known_paths - delegate :logger, to: :app + + def_delegator :@app, :logger # Initialize api and internal path cache def initialize(app) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index e707f612..b33322a7 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -52,7 +52,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - delegate :logger, to: :app + def_delegator :@app, :logger def langs @langs ||= known_languages diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb index b4c59f1a..c833a1ec 100644 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ b/middleman-core/lib/middleman-core/core_extensions/request.rb @@ -146,8 +146,9 @@ module Middleman # Methods to be mixed-in to Middleman::Application module InstanceMethods - delegate :use, to: :"self.class" - delegate :map, to: :"self.class" + def self.included(app) + app.send :def_delegators, :"self.class", :use, :map + end def call(env) dup.call!(env) diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 734d8123..d2823632 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -1,4 +1,3 @@ -require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/class/attribute' require 'middleman-core/configuration' @@ -65,6 +64,8 @@ module Middleman # # @see http://middlemanapp.com/advanced/custom/ Middleman Custom Extensions Documentation class Extension + extend Forwardable + # @!attribute supports_multiple_instances # @!scope class # @return [Boolean] whether or not an extension can be activated multiple times, generating multiple instances of the extension. @@ -175,7 +176,7 @@ module Middleman # @param [Symbol] name The name the extension was registered under # @param [Proc] block A callback to run when the named extension is activated # @return [void] - delegate :after_extension_activated, to: :"::Middleman::Extension" + def_delegator :"::Middleman::Extension", :after_extension_activated # Extensions are instantiated when they are activated. # @param [Class] klass The Middleman::Application class diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index b55cb48e..c11537fd 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -3,11 +3,13 @@ require 'active_support/core_ext/string/output_safety' module Middleman class FileRenderer + extend Forwardable + def self.cache @_cache ||= ::Tilt::Cache.new end - delegate :cache, to: :"self.class" + def_delegator :"self.class", :cache def initialize(app, path) @app = app diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index e7d82335..a94ee6c6 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -8,8 +8,10 @@ module Middleman DEFAULT_PORT = 4567 class << self + extend Forwardable + attr_reader :app, :host, :port - delegate :logger, to: :app + def_delegator :app, :logger # Start an instance of Middleman::Application # @return [void] diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index c12a1e6f..203699af 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -54,7 +54,7 @@ module Middleman register_resource_list_manipulator(k, m) end - @app.config_context.class.send :delegate, :sitemap, to: :app + @app.config_context.class.send :def_delegator, :app, :sitemap end # Register an object which can transform the sitemap resource list. Best to register diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 01b55fa5..17b970fb 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -11,6 +11,8 @@ module Middleman # A new context is created for each render of a path, but that context is shared through # the request, passed from template, to layouts and partials. class TemplateContext + extend Forwardable + # Allow templates to directly access the current app instance. # @return [Middleman::Application] attr_reader :app @@ -19,7 +21,7 @@ module Middleman attr_accessor :current_engine # Shorthand references to global values on the app instance. - delegate :config, :logger, :sitemap, :server?, :build?, :environment?, :data, :extensions, :source_dir, :root, to: :app + def_delegators :@app, :config, :logger, :sitemap, :server?, :build?, :environment?, :data, :extensions, :source_dir, :root # Initialize a context with the current app and predefined locals and options hashes. # @@ -154,7 +156,7 @@ module Middleman file_renderer = ::Middleman::FileRenderer.new(@app, path) file_renderer.render(locs, opts, self, &block) end - + def current_path @locs[:current_path] end diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 1b47db05..a8d1d527 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -5,11 +5,13 @@ require 'middleman-core/file_renderer' module Middleman class TemplateRenderer + extend Forwardable + def self.cache @_cache ||= ::Tilt::Cache.new end - delegate :cache, to: :"self.class" + def_delegator :"self.class", :cache # Custom error class for handling class TemplateNotFound < RuntimeError; end From 571704322dfddd332743ff59d3c5899ce2474012 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 26 May 2014 19:55:25 -0700 Subject: [PATCH 105/662] Load templates from Git --- middleman-cli/lib/middleman-cli.rb | 3 ++ middleman-cli/lib/middleman-cli/git.rb | 52 ++++++++++++++++++++++++++ middleman-cli/middleman-cli.gemspec | 2 +- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 middleman-cli/lib/middleman-cli/git.rb diff --git a/middleman-cli/lib/middleman-cli.rb b/middleman-cli/lib/middleman-cli.rb index e49df2f9..fa8a4b0f 100644 --- a/middleman-cli/lib/middleman-cli.rb +++ b/middleman-cli/lib/middleman-cli.rb @@ -32,6 +32,8 @@ module Middleman say "Middleman #{Middleman::VERSION}" end + desc 'help', 'Show help' + # Override the Thor help method to find help for subtasks # @param [Symbol, String, nil] meth # @param [Boolean] subcommand @@ -92,3 +94,4 @@ require 'middleman-cli/extension' require 'middleman-cli/server' require 'middleman-cli/build' require 'middleman-cli/console' +require 'middleman-cli/git' diff --git a/middleman-cli/lib/middleman-cli/git.rb b/middleman-cli/lib/middleman-cli/git.rb new file mode 100644 index 00000000..b8d512e0 --- /dev/null +++ b/middleman-cli/lib/middleman-cli/git.rb @@ -0,0 +1,52 @@ +# CLI Module +module Middleman::Cli + # A thor task for creating new projects + class Git < Thor + include Thor::Actions + check_unknown_options! + + namespace :git + + desc 'git REPO TARGET [options]', 'Create new project from REPO at TARGET' + + # Do not run bundle install + method_option 'skip-bundle', + type: :boolean, + aliases: '-B', + default: false, + desc: "Don't run bundle install" + + # The git task + # @param [String] name + def git(repo, target='.') + require 'rugged' + require 'tmpdir' + + path = repository_path(repo) + + Dir.mktmpdir do |dir| + Rugged::Repository.clone_at(path, dir) + + source_paths << dir + + directory dir, target, exclude_pattern: /\.git\/|\.gitignore$/ + + inside(target) do + run('bundle install') + end unless ENV['TEST'] || options[:'skip-bundle'] + end + end + + protected + + def repository_path(repo) + "git://github.com/#{repo}.git" + end + end + + def self.exit_on_failure? + true + end + + Base.map('g' => 'git') +end diff --git a/middleman-cli/middleman-cli.gemspec b/middleman-cli/middleman-cli.gemspec index 8102ed15..5a2fde18 100644 --- a/middleman-cli/middleman-cli.gemspec +++ b/middleman-cli/middleman-cli.gemspec @@ -23,5 +23,5 @@ Gem::Specification.new do |s| s.add_dependency('thor', ['>= 0.17.0', '< 2.0']) # Templates - s.add_dependency('octokit', ['~> 3.1']) + s.add_dependency('rugged', []) end From c0a6d8ac4cad5eb9a1eba6653edb9030022497e1 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 12:51:41 -0700 Subject: [PATCH 106/662] Pull mixin for extension activation into a real class --- .../lib/middleman-core/application.rb | 86 ++++++++-- .../lib/middleman-core/config_context.rb | 3 +- .../core_extensions/extensions.rb | 162 ------------------ .../lib/middleman-core/extension_manager.rb | 73 ++++++++ .../lib/middleman-core/extensions.rb | 2 +- 5 files changed, 151 insertions(+), 175 deletions(-) delete mode 100644 middleman-core/lib/middleman-core/core_extensions/extensions.rb create mode 100644 middleman-core/lib/middleman-core/extension_manager.rb diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index 1ad45f2b..ab1b9798 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -18,6 +18,8 @@ require 'middleman-core/logger' require 'middleman-core/sitemap/store' require 'middleman-core/configuration' + +require 'middleman-core/extension_manager' require 'middleman-core/core_extensions' require 'middleman-core/config_context' @@ -27,9 +29,6 @@ require 'middleman-core/template_renderer' # Rack Request require 'middleman-core/core_extensions/request' -# Custom Extension API and config.rb handling -require 'middleman-core/core_extensions/extensions' - # Core Middleman Class module Middleman class Application @@ -156,8 +155,13 @@ module Middleman } }, 'Callbacks that can exclude paths from the sitemap' - # Activate custom features and extensions - include Middleman::CoreExtensions::Extensions + define_hook :initialized + define_hook :instance_available + define_hook :after_configuration + define_hook :before_configuration + + config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' + config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] # Basic Rack Request Handling include Middleman::CoreExtensions::Request @@ -166,9 +170,7 @@ module Middleman include Middleman::CoreExtensions::Rendering # Reference to Logger singleton - def logger - ::Middleman::Logger.singleton - end + def_delegator :"::Middleman::Logger", :singleton, :logger # New container for config.rb commands attr_reader :config_context @@ -181,11 +183,19 @@ module Middleman attr_reader :template_context_class + # Hack to get a sandboxed copy of these helpers for overriding similar methods inside Markdown renderers. attr_reader :generic_template_context def_delegators :@generic_template_context, :link_to, :image_tag, :asset_path + attr_reader :extensions + # Initialize the Middleman project - def initialize + def initialize(&block) + self.class.inst = self + + # Search the root of the project for required files + $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) + @template_context_class = Class.new(Middleman::TemplateContext) @generic_template_context = @template_context_class.new(self) @config_context = ConfigContext.new(self, @template_context_class) @@ -196,7 +206,8 @@ module Middleman # Setup the default values from calls to set before initialization self.class.config.load_settings(self.class.superclass.config.all_settings) - ::Middleman::Extensions.auto_activate(:before_sitemap, self) + @extensions = ::Middleman::ExtensionManager.new(self) + @extensions.auto_activate(:before_sitemap) # Initialize the Sitemap @sitemap = ::Middleman::Sitemap::Store.new(self) @@ -208,7 +219,60 @@ module Middleman config[:source] = ENV['MM_SOURCE'] if ENV['MM_SOURCE'] - super + ::Middleman::Extension.clear_after_extension_callbacks + + @extensions.auto_activate(:before_configuration) + + if config[:autoload_sprockets] + begin + require 'middleman-sprockets' + activate :sprockets + rescue LoadError + # It's OK if somebody is using middleman-core without middleman-sprockets + end + end + + run_hook :initialized + + run_hook :before_configuration + + evaluate_configuration(&block) + + run_hook :instance_available + + # This is for making the tests work - since the tests + # don't completely reload middleman, I18n.load_path can get + # polluted with paths from other test app directories that don't + # exist anymore. + if ENV['TEST'] + ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } + ::I18n.reload! + end + + run_hook :after_configuration + config_context.execute_after_configuration_callbacks + + @extensions.activate_all + end + + def evaluate_configuration(&block) + # Evaluate a passed block if given + config_context.instance_exec(&block) if block_given? + + # Check for and evaluate local configuration in `config.rb` + local_config = File.join(root, 'config.rb') + if File.exist? local_config + logger.debug '== Reading: Local config' + config_context.instance_eval File.read(local_config), local_config, 1 + end + + env_config = File.join(root, 'environments', "#{config[:environment]}.rb") + if File.exist? env_config + logger.debug "== Reading: #{config[:environment]} config" + config_context.instance_eval File.read(env_config), env_config, 1 + end + + config_context.execute_configure_callbacks(config[:environment]) end def add_to_instance(name, &func) diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index 92368760..caeebd51 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -5,7 +5,8 @@ module Middleman attr_reader :app # Whitelist methods that can reach out. - def_delegators :@app, :config, :logger, :activate, :use, :map, :mime_type, :data, :files, :root + def_delegators :@app, :config, :logger, :use, :map, :mime_type, :data, :files, :root + def_delegator :"@app.extensions", :activate def initialize(app, template_context_class) @app = app diff --git a/middleman-core/lib/middleman-core/core_extensions/extensions.rb b/middleman-core/lib/middleman-core/core_extensions/extensions.rb deleted file mode 100644 index 9c62edf6..00000000 --- a/middleman-core/lib/middleman-core/core_extensions/extensions.rb +++ /dev/null @@ -1,162 +0,0 @@ -module Middleman - module CoreExtensions - # The Extensions core module provides basic configurability to Middleman projects: - # - # * It loads and evaluates `config.rb`. - # * It defines lifecycle hooks for extensions and `config.rb` to use. - # * It provides the {#activate} method for use in `config.rb`. - module Extensions - def self.included(app) - app.define_hook :initialized - app.define_hook :instance_available - app.define_hook :after_configuration - app.define_hook :before_configuration - - app.config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' - app.config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - - app.extend ClassMethods - app.def_delegator :"self.class", :configure - end - - module ClassMethods - # Register a block to run only in a specific environment. - # - # @example - # # Only minify when building - # configure :production do - # activate :minify_javascript - # end - # - # @param [String, Symbol] env The environment to run in - # @return [void] - def configure(env, &block) - send("#{env}_config", &block) - end - end - - # Activate an extension, optionally passing in options. - # This method is typically used from a project's `config.rb`. - # - # @example Activate an extension with no options - # activate :lorem - # - # @example Activate an extension, with options - # activate :minify_javascript, inline: true - # - # @example Use a block to configure extension options - # activate :minify_javascript do |opts| - # opts.ignore += ['*-test.js'] - # end - # - # @param [Symbol] ext_name The name of thed extension to activate - # @param [Hash] options Options to pass to the extension - # @yield [Middleman::Configuration::ConfigurationManager] Extension options that can be modified before the extension is initialized. - # @return [void] - def activate(ext_name, options={}, &block) - extension = ::Middleman::Extensions.load(ext_name) - logger.debug "== Activating: #{ext_name}" - - if extension.supports_multiple_instances? - extensions[ext_name] ||= {} - key = "instance_#{extensions[ext_name].keys.length}" - extensions[ext_name][key] = extension.new(self.class, options, &block) - elsif extensions.key?(ext_name) - raise "#{ext_name} has already been activated and cannot be re-activated." - else - extensions[ext_name] = extension.new(self.class, options, &block) - end - end - - # A hash of all activated extensions, indexed by their name. If an extension supports multiple - # instances, it will be stored as a hash of instances instead of just the instance. - # - # @return [Hash{Symbol => Middleman::Extension, Hash{String => Middleman::Extension}}] - def extensions - @extensions ||= {} - end - - # Override application initialization to load `config.rb` and to call lifecycle hooks. - def initialize(&block) - self.class.inst = self - - # Search the root of the project for required files - $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) - - super - - ::Middleman::Extension.clear_after_extension_callbacks - - ::Middleman::Extensions.auto_activate(:before_configuration, self) - - if config[:autoload_sprockets] - begin - require 'middleman-sprockets' - activate :sprockets - rescue LoadError - # It's OK if somebody is using middleman-core without middleman-sprockets - end - end - - run_hook :initialized - - run_hook :before_configuration - - # Evaluate a passed block if given - config_context.instance_exec(&block) if block_given? - - # Check for and evaluate local configuration in `config.rb` - local_config = File.join(root, 'config.rb') - if File.exist? local_config - logger.debug '== Reading: Local config' - config_context.instance_eval File.read(local_config), local_config, 1 - end - - env_config = File.join(root, 'environments', "#{config[:environment]}.rb") - if File.exist? env_config - logger.debug "== Reading: #{config[:environment]} config" - config_context.instance_eval File.read(env_config), env_config, 1 - end - - config_context.execute_configure_callbacks(config[:environment]) - - run_hook :instance_available - - # This is for making the tests work - since the tests - # don't completely reload middleman, I18n.load_path can get - # polluted with paths from other test app directories that don't - # exist anymore. - if ENV['TEST'] - ::I18n.load_path.delete_if { |path| path =~ %r{tmp/aruba} } - ::I18n.reload! - end - - run_hook :after_configuration - config_context.execute_after_configuration_callbacks - - extension_instances = [] - logger.debug 'Loaded extensions:' - extensions.each do |ext_name, ext| - if ext.is_a?(Hash) - ext.each do |instance_key, instance| - logger.debug "== Extension: #{ext_name} #{instance_key}" - extension_instances << instance - end - else - logger.debug "== Extension: #{ext_name}" - extension_instances << ext - end - end - - extension_instances.each do |ext| - # Forward Extension helpers to TemplateContext - Array(ext.class.defined_helpers).each do |m| - @template_context_class.send(:include, m) - end - - ::Middleman::Extension.activated_extension(ext) - end - end - end - end -end diff --git a/middleman-core/lib/middleman-core/extension_manager.rb b/middleman-core/lib/middleman-core/extension_manager.rb new file mode 100644 index 00000000..169646e5 --- /dev/null +++ b/middleman-core/lib/middleman-core/extension_manager.rb @@ -0,0 +1,73 @@ +module Middleman + class ExtensionManager + extend Forwardable + def_delegator :"::Middleman::Logger", :singleton, :logger + def_delegators :@activated, :[] + + def initialize(app) + @app = app + @activated = {} + end + + def auto_activate(key) + ::Middleman::Extensions.auto_activate(key, @app) + end + + # Activate an extension, optionally passing in options. + # This method is typically used from a project's `config.rb`. + # + # @example Activate an extension with no options + # activate :lorem + # + # @example Activate an extension, with options + # activate :minify_javascript, inline: true + # + # @example Use a block to configure extension options + # activate :minify_javascript do |opts| + # opts.ignore += ['*-test.js'] + # end + # + # @param [Symbol] ext_name The name of thed extension to activate + # @param [Hash] options Options to pass to the extension + # @yield [Middleman::Configuration::ConfigurationManager] Extension options that can be modified before the extension is initialized. + # @return [void] + def activate(ext_name, options={}, &block) + extension = ::Middleman::Extensions.load(ext_name) + logger.debug "== Activating: #{ext_name}" + + if extension.supports_multiple_instances? + @activated[ext_name] ||= {} + key = "instance_#{@activated[ext_name].keys.length}" + @activated[ext_name][key] = extension.new(@app.class, options, &block) + elsif @activated.key?(ext_name) + raise "#{ext_name} has already been activated and cannot be re-activated." + else + @activated[ext_name] = extension.new(@app.class, options, &block) + end + end + + def activate_all + logger.debug 'Loaded extensions:' + instances = @activated.each_with_object([]) do |(ext_name, ext), sum| + if ext.is_a?(Hash) + ext.each do |instance_key, instance| + logger.debug "== Extension: #{ext_name} #{instance_key}" + sum << instance + end + else + logger.debug "== Extension: #{ext_name}" + sum << ext + end + end + + instances.each do |ext| + # Forward Extension helpers to TemplateContext + Array(ext.class.defined_helpers).each do |m| + @app.template_context_class.send(:include, m) + end + + ::Middleman::Extension.activated_extension(ext) + end + end + end +end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index dac9ea75..37690957 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -116,7 +116,7 @@ module Middleman @auto_activate[group].each do |descriptor| next unless descriptor[:modes] == :all || descriptor[:modes].include?(app.config[:mode]) - app.activate descriptor[:name] + app.extensions.activate descriptor[:name] end end end From 300ef8d8feea43c787e55eee3b1e8b74d5f7a448 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 13:41:59 -0700 Subject: [PATCH 107/662] Convert renderers into first-class extensions --- .../lib/middleman-core/application.rb | 17 ++- .../core_extensions/rendering.rb | 139 +++++++----------- .../lib/middleman-core/extension_manager.rb | 10 +- .../lib/middleman-core/file_renderer.rb | 3 + .../lib/middleman-core/preview_server.rb | 11 +- .../middleman-core/renderers/coffee_script.rb | 20 ++- .../lib/middleman-core/renderers/erb.rb | 14 +- .../lib/middleman-core/renderers/haml.rb | 19 +-- .../lib/middleman-core/renderers/less.rb | 24 ++- .../lib/middleman-core/renderers/markdown.rb | 75 +++++----- .../lib/middleman-core/renderers/sass.rb | 35 ++--- .../lib/middleman-core/renderers/slim.rb | 39 +++-- .../lib/middleman-core/renderers/stylus.rb | 14 +- 13 files changed, 185 insertions(+), 235 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index ab1b9798..a40158e9 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -53,6 +53,9 @@ module Middleman # Runs after the build is finished define_hook :after_build + define_hook :before_render + define_hook :after_render + # Root project directory (overwritten in middleman build/server) # @return [String] def self.root @@ -166,9 +169,6 @@ module Middleman # Basic Rack Request Handling include Middleman::CoreExtensions::Request - # Setup custom rendering - include Middleman::CoreExtensions::Rendering - # Reference to Logger singleton def_delegator :"::Middleman::Logger", :singleton, :logger @@ -226,7 +226,7 @@ module Middleman if config[:autoload_sprockets] begin require 'middleman-sprockets' - activate :sprockets + @extensions.activate :sprockets rescue LoadError # It's OK if somebody is using middleman-core without middleman-sprockets end @@ -249,6 +249,15 @@ module Middleman ::I18n.reload! end + # Clean up missing Tilt exts + Tilt.mappings.each do |key, _| + begin + Tilt[".#{key}"] + rescue LoadError, NameError + Tilt.mappings.delete(key) + end + end + run_hook :after_configuration config_context.execute_after_configuration_callbacks diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 42854825..33d3d02d 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -1,90 +1,55 @@ require 'middleman-core/template_context' -# Rendering extension -module Middleman - module CoreExtensions - module Rendering - # Setup extension - class << self - # Once registered - def included(app) - app.define_hook :before_render - app.define_hook :after_render - - ::Tilt.mappings.delete('html') # WTF, Tilt? - ::Tilt.mappings.delete('csv') - - require 'active_support/core_ext/string/output_safety' - - # Activate custom renderers - require 'middleman-core/renderers/erb' - app.send :include, Middleman::Renderers::ERb - - # CoffeeScript Support - begin - require 'middleman-core/renderers/coffee_script' - app.send :include, Middleman::Renderers::CoffeeScript - rescue LoadError - end - - # Haml Support - begin - require 'middleman-core/renderers/haml' - app.send :include, Middleman::Renderers::Haml - rescue LoadError - end - - # Sass Support - begin - require 'middleman-core/renderers/sass' - app.send :include, Middleman::Renderers::Sass - rescue LoadError - end - - # Markdown Support - require 'middleman-core/renderers/markdown' - app.send :include, Middleman::Renderers::Markdown - - # Liquid Support - begin - require 'middleman-core/renderers/liquid' - Middleman::Extensions.register :liquid, Middleman::Renderers::Liquid, auto_activate: :before_configuration - rescue LoadError - end - - # Slim Support - begin - require 'middleman-core/renderers/slim' - app.send :include, Middleman::Renderers::Slim - rescue LoadError - end - - # Less Support - begin - require 'middleman-core/renderers/less' - app.send :include, Middleman::Renderers::Less - rescue LoadError - end - - # Stylus Support - begin - require 'middleman-core/renderers/stylus' - app.send :include, Middleman::Renderers::Stylus - rescue LoadError - end - - # Clean up missing Tilt exts - app.after_configuration do - Tilt.mappings.each do |key, _| - begin - Tilt[".#{key}"] - rescue LoadError, NameError - Tilt.mappings.delete(key) - end - end - end - end - end - end - end +# ERb Support +Middleman::Extensions.register :erb_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/erb' + Middleman::Renderers::ERb +end + +# CoffeeScript Support +Middleman::Extensions.register :coffee_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/coffee_script' + Middleman::Renderers::CoffeeScript +end + +# Haml Support +Middleman::Extensions.register :haml_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/haml' + Middleman::Renderers::Haml +end + +# Sass Support +Middleman::Extensions.register :sass_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/sass' + Middleman::Renderers::Sass +end + +# Markdown Support +Middleman::Extensions.register :markdown_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/markdown' + Middleman::Renderers::Markdown +end + +# Liquid Support +Middleman::Extensions.register :liquid_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/liquid' + Middleman::Renderers::Liquid +end + +# Slim Support +Middleman::Extensions.register :slim_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/slim' + Middleman::Renderers::Slim +end + +# Less Support +Middleman::Extensions.register :less_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/less' + Middleman::Renderers::Less +end + +# Stylus Support +Middleman::Extensions.register :stylus_renderer, auto_activate: :before_configuration do + require 'middleman-core/renderers/stylus' + Middleman::Renderers::Stylus end diff --git a/middleman-core/lib/middleman-core/extension_manager.rb b/middleman-core/lib/middleman-core/extension_manager.rb index 169646e5..e05a5d24 100644 --- a/middleman-core/lib/middleman-core/extension_manager.rb +++ b/middleman-core/lib/middleman-core/extension_manager.rb @@ -1,7 +1,7 @@ module Middleman class ExtensionManager extend Forwardable - def_delegator :"::Middleman::Logger", :singleton, :logger + def_delegator :@app, :logger def_delegators :@activated, :[] def initialize(app) @@ -32,7 +32,13 @@ module Middleman # @yield [Middleman::Configuration::ConfigurationManager] Extension options that can be modified before the extension is initialized. # @return [void] def activate(ext_name, options={}, &block) - extension = ::Middleman::Extensions.load(ext_name) + begin + extension = ::Middleman::Extensions.load(ext_name) + rescue LoadError => e + logger.debug "== Failed Activation `#{ext_name}` : #{e.message}" + return + end + logger.debug "== Activating: #{ext_name}" if extension.supports_multiple_instances? diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index c11537fd..1e0bbebd 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -1,6 +1,9 @@ require 'tilt' require 'active_support/core_ext/string/output_safety' +::Tilt.mappings.delete('html') # WTF, Tilt? +::Tilt.mappings.delete('csv') + module Middleman class FileRenderer extend Forwardable diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index a94ee6c6..301b1b69 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -94,6 +94,12 @@ module Middleman def new_app opts = @options.dup + + ::Middleman::Logger.singleton( + opts[:debug] ? 0 : 1, + opts[:instrumenting] || false + ) + server = ::Middleman::Application.server # Add in the meta pages application @@ -103,11 +109,6 @@ module Middleman end @app = server.inst do - ::Middleman::Logger.singleton( - opts[:debug] ? 0 : 1, - opts[:instrumenting] || false - ) - config[:environment] = opts[:environment].to_sym if opts[:environment] end end diff --git a/middleman-core/lib/middleman-core/renderers/coffee_script.rb b/middleman-core/lib/middleman-core/renderers/coffee_script.rb index b8519845..ba39159c 100644 --- a/middleman-core/lib/middleman-core/renderers/coffee_script.rb +++ b/middleman-core/lib/middleman-core/renderers/coffee_script.rb @@ -4,20 +4,18 @@ require 'coffee_script' module Middleman module Renderers # CoffeeScript Renderer - module CoffeeScript + class CoffeeScript < ::Middleman::Extension # Setup extension - class << self - # Once registered - def registered(app) - # Tell Tilt to use it as well (for inline scss blocks) - ::Tilt.register 'coffee', DebuggingCoffeeScriptTemplate - ::Tilt.prefer(DebuggingCoffeeScriptTemplate) + def initialize(app, options={}, &block) + super - app.before_configuration do - DebuggingCoffeeScriptTemplate.middleman_app = self - end + # Tell Tilt to use it as well (for inline scss blocks) + ::Tilt.register 'coffee', DebuggingCoffeeScriptTemplate + ::Tilt.prefer(DebuggingCoffeeScriptTemplate) + + app.before_configuration do + DebuggingCoffeeScriptTemplate.middleman_app = self end - alias_method :included, :registered end # A Template for Tilt which outputs debug messages diff --git a/middleman-core/lib/middleman-core/renderers/erb.rb b/middleman-core/lib/middleman-core/renderers/erb.rb index a3a1239c..5305406f 100644 --- a/middleman-core/lib/middleman-core/renderers/erb.rb +++ b/middleman-core/lib/middleman-core/renderers/erb.rb @@ -1,17 +1,9 @@ # ERb renderer module Middleman module Renderers - module ERb - # Setup extension - class << self - # once registered - def registered(app) - # After config - app.after_configuration do - ::Tilt.prefer(Template, :erb) - end - end - alias_method :included, :registered + class ERb < ::Middleman::Extension + def after_configuration + ::Tilt.prefer(Template, :erb) end class Template < ::Tilt::ErubisTemplate diff --git a/middleman-core/lib/middleman-core/renderers/haml.rb b/middleman-core/lib/middleman-core/renderers/haml.rb index fc75a4e8..cde27a70 100644 --- a/middleman-core/lib/middleman-core/renderers/haml.rb +++ b/middleman-core/lib/middleman-core/renderers/haml.rb @@ -37,19 +37,16 @@ module Middleman end # Haml Renderer - module Haml - mattr_accessor :last_haml_scope + class Haml < ::Middleman::Extension + cattr_accessor :last_haml_scope - # Setup extension - class << self - # Once registered - def registered(_) - ::Tilt.prefer(::Middleman::Renderers::HamlTemplate, :haml) + def initialize(app, options={}, &block) + super - # Add haml helpers to context - ::Middleman::TemplateContext.send :include, ::Haml::Helpers - end - alias_method :included, :registered + ::Tilt.prefer(::Middleman::Renderers::HamlTemplate, :haml) + + # Add haml helpers to context + ::Middleman::TemplateContext.send :include, ::Haml::Helpers end end end diff --git a/middleman-core/lib/middleman-core/renderers/less.rb b/middleman-core/lib/middleman-core/renderers/less.rb index db097298..5ad79c77 100644 --- a/middleman-core/lib/middleman-core/renderers/less.rb +++ b/middleman-core/lib/middleman-core/renderers/less.rb @@ -3,24 +3,20 @@ require 'less' module Middleman module Renderers # Sass renderer - module Less - # Setup extension - class << self - # Once registered - def registered(app) - # Default less options - app.config.define_setting :less, {}, 'LESS compiler options' + class Less < ::Middleman::Extension + def initialize(app, options={}, &block) + super - app.after_configuration do - ::Less.paths << File.join(source_dir, config[:css_dir]) - end + # Default less options + app.config.define_setting :less, {}, 'LESS compiler options' - # Tell Tilt to use it as well (for inline sass blocks) - ::Tilt.register 'less', LocalLoadingLessTemplate - ::Tilt.prefer(LocalLoadingLessTemplate) + app.after_configuration do + ::Less.paths << File.join(source_dir, config[:css_dir]) end - alias_method :included, :registered + # Tell Tilt to use it as well (for inline sass blocks) + ::Tilt.register 'less', LocalLoadingLessTemplate + ::Tilt.prefer(LocalLoadingLessTemplate) end # A SassTemplate for Tilt which outputs debug messages diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index c60c4030..80b57ce7 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -1,51 +1,48 @@ module Middleman module Renderers # Markdown renderer - module Markdown - # Setup extension - class << self - # Once registered - def registered(app) - # Set our preference for a markdown engine - app.config.define_setting :markdown_engine, :kramdown, 'Preferred markdown engine' - app.config.define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines' + class Markdown < ::Middleman::Extension + # Once registered + def initialize(app, options={}, &block) + super - # Once configuration is parsed - app.after_configuration do - markdown_exts = %w(markdown mdown md mkd mkdn) + # Set our preference for a markdown engine + app.config.define_setting :markdown_engine, :kramdown, 'Preferred markdown engine' + app.config.define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines' + end - begin - # Look for the user's preferred engine - if config[:markdown_engine] == :redcarpet - require 'middleman-core/renderers/redcarpet' - ::Tilt.prefer(::Middleman::Renderers::RedcarpetTemplate, *markdown_exts) - elsif config[:markdown_engine] == :kramdown - require 'middleman-core/renderers/kramdown' - ::Tilt.prefer(::Middleman::Renderers::KramdownTemplate, *markdown_exts) - elsif config[:markdown_engine] - # Map symbols to classes - markdown_engine_klass = if config[:markdown_engine].is_a? Symbol - engine = config[:markdown_engine].to_s - engine = engine == 'rdiscount' ? 'RDiscount' : engine.camelize - config[:markdown_engine_prefix].const_get("#{engine}Template") - else - config[:markdown_engine_prefix] - end + # Once configuration is parsed + def after_configuration + markdown_exts = %w(markdown mdown md mkd mkdn) - # Tell tilt to use that engine - ::Tilt.prefer(markdown_engine_klass, *markdown_exts) - end - rescue LoadError - # If they just left it at the default engine and don't happen to have it, - # then they're using middleman-core bare and we shouldn't bother them. - if config.setting(:markdown_engine).value_set? - logger.warn "Requested Markdown engine (#{config[:markdown_engine]}) not found. Maybe the gem needs to be installed and required?" - end + begin + # Look for the user's preferred engine + if app.config[:markdown_engine] == :redcarpet + require 'middleman-core/renderers/redcarpet' + ::Tilt.prefer(::Middleman::Renderers::RedcarpetTemplate, *markdown_exts) + elsif app.config[:markdown_engine] == :kramdown + require 'middleman-core/renderers/kramdown' + ::Tilt.prefer(::Middleman::Renderers::KramdownTemplate, *markdown_exts) + elsif app.config[:markdown_engine] + # Map symbols to classes + markdown_engine_klass = if app.config[:markdown_engine].is_a? Symbol + engine = app.config[:markdown_engine].to_s + engine = engine == 'rdiscount' ? 'RDiscount' : engine.camelize + app.config[:markdown_engine_prefix].const_get("#{engine}Template") + else + app.config[:markdown_engine_prefix] end + + # Tell tilt to use that engine + ::Tilt.prefer(markdown_engine_klass, *markdown_exts) + end + rescue LoadError + # If they just left it at the default engine and don't happen to have it, + # then they're using middleman-core bare and we shouldn't bother them. + if config.setting(:markdown_engine).value_set? + logger.warn "Requested Markdown engine (#{app.config[:markdown_engine]}) not found. Maybe the gem needs to be installed and required?" end end - - alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index b5642655..05d0b8e5 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -33,33 +33,30 @@ end module Middleman module Renderers # Sass renderer - module Sass + class Sass < ::Middleman::Extension # Setup extension - class << self - # Once registered - def registered(app) - opts = { output_style: :nested } - opts[:line_comments] = false if ENV['TEST'] + def initialize(app, options={}, &block) + super - # Default sass options - app.config.define_setting :sass, opts, 'Sass engine options' + opts = { output_style: :nested } + opts[:line_comments] = false if ENV['TEST'] - app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' + # Default sass options + app.config.define_setting :sass, opts, 'Sass engine options' - # Tell Tilt to use it as well (for inline sass blocks) - ::Tilt.register 'sass', SassPlusCSSFilenameTemplate - ::Tilt.prefer(SassPlusCSSFilenameTemplate) + app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files' - # Tell Tilt to use it as well (for inline scss blocks) - ::Tilt.register 'scss', ScssPlusCSSFilenameTemplate - ::Tilt.prefer(ScssPlusCSSFilenameTemplate) + # Tell Tilt to use it as well (for inline sass blocks) + ::Tilt.register 'sass', SassPlusCSSFilenameTemplate + ::Tilt.prefer(SassPlusCSSFilenameTemplate) - ::Compass::ImportOnce.activate! + # Tell Tilt to use it as well (for inline scss blocks) + ::Tilt.register 'scss', ScssPlusCSSFilenameTemplate + ::Tilt.prefer(ScssPlusCSSFilenameTemplate) - require 'middleman-core/renderers/sass_functions' - end + ::Compass::ImportOnce.activate! - alias_method :included, :registered + require 'middleman-core/renderers/sass_functions' end # A SassTemplate for Tilt which outputs debug messages diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index d3ec7541..ace8f751 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -18,32 +18,27 @@ end module Middleman module Renderers # Slim renderer - module Slim + class Slim < ::Middleman::Extension # Setup extension - class << self - # Once registered - def registered(app) - # Setup Slim options to work with partials - ::Slim::Engine.set_default_options( - buffer: '@_out_buf', - use_html_safe: true, - generator: ::Temple::Generators::RailsOutputBuffer, - disable_escape: true - ) + def initialize(_app, _options={}, &_block) + # Setup Slim options to work with partials + ::Slim::Engine.set_default_options( + buffer: '@_out_buf', + use_html_safe: true, + generator: ::Temple::Generators::RailsOutputBuffer, + disable_escape: true + ) + end - app.after_configuration do - context_hack = { - context: template_context_class.new(self) - } + def after_configuration + context_hack = { + context: app.template_context_class.new(self) + } - ::Slim::Embedded::SassEngine.disable_option_validator! - %w(sass scss markdown).each do |engine| - ::Slim::Embedded.default_options[engine.to_sym] = context_hack - end - end + ::Slim::Embedded::SassEngine.disable_option_validator! + %w(sass scss markdown).each do |engine| + ::Slim::Embedded.default_options[engine.to_sym] = context_hack end - - alias_method :included, :registered end end end diff --git a/middleman-core/lib/middleman-core/renderers/stylus.rb b/middleman-core/lib/middleman-core/renderers/stylus.rb index 7c7989e2..19bc0f17 100644 --- a/middleman-core/lib/middleman-core/renderers/stylus.rb +++ b/middleman-core/lib/middleman-core/renderers/stylus.rb @@ -3,17 +3,11 @@ require 'stylus/tilt' module Middleman module Renderers - # Sass renderer - module Stylus - # Setup extension - class << self - # Once registered - def registered(app) - # Default stylus options - app.config.define_setting :styl, {}, 'Stylus config options' - end + class Stylus < ::Middleman::Extension + def initialize(app, options={}, &block) + super - alias_method :included, :registered + app.config.define_setting :styl, {}, 'Stylus config options' end end end From 60bbe44e0e16a70f056ba928a1b86677083da850 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 16:05:00 -0700 Subject: [PATCH 108/662] Data ext doesn't need to touch the app obj --- .../middleman-core/core_extensions/data.rb | 20 +++++++++---------- .../lib/middleman-core/renderers/liquid.rb | 4 +++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 8fac7911..29bf3261 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -9,32 +9,32 @@ module Middleman # The regex which tells Middleman which files are for data MATCHER = /[\w-]+\.(yml|yaml|json)$/ + attr_reader :data_store + def initialize(app, options_hash={}, &block) super - app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' - # Directly include the #data method instead of using helpers so that this is available immediately - app.send :include, InstanceMethods + @data_store = DataStore.new(app) end def before_configuration + app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' + app.add_to_config_context :data, &method(:data_store) + # Setup data files before anything else so they are available when # parsing config.rb app.files.changed MATCHER do |file| - data.touch_file(file) if file.start_with?("#{config[:data_dir]}/") + extensions[:data].data_store.touch_file(file) if file.start_with?("#{config[:data_dir]}/") end app.files.deleted MATCHER do |file| - data.remove_file(file) if file.start_with?("#{config[:data_dir]}/") + extensions[:data].data_store.remove_file(file) if file.start_with?("#{config[:data_dir]}/") end end - module InstanceMethods - # The data object - # - # @return [DataStore] + helpers do def data - @_data ||= DataStore.new(self) + extensions[:data].data_store end end diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index 2085d939..e3d51417 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -11,11 +11,13 @@ module Middleman end def manipulate_resource_list(resources) + return resources unless app.extensions[:data] + resources.each do |resource| next unless resource.source_file =~ %r{\.liquid$} # Convert data object into a hash for liquid - resource.add_metadata locals: { data: app.data.to_h } + resource.add_metadata locals: { data: app.extensions[:data].data_store.to_h } end end end From 0ca6c37e5dd426876774587d4a418727849c0824 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 16:44:04 -0700 Subject: [PATCH 109/662] Remove App include in File Watcher --- middleman-cli/lib/middleman-cli/build.rb | 2 +- .../lib/middleman-core/core_extensions.rb | 12 +++++----- .../middleman-core/core_extensions/data.rb | 23 +++++++----------- .../core_extensions/file_watcher.rb | 24 +++++-------------- .../core_extensions/front_matter.rb | 9 ++++--- .../middleman-core/core_extensions/i18n.rb | 8 +++---- .../lib/middleman-core/extension.rb | 2 ++ .../sitemap/extensions/on_disk.rb | 4 ++-- .../step_definitions/middleman_steps.rb | 4 ++-- 9 files changed, 35 insertions(+), 53 deletions(-) diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index a08dd4d9..e6837604 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -192,7 +192,7 @@ module Middleman::Cli logger.debug '== Checking for generated images' # Double-check for generated images - @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) + @app.extensions[:file_watcher].api.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) @app.sitemap.ensure_resource_list_updated! # Sort paths to be built by the above order. This is primarily so Compass can diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index 1177eefe..ff7b0088 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -1,3 +1,9 @@ +# File Change Notifier +Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do + require 'middleman-core/core_extensions/file_watcher' + Middleman::CoreExtensions::FileWatcher +end + # Parse YAML from templates Middleman::Extensions.register :front_matter, auto_activate: :before_sitemap do require 'middleman-core/core_extensions/front_matter' @@ -17,12 +23,6 @@ Middleman::Extensions.register :show_exceptions, auto_activate: :before_configur Middleman::CoreExtensions::ShowExceptions end -# File Change Notifier -Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do - require 'middleman-core/core_extensions/file_watcher' - Middleman::CoreExtensions::FileWatcher -end - # External helpers looks in the helpers/ folder for helper modules Middleman::Extensions.register :external_helpers, auto_activate: :before_configuration do require 'middleman-core/core_extensions/external_helpers' diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 29bf3261..346d64f1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -6,30 +6,23 @@ module Middleman # The data extension parses YAML and JSON files in the `data/` directory # and makes them available to `config.rb`, templates and extensions class Data < Extension - # The regex which tells Middleman which files are for data - MATCHER = /[\w-]+\.(yml|yaml|json)$/ - attr_reader :data_store - def initialize(app, options_hash={}, &block) - super - - @data_store = DataStore.new(app) - end - def before_configuration + @data_store = DataStore.new(app) app.config.define_setting :data_dir, 'data', 'The directory data files are stored in' + app.add_to_config_context :data, &method(:data_store) + # The regex which tells Middleman which files are for data + data_file_matcher = /#{app.config[:data_dir]}\/(.*?)[\w-]+\.(yml|yaml|json)$/ + # Setup data files before anything else so they are available when # parsing config.rb - app.files.changed MATCHER do |file| - extensions[:data].data_store.touch_file(file) if file.start_with?("#{config[:data_dir]}/") - end + file_watcher.changed(data_file_matcher, &app.extensions[:data].data_store.method(:touch_file)) + file_watcher.deleted(data_file_matcher, &app.extensions[:data].data_store.method(:remove_file)) - app.files.deleted MATCHER do |file| - extensions[:data].data_store.remove_file(file) if file.start_with?("#{config[:data_dir]}/") - end + file_watcher.reload_path(app.config[:data_dir]) end helpers do 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 2b4e7002..8a3e0a9c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -24,31 +24,19 @@ module Middleman /^tmp\// ] - def initialize(app, options_hash={}, &block) - super - - app.config.define_setting :file_watcher_ignore, IGNORE_LIST, 'Regexes for paths that should be ignored when they change.' - - # Directly include the #files method instead of using helpers so that this is available immediately - app.send :include, InstanceMethods - end + attr_reader :api # Before parsing config, load the data/ directory def before_configuration - app.files.reload_path(app.config[:data_dir]) + app.config.define_setting :file_watcher_ignore, IGNORE_LIST, 'Regexes for paths that should be ignored when they change.' + + @api = API.new(app) + app.add_to_config_context :files, &method(:api) end def after_configuration app.config[:file_watcher_ignore] << %r{^#{app.config[:build_dir]}(\/|$)} - app.files.reload_path('.') - end - - module InstanceMethods - # Access the file api - # @return [Middleman::CoreExtensions::FileWatcher::API] - def files - @files_api ||= API.new(self) - end + @api.reload_path('.') end # Core File Change API class 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 13bb3361..712d5d6c 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -27,9 +27,8 @@ module Middleman::CoreExtensions end def before_configuration - ext = self - app.files.changed { |file| ext.clear_data(file) } - app.files.deleted { |file| ext.clear_data(file) } + file_watcher.changed(&method(:clear_data)) + file_watcher.deleted(&method(:clear_data)) end # Modify each resource to add data & options from frontmatter. @@ -74,7 +73,7 @@ module Middleman::CoreExtensions @cache[p] ||= begin data, content = frontmatter_and_content(p) - if app.files.exists?("#{path}.frontmatter") + if file_watcher.exists?("#{path}.frontmatter") external_data, _ = frontmatter_and_content("#{p}.frontmatter") data = external_data.deep_merge(data) end @@ -155,7 +154,7 @@ module Middleman::CoreExtensions data = {} - return [data, nil] if !app.files.exists?(full_path) || ::Middleman::Util.binary?(full_path) + return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path) content = File.read(full_path) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index b33322a7..3764fdc1 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -27,7 +27,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end def after_configuration - app.files.reload_path(app.config[:locales_dir] || options[:data]) + file_watcher.reload_path(app.config[:locales_dir] || options[:data]) @locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}') @locales_regex = convert_glob_to_regex(@locales_glob) @@ -42,8 +42,8 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # Don't output localizable files app.ignore File.join(options[:templates_dir], '**') - app.files.changed(&method(:on_file_changed)) - app.files.deleted(&method(:on_file_changed)) + file_watcher.changed(&method(:on_file_changed)) + file_watcher.deleted(&method(:on_file_changed)) end helpers do @@ -118,7 +118,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension if options[:langs] Array(options[:langs]).map(&:to_sym) else - known_langs = app.files.known_paths.select do |p| + known_langs = file_watcher.known_paths.select do |p| p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length == 2) end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index d2823632..96186848 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -178,6 +178,8 @@ module Middleman # @return [void] def_delegator :"::Middleman::Extension", :after_extension_activated + def_delegator :"@app.extensions[:file_watcher]", :api, :file_watcher + # Extensions are instantiated when they are activated. # @param [Class] klass The Middleman::Application class # @param [Hash] options_hash The raw options hash. Subclasses should not manipulate this directly - it will be turned into {#options}. diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 379bb996..a12ecf44 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -17,12 +17,12 @@ module Middleman @app.before_configuration do # Register file change callback - files.changed do |file| + extensions[:file_watcher].api.changed do |file| scoped_self.touch_file(file) end # Register file delete callback - files.deleted do |file| + extensions[:file_watcher].api.deleted do |file| scoped_self.remove_file(file) end end diff --git a/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb b/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb index 70dbcf44..b2101df4 100644 --- a/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb @@ -9,9 +9,9 @@ Then /^the file "([^\"]*)" is removed$/ do |path| end Then /^the file "([^\"]*)" did change$/ do |path| - @server_inst.files.did_change(path) + @server_inst.extensions[:file_watcher].api.did_change(path) end Then /^the file "([^\"]*)" did delete$/ do |path| - @server_inst.files.did_delete(path) + @server_inst.extensions[:file_watcher].api.did_delete(path) end From c94470d33f9d5d4e62cf14fbbe229fe8e013d4a4 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 16:50:19 -0700 Subject: [PATCH 110/662] get i18n's hands out of app too --- .../lib/middleman-core/core_extensions/i18n.rb | 18 ++---------------- .../lib/middleman-core/sitemap/store.rb | 4 ++-- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 3764fdc1..c5b8029b 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -7,9 +7,9 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension option :mount_at_root, nil, 'Mount a specific language at the root of the site' option :data, 'locales', 'The directory holding your locale configurations' - def initialize(app, options_hash={}, &block) - super + def_delegator :@app, :logger + def after_configuration # TODO # If :directory_indexes is already active, # throw a warning explaining the bug and telling the use @@ -23,10 +23,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension app.config.define_setting :locales_dir, 'locales', 'The directory holding your locale configurations' - app.send :include, LocaleHelpers - end - - def after_configuration file_watcher.reload_path(app.config[:locales_dir] || options[:data]) @locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}') @@ -52,8 +48,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end - def_delegator :@app, :logger - def langs @langs ||= known_languages end @@ -168,12 +162,4 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n.locale = old_locale p end - - module LocaleHelpers - # Access the list of languages supported by this Middleman application - # @return [Array] - def langs - extensions[:i18n].langs - end - end end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 203699af..a4330696 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -204,10 +204,10 @@ module Middleman # @param [String] path # @return [String] def strip_away_locale(path) - if @app.respond_to? :langs + if @app.extensions[:i18n] path_bits = path.split('.') lang = path_bits.last - return path_bits[0..-2].join('.') if @app.langs.include?(lang.to_sym) + return path_bits[0..-2].join('.') if @app.extensions[:i18n].langs.include?(lang.to_sym) end path From 6752a86b8318254776ba9cdc4b48640ddc665c34 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 12:14:58 -0700 Subject: [PATCH 111/662] Make our Rack pipeline a simple class abstracted from the App. --- middleman-cli/lib/middleman-cli/build.rb | 6 +- .../lib/middleman-core/application.rb | 109 ++++---- .../lib/middleman-core/config_context.rb | 12 + .../lib/middleman-core/configuration.rb | 16 -- .../middleman-core/core_extensions/request.rb | 263 ------------------ .../lib/middleman-core/extension.rb | 52 +--- .../lib/middleman-core/extension_manager.rb | 5 +- .../middleman-core/extensions/asset_hash.rb | 5 +- .../lib/middleman-core/meta_pages.rb | 10 +- .../lib/middleman-core/preview_server.rb | 15 +- middleman-core/lib/middleman-core/rack.rb | 138 +++++++++ .../step_definitions/server_steps.rb | 7 +- 12 files changed, 243 insertions(+), 395 deletions(-) delete mode 100644 middleman-core/lib/middleman-core/core_extensions/request.rb create mode 100644 middleman-core/lib/middleman-core/rack.rb diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index e6837604..87b8ea35 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -53,6 +53,7 @@ module Middleman::Cli require 'middleman-core' require 'middleman-core/logger' + require 'middleman-core/rack' require 'rack' require 'rack/mock' @@ -66,7 +67,7 @@ module Middleman::Cli verbose = options['verbose'] ? 0 : 1 instrument = options['instrument'] - app = ::Middleman::Application.server.inst do + app = ::Middleman::Application.new do config[:mode] = :build config[:environment] = env ::Middleman::Logger.singleton(verbose, instrument) @@ -118,7 +119,8 @@ module Middleman::Cli @to_clean = Set.new @logger = @app.logger - @rack = ::Rack::MockRequest.new(@app.class.to_rack_app) + rack_app = ::Middleman::Rack.new(@app).to_app + @rack = ::Rack::MockRequest.new(rack_app) super(base, @build_dir, config) end diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index a40158e9..fe262672 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -26,21 +26,38 @@ require 'middleman-core/config_context' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' -# Rack Request -require 'middleman-core/core_extensions/request' - # Core Middleman Class module Middleman class Application extend Forwardable - # Global configuration - include Configuration::Global + class << self + # Global configuration for the whole Middleman project. + # @return [ConfigurationManager] + def config + @config ||= ::Middleman::Configuration::ConfigurationManager.new + end + + # Root project directory (overwritten in middleman build/server) + # @return [String] + def root + ENV['MM_ROOT'] || Dir.pwd + end + + # Pathname-addressed root + def root_path + Pathname(root) + end + end # Uses callbacks include Hooks include Hooks::InstanceHooks + define_hook :initialized + define_hook :after_configuration + define_hook :before_configuration + # Before request hook define_hook :before @@ -56,19 +73,6 @@ module Middleman define_hook :before_render define_hook :after_render - # Root project directory (overwritten in middleman build/server) - # @return [String] - def self.root - ENV['MM_ROOT'] || Dir.pwd - end - def_delegator :"self.class", :root - - # Pathname-addressed root - def self.root_path - Pathname(root) - end - def_delegator :"self.class", :root_path - # Name of the source directory # @return [String] config.define_setting :source, 'source', 'Name of the source directory' @@ -158,44 +162,33 @@ module Middleman } }, 'Callbacks that can exclude paths from the sitemap' - define_hook :initialized - define_hook :instance_available - define_hook :after_configuration - define_hook :before_configuration - config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - # Basic Rack Request Handling - include Middleman::CoreExtensions::Request + attr_reader :config_context + attr_reader :sitemap + attr_reader :cache + attr_reader :template_context_class + attr_reader :config + attr_reader :generic_template_context + attr_reader :extensions + attr_reader :middleware + attr_reader :mappings # Reference to Logger singleton def_delegator :"::Middleman::Logger", :singleton, :logger - - # New container for config.rb commands - attr_reader :config_context - - # Reference to Sitemap - attr_reader :sitemap - - # Template cache - attr_reader :cache - - attr_reader :template_context_class - - # Hack to get a sandboxed copy of these helpers for overriding similar methods inside Markdown renderers. - attr_reader :generic_template_context + def_delegator :"::Middleman::Util", :instrument + def_delegators :"self.class", :root, :root_path def_delegators :@generic_template_context, :link_to, :image_tag, :asset_path - - attr_reader :extensions - + # Initialize the Middleman project def initialize(&block) - self.class.inst = self - # Search the root of the project for required files $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) + @middleware = [] + @mappings = [] + @template_context_class = Class.new(Middleman::TemplateContext) @generic_template_context = @template_context_class.new(self) @config_context = ConfigContext.new(self, @template_context_class) @@ -204,7 +197,8 @@ module Middleman ::Middleman::TemplateRenderer.cache.clear # Setup the default values from calls to set before initialization - self.class.config.load_settings(self.class.superclass.config.all_settings) + @config = ::Middleman::Configuration::ConfigurationManager.new + @config.load_settings(self.class.config.all_settings) @extensions = ::Middleman::ExtensionManager.new(self) @extensions.auto_activate(:before_sitemap) @@ -238,8 +232,6 @@ module Middleman evaluate_configuration(&block) - run_hook :instance_available - # This is for making the tests work - since the tests # don't completely reload middleman, I18n.load_path can get # polluted with paths from other test app directories that don't @@ -262,6 +254,9 @@ module Middleman config_context.execute_after_configuration_callbacks @extensions.activate_all + + run_hook :ready + @config_context.execute_ready_callbacks end def evaluate_configuration(&block) @@ -317,7 +312,21 @@ module Middleman File.join(root, config[:source]) end - def_delegator ::Middleman::Util, :instrument + # Use Rack middleware + # + # @param [Class] middleware Middleware module + # @return [void] + def use(middleware, *args, &block) + @middleware << [middleware, args, block] + end + + # Add Rack App mapped to specific path + # + # @param [String] map Path to map + # @return [void] + def map(map, &block) + @mappings << [map, block] + end # Work around this bug: http://bugs.ruby-lang.org/issues/4521 # where Ruby will call to_s/inspect while printing exception @@ -328,9 +337,5 @@ module Middleman end alias_method :inspect, :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s - # Hooks clones _hooks from the class to the instance. - # https://github.com/apotonick/hooks/blob/master/lib/hooks/instance_hooks.rb#L10 - # Middleman expects the same list of hooks for class and instance hooks: - def_delegator :"self.class", :_hooks end end diff --git a/middleman-core/lib/middleman-core/config_context.rb b/middleman-core/lib/middleman-core/config_context.rb index caeebd51..5c5ee42f 100644 --- a/middleman-core/lib/middleman-core/config_context.rb +++ b/middleman-core/lib/middleman-core/config_context.rb @@ -1,3 +1,5 @@ +require 'rack/mime' + module Middleman class ConfigContext extend Forwardable @@ -87,5 +89,15 @@ module Middleman config.define_setting(key, default) unless config.defines_setting?(key) @app.config[key] = block_given? ? block : default end + + # Add a new mime-type for a specific extension + # + # @param [Symbol] type File extension + # @param [String] value Mime type + # @return [void] + def mime_type(type, value) + type = ".#{type}" unless type.to_s[0] == '.' + ::Rack::Mime::MIME_TYPES[type] = value + end end end diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index 9678801d..a17382ce 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -1,21 +1,5 @@ module Middleman module Configuration - # Access to a global configuration manager for the whole Middleman project, - # plus backwards compatibility mechanisms for older Middleman projects. - module Global - def self.included(app) - app.send :extend, ClassMethods - app.send :def_delegator, :"self.class", :config - end - - module ClassMethods - # Global configuration for the whole Middleman project. - # @return [ConfigurationManager] - def config - @_config ||= ConfigurationManager.new - end - end - end # A class that manages a collection of documented settings. # Can be used by extensions as well as the main Middleman diff --git a/middleman-core/lib/middleman-core/core_extensions/request.rb b/middleman-core/lib/middleman-core/core_extensions/request.rb deleted file mode 100644 index c833a1ec..00000000 --- a/middleman-core/lib/middleman-core/core_extensions/request.rb +++ /dev/null @@ -1,263 +0,0 @@ -# Built on Rack -require 'rack' -require 'rack/file' -require 'rack/lint' -require 'rack/head' - -require 'middleman-core/util' -require 'middleman-core/template_renderer' - -module Middleman - module CoreExtensions - # Base helper to manipulate asset paths - module Request - # Extension registered - class << self - # @private - def included(app) - # CSSPIE HTC File - ::Rack::Mime::MIME_TYPES['.htc'] = 'text/x-component' - - # Let's serve all HTML as UTF-8 - ::Rack::Mime::MIME_TYPES['.html'] = 'text/html; charset=utf-8' - ::Rack::Mime::MIME_TYPES['.htm'] = 'text/html; charset=utf-8' - - app.extend ClassMethods - app.extend ServerMethods - - Middleman.extend CompatibleClassMethods - - # Include instance methods - app.send :include, InstanceMethods - end - end - - module ClassMethods - # Reset Rack setup - # - # @private - def reset! - @rack_app = nil - end - - # Get the static instance - # - # @private - # @return [Middleman::Application] - def inst(&block) - @inst ||= begin - mm = new(&block) - mm.run_hook :ready - mm.config_context.execute_ready_callbacks - mm - end - end - - # Set the shared instance - # - # @private - attr_writer :inst - - # Return built Rack app - # - # @private - # @return [Rack::Builder] - def to_rack_app(&block) - @rack_app ||= begin - app = ::Rack::Builder.new - app.use Rack::Lint - app.use Rack::Head - - Array(@middleware).each do |klass, options, middleware_block| - app.use(klass, *options, &middleware_block) - end - - inner_app = inst(&block) - app.map('/') { run inner_app } - - Array(@mappings).each do |path, map_block| - app.map(path, &map_block) - end - - app - end - end - - # Prototype app. Used in config.ru - # - # @private - # @return [Rack::Builder] - def prototype - reset! - to_rack_app - end - - # Call prototype, use in config.ru - # - # @private - def call(env) - prototype.call(env) - end - - # Use Rack middleware - # - # @param [Class] middleware Middleware module - # @return [void] - def use(middleware, *args, &block) - @middleware ||= [] - @middleware << [middleware, args, block] - end - - # Add Rack App mapped to specific path - # - # @param [String] map Path to map - # @return [void] - def map(map, &block) - @mappings ||= [] - @mappings << [map, block] - end - end - - module ServerMethods - # Create a new Class which is based on Middleman::Application - # Used to create a safe sandbox into which extensions and - # configuration can be included later without impacting - # other classes and instances. - # - # @return [Class] - def server(&block) - @servercounter ||= 0 - @servercounter += 1 - const_set("MiddlemanApplication#{@servercounter}", Class.new(Middleman::Application, &block)) - end - end - - module CompatibleClassMethods - # Create a new Class which is based on Middleman::Application - # Used to create a safe sandbox into which extensions and - # configuration can be included later without impacting - # other classes and instances. - # - # @return [Class] - def server(&block) - ::Middleman::Application.server(&block) - end - end - - # Methods to be mixed-in to Middleman::Application - module InstanceMethods - def self.included(app) - app.send :def_delegators, :"self.class", :use, :map - end - - def call(env) - dup.call!(env) - end - - # Rack Interface - # - # @param env Rack environment - def call!(env) - # Store environment, request and response for later - req = ::Rack::Request.new(env) - res = ::Rack::Response.new - - logger.debug "== Request: #{env['PATH_INFO']}" - - # Catch :halt exceptions and use that response if given - catch(:halt) do - process_request(env, req, res) - - res.status = 404 - - res.finish - end - end - - # Halt the current request and return a response - # - # @param [String] response Response value - def halt(response) - throw :halt, response - end - - # Core response method. We process the request, check with - # the sitemap, and return the correct file, response or status - # message. - # - # @param env - # @param [Rack::Response] res - def process_request(env, _, res) - start_time = Time.now - - request_path = URI.decode(env['PATH_INFO'].dup) - if request_path.respond_to? :force_encoding - request_path.force_encoding('UTF-8') - end - request_path = ::Middleman::Util.full_path(request_path, self) - - # Run before callbacks - run_hook :before - - # Get the resource object for this path - resource = sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20')) - - # Return 404 if not in sitemap - return not_found(res, request_path) unless resource && !resource.ignored? - - # If this path is a binary file, send it immediately - return send_file(resource, env) if resource.binary? - - res['Content-Type'] = resource.content_type || 'text/plain' - - begin - # Write out the contents of the page - res.write resource.render - - # Valid content is a 200 status - res.status = 200 - rescue Middleman::TemplateRenderer::TemplateNotFound => e - res.write "Error: #{e.message}" - res.status = 500 - end - - # End the request - logger.debug "== Finishing Request: #{resource.destination_path} (#{(Time.now - start_time).round(2)}s)" - halt res.finish - end - - # Add a new mime-type for a specific extension - # - # @param [Symbol] type File extension - # @param [String] value Mime type - # @return [void] - def mime_type(type, value) - type = ".#{type}" unless type.to_s[0] == '.' - ::Rack::Mime::MIME_TYPES[type] = value - end - - # Halt request and return 404 - def not_found(res, path) - res.status = 404 - res.write "

File Not Found

#{path}

" - res.finish - end - - # Immediately send static file - def send_file(resource, env) - file = ::Rack::File.new nil - file.path = resource.source_file - response = file.serving(env) - status = response[0] - response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext) - # Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise - # Rack will throw an error (500) - if !(100..199).include?(status) && ![204, 205, 304].include?(status) - response[1]['Content-Type'] = resource.content_type || 'application/octet-stream' - end - halt response - end - end - end - end -end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 96186848..713a12c0 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -53,7 +53,6 @@ module Middleman # * {#after_configuration} # * {#after_build} # * {#before_build} - # * {#instance_available} # # There are also some less common hooks that can be listened to from within an extension's `initialize` method: # @@ -181,16 +180,15 @@ module Middleman def_delegator :"@app.extensions[:file_watcher]", :api, :file_watcher # Extensions are instantiated when they are activated. - # @param [Class] klass The Middleman::Application class + # @param [Middleman::Application] app The Middleman::Application instance # @param [Hash] options_hash The raw options hash. Subclasses should not manipulate this directly - it will be turned into {#options}. # @yield An optional block that can be used to customize options before the extension is activated. # @yieldparam [Middleman::Configuration::ConfigurationManager] options Extension options - def initialize(klass, options_hash={}, &block) + def initialize(app, options_hash={}, &block) @_helpers = [] - @klass = klass + @app = app setup_options(options_hash, &block) - setup_app_reference_when_available # Bind app hooks to local methods bind_before_configuration @@ -216,10 +214,6 @@ module Middleman # Respond to the `after_build` event. # If an `after_build` method is implemented, that method will be run after the builder runs. - # @!method instance_available - # Respond to the `instance_available` event. - # If an `instance_available` method is implemented, that method will be run after `config.rb` is run and after environment-specific config blocks have been run, but before any `after_configuration` callbacks. - # @!method manipulate_resource_list(resources) # Manipulate the resource list by transforming or adding {Sitemap::Resource}s. # Sitemap manipulation is a powerful way of interacting with a project, since it can modify each {Sitemap::Resource} or generate new {Sitemap::Resources}. This method is used in a pipeline where each sitemap manipulator is run in turn, with each one being fed the output of the previous manipulator. See the source of built-in Middleman extensions like {Middleman::Extensions::DirectoryIndexes} and {Middleman::Extensions::AssetHash} for examples of how to use this. @@ -230,20 +224,6 @@ module Middleman # @param [Array] resources A list of all the resources known to the sitemap. # @return [Array] The transformed list of resources. - # Assign the app instance. Used internally. - # @api private - def app=(app) - @app = app - - ext = self - - return unless ext.respond_to?(:instance_available) - - @klass.instance_available do - ext.instance_available - end - end - private # @yield An optional block that can be used to customize options before the extension is activated. @@ -259,30 +239,14 @@ module Middleman yield @options if block_given? end - def setup_app_reference_when_available - ext = self - - @klass.initialized do - ext.app = self - end - - @klass.instance_available do - ext.app ||= self - end - end - def bind_before_configuration - ext = self - return unless ext.respond_to?(:before_configuration) - - @klass.before_configuration do - ext.before_configuration - end + return unless respond_to?(:before_configuration) + @app.before_configuration(&method(:before_configuration)) end def bind_after_configuration ext = self - @klass.after_configuration do + @app.after_configuration do ext.after_configuration if ext.respond_to?(:after_configuration) if ext.respond_to?(:manipulate_resource_list) @@ -295,7 +259,7 @@ module Middleman ext = self return unless ext.respond_to?(:before_build) - @klass.before_build do |builder| + @app.before_build do |builder| if ext.method(:before_build).arity == 1 ext.before_build(builder) else @@ -308,7 +272,7 @@ module Middleman ext = self return unless ext.respond_to?(:after_build) - @klass.after_build do |builder| + @app.after_build do |builder| if ext.method(:after_build).arity == 1 ext.after_build(builder) else diff --git a/middleman-core/lib/middleman-core/extension_manager.rb b/middleman-core/lib/middleman-core/extension_manager.rb index e05a5d24..0356f0bd 100644 --- a/middleman-core/lib/middleman-core/extension_manager.rb +++ b/middleman-core/lib/middleman-core/extension_manager.rb @@ -1,6 +1,7 @@ module Middleman class ExtensionManager extend Forwardable + def_delegator :@app, :logger def_delegators :@activated, :[] @@ -44,11 +45,11 @@ module Middleman if extension.supports_multiple_instances? @activated[ext_name] ||= {} key = "instance_#{@activated[ext_name].keys.length}" - @activated[ext_name][key] = extension.new(@app.class, options, &block) + @activated[ext_name][key] = extension.new(@app, options, &block) elsif @activated.key?(ext_name) raise "#{ext_name} has already been activated and cannot be re-activated." else - @activated[ext_name] = extension.new(@app.class, options, &block) + @activated[ext_name] = extension.new(@app, options, &block) end end diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index 3fa5e9ea..fb277adf 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -45,7 +45,10 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension # Update the main sitemap resource list # @return [void] def manipulate_resource_list(resources) - @rack_client = ::Rack::MockRequest.new(app.class.to_rack_app) + @rack_client ||= begin + rack_app = ::Middleman::Rack.new(app).to_app + ::Rack::MockRequest.new(rack_app) + end # Process resources in order: binary images and fonts, then SVG, then JS/CSS. # This is so by the time we get around to the text files (which may reference diff --git a/middleman-core/lib/middleman-core/meta_pages.rb b/middleman-core/lib/middleman-core/meta_pages.rb index c21f25d7..cd789ef1 100644 --- a/middleman-core/lib/middleman-core/meta_pages.rb +++ b/middleman-core/lib/middleman-core/meta_pages.rb @@ -17,9 +17,9 @@ module Middleman @middleman = middleman meta_pages = self - @rack_app = Rack::Builder.new do + @rack_app = ::Rack::Builder.new do # Serve assets from metadata/assets - use Rack::Static, urls: ['/assets'], root: File.join(File.dirname(__FILE__), 'meta_pages') + use ::Rack::Static, urls: ['/assets'], root: File.join(File.dirname(__FILE__), 'meta_pages') map '/' do run meta_pages.method(:index) @@ -46,7 +46,7 @@ module Middleman # Inspect the sitemap def sitemap(_) - resources = @middleman.inst.sitemap.resources(true) + resources = @middleman.sitemap.resources(true) sitemap_tree = SitemapTree.new @@ -59,10 +59,10 @@ module Middleman # Inspect configuration def config(_) - global_config = @middleman.inst.config.all_settings.map { |c| ConfigSetting.new(c) } + global_config = @middleman.config.all_settings.map { |c| ConfigSetting.new(c) } extension_config = {} - @middleman.inst.extensions.each do |ext_name, extension| + @middleman.extensions.each do |ext_name, extension| next if ::Middleman::Extension.auto_activated.include? ext_name if extension.is_a?(Hash) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 301b1b69..577a0c1b 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -1,6 +1,7 @@ require 'webrick' require 'middleman-core/meta_pages' require 'middleman-core/logger' +require 'middleman-core/rack' # rubocop:disable GlobalVars module Middleman @@ -100,17 +101,17 @@ module Middleman opts[:instrumenting] || false ) - server = ::Middleman::Application.server + app = ::Middleman::Application.new do + config[:environment] = opts[:environment].to_sym if opts[:environment] + end # Add in the meta pages application - meta_app = Middleman::MetaPages::Application.new(server) - server.map '/__middleman' do + meta_app = Middleman::MetaPages::Application.new(app) + app.map '/__middleman' do run meta_app end - @app = server.inst do - config[:environment] = opts[:environment].to_sym if opts[:environment] - end + app end def start_file_watcher @@ -197,7 +198,7 @@ module Middleman start_file_watcher - rack_app = app.class.to_rack_app + rack_app = ::Middleman::Rack.new(@app).to_app @webrick.mount '/', ::Rack::Handler::WEBrick, rack_app end diff --git a/middleman-core/lib/middleman-core/rack.rb b/middleman-core/lib/middleman-core/rack.rb new file mode 100644 index 00000000..3d540685 --- /dev/null +++ b/middleman-core/lib/middleman-core/rack.rb @@ -0,0 +1,138 @@ +require 'rack' +require 'rack/file' +require 'rack/lint' +require 'rack/head' + +require 'middleman-core/util' +require 'middleman-core/template_renderer' + +# CSSPIE HTC File +::Rack::Mime::MIME_TYPES['.htc'] = 'text/x-component' + +# Let's serve all HTML as UTF-8 +::Rack::Mime::MIME_TYPES['.html'] = 'text/html; charset=utf-8' +::Rack::Mime::MIME_TYPES['.htm'] = 'text/html; charset=utf-8' + +module Middleman + class Rack + extend Forwardable + + def to_app + app = ::Rack::Builder.new + + app.use ::Rack::Lint + app.use ::Rack::Head + + @middleman.middleware.each do |klass, options, middleware_block| + app.use(klass, *options, &middleware_block) + end + + inner_app = self + app.map('/') { run inner_app } + + @middleman.mappings.each do |path, map_block| + app.map(path, &map_block) + end + + app + end + + def_delegator :"::Middleman::Logger", :singleton, :logger + + def initialize(middleman) + @middleman = middleman + end + + # Rack Interface + # + # @param env Rack environment + def call(env) + # Store environment, request and response for later + req = ::Rack::Request.new(env) + res = ::Rack::Response.new + + logger.debug "== Request: #{env['PATH_INFO']}" + + # Catch :halt exceptions and use that response if given + catch(:halt) do + process_request(env, req, res) + res.status = 404 + res.finish + end + end + + # Halt the current request and return a response + # + # @param [String] response Response value + def halt(response) + throw :halt, response + end + + # Core response method. We process the request, check with + # the sitemap, and return the correct file, response or status + # message. + # + # @param env + # @param [Rack::Response] res + def process_request(env, _, res) + start_time = Time.now + + request_path = URI.decode(env['PATH_INFO'].dup) + if request_path.respond_to? :force_encoding + request_path.force_encoding('UTF-8') + end + request_path = ::Middleman::Util.full_path(request_path, @middleman) + + # Run before callbacks + @middleman.run_hook :before + + # Get the resource object for this path + resource = @middleman.sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20')) + + # Return 404 if not in sitemap + return not_found(res, request_path) unless resource && !resource.ignored? + + # If this path is a binary file, send it immediately + return send_file(resource, env) if resource.binary? + + res['Content-Type'] = resource.content_type || 'text/plain' + + begin + # Write out the contents of the page + res.write resource.render + + # Valid content is a 200 status + res.status = 200 + rescue Middleman::TemplateRenderer::TemplateNotFound => e + res.write "Error: #{e.message}" + res.status = 500 + end + + # End the request + logger.debug "== Finishing Request: #{resource.destination_path} (#{(Time.now - start_time).round(2)}s)" + halt res.finish + end + + # Halt request and return 404 + def not_found(res, path) + res.status = 404 + res.write "

File Not Found

#{path}

" + res.finish + end + + # Immediately send static file + def send_file(resource, env) + file = ::Rack::File.new nil + file.path = resource.source_file + response = file.serving(env) + status = response[0] + response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext) + # Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise + # Rack will throw an error (500) + if !(100..199).include?(status) && ![204, 205, 304].include?(status) + response[1]['Content-Type'] = resource.content_type || 'application/octet-stream' + end + halt response + end + end +end 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 94905abe..470a46b1 100644 --- a/middleman-core/lib/middleman-core/step_definitions/server_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/server_steps.rb @@ -1,6 +1,7 @@ # encoding: UTF-8 require 'rack/mock' +require 'middleman-core/rack' Given /^a clean server$/ do @initialize_commands = [] @@ -43,14 +44,14 @@ Given /^the Server is running$/ do initialize_commands = @initialize_commands || [] initialize_commands.unshift lambda { config[:show_exceptions] = false } - @server_inst = Middleman::Application.server.inst do + @server_inst = ::Middleman::Application.new do initialize_commands.each do |p| instance_exec(&p) end end - app_rack = @server_inst.class.to_rack_app - @browser = ::Rack::MockRequest.new(app_rack) + rack = ::Middleman::Rack.new(@server_inst) + @browser = ::Rack::MockRequest.new(rack.to_app) end Given /^the Server is running at "([^\"]*)"$/ do |app_path| From c8248071193882bd313e35d8839824ea6986339d Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Sun, 6 Jul 2014 02:15:44 +0100 Subject: [PATCH 112/662] Update badges --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4bb81bad..b88d75c9 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,12 @@ Additionally, up-to-date generated code documentation is available on [RubyDoc]. ## Build & Dependency Status -[![Gem Version](https://badge.fury.io/rb/middleman.png)][gem] -[![Build Status](https://travis-ci.org/middleman/middleman.png)][travis] -[![Code Coverage](https://coveralls.io/repos/middleman/middleman/badge.png)][coveralls] -[![Dependency Status](https://gemnasium.com/middleman/middleman.png?travis)][gemnasium] -[![Code Quality](https://codeclimate.com/github/middleman/middleman.png)][codeclimate] +[![Gem Version](http://img.shields.io/gem/v/middleman.svg?style=flat)][gem] +[![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)][license] +[![Dependency Status](http://img.shields.io/gemnasium/middleman/middleman.svg?style=flat)][gemnasium] +[![Build Status](http://img.shields.io/travis/middleman/middleman.svg?style=flat)][travis] +[![Code Coverage](http://img.shields.io/coveralls/middleman/middleman.svg?style=flat)][coveralls] +[![Code Quality](http://img.shields.io/codeclimate/github/middleman/middleman.svg?style=flat)][codeclimate] ## Community From 13acee8fd5ff8fb5890de9ba0b2f0ffd6bcaebd8 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 18:26:51 -0700 Subject: [PATCH 113/662] Reload MM on environment and helpers_dir changes. Closes #1274. Closes #1105 --- middleman-core/lib/middleman-core/preview_server.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index 301b1b69..62f82ad9 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -127,7 +127,7 @@ module Middleman # See if the changed file is config.rb or lib/*.rb if needs_to_reload?(added_and_modified + removed) - @mm_reload = true + $mm_reload = true @webrick.stop else added_and_modified.each do |path| @@ -213,9 +213,10 @@ module Middleman # @return [Boolean] Whether the server needs to reload def needs_to_reload?(paths) match_against = [ - %r{^config\.rb}, - %r{^lib/[^\.](.*)\.rb$}, - %r{^helpers/[^\.](.*)\.rb$} + %r{^/config\.rb}, + %r{^/environments/[^\.](.*)\.rb$}, + %r{^/lib/[^\.](.*)\.rb$}, + %r{^/#{@app.config[:helpers_dir]}/[^\.](.*)\.rb$} ] if @options[:reload_paths] @@ -226,7 +227,7 @@ module Middleman paths.any? do |path| match_against.any? do |matcher| - path =~ matcher + path.sub(@app.root, '').match matcher end end end From 605bd4ca2408da7fc59ed82524f613445e7220e3 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 18:35:39 -0700 Subject: [PATCH 114/662] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b88d75c9..152f55e2 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Additionally, up-to-date generated code documentation is available on [RubyDoc]. [![Build Status](http://img.shields.io/travis/middleman/middleman.svg?style=flat)][travis] [![Code Coverage](http://img.shields.io/coveralls/middleman/middleman.svg?style=flat)][coveralls] [![Code Quality](http://img.shields.io/codeclimate/github/middleman/middleman.svg?style=flat)][codeclimate] +[![Gittip](http://img.shields.io/gittip/middleman.svg?style=flat)][gittip] ## Community @@ -116,6 +117,7 @@ Copyright (c) 2010-2013 Thomas Reynolds. MIT Licensed, see [LICENSE] for details [coveralls]: https://coveralls.io/r/middleman/middleman [gemnasium]: https://gemnasium.com/middleman/middleman [codeclimate]: https://codeclimate.com/github/middleman/middleman +[gittip]: https://www.gittip.com/middleman/ [rubyinstaller]: http://rubyinstaller.org/ [rubydoc]: http://rubydoc.info/github/middleman/middleman [LICENSE]: https://github.com/middleman/middleman/blob/master/LICENSE.md From ffa8415aafaf9918a84f1bca3adc49d5a71ae08f Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 18:42:15 -0700 Subject: [PATCH 115/662] bump aruba dep --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 4c721ffa..e0243795 100644 --- a/Gemfile +++ b/Gemfile @@ -1,13 +1,13 @@ source 'https://rubygems.org' # Build and doc tools -gem 'rake', '~> 10.0.3', require: false +gem 'rake', '~> 10.3.2', require: false gem 'yard', '~> 0.8.0', require: false # Test tools gem 'cucumber', '~> 1.3.1' gem 'fivemat', '~> 1.2.1' -gem 'aruba', '~> 0.5.1' +gem 'aruba', '~> 0.6.0' gem 'rspec', '~> 2.12' gem 'simplecov' From a19c1cbecc8a424f7e653d112d78c2562537bde7 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sat, 5 Jul 2014 18:46:39 -0700 Subject: [PATCH 116/662] refer to v4 in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a753fcad..deea91eb 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ introduced with new major versions. As a result of this policy, you can (and should) specify a dependency on this gem using the [Pessimistic Version Constraint][pvc] with two digits of precision. For example: - spec.add_dependency 'middleman-core', '~> 3.0' + spec.add_dependency 'middleman-core', '~> 4.0' [semver]: http://semver.org/ [pvc]: http://docs.rubygems.org/read/chapter/16#page74 From 21c2b737f5fee5f46821b27f4dcae6f07f05dd35 Mon Sep 17 00:00:00 2001 From: Eliott Appleford Date: Sun, 6 Jul 2014 04:02:43 +0100 Subject: [PATCH 117/662] fix gzip spec --- middleman-core/features/gzip.feature | 4 +--- .../lib/middleman-core/step_definitions/builder_steps.rb | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/middleman-core/features/gzip.feature b/middleman-core/features/gzip.feature index 93955a49..18669476 100644 --- a/middleman-core/features/gzip.feature +++ b/middleman-core/features/gzip.feature @@ -1,4 +1,3 @@ -@nowindows Feature: GZIP assets during build Scenario: Built assets should be gzipped @@ -10,8 +9,7 @@ Feature: GZIP assets during build | build/javascripts/test.js.gz | | build/stylesheets/test.css | | build/stylesheets/test.css.gz | - When I run `file build/javascripts/test.js.gz` - Then the output should contain "gzip" + And build/javascripts/test.js.gz should be binary Scenario: Preview server doesn't change Given the Server is running at "gzip-app" diff --git a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb index eda6467b..ce942284 100644 --- a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb @@ -71,3 +71,7 @@ end Then /^the file "([^"]*)" should contain '([^']*)'$/ do |file, partial_content| check_file_content(file, partial_content, true) end + +And /(.*) should be binary/ do |file| + expect(File.binread(File.join(current_dir, file), 2)).to eq(['1F8B'].pack('H*')) +end From 0cbc232dac43584d0523ee3cd4b245603e9edcd9 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 3 Jul 2014 19:44:26 -0700 Subject: [PATCH 118/662] Remove neighbor frontmatter support --- .../frontmatter-neighbor-app/config.rb | 27 +++++++ .../config.rb | 28 +++++++ .../core_extensions/front_matter.rb | 81 ++++++++----------- .../middleman-core/core_extensions/routing.rb | 2 - .../lib/middleman-core/sitemap/resource.rb | 2 +- 5 files changed, 90 insertions(+), 50 deletions(-) diff --git a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb index e69de29b..234b9a20 100644 --- a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb @@ -0,0 +1,27 @@ +ignore '*.frontmatter' + +# Reads neighbor for every file on every refresh. +# TODO: Optimize +class NeighborFrontmatter < ::Middleman::Extension + self.resource_list_manipulator_priority = 81 + + def manipulate_resource_list(resources) + resources.each do |resource| + next unless resource.source_file + + neighbor = "#{resource.source_file}.frontmatter" + if File.exists?(neighbor) + fmdata = app.extensions[:front_matter].frontmatter_and_content(neighbor).first + opts = fmdata.extract!(:layout, :layout_engine, :renderer_options, :directory_index, :content_type) + opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options) + ignored = fmdata.delete(:ignored) + resource.add_metadata options: opts, page: fmdata + resource.ignore! if ignored == true && !resource.proxy? + end + end + end +end + +Middleman::Extensions.register :neighbor_frontmatter, NeighborFrontmatter unless Middleman::Extensions.registered.include? :neighbor_frontmatter + +activate :neighbor_frontmatter diff --git a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb index a5e8129a..4318d2fd 100644 --- a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb @@ -2,3 +2,31 @@ proxy 'proxied.html', 'ignored.html' page 'override_layout.html', layout: :alternate page 'page_mentioned.html' + +ignore '*.frontmatter' + +# Reads neighbor for every file on every refresh. +# TODO: Optimize +class NeighborFrontmatter < ::Middleman::Extension + self.resource_list_manipulator_priority = 81 + + def manipulate_resource_list(resources) + resources.each do |resource| + next unless resource.source_file + + neighbor = "#{resource.source_file}.frontmatter" + if File.exists?(neighbor) + fmdata = app.extensions[:front_matter].frontmatter_and_content(neighbor).first + opts = fmdata.extract!(:layout, :layout_engine, :renderer_options, :directory_index, :content_type) + opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options) + ignored = fmdata.delete(:ignored) + resource.add_metadata options: opts, page: fmdata + resource.ignore! if ignored == true && !resource.proxy? + end + end + end +end + +Middleman::Extensions.register :neighbor_frontmatter, NeighborFrontmatter unless Middleman::Extensions.registered.include? :neighbor_frontmatter + +activate :neighbor_frontmatter 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 712d5d6c..546bc761 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -57,10 +57,6 @@ module Middleman::CoreExtensions end end - def after_configuration - app.ignore %r{\.frontmatter$} - end - # Get the template data from a path # @param [String] path # @return [String] @@ -70,16 +66,7 @@ module Middleman::CoreExtensions def data(path) p = normalize_path(path) - @cache[p] ||= begin - data, content = frontmatter_and_content(p) - - if file_watcher.exists?("#{path}.frontmatter") - external_data, _ = frontmatter_and_content("#{p}.frontmatter") - data = external_data.deep_merge(data) - end - - [data, content] - end + @cache[p] ||= frontmatter_and_content(p) end def clear_data(file) @@ -88,11 +75,43 @@ module Middleman::CoreExtensions file = File.join(app.root, file) prefix = app.source_dir.sub(/\/$/, '') + '/' return unless file.include?(prefix) - path = file.sub(prefix, '').sub(/\.frontmatter$/, '') + path = file.sub(prefix, '') @cache.delete(path) end + # Get the frontmatter and plain content from a file + # @param [String] path + # @return [Array] + def frontmatter_and_content(path) + full_path = if Pathname(path).relative? + File.join(app.source_dir, path) + else + path + end + + data = {} + + return [data, nil] if !app.files.exists?(full_path) || ::Middleman::Util.binary?(full_path) + + content = File.read(full_path) + + begin + if content =~ /\A.*coding:/ + lines = content.split(/\n/) + lines.shift + content = lines.join("\n") + end + + result = parse_yaml_front_matter(content, full_path) || parse_json_front_matter(content, full_path) + return result if result + rescue + # Probably a binary file, move on + end + + [data, content] + end + private # Parse YAML frontmatter out of a string @@ -142,38 +161,6 @@ module Middleman::CoreExtensions [{}, content] end - # Get the frontmatter and plain content from a file - # @param [String] path - # @return [Array] - def frontmatter_and_content(path) - full_path = if Pathname(path).relative? - File.join(app.source_dir, path) - else - path - end - - data = {} - - return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path) - - content = File.read(full_path) - - begin - if content =~ /\A.*coding:/ - lines = content.split(/\n/) - lines.shift - content = lines.join("\n") - end - - result = parse_yaml_front_matter(content, full_path) || parse_json_front_matter(content, full_path) - return result if result - rescue - # Probably a binary file, move on - end - - [data, content] - end - def normalize_path(path) path.sub(%r{^#{Regexp.escape(app.source_dir)}\/}, '') end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index b7f4ee52..24539ce0 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -45,8 +45,6 @@ module Middleman options = opts.dup # Default layout - # TODO: This seems wrong - options[:layout] = @app.config[:layout] if options[:layout].nil? metadata = { options: options, locals: options.delete(:locals) || {}, diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 97b4e832..3ccc9895 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -136,7 +136,7 @@ module Middleman # # @return [Boolean] def binary? - ::Middleman::Util.binary?(source_file) + source_file && ::Middleman::Util.binary?(source_file) end end end From bf4310697d147623fda2df8719851868ab206375 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Thu, 3 Jul 2014 20:41:44 -0700 Subject: [PATCH 119/662] Move proxy/ignore/content_type Resource methods into the Resource class --- .../sitemap/extensions/content_type.rb | 16 ---- .../sitemap/extensions/ignores.rb | 22 ----- .../sitemap/extensions/redirects.rb | 9 --- .../sitemap/extensions/request_endpoints.rb | 9 --- .../lib/middleman-core/sitemap/resource.rb | 81 ++++++++++++++++++- 5 files changed, 79 insertions(+), 58 deletions(-) delete mode 100644 middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb b/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb deleted file mode 100644 index 23325012..00000000 --- a/middleman-core/lib/middleman-core/sitemap/extensions/content_type.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'rack' - -module Middleman::Sitemap::Extensions - # Content type is implemented as a module so it can be overridden by other sitemap extensions - module ContentType - # The preferred MIME content type for this resource - def content_type - # Allow explcitly setting content type from page/proxy options or frontmatter - meta_type = options[:content_type] - return meta_type if meta_type - - # Look up mime type based on extension - ::Rack::Mime.mime_type(ext, nil) - end - end -end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 9ca344a2..b77f0e19 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -12,7 +12,6 @@ module Middleman @ignored_callbacks = [] sitemap.define_singleton_method :ignored?, &method(:ignored?) - ::Middleman::Sitemap::Resource.send :include, IgnoreResourceInstanceMethods end # Ignore a path or add an ignore callback @@ -45,27 +44,6 @@ module Middleman @ignored_callbacks.any? { |b| b.call(path_clean) } end end - - # Helpers methods for Resources - module IgnoreResourceInstanceMethods - # Ignore a resource directly, without going through the whole - # ignore filter stuff. - def ignore! - @ignored = true - end - - # Whether the Resource is ignored - # @return [Boolean] - def ignored? - return true if @ignored - - # Ignore based on the source path (without template extensions) - return true if @app.sitemap.ignored?(path) - - # This allows files to be ignored by their source file name (with template extensions) - @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) - end - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index 3f4dafd1..d6b79045 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -75,18 +75,9 @@ module Middleman end end - def binary? - false - end - def ignored? false end - - # rubocop:disable AccessorMethodName - def get_source_file - '' - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 4f5a646e..8d555fa6 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -64,18 +64,9 @@ module Middleman return output.call if output end - def binary? - false - end - def ignored? false end - - # rubocop:disable AccessorMethodName - def get_source_file - '' - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index 3ccc9895..a7bf56e9 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -1,5 +1,5 @@ +require 'rack/mime' require 'middleman-core/sitemap/extensions/traversal' -require 'middleman-core/sitemap/extensions/content_type' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' @@ -9,7 +9,6 @@ module Middleman # Sitemap Resource class class Resource include Middleman::Sitemap::Extensions::Traversal - include Middleman::Sitemap::Extensions::ContentType # The source path of this resource (relative to the source directory, # without template extensions) @@ -25,6 +24,18 @@ module Middleman # @return [String] alias_method :request_path, :destination_path + # Get the on-disk source file for this resource + # @return [String] + def source_file + if @source_file + @source_file + elsif proxy? + proxied_to_resource.source_file + else + nil + end + end + # Initialize resource with parent store and URL # @param [Middleman::Sitemap::Store] store # @param [String] path @@ -138,6 +149,72 @@ module Middleman def binary? source_file && ::Middleman::Util.binary?(source_file) end + + # Ignore a resource directly, without going through the whole + # ignore filter stuff. + # @return [void] + def ignore! + @ignored = true + end + + # Whether the Resource is ignored + # @return [Boolean] + def ignored? + return true if @ignored + # Ignore based on the source path (without template extensions) + return true if @app.sitemap.ignored?(path) + # This allows files to be ignored by their source file name (with template extensions) + !proxy? && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) + end + + # The preferred MIME content type for this resource based on extension or metadata + # @return [String] MIME type for this resource + def content_type + mime_type = options[:content_type] || ::Rack::Mime.mime_type(ext, nil) + return mime_type if mime_type + + if proxy? + proxied_to_resource.content_type + else + nil + end + end + + # Whether this page is a proxy + # @return [Boolean] + def proxy? + @proxied_to + end + + # Set this page to proxy to a target path + # @param [String] target + # @return [void] + def proxy_to(target) + target = ::Middleman::Util.normalize_path(target) + raise "You can't proxy #{path} to itself!" if target == path + @proxied_to = target + end + + # The path of the page this page is proxied to, or nil if it's not proxied. + # @return [String] + attr_reader :proxied_to + + # The resource for the page this page is proxied to. Throws an exception + # if there is no resource. + # @return [Sitemap::Resource] + def proxied_to_resource + proxy_resource = @store.find_resource_by_path(proxied_to) + + unless proxy_resource + raise "Path #{path} proxies to unknown file #{proxied_to}:#{@store.resources.map(&:path)}" + end + + if proxy_resource.proxy? + raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy." + end + + proxy_resource + end end end end From f47a58633224fd5301218e876cd7f6fb5a96b9b6 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 7 Jul 2014 09:51:23 -0700 Subject: [PATCH 120/662] no longer need warning --- middleman-core/lib/middleman-core/core_extensions/i18n.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index c5b8029b..d62d15cb 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -10,11 +10,6 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension def_delegator :@app, :logger def after_configuration - # TODO - # If :directory_indexes is already active, - # throw a warning explaining the bug and telling the use - # to reverse the order. - # See https://github.com/svenfuchs/i18n/wiki/Fallbacks unless options[:no_fallbacks] require 'i18n/backend/fallbacks' From a1fe810a50076792e3abe05bdc427e6aad7c1ee6 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 7 Jul 2014 22:12:44 -0700 Subject: [PATCH 121/662] Fixup after rebase --- .../frontmatter-neighbor-app/config.rb | 2 +- .../config.rb | 2 +- .../core_extensions/front_matter.rb | 2 +- .../sitemap/extensions/proxies.rb | 14 +--- .../lib/middleman-core/sitemap/resource.rb | 70 ++----------------- 5 files changed, 10 insertions(+), 80 deletions(-) diff --git a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb index 234b9a20..50a368eb 100644 --- a/middleman-core/fixtures/frontmatter-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-neighbor-app/config.rb @@ -16,7 +16,7 @@ class NeighborFrontmatter < ::Middleman::Extension opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options) ignored = fmdata.delete(:ignored) resource.add_metadata options: opts, page: fmdata - resource.ignore! if ignored == true && !resource.proxy? + resource.ignore! if ignored == true && !resource.is_a?(::Middleman::Sitemap::ProxyResource) end end end diff --git a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb index 4318d2fd..600b96f8 100644 --- a/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb +++ b/middleman-core/fixtures/frontmatter-settings-neighbor-app/config.rb @@ -21,7 +21,7 @@ class NeighborFrontmatter < ::Middleman::Extension opts[:renderer_options].symbolize_keys! if opts.key?(:renderer_options) ignored = fmdata.delete(:ignored) resource.add_metadata options: opts, page: fmdata - resource.ignore! if ignored == true && !resource.proxy? + resource.ignore! if ignored == true && !resource.is_a?(::Middleman::Sitemap::ProxyResource) end 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 546bc761..72412398 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -92,7 +92,7 @@ module Middleman::CoreExtensions data = {} - return [data, nil] if !app.files.exists?(full_path) || ::Middleman::Util.binary?(full_path) + return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path) content = File.read(full_path) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index b9abe44e..9acce571 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -119,8 +119,7 @@ module Middleman resource end - # rubocop:disable AccessorMethodName - def get_source_file + def source_file target_resource.source_file end @@ -130,17 +129,6 @@ module Middleman target_resource.content_type end - - # Whether the Resource is ignored - # @return [Boolean] - def ignored? - return true if @ignored - - # Ignore based on the source path (without template extensions) - return true if @app.sitemap.ignored?(path) - - false - end end end end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index a7bf56e9..fdd57b00 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -19,23 +19,15 @@ module Middleman # @return [String] attr_accessor :destination_path + # The on-disk source file for this resource, if there is one + # @return [String] + attr_reader :source_file + # The path to use when requesting this resource. Normally it's # the same as {#destination_path} but it can be overridden in subclasses. # @return [String] alias_method :request_path, :destination_path - # Get the on-disk source file for this resource - # @return [String] - def source_file - if @source_file - @source_file - elsif proxy? - proxied_to_resource.source_file - else - nil - end - end - # Initialize resource with parent store and URL # @param [Middleman::Sitemap::Store] store # @param [String] path @@ -54,13 +46,6 @@ module Middleman @metadata = { options: {}, locals: {}, page: {} } end - # Set the on-disk source file for this resource - # @return [String] - def source_file - # TODO: Make this work when get_source_file doesn't exist - @source_file || get_source_file - end - # Whether this resource has a template file # @return [Boolean] def template? @@ -164,56 +149,13 @@ module Middleman # Ignore based on the source path (without template extensions) return true if @app.sitemap.ignored?(path) # This allows files to be ignored by their source file name (with template extensions) - !proxy? && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) + !self.is_a?(ProxyResource) && @app.sitemap.ignored?(source_file.sub("#{@app.source_dir}/", '')) end # The preferred MIME content type for this resource based on extension or metadata # @return [String] MIME type for this resource def content_type - mime_type = options[:content_type] || ::Rack::Mime.mime_type(ext, nil) - return mime_type if mime_type - - if proxy? - proxied_to_resource.content_type - else - nil - end - end - - # Whether this page is a proxy - # @return [Boolean] - def proxy? - @proxied_to - end - - # Set this page to proxy to a target path - # @param [String] target - # @return [void] - def proxy_to(target) - target = ::Middleman::Util.normalize_path(target) - raise "You can't proxy #{path} to itself!" if target == path - @proxied_to = target - end - - # The path of the page this page is proxied to, or nil if it's not proxied. - # @return [String] - attr_reader :proxied_to - - # The resource for the page this page is proxied to. Throws an exception - # if there is no resource. - # @return [Sitemap::Resource] - def proxied_to_resource - proxy_resource = @store.find_resource_by_path(proxied_to) - - unless proxy_resource - raise "Path #{path} proxies to unknown file #{proxied_to}:#{@store.resources.map(&:path)}" - end - - if proxy_resource.proxy? - raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy." - end - - proxy_resource + options[:content_type] || ::Rack::Mime.mime_type(ext, nil) end end end From 004ba3674181cb8a6499798208f486db4dfd3a13 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Mon, 7 Jul 2014 23:43:09 -0700 Subject: [PATCH 122/662] Remove partials_dir functionality --- CHANGELOG.md | 2 ++ middleman-core/features/partials_dir.feature | 30 ------------------ .../source/_partial.html.erb | 1 - .../source/index.html.erb | 2 -- .../shared/{snippet.erb => _snippet.html.erb} | 0 .../partials-app/source/sub/index.html.erb | 2 +- .../partials-dir-app/source/index.html.erb | 2 -- .../source/nested/partials/_partial.html.erb | 1 - .../source/partials/_partial.html.erb | 1 - .../lib/middleman-core/application.rb | 4 --- .../lib/middleman-core/template_context.rb | 31 ++++++------------- .../lib/middleman-core/template_renderer.rb | 10 ++---- 12 files changed, 15 insertions(+), 71 deletions(-) delete mode 100644 middleman-core/features/partials_dir.feature delete mode 100644 middleman-core/fixtures/default-partials-dir-app/source/_partial.html.erb delete mode 100644 middleman-core/fixtures/default-partials-dir-app/source/index.html.erb rename middleman-core/fixtures/partials-app/source/shared/{snippet.erb => _snippet.html.erb} (100%) delete mode 100644 middleman-core/fixtures/partials-dir-app/source/index.html.erb delete mode 100644 middleman-core/fixtures/partials-dir-app/source/nested/partials/_partial.html.erb delete mode 100644 middleman-core/fixtures/partials-dir-app/source/partials/_partial.html.erb diff --git a/CHANGELOG.md b/CHANGELOG.md index 08751a8e..22e2750e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ master === +* Remove the `partials_dir` setting. Partials should live next to content, or be addressed with absolute paths. +* Partials must be named with a leading underscore. `_my_snippet.html.erb`, not `my_snippet.html.erb`. * Removed the `proxy` and `ignore` options for the `page` command in `config.rb`. Use the `proxy` and `ignore` commands instead of passing these options to `page`. * The `page` command in `config.rb` can now be used to add data to the page via the `data` argument. It is accessed the same way as frontmatter data, via `current_resource.data`. * Add support for `environments` with the `-e` CLI flag. Loads additional config from `environments/envname.rb`. Removed `development?` helper in favor of `environment?(:development)`. Added `server?` helper to differentiate between build and server mode. diff --git a/middleman-core/features/partials_dir.feature b/middleman-core/features/partials_dir.feature deleted file mode 100644 index 8648c8e2..00000000 --- a/middleman-core/features/partials_dir.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Partials dir - Scenario: Find partials in a custom partials dir - Given a fixture app "partials-dir-app" - And a file named "config.rb" with: - """ - set :partials_dir, 'partials' - """ - And the Server is running - When I go to "/index.html" - Then I should see "contents of the partial" - - Scenario: Find partials in a nested custom partials dir - Given a fixture app "partials-dir-app" - And a file named "config.rb" with: - """ - set :partials_dir, 'nested/partials' - """ - And the Server is running - When I go to "/index.html" - Then I should see "contents of the nested partial" - - Scenario: Find partials in the default partials dir - Given a fixture app "default-partials-dir-app" - And a file named "config.rb" with: - """ - """ - And the Server is running - When I go to "/index.html" - Then I should see "contents of the partial" - diff --git a/middleman-core/fixtures/default-partials-dir-app/source/_partial.html.erb b/middleman-core/fixtures/default-partials-dir-app/source/_partial.html.erb deleted file mode 100644 index 5b50edf3..00000000 --- a/middleman-core/fixtures/default-partials-dir-app/source/_partial.html.erb +++ /dev/null @@ -1 +0,0 @@ -contents of the partial diff --git a/middleman-core/fixtures/default-partials-dir-app/source/index.html.erb b/middleman-core/fixtures/default-partials-dir-app/source/index.html.erb deleted file mode 100644 index 871728d4..00000000 --- a/middleman-core/fixtures/default-partials-dir-app/source/index.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<%= partial 'partial' %> - diff --git a/middleman-core/fixtures/partials-app/source/shared/snippet.erb b/middleman-core/fixtures/partials-app/source/shared/_snippet.html.erb similarity index 100% rename from middleman-core/fixtures/partials-app/source/shared/snippet.erb rename to middleman-core/fixtures/partials-app/source/shared/_snippet.html.erb diff --git a/middleman-core/fixtures/partials-app/source/sub/index.html.erb b/middleman-core/fixtures/partials-app/source/sub/index.html.erb index 5ce2eb35..e09e527b 100644 --- a/middleman-core/fixtures/partials-app/source/sub/index.html.erb +++ b/middleman-core/fixtures/partials-app/source/sub/index.html.erb @@ -1,3 +1,3 @@ <%= partial "shared/header" %> <%= partial "local" %> -<%= partial "shared/footer" %> \ No newline at end of file +<%= partial "../shared/footer" %> diff --git a/middleman-core/fixtures/partials-dir-app/source/index.html.erb b/middleman-core/fixtures/partials-dir-app/source/index.html.erb deleted file mode 100644 index 871728d4..00000000 --- a/middleman-core/fixtures/partials-dir-app/source/index.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -<%= partial 'partial' %> - diff --git a/middleman-core/fixtures/partials-dir-app/source/nested/partials/_partial.html.erb b/middleman-core/fixtures/partials-dir-app/source/nested/partials/_partial.html.erb deleted file mode 100644 index b27433e1..00000000 --- a/middleman-core/fixtures/partials-dir-app/source/nested/partials/_partial.html.erb +++ /dev/null @@ -1 +0,0 @@ -contents of the nested partial diff --git a/middleman-core/fixtures/partials-dir-app/source/partials/_partial.html.erb b/middleman-core/fixtures/partials-dir-app/source/partials/_partial.html.erb deleted file mode 100644 index 5b50edf3..00000000 --- a/middleman-core/fixtures/partials-dir-app/source/partials/_partial.html.erb +++ /dev/null @@ -1 +0,0 @@ -contents of the partial diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index a40158e9..63db4237 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -109,10 +109,6 @@ module Middleman # @return [String] config.define_setting :fonts_dir, 'fonts', 'Location of fonts within source' - # Location of partials within source. Used by renderers. - # @return [String] - config.define_setting :partials_dir, '', 'Location of partials within source' - # Location of layouts within source. Used by renderers. # @return [String] config.define_setting :layouts_dir, 'layouts', 'Location of layouts within source' diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 17b970fb..d80b46d3 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -91,14 +91,13 @@ module Middleman # Sinatra/Padrino compatible render method signature referenced by some view # helpers. Especially partials. # - # @param [] _ Unused parameter. # @param [String, Symbol] name The partial to render. # @param [Hash] options # @return [String] def render(_, name, options={}, &block) name = name.to_s - partial_path = locate_partial_relative(name) || locate_partial_in_partials_dir(name) + partial_path = locate_partial(name) raise ::Middleman::TemplateRenderer::TemplateNotFound, "Could not locate partial: #{name}" unless partial_path @@ -110,38 +109,28 @@ module Middleman protected - # Locate a partial reltive to the current path, given a name. + # Locate a partial relative to the current path or the source dir, given a partial's path. # # @api private - # @param [String] name + # @param [String] partial_path # @return [String] - def locate_partial_relative(name) + def locate_partial(partial_path) return unless resource = sitemap.find_resource_by_path(current_path) # Look for partials relative to the current path current_dir = File.dirname(resource.source_file) - relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), name) + relative_dir = File.join(current_dir.sub(%r{^#{Regexp.escape(source_dir)}/?}, ''), partial_path) - ::Middleman::TemplateRenderer.resolve_template( + partial = ::Middleman::TemplateRenderer.resolve_template( @app, relative_dir, - try_without_underscore: true, preferred_engine: File.extname(resource.source_file)[1..-1].to_sym ) - end - # Locate a partial reltive to the partials dir, given a name. - # - # @api private - # @param [String] name - # @return [String] - def locate_partial_in_partials_dir(name) - partials_path = File.join(@app.config[:partials_dir], name) - ::Middleman::TemplateRenderer.resolve_template( - @app, - partials_path, - try_without_underscore: true - ) + return partial if partial + + # Try to find one relative to the source dir + ::Middleman::TemplateRenderer.resolve_template(@app, File.join('', partial_path)) end # Render a path with locs, opts and contents block. diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index a8d1d527..27384ccf 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -150,7 +150,6 @@ module Middleman # Find a template on disk given a output path # @param [String] request_path # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine. - # @option options [Boolean] :try_without_underscore # @return [String, Boolean] Either the path to the template, or false def self.resolve_template(app, request_path, options={}) # Find the path by searching or using the cache @@ -177,13 +176,8 @@ module Middleman end end - search_paths = preferred_engines.flat_map do |preferred_engine| - path_with_ext = on_disk_path + '.' + preferred_engine - paths = [path_with_ext] - if options[:try_without_underscore] - paths << path_with_ext.sub(relative_path, relative_path.sub(/^_/, '').sub(/\/_/, '/')) - end - paths + search_paths = preferred_engines.map do |preferred_engine| + on_disk_path + '.' + preferred_engine end found_path = nil From 928eb82d65bc7426d9579e19958cb263a0bb22c0 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 8 Jul 2014 17:02:02 -0700 Subject: [PATCH 123/662] Convert Sitemap::Extensions into actual Middleman::Extension --- .../lib/middleman-core/application.rb | 3 +- .../lib/middleman-core/configuration.rb | 1 - .../sitemap/extensions/ignores.rb | 9 +-- .../sitemap/extensions/on_disk.rb | 40 ++++++-------- .../sitemap/extensions/proxies.rb | 9 ++- .../sitemap/extensions/redirects.rb | 7 ++- .../sitemap/extensions/request_endpoints.rb | 9 ++- .../lib/middleman-core/sitemap/store.rb | 55 ++++++++++--------- 8 files changed, 67 insertions(+), 66 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index c6848bb9..f5cfc1c3 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -176,7 +176,7 @@ module Middleman def_delegator :"::Middleman::Util", :instrument def_delegators :"self.class", :root, :root_path def_delegators :@generic_template_context, :link_to, :image_tag, :asset_path - + # Initialize the Middleman project def initialize(&block) # Search the root of the project for required files @@ -332,6 +332,5 @@ module Middleman "#" end alias_method :inspect, :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s - end end diff --git a/middleman-core/lib/middleman-core/configuration.rb b/middleman-core/lib/middleman-core/configuration.rb index a17382ce..58141d11 100644 --- a/middleman-core/lib/middleman-core/configuration.rb +++ b/middleman-core/lib/middleman-core/configuration.rb @@ -1,6 +1,5 @@ module Middleman module Configuration - # A class that manages a collection of documented settings. # Can be used by extensions as well as the main Middleman # application. Extensions should probably finalize their instance diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index b77f0e19..feee4c1d 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -2,16 +2,17 @@ module Middleman module Sitemap module Extensions # Class to handle managing ignores - class Ignores - def initialize(app, sitemap) - @app = app + class Ignores < Extension + def initialize(app, config={}, &block) + super + @app.add_to_config_context :ignore, &method(:create_ignore) @app.define_singleton_method :ignore, &method(:create_ignore) # Array of callbacks which can ass ignored @ignored_callbacks = [] - sitemap.define_singleton_method :ignored?, &method(:ignored?) + @app.sitemap.define_singleton_method :ignored?, &method(:ignored?) end # Ignore a path or add an ignore callback diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index a12ecf44..e39ca08f 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -3,30 +3,17 @@ require 'set' module Middleman module Sitemap module Extensions - class OnDisk - attr_accessor :sitemap + class OnDisk < Extension attr_accessor :waiting_for_ready - def initialize(app, sitemap) - @sitemap = sitemap - @app = app + def initialize(app, config={}, &block) + super + @file_paths_on_disk = Set.new scoped_self = self @waiting_for_ready = true - @app.before_configuration do - # Register file change callback - extensions[:file_watcher].api.changed do |file| - scoped_self.touch_file(file) - end - - # Register file delete callback - extensions[:file_watcher].api.deleted do |file| - scoped_self.remove_file(file) - end - end - @app.ready do scoped_self.waiting_for_ready = false # Make sure the sitemap is ready for the first request @@ -34,13 +21,18 @@ module Middleman end end + def before_configuration + file_watcher.changed(&method(:touch_file)) + file_watcher.deleted(&method(:remove_file)) + end + # Update or add an on-disk file path # @param [String] file # @return [Boolean] def touch_file(file) return false if File.directory?(file) - path = @sitemap.file_to_path(file) + path = @app.sitemap.file_to_path(file) return false unless path ignored = @app.config[:ignored_sitemap_matchers].any? do |_, callback| @@ -57,11 +49,11 @@ module Middleman # in case one of the other manipulators # (like asset_hash) cares about the contents of this file, # whether or not it belongs in the sitemap (like a partial) - @sitemap.rebuild_resource_list!(:touched_file) + @app.sitemap.rebuild_resource_list!(:touched_file) # Force sitemap rebuild so the next request is ready to go. # Skip this during build because the builder will control sitemap refresh. - @sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? + @app.sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? end # Remove a file from the store @@ -70,11 +62,11 @@ module Middleman def remove_file(file) return unless @file_paths_on_disk.delete?(file) - @sitemap.rebuild_resource_list!(:removed_file) + @app.sitemap.rebuild_resource_list!(:removed_file) # Force sitemap rebuild so the next request is ready to go. # Skip this during build because the builder will control sitemap refresh. - @sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? + @app.sitemap.ensure_resource_list_updated! unless waiting_for_ready || @app.build? end # Update the main sitemap resource list @@ -82,8 +74,8 @@ module Middleman def manipulate_resource_list(resources) resources + @file_paths_on_disk.map do |file| ::Middleman::Sitemap::Resource.new( - @sitemap, - @sitemap.file_to_path(file), + @app.sitemap, + @app.sitemap.file_to_path(file), File.join(@app.root, file) ) end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 9acce571..03541302 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -1,11 +1,14 @@ +require 'middleman-core/sitemap/resource' + module Middleman module Sitemap module Extensions # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations - class Proxies - def initialize(app) - @app = app + class Proxies < Extension + def initialize(app, config={}, &block) + super + @app.add_to_config_context :proxy, &method(:create_proxy) @app.define_singleton_method(:proxy, &method(:create_proxy)) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index d6b79045..babe6509 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -5,9 +5,10 @@ module Middleman module Extensions # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations - class Redirects - def initialize(app) - @app = app + class Redirects < Extension + def initialize(app, config={}, &block) + super + @app.add_to_config_context :redirect, &method(:create_redirect) @redirects = {} diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index 8d555fa6..c6046f40 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -1,11 +1,14 @@ +require 'middleman-core/sitemap/resource' + module Middleman module Sitemap module Extensions - class RequestEndpoints + class RequestEndpoints < Extension # Manages the list of proxy configurations and manipulates the sitemap # to include new resources based on those configurations - def initialize(app) - @app = app + def initialize(app, config={}, &block) + super + @app.add_to_config_context :endpoint, &method(:create_endpoint) @endpoints = {} diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index a4330696..bf7d2a57 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -2,12 +2,35 @@ require 'active_support/core_ext/hash/deep_merge' require 'monitor' -# Extensions -require 'middleman-core/sitemap/extensions/on_disk' -require 'middleman-core/sitemap/extensions/redirects' -require 'middleman-core/sitemap/extensions/request_endpoints' -require 'middleman-core/sitemap/extensions/proxies' -require 'middleman-core/sitemap/extensions/ignores' +# Ignores +Middleman::Extensions.register :sitemap_ignore, auto_activate: :before_configuration do + require 'middleman-core/sitemap/extensions/ignores' + Middleman::Sitemap::Extensions::Ignores +end + +# Files on Disk +Middleman::Extensions.register :sitemap_ondisk, auto_activate: :before_configuration do + require 'middleman-core/sitemap/extensions/on_disk' + Middleman::Sitemap::Extensions::OnDisk +end + +# Endpoints +Middleman::Extensions.register :sitemap_endpoint, auto_activate: :before_configuration do + require 'middleman-core/sitemap/extensions/request_endpoints' + Middleman::Sitemap::Extensions::RequestEndpoints +end + +# Proxies +Middleman::Extensions.register :sitemap_proxies, auto_activate: :before_configuration do + require 'middleman-core/sitemap/extensions/proxies' + Middleman::Sitemap::Extensions::Proxies +end + +# Redirects +Middleman::Extensions.register :sitemap_redirects, auto_activate: :before_configuration do + require 'middleman-core/sitemap/extensions/redirects' + Middleman::Sitemap::Extensions::Redirects +end module Middleman # Sitemap namespace @@ -34,26 +57,6 @@ module Middleman @lock = Monitor.new reset_lookup_cache! - # Handle ignore commands - Middleman::Sitemap::Extensions::Ignores.new(@app, self) - - # Extensions - { - # Register classes which can manipulate the main site map list - on_disk: Middleman::Sitemap::Extensions::OnDisk.new(@app, self), - - # Request Endpoints - request_endpoints: Middleman::Sitemap::Extensions::RequestEndpoints.new(@app), - - # Proxies - proxies: Middleman::Sitemap::Extensions::Proxies.new(@app), - - # Redirects - redirects: Middleman::Sitemap::Extensions::Redirects.new(@app) - }.each do |k, m| - register_resource_list_manipulator(k, m) - end - @app.config_context.class.send :def_delegator, :app, :sitemap end From 0185d37473156dacdd785fa111cfd02d65622970 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 2 Jul 2014 19:04:34 -0700 Subject: [PATCH 124/662] Experiment with Contracts --- Gemfile | 1 + .../lib/middleman-core/contracts.rb | 95 +++ .../lib/middleman-core/core_extensions.rb | 2 + .../middleman-core/core_extensions/data.rb | 29 +- .../core_extensions/file_watcher.rb | 6 + .../core_extensions/front_matter.rb | 19 +- .../middleman-core/core_extensions/i18n.rb | 8 +- .../middleman-core/core_extensions/routing.rb | 2 + .../lib/middleman-core/extension.rb | 2 + .../middleman-core/extensions/asset_hash.rb | 7 +- .../middleman-core/extensions/asset_host.rb | 1 + .../middleman-core/extensions/cache_buster.rb | 1 + .../extensions/directory_indexes.rb | 3 +- .../lib/middleman-core/extensions/gzip.rb | 2 + .../middleman-core/extensions/minify_css.rb | 5 + .../extensions/minify_javascript.rb | 5 + .../extensions/relative_assets.rb | 1 + .../lib/middleman-core/file_renderer.rb | 6 + .../middleware/inline_url_rewriter.rb | 6 +- .../lib/middleman-core/renderers/liquid.rb | 2 + .../sitemap/extensions/ignores.rb | 2 + .../sitemap/extensions/on_disk.rb | 16 +- .../sitemap/extensions/proxies.rb | 7 +- .../sitemap/extensions/redirects.rb | 9 +- .../sitemap/extensions/request_endpoints.rb | 9 +- .../lib/middleman-core/sitemap/resource.rb | 26 +- .../lib/middleman-core/sitemap/store.rb | 14 +- .../lib/middleman-core/template_context.rb | 5 + .../lib/middleman-core/template_renderer.rb | 12 +- middleman-core/lib/middleman-core/util.rb | 712 +++++++++--------- 30 files changed, 639 insertions(+), 376 deletions(-) create mode 100644 middleman-core/lib/middleman-core/contracts.rb diff --git a/Gemfile b/Gemfile index 81bd9e5e..288cd699 100644 --- a/Gemfile +++ b/Gemfile @@ -10,6 +10,7 @@ gem 'fivemat', '~> 1.3.1' gem 'aruba', '~> 0.6.0' gem 'rspec', '~> 3.0' gem 'simplecov' +gem 'contracts', require: false # Optional middleman dependencies, included for tests gem 'sinatra', require: false diff --git a/middleman-core/lib/middleman-core/contracts.rb b/middleman-core/lib/middleman-core/contracts.rb new file mode 100644 index 00000000..3eec15d2 --- /dev/null +++ b/middleman-core/lib/middleman-core/contracts.rb @@ -0,0 +1,95 @@ +if ENV['TEST'] || ENV['CONTRACTS'] == 'true' + require 'contracts' + + class IsA + def self.[](val) + @lookup ||= {} + @lookup[val] ||= new(val) + end + + def initialize(val) + @val = val + end + + def valid?(val) + val.is_a? @val.constantize + end + end + + ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']] +else + module Contracts + def self.included(base) + base.extend self + end + + # rubocop:disable MethodName + def Contract(*) + end + + class Callable + def self.[](*) + end + end + + class Bool + end + + class Num + end + + class Pos + end + + class Neg + end + + class Any + end + + class None + end + + class Or < Callable + end + + class Xor < Callable + end + + class And < Callable + end + + class Not < Callable + end + + class RespondTo < Callable + end + + class Send < Callable + end + + class Exactly < Callable + end + + class ArrayOf < Callable + end + + class ResourceList < Callable + end + + class Args < Callable + end + + class HashOf < Callable + end + + class Bool + end + + class Maybe < Callable + end + + class IsA < Callable + end + end +end diff --git a/middleman-core/lib/middleman-core/core_extensions.rb b/middleman-core/lib/middleman-core/core_extensions.rb index ff7b0088..36fdb509 100644 --- a/middleman-core/lib/middleman-core/core_extensions.rb +++ b/middleman-core/lib/middleman-core/core_extensions.rb @@ -1,3 +1,5 @@ +require 'middleman-core/extensions' + # File Change Notifier Middleman::Extensions.register :file_watcher, auto_activate: :before_sitemap do require 'middleman-core/core_extensions/file_watcher' diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 346d64f1..02af521a 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -1,5 +1,6 @@ require 'yaml' require 'active_support/json' +require 'middleman-core/contracts' module Middleman module CoreExtensions @@ -33,11 +34,24 @@ module Middleman # The core logic behind the data extension. class DataStore + include Contracts + + # Setup data store + # + # @param [Middleman::Application] app The current instance of Middleman + def initialize(app) + @app = app + @local_data = {} + @local_sources = {} + @callback_sources = {} + end + # Store static data hash # # @param [Symbol] name Name of the data, used for namespacing # @param [Hash] content The content for this data # @return [Hash] + Contract Symbol, Hash => Hash def store(name=nil, content=nil) @local_sources[name.to_s] = content unless name.nil? || content.nil? @local_sources @@ -48,21 +62,12 @@ module Middleman # @param [Symbol] name Name of the data, used for namespacing # @param [Proc] proc The callback which will return data # @return [Hash] + Contract Symbol, Proc => Hash def callbacks(name=nil, proc=nil) @callback_sources[name.to_s] = proc unless name.nil? || proc.nil? @callback_sources end - # Setup data store - # - # @param [Middleman::Application] app The current instance of Middleman - def initialize(app) - @app = app - @local_data = {} - @local_sources = {} - @callback_sources = {} - end - # Update the internal cache for a given file path # # @param [String] file The file to be re-parsed @@ -91,7 +96,7 @@ module Middleman data_branch = data_branch[dir] end - data_branch[basename] = ::Middleman::Util.recursively_enhance(data) + data_branch[basename] = data && ::Middleman::Util.recursively_enhance(data) end # Remove a given file from the internal cache @@ -120,6 +125,7 @@ module Middleman # # @param [String, Symbol] path The name of the data namespace # @return [Hash, nil] + Contract Or[String, Symbol] => Maybe[Hash] def data_for_path(path) response = nil @@ -170,6 +176,7 @@ module Middleman # Convert all the data into a static hash # # @return [Hash] + Contract None => Hash def to_h data = {} 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 8a3e0a9c..68a83280 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -1,5 +1,6 @@ require 'pathname' require 'set' +require 'middleman-core/contracts' module Middleman module CoreExtensions @@ -42,6 +43,7 @@ module Middleman # Core File Change API class class API extend Forwardable + include Contracts attr_reader :app attr_reader :known_paths @@ -61,6 +63,7 @@ module Middleman # # @param [nil,Regexp] matcher A Regexp to match the change path against # @return [Array] + Contract Or[Regexp, Proc] => ArrayOf[ArrayOf[Or[Proc, Regexp, nil]]] def changed(matcher=nil, &block) @_changed << [block, matcher] if block_given? @_changed @@ -70,6 +73,7 @@ module Middleman # # @param [nil,Regexp] matcher A Regexp to match the deleted path against # @return [Array] + Contract Or[Regexp, Proc] => ArrayOf[ArrayOf[Or[Proc, Regexp, nil]]] def deleted(matcher=nil, &block) @_deleted << [block, matcher] if block_given? @_deleted @@ -130,6 +134,7 @@ module Middleman reload_path(path, true) end + Contract String => Bool def exists?(path) p = Pathname(path) p = p.relative_path_from(Pathname(@app.root)) unless p.relative? @@ -139,6 +144,7 @@ module Middleman # Whether this path is ignored # @param [Pathname] path # @return [Boolean] + Contract Or[String, Pathname] => Bool def ignored?(path) path = path.to_s app.config[:file_watcher_ignore].any? { |r| path =~ r } 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 72412398..cd96eb38 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -31,7 +31,8 @@ module Middleman::CoreExtensions file_watcher.deleted(&method(:clear_data)) end - # Modify each resource to add data & options from frontmatter. + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources.each do |resource| next if resource.source_file.blank? @@ -60,10 +61,12 @@ module Middleman::CoreExtensions # Get the template data from a path # @param [String] path # @return [String] + Contract String => String def template_data_for_file(path) data(path).last end + Contract String => [Hash, Maybe[String]] def data(path) p = normalize_path(path) @cache[p] ||= frontmatter_and_content(p) @@ -83,6 +86,7 @@ module Middleman::CoreExtensions # Get the frontmatter and plain content from a file # @param [String] path # @return [Array] + Contract String => [Hash, Maybe[String]] def frontmatter_and_content(path) full_path = if Pathname(path).relative? File.join(app.source_dir, path) @@ -117,6 +121,7 @@ module Middleman::CoreExtensions # Parse YAML frontmatter out of a string # @param [String] content # @return [Array] + Contract String, String => Maybe[[Hash, String]] def parse_yaml_front_matter(content, full_path) yaml_regex = /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m if content =~ yaml_regex @@ -127,10 +132,10 @@ module Middleman::CoreExtensions data = data.symbolize_keys rescue *YAML_ERRORS => e app.logger.error "YAML Exception parsing #{full_path}: #{e.message}" - return false + return nil end else - return false + return nil end [data, content] @@ -138,6 +143,10 @@ module Middleman::CoreExtensions [{}, content] end + # Parse JSON frontmatter out of a string + # @param [String] content + # @return [Array] + Contract String, String => Maybe[[Hash, String]] def parse_json_front_matter(content, full_path) json_regex = /\A(;;;\s*\n.*?\n?)^(;;;\s*$\n?)/m @@ -149,11 +158,11 @@ module Middleman::CoreExtensions data = ActiveSupport::JSON.decode(json).symbolize_keys rescue => e app.logger.error "JSON Exception parsing #{full_path}: #{e.message}" - return false + return nil end else - return false + return nil end [data, content] diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index d62d15cb..32f3f2b0 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -43,12 +43,14 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension end end + Contract None => ArrayOf[Symbol] def langs @langs ||= known_languages end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) new_resources = [] @@ -87,6 +89,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n.reload! end + Contract String => Regexp def convert_glob_to_regex(glob) # File.fnmatch doesn't support brackets: {rb,yml,yaml} regex = glob.sub(/\./, '\.').sub(File.join('**', '*'), '.*').sub(/\//, '\/').sub('{rb,yml,yaml}', '(rb|ya?ml)') @@ -103,6 +106,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n.fallbacks = ::I18n::Locale::Fallbacks.new if ::I18n.respond_to?(:fallbacks) end + Contract None => ArrayOf[Symbol] def known_languages if options[:langs] Array(options[:langs]).map(&:to_sym) @@ -120,6 +124,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # Parse locale extension filename # @return [lang, path, basename] # will return +nil+ if no locale extension + Contract String => Maybe[[Symbol, String, String]] def parse_locale_extension(path) path_bits = path.split('.') return nil if path_bits.size < 3 @@ -132,6 +137,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension [lang, path, basename] end + Contract String, String, String, Symbol => IsA['Middleman::Sitemap::Resource'] def build_resource(path, source_path, page_id, lang) old_locale = ::I18n.locale ::I18n.locale = lang diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 24539ce0..61e80028 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -16,6 +16,8 @@ module Middleman app.add_to_config_context :page, &method(:page) end + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources.each do |resource| @page_configs.each do |matcher, metadata| diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index 713a12c0..cb875e89 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/class/attribute' require 'middleman-core/configuration' +require 'middleman-core/contracts' module Middleman # Middleman's Extension API provides the ability to add functionality to Middleman @@ -64,6 +65,7 @@ module Middleman # @see http://middlemanapp.com/advanced/custom/ Middleman Custom Extensions Documentation class Extension extend Forwardable + include Contracts # @!attribute supports_multiple_instances # @!scope class diff --git a/middleman-core/lib/middleman-core/extensions/asset_hash.rb b/middleman-core/lib/middleman-core/extensions/asset_hash.rb index fb277adf..ae4801c2 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_hash.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_hash.rb @@ -26,6 +26,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension proc: method(:rewrite_url) end + Contract String, Or[String, Pathname], Any => Maybe[String] def rewrite_url(asset_path, dirpath, _request_path) relative_path = Pathname.new(asset_path).relative? @@ -43,7 +44,8 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) @rack_client ||= begin rack_app = ::Middleman::Rack.new(app).to_app @@ -64,6 +66,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension end.each(&method(:manipulate_single_resource)) end + Contract IsA['Middleman::Sitemap::Resource'] => Maybe[IsA['Middleman::Sitemap::Resource']] def manipulate_single_resource(resource) return unless options.exts.include?(resource.ext) return if ignored_resource?(resource) @@ -79,8 +82,10 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension digest = Digest::SHA1.hexdigest(response.body)[0..7] resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" } + resource end + Contract IsA['Middleman::Sitemap::Resource'] => Bool def ignored_resource?(resource) @ignore.any? { |ignore| Middleman::Util.path_match(ignore, resource.destination_path) } end diff --git a/middleman-core/lib/middleman-core/extensions/asset_host.rb b/middleman-core/lib/middleman-core/extensions/asset_host.rb index ff687895..28765c24 100644 --- a/middleman-core/lib/middleman-core/extensions/asset_host.rb +++ b/middleman-core/lib/middleman-core/extensions/asset_host.rb @@ -16,6 +16,7 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension proc: method(:rewrite_url) end + Contract String, Or[String, Pathname], Any => String def rewrite_url(asset_path, dirpath, _request_path) relative_path = Pathname.new(asset_path).relative? diff --git a/middleman-core/lib/middleman-core/extensions/cache_buster.rb b/middleman-core/lib/middleman-core/extensions/cache_buster.rb index f1d22610..24536f95 100644 --- a/middleman-core/lib/middleman-core/extensions/cache_buster.rb +++ b/middleman-core/lib/middleman-core/extensions/cache_buster.rb @@ -20,6 +20,7 @@ class Middleman::Extensions::CacheBuster < ::Middleman::Extension proc: method(:rewrite_url) end + Contract String, Or[String, Pathname], Any => String def rewrite_url(asset_path, _dirpath, _request_path) asset_path + '?' + Time.now.strftime('%s') end diff --git a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb index b63eb64e..171b1493 100644 --- a/middleman-core/lib/middleman-core/extensions/directory_indexes.rb +++ b/middleman-core/lib/middleman-core/extensions/directory_indexes.rb @@ -5,7 +5,8 @@ class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension self.resource_list_manipulator_priority = 100 # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) index_file = app.config[:index_file] new_index_path = "/#{index_file}" diff --git a/middleman-core/lib/middleman-core/extensions/gzip.rb b/middleman-core/lib/middleman-core/extensions/gzip.rb index d3015ecf..70af4ad1 100644 --- a/middleman-core/lib/middleman-core/extensions/gzip.rb +++ b/middleman-core/lib/middleman-core/extensions/gzip.rb @@ -70,6 +70,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension I18n.locale = old_locale end + Contract String => [Maybe[String], Maybe[Num], Maybe[Num]] def gzip_file(path) input_file = File.open(path, 'rb').read output_filename = path + '.gz' @@ -104,6 +105,7 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension # Whether a path should be gzipped # @param [Pathname] path A destination path # @return [Boolean] + Contract Pathname => Bool def should_gzip?(path) path = path.sub app.config[:build_dir] + '/', '' options.exts.include?(path.extname) && options.ignore.none? { |ignore| Middleman::Util.path_match(ignore, path.to_s) } diff --git a/middleman-core/lib/middleman-core/extensions/minify_css.rb b/middleman-core/lib/middleman-core/extensions/minify_css.rb index 0b1f0e1b..08a28d95 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_css.rb @@ -1,3 +1,5 @@ +require 'middleman-core/contracts' + # Minify CSS Extension class Middleman::Extensions::MinifyCss < ::Middleman::Extension option :inline, false, 'Whether to minify CSS inline within HTML files' @@ -24,6 +26,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension # Rack middleware to look for CSS and compress it class Rack + include Contracts INLINE_CSS_REGEX = /(]*>\s*(?:\/\*\*\/)?\s*<\/style>)/m # Init @@ -65,10 +68,12 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension private + Contract String => Bool def inline_html_content?(path) (path.end_with?('.html') || path.end_with?('.php')) && @inline end + Contract String => Bool def standalone_css_content?(path) path.end_with?('.css') && @ignore.none? { |ignore| Middleman::Util.path_match(ignore, path) } end diff --git a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb index 5a03671b..208b4fda 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb @@ -1,3 +1,5 @@ +require 'middleman-core/contracts' + # Minify Javascript Extension class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension option :inline, false, 'Whether to minify JS inline within HTML files' @@ -16,6 +18,8 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension # Rack middleware to look for JS and compress it class Rack + include Contracts + # Init # @param [Class] app # @param [Hash] options @@ -61,6 +65,7 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension private + Contract String => String def minify_inline_content(uncompressed_source) uncompressed_source.gsub(/(]*>\s*(?:\/\/(?:(?:)|(?:\]\]>)))?\s*<\/script>)/m) do |match| first = $1 diff --git a/middleman-core/lib/middleman-core/extensions/relative_assets.rb b/middleman-core/lib/middleman-core/extensions/relative_assets.rb index 3820b8f8..95d32698 100644 --- a/middleman-core/lib/middleman-core/extensions/relative_assets.rb +++ b/middleman-core/lib/middleman-core/extensions/relative_assets.rb @@ -20,6 +20,7 @@ class Middleman::Extensions::RelativeAssets < ::Middleman::Extension proc: method(:rewrite_url) end + Contract String, Or[String, Pathname], Any => Maybe[String] def rewrite_url(asset_path, dirpath, request_path) relative_path = Pathname.new(asset_path).relative? diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index 1e0bbebd..6e43d712 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -1,5 +1,7 @@ require 'tilt' require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/module/delegation' +require 'middleman-core/contracts' ::Tilt.mappings.delete('html') # WTF, Tilt? ::Tilt.mappings.delete('csv') @@ -7,6 +9,7 @@ require 'active_support/core_ext/string/output_safety' module Middleman class FileRenderer extend Forwardable + include Contracts def self.cache @_cache ||= ::Tilt::Cache.new @@ -25,6 +28,7 @@ module Middleman # @param [Hash] opts # @param [Class] context # @return [String] + Contract Hash, Hash, Any, Proc => String def render(locs={}, opts={}, context, &block) path = @path.dup @@ -96,6 +100,7 @@ module Middleman # Get the template data from a path # @param [String] path # @return [String] + Contract String => String def template_data_for_file if @app.extensions[:front_matter] @app.extensions[:front_matter].template_data_for_file(@path) @@ -111,6 +116,7 @@ module Middleman # # @param [String] ext # @return [Hash] + Contract String => Hash def options_for_ext(ext) # Read options for extension from config/Tilt or cache cache.fetch(:options_for_ext, ext) do diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index 88142b4a..094a9d9c 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -1,10 +1,13 @@ require 'middleman-core/util' +require 'middleman-core/contracts' require 'rack' require 'rack/response' module Middleman module Middleware class InlineURLRewriter + include Contracts + def initialize(app, options={}) @rack_app = app @middleman_app = options[:middleman_app] @@ -63,10 +66,11 @@ module Middleman [status, headers, response] end + Contract Or[Regexp, RespondTo[:call], String] => Bool def should_ignore?(validator, value) if validator.is_a? Regexp # Treat as Regexp - value.match(validator) + !value.match(validator).nil? elsif validator.respond_to? :call # Treat as proc validator.call(value) diff --git a/middleman-core/lib/middleman-core/renderers/liquid.rb b/middleman-core/lib/middleman-core/renderers/liquid.rb index e3d51417..78ff5a75 100644 --- a/middleman-core/lib/middleman-core/renderers/liquid.rb +++ b/middleman-core/lib/middleman-core/renderers/liquid.rb @@ -10,6 +10,8 @@ module Middleman ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(app.source_dir) end + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) return resources unless app.extensions[:data] diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index feee4c1d..7ac26615 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -18,6 +18,7 @@ module Middleman # Ignore a path or add an ignore callback # @param [String, Regexp] path Path glob expression, or path regex # @return [void] + Contract Maybe[Or[String, Regexp]], Proc => Any def create_ignore(path=nil, &block) if path.is_a? Regexp @ignored_callbacks << proc { |p| p =~ path } @@ -40,6 +41,7 @@ module Middleman # Whether a path is ignored # @param [String] path # @return [Boolean] + Contract String => Bool def ignored?(path) path_clean = ::Middleman::Util.normalize_path(path) @ignored_callbacks.any? { |b| b.call(path_clean) } diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index e39ca08f..0a42198c 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -1,4 +1,5 @@ require 'set' +require 'middleman-core/contracts' module Middleman module Sitemap @@ -21,6 +22,7 @@ module Middleman end end + Contract None => Any def before_configuration file_watcher.changed(&method(:touch_file)) file_watcher.deleted(&method(:remove_file)) @@ -28,12 +30,16 @@ module Middleman # Update or add an on-disk file path # @param [String] file - # @return [Boolean] + # @return [void] + Contract String => Any def touch_file(file) return false if File.directory?(file) - path = @app.sitemap.file_to_path(file) - return false unless path + begin + @app.sitemap.file_to_path(file) + rescue + return + end ignored = @app.config[:ignored_sitemap_matchers].any? do |_, callback| if callback.arity == 1 @@ -59,6 +65,7 @@ module Middleman # Remove a file from the store # @param [String] file # @return [void] + Contract String => Any def remove_file(file) return unless @file_paths_on_disk.delete?(file) @@ -70,7 +77,8 @@ module Middleman end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources + @file_paths_on_disk.map do |file| ::Middleman::Sitemap::Resource.new( diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb index 03541302..cadf81f3 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/proxies.rb @@ -24,6 +24,7 @@ module Middleman # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. # @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}. # @return [void] + Contract String, String, Maybe[Hash] => Any def create_proxy(path, target, opts={}) options = opts.dup @@ -41,7 +42,8 @@ module Middleman end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources + @proxy_configs.map do |config| p = ProxyResource.new( @@ -108,6 +110,7 @@ module Middleman # The resource for the page this page is proxied to. Throws an exception # if there is no resource. # @return [Sitemap::Resource] + Contract None => IsA['Middleman::Sitemap::Resource'] def target_resource resource = @store.find_resource_by_path(@target) @@ -122,10 +125,12 @@ module Middleman resource end + Contract None => String def source_file target_resource.source_file end + Contract None => Maybe[String] def content_type mime_type = super return mime_type if mime_type diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb index babe6509..9b1a4953 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/redirects.rb @@ -1,4 +1,5 @@ require 'middleman-core/sitemap/resource' +require 'middleman-core/contracts' module Middleman module Sitemap @@ -17,6 +18,7 @@ module Middleman # Setup a redirect from a path to a target # @param [String] path # @param [Hash] opts The :to value gives a target path + Contract String, ({ to: Or[String, IsA['Middleman::Sitemap::Resource']] }), Proc => Any def create_redirect(path, opts={}, &block) opts[:template] = block if block_given? @@ -26,7 +28,8 @@ module Middleman end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources + @redirects.map do |path, opts| r = RedirectResource.new( @@ -41,6 +44,7 @@ module Middleman end class RedirectResource < ::Middleman::Sitemap::Resource + Contract None => Maybe[Proc] attr_accessor :output def initialize(store, path, target) @@ -49,10 +53,12 @@ module Middleman super(store, path) end + Contract None => Bool def template? true end + Contract Args[Any] => String def render(*) url = ::Middleman::Util.url_for(@store.app, @request_path, relative: false, @@ -76,6 +82,7 @@ module Middleman end end + Contract None => Bool def ignored? false end diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb index c6046f40..16a43deb 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/request_endpoints.rb @@ -18,6 +18,7 @@ module Middleman # @param [String] path # @param [Hash] opts The :path value gives a request path if it # differs from the output path + Contract String, Or[({ path: String }), Proc] => Any def create_endpoint(path, opts={}, &block) endpoint = { request_path: path @@ -35,7 +36,8 @@ module Middleman end # Update the main sitemap resource list - # @return [void] + # @return Array + Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources + @endpoints.map do |path, config| r = EndpointResource.new( @@ -50,6 +52,7 @@ module Middleman end class EndpointResource < ::Middleman::Sitemap::Resource + Contract None => Maybe[Proc] attr_accessor :output def initialize(store, path, request_path) @@ -57,16 +60,20 @@ module Middleman @request_path = ::Middleman::Util.normalize_path(request_path) end + Contract None => String attr_reader :request_path + Contract None => Bool def template? true end + Contract Args[Any] => String def render(*) return output.call if output end + Contract None => Bool def ignored? false end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index fdd57b00..eee2068a 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -2,12 +2,14 @@ require 'rack/mime' require 'middleman-core/sitemap/extensions/traversal' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' +require 'middleman-core/contracts' module Middleman # Sitemap namespace module Sitemap # Sitemap Resource class class Resource + include Contracts include Middleman::Sitemap::Extensions::Traversal # The source path of this resource (relative to the source directory, @@ -28,6 +30,10 @@ module Middleman # @return [String] alias_method :request_path, :destination_path + # The metadata for this resource + # @return [Hash] + attr_reader :metadata + # Initialize resource with parent store and URL # @param [Middleman::Sitemap::Store] store # @param [String] path @@ -48,6 +54,7 @@ module Middleman # Whether this resource has a template file # @return [Boolean] + Contract None => Bool def template? return false if source_file.nil? !::Tilt[source_file].nil? @@ -59,16 +66,14 @@ module Middleman # Locals are local variables for rendering this resource's template # Page are data that is exposed through this resource's data member. # Note: It is named 'page' for backwards compatibility with older MM. + Contract Hash => Hash def add_metadata(meta={}) @metadata.deep_merge!(meta) end - # The metadata for this resource - # @return [Hash] - attr_reader :metadata - # Data about this resource, populated from frontmatter or extensions. # @return [HashWithIndifferentAccess] + Contract None => IsA['Middleman::Util::HashWithIndifferentAccess'] def data # TODO: Should this really be a HashWithIndifferentAccess? ::Middleman::Util.recursively_enhance(metadata[:page]).freeze @@ -77,30 +82,34 @@ module Middleman # Options about how this resource is rendered, such as its :layout, # :renderer_options, and whether or not to use :directory_indexes. # @return [Hash] + Contract None => Hash def options metadata[:options] end # Local variable mappings that are used when rendering the template for this resource. # @return [Hash] + Contract None => Hash def locals metadata[:locals] end # Extension of the path (i.e. '.js') # @return [String] + Contract None => String def ext File.extname(path) end # Render this resource # @return [String] + Contract Hash, Hash => String def render(opts={}, locs={}) return ::Middleman::FileRenderer.new(@app, source_file).template_data_for_file unless template? relative_source = Pathname(source_file).relative_path_from(Pathname(@app.root)) - @app.instrument 'render.resource', path: relative_source, destination_path: destination_path do + ::Middleman::Util.instrument 'render.resource', path: relative_source, destination_path: destination_path do md = metadata opts = md[:options].deep_merge(opts) locs = md[:locals].deep_merge(locs) @@ -119,6 +128,7 @@ module Middleman # A path without the directory index - so foo/index.html becomes # just foo. Best for linking. # @return [String] + Contract None => String def url url_path = destination_path if @app.config[:strip_index_file] @@ -131,19 +141,22 @@ module Middleman # Whether the source file is binary. # # @return [Boolean] + Contract None => Bool def binary? - source_file && ::Middleman::Util.binary?(source_file) + !source_file.nil? && ::Middleman::Util.binary?(source_file) end # Ignore a resource directly, without going through the whole # ignore filter stuff. # @return [void] + Contract None => Any def ignore! @ignored = true end # Whether the Resource is ignored # @return [Boolean] + Contract None => Bool def ignored? return true if @ignored # Ignore based on the source path (without template extensions) @@ -154,6 +167,7 @@ module Middleman # The preferred MIME content type for this resource based on extension or metadata # @return [String] MIME type for this resource + Contract None => Maybe[String] def content_type options[:content_type] || ::Rack::Mime.mime_type(ext, nil) end diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index bf7d2a57..12348695 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -32,6 +32,8 @@ Middleman::Extensions.register :sitemap_redirects, auto_activate: :before_config Middleman::Sitemap::Extensions::Redirects end +require 'middleman-core/contracts' + module Middleman # Sitemap namespace module Sitemap @@ -42,6 +44,8 @@ module Middleman # which is the path relative to the source directory, minus any template # extensions. All "path" parameters used in this class are source paths. class Store + include Contracts + # @return [Middleman::Application] attr_reader :app @@ -67,6 +71,7 @@ module Middleman # @param [#manipulate_resource_list] manipulator Resource list manipulator # @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators. # @return [void] + Contract Symbol, RespondTo['manipulate_resource_list'], Maybe[Num] => Any def register_resource_list_manipulator(name, manipulator, priority=50) # The third argument used to be a boolean - handle those who still pass one priority = 50 unless priority.is_a? Numeric @@ -92,6 +97,7 @@ module Middleman # Find a resource given its original path # @param [String] request_path The original path of a resource. # @return [Middleman::Sitemap::Resource] + Contract String => Maybe[IsA['Middleman::Sitemap::Resource']] def find_resource_by_path(request_path) @lock.synchronize do request_path = ::Middleman::Util.normalize_path(request_path) @@ -103,6 +109,7 @@ module Middleman # Find a resource given its destination path # @param [String] request_path The destination (output) path of a resource. # @return [Middleman::Sitemap::Resource] + Contract String => Maybe[IsA['Middleman::Sitemap::Resource']] def find_resource_by_destination_path(request_path) @lock.synchronize do request_path = ::Middleman::Util.normalize_path(request_path) @@ -114,6 +121,7 @@ module Middleman # Get the array of all resources # @param [Boolean] include_ignored Whether to include ignored resources # @return [Array] + Contract Bool => ResourceList def resources(include_ignored=false) @lock.synchronize do ensure_resource_list_updated! @@ -134,11 +142,12 @@ module Middleman # Get the URL path for an on-disk file # @param [String] file # @return [String] + Contract String => String def file_to_path(file) file = File.join(@app.root, file) prefix = @app.source_dir.sub(/\/$/, '') + '/' - return false unless file.start_with?(prefix) + raise "'#{file}' not inside project folder '#{prefix}" unless file.start_with?(prefix) path = file.sub(prefix, '') @@ -153,6 +162,7 @@ module Middleman # Get a path without templating extensions # @param [String] file # @return [String] + Contract String => String def extensionless_path(file) path = file.dup remove_templating_extensions(path) @@ -197,6 +207,7 @@ module Middleman # Removes the templating extensions, while keeping the others # @param [String] path # @return [String] + Contract String => String def remove_templating_extensions(path) # Strip templating extensions as long as Tilt knows them path = path.sub(File.extname(path), '') while ::Tilt[path] @@ -206,6 +217,7 @@ module Middleman # Remove the locale token from the end of the path # @param [String] path # @return [String] + Contract String => String def strip_away_locale(path) if @app.extensions[:i18n] path_bits = path.split('.') diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index d80b46d3..78becaf5 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -1,6 +1,7 @@ require 'pathname' require 'middleman-core/file_renderer' require 'middleman-core/template_renderer' +require 'middleman-core/contracts' module Middleman # The TemplateContext Class @@ -12,6 +13,7 @@ module Middleman # the request, passed from template, to layouts and partials. class TemplateContext extend Forwardable + include Contracts # Allow templates to directly access the current app instance. # @return [Middleman::Application] @@ -94,6 +96,7 @@ module Middleman # @param [String, Symbol] name The partial to render. # @param [Hash] options # @return [String] + Contract Any, Or[Symbol, String], Hash => String def render(_, name, options={}, &block) name = name.to_s @@ -114,6 +117,7 @@ module Middleman # @api private # @param [String] partial_path # @return [String] + Contract String => Maybe[String] def locate_partial(partial_path) return unless resource = sitemap.find_resource_by_path(current_path) @@ -141,6 +145,7 @@ module Middleman # @param [Hash] opts Template options. # @param [Proc] block A block will be evaluated to return internal contents. # @return [String] The resulting content string. + Contract String, Hash, Hash, Proc => String def render_file(path, locs, opts, &block) file_renderer = ::Middleman::FileRenderer.new(@app, path) file_renderer.render(locs, opts, self, &block) diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 27384ccf..0eb2fc8f 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -2,10 +2,12 @@ require 'tilt' require 'active_support/core_ext/string/output_safety' require 'middleman-core/template_context' require 'middleman-core/file_renderer' +require 'middleman-core/contracts' module Middleman class TemplateRenderer extend Forwardable + include Contracts def self.cache @_cache ||= ::Tilt::Cache.new @@ -26,6 +28,7 @@ module Middleman # @param [Hash] locs # @param [Hash] opts # @return [String] + Contract Hash, Hash => String def render(locs={}, opts={}) path = @path.dup extension = File.extname(path) @@ -78,7 +81,8 @@ module Middleman # # @param [Symbol] engine # @param [Hash] opts - # @return [String] + # @return [String, Boolean] + Contract Symbol, Hash => Or[String, Bool] def fetch_layout(engine, opts) # The layout name comes from either the system default or the options local_layout = opts.key?(:layout) ? opts[:layout] : @app.config[:layout] @@ -117,6 +121,7 @@ module Middleman # @param [String] name # @param [Symbol] preferred_engine # @return [String] + Contract Or[String, Symbol], Symbol => Maybe[String] def locate_layout(name, preferred_engine=nil) self.class.locate_layout(@app, name, preferred_engine) end @@ -125,6 +130,7 @@ module Middleman # @param [String] name # @param [Symbol] preferred_engine # @return [String] + Contract IsA['Middleman::Application'], Or[String, Symbol], Symbol => Maybe[String] def self.locate_layout(app, name, preferred_engine=nil) resolve_opts = {} resolve_opts[:preferred_engine] = preferred_engine unless preferred_engine.nil? @@ -143,6 +149,7 @@ module Middleman # @param [String] request_path # @param [Hash] options # @return [Array, Boolean] + Contract String, Hash => ArrayOf[Or[String, Symbol]] def resolve_template(request_path, options={}) self.class.resolve_template(@app, request_path, options) end @@ -151,6 +158,7 @@ module Middleman # @param [String] request_path # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine. # @return [String, Boolean] Either the path to the template, or false + Contract IsA['Middleman::Application'], Or[Symbol, String], Hash => Maybe[String] def self.resolve_template(app, request_path, options={}) # Find the path by searching or using the cache request_path = request_path.to_s @@ -194,7 +202,7 @@ module Middleman elsif File.exist?(on_disk_path) on_disk_path else - false + nil end end end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 3620259e..8c7b8c4d 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -11,348 +11,12 @@ require 'pathname' require 'tilt' require 'rack/mime' +# DbC +require 'middleman-core/contracts' + module Middleman module Util - class << self - # Whether the source file is binary. - # - # @param [String] filename The file to check. - # @return [Boolean] - def binary?(filename) - ext = File.extname(filename) - - # We hardcode detecting of gzipped SVG files - return true if ext == '.svgz' - - return false if Tilt.registered?(ext.sub('.', '')) - - dot_ext = (ext.to_s[0] == '.') ? ext.dup : ".#{ext}" - - if mime = ::Rack::Mime.mime_type(dot_ext, nil) - !nonbinary_mime?(mime) - else - file_contents_include_binary_bytes?(filename) - end - end - - # Facade for ActiveSupport/Notification - def instrument(name, payload={}, &block) - suffixed_name = (name =~ /\.middleman$/) ? name.dup : "#{name}.middleman" - ::ActiveSupport::Notifications.instrument(suffixed_name, payload, &block) - end - - # Recursively convert a normal Hash into a HashWithIndifferentAccess - # - # @private - # @param [Hash] data Normal hash - # @return [Middleman::Util::HashWithIndifferentAccess] - def recursively_enhance(data) - if data.is_a? Hash - data = ::Middleman::Util::HashWithIndifferentAccess.new(data) - data.each do |key, val| - data[key] = recursively_enhance(val) - end - data - elsif data.is_a? Array - data.each_with_index do |val, i| - data[i] = recursively_enhance(val) - end - data - else - data - end - end - - # Normalize a path to not include a leading slash - # @param [String] path - # @return [String] - def normalize_path(path) - # The tr call works around a bug in Ruby's Unicode handling - path.sub(%r{^/}, '').tr('', '') - end - - # This is a separate method from normalize_path in case we - # change how we normalize paths - def strip_leading_slash(path) - path.sub(%r{^/}, '') - end - - # Extract the text of a Rack response as a string. - # Useful for extensions implemented as Rack middleware. - # @param response The response from #call - # @return [String] The whole response as a string. - def extract_response_text(response) - # The rack spec states all response bodies must respond to each - result = '' - response.each do |part, _| - result << part - end - result - end - - # Takes a matcher, which can be a literal string - # or a string containing glob expressions, or a - # regexp, or a proc, or anything else that responds - # to #match or #call, and returns whether or not the - # given path matches that matcher. - # - # @param [String, #match, #call] matcher A matcher String, RegExp, Proc, etc. - # @param [String] path A path as a string - # @return [Boolean] Whether the path matches the matcher - def path_match(matcher, path) - case - when matcher.is_a?(String) - if matcher.include? '*' - File.fnmatch(matcher, path) - else - path == matcher - end - when matcher.respond_to?(:match) - !matcher.match(path).nil? - when matcher.respond_to?(:call) - matcher.call(path) - else - File.fnmatch(matcher.to_s, path) - end - end - - # Get a recusive list of files inside a path. - # Works with symlinks. - # - # @param path Some path string or Pathname - # @param ignore A proc/block that returns true if a given path should be ignored - if a path - # is ignored, nothing below it will be searched either. - # @return [Array] An array of Pathnames for each file (no directories) - def all_files_under(path, &ignore) - path = Pathname(path) - - return [] if ignore && ignore.call(path) - - if path.directory? - path.children.flat_map do |child| - all_files_under(child, &ignore) - end.compact - elsif path.file? - [path] - else - [] - end - end - - # Get the path of a file of a given type - # - # @param [Symbol] kind The type of file - # @param [String] source The path to the file - # @param [Hash] options Data to pass through. - # @return [String] - def asset_path(app, kind, source, options={}) - return source if source.to_s.include?('//') || source.to_s.start_with?('data:') - - asset_folder = case kind - when :css - app.config[:css_dir] - when :js - app.config[:js_dir] - when :images - app.config[:images_dir] - when :fonts - app.config[:fonts_dir] - else - kind.to_s - end - - source = source.to_s.tr(' ', '') - ignore_extension = (kind == :images || kind == :fonts) # don't append extension - source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") - asset_folder = '' if source.start_with?('/') # absolute path - - asset_url(app, source, asset_folder, options) - end - - # Get the URL of an asset given a type/prefix - # - # @param [String] path The path (such as "photo.jpg") - # @param [String] prefix The type prefix (such as "images") - # @param [Hash] options Data to pass through. - # @return [String] The fully qualified asset url - def asset_url(app, path, prefix='', _options={}) - # Don't touch assets which already have a full path - if path.include?('//') || path.start_with?('data:') - path - else # rewrite paths to use their destination path - if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) - resource.url - else - path = File.join(prefix, path) - if resource = app.sitemap.find_resource_by_path(path) - resource.url - else - File.join(app.config[:http_prefix], path) - end - end - end - 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(app, path_or_resource, options={}) - # Handle Resources and other things which define their own url method - url = if path_or_resource.respond_to?(:url) - path_or_resource.url - else - path_or_resource.dup - end.gsub(' ', '%20') - - # Try to parse URL - begin - uri = URI(url) - rescue URI::InvalidURIError - # Nothing we can do with it, it's not really a URI - return url - end - - relative = options[: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? && app.config[:relative_links] - - # Try to find a sitemap resource corresponding to the desired path - this_resource = options[:current_resource] - - if path_or_resource.is_a?(::Middleman::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 = app.sitemap.find_resource_by_path(url_path.to_s) - resource_url = resource.url if resource - elsif options[:find_resource] && uri.path - resource = app.sitemap.find_resource_by_path(uri.path) - resource_url = resource.url if resource - end - - if resource - uri.path = relative_path_from_resource(this_resource, resource_url, effective_relative) - 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[: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[:anchor] || options[:fragment] - uri.fragment = fragment.to_s if fragment - - # Finally make the URL back into a string - uri.to_s - end - - # Expand a path to include the index file if it's a directory - # - # @param [String] path Request path/ - # @param [Middleman::Application] app The requesting app. - # @return [String] Path with index file if necessary. - def full_path(path, app) - resource = app.sitemap.find_resource_by_destination_path(path) - - unless resource - # Try it with /index.html at the end - indexed_path = File.join(path.sub(%r{/$}, ''), app.config[:index_file]) - resource = app.sitemap.find_resource_by_destination_path(indexed_path) - end - - if resource - '/' + resource.destination_path - else - '/' + normalize_path(path) - end - end - - def rewrite_paths(body, _path, exts, &_block) - body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| - opening_character = $1 - asset_path = $2 - - if result = yield(asset_path) - "#{opening_character}#{result}" - else - match - end - end - end - - private - - # Is mime type known to be non-binary? - # - # @param [String] mime The mimetype to check. - # @return [Boolean] - def nonbinary_mime?(mime) - case - when mime.start_with?('text/') - true - when mime.include?('xml') - true - when mime.include?('json') - true - when mime.include?('javascript') - true - else - false - end - end - - # Read a few bytes from the file and see if they are binary. - # - # @param [String] filename The file to check. - # @return [Boolean] - def file_contents_include_binary_bytes?(filename) - 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 - - false - end - - # Get a relative path to a resource. - # - # @param [Middleman::Sitemap::Resource] curr_resource The resource. - # @param [String] resource_url The target url. - # @param [Boolean] relative If the path should be relative. - # @return [String] - def relative_path_from_resource(curr_resource, resource_url, relative) - # Switch to the relative path between resource and the given resource - # if we've been asked to. - if relative && curr_resource - # Output urls relative to the destination path, not the source path - current_dir = Pathname('/' + curr_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 - - relative_path - else - resource_url - end - end - end + include Contracts # A hash with indifferent access and magic predicates. # Copied from Thor @@ -428,5 +92,373 @@ module Middleman end end end + + # Whether the source file is binary. + # + # @param [String] filename The file to check. + # @return [Boolean] + Contract String => Bool + def self.binary?(filename) + ext = File.extname(filename) + + # We hardcode detecting of gzipped SVG files + return true if ext == '.svgz' + + return false if Tilt.registered?(ext.sub('.', '')) + + dot_ext = (ext.to_s[0] == '.') ? ext.dup : ".#{ext}" + + if mime = ::Rack::Mime.mime_type(dot_ext, nil) + !nonbinary_mime?(mime) + else + file_contents_include_binary_bytes?(filename) + end + end + + # Takes a matcher, which can be a literal string + # or a string containing glob expressions, or a + # regexp, or a proc, or anything else that responds + # to #match or #call, and returns whether or not the + # given path matches that matcher. + # + # @param [String, #match, #call] matcher A matcher String, RegExp, Proc, etc. + # @param [String] path A path as a string + # @return [Boolean] Whether the path matches the matcher + Contract Or[String, RespondTo[:match], RespondTo[:call], RespondTo[:to_s]], String => Bool + def self.path_match(matcher, path) + case + when matcher.is_a?(String) + if matcher.include? '*' + File.fnmatch(matcher, path) + else + path == matcher + end + when matcher.respond_to?(:match) + !matcher.match(path).nil? + when matcher.respond_to?(:call) + matcher.call(path) + else + File.fnmatch(matcher.to_s, path) + end + end + + # Recursively convert a normal Hash into a HashWithIndifferentAccess + # + # @private + # @param [Hash] data Normal hash + # @return [Middleman::Util::HashWithIndifferentAccess] + Contract Or[Hash, Array] => Or[HashWithIndifferentAccess, Array] + def self.recursively_enhance(data) + if data.is_a? Hash + enhanced = ::Middleman::Util::HashWithIndifferentAccess.new(data) + + enhanced.each do |key, val| + enhanced[key] = if val.is_a?(Hash) || val.is_a?(Array) + recursively_enhance(val) + else + val + end + end + + enhanced + elsif data.is_a? Array + enhanced = data.dup + + enhanced.each_with_index do |val, i| + enhanced[i] = if val.is_a?(Hash) || val.is_a?(Array) + recursively_enhance(val) + else + val + end + end + + enhanced + end + end + + # Normalize a path to not include a leading slash + # @param [String] path + # @return [String] + Contract String => String + def self.normalize_path(path) + # The tr call works around a bug in Ruby's Unicode handling + path.sub(%r{^/}, '').tr('', '') + end + + # This is a separate method from normalize_path in case we + # change how we normalize paths + Contract String => String + def self.strip_leading_slash(path) + path.sub(%r{^/}, '') + end + + # Facade for ActiveSupport/Notification + def self.instrument(name, payload={}, &block) + suffixed_name = (name =~ /\.middleman$/) ? name.dup : "#{name}.middleman" + ::ActiveSupport::Notifications.instrument(suffixed_name, payload, &block) + end + + # Extract the text of a Rack response as a string. + # Useful for extensions implemented as Rack middleware. + # @param response The response from #call + # @return [String] The whole response as a string. + Contract IsA['Rack::BodyProxy'] => String + def self.extract_response_text(response) + # The rack spec states all response bodies must respond to each + result = '' + response.each do |part, _| + result << part + end + result + end + + # Get a recusive list of files inside a path. + # Works with symlinks. + # + # @param path Some path string or Pathname + # @param ignore A proc/block that returns true if a given path should be ignored - if a path + # is ignored, nothing below it will be searched either. + # @return [Array] An array of Pathnames for each file (no directories) + Contract Or[String, Pathname], Proc => ArrayOf[Pathname] + def self.all_files_under(path, &ignore) + path = Pathname(path) + + return [] if ignore && ignore.call(path) + + if path.directory? + path.children.flat_map do |child| + all_files_under(child, &ignore) + end.compact + elsif path.file? + [path] + else + [] + end + end + + # Get the path of a file of a given type + # + # @param [Middleman::Application] app The app. + # @param [Symbol] kind The type of file + # @param [String, Symbol] source The path to the file + # @param [Hash] options Data to pass through. + # @return [String] + Contract IsA['Middleman::Application'], Symbol, Or[String, Symbol], Hash => String + def self.asset_path(app, kind, source, options={}) + return source if source.to_s.include?('//') || source.to_s.start_with?('data:') + + asset_folder = case kind + when :css + app.config[:css_dir] + when :js + app.config[:js_dir] + when :images + app.config[:images_dir] + when :fonts + app.config[:fonts_dir] + else + kind.to_s + end + + source = source.to_s.tr(' ', '') + ignore_extension = (kind == :images || kind == :fonts) # don't append extension + source << ".#{kind}" unless ignore_extension || source.end_with?(".#{kind}") + asset_folder = '' if source.start_with?('/') # absolute path + + asset_url(app, source, asset_folder, options) + end + + # Get the URL of an asset given a type/prefix + # + # @param [String] path The path (such as "photo.jpg") + # @param [String] prefix The type prefix (such as "images") + # @param [Hash] options Data to pass through. + # @return [String] The fully qualified asset url + Contract IsA['Middleman::Application'], String, String, Hash => String + def self.asset_url(app, path, prefix='', _options={}) + # Don't touch assets which already have a full path + if path.include?('//') || path.start_with?('data:') + path + else # rewrite paths to use their destination path + if resource = app.sitemap.find_resource_by_destination_path(url_for(app, path)) + resource.url + else + path = File.join(prefix, path) + if resource = app.sitemap.find_resource_by_path(path) + resource.url + else + File.join(app.config[:http_prefix], path) + end + end + end + 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. + Contract IsA['Middleman::Application'], Or[String, IsA['Middleman::Sitemap::Resource']], Hash => String + def self.url_for(app, path_or_resource, options={}) + # Handle Resources and other things which define their own url method + url = if path_or_resource.respond_to?(:url) + path_or_resource.url + else + path_or_resource.dup + end.gsub(' ', '%20') + + # Try to parse URL + begin + uri = URI(url) + rescue URI::InvalidURIError + # Nothing we can do with it, it's not really a URI + return url + end + + relative = options[: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? && app.config[:relative_links] + + # Try to find a sitemap resource corresponding to the desired path + this_resource = options[:current_resource] + + if path_or_resource.is_a?(::Middleman::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 = app.sitemap.find_resource_by_path(url_path.to_s) + resource_url = resource.url if resource + elsif options[:find_resource] && uri.path + resource = app.sitemap.find_resource_by_path(uri.path) + resource_url = resource.url if resource + end + + if resource + uri.path = if this_resource + relative_path_from_resource(this_resource, resource_url, effective_relative) + else + 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[: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[:anchor] || options[:fragment] + uri.fragment = fragment.to_s if fragment + + # Finally make the URL back into a string + uri.to_s + end + + # Expand a path to include the index file if it's a directory + # + # @param [String] path Request path/ + # @param [Middleman::Application] app The requesting app. + # @return [String] Path with index file if necessary. + Contract String, IsA['Middleman::Application'] => String + def self.full_path(path, app) + resource = app.sitemap.find_resource_by_destination_path(path) + + unless resource + # Try it with /index.html at the end + indexed_path = File.join(path.sub(%r{/$}, ''), app.config[:index_file]) + resource = app.sitemap.find_resource_by_destination_path(indexed_path) + end + + if resource + '/' + resource.destination_path + else + '/' + normalize_path(path) + end + end + + Contract String, String, ArrayOf[String], Proc => String + def self.rewrite_paths(body, _path, exts, &_block) + body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| + opening_character = $1 + asset_path = $2 + + if result = yield(asset_path) + "#{opening_character}#{result}" + else + match + end + end + end + + # Is mime type known to be non-binary? + # + # @param [String] mime The mimetype to check. + # @return [Boolean] + Contract String => Bool + def self.nonbinary_mime?(mime) + case + when mime.start_with?('text/') + true + when mime.include?('xml') + true + when mime.include?('json') + true + when mime.include?('javascript') + true + else + false + end + end + + # Read a few bytes from the file and see if they are binary. + # + # @param [String] filename The file to check. + # @return [Boolean] + Contract String => Bool + def self.file_contents_include_binary_bytes?(filename) + 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 + + false + end + + # Get a relative path to a resource. + # + # @param [Middleman::Sitemap::Resource] curr_resource The resource. + # @param [String] resource_url The target url. + # @param [Boolean] relative If the path should be relative. + # @return [String] + Contract IsA['Middleman::Sitemap::Resource'], String, Bool => String + def self.relative_path_from_resource(curr_resource, resource_url, relative) + # Switch to the relative path between resource and the given resource + # if we've been asked to. + if relative + # Output urls relative to the destination path, not the source path + current_dir = Pathname('/' + curr_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 + + relative_path + else + resource_url + end + end end end From c9d0dc7fb093f08ddd5018d3a24b2b6bfed217da Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 9 Jul 2014 09:50:51 -0700 Subject: [PATCH 125/662] remove autoload sprockets, it'll use our new auto_activation code --- Gemfile | 6 +++--- middleman-core/lib/middleman-core/application.rb | 12 ------------ .../lib/middleman-core/renderers/markdown.rb | 2 +- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Gemfile b/Gemfile index a55b06a9..9bf93ff3 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,9 @@ gem 'cucumber', '~> 1.3' gem 'contracts', '~> 0.4' # Optional middleman dependencies, included for tests +gem 'haml', '>= 4.0.5', require: false +gem 'coffee-script', '~> 2.2.0', require: false +gem 'kramdown', '~> 1.2', require: false gem 'less', '2.3.0', require: false gem 'slim', '>= 2.0', require: false gem 'liquid', '>= 2.6', require: false @@ -32,8 +35,5 @@ gem 'coveralls', '~> 0.7', require: false gem 'codeclimate-test-reporter', '~> 0.3', require: false, group: :test # Middleman itself -gem 'middleman', path: 'middleman' gem 'middleman-cli', path: 'middleman-cli' gem 'middleman-core', path: 'middleman-core' -gem 'middleman-compass', github: 'middleman/middleman-compass', require: false -gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index f5cfc1c3..fd072d57 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -158,9 +158,6 @@ module Middleman } }, 'Callbacks that can exclude paths from the sitemap' - config.define_setting :autoload_sprockets, true, 'Automatically load sprockets at startup?' - config[:autoload_sprockets] = (ENV['AUTOLOAD_SPROCKETS'] == 'true') if ENV['AUTOLOAD_SPROCKETS'] - attr_reader :config_context attr_reader :sitemap attr_reader :cache @@ -213,15 +210,6 @@ module Middleman @extensions.auto_activate(:before_configuration) - if config[:autoload_sprockets] - begin - require 'middleman-sprockets' - @extensions.activate :sprockets - rescue LoadError - # It's OK if somebody is using middleman-core without middleman-sprockets - end - end - run_hook :initialized run_hook :before_configuration diff --git a/middleman-core/lib/middleman-core/renderers/markdown.rb b/middleman-core/lib/middleman-core/renderers/markdown.rb index 80b57ce7..6a285a89 100644 --- a/middleman-core/lib/middleman-core/renderers/markdown.rb +++ b/middleman-core/lib/middleman-core/renderers/markdown.rb @@ -39,7 +39,7 @@ module Middleman rescue LoadError # If they just left it at the default engine and don't happen to have it, # then they're using middleman-core bare and we shouldn't bother them. - if config.setting(:markdown_engine).value_set? + if app.config.setting(:markdown_engine).value_set? logger.warn "Requested Markdown engine (#{app.config[:markdown_engine]}) not found. Maybe the gem needs to be installed and required?" end end From 0dc5843b57243df6e6db364fca907d1c1609cd5d Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 9 Jul 2014 10:09:41 -0700 Subject: [PATCH 126/662] autorequire less --- Gemfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 9bf93ff3..6fde5899 100644 --- a/Gemfile +++ b/Gemfile @@ -5,12 +5,12 @@ gem 'rake', '~> 10.3', require: false gem 'yard', '~> 0.8', require: false # Test tools -gem 'pry', '~> 0.10', group: :development -gem 'aruba', '~> 0.6' -gem 'rspec', '~> 3.0' -gem 'fivemat', '~> 1.3' -gem 'cucumber', '~> 1.3' -gem 'contracts', '~> 0.4' +gem 'pry', '~> 0.10', group: :development, require: false +gem 'aruba', '~> 0.6', require: false +gem 'rspec', '~> 3.0', require: false +gem 'fivemat', '~> 1.3', require: false +gem 'cucumber', '~> 1.3', require: false +gem 'contracts', '~> 0.4', require: false # Optional middleman dependencies, included for tests gem 'haml', '>= 4.0.5', require: false From fafeea085728e50bde52324d2fb08cbf69c4ef09 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 9 Jul 2014 10:46:03 -0700 Subject: [PATCH 127/662] Handle Rack responses from Sprockets --- 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 8c7b8c4d..f2d1ac51 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -202,7 +202,7 @@ module Middleman # Useful for extensions implemented as Rack middleware. # @param response The response from #call # @return [String] The whole response as a string. - Contract IsA['Rack::BodyProxy'] => String + Contract Or[ArrayOf[String], IsA['Rack::BodyProxy']] => String def self.extract_response_text(response) # The rack spec states all response bodies must respond to each result = '' From 08b75f06eff4aab292a4e1a0003e4a2fa2d9f742 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Wed, 9 Jul 2014 10:59:00 -0700 Subject: [PATCH 128/662] more generic duck-typed rack extractor --- 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 f2d1ac51..b98994d0 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -202,7 +202,7 @@ module Middleman # Useful for extensions implemented as Rack middleware. # @param response The response from #call # @return [String] The whole response as a string. - Contract Or[ArrayOf[String], IsA['Rack::BodyProxy']] => String + Contract RespondTo[:each] => String def self.extract_response_text(response) # The rack spec states all response bodies must respond to each result = '' From 6ccab8e0711fa0714f21c7c017800e46d5555534 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 10 Jul 2014 12:35:47 -0700 Subject: [PATCH 129/662] Name things :) --- .../lib/middleman-core/application.rb | 21 +++++-- .../lib/middleman-core/contracts.rb | 61 ++++++++++++++++--- .../core_extensions/default_helpers.rb | 2 +- .../core_extensions/file_watcher.rb | 24 ++++---- .../middleman-core/core_extensions/routing.rb | 11 ++-- .../lib/middleman-core/extensions.rb | 4 +- .../middleman-core/extensions/minify_css.rb | 5 ++ .../extensions/minify_javascript.rb | 5 ++ .../middleware/inline_url_rewriter.rb | 24 +++++--- middleman-core/lib/middleman-core/rack.rb | 8 +-- .../sitemap/extensions/ignores.rb | 2 +- .../lib/middleman-core/sitemap/resource.rb | 5 +- middleman-core/lib/middleman-core/util.rb | 2 +- 13 files changed, 128 insertions(+), 46 deletions(-) diff --git a/middleman-core/lib/middleman-core/application.rb b/middleman-core/lib/middleman-core/application.rb index fd072d57..1121bf23 100644 --- a/middleman-core/lib/middleman-core/application.rb +++ b/middleman-core/lib/middleman-core/application.rb @@ -15,6 +15,8 @@ require 'hooks' # Our custom logger require 'middleman-core/logger' +require 'middleman-core/contracts' + require 'middleman-core/sitemap/store' require 'middleman-core/configuration' @@ -30,6 +32,7 @@ require 'middleman-core/template_renderer' module Middleman class Application extend Forwardable + include Contracts class << self # Global configuration for the whole Middleman project. @@ -165,7 +168,11 @@ module Middleman attr_reader :config attr_reader :generic_template_context attr_reader :extensions + + Contract None => SetOf['Middleman::Application::MiddlewareDescriptor'] attr_reader :middleware + + Contract None => SetOf['Middleman::Application::MapDescriptor'] attr_reader :mappings # Reference to Logger singleton @@ -179,8 +186,8 @@ module Middleman # Search the root of the project for required files $LOAD_PATH.unshift(root) unless $LOAD_PATH.include?(root) - @middleware = [] - @mappings = [] + @middleware = Set.new + @mappings = Set.new @template_context_class = Class.new(Middleman::TemplateContext) @generic_template_context = @template_context_class.new(self) @@ -296,20 +303,26 @@ module Middleman File.join(root, config[:source]) end + MiddlewareDescriptor = Struct.new(:class, :options, :block) + # Use Rack middleware # # @param [Class] middleware Middleware module # @return [void] + Contract Any, Args[Any], Proc => Any def use(middleware, *args, &block) - @middleware << [middleware, args, block] + @middleware << MiddlewareDescriptor.new(middleware, args, block) end + MapDescriptor = Struct.new(:path, :block) + # Add Rack App mapped to specific path # # @param [String] map Path to map # @return [void] + Contract String, Proc => Any def map(map, &block) - @mappings << [map, block] + @mappings << MapDescriptor.new(map, block) end # Work around this bug: http://bugs.ruby-lang.org/issues/4521 diff --git a/middleman-core/lib/middleman-core/contracts.rb b/middleman-core/lib/middleman-core/contracts.rb index 3eec15d2..2f13bc1c 100644 --- a/middleman-core/lib/middleman-core/contracts.rb +++ b/middleman-core/lib/middleman-core/contracts.rb @@ -1,22 +1,56 @@ if ENV['TEST'] || ENV['CONTRACTS'] == 'true' require 'contracts' - class IsA - def self.[](val) - @lookup ||= {} - @lookup[val] ||= new(val) + module Contracts + class IsA + def self.[](val) + @lookup ||= {} + @lookup[val] ||= new(val) + end + + def initialize(val) + @val = val + end + + def valid?(val) + val.is_a? @val.constantize + end end - def initialize(val) - @val = val + class ArrayOf + def initialize(contract) + @contract = contract.is_a?(String) ? IsA[contract] : contract + end end - def valid?(val) - val.is_a? @val.constantize + class SetOf < CallableClass + def initialize(contract) + @contract = contract.is_a?(String) ? IsA[contract] : contract + end + + def valid?(vals) + return false unless vals.is_a?(Set) + vals.all? do |val| + res, _ = Contract.valid?(val, @contract) + res + end + end + + def to_s + "a set of #{@contract}" + end + + def testable? + Testable.testable? @contract + end + + def test_data + Set.new([], [Testable.test_data(@contract)], [Testable.test_data(@contract), Testable.test_data(@contract)]) + end end + + ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']] end - - ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']] else module Contracts def self.included(base) @@ -91,5 +125,12 @@ else class IsA < Callable end + + class SetOf < Callable + end end end + +module Contracts + PATH_MATCHER = Or[String, RespondTo[:match], RespondTo[:call], RespondTo[:to_s]] +end 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 99120528..fa359a77 100644 --- a/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-core/core_extensions/default_helpers.rb @@ -140,7 +140,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension path << index_file if path.end_with?('/') path = ::Middleman::Util.strip_leading_slash(path) - classes = [] + classes = Set.new parts = path.split('.').first.split('/') parts.each_with_index { |_, i| classes << parts.first(i + 1).join('_') } 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 68a83280..fca753ab 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -55,28 +55,30 @@ module Middleman @app = app @known_paths = Set.new - @_changed = [] - @_deleted = [] + @on_change_callbacks = Set.new + @on_delete_callbacks = Set.new end + CallbackDescriptor = Struct.new(:proc, :matcher) + # Add callback to be run on file change # # @param [nil,Regexp] matcher A Regexp to match the change path against # @return [Array] - Contract Or[Regexp, Proc] => ArrayOf[ArrayOf[Or[Proc, Regexp, nil]]] + Contract Or[Regexp, Proc] => SetOf['Middleman::CoreExtensions::FileWatcher::API::CallbackDescriptor'] def changed(matcher=nil, &block) - @_changed << [block, matcher] if block_given? - @_changed + @on_change_callbacks << CallbackDescriptor.new(block, matcher) if block_given? + @on_change_callbacks end # Add callback to be run on file deletion # # @param [nil,Regexp] matcher A Regexp to match the deleted path against # @return [Array] - Contract Or[Regexp, Proc] => ArrayOf[ArrayOf[Or[Proc, Regexp, nil]]] + Contract Or[Regexp, Proc] => SetOf['Middleman::CoreExtensions::FileWatcher::API::CallbackDescriptor'] def deleted(matcher=nil, &block) - @_deleted << [block, matcher] if block_given? - @_deleted + @on_delete_callbacks << CallbackDescriptor.new(block, matcher) if block_given? + @on_delete_callbacks end # Notify callbacks that a file changed @@ -159,9 +161,9 @@ module Middleman # @return [void] def run_callbacks(path, callbacks_name) path = path.to_s - send(callbacks_name).each do |callback, matcher| - next unless matcher.nil? || path.match(matcher) - @app.instance_exec(path, &callback) + send(callbacks_name).each do |callback| + next unless callback[:matcher].nil? || path.match(callback[:matcher]) + @app.instance_exec(path, &callback[:proc]) end end end diff --git a/middleman-core/lib/middleman-core/core_extensions/routing.rb b/middleman-core/lib/middleman-core/core_extensions/routing.rb index 61e80028..2bf11eea 100644 --- a/middleman-core/lib/middleman-core/core_extensions/routing.rb +++ b/middleman-core/lib/middleman-core/core_extensions/routing.rb @@ -9,7 +9,7 @@ module Middleman def initialize(app, options_hash={}, &block) super - @page_configs = [] + @page_configs = Set.new end def before_configuration @@ -20,12 +20,14 @@ module Middleman Contract ResourceList => ResourceList def manipulate_resource_list(resources) resources.each do |resource| - @page_configs.each do |matcher, metadata| - resource.add_metadata(metadata) if Middleman::Util.path_match(matcher, "/#{resource.path}") + @page_configs.each do |p| + resource.add_metadata(p[:metadata]) if Middleman::Util.path_match(p[:path], "/#{resource.path}") end end end + PageDescriptor = Struct.new(:path, :metadata) + # The page method allows options to be set for a given source path, regex, or glob. # Options that may be set include layout, locals, proxy, andx ignore. # @@ -43,6 +45,7 @@ module Middleman # @option opts [Hash] locals Local variables for the template. These will be available when the template renders. # @option opts [Hash] data Extra metadata to add to the page. This is the same as frontmatter, though frontmatter will take precedence over metadata defined here. Available via {Resource#data}. # @return [void] + Contract String, Hash => Any def page(path, opts={}) options = opts.dup @@ -63,7 +66,7 @@ module Middleman path = '/' + Util.strip_leading_slash(path) if path.is_a?(String) - @page_configs << [path, metadata] + @page_configs << PageDescriptor.new(path, metadata) end end end diff --git a/middleman-core/lib/middleman-core/extensions.rb b/middleman-core/lib/middleman-core/extensions.rb index 37690957..77c99a64 100644 --- a/middleman-core/lib/middleman-core/extensions.rb +++ b/middleman-core/lib/middleman-core/extensions.rb @@ -9,9 +9,9 @@ module Middleman @registered = {} @auto_activate = { # Activate before the Sitemap is instantiated - before_sitemap: [], + before_sitemap: Set.new, # Activate the extension before `config.rb` and the `:before_configuration` hook. - before_configuration: [] + before_configuration: Set.new } AutoActivation = Struct.new(:name, :modes) diff --git a/middleman-core/lib/middleman-core/extensions/minify_css.rb b/middleman-core/lib/middleman-core/extensions/minify_css.rb index 08a28d95..75b2ca4b 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_css.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_css.rb @@ -32,6 +32,11 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension # Init # @param [Class] app # @param [Hash] options + Contract RespondTo[:call], ({ + ignore: ArrayOf[PATH_MATCHER], + inline: Bool, + compressor: Or[Proc, RespondTo[:to_proc], RespondTo[:compress]] + }) => Any def initialize(app, options={}) @app = app @ignore = options.fetch(:ignore) diff --git a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb index 208b4fda..5c90bd13 100644 --- a/middleman-core/lib/middleman-core/extensions/minify_javascript.rb +++ b/middleman-core/lib/middleman-core/extensions/minify_javascript.rb @@ -23,6 +23,11 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension # Init # @param [Class] app # @param [Hash] options + Contract RespondTo[:call], ({ + ignore: ArrayOf[PATH_MATCHER], + inline: Bool, + compressor: Or[Proc, RespondTo[:to_proc], RespondTo[:compress]] + }) => Any def initialize(app, options={}) @app = app @ignore = options.fetch(:ignore) diff --git a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb index 094a9d9c..1151800c 100644 --- a/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb +++ b/middleman-core/lib/middleman-core/middleware/inline_url_rewriter.rb @@ -8,21 +8,31 @@ module Middleman class InlineURLRewriter include Contracts + IGNORE_DESCRIPTOR = Or[Regexp, RespondTo[:call], String] + + Contract RespondTo[:call], ({ + middleman_app: IsA['Middleman::Application'], + id: Maybe[Symbol], + proc: Or[Proc, Method], + url_extensions: ArrayOf[String], + source_extensions: ArrayOf[String], + ignore: ArrayOf[IGNORE_DESCRIPTOR] + }) => Any def initialize(app, options={}) @rack_app = app - @middleman_app = options[:middleman_app] + @middleman_app = options.fetch(:middleman_app) - @uid = options[:id] - @proc = options[:proc] + @uid = options.fetch(:id, nil) + @proc = options.fetch(:proc) raise 'InlineURLRewriter requires a :proc to call with inline URL results' unless @proc - @exts = options[:url_extensions] + @exts = options.fetch(:url_extensions) - @source_exts = options[:source_extensions] + @source_exts = options.fetch(:source_extensions) @source_exts_regex_text = Regexp.union(@source_exts).to_s - @ignore = options[:ignore] + @ignore = options.fetch(:ignore) end def call(env) @@ -66,7 +76,7 @@ module Middleman [status, headers, response] end - Contract Or[Regexp, RespondTo[:call], String] => Bool + Contract IGNORE_DESCRIPTOR => Bool def should_ignore?(validator, value) if validator.is_a? Regexp # Treat as Regexp diff --git a/middleman-core/lib/middleman-core/rack.rb b/middleman-core/lib/middleman-core/rack.rb index 3d540685..cd80f61b 100644 --- a/middleman-core/lib/middleman-core/rack.rb +++ b/middleman-core/lib/middleman-core/rack.rb @@ -23,15 +23,15 @@ module Middleman app.use ::Rack::Lint app.use ::Rack::Head - @middleman.middleware.each do |klass, options, middleware_block| - app.use(klass, *options, &middleware_block) + @middleman.middleware.each do |middleware| + app.use(middleware[:class], *middleware[:options], &middleware[:block]) end inner_app = self app.map('/') { run inner_app } - @middleman.mappings.each do |path, map_block| - app.map(path, &map_block) + @middleman.mappings.each do |mapping| + app.map(mapping[:path], &mapping[:block]) end app diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb index 7ac26615..565c3151 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/ignores.rb @@ -10,7 +10,7 @@ module Middleman @app.define_singleton_method :ignore, &method(:create_ignore) # Array of callbacks which can ass ignored - @ignored_callbacks = [] + @ignored_callbacks = Set.new @app.sitemap.define_singleton_method :ignored?, &method(:ignored?) end diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index eee2068a..add3919d 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -30,8 +30,11 @@ module Middleman # @return [String] alias_method :request_path, :destination_path + METADATA_HASH = ({ options: Maybe[Hash], locals: Maybe[Hash], page: Maybe[Hash] }) + # The metadata for this resource # @return [Hash] + Contract None => METADATA_HASH attr_reader :metadata # Initialize resource with parent store and URL @@ -66,7 +69,7 @@ module Middleman # Locals are local variables for rendering this resource's template # Page are data that is exposed through this resource's data member. # Note: It is named 'page' for backwards compatibility with older MM. - Contract Hash => Hash + Contract METADATA_HASH => METADATA_HASH def add_metadata(meta={}) @metadata.deep_merge!(meta) end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index b98994d0..36dd881d 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -124,7 +124,7 @@ module Middleman # @param [String, #match, #call] matcher A matcher String, RegExp, Proc, etc. # @param [String] path A path as a string # @return [Boolean] Whether the path matches the matcher - Contract Or[String, RespondTo[:match], RespondTo[:call], RespondTo[:to_s]], String => Bool + Contract PATH_MATCHER, String => Bool def self.path_match(matcher, path) case when matcher.is_a?(String) From 9ae8a3128b47eebf44dd21f5f032940730e40f6c Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Tue, 25 Mar 2014 16:54:16 -0700 Subject: [PATCH 130/662] Refactor FileWatcher --- .rubocop.yml | 2 + CHANGELOG.md | 1 + middleman-cli/lib/middleman-cli/build.rb | 2 +- .../middleman-core/core_extensions/data.rb | 11 ++- .../core_extensions/file_watcher.rb | 82 +++++++++++++------ .../core_extensions/front_matter.rb | 6 +- .../middleman-core/core_extensions/i18n.rb | 17 ++-- .../lib/middleman-core/extension.rb | 5 +- .../lib/middleman-core/renderers/sass.rb | 4 + .../sitemap/extensions/on_disk.rb | 4 +- .../step_definitions/middleman_steps.rb | 4 +- middleman-core/lib/middleman-core/util.rb | 8 +- 12 files changed, 98 insertions(+), 48 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 100c188c..671d371d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,6 +15,8 @@ AllCops: - 'middleman-core/fixtures/**/*' - 'middleman-core/features/**/*' - 'middleman-core/spec/**/*' +DoubleNegation: + Enabled: false LineLength: Enabled: false MethodLength: diff --git a/CHANGELOG.md b/CHANGELOG.md index 22e2750e..8de8854c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* New FileWatcher API. * Remove the `partials_dir` setting. Partials should live next to content, or be addressed with absolute paths. * Partials must be named with a leading underscore. `_my_snippet.html.erb`, not `my_snippet.html.erb`. * Removed the `proxy` and `ignore` options for the `page` command in `config.rb`. Use the `proxy` and `ignore` commands instead of passing these options to `page`. diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 87b8ea35..3918319d 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -194,7 +194,7 @@ module Middleman::Cli logger.debug '== Checking for generated images' # Double-check for generated images - @app.extensions[:file_watcher].api.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) + @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) @app.sitemap.ensure_resource_list_updated! # Sort paths to be built by the above order. This is primarily so Compass can diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 02af521a..95fabdcd 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -20,10 +20,15 @@ module Middleman # Setup data files before anything else so they are available when # parsing config.rb - file_watcher.changed(data_file_matcher, &app.extensions[:data].data_store.method(:touch_file)) - file_watcher.deleted(data_file_matcher, &app.extensions[:data].data_store.method(:remove_file)) + app.files.changed(data_file_matcher, &app.extensions[:data].data_store.method(:touch_file)) + app.files.deleted(data_file_matcher, &app.extensions[:data].data_store.method(:remove_file)) - file_watcher.reload_path(app.config[:data_dir]) + # Tell the file watcher to observe the :data_dir + app.files.watch :data do |path, _app| + path.match data_file_matcher + end + + app.files.reload_path(app.config[:data_dir]) end helpers do 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 fca753ab..c8be0d89 100644 --- a/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb +++ b/middleman-core/lib/middleman-core/core_extensions/file_watcher.rb @@ -6,38 +6,24 @@ module Middleman module CoreExtensions # API for watching file change events class FileWatcher < Extension - # Regexes in this list will filter out filenames of files that shouldn't cause file change notifications. - IGNORE_LIST = [ - /^bin(\/|$)/, - /^\.bundle(\/|$)/, - /^vendor(\/|$)/, - /^node_modules(\/|$)/, - /^\.sass-cache(\/|$)/, - /^\.cache(\/|$)/, - /^\.git(\/|$)/, - /^\.gitignore$/, - /\.DS_Store/, - /^\.rbenv-.*$/, - /^Gemfile$/, - /^Gemfile\.lock$/, - /~$/, - /(^|\/)\.?#/, - /^tmp\// - ] - attr_reader :api - # Before parsing config, load the data/ directory - def before_configuration - app.config.define_setting :file_watcher_ignore, IGNORE_LIST, 'Regexes for paths that should be ignored when they change.' + def initialize(app, config={}, &block) + super + end + # Before parsing config, load the data/ directory + Contract None => Any + def before_configuration @api = API.new(app) + app.add_to_instance :files, &method(:api) app.add_to_config_context :files, &method(:api) end + Contract None => Any def after_configuration - app.config[:file_watcher_ignore] << %r{^#{app.config[:build_dir]}(\/|$)} @api.reload_path('.') + @api.is_ready = true end # Core File Change API class @@ -47,6 +33,7 @@ module Middleman attr_reader :app attr_reader :known_paths + attr_accessor :is_ready def_delegator :@app, :logger @@ -54,11 +41,40 @@ module Middleman def initialize(app) @app = app @known_paths = Set.new + @is_ready = false + + @watchers = { + source: proc { |path, _| path.match(/^#{app.config[:source]}\//) }, + library: /^(lib|helpers)\/.*\.rb$/ + } + + @ignores = { + emacs_files: /(^|\/)\.?#/, + tilde_files: /~$/, + ds_store: /\.DS_Store\//, + git: /(^|\/)\.git(ignore|modules|\/)/ + } @on_change_callbacks = Set.new @on_delete_callbacks = Set.new end + # Add a proc to watch paths + Contract Symbol, Or[Regexp, Proc] => Any + def watch(name, regex=nil, &block) + @watchers[name] = block_given? ? block : regex + + reload_path('.') if @is_ready + end + + # Add a proc to ignore paths + Contract Symbol, Or[Regexp, Proc] => Any + def ignore(name, regex=nil, &block) + @ignores[name] = block_given? ? block : regex + + reload_path('.') if @is_ready + end + CallbackDescriptor = Struct.new(:proc, :matcher) # Add callback to be run on file change @@ -85,6 +101,7 @@ module Middleman # # @param [Pathname] path The file that changed # @return [void] + Contract Or[Pathname, String] => Any def did_change(path) path = Pathname(path) logger.debug "== File Change: #{path}" @@ -96,6 +113,7 @@ module Middleman # # @param [Pathname] path The file that was deleted # @return [void] + Contract Or[Pathname, String] => Any def did_delete(path) path = Pathname(path) logger.debug "== File Deletion: #{path}" @@ -108,6 +126,7 @@ module Middleman # @param [Pathname] path The path to reload # @param [Boolean] only_new Whether we only look for new files # @return [void] + Contract Or[String, Pathname], Maybe[Bool] => Any def reload_path(path, only_new=false) # chdir into the root directory so Pathname can work with relative paths Dir.chdir @app.root_path do @@ -132,6 +151,7 @@ module Middleman # # @param [Pathname] path The path to reload # @return [void] + Contract Pathname => Any def find_new_files(path) reload_path(path, true) end @@ -149,7 +169,20 @@ module Middleman Contract Or[String, Pathname] => Bool def ignored?(path) path = path.to_s - app.config[:file_watcher_ignore].any? { |r| path =~ r } + + watched = @watchers.values.any? { |validator| matches?(validator, path) } + not_ignored = @ignores.values.none? { |validator| matches?(validator, path) } + + !(watched && not_ignored) + end + + Contract Or[Regexp, RespondTo[:call]], String => Bool + def matches?(validator, path) + if validator.is_a? Regexp + !!validator.match(path) + else + !!validator.call(path, @app) + end end protected @@ -159,6 +192,7 @@ module Middleman # @param [Pathname] path The file that was changed # @param [Symbol] callbacks_name The name of the callbacks method # @return [void] + Contract Or[Pathname, String], Symbol => Any def run_callbacks(path, callbacks_name) path = path.to_s send(callbacks_name).each do |callback| 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 cd96eb38..4dbb7082 100644 --- a/middleman-core/lib/middleman-core/core_extensions/front_matter.rb +++ b/middleman-core/lib/middleman-core/core_extensions/front_matter.rb @@ -27,8 +27,8 @@ module Middleman::CoreExtensions end def before_configuration - file_watcher.changed(&method(:clear_data)) - file_watcher.deleted(&method(:clear_data)) + app.files.changed(&method(:clear_data)) + app.files.deleted(&method(:clear_data)) end # @return Array @@ -96,7 +96,7 @@ module Middleman::CoreExtensions data = {} - return [data, nil] if !file_watcher.exists?(full_path) || ::Middleman::Util.binary?(full_path) + return [data, nil] if !app.files.exists?(full_path) || ::Middleman::Util.binary?(full_path) content = File.read(full_path) diff --git a/middleman-core/lib/middleman-core/core_extensions/i18n.rb b/middleman-core/lib/middleman-core/core_extensions/i18n.rb index 32f3f2b0..e7d94f69 100644 --- a/middleman-core/lib/middleman-core/core_extensions/i18n.rb +++ b/middleman-core/lib/middleman-core/core_extensions/i18n.rb @@ -16,11 +16,16 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension ::I18n::Backend::Simple.send(:include, ::I18n::Backend::Fallbacks) end - app.config.define_setting :locales_dir, 'locales', 'The directory holding your locale configurations' + locales_file_path = options[:data] - file_watcher.reload_path(app.config[:locales_dir] || options[:data]) + # Tell the file watcher to observe the :locales_dir + app.files.watch :locales do |path, _app| + path.match(/^#{locales_file_path}\/.*(yml|yaml)$/) + end - @locales_glob = File.join(app.config[:locales_dir] || options[:data], '**', '*.{rb,yml,yaml}') + app.files.reload_path(locales_file_path) + + @locales_glob = File.join(locales_file_path, '**', '*.{rb,yml,yaml}') @locales_regex = convert_glob_to_regex(@locales_glob) @maps = {} @@ -33,8 +38,8 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension # Don't output localizable files app.ignore File.join(options[:templates_dir], '**') - file_watcher.changed(&method(:on_file_changed)) - file_watcher.deleted(&method(:on_file_changed)) + app.files.changed(&method(:on_file_changed)) + app.files.deleted(&method(:on_file_changed)) end helpers do @@ -111,7 +116,7 @@ class Middleman::CoreExtensions::Internationalization < ::Middleman::Extension if options[:langs] Array(options[:langs]).map(&:to_sym) else - known_langs = file_watcher.known_paths.select do |p| + known_langs = app.files.known_paths.select do |p| p.to_s.match(@locales_regex) && (p.to_s.split(File::SEPARATOR).length == 2) end diff --git a/middleman-core/lib/middleman-core/extension.rb b/middleman-core/lib/middleman-core/extension.rb index cb875e89..d52a1fae 100644 --- a/middleman-core/lib/middleman-core/extension.rb +++ b/middleman-core/lib/middleman-core/extension.rb @@ -179,8 +179,6 @@ module Middleman # @return [void] def_delegator :"::Middleman::Extension", :after_extension_activated - def_delegator :"@app.extensions[:file_watcher]", :api, :file_watcher - # Extensions are instantiated when they are activated. # @param [Middleman::Application] app The Middleman::Application instance # @param [Hash] options_hash The raw options hash. Subclasses should not manipulate this directly - it will be turned into {#options}. @@ -242,8 +240,7 @@ module Middleman end def bind_before_configuration - return unless respond_to?(:before_configuration) - @app.before_configuration(&method(:before_configuration)) + @app.before_configuration(&method(:before_configuration)) if respond_to?(:before_configuration) end def bind_after_configuration diff --git a/middleman-core/lib/middleman-core/renderers/sass.rb b/middleman-core/lib/middleman-core/renderers/sass.rb index 05d0b8e5..5ec93b9a 100644 --- a/middleman-core/lib/middleman-core/renderers/sass.rb +++ b/middleman-core/lib/middleman-core/renderers/sass.rb @@ -59,6 +59,10 @@ module Middleman require 'middleman-core/renderers/sass_functions' end + def before_configuration + app.files.watch :sass_cache, /(^|\/)\.sass-cache\// + end + # A SassTemplate for Tilt which outputs debug messages class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate def initialize(*args, &block) diff --git a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb index 0a42198c..66acb8df 100644 --- a/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb +++ b/middleman-core/lib/middleman-core/sitemap/extensions/on_disk.rb @@ -24,8 +24,8 @@ module Middleman Contract None => Any def before_configuration - file_watcher.changed(&method(:touch_file)) - file_watcher.deleted(&method(:remove_file)) + app.files.changed(&method(:touch_file)) + app.files.deleted(&method(:remove_file)) end # Update or add an on-disk file path diff --git a/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb b/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb index b2101df4..70dbcf44 100644 --- a/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/middleman_steps.rb @@ -9,9 +9,9 @@ Then /^the file "([^\"]*)" is removed$/ do |path| end Then /^the file "([^\"]*)" did change$/ do |path| - @server_inst.extensions[:file_watcher].api.did_change(path) + @server_inst.files.did_change(path) end Then /^the file "([^\"]*)" did delete$/ do |path| - @server_inst.extensions[:file_watcher].api.did_delete(path) + @server_inst.files.did_delete(path) end diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 36dd881d..aa618ed9 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -223,14 +223,16 @@ module Middleman def self.all_files_under(path, &ignore) path = Pathname(path) - return [] if ignore && ignore.call(path) - if path.directory? path.children.flat_map do |child| all_files_under(child, &ignore) end.compact elsif path.file? - [path] + if block_given? && ignore.call(path) + [] + else + [path] + end else [] end From 7e068cc77d2f5f5f9d79e8f254ff357ed2760418 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 10 Jul 2014 13:07:27 -0700 Subject: [PATCH 131/662] move contracts from gemfile to gemspec --- Gemfile | 1 - middleman-core/middleman-core.gemspec | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 6fde5899..153a501e 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,6 @@ gem 'aruba', '~> 0.6', require: false gem 'rspec', '~> 3.0', require: false gem 'fivemat', '~> 1.3', require: false gem 'cucumber', '~> 1.3', require: false -gem 'contracts', '~> 0.4', require: false # Optional middleman dependencies, included for tests gem 'haml', '>= 4.0.5', require: false diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index 3c8c40a0..acfabe73 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -47,4 +47,7 @@ Gem::Specification.new do |s| # Minify JS s.add_dependency('uglifier', ['~> 2.5']) s.add_dependency('execjs', ['~> 2.0']) + + # Testings + s.add_development_dependency('contracts', ['~> 0.4']) end From 215ddad6600b867b1b3ca9965385a264788d8041 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 10 Jul 2014 13:11:14 -0700 Subject: [PATCH 132/662] actually, just depend on it --- middleman-core/middleman-core.gemspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/middleman-core/middleman-core.gemspec b/middleman-core/middleman-core.gemspec index acfabe73..2bced4f9 100644 --- a/middleman-core/middleman-core.gemspec +++ b/middleman-core/middleman-core.gemspec @@ -48,6 +48,6 @@ Gem::Specification.new do |s| s.add_dependency('uglifier', ['~> 2.5']) s.add_dependency('execjs', ['~> 2.0']) - # Testings - s.add_development_dependency('contracts', ['~> 0.4']) + # Testing + s.add_dependency('contracts', ['~> 0.4']) end From 840c927ac0708f26d972c1e93c13021407bfc5cf Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 10 Jul 2014 13:30:16 -0700 Subject: [PATCH 133/662] Fix some bugs in the Slim renderer when converting to Extensions --- middleman-core/lib/middleman-core/renderers/slim.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/middleman-core/lib/middleman-core/renderers/slim.rb b/middleman-core/lib/middleman-core/renderers/slim.rb index ace8f751..c89a99a0 100644 --- a/middleman-core/lib/middleman-core/renderers/slim.rb +++ b/middleman-core/lib/middleman-core/renderers/slim.rb @@ -21,6 +21,8 @@ module Middleman class Slim < ::Middleman::Extension # Setup extension def initialize(_app, _options={}, &_block) + super + # Setup Slim options to work with partials ::Slim::Engine.set_default_options( buffer: '@_out_buf', @@ -32,7 +34,7 @@ module Middleman def after_configuration context_hack = { - context: app.template_context_class.new(self) + context: app.template_context_class.new(app) } ::Slim::Embedded::SassEngine.disable_option_validator! From 3ae16111ef6518949892f9e4ac11b89f1a4e3c33 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 7 Jul 2014 19:43:22 -0700 Subject: [PATCH 134/662] Separate Build from Thor --- CHANGELOG.md | 1 + middleman-cli/lib/middleman-cli/build.rb | 268 +++--------------- middleman-core/fixtures/clean-app/config.rb | 9 + middleman-core/lib/middleman-core/builder.rb | 255 +++++++++++++++++ .../core_extensions/show_exceptions.rb | 2 +- .../lib/middleman-core/extensions/gzip.rb | 4 +- .../step_definitions/builder_steps.rb | 4 +- 7 files changed, 317 insertions(+), 226 deletions(-) create mode 100644 middleman-core/lib/middleman-core/builder.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 8de8854c..724499e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ master === +* Builder extracted from Thor. `after_build` hook now passes an instance of a Builder instead of the Thor CLI. * New FileWatcher API. * Remove the `partials_dir` setting. Partials should live next to content, or be addressed with absolute paths. * Partials must be named with a leading underscore. `_my_snippet.html.erb`, not `my_snippet.html.erb`. diff --git a/middleman-cli/lib/middleman-cli/build.rb b/middleman-cli/lib/middleman-cli/build.rb index 3918319d..0ec5d234 100644 --- a/middleman-cli/lib/middleman-cli/build.rb +++ b/middleman-cli/lib/middleman-cli/build.rb @@ -1,18 +1,9 @@ -require 'fileutils' -require 'set' - # CLI Module module Middleman::Cli - # Alias "b" to "build" - Base.map('b' => 'build') - # The CLI Build class class Build < Thor include Thor::Actions - attr_reader :debugging - attr_accessor :had_errors - check_unknown_options! namespace :build @@ -53,250 +44,85 @@ module Middleman::Cli require 'middleman-core' require 'middleman-core/logger' - require 'middleman-core/rack' - - require 'rack' - require 'rack/mock' - - require 'find' - - @debugging = Middleman::Cli::Base.respond_to?(:debugging) && Middleman::Cli::Base.debugging - self.had_errors = false + require 'middleman-core/builder' + require 'fileutils' env = options['environment'].to_sym verbose = options['verbose'] ? 0 : 1 instrument = options['instrument'] - app = ::Middleman::Application.new do + @app = ::Middleman::Application.new do config[:mode] = :build config[:environment] = env + config[:show_exceptions] = false ::Middleman::Logger.singleton(verbose, instrument) end - opts = {} - opts[:glob] = options['glob'] if options.key?('glob') - opts[:clean] = options['clean'] + builder = Middleman::Builder.new(@app, + glob: options['glob'], + clean: options['clean']) - app.run_hook :before_build, self + builder.on_build_event(&method(:on_event)) - action BuildAction.new(self, app, opts) - - app.run_hook :after_build, self - app.config_context.execute_after_build_callbacks(self) - - if had_errors && !debugging + if builder.run! + clean_directories! if options['clean'] + else msg = 'There were errors during this build' unless options['verbose'] msg << ', re-run with `middleman build --verbose` to see the full exception.' end shell.say msg, :red - end - exit(1) if had_errors - end - - # Static methods - class << self - def exit_on_failure? - true - end - end - end - - # A Thor Action, modular code, which does the majority of the work. - class BuildAction < ::Thor::Actions::EmptyDirectory - attr_reader :source - attr_reader :logger - - # Setup the action - # - # @param [Middleman::Cli::Build] base - # @param [Hash] config - def initialize(base, app, config={}) - @app = app - @source_dir = Pathname(@app.source_dir) - @build_dir = Pathname(@app.config[:build_dir]) - @to_clean = Set.new - - @logger = @app.logger - rack_app = ::Middleman::Rack.new(@app).to_app - @rack = ::Rack::MockRequest.new(rack_app) - - super(base, @build_dir, config) - end - - # Execute the action - # @return [void] - def invoke! - queue_current_paths if should_clean? - execute! - clean! if should_clean? - end - - protected - - # Remove files which were not built in this cycle - # @return [void] - def clean! - @to_clean.each do |f| - base.remove_file f, force: true - end - - Dir[@build_dir.join('**', '*')].select { |d| File.directory?(d) }.each do |d| - base.remove_file d, force: true if directory_empty? d + exit(1) end end - # Whether we should clean the build - # @return [Boolean] - def should_clean? - @config[:clean] + # Tell Thor to send an exit status on a failure. + def self.exit_on_failure? + true end - # Whether the given directory is empty - # @param [String, Pathname] directory - # @return [Boolean] - def directory_empty?(directory) - Pathname(directory).children.empty? - end + no_tasks do - # Get a list of all the file paths in the destination folder and save them - # for comparison against the files we build in this cycle - # @return [void] - def queue_current_paths - return unless File.exist?(@build_dir) - - paths = ::Middleman::Util.all_files_under(@build_dir).map(&:realpath).select(&:file?) - - @to_clean += paths.select do |path| - path.to_s !~ /\/\./ || path.to_s =~ /\.(htaccess|htpasswd)/ - end - - return unless RUBY_PLATFORM =~ /darwin/ - - # handle UTF-8-MAC filename on MacOS - @to_clean = @to_clean.map { |path| path.to_s.encode('UTF-8', 'UTF-8-MAC') } - end - - # Actually build the app - # @return [void] - def execute! - # Sort order, images, fonts, js/css and finally everything else. - sort_order = %w(.png .jpeg .jpg .gif .bmp .svg .svgz .ico .woff .otf .ttf .eot .js .css) - - # Pre-request CSS to give Compass a chance to build sprites - logger.debug '== Prerendering CSS' - - @app.sitemap.resources.select do |resource| - resource.ext == '.css' - end.each(&method(:build_resource)) - - logger.debug '== Checking for generated images' - - # Double-check for generated images - @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) - @app.sitemap.ensure_resource_list_updated! - - # Sort paths to be built by the above order. This is primarily so Compass can - # find files in the build folder when it needs to generate sprites for the - # css files - - logger.debug '== Building files' - - resources = @app.sitemap.resources.sort_by do |r| - sort_order.index(r.ext) || 100 - end - - if @build_dir.expand_path.relative_path_from(@source_dir).to_s =~ /\A[.\/]+\Z/ - raise ":build_dir (#{@build_dir}) cannot be a parent of :source_dir (#{@source_dir})" - end - - # Loop over all the paths and build them. - resources.reject do |resource| - resource.ext == '.css' - end.each(&method(:build_resource)) - - ::Middleman::Profiling.report('build') - end - - def build_resource(resource) - return if @config[:glob] && !File.fnmatch(@config[:glob], resource.destination_path) - - output_path = render_to_file(resource) - - return unless should_clean? && output_path.exist? - - if RUBY_PLATFORM =~ /darwin/ - # handle UTF-8-MAC filename on MacOS - - @to_clean.delete(output_path.realpath.to_s.encode('UTF-8', 'UTF-8-MAC')) - else - @to_clean.delete(output_path.realpath) - end - end - - # Render a resource to a file. - # - # @param [Middleman::Sitemap::Resource] resource - # @return [Pathname] The full path of the file that was written - def render_to_file(resource) - output_file = @build_dir + resource.destination_path.gsub('%20', ' ') - - if resource.binary? - if !output_file.exist? - base.say_status :create, output_file, :green - elsif FileUtils.compare_file(resource.source_file, output_file) - base.say_status :identical, output_file, :blue - return output_file + # Handles incoming events from the builder. + # @param [Symbol] event_type The type of event. + # @param [String] contents The event contents. + # @param [String] extra The extra information. + # @return [void] + def on_event(event_type, target, extra=nil) + case event_type + when :error + say_status :error, target, :red + shell.say extra, :red if options['verbose'] + when :deleted + say_status :remove, target, :green + when :created + say_status :create, target, :green + when :identical + say_status :identical, target, :blue + when :updated + say_status :updated, target, :yellow else - base.say_status :update, output_file, :yellow - end - - output_file.dirname.mkpath - FileUtils.cp(resource.source_file, output_file) - else - begin - response = @rack.get(URI.escape(resource.request_path)) - - if response.status == 200 - base.create_file(output_file, binary_encode(response.body)) - else - handle_error(output_file, response.body) - end - rescue => e - handle_error(output_file, "#{e}\n#{e.backtrace.join("\n")}", e) + say_status event_type, extra, :blue end end - output_file - end + # Find empty directories in the build folder and remove them. + # @return [Boolean] + def clean_directories! + all_build_files = File.join(@app.config[:build_dir], '**', '*') - def handle_error(file_name, response, e=Thor::Error.new(response)) - base.had_errors = true + empty_directories = Dir[all_build_files].select do |d| + File.directory?(d) + end - base.say_status :error, file_name, :red - if base.debugging - raise e - elsif base.options['verbose'] - base.shell.say response, :red + empty_directories.each do |d| + remove_file d, force: true if Pathname(d).children.empty? + end end end - - def binary_encode(string) - string.force_encoding('ascii-8bit') if string.respond_to?(:force_encoding) - string - end end -end -# Quiet down create file -class ::Thor::Actions::CreateFile - def on_conflict_behavior(&block) - if identical? - say_status :identical, :blue - else - say_status :update, :yellow - block.call unless pretend? - end - end + # Alias "b" to "build" + Base.map('b' => 'build') end diff --git a/middleman-core/fixtures/clean-app/config.rb b/middleman-core/fixtures/clean-app/config.rb index e69de29b..1326120c 100644 --- a/middleman-core/fixtures/clean-app/config.rb +++ b/middleman-core/fixtures/clean-app/config.rb @@ -0,0 +1,9 @@ +proxy "/fake.html", "/real.html", layout: false + +ignore "/should_be_ignored.html" +ignore "/should_be_ignored2.html" +proxy "/target_ignore.html", "/should_be_ignored3.html", ignore: true + +%w(one two).each do |num| + proxy "/fake/#{num}.html", "/real/index.html", locals: { num: num } +end diff --git a/middleman-core/lib/middleman-core/builder.rb b/middleman-core/lib/middleman-core/builder.rb new file mode 100644 index 00000000..23a9ac3a --- /dev/null +++ b/middleman-core/lib/middleman-core/builder.rb @@ -0,0 +1,255 @@ +require 'pathname' +require 'fileutils' +require 'tempfile' +require 'middleman-core/rack' +require 'middleman-core/contracts' + +module Middleman + class Builder + extend Forwardable + include Contracts + + # Make app & events available to `after_build` callbacks. + attr_reader :app, :events + + # Logger comes from App. + def_delegator :@app, :logger + + # Sort order, images, fonts, js/css and finally everything else. + SORT_ORDER = %w(.png .jpeg .jpg .gif .bmp .svg .svgz .ico .woff .otf .ttf .eot .js .css) + + # Create a new Builder instance. + # @param [Middleman::Application] app The app to build. + # @param [Hash] opts The builder options + def initialize(app, opts={}) + @app = app + @source_dir = Pathname(@app.source_dir) + @build_dir = Pathname(@app.config[:build_dir]) + + if @build_dir.expand_path.relative_path_from(@source_dir).to_s =~ /\A[.\/]+\Z/ + raise ":build_dir (#{@build_dir}) cannot be a parent of :source_dir (#{@source_dir})" + end + + @glob = opts.fetch(:glob) + @cleaning = opts.fetch(:clean) + + @_event_callbacks = [] + + rack_app = ::Middleman::Rack.new(@app).to_app + @rack = ::Rack::MockRequest.new(rack_app) + end + + # Run the build phase. + # @return [Boolean] Whether the build was successful. + Contract None => Bool + def run! + @has_error = false + @events = {} + + @app.run_hook :before_build, self + + queue_current_paths if @cleaning + prerender_css + output_files + clean if @cleaning + + ::Middleman::Profiling.report('build') + + # Run hooks + @app.run_hook :after_build, self + @app.config_context.execute_after_build_callbacks(self) + + !@has_error + end + + # Attach callbacks for build events. + # @return [Array] All the attached events. + Contract Proc => ArrayOf[Proc] + def on_build_event(&block) + @_event_callbacks << block if block_given? + @_event_callbacks + end + + # Pre-request CSS to give Compass a chance to build sprites + # @return [Array] List of css resources that were output. + Contract None => ResourceList + def prerender_css + logger.debug '== Prerendering CSS' + + css_files = @app.sitemap.resources.select do |resource| + resource.ext == '.css' + end.each(&method(:output_resource)) + + logger.debug '== Checking for Compass sprites' + + # Double-check for compass sprites + @app.files.find_new_files((@source_dir + @app.config[:images_dir]).relative_path_from(@app.root_path)) + @app.sitemap.ensure_resource_list_updated! + + css_files + end + + # Find all the files we need to output and do so. + # @return [Array] List of resources that were output. + Contract None => ResourceList + def output_files + logger.debug '== Building files' + + # Sort paths to be built by the above order. This is primarily so Compass can + # find files in the build folder when it needs to generate sprites for the + # css files. + # + # Loop over all the paths and build them. + @app.sitemap.resources + .sort_by { |resource| SORT_ORDER.index(resource.ext) || 100 } + .reject { |resource| resource.ext == '.css' } + .select { |resource| !@glob || File.fnmatch(@glob, resource.destination_path) } + .each(&method(:output_resource)) + end + + # Figure out the correct event mode. + # @param [Pathname] output_file The output file path. + # @param [String] source The source file path. + # @return [Symbol] + Contract Pathname, String => Symbol + def which_mode(output_file, source) + if !output_file.exist? + :created + else + FileUtils.compare_file(source.to_s, output_file.to_s) ? :identical : :updated + end + end + + # Create a tempfile for a given output with contents. + # @param [Pathname] output_file The output path. + # @param [String] contents The file contents. + # @return [Tempfile] + Contract Pathname, String => Tempfile + def write_tempfile(output_file, contents) + file = Tempfile.new([ + File.basename(output_file), + File.extname(output_file)]) + file.binmode + file.write(contents) + file.close + file + end + + # Actually export the file. + # @param [Pathname] output_file The path to output to. + # @param [String|Pathname] source The source path or contents. + # @return [void] + Contract Pathname, Or[String, Pathname] => Any + def export_file!(output_file, source) + source = write_tempfile(output_file, source.to_s) if source.is_a? String + + method, source_path = if source.is_a? Tempfile + [FileUtils.method(:mv), source.path] + else + [FileUtils.method(:cp), source.to_s] + end + + mode = which_mode(output_file, source_path) + + if mode == :created || mode == :updated + FileUtils.mkdir_p(output_file.dirname) + method.call(source_path, output_file.to_s) + end + + source.unlink if source.is_a? Tempfile + + trigger(mode, output_file) + end + + # Try to output a resource and capture errors. + # @param [Middleman::Sitemap::Resource] resource The resource. + # @return [void] + Contract IsA['Middleman::Sitemap::Resource'] => Any + def output_resource(resource) + output_file = @build_dir + resource.destination_path.gsub('%20', ' ') + + begin + if resource.binary? + export_file!(output_file, Pathname(resource.source_file)) + else + response = @rack.get(URI.escape(resource.request_path)) + + # If we get a response, save it to a tempfile. + if response.status == 200 + export_file!(output_file, binary_encode(response.body)) + else + @has_error = true + trigger(:error, output_file, response.body) + end + end + rescue => e + @has_error = true + trigger(:error, output_file, "#{e}\n#{e.backtrace.join("\n")}") + end + + return unless @cleaning + return unless output_file.exist? + + # handle UTF-8-MAC filename on MacOS + cleaned_name = if RUBY_PLATFORM =~ /darwin/ + output_file.to_s.encode('UTF-8', 'UTF-8-MAC') + else + output_file + end + + @to_clean.delete(Pathname(cleaned_name)) + end + + # Get a list of all the paths in the destination folder and save them + # for comparison against the files we build in this cycle + # @return [void] + Contract None => Any + def queue_current_paths + @to_clean = [] + + return unless File.exist?(@app.config[:build_dir]) + + paths = ::Middleman::Util.all_files_under(@app.config[:build_dir]).map do |path| + Pathname(path) + end + + @to_clean = paths.select do |path| + path.to_s !~ /\/\./ || path.to_s =~ /\.(htaccess|htpasswd)/ + end + + # handle UTF-8-MAC filename on MacOS + @to_clean = @to_clean.map do |path| + if RUBY_PLATFORM =~ /darwin/ + Pathname(path.to_s.encode('UTF-8', 'UTF-8-MAC')) + else + Pathname(path) + end + end + end + + # Remove files which were not built in this cycle + Contract None => ArrayOf[Pathname] + def clean + @to_clean.each do |f| + FileUtils.rm(f) + trigger(:deleted, f) + end + end + + Contract String => String + def binary_encode(string) + string.force_encoding('ascii-8bit') if string.respond_to?(:force_encoding) + string + end + + Contract Symbol, Or[String, Pathname], Maybe[String] => Any + def trigger(event_type, target, extra=nil) + @events[event_type] ||= [] + @events[event_type] << target + + @_event_callbacks.each do |callback| + callback.call(event_type, target, extra) + end + end + end +end diff --git a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb index a28e6a7f..53c48877 100644 --- a/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb +++ b/middleman-core/lib/middleman-core/core_extensions/show_exceptions.rb @@ -6,7 +6,7 @@ module Middleman::CoreExtensions def initialize(app, options_hash={}, &block) super - app.config.define_setting :show_exceptions, true, 'Whether to catch and display exceptions' + app.config.define_setting :show_exceptions, !!ENV['TEST'], 'Whether to catch and display exceptions' end def after_configuration diff --git a/middleman-core/lib/middleman-core/extensions/gzip.rb b/middleman-core/lib/middleman-core/extensions/gzip.rb index 70af4ad1..36cccf5e 100644 --- a/middleman-core/lib/middleman-core/extensions/gzip.rb +++ b/middleman-core/lib/middleman-core/extensions/gzip.rb @@ -63,10 +63,10 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension total_savings += (old_size - new_size) size_change_word = (old_size - new_size) > 0 ? 'smaller' : 'larger' - builder.say_status :gzip, "#{output_filename} (#{NumberHelpers.new.number_to_human_size((old_size - new_size).abs)} #{size_change_word})" + builder.trigger :gzip, "#{output_filename} (#{NumberHelpers.new.number_to_human_size((old_size - new_size).abs)} #{size_change_word})" end - builder.say_status :gzip, "Total gzip savings: #{NumberHelpers.new.number_to_human_size(total_savings)}", :blue + builder.trigger :gzip, "Total gzip savings: #{NumberHelpers.new.number_to_human_size(total_savings)}" I18n.locale = old_locale end diff --git a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb index 291eb449..5582db77 100644 --- a/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb +++ b/middleman-core/lib/middleman-core/step_definitions/builder_steps.rb @@ -34,12 +34,12 @@ end Given /^a built app at "([^\"]*)"$/ do |path| step %Q{a fixture app "#{path}"} - step %Q{I run `middleman build`} + step %Q{I run `middleman build --verbose`} end Given /^was successfully built$/ do - step %Q{a directory named "build" should exist} step %Q{the exit status should be 0} + step %Q{a directory named "build" should exist} end Given /^a successfully built app at "([^\"]*)"$/ do |path| From c74d03777a47d8cb72f311ffd36c9e9822950715 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 14 Jul 2014 08:56:29 -0700 Subject: [PATCH 135/662] Add edge references to compass and sprockets back to gemfile --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 153a501e..10f9c9b7 100644 --- a/Gemfile +++ b/Gemfile @@ -36,3 +36,5 @@ gem 'codeclimate-test-reporter', '~> 0.3', require: false, group: :test # Middleman itself gem 'middleman-cli', path: 'middleman-cli' gem 'middleman-core', path: 'middleman-core' +gem 'middleman-compass', github: 'middleman/middleman-compass', require: false +gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', require: false From 332ce2bebcc4c387ea12cd759b4328a9766c78bc Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 14 Jul 2014 09:50:44 -0700 Subject: [PATCH 136/662] slight util reorg --- middleman-core/lib/middleman-core/util.rb | 113 ++++-------------- .../util/hash_with_indifferent_access.rb | 78 ++++++++++++ 2 files changed, 98 insertions(+), 93 deletions(-) create mode 100644 middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index aa618ed9..7556b504 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -1,8 +1,8 @@ # For instrumenting require 'active_support/notifications' -# Using Thor's indifferent hash access -require 'thor' +# Indifferent hash access +require 'middleman-core/util/hash_with_indifferent_access' # Core Pathname library used for traversal require 'pathname' @@ -15,90 +15,17 @@ require 'rack/mime' require 'middleman-core/contracts' module Middleman + module Util + extend self include Contracts - # A hash with indifferent access and magic predicates. - # Copied from Thor - # - # hash = Middleman::Util::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true - # - # hash[:foo] #=> 'bar' - # hash['foo'] #=> 'bar' - # hash.foo? #=> true - # - class HashWithIndifferentAccess < ::Hash #:nodoc: - def initialize(hash={}) - super() - hash.each do |key, value| - self[convert_key(key)] = value - end - end - - def [](key) - super(convert_key(key)) - end - - def []=(key, value) - super(convert_key(key), value) - end - - def delete(key) - super(convert_key(key)) - end - - def values_at(*indices) - indices.map { |key| self[convert_key(key)] } - end - - def merge(other) - dup.merge!(other) - end - - def merge!(other) - other.each do |key, value| - self[convert_key(key)] = value - end - self - end - - # Convert to a Hash with String keys. - def to_hash - Hash.new(default).merge!(self) - end - - protected - - def convert_key(key) - key.is_a?(Symbol) ? key.to_s : key - end - - # Magic predicates. For instance: - # - # options.force? # => !!options['force'] - # options.shebang # => "/usr/lib/local/ruby" - # options.test_framework?(:rspec) # => options[:test_framework] == :rspec - # rubocop:disable DoubleNegation - def method_missing(method, *args) - method = method.to_s - if method =~ /^(\w+)\?$/ - if args.empty? - !!self[$1] - else - self[$1] == args.first - end - else - self[method] - end - end - end - # Whether the source file is binary. # # @param [String] filename The file to check. # @return [Boolean] Contract String => Bool - def self.binary?(filename) + def binary?(filename) ext = File.extname(filename) # We hardcode detecting of gzipped SVG files @@ -125,7 +52,7 @@ module Middleman # @param [String] path A path as a string # @return [Boolean] Whether the path matches the matcher Contract PATH_MATCHER, String => Bool - def self.path_match(matcher, path) + def path_match(matcher, path) case when matcher.is_a?(String) if matcher.include? '*' @@ -148,7 +75,7 @@ module Middleman # @param [Hash] data Normal hash # @return [Middleman::Util::HashWithIndifferentAccess] Contract Or[Hash, Array] => Or[HashWithIndifferentAccess, Array] - def self.recursively_enhance(data) + def recursively_enhance(data) if data.is_a? Hash enhanced = ::Middleman::Util::HashWithIndifferentAccess.new(data) @@ -180,7 +107,7 @@ module Middleman # @param [String] path # @return [String] Contract String => String - def self.normalize_path(path) + def normalize_path(path) # The tr call works around a bug in Ruby's Unicode handling path.sub(%r{^/}, '').tr('', '') end @@ -188,12 +115,12 @@ module Middleman # This is a separate method from normalize_path in case we # change how we normalize paths Contract String => String - def self.strip_leading_slash(path) + def strip_leading_slash(path) path.sub(%r{^/}, '') end # Facade for ActiveSupport/Notification - def self.instrument(name, payload={}, &block) + def instrument(name, payload={}, &block) suffixed_name = (name =~ /\.middleman$/) ? name.dup : "#{name}.middleman" ::ActiveSupport::Notifications.instrument(suffixed_name, payload, &block) end @@ -203,7 +130,7 @@ module Middleman # @param response The response from #call # @return [String] The whole response as a string. Contract RespondTo[:each] => String - def self.extract_response_text(response) + def extract_response_text(response) # The rack spec states all response bodies must respond to each result = '' response.each do |part, _| @@ -220,7 +147,7 @@ module Middleman # is ignored, nothing below it will be searched either. # @return [Array] An array of Pathnames for each file (no directories) Contract Or[String, Pathname], Proc => ArrayOf[Pathname] - def self.all_files_under(path, &ignore) + def all_files_under(path, &ignore) path = Pathname(path) if path.directory? @@ -246,7 +173,7 @@ module Middleman # @param [Hash] options Data to pass through. # @return [String] Contract IsA['Middleman::Application'], Symbol, Or[String, Symbol], Hash => String - def self.asset_path(app, kind, source, options={}) + def asset_path(app, kind, source, options={}) return source if source.to_s.include?('//') || source.to_s.start_with?('data:') asset_folder = case kind @@ -277,7 +204,7 @@ module Middleman # @param [Hash] options Data to pass through. # @return [String] The fully qualified asset url Contract IsA['Middleman::Application'], String, String, Hash => String - def self.asset_url(app, path, prefix='', _options={}) + def asset_url(app, path, prefix='', _options={}) # Don't touch assets which already have a full path if path.include?('//') || path.start_with?('data:') path @@ -299,7 +226,7 @@ module Middleman # or a Resource, this will produce the nice URL configured for that # path, respecting :relative_links, directory indexes, etc. Contract IsA['Middleman::Application'], Or[String, IsA['Middleman::Sitemap::Resource']], Hash => String - def self.url_for(app, path_or_resource, options={}) + def url_for(app, path_or_resource, options={}) # Handle Resources and other things which define their own url method url = if path_or_resource.respond_to?(:url) path_or_resource.url @@ -372,7 +299,7 @@ module Middleman # @param [Middleman::Application] app The requesting app. # @return [String] Path with index file if necessary. Contract String, IsA['Middleman::Application'] => String - def self.full_path(path, app) + def full_path(path, app) resource = app.sitemap.find_resource_by_destination_path(path) unless resource @@ -389,7 +316,7 @@ module Middleman end Contract String, String, ArrayOf[String], Proc => String - def self.rewrite_paths(body, _path, exts, &_block) + def rewrite_paths(body, _path, exts, &_block) body.dup.gsub(/([=\'\"\(]\s*)([^\s\'\"\)]+(#{Regexp.union(exts)}))/) do |match| opening_character = $1 asset_path = $2 @@ -407,7 +334,7 @@ module Middleman # @param [String] mime The mimetype to check. # @return [Boolean] Contract String => Bool - def self.nonbinary_mime?(mime) + def nonbinary_mime?(mime) case when mime.start_with?('text/') true @@ -427,7 +354,7 @@ module Middleman # @param [String] filename The file to check. # @return [Boolean] Contract String => Bool - def self.file_contents_include_binary_bytes?(filename) + def file_contents_include_binary_bytes?(filename) 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| @@ -444,7 +371,7 @@ module Middleman # @param [Boolean] relative If the path should be relative. # @return [String] Contract IsA['Middleman::Sitemap::Resource'], String, Bool => String - def self.relative_path_from_resource(curr_resource, resource_url, relative) + def relative_path_from_resource(curr_resource, resource_url, relative) # Switch to the relative path between resource and the given resource # if we've been asked to. if relative diff --git a/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb b/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb new file mode 100644 index 00000000..bae61b95 --- /dev/null +++ b/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb @@ -0,0 +1,78 @@ +module Middleman + module Util + # A hash with indifferent access and magic predicates. + # Copied from Thor + # + # hash = Middleman::Util::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true + # + # hash[:foo] #=> 'bar' + # hash['foo'] #=> 'bar' + # hash.foo? #=> true + # + class HashWithIndifferentAccess < ::Hash #:nodoc: + def initialize(hash={}) + super() + hash.each do |key, value| + self[convert_key(key)] = value + end + end + + def [](key) + super(convert_key(key)) + end + + def []=(key, value) + super(convert_key(key), value) + end + + def delete(key) + super(convert_key(key)) + end + + def values_at(*indices) + indices.map { |key| self[convert_key(key)] } + end + + def merge(other) + dup.merge!(other) + end + + def merge!(other) + other.each do |key, value| + self[convert_key(key)] = value + end + self + end + + # Convert to a Hash with String keys. + def to_hash + Hash.new(default).merge!(self) + end + + protected + + def convert_key(key) + key.is_a?(Symbol) ? key.to_s : key + end + + # Magic predicates. For instance: + # + # options.force? # => !!options['force'] + # options.shebang # => "/usr/lib/local/ruby" + # options.test_framework?(:rspec) # => options[:test_framework] == :rspec + # rubocop:disable DoubleNegation + def method_missing(method, *args) + method = method.to_s + if method =~ /^(\w+)\?$/ + if args.empty? + !!self[$1] + else + self[$1] == args.first + end + else + self[method] + end + end + end + end +end From 1f3e2043cb5c03a9f46b0ac933b10e1c1f799ca5 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Mon, 14 Jul 2014 13:19:34 -0700 Subject: [PATCH 137/662] Deep freeze IndifferentAccess. --- .../lib/middleman-core/contracts.rb | 13 +++++++ .../middleman-core/core_extensions/data.rb | 16 ++++----- .../lib/middleman-core/file_renderer.rb | 2 +- .../lib/middleman-core/preview_server.rb | 4 +-- .../lib/middleman-core/sitemap/resource.rb | 2 +- .../lib/middleman-core/template_context.rb | 6 ++-- .../lib/middleman-core/template_renderer.rb | 15 ++++---- middleman-core/lib/middleman-core/util.rb | 36 ++++++------------- .../util/hash_with_indifferent_access.rb | 29 +++++++++++++-- 9 files changed, 74 insertions(+), 49 deletions(-) diff --git a/middleman-core/lib/middleman-core/contracts.rb b/middleman-core/lib/middleman-core/contracts.rb index 2f13bc1c..5fd05e11 100644 --- a/middleman-core/lib/middleman-core/contracts.rb +++ b/middleman-core/lib/middleman-core/contracts.rb @@ -17,6 +17,16 @@ if ENV['TEST'] || ENV['CONTRACTS'] == 'true' end end + class Frozen < CallableClass + def initialize(contract) + @contract = contract + end + + def valid?(val) + val.frozen? && Contract.valid?(val, @contract) + end + end + class ArrayOf def initialize(contract) @contract = contract.is_a?(String) ? IsA[contract] : contract @@ -128,6 +138,9 @@ else class SetOf < Callable end + + class Frozen < Callable + end 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 95fabdcd..e5824362 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -97,11 +97,11 @@ module Middleman path = data_path.to_s.split(File::SEPARATOR)[0..-2] path.each do |dir| - data_branch[dir] ||= ::Middleman::Util.recursively_enhance({}) + data_branch[dir] ||= {} data_branch = data_branch[dir] end - data_branch[basename] = data && ::Middleman::Util.recursively_enhance(data) + data_branch[basename] = data end # Remove a given file from the internal cache @@ -132,14 +132,13 @@ module Middleman # @return [Hash, nil] Contract Or[String, Symbol] => Maybe[Hash] def data_for_path(path) - response = nil - - if store.key?(path.to_s) - response = store[path.to_s] + response = if store.key?(path.to_s) + store[path.to_s] elsif callbacks.key?(path.to_s) - response = callbacks[path.to_s].call + callbacks[path.to_s].call end + response = ::Middleman::Util.recursively_enhance(response) response end @@ -149,10 +148,11 @@ module Middleman # @return [Hash, nil] def method_missing(path) if @local_data.key?(path.to_s) + @local_data[path.to_s] = ::Middleman::Util.recursively_enhance(@local_data[path.to_s]) return @local_data[path.to_s] else result = data_for_path(path) - return ::Middleman::Util.recursively_enhance(result) if result + return result if result end super diff --git a/middleman-core/lib/middleman-core/file_renderer.rb b/middleman-core/lib/middleman-core/file_renderer.rb index 6e43d712..a97eae7c 100644 --- a/middleman-core/lib/middleman-core/file_renderer.rb +++ b/middleman-core/lib/middleman-core/file_renderer.rb @@ -51,7 +51,7 @@ module Middleman # Merge per-extension options from config extension = File.extname(path) - options = opts.dup.merge(options_for_ext(extension)) + options = opts.merge(options_for_ext(extension)) options[:outvar] ||= '@_out_buf' options.delete(:layout) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index c0d8f7c2..82b65acc 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -17,7 +17,7 @@ module Middleman # Start an instance of Middleman::Application # @return [void] def start(opts={}) - @options = opts + @options = opts.dup.freeze @host = @options[:host] || '0.0.0.0' @port = @options[:port] || DEFAULT_PORT @@ -94,7 +94,7 @@ module Middleman private def new_app - opts = @options.dup + opts = @options ::Middleman::Logger.singleton( opts[:debug] ? 0 : 1, diff --git a/middleman-core/lib/middleman-core/sitemap/resource.rb b/middleman-core/lib/middleman-core/sitemap/resource.rb index add3919d..5f9ecc67 100644 --- a/middleman-core/lib/middleman-core/sitemap/resource.rb +++ b/middleman-core/lib/middleman-core/sitemap/resource.rb @@ -79,7 +79,7 @@ module Middleman Contract None => IsA['Middleman::Util::HashWithIndifferentAccess'] def data # TODO: Should this really be a HashWithIndifferentAccess? - ::Middleman::Util.recursively_enhance(metadata[:page]).freeze + ::Middleman::Util.recursively_enhance(metadata[:page]) end # Options about how this resource is rendered, such as its :layout, diff --git a/middleman-core/lib/middleman-core/template_context.rb b/middleman-core/lib/middleman-core/template_context.rb index 78becaf5..1cca89aa 100644 --- a/middleman-core/lib/middleman-core/template_context.rb +++ b/middleman-core/lib/middleman-core/template_context.rb @@ -30,10 +30,10 @@ module Middleman # @param [Middleman::Application] app # @param [Hash] locs # @param [Hash] opts - def initialize(app, locs={}, opts={}) + def initialize(app, locs={}.freeze, opts={}.freeze) @app = app - @locs = locs.dup.freeze - @opts = opts.dup.freeze + @locs = locs + @opts = opts end # Return the current buffer to the caller and clear the value internally. diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 0eb2fc8f..72fa9db2 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -31,16 +31,19 @@ module Middleman Contract Hash, Hash => String def render(locs={}, opts={}) path = @path.dup + locals = locs.dup.freeze + options = opts.dup + extension = File.extname(path) engine = extension[1..-1].to_sym if defined?(::I18n) old_locale = ::I18n.locale - ::I18n.locale = opts[:lang] if opts[:lang] + ::I18n.locale = options[:lang] if options[:lang] end # Sandboxed class for template eval - context = @app.template_context_class.new(@app, locs, opts) + context = @app.template_context_class.new(@app, locals, options) # TODO: Only for HAML files context.init_haml_helpers if context.respond_to?(:init_haml_helpers) @@ -50,10 +53,10 @@ module Middleman content = nil while ::Tilt[path] begin - opts[:template_body] = content if content + options[:template_body] = content if content content_renderer = ::Middleman::FileRenderer.new(@app, path) - content = content_renderer.render(locs, opts, context) + content = content_renderer.render(locals, options, context) path = File.basename(path, File.extname(path)) rescue LocalJumpError @@ -62,9 +65,9 @@ module Middleman end # If we need a layout and have a layout, use it - if layout_path = fetch_layout(engine, opts) + if layout_path = fetch_layout(engine, options) layout_renderer = ::Middleman::FileRenderer.new(@app, layout_path) - content = layout_renderer.render(locs, opts, context) { content } + content = layout_renderer.render(locals, options, context) { content } end # Return result diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 7556b504..5ce84523 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -15,11 +15,11 @@ require 'rack/mime' require 'middleman-core/contracts' module Middleman - module Util - extend self include Contracts + module_function + # Whether the source file is binary. # # @param [String] filename The file to check. @@ -74,32 +74,16 @@ module Middleman # @private # @param [Hash] data Normal hash # @return [Middleman::Util::HashWithIndifferentAccess] - Contract Or[Hash, Array] => Or[HashWithIndifferentAccess, Array] + Contract Maybe[Or[Array, Hash, HashWithIndifferentAccess]] => Maybe[Frozen[Or[HashWithIndifferentAccess, Array]]] def recursively_enhance(data) - if data.is_a? Hash - enhanced = ::Middleman::Util::HashWithIndifferentAccess.new(data) - - enhanced.each do |key, val| - enhanced[key] = if val.is_a?(Hash) || val.is_a?(Array) - recursively_enhance(val) - else - val - end - end - - enhanced + if data.is_a? HashWithIndifferentAccess + data + elsif data.is_a? Hash + HashWithIndifferentAccess.new(data) elsif data.is_a? Array - enhanced = data.dup - - enhanced.each_with_index do |val, i| - enhanced[i] = if val.is_a?(Hash) || val.is_a?(Array) - recursively_enhance(val) - else - val - end - end - - enhanced + data.map(&method(:recursively_enhance)) + else + nil end end diff --git a/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb b/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb index bae61b95..4f2254e9 100644 --- a/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb +++ b/middleman-core/lib/middleman-core/util/hash_with_indifferent_access.rb @@ -1,3 +1,5 @@ +require 'middleman-core/contracts' + module Middleman module Util # A hash with indifferent access and magic predicates. @@ -10,11 +12,17 @@ module Middleman # hash.foo? #=> true # class HashWithIndifferentAccess < ::Hash #:nodoc: + include Contracts + + Contract Hash => Any def initialize(hash={}) super() - hash.each do |key, value| - self[convert_key(key)] = value + + hash.each do |key, val| + self[key] = recursively_enhance(val) end + + freeze end def [](key) @@ -73,6 +81,23 @@ module Middleman self[method] end end + + private + + Contract Any => Frozen[Any] + def recursively_enhance(data) + if data.is_a? HashWithIndifferentAccess + data + elsif data.is_a? Hash + self.class.new(data) + elsif data.is_a? Array + data.map(&method(:recursively_enhance)).freeze + elsif data.frozen? + data + else + data.dup.freeze + end + end end end end From b6951f2729c368bc47de7e27a3247d03d7b3b5e1 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Thu, 17 Jul 2014 09:32:38 -0700 Subject: [PATCH 138/662] use stable sprockets branch --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index a37adb4d..1fc15c03 100644 --- a/Gemfile +++ b/Gemfile @@ -32,4 +32,4 @@ gem 'coveralls', '~> 0.7', require: false # Middleman itself gem 'middleman', path: 'middleman' gem 'middleman-core', path: 'middleman-core' -gem 'middleman-sprockets', github: 'middleman/middleman-sprockets' +gem 'middleman-sprockets', github: 'middleman/middleman-sprockets', branch: 'v3-stable' From f0603ddf2f29b16bdf22addf50b1dfd78ad67868 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 18 Jul 2014 10:54:48 -0700 Subject: [PATCH 139/662] work with static partials. Closes #1206 --- middleman-core/features/partials.feature | 5 + .../partials-app/source/images/tiger.svg | 725 ++++++++++++++++++ .../fixtures/partials-app/source/svg.html.erb | 1 + .../core_extensions/rendering.rb | 25 +- .../lib/middleman-core/preview_server.rb | 4 +- .../lib/middleman-core/sitemap/store.rb | 2 +- 6 files changed, 754 insertions(+), 8 deletions(-) create mode 100644 middleman-core/fixtures/partials-app/source/images/tiger.svg create mode 100644 middleman-core/fixtures/partials-app/source/svg.html.erb diff --git a/middleman-core/features/partials.feature b/middleman-core/features/partials.feature index d039bdcb..76a7e75a 100644 --- a/middleman-core/features/partials.feature +++ b/middleman-core/features/partials.feature @@ -44,3 +44,8 @@ Feature: Provide Sane Defaults for Partial Behavior When I go to "/index.html" Then I should see "ERb Header" And I should see "Str Footer" + + Scenario: Works with non-template content (svg) + Given the Server is running at "partials-app" + When I go to "/svg.html" + Then I should see " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/middleman-core/fixtures/partials-app/source/svg.html.erb b/middleman-core/fixtures/partials-app/source/svg.html.erb new file mode 100644 index 00000000..759ab44a --- /dev/null +++ b/middleman-core/fixtures/partials-app/source/svg.html.erb @@ -0,0 +1 @@ +<%= partial "images/tiger.svg" %> \ No newline at end of file diff --git a/middleman-core/lib/middleman-core/core_extensions/rendering.rb b/middleman-core/lib/middleman-core/core_extensions/rendering.rb index 091a0e85..074fa017 100644 --- a/middleman-core/lib/middleman-core/core_extensions/rendering.rb +++ b/middleman-core/lib/middleman-core/core_extensions/rendering.rb @@ -188,7 +188,7 @@ module Middleman locals = options[:locals] found_partial = false - resolve_opts = { try_without_underscore: true } + resolve_opts = { try_without_underscore: true, try_static: true } # If the path is known to the sitemap if resource = sitemap.find_resource_by_path(current_path) @@ -209,8 +209,14 @@ module Middleman raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}" unless found_partial - # Render the partial if found, otherwide throw exception - render_individual_file(found_partial, locals, options, self, &block) + r = sitemap.find_resource_by_path(sitemap.file_to_path(found_partial)) + + if r && !r.template? + File.read(r.source_file) + else + # Render the partial if found, otherwide throw exception + render_individual_file(found_partial, locals, options, self, &block) + end end # Render an on-disk file. Used for everything, including layouts. @@ -428,6 +434,7 @@ module Middleman # @param [String] request_path # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine. # @option options [Boolean] :try_without_underscore + # @option options [Boolean] :try_static # @return [Array, Boolean] def resolve_template(request_path, options={}) # Find the path by searching or using the cache @@ -438,6 +445,7 @@ module Middleman # By default, any engine will do preferred_engines = ['*'] + preferred_engines << nil if options[:try_static] # If we're specifically looking for a preferred engine if options.key?(:preferred_engine) @@ -455,7 +463,9 @@ module Middleman end search_paths = preferred_engines.flat_map do |preferred_engine| - path_with_ext = on_disk_path + '.' + preferred_engine + path_with_ext = on_disk_path.dup + path_with_ext << ('.' + preferred_engine) unless preferred_engine.nil? + paths = [path_with_ext] if options[:try_without_underscore] paths << path_with_ext.sub(relative_path, relative_path.sub(/^_/, '').sub(/\/_/, '/')) @@ -468,10 +478,15 @@ module Middleman found_path = Dir[path_with_ext].find do |path| ::Tilt[path] end + + unless found_path + found_path = path_with_ext if File.exist?(path_with_ext) + end + break if found_path end - # If we found one, return it and the found engine + # If we found one, return it if found_path found_path elsif File.exist?(on_disk_path) diff --git a/middleman-core/lib/middleman-core/preview_server.rb b/middleman-core/lib/middleman-core/preview_server.rb index d848fda9..ef3cd21c 100644 --- a/middleman-core/lib/middleman-core/preview_server.rb +++ b/middleman-core/lib/middleman-core/preview_server.rb @@ -111,12 +111,12 @@ module Middleman end def start_file_watcher - return if @listener or @options[:disable_watcher] + return if @listener || @options[:disable_watcher] # Watcher Library require 'listen' - options = {force_polling: @options[:force_polling]} + options = { force_polling: @options[:force_polling] } options[:latency] = @options[:latency] if @options[:latency] @listener = Listen.to(Dir.pwd, options) do |modified, added, removed| diff --git a/middleman-core/lib/middleman-core/sitemap/store.rb b/middleman-core/lib/middleman-core/sitemap/store.rb index 6fbb8b68..18333788 100644 --- a/middleman-core/lib/middleman-core/sitemap/store.rb +++ b/middleman-core/lib/middleman-core/sitemap/store.rb @@ -174,7 +174,7 @@ module Middleman # @param [String] file # @return [String] def file_to_path(file) - file = File.join(@app.root, file) + file = File.expand_path(file, @app.root) prefix = @app.source_dir.sub(/\/$/, '') + '/' return false unless file.start_with?(prefix) From 2426abe6f5fb2e5019840dfa1648a98e58bfb871 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Fri, 18 Jul 2014 14:16:50 -0700 Subject: [PATCH 140/662] bump deps --- Gemfile | 4 ++-- middleman/middleman.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 1fc15c03..893b4fa1 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem 'fivemat', '~> 1.3' gem 'cucumber', '~> 1.3' # Optional middleman dependencies, included for tests -gem 'less', '2.3.0', require: false +gem 'less', '2.3', require: false gem 'slim', '>= 2.0', require: false gem 'liquid', '>= 2.6', require: false gem 'stylus', '>= 1.0', require: false @@ -26,7 +26,7 @@ gem 'therubyrhino', '>= 2.0', platforms: :jruby # Code Quality gem 'rubocop', '~> 0.24', require: false -gem 'simplecov', '0.7.1', require: false +gem 'simplecov', '0.9', require: false gem 'coveralls', '~> 0.7', require: false # Middleman itself diff --git a/middleman/middleman.gemspec b/middleman/middleman.gemspec index 506fc640..a26c64ad 100644 --- a/middleman/middleman.gemspec +++ b/middleman/middleman.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |s| s.add_dependency("compass-import-once", ["1.0.4"]) s.add_dependency("compass", [">= 0.12.4"]) s.add_dependency("uglifier", ["~> 2.5"]) - s.add_dependency("coffee-script", ["~> 2.2.0"]) + s.add_dependency("coffee-script", ["~> 2.2"]) s.add_dependency("execjs", ["~> 2.0"]) s.add_dependency("kramdown", ["~> 1.2"]) end From 22dace72df8e9f9a30e29d064484e2830c467054 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 22 Sep 2013 14:36:00 -0700 Subject: [PATCH 141/662] Upgrade url_for to search for resources relative to their destination paths as well as their source paths. This would fix #818. --- middleman-core/features/directory_index.feature | 11 +++++------ middleman-core/lib/middleman-core/util.rb | 11 ++++++++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/middleman-core/features/directory_index.feature b/middleman-core/features/directory_index.feature index 99dbe60e..c1b8f2ef 100644 --- a/middleman-core/features/directory_index.feature +++ b/middleman-core/features/directory_index.feature @@ -27,12 +27,12 @@ Feature: Directory Index And the file "regular/index.html" should contain "Regular" And the file "evil spaces/index.html" should contain "Spaces" - + Scenario: Preview normal file Given the Server is running at "indexable-app" When I go to "/needs_index/" Then I should see "Indexable" - + Scenario: Preview normal file with spaces in filename Given the Server is running at "indexable-app" When I go to "/evil%20spaces/" @@ -42,7 +42,7 @@ Feature: Directory Index Given the Server is running at "indexable-app" When I go to "/a_folder/needs_index/" Then I should see "Indexable" - + Scenario: Preview ignored file Given the Server is running at "indexable-app" When I go to "/leave_me_alone/" @@ -69,14 +69,13 @@ Feature: Directory Index And the Server is running at "indexable-app" When I go to "/link_to/" Then I should see 'link_to: Needs Index' - Then I should see 'explicit_link_to: Explicit' + Then I should see 'explicit_link_to: Explicit' Then I should see 'unknown_link_to: Unknown' Then I should see 'relative_link_to: Relative' Then I should see 'link_to_with_spaces: Spaces' When I go to "/link_to/sub/" Then I should see 'link_to: Needs Index' - Then I should see 'explicit_link_to: Explicit' + Then I should see 'explicit_link_to: Explicit' Then I should see 'unknown_link_to: Unknown' Then I should see 'relative_link_to: Relative' Then I should see 'link_to_with_spaces: Spaces' - diff --git a/middleman-core/lib/middleman-core/util.rb b/middleman-core/lib/middleman-core/util.rb index 5ce84523..eabd3e8e 100644 --- a/middleman-core/lib/middleman-core/util.rb +++ b/middleman-core/lib/middleman-core/util.rb @@ -247,7 +247,16 @@ module Middleman current_source_dir = Pathname('/' + this_resource.path).dirname url_path = current_source_dir.join(url_path) if url_path.relative? resource = app.sitemap.find_resource_by_path(url_path.to_s) - resource_url = resource.url if resource + if resource + resource_url = resource.url + else + # Try to find a resource relative to destination paths + url_path = Pathname(uri.path) + current_source_dir = Pathname('/' + this_resource.destination_path).dirname + url_path = current_source_dir.join(url_path) if url_path.relative? + resource = app.sitemap.find_resource_by_destination_path(url_path.to_s) + resource_url = resource.url if resource + end elsif options[:find_resource] && uri.path resource = app.sitemap.find_resource_by_path(uri.path) resource_url = resource.url if resource From debf3c704b02c10511841a9268bae341cf6ab4bf Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sun, 20 Jul 2014 13:37:16 -0700 Subject: [PATCH 142/662] Remove template lookup cache in build mode. Fixes #1301 --- .../lib/middleman-core/template_renderer.rb | 95 +++++++++++-------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/middleman-core/lib/middleman-core/template_renderer.rb b/middleman-core/lib/middleman-core/template_renderer.rb index 87111580..bea250d7 100644 --- a/middleman-core/lib/middleman-core/template_renderer.rb +++ b/middleman-core/lib/middleman-core/template_renderer.rb @@ -161,60 +161,71 @@ module Middleman # @param [String] request_path # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine. # @return [String, Boolean] Either the path to the template, or false - Contract IsA['Middleman::Application'], Or[Symbol, String], Hash => Maybe[String] + Contract IsA['Middleman::Application'], Or[Symbol, String], Maybe[Hash] => Maybe[String] def self.resolve_template(app, request_path, options={}) # 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 = Util.strip_leading_slash(request_path) - on_disk_path = File.expand_path(relative_path, app.source_dir) - # By default, any engine will do - preferred_engines = ['*'] - preferred_engines << nil if options[:try_static] + # Cache lookups in build mode only + if app.build? + cache.fetch(:resolve_template, request_path, options) do + uncached_resolve_template(app, request_path, options) + end + else + uncached_resolve_template(app, request_path, options) + end + end - # If we're specifically looking for a preferred engine - if options.key?(:preferred_engine) - extension_class = ::Tilt[options[:preferred_engine]] + Contract IsA['Middleman::Application'], String, Hash => Maybe[String] + def self.uncached_resolve_template(app, request_path, options) + relative_path = Util.strip_leading_slash(request_path) + on_disk_path = File.expand_path(relative_path, app.source_dir) - # Get a list of extensions for a preferred engine - matched_exts = ::Tilt.mappings.select do |_, engines| - engines.include? extension_class - end.keys + # By default, any engine will do + preferred_engines = ['*'] + preferred_engines << nil if options[:try_static] - # Prefer to look for the matched extensions - unless matched_exts.empty? - preferred_engines.unshift('{' + matched_exts.join(',') + '}') - end + # If we're specifically looking for a preferred engine + if options.key?(:preferred_engine) + extension_class = ::Tilt[options[:preferred_engine]] + + # Get a list of extensions for a preferred engine + matched_exts = ::Tilt.mappings.select do |_, engines| + engines.include? extension_class + end.keys + + # Prefer to look for the matched extensions + unless matched_exts.empty? + preferred_engines.unshift('{' + matched_exts.join(',') + '}') + end + end + + search_paths = preferred_engines.map do |preferred_engine| + path_with_ext = on_disk_path.dup + path_with_ext << ('.' + preferred_engine) unless preferred_engine.nil? + path_with_ext + end + + found_path = nil + search_paths.each do |path_with_ext| + found_path = Dir[path_with_ext].find do |path| + ::Tilt[path] end - search_paths = preferred_engines.map do |preferred_engine| - path_with_ext = on_disk_path.dup - path_with_ext << ('.' + preferred_engine) unless preferred_engine.nil? - path_with_ext + unless found_path + found_path = path_with_ext if File.exist?(path_with_ext) end - found_path = nil - search_paths.each do |path_with_ext| - found_path = Dir[path_with_ext].find do |path| - ::Tilt[path] - end + break if found_path + end - unless found_path - found_path = path_with_ext if File.exist?(path_with_ext) - end - - break if found_path - end - - # If we found one, return it - if found_path - found_path - elsif File.exist?(on_disk_path) - on_disk_path - else - nil - end + # If we found one, return it + if found_path + found_path + elsif File.exist?(on_disk_path) + on_disk_path + else + nil end end end From 15d6210df85560cca00df520811de25f9b79392a Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sun, 20 Jul 2014 13:53:05 -0700 Subject: [PATCH 143/662] Use the resource instead of the request path for auto asset helpers. Fixes #1326 --- .../features/helpers_auto_javascript_include_tag.feature | 5 +++++ .../fixtures/auto-js-directory-index-app/config.rb | 1 + .../auto-js-directory-index-app/source/auto-js.html.erb | 1 + .../source/javascripts/auto-js.js | 1 + .../lib/middleman-more/core_extensions/default_helpers.rb | 2 +- 5 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 middleman-core/fixtures/auto-js-directory-index-app/config.rb create mode 100755 middleman-core/fixtures/auto-js-directory-index-app/source/auto-js.html.erb create mode 100644 middleman-core/fixtures/auto-js-directory-index-app/source/javascripts/auto-js.js diff --git a/middleman-core/features/helpers_auto_javascript_include_tag.feature b/middleman-core/features/helpers_auto_javascript_include_tag.feature index 4407ea72..ffcf7df5 100644 --- a/middleman-core/features/helpers_auto_javascript_include_tag.feature +++ b/middleman-core/features/helpers_auto_javascript_include_tag.feature @@ -6,6 +6,11 @@ Feature: Built-in auto_javascript_include_tag view helper When I go to "/auto-js.html" Then I should see "javascripts/auto-js.js" + Scenario: Viewing the root path (directory index) + Given the Server is running at "auto-js-directory-index-app" + When I go to "/auto-js/index.html" + Then I should see "javascripts/auto-js.js" + Scenario: Viewing the root path (build mode) Given a successfully built app at "auto-js-app" When I cd to "build" diff --git a/middleman-core/fixtures/auto-js-directory-index-app/config.rb b/middleman-core/fixtures/auto-js-directory-index-app/config.rb new file mode 100644 index 00000000..f343b291 --- /dev/null +++ b/middleman-core/fixtures/auto-js-directory-index-app/config.rb @@ -0,0 +1 @@ +activate :directory_indexes \ No newline at end of file diff --git a/middleman-core/fixtures/auto-js-directory-index-app/source/auto-js.html.erb b/middleman-core/fixtures/auto-js-directory-index-app/source/auto-js.html.erb new file mode 100755 index 00000000..7af247d9 --- /dev/null +++ b/middleman-core/fixtures/auto-js-directory-index-app/source/auto-js.html.erb @@ -0,0 +1 @@ +<%= auto_javascript_include_tag %> \ No newline at end of file diff --git a/middleman-core/fixtures/auto-js-directory-index-app/source/javascripts/auto-js.js b/middleman-core/fixtures/auto-js-directory-index-app/source/javascripts/auto-js.js new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/middleman-core/fixtures/auto-js-directory-index-app/source/javascripts/auto-js.js @@ -0,0 +1 @@ + diff --git a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb index 4b60bb65..91ade628 100644 --- a/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb +++ b/middleman-core/lib/middleman-more/core_extensions/default_helpers.rb @@ -118,7 +118,7 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension # 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 = File.join(asset_dir, current_resource.path) path = path.sub(/#{Regexp.escape(File.extname(path))}$/, ".#{asset_ext}") yield path if sitemap.find_resource_by_path(path) From 525e700bfa5f6515621fec2fef454d301c83ce72 Mon Sep 17 00:00:00 2001 From: Thomas Reynolds Date: Sun, 20 Jul 2014 14:25:47 -0700 Subject: [PATCH 144/662] Move all templates over to Github. Remove need for auto-loaded extensions in CLI --- middleman-cli/lib/middleman-cli.rb | 1 - middleman-cli/lib/middleman-cli/git.rb | 51 - middleman-cli/lib/middleman-cli/init.rb | 76 +- middleman-cli/lib/middleman-templates.rb | 108 -- .../lib/middleman-templates/default.rb | 31 - .../default/source/images/background.png | Bin 2726 -> 0 bytes .../default/source/images/middleman.png | Bin 25282 -> 0 bytes .../default/source/index.html.erb | 10 - .../default/source/javascripts/all.js | 1 - .../default/source/layouts/layout.erb | 19 - .../default/source/stylesheets/all.css | 55 - .../default/source/stylesheets/normalize.css | 375 ----- .../lib/middleman-templates/empty.rb | 19 - .../lib/middleman-templates/html5.rb | 23 - .../html5/source/.htaccess | 679 --------- .../middleman-templates/html5/source/404.html | 59 - .../html5/source/CHANGELOG.md | 197 --- .../html5/source/CONTRIBUTING.md | 154 -- .../html5/source/LICENSE.md | 19 - .../html5/source/README.md | 62 - .../source/apple-touch-icon-precomposed.png | Bin 1076 -> 0 bytes .../html5/source/crossdomain.xml | 15 - .../html5/source/css/main.css | 294 ---- .../html5/source/css/normalize.css | 527 ------- .../html5/source/favicon.ico | Bin 766 -> 0 bytes .../html5/source/humans.txt | 15 - .../html5/source/img/.gitignore | 0 .../html5/source/index.html.erb | 6 - .../html5/source/js/main.js | 1 - .../html5/source/js/plugins.js | 24 - .../source/js/vendor/jquery-1.11.0.min.js | 4 - .../source/js/vendor/modernizr-2.7.1.min.js | 4 - .../html5/source/layouts/layout.erb | 42 - .../html5/source/robots.txt | 5 - .../lib/middleman-templates/local.rb | 17 - .../lib/middleman-templates/mobile.rb | 23 - .../mobile/source/404.html | 37 - .../mobile/source/README.markdown | 21 - .../mobile/source/crossdomain.xml | 25 - .../mobile/source/css/style.css | 315 ---- .../mobile/source/humans.txt | 43 - .../mobile/source/img/h/apple-touch-icon.png | Bin 3037 -> 0 bytes .../mobile/source/img/h/splash.png | Bin 17069 -> 0 bytes .../img/l/apple-touch-icon-precomposed.png | Bin 2436 -> 0 bytes .../mobile/source/img/l/apple-touch-icon.png | Bin 2436 -> 0 bytes .../mobile/source/img/l/splash.png | Bin 1915 -> 0 bytes .../mobile/source/img/m/apple-touch-icon.png | Bin 4469 -> 0 bytes .../mobile/source/index.html | 92 -- .../mobile/source/js/libs/modernizr-custom.js | 14 - .../mobile/source/js/libs/respond.min.js | 7 - .../mobile/source/js/mylibs/helper.js | 171 --- .../mobile/source/js/plugins.js | 20 - .../mobile/source/js/script.js | 0 .../mobile/source/robots.txt | 4 - .../mobile/source/sitemap.xml | 9 - .../mobile/source/test/index.html | 31 - .../mobile/source/test/qunit/qunit.css | 148 -- .../mobile/source/test/qunit/qunit.js | 1265 ----------------- .../mobile/source/test/tests.js | 21 - .../tools/googleanalyticsformobile/Readme.PDF | Bin 22114 -> 0 bytes .../aspx/aspx1.snippet | 31 - .../aspx/aspx2.snippet | 2 - .../googleanalyticsformobile/aspx/ga.aspx | 195 --- .../googleanalyticsformobile/aspx/sample.aspx | 44 - .../tools/googleanalyticsformobile/jsp/ga.jsp | 225 --- .../googleanalyticsformobile/jsp/jsp1.snippet | 35 - .../googleanalyticsformobile/jsp/jsp2.snippet | 2 - .../googleanalyticsformobile/jsp/sample.jsp | 51 - .../tools/googleanalyticsformobile/php/ga.php | 176 --- .../googleanalyticsformobile/php/php1.snippet | 30 - .../googleanalyticsformobile/php/php2.snippet | 4 - .../googleanalyticsformobile/php/sample.php | 44 - .../tools/googleanalyticsformobile/pl/ga.pl | 195 --- .../googleanalyticsformobile/pl/perl1.snippet | 27 - .../googleanalyticsformobile/pl/perl2.snippet | 1 - .../googleanalyticsformobile/pl/sample.pl | 38 - .../tools/mobile-bookmark-bubble/COPYING | 202 --- .../mobile-bookmark-bubble/bookmark_bubble.js | 559 -------- .../example/example.html | 43 - .../mobile-bookmark-bubble/example/example.js | 57 - .../mobile-bookmark-bubble/images/arrow.png | Bin 704 -> 0 bytes .../mobile-bookmark-bubble/images/close.png | Bin 206 -> 0 bytes .../images/generate_base64_images | 33 - .../images/icon_calendar.png | Bin 3758 -> 0 bytes .../mobile/source/tools/wspl/README | 27 - .../source/tools/wspl/databasefactory.js | 45 - .../mobile/source/tools/wspl/dbworker.js | 324 ----- .../source/tools/wspl/dbworker_test.html | 393 ----- .../source/tools/wspl/dbworkerstarter.js | 32 - .../source/tools/wspl/dbwrapper_gears.js | 595 -------- .../tools/wspl/dbwrapper_gears_test.html | 404 ------ .../source/tools/wspl/dbwrapper_html5.js | 203 --- .../tools/wspl/dbwrapper_html5_test.html | 468 ------ .../mobile/source/tools/wspl/dbwrapperapi.js | 202 --- .../source/tools/wspl/dbwrapperapi_test.html | 51 - .../source/tools/wspl/gears_resultset.js | 71 - .../tools/wspl/gears_resultset_test.html | 86 -- .../source/tools/wspl/gears_transaction.js | 196 --- .../tools/wspl/gears_transaction_test.html | 221 --- .../mobile/source/tools/wspl/gearsutils.js | 94 -- .../source/tools/wspl/gearsutils_test.html | 84 -- .../source/tools/wspl/global_functions.js | 72 - .../source/tools/wspl/simplenotes/index.html | 347 ----- .../tools/wspl/simplenotes/simplenotes.js | 503 ------- .../source/tools/wspl/simplenotes/styles.css | 66 - .../source/tools/wspl/simplenotes/template.js | 75 - .../lib/middleman-templates/shared/Gemfile.tt | 14 - .../lib/middleman-templates/shared/config.ru | 4 - .../lib/middleman-templates/shared/config.tt | 84 -- .../lib/middleman-templates/shared/gitignore | 18 - middleman-core/features/cli_init.feature | 77 +- .../lib/middleman-core/auto_gem_extensions.rb | 55 - .../lib/middleman-core/load_paths.rb | 9 +- 113 files changed, 67 insertions(+), 11886 deletions(-) delete mode 100644 middleman-cli/lib/middleman-cli/git.rb delete mode 100644 middleman-cli/lib/middleman-templates.rb delete mode 100644 middleman-cli/lib/middleman-templates/default.rb delete mode 100644 middleman-cli/lib/middleman-templates/default/source/images/background.png delete mode 100644 middleman-cli/lib/middleman-templates/default/source/images/middleman.png delete mode 100644 middleman-cli/lib/middleman-templates/default/source/index.html.erb delete mode 100644 middleman-cli/lib/middleman-templates/default/source/javascripts/all.js delete mode 100644 middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb delete mode 100644 middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css delete mode 100644 middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css delete mode 100644 middleman-cli/lib/middleman-templates/empty.rb delete mode 100644 middleman-cli/lib/middleman-templates/html5.rb delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/.htaccess delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/404.html delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/LICENSE.md delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/README.md delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/css/main.css delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/css/normalize.css delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/favicon.ico delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/humans.txt delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/img/.gitignore delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/index.html.erb delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/js/main.js delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/js/plugins.js delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/js/vendor/modernizr-2.7.1.min.js delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/layouts/layout.erb delete mode 100644 middleman-cli/lib/middleman-templates/html5/source/robots.txt delete mode 100644 middleman-cli/lib/middleman-templates/local.rb delete mode 100644 middleman-cli/lib/middleman-templates/mobile.rb delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/404.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/README.markdown delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/crossdomain.xml delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/css/style.css delete mode 100644 middleman-cli/lib/middleman-templates/mobile/source/humans.txt delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/h/apple-touch-icon.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/h/splash.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon-precomposed.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/l/apple-touch-icon.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/l/splash.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/img/m/apple-touch-icon.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/index.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/js/libs/modernizr-custom.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/js/libs/respond.min.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/js/mylibs/helper.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/js/plugins.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/js/script.js delete mode 100644 middleman-cli/lib/middleman-templates/mobile/source/robots.txt delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/sitemap.xml delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/test/index.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.css delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/test/qunit/qunit.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/test/tests.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/ga.php delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/php/sample.php delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/COPYING delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/README delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/databasefactory.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworker_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbworkerstarter.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_gears_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapper_html5_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/dbwrapperapi_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_resultset_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gears_transaction_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/gearsutils_test.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/global_functions.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/index.html delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/simplenotes.js delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/styles.css delete mode 100755 middleman-cli/lib/middleman-templates/mobile/source/tools/wspl/simplenotes/template.js delete mode 100644 middleman-cli/lib/middleman-templates/shared/Gemfile.tt delete mode 100644 middleman-cli/lib/middleman-templates/shared/config.ru delete mode 100755 middleman-cli/lib/middleman-templates/shared/config.tt delete mode 100644 middleman-cli/lib/middleman-templates/shared/gitignore delete mode 100644 middleman-core/lib/middleman-core/auto_gem_extensions.rb diff --git a/middleman-cli/lib/middleman-cli.rb b/middleman-cli/lib/middleman-cli.rb index fa8a4b0f..73f59795 100644 --- a/middleman-cli/lib/middleman-cli.rb +++ b/middleman-cli/lib/middleman-cli.rb @@ -94,4 +94,3 @@ require 'middleman-cli/extension' require 'middleman-cli/server' require 'middleman-cli/build' require 'middleman-cli/console' -require 'middleman-cli/git' diff --git a/middleman-cli/lib/middleman-cli/git.rb b/middleman-cli/lib/middleman-cli/git.rb deleted file mode 100644 index c233824d..00000000 --- a/middleman-cli/lib/middleman-cli/git.rb +++ /dev/null @@ -1,51 +0,0 @@ -# CLI Module -module Middleman::Cli - # A thor task for creating new projects - class Git < Thor - include Thor::Actions - check_unknown_options! - - namespace :git - - desc 'git REPO TARGET [options]', 'Create new project from REPO at TARGET' - - # Do not run bundle install - method_option 'skip-bundle', - type: :boolean, - aliases: '-B', - default: false, - desc: "Don't run bundle install" - - # The git task - # @param [String] name - def git(repo, target='.') - require 'tmpdir' - - path = repository_path(repo) - - Dir.mktmpdir do |dir| - run("git clone #{path} #{dir}") - - source_paths << dir - - directory dir, target, exclude_pattern: /\.git\/|\.gitignore$/ - - inside(target) do - run('bundle install') - end unless ENV['TEST'] || options[:'skip-bundle'] - end - end - - protected - - def repository_path(repo) - "git://github.com/#{repo}.git" - end - end - - def self.exit_on_failure? - true - end - - Base.map('g' => 'git') -end diff --git a/middleman-cli/lib/middleman-cli/init.rb b/middleman-cli/lib/middleman-cli/init.rb index 444f4c6b..3efdd11e 100644 --- a/middleman-cli/lib/middleman-cli/init.rb +++ b/middleman-cli/lib/middleman-cli/init.rb @@ -1,48 +1,70 @@ -require 'middleman-templates' - # CLI Module module Middleman::Cli # A thor task for creating new projects class Init < Thor + include Thor::Actions check_unknown_options! namespace :init - desc 'init NAME [options]', 'Create new project NAME' - available_templates = ::Middleman::Templates.registered.keys.join(', ') + desc 'init TARGET [options]', 'Create new project at TARGET' method_option 'template', aliases: '-T', - default: 'default', - desc: "Use a project template: #{available_templates}" - method_option 'css_dir', - desc: 'The path to the css files' - method_option 'js_dir', - desc: 'The path to the javascript files' - method_option 'images_dir', - desc: 'The path to the image files' - method_option 'rack', - type: :boolean, - default: false, - desc: 'Include a config.ru file' + default: 'middleman/middleman-templates-default', + desc: 'Use a project template' + + # Do not run bundle install method_option 'skip-bundle', type: :boolean, aliases: '-B', default: false, - desc: "Don't run bundle install" - method_option 'skip-git', - type: :boolean, - default: false, - desc: 'Skip Git ignores and keeps' + desc: 'Skip bundle install' + # The init task # @param [String] name - def init(name='.') - key = options[:template].to_sym - unless ::Middleman::Templates.registered.key?(key) - raise Thor::Error, "Unknown project template '#{key}'" + def init(target='.') + require 'tmpdir' + + repo = if shortname?(options[:template]) + require 'open-uri' + require 'json' + + api = 'http://directory.middlemanapp.com/api' + uri = ::URI.parse("#{api}/#{options[:template]}.json") + + begin + data = ::JSON.parse(uri.read) + data['links']['github'] + rescue ::OpenURI::HTTPError + puts "Template `#{options[:template]}` not found in Middleman Directory." + puts 'Did you mean to use a full `user/repo` path?' + exit + end + else + repository_path(options[:template]) end - thor_group = ::Middleman::Templates.registered[key] - thor_group.new([name], options).invoke_all + Dir.mktmpdir do |dir| + run("git clone #{repo} #{dir}") + + source_paths << dir + + directory dir, target, exclude_pattern: /\.git\/|\.gitignore$/ + + inside(target) do + run('bundle install') + end unless ENV['TEST'] || options[:'skip-bundle'] + end + end + + protected + + def shortname?(repo) + repo.split('/').length != 2 + end + + def repository_path(repo) + "git://github.com/#{repo}.git" end end diff --git a/middleman-cli/lib/middleman-templates.rb b/middleman-cli/lib/middleman-templates.rb deleted file mode 100644 index 477f0633..00000000 --- a/middleman-cli/lib/middleman-templates.rb +++ /dev/null @@ -1,108 +0,0 @@ -# rubocop:disable FileName - -# Setup our load paths -libdir = File.expand_path(File.dirname(__FILE__)) -$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir) - -# Require Thor since that's what the whole CLI is built around -require 'thor' -require 'thor/group' - -# Templates Module -module Middleman - module Templates - # Static methods - class << self - # Get list of registered templates and add new ones - # - # Middleman::Templates.register(:ext_name, klass) - # - # @param [Symbol] name The name of the template - # @param [Class] klass The class to be executed for this template - # @return [Hash] List of registered templates - def register(name=nil, klass=nil) - @_template_mappings ||= {} - @_template_mappings[name] = klass if name && klass - @_template_mappings - end - - # Middleman::Templates.register(name, klass) - alias_method :registered, :register - end - - # Base Template class. Handles basic options and paths. - class Base < ::Thor::Group - include Thor::Actions - - def initialize(names, options) - super - source_paths << File.join(File.dirname(__FILE__), 'middleman-templates') - end - - # The gemfile template to use. Individual templates can define this class - # method to override the template path. - def self.gemfile_template - 'shared/Gemfile.tt' - end - - # Required path for the new project to be generated - argument :location, type: :string - - # Name of the template being used to generate the project. - class_option :template, default: 'default' - - # Output a config.ru file for Rack if --rack is passed - class_option :rack, type: :boolean, default: false - - # Write a Rack config.ru file for project - # @return [void] - def generate_rack! - return unless options[:rack] - template 'shared/config.ru', File.join(location, 'config.ru') - end - - # Do not run bundle install - class_option :'skip-bundle', type: :boolean, default: false - - # Write a Bundler Gemfile file for project - # @return [void] - def generate_bundler! - template self.class.gemfile_template, File.join(location, 'Gemfile') - return if options[:'skip-bundle'] - inside(location) do - run('bundle install') - end unless ENV['TEST'] - end - - # Output a .gitignore file - class_option :'skip-git', type: :boolean, default: false - - # Write a .gitignore file for project - # @return [void] - def generate_gitignore! - return if options[:'skip-git'] - copy_file 'shared/gitignore', File.join(location, '.gitignore') - end - end - end -end - -# Register all official templates -Dir.glob(File.expand_path('../middleman-templates/*.rb', __FILE__), &method(:require)) - -# Sometimes HOME doesn't exist, in which case there's no point to local templates -if ENV['HOME'] - # Iterate over directories in the templates path and register each one. - Dir[File.join(Middleman::Templates::Local.source_root, '*')].each do |dir| - next unless File.directory?(dir) - template_file = File.join(dir, 'template.rb') - - # If a template.rb file is found require it (therefore registering the template) - # else register the folder as a Local template (which when built, just copies the folder) - if File.exist?(template_file) - require template_file - else - Middleman::Templates.register(File.basename(dir).to_sym, Middleman::Templates::Local) - end - end -end diff --git a/middleman-cli/lib/middleman-templates/default.rb b/middleman-cli/lib/middleman-templates/default.rb deleted file mode 100644 index 3eb1ff52..00000000 --- a/middleman-cli/lib/middleman-templates/default.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Default Middleman template -class Middleman::Templates::Default < Middleman::Templates::Base - class_option :css_dir, default: 'stylesheets', desc: 'The path to the css files' - class_option :js_dir, default: 'javascripts', desc: 'The path to the javascript files' - class_option :images_dir, default: 'images', desc: 'The path to the image files' - - # Template files are relative to this file - # @return [String] - def self.source_root - File.dirname(__FILE__) - end - - # Output the files - # @return [void] - def build_scaffold! - template 'shared/config.tt', File.join(location, 'config.rb') - copy_file 'default/source/index.html.erb', File.join(location, 'source/index.html.erb') - copy_file 'default/source/layouts/layout.erb', File.join(location, 'source/layouts/layout.erb') - empty_directory File.join(location, 'source', options[:css_dir]) - copy_file 'default/source/stylesheets/all.css', File.join(location, 'source', options[:css_dir], 'all.css') - copy_file 'default/source/stylesheets/normalize.css', File.join(location, 'source', options[:css_dir], 'normalize.css') - empty_directory File.join(location, 'source', options[:js_dir]) - copy_file 'default/source/javascripts/all.js', File.join(location, 'source', options[:js_dir], 'all.js') - empty_directory File.join(location, 'source', options[:images_dir]) - copy_file 'default/source/images/background.png', File.join(location, 'source', options[:images_dir], 'background.png') - copy_file 'default/source/images/middleman.png', File.join(location, 'source', options[:images_dir], 'middleman.png') - end -end - -# Register this template -Middleman::Templates.register(:default, Middleman::Templates::Default) diff --git a/middleman-cli/lib/middleman-templates/default/source/images/background.png b/middleman-cli/lib/middleman-templates/default/source/images/background.png deleted file mode 100644 index 8681d44f7954cf98014bf87abb43af7ee7f63cd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2726 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 bGcYsM>m>xaUi%pUYB_qk`njxgN@xNA9EPZY diff --git a/middleman-cli/lib/middleman-templates/default/source/images/middleman.png b/middleman-cli/lib/middleman-templates/default/source/images/middleman.png deleted file mode 100644 index c685e564378b038c44e51ec98454af7237d3412a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25282 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 a7#`i-@whYe`D6wL1_n=8KbLh*2~7ZtE++T@ diff --git a/middleman-cli/lib/middleman-templates/default/source/index.html.erb b/middleman-cli/lib/middleman-templates/default/source/index.html.erb deleted file mode 100644 index 7537cd68..00000000 --- a/middleman-cli/lib/middleman-templates/default/source/index.html.erb +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Welcome to Middleman ---- - -
-

Middleman is Watching

-

- <%= link_to "Read Online Documentation", "http://middlemanapp.com/" %> -

-
\ No newline at end of file diff --git a/middleman-cli/lib/middleman-templates/default/source/javascripts/all.js b/middleman-cli/lib/middleman-templates/default/source/javascripts/all.js deleted file mode 100644 index 2becd765..00000000 --- a/middleman-cli/lib/middleman-templates/default/source/javascripts/all.js +++ /dev/null @@ -1 +0,0 @@ -//= require_tree . \ No newline at end of file diff --git a/middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb b/middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb deleted file mode 100644 index fffa9ad9..00000000 --- a/middleman-cli/lib/middleman-templates/default/source/layouts/layout.erb +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - <%= current_page.data.title || "The Middleman" %> - - <%= stylesheet_link_tag "normalize", "all" %> - <%= javascript_include_tag "all" %> - - - - <%= yield %> - - diff --git a/middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css b/middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css deleted file mode 100644 index 6ff94cf9..00000000 --- a/middleman-cli/lib/middleman-templates/default/source/stylesheets/all.css +++ /dev/null @@ -1,55 +0,0 @@ -@charset "utf-8"; - -body { - background: #d4d4d4 url("../images/background.png"); - text-align: center; - font-family: sans-serif; } - -h1 { - color: rgba(0, 0, 0, .3); - font-weight: bold; - font-size: 32px; - letter-spacing: -1px; - text-transform: uppercase; - text-shadow: 0 1px 0 rgba(255, 255, 255, .5); - background: url("../images/middleman.png") no-repeat center 100px; - padding: 350px 0 10px; - margin: 0; } - -.doc { - font-size: 14px; - margin: 0; } - .doc:before, - .doc:after { - opacity: .2; - padding: 6px; - font-style: normal; - position: relative; - content: "•"; } - .doc a { - color: rgba(0, 0, 0, 0.3); } - .doc a:hover { - color: #666; } - -.welcome { - -webkit-animation-name: welcome; - -webkit-animation-duration: .9s; } - -@-webkit-keyframes welcome { - from { - -webkit-transform: scale(0); - opacity: 0; - } - 50% { - -webkit-transform: scale(0); - opacity: 0; - } - 82.5% { - -webkit-transform: scale(1.03); - -webkit-animation-timing-function: ease-out; - opacity: 1; - } - to { - -webkit-transform: scale(1); - } -} \ No newline at end of file diff --git a/middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css b/middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css deleted file mode 100644 index 73abb76f..00000000 --- a/middleman-cli/lib/middleman-templates/default/source/stylesheets/normalize.css +++ /dev/null @@ -1,375 +0,0 @@ -/*! normalize.css v2.0.1 | MIT License | git.io/normalize */ - -/* ========================================================================== - HTML5 display definitions - ========================================================================== */ - -/* - * Corrects `block` display not defined in IE 8/9. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section, -summary { - display: block; -} - -/* - * Corrects `inline-block` display not defined in IE 8/9. - */ - -audio, -canvas, -video { - display: inline-block; -} - -/* - * Prevents modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/* - * Addresses styling for `hidden` attribute not present in IE 8/9. - */ - -[hidden] { - display: none; -} - -/* ========================================================================== - Base - ========================================================================== */ - -/* - * 1. Sets default font family to sans-serif. - * 2. Prevents iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ - -ms-text-size-adjust: 100%; /* 2 */ -} - -/* - * Removes default margin. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/* - * Addresses `outline` inconsistency between Chrome and other browsers. - */ - -a:focus { - outline: thin dotted; -} - -/* - * Improves readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* ========================================================================== - Typography - ========================================================================== */ - -/* - * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, - * Safari 5, and Chrome. - */ - -h1 { - font-size: 2em; -} - -/* - * Addresses styling not present in IE 8/9, Safari 5, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/* - * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/* - * Addresses styling not present in Safari 5 and Chrome. - */ - -dfn { - font-style: italic; -} - -/* - * Addresses styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - - -/* - * Corrects font family set oddly in Safari 5 and Chrome. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -/* - * Improves readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/* - * Sets consistent quote types. - */ - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -/* - * Addresses inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/* - * Prevents `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* ========================================================================== - Embedded content - ========================================================================== */ - -/* - * Removes border when inside `a` element in IE 8/9. - */ - -img { - border: 0; -} - -/* - * Corrects overflow displayed oddly in IE 9. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* ========================================================================== - Figures - ========================================================================== */ - -/* - * Addresses margin not present in IE 8/9 and Safari 5. - */ - -figure { - margin: 0; -} - -/* ========================================================================== - Forms - ========================================================================== */ - -/* - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/* - * 1. Corrects color not being inherited in IE 8/9. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/* - * 1. Corrects font family not being inherited in all browsers. - * 2. Corrects font size not being inherited in all browsers. - * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome - */ - -button, -input, -select, -textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 2 */ - margin: 0; /* 3 */ -} - -/* - * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -button, -input { - line-height: normal; -} - -/* - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Corrects inability to style clickable `input` types in iOS. - * 3. Improves usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/* - * Re-set default cursor for disabled elements. - */ - -button[disabled], -input[disabled] { - cursor: default; -} - -/* - * 1. Addresses box sizing set to `content-box` in IE 8/9. - * 2. Removes excess padding in IE 8/9. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/* - * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/* - * Removes inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/* - * Removes inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/* - * 1. Removes default vertical scrollbar in IE 8/9. - * 2. Improves readability and alignment in all browsers. - */ - -textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ -} - -/* ========================================================================== - Tables - ========================================================================== */ - -/* - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} \ No newline at end of file diff --git a/middleman-cli/lib/middleman-templates/empty.rb b/middleman-cli/lib/middleman-templates/empty.rb deleted file mode 100644 index 18ac3106..00000000 --- a/middleman-cli/lib/middleman-templates/empty.rb +++ /dev/null @@ -1,19 +0,0 @@ -# A barebones template with nothing much in it -class Middleman::Templates::Empty < Middleman::Templates::Base - # Template files are relative to this file - # @return [String] - def self.source_root - File.dirname(__FILE__) - end - - # Output the files - # @return [void] - def build_scaffold! - template 'shared/config.tt', File.join(location, 'config.rb') - empty_directory File.join(location, 'source') - create_file File.join(location, 'source', '.gitkeep') unless options[:'skip-git'] - end -end - -# Register this template -Middleman::Templates.register(:empty, Middleman::Templates::Empty) diff --git a/middleman-cli/lib/middleman-templates/html5.rb b/middleman-cli/lib/middleman-templates/html5.rb deleted file mode 100644 index de0bf25d..00000000 --- a/middleman-cli/lib/middleman-templates/html5.rb +++ /dev/null @@ -1,23 +0,0 @@ -# HTML5 Boilerplate template -class Middleman::Templates::Html5 < Middleman::Templates::Base - # Slightly different paths - class_option :css_dir, default: 'css', desc: 'The path to the css files' - class_option :js_dir, default: 'js', desc: 'The path to the javascript files' - class_option :images_dir, default: 'img', desc: 'The path to the image files' - - # Template files are relative to this file - # @return [String] - def self.source_root - File.dirname(__FILE__) - end - - # Output the files - # @return [void] - def build_scaffold! - template 'shared/config.tt', File.join(location, 'config.rb') - directory 'html5/source', File.join(location, 'source') - end -end - -# Register this template -Middleman::Templates.register(:html5, Middleman::Templates::Html5) diff --git a/middleman-cli/lib/middleman-templates/html5/source/.htaccess b/middleman-cli/lib/middleman-templates/html5/source/.htaccess deleted file mode 100644 index 63c0aaca..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/.htaccess +++ /dev/null @@ -1,679 +0,0 @@ -# Apache Server Configs v2.3.0 | MIT License -# https://github.com/h5bp/server-configs-apache - -# (!) Using `.htaccess` files slows down Apache, therefore, if you have access -# to the main server config file (usually called `httpd.conf`), you should add -# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html. - -# ############################################################################## -# # CROSS-ORIGIN RESOURCE SHARING (CORS) # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Cross-domain AJAX requests | -# ------------------------------------------------------------------------------ - -# Allow cross-origin AJAX requests. -# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity -# http://enable-cors.org/ - -# -# Header set Access-Control-Allow-Origin "*" -# - -# ------------------------------------------------------------------------------ -# | CORS-enabled images | -# ------------------------------------------------------------------------------ - -# Send the CORS header for images when browsers request it. -# https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image -# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html -# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/ - - - - - SetEnvIf Origin ":" IS_CORS - Header set Access-Control-Allow-Origin "*" env=IS_CORS - - - - -# ------------------------------------------------------------------------------ -# | Web fonts access | -# ------------------------------------------------------------------------------ - -# Allow access to web fonts from all domains. - - - - Header set Access-Control-Allow-Origin "*" - - - - -# ############################################################################## -# # ERRORS # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | 404 error prevention for non-existing redirected folders | -# ------------------------------------------------------------------------------ - -# Prevent Apache from returning a 404 error as the result of a rewrite -# when the directory with the same name does not exist. -# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews -# http://www.webmasterworld.com/apache/3808792.htm - -Options -MultiViews - -# ------------------------------------------------------------------------------ -# | Custom error messages / pages | -# ------------------------------------------------------------------------------ - -# Customize what Apache returns to the client in case of an error. -# http://httpd.apache.org/docs/current/mod/core.html#errordocument - -ErrorDocument 404 /404.html - - -# ############################################################################## -# # INTERNET EXPLORER # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Better website experience | -# ------------------------------------------------------------------------------ - -# Force Internet Explorer to render pages in the highest available mode -# in the various cases when it may not. -# http://hsivonen.iki.fi/doctype/ie-mode.pdf - - - Header set X-UA-Compatible "IE=edge" - # `mod_headers` cannot match based on the content-type, however, this - # header should be send only for HTML pages and not for the other resources - - Header unset X-UA-Compatible - - - -# ------------------------------------------------------------------------------ -# | Cookie setting from iframes | -# ------------------------------------------------------------------------------ - -# Allow cookies to be set from iframes in Internet Explorer. -# http://msdn.microsoft.com/en-us/library/ms537343.aspx -# http://www.w3.org/TR/2000/CR-P3P-20001215/ - -# -# Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" -# - -# ------------------------------------------------------------------------------ -# | Screen flicker | -# ------------------------------------------------------------------------------ - -# Stop screen flicker in Internet Explorer on CSS rollovers. - -# IMPORTANT: This will only work in combination with the image related -# `ExpiresByType` directives from below. - -# BrowserMatch "MSIE" brokenvary=1 -# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 -# BrowserMatch "Opera" !brokenvary -# SetEnvIf brokenvary 1 force-no-vary - - -# ############################################################################## -# # MIME TYPES AND ENCODING # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Proper MIME types for all files | -# ------------------------------------------------------------------------------ - - - - # Audio - AddType audio/mp4 m4a f4a f4b - AddType audio/ogg oga ogg opus - - # Data interchange - AddType application/json json map - AddType application/ld+json jsonld - - # JavaScript - # Normalize to standard type. - # http://tools.ietf.org/html/rfc4329#section-7.2 - AddType application/javascript js - - # Video - AddType video/mp4 f4v f4p m4v mp4 - AddType video/ogg ogv - AddType video/webm webm - AddType video/x-flv flv - - # Web fonts - AddType application/font-woff woff - AddType application/vnd.ms-fontobject eot - - # Browsers usually ignore the font MIME types and simply sniff the bytes - # to figure out the font type. - # http://mimesniff.spec.whatwg.org/#matching-a-font-type-pattern - - # Chrome however, shows a warning if any other MIME types are used for - # the following fonts. - - AddType application/x-font-ttf ttc ttf - AddType font/opentype otf - - # Make SVGZ fonts work on the iPad. - # https://twitter.com/FontSquirrel/status/14855840545 - AddType image/svg+xml svgz - AddEncoding gzip svgz - - # Other - AddType application/octet-stream safariextz - AddType application/x-chrome-extension crx - AddType application/x-opera-extension oex - AddType application/x-web-app-manifest+json webapp - AddType application/x-xpinstall xpi - AddType application/xml atom rdf rss xml - AddType image/webp webp - AddType image/x-icon cur - AddType text/cache-manifest appcache manifest - AddType text/vtt vtt - AddType text/x-component htc - AddType text/x-vcard vcf - - - -# ------------------------------------------------------------------------------ -# | UTF-8 encoding | -# ------------------------------------------------------------------------------ - -# Use UTF-8 encoding for anything served as `text/html` or `text/plain`. -AddDefaultCharset utf-8 - -# Force UTF-8 for certain file formats. - - AddCharset utf-8 .atom .css .js .json .jsonld .rss .vtt .webapp .xml - - - -# ############################################################################## -# # URL REWRITES # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Rewrite engine | -# ------------------------------------------------------------------------------ - -# Turn on the rewrite engine and enable the `FollowSymLinks` option (this is -# necessary in order for the following directives to work). - -# If your web host doesn't allow the `FollowSymlinks` option, you may need to -# comment it out and use `Options +SymLinksIfOwnerMatch`, but be aware of the -# performance impact. -# http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks - -# Also, some cloud hosting services require `RewriteBase` to be set. -# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site - - - Options +FollowSymlinks - # Options +SymLinksIfOwnerMatch - RewriteEngine On - # RewriteBase / - - -# ------------------------------------------------------------------------------ -# | Suppressing / Forcing the `www.` at the beginning of URLs | -# ------------------------------------------------------------------------------ - -# The same content should never be available under two different URLs, -# especially not with and without `www.` at the beginning. This can cause -# SEO problems (duplicate content), and therefore, you should choose one -# of the alternatives and redirect the other one. - -# By default `Option 1` (no `www.`) is activated. -# http://no-www.org/faq.php?q=class_b - -# If you would prefer to use `Option 2`, just comment out all the lines -# from `Option 1` and uncomment the ones from `Option 2`. - -# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME! - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Option 1: rewrite www.example.com → example.com - - - RewriteCond %{HTTPS} !=on - RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] - RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] - - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Option 2: rewrite example.com → www.example.com - -# Be aware that the following might not be a good idea if you use "real" -# subdomains for certain parts of your website. - -# -# RewriteCond %{HTTPS} !=on -# RewriteCond %{HTTP_HOST} !^www\. [NC] -# RewriteCond %{SERVER_ADDR} !=127.0.0.1 -# RewriteCond %{SERVER_ADDR} !=::1 -# RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] -# - - -# ############################################################################## -# # SECURITY # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Clickjacking | -# ------------------------------------------------------------------------------ - -# Protect website against clickjacking. - -# The example below sends the `X-Frame-Options` response header with the value -# `DENY`, informing browsers not to display the web page content in any frame. - -# This might not be the best setting for everyone. You should read about the -# other two possible values for `X-Frame-Options`: `SAMEORIGIN` & `ALLOW-FROM`. -# http://tools.ietf.org/html/rfc7034#section-2.1 - -# Keep in mind that while you could send the `X-Frame-Options` header for all -# of your site’s pages, this has the potential downside that it forbids even -# non-malicious framing of your content (e.g.: when users visit your site using -# a Google Image Search results page). - -# Nonetheless, you should ensure that you send the `X-Frame-Options` header for -# all pages that allow a user to make a state changing operation (e.g: pages -# that contain one-click purchase links, checkout or bank-transfer confirmation -# pages, pages that make permanent configuration changes, etc.). - -# Sending the `X-Frame-Options` header can also protect your website against -# more than just clickjacking attacks: https://cure53.de/xfo-clickjacking.pdf. - -# http://tools.ietf.org/html/rfc7034 -# http://blogs.msdn.com/b/ieinternals/archive/2010/03/30/combating-clickjacking-with-x-frame-options.aspx -# https://www.owasp.org/index.php/Clickjacking - -# -# Header set X-Frame-Options "DENY" -# -# Header unset X-Frame-Options -# -# - -# ------------------------------------------------------------------------------ -# | Content Security Policy (CSP) | -# ------------------------------------------------------------------------------ - -# Mitigate the risk of cross-site scripting and other content-injection attacks. - -# This can be done by setting a `Content Security Policy` which whitelists -# trusted sources of content for your website. - -# The example header below allows ONLY scripts that are loaded from the current -# site's origin (no inline scripts, no CDN, etc). This almost certainly won't -# work as-is for your site! - -# For more details on how to craft a reasonable policy for your site, read: -# http://html5rocks.com/en/tutorials/security/content-security-policy (or the -# specification: http://w3.org/TR/CSP). Also, to make things easier, you can -# use an online CSP header generator such as: http://cspisawesome.com/. - -# -# Header set Content-Security-Policy "script-src 'self'; object-src 'self'" -# -# Header unset Content-Security-Policy -# -# - -# ------------------------------------------------------------------------------ -# | File access | -# ------------------------------------------------------------------------------ - -# Block access to directories without a default document. -# You should leave the following uncommented, as you shouldn't allow anyone to -# surf through every directory on your server (which may includes rather private -# places such as the CMS's directories). - - - Options -Indexes - - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Block access to hidden files and directories. -# This includes directories used by version control systems such as Git and SVN. - - - RewriteCond %{SCRIPT_FILENAME} -d [OR] - RewriteCond %{SCRIPT_FILENAME} -f - RewriteRule "(^|/)\." - [F] - - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Block access to files that can expose sensitive information. - -# By default, block access to backup and source files that may be left by some -# text editors and can pose a security risk when anyone has access to them. -# http://feross.org/cmsploit/ - -# IMPORTANT: Update the `` regular expression from below to include -# any files that might end up on your production server and can expose sensitive -# information about your website. These files may include: configuration files, -# files that contain metadata about the project (e.g.: project dependencies), -# build scripts, etc.. - - - - # Apache < 2.3 - - Order allow,deny - Deny from all - Satisfy All - - - # Apache ≥ 2.3 - - Require all denied - - - - -# ------------------------------------------------------------------------------ -# | Reducing MIME type security risks | -# ------------------------------------------------------------------------------ - -# Prevent some browsers from MIME-sniffing the response. - -# This reduces exposure to drive-by download attacks and cross-origin data -# leaks, and should be left uncommented, especially if the web server is -# serving user-uploaded content or content that could potentially be treated -# as executable by the browser. - -# http://www.slideshare.net/hasegawayosuke/owasp-hasegawa -# http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx -# http://msdn.microsoft.com/en-us/library/ie/gg622941.aspx -# http://mimesniff.spec.whatwg.org/ - - - Header set X-Content-Type-Options "nosniff" - - -# ------------------------------------------------------------------------------ -# | Reflected Cross-Site Scripting (XSS) attacks | -# ------------------------------------------------------------------------------ - -# (1) Try to re-enable the Cross-Site Scripting (XSS) filter built into the -# most recent web browsers. -# -# The filter is usually enabled by default, but in some cases it may be -# disabled by the user. However, in Internet Explorer for example, it can -# be re-enabled just by sending the `X-XSS-Protection` header with the -# value of `1`. -# -# (2) Prevent web browsers from rendering the web page if a potential reflected -# (a.k.a non-persistent) XSS attack is detected by the filter. -# -# By default, if the filter is enabled and browsers detect a reflected -# XSS attack, they will attempt to block the attack by making the smallest -# possible modifications to the returned web page. -# -# Unfortunately, in some browsers (e.g.: Internet Explorer), this default -# behavior may allow the XSS filter to be exploited, thereby, it's better -# to tell browsers to prevent the rendering of the page altogether, instead -# of attempting to modify it. -# -# http://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities -# -# IMPORTANT: Do not rely on the XSS filter to prevent XSS attacks! Ensure that -# you are taking all possible measures to prevent XSS attacks, the most obvious -# being: validating and sanitizing your site's inputs. -# -# http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-iv-the-xss-filter.aspx -# http://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx -# https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29 - -# -# # (1) (2) -# Header set X-XSS-Protection "1; mode=block" -# -# Header unset X-XSS-Protection -# -# - -# ------------------------------------------------------------------------------ -# | Secure Sockets Layer (SSL) | -# ------------------------------------------------------------------------------ - -# Rewrite secure requests properly in order to prevent SSL certificate warnings. -# E.g.: prevent `https://www.example.com` when your certificate only allows -# `https://secure.example.com`. - -# -# RewriteCond %{SERVER_PORT} !^443 -# RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] -# - -# ------------------------------------------------------------------------------ -# | HTTP Strict Transport Security (HSTS) | -# ------------------------------------------------------------------------------ - -# Force client-side SSL redirection. - -# If a user types `example.com` in his browser, the above rule will redirect -# him to the secure version of the site. That still leaves a window of -# opportunity (the initial HTTP connection) for an attacker to downgrade or -# redirect the request. - -# The following header ensures that browser will ONLY connect to your server -# via HTTPS, regardless of what the users type in the address bar. - -# http://tools.ietf.org/html/draft-ietf-websec-strict-transport-sec-14#section-6.1 -# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/ - -# IMPORTANT: Remove the `includeSubDomains` optional directive if the subdomains -# are not using HTTPS. - -# -# Header set Strict-Transport-Security "max-age=16070400; includeSubDomains" -# - -# ------------------------------------------------------------------------------ -# | Server software information | -# ------------------------------------------------------------------------------ - -# Avoid displaying the exact Apache version number, the description of the -# generic OS-type and the information about Apache's compiled-in modules. - -# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`! - -# ServerTokens Prod - - -# ############################################################################## -# # WEB PERFORMANCE # -# ############################################################################## - -# ------------------------------------------------------------------------------ -# | Compression | -# ------------------------------------------------------------------------------ - - - - # Force compression for mangled headers. - # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping - - - SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding - RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding - - - - # Compress all output labeled with one of the following MIME-types - # (for Apache versions below 2.3.7, you don't need to enable `mod_filter` - # and can remove the `` and `` lines - # as `AddOutputFilterByType` is still in the core directives). - - AddOutputFilterByType DEFLATE application/atom+xml \ - application/javascript \ - application/json \ - application/ld+json \ - application/rss+xml \ - application/vnd.ms-fontobject \ - application/x-font-ttf \ - application/x-web-app-manifest+json \ - application/xhtml+xml \ - application/xml \ - font/opentype \ - image/svg+xml \ - image/x-icon \ - text/css \ - text/html \ - text/plain \ - text/x-component \ - text/xml - - - - -# ------------------------------------------------------------------------------ -# | Content transformations | -# ------------------------------------------------------------------------------ - -# Prevent mobile network providers from modifying the website's content. -# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5. - -# -# Header set Cache-Control "no-transform" -# - -# ------------------------------------------------------------------------------ -# | ETags | -# ------------------------------------------------------------------------------ - -# Remove `ETags` as resources are sent with far-future expires headers. -# http://developer.yahoo.com/performance/rules.html#etags. - -# `FileETag None` doesn't work in all cases. - - Header unset ETag - - -FileETag None - -# ------------------------------------------------------------------------------ -# | Expires headers | -# ------------------------------------------------------------------------------ - -# The following expires headers are set pretty far in the future. If you -# don't control versioning with filename-based cache busting, consider -# lowering the cache time for resources such as style sheets and JavaScript -# files to something like one week. - - - - ExpiresActive on - ExpiresDefault "access plus 1 month" - - # CSS - ExpiresByType text/css "access plus 1 year" - - # Data interchange - ExpiresByType application/json "access plus 0 seconds" - ExpiresByType application/ld+json "access plus 0 seconds" - ExpiresByType application/xml "access plus 0 seconds" - ExpiresByType text/xml "access plus 0 seconds" - - # Favicon (cannot be renamed!) and cursor images - ExpiresByType image/x-icon "access plus 1 week" - - # HTML components (HTCs) - ExpiresByType text/x-component "access plus 1 month" - - # HTML - ExpiresByType text/html "access plus 0 seconds" - - # JavaScript - ExpiresByType application/javascript "access plus 1 year" - - # Manifest files - ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" - ExpiresByType text/cache-manifest "access plus 0 seconds" - - # Media - ExpiresByType audio/ogg "access plus 1 month" - ExpiresByType image/gif "access plus 1 month" - ExpiresByType image/jpeg "access plus 1 month" - ExpiresByType image/png "access plus 1 month" - ExpiresByType video/mp4 "access plus 1 month" - ExpiresByType video/ogg "access plus 1 month" - ExpiresByType video/webm "access plus 1 month" - - # Web feeds - ExpiresByType application/atom+xml "access plus 1 hour" - ExpiresByType application/rss+xml "access plus 1 hour" - - # Web fonts - ExpiresByType application/font-woff "access plus 1 month" - ExpiresByType application/vnd.ms-fontobject "access plus 1 month" - ExpiresByType application/x-font-ttf "access plus 1 month" - ExpiresByType font/opentype "access plus 1 month" - ExpiresByType image/svg+xml "access plus 1 month" - - - -# ------------------------------------------------------------------------------ -# | Filename-based cache busting | -# ------------------------------------------------------------------------------ - -# If you're not using a build process to manage your filename version revving, -# you might want to consider enabling the following directives to route all -# requests such as `/css/style.12345.css` to `/css/style.css`. - -# To understand why this is important and a better idea than `*.css?v231`, read: -# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring - -# -# RewriteCond %{REQUEST_FILENAME} !-f -# RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpe?g|gif)$ $1.$3 [L] -# - -# ------------------------------------------------------------------------------ -# | File concatenation | -# ------------------------------------------------------------------------------ - -# Allow concatenation from within specific style sheets and JavaScript files. - -# e.g.: -# -# If you have the following content in a file -# -# -# -# -# Apache will replace it with the content from the specified files. - -# -# -# Options +Includes -# AddOutputFilterByType INCLUDES application/javascript application/json -# SetOutputFilter INCLUDES -# -# -# Options +Includes -# AddOutputFilterByType INCLUDES text/css -# SetOutputFilter INCLUDES -# -# diff --git a/middleman-cli/lib/middleman-templates/html5/source/404.html b/middleman-cli/lib/middleman-templates/html5/source/404.html deleted file mode 100644 index 190accc5..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/404.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - Page Not Found - - - - -

Page Not Found

-

Sorry, but the page you were trying to view does not exist.

- - - diff --git a/middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md b/middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md deleted file mode 100644 index 609abef6..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/CHANGELOG.md +++ /dev/null @@ -1,197 +0,0 @@ -### HEAD - -* Update to Apache Server Configs 2.3.0. -* Use `` instead of `` - ([#1522](https://github.com/h5bp/html5-boilerplate/issues/1522)). -* Update to jQuery 1.11.0. -* Add `Disallow:` to `robots.txt` - ([#1487](https://github.com/h5bp/html5-boilerplate/issues/1487)). -* Remove default foreground color from form elements - ([#1390](https://github.com/h5bp/html5-boilerplate/issues/1390)). -* Remove default margin from print styles - ([#1477](https://github.com/h5bp/html5-boilerplate/issues/1477)). -* Update to Modernizr 2.7.1. -* Add vertical centering for `svg` - ([#1453](https://github.com/h5bp/html5-boilerplate/issues/1453)). -* Redesign 404 page - ([#1443](https://github.com/h5bp/html5-boilerplate/pull/1443)). - -### 4.3.0 (September 10, 2013) - -* Use one apple-touch-icon instead of six - ([#1367](https://github.com/h5bp/html5-boilerplate/issues/1367)). -* Move font-related declarations from `body` to `html` - ([#1411](https://github.com/h5bp/html5-boilerplate/issues/1411)). -* Update to Apache Server Configs 1.1.0. -* Add `initial-scale=1` to the viewport `meta` - ([#1398](https://github.com/h5bp/html5-boilerplate/pull/1398)). -* Vertical centering for audio-, canvas- and video-tags - ([#1326](https://github.com/h5bp/html5-boilerplate/issues/1326)). -* Remove Google Chrome Frame related code - ([#1379](https://github.com/h5bp/html5-boilerplate/pull/1379), - [#1396](https://github.com/h5bp/html5-boilerplate/pull/1396)). -* Update to Google Universal Analytics - ([#1347](https://github.com/h5bp/html5-boilerplate/issues/1347)). -* Update to jQuery 1.10.2. -* Update to Normalize.css 1.1.3. - -### 4.2.0 (April 8, 2013) - -* Remove Google Analytics protocol check - ([#1319](https://github.com/h5bp/html5-boilerplate/pull/1319)). -* Update to Normalize.css 1.1.1. -* Update Apache configurations to include the latest changes in the - canonical [`.htaccess`](https://github.com/h5bp/server-configs-apache) - file. -* Use a protocol relative URL for the 404 template script. -* Update to jQuery 1.9.1. - -### 4.1.0 (January 21, 2013) - -* Update to Normalize.css 1.1.0. -* Update to jQuery 1.9.0. - -### 4.0.3 (January 12, 2013) - -* Use 32x32 favicon.ico - ([#1286](https://github.com/h5bp/html5-boilerplate/pull/1286)). -* Remove named function expression in plugins.js - ([#1280](https://github.com/h5bp/html5-boilerplate/pull/1280)). -* Adjust CSS image-replacement code - ([#1239](https://github.com/h5bp/html5-boilerplate/issues/1239)). -* Update HiDPI example media query - ([#1127](https://github.com/h5bp/html5-boilerplate/issues/1127)). - -### 4.0.2 (December 9, 2012) - -* Update placeholder icons. -* Update to Normalize.css 1.0.2. -* Update to jQuery 1.8.3. - -### 4.0.1 (October 20, 2012) - -* Further improvements to `console` method stubbing - ([#1206](https://github.com/h5bp/html5-boilerplate/issues/1206), - [#1229](https://github.com/h5bp/html5-boilerplate/pull/1229)). -* Update to jQuery 1.8.2. -* Update to Modernizr 2.6.2. -* Minor additions to the documentation. - -### 4.0.0 (August 28, 2012) - -* Improve the Apache compression configuration - ([#1012](https://github.com/h5bp/html5-boilerplate/issues/1012), - [#1173](https://github.com/h5bp/html5-boilerplate/issues/1173)). -* Add a HiDPI example media query - ([#1127](https://github.com/h5bp/html5-boilerplate/issues/1127)). -* Add bundled docs - ([#1154](https://github.com/h5bp/html5-boilerplate/issues/1154)). -* Add MIT license - ([#1139](https://github.com/h5bp/html5-boilerplate/issues/1139)). -* Update to Normalize.css 1.0.1. -* Separate Normalize.css from the rest of the CSS - ([#1160](https://github.com/h5bp/html5-boilerplate/issues/1160)). -* Improve `console.log` protection - ([#1107](https://github.com/h5bp/html5-boilerplate/issues/1107)). -* Replace hot pink text selection color with a neutral color. -* Change image replacement technique - ([#1149](https://github.com/h5bp/html5-boilerplate/issues/1149)). -* Code format and consistency changes - ([#1112](https://github.com/h5bp/html5-boilerplate/issues/1112)). -* Rename CSS file and rename JS files and subdirectories. -* Update to jQuery 1.8 - ([#1161](https://github.com/h5bp/html5-boilerplate/issues/1161)). -* Update to Modernizr 2.6.1 - ([#1086](https://github.com/h5bp/html5-boilerplate/issues/1086)). -* Remove uncompressed jQuery - ([#1153](https://github.com/h5bp/html5-boilerplate/issues/1153)). -* Remove superfluous inline comments - ([#1150](https://github.com/h5bp/html5-boilerplate/issues/1150)). - -### 3.0.2 (February 19, 2012) - -* Update to Modernizr 2.5.3. - -### 3.0.1 (February 08, 2012). - -* Update to Modernizr 2.5.2 (includes html5shiv 3.3). - -### 3.0.0 (February 06, 2012) - -* Improvements to `.htaccess`. -* Improve 404 design. -* Simplify JS folder structure. -* Change `html` IE class names changed to target ranges rather than - specific versions of IE. -* Update CSS to include latest normalize.css changes and better - typographic defaults - ([#825](https://github.com/h5bp/html5-boilerplate/issues/825)). -* Update to Modernizr 2.5 (includes yepnope 1.5 and html5shiv 3.2). -* Update to jQuery 1.7.1. -* Revert to async snippet for the Google Analytics script. -* Remove the ant build script - ([#826](https://github.com/h5bp/html5-boilerplate/issues/826)). -* Remove Respond.js - ([#816](https://github.com/h5bp/html5-boilerplate/issues/816)). -* Remove the `demo/` directory - ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). -* Remove the `test/` directory - ([#808](https://github.com/h5bp/html5-boilerplate/issues/808)). -* Remove Google Chrome Frame script for IE6 users; replace with links - to Chrome Frame and options for alternative browsers. -* Remove `initial-scale=1` from the viewport `meta` - ([#824](https://github.com/h5bp/html5-boilerplate/issues/824)). -* Remove `defer` from all scripts to avoid legacy IE bugs. -* Remove explicit Site Speed tracking for Google Analytics. It's now - enabled by default. - -### 2.0.0 (August 10, 2011) - -* Change starting CSS to be based on normalize.css instead of reset.css - ([#500](https://github.com/h5bp/html5-boilerplate/issues/500)). -* Add Respond.js media query polyfill. -* Add Google Chrome Frame script prompt for IE6 users. -* Simplify the `html` conditional comments for modern browsers and add - an `oldie` class. -* Update clearfix to use "micro clearfix". -* Add placeholder CSS MQs for mobile-first approach. -* Add `textarea { resize: vertical; }` to only allow vertical resizing. -* Add `img { max-width: 100%; }` to the print styles; prevents images - being truncated. -* Add Site Speed tracking for Google Analytics. -* Update to jQuery 1.6.2 (and use minified by default). -* Update to Modernizr 2.0 Complete, Production minified (includes - yepnope, html5shiv, and Respond.js). -* Use `Modernizr.load()` to load the Google Analytics script. -* Much faster build process. -* Add build script options for CSSLint, JSLint, JSHint tools. -* Build script now compresses all images in subfolders. -* Build script now versions files by SHA hash. -* Many `.htaccess` improvements including: disable directory browsing, - improved support for all versions of Apache, more robust and extensive - HTTP compression rules. -* Remove `handheld.css` as it has very poor device support. -* Remove touch-icon `link` elements from the HTML and include improved - touch-icon support. -* Remove the cache-busting query paramaters from files references in - the HTML. -* Remove IE6 PNGFix. - -### 1.0.0 (March 21, 2011) - -* Rewrite build script to make it more customizable and flexible. -* Add a humans.txt. -* Numerous `.htaccess` improvements (including inline documentation). -* Move the alternative server configurations to the H5BP server configs - repo. -* Use a protocol-relative url to reference jQuery and prevent mixed - content warnings. -* Optimize the Google Analytics snippet. -* Use Eric Meyer's recent CSS reset update and the HTML5 Doctor reset. -* More robust `sub`/`sup` CSS styles. -* Add keyboard `.focusable` helper class that extends `.visuallyhidden`. -* Print styles no longer print hash or JavaScript links. -* Add a print reset for IE's proprietary filters. -* Remove IE9-specific conditional class on the `html` element. -* Remove margins from lists within `nav` elements. -* Remove YUI profiling. diff --git a/middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md b/middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md deleted file mode 100644 index 89c63e1d..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/CONTRIBUTING.md +++ /dev/null @@ -1,154 +0,0 @@ -# Contributing to HTML5 Boilerplate - -♥ [HTML5 Boilerplate](http://html5boilerplate.com) and want to get involved? -Thanks! There are plenty of ways you can help! - -Please take a moment to review this document in order to make the contribution -process easy and effective for everyone involved. - -Following these guidelines helps to communicate that you respect the time of -the developers managing and developing this open source project. In return, -they should reciprocate that respect in addressing your issue or assessing -patches and features. - - -## Using the issue tracker - -The [issue tracker](https://github.com/h5bp/html5-boilerplate/issues) is -the preferred channel for [bug reports](#bugs), [features requests](#features) -and [submitting pull requests](#pull-requests), but please respect the following -restrictions: - -* Please **do not** use the issue tracker for personal support requests (use - [Stack Overflow](http://stackoverflow.com/questions/tagged/html5boilerplate) - or IRC). - -* Please **do not** derail or troll issues. Keep the discussion on topic and - respect the opinions of others. - -* Please **do not** open issues or pull requests regarding the code in - [`.htaccess`](https://github.com/h5bp/server-configs-apache), - [`jQuery`](https://github.com/jquery/jquery/), - [`Modernizr`](https://github.com/Modernizr/Modernizr) or - [`Normalize.css`](https://github.com/necolas/normalize.css) (open them in - their respective repositories). - - - -## Bug reports - -A bug is a _demonstrable problem_ that is caused by the code in the repository. -Good bug reports are extremely helpful - thank you! - -Guidelines for bug reports: - -1. **Use the GitHub issue search** — check if the issue has already been - reported. - -2. **Check if the issue has been fixed** — try to reproduce it using the - latest `master` or development branch in the repository. - -3. **Isolate the problem** — ideally create a [reduced test - case](http://css-tricks.com/6263-reduced-test-cases/) and a live example. - -A good bug report shouldn't leave others needing to chase you up for more -information. Please try to be as detailed as possible in your report. What is -your environment? What steps will reproduce the issue? What browser(s) and OS -experience the problem? What would you expect to be the outcome? All these -details will help people to fix any potential bugs. - -Example: - -> Short and descriptive example bug report title -> -> A summary of the issue and the browser/OS environment in which it occurs. If -> suitable, include the steps required to reproduce the bug. -> -> 1. This is the first step -> 2. This is the second step -> 3. Further steps, etc. -> -> `` - a link to the reduced test case -> -> Any other information you want to share that is relevant to the issue being -> reported. This might include the lines of code that you have identified as -> causing the bug, and potential solutions (and your opinions on their -> merits). - - - -## Feature requests - -Feature requests are welcome. But take a moment to find out whether your idea -fits with the scope and aims of the project. It's up to *you* to make a strong -case to convince the project's developers of the merits of this feature. Please -provide as much detail and context as possible. - - - -## Pull requests - -Good pull requests - patches, improvements, new features - are a fantastic -help. They should remain focused in scope and avoid containing unrelated -commits. - -**Please ask first** before embarking on any significant pull request (e.g. -implementing features, refactoring code, porting to a different language), -otherwise you risk spending a lot of time working on something that the -project's developers might not want to merge into the project. - -Please adhere to the coding conventions used throughout a project (indentation, -accurate comments, etc.) and any other requirements (such as test coverage). - -Adhering to the following this process is the best way to get your work -included in the project: - -1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, - and configure the remotes: - - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com//html5-boilerplate.git - # Navigate to the newly cloned directory - cd html5-boilerplate - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/h5bp/html5-boilerplate.git - ``` - -2. If you cloned a while ago, get the latest changes from upstream: - - ```bash - git checkout master - git pull upstream master - ``` - -3. Create a new topic branch (off the main project development branch) to - contain your feature, change, or fix: - - ```bash - git checkout -b - ``` - -4. Commit your changes in logical chunks. Please adhere to these [git commit - message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - or your code is unlikely be merged into the main project. Use Git's - [interactive rebase](https://help.github.com/articles/interactive-rebase) - feature to tidy up your commits before making them public. - -5. Locally merge (or rebase) the upstream development branch into your topic branch: - - ```bash - git pull [--rebase] upstream master - ``` - -6. Push your topic branch up to your fork: - - ```bash - git push origin - ``` - -7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) - with a clear title and description. - -**IMPORTANT**: By submitting a patch, you agree to allow the project owners to -license your work under the the terms of the [MIT License](LICENSE.md). diff --git a/middleman-cli/lib/middleman-templates/html5/source/LICENSE.md b/middleman-cli/lib/middleman-templates/html5/source/LICENSE.md deleted file mode 100644 index 294e91d8..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/LICENSE.md +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) HTML5 Boilerplate - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/middleman-cli/lib/middleman-templates/html5/source/README.md b/middleman-cli/lib/middleman-templates/html5/source/README.md deleted file mode 100644 index 864900b1..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# [HTML5 Boilerplate](http://html5boilerplate.com) - -HTML5 Boilerplate is a professional front-end template for building fast, -robust, and adaptable web apps or sites. - -This project is the product of many years of iterative development and combined -community knowledge. It does not impose a specific development philosophy or -framework, so you're free to architect your code in the way that you want. - -* Source: [https://github.com/h5bp/html5-boilerplate](https://github.com/h5bp/html5-boilerplate) -* Homepage: [http://html5boilerplate.com](http://html5boilerplate.com) -* Twitter: [@h5bp](http://twitter.com/h5bp) - - -## Quick start - -Choose one of the following options: - -1. Download the latest stable release from - [html5boilerplate.com](http://html5boilerplate.com/) or a custom build from - [Initializr](http://www.initializr.com). -2. Clone the git repo — `git clone - https://github.com/h5bp/html5-boilerplate.git` - and checkout the [tagged - release](https://github.com/h5bp/html5-boilerplate/releases) you'd like to - use. - - -## Features - -* HTML5 ready. Use the new elements with confidence. -* Cross-browser compatible (Chrome, Opera, Safari, Firefox 3.6+, IE6+). -* Designed with progressive enhancement in mind. -* Includes [Normalize.css](http://necolas.github.com/normalize.css/) for CSS - normalizations and common bug fixes. -* The latest [jQuery](http://jquery.com/) via CDN, with a local fallback. -* The latest [Modernizr](http://modernizr.com/) build for feature detection. -* IE-specific classes for easier cross-browser control. -* Placeholder CSS Media Queries. -* Useful CSS helpers. -* Default print CSS, performance optimized. -* Protection against any stray `console.log` causing JavaScript errors in - IE6/7. -* An optimized Google Analytics snippet. -* Apache server caching, compression, and other configuration defaults for - Grade-A performance. -* Cross-domain Ajax and Flash. -* "Delete-key friendly." Easy to strip out parts you don't need. -* Extensive inline and accompanying documentation. - - -## Documentation - -Take a look at the [documentation table of contents](doc/TOC.md). This -documentation is bundled with the project, which makes it readily available for -offline reading and provides a useful starting point for any documentation you -want to write about your project. - - -## Contributing - -Anyone and everyone is welcome to [contribute](CONTRIBUTING.md). Hundreds of -developers have helped make the HTML5 Boilerplate what it is today. diff --git a/middleman-cli/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png b/middleman-cli/lib/middleman-templates/html5/source/apple-touch-icon-precomposed.png deleted file mode 100644 index bee3e36990af10c2d29839145f2e27f50b7ef25f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1076 zcmeAS@N?(olHy`uVBq!ia0y~yV3+~I9Lx+14Eiz`gc%qZbOU@sTon}+RW-H5q!n^J zl)TLq-O>vTJOg(ZDbGw$vI&bZ(o%fTrmSb@tZ8iax?8y=D{cV;1M?wI7srr_TW@FH zE?aECFiL^Ys!>^#@Kz8rw`+7;he#X7-FdnfNQlw9ny zXVE6Vnq3l$E#d-hILRI;{-Y)#vaKw6llSyI?K6Szo=iOWG^Nx|1!9F zJ%a0_;LP70M)QcpY8HnKip07pSt(-pI*}qA_X#BQ|HdmiCxC$lcW=S z@827he}|q19y5sS-&C^G^FfDR8RumF6E&Gr5^uiO0bAL8(&*HuqT?5qKZre`(r|ii z0Qcn2y9+k<-RImYu;-2PwTZDiW}cXF?XAE3d7re%Ntqob>VcA-#=^P(l{>#ZcHOBb zKEo&K-y~n>s#Vj>1oQj3mzFLNmb$Omn<=z(myL>!?btitb|WRZEjEg|Fk+PJUO#2=GR0s(TAlq>7N&^`goyE|CiMH z>zZ0pAKw)wOwG8sV!g1`%LccpoUFaM50}bkUbyjZM~M2AobJDk>%wOR6vr<9m%88_ zWACYrf>%tL@?IFtyb-Z_m0-)ZYybECHp#vs&){)UpH7LvO) z9iMkL+f0$#ew>x(oYU8(K6jV=`0zP_f37-z(YK&F509sFm)LNhT=Gh&Pj1&f1@Vb$ zeIzopr0EPSwN&o-= diff --git a/middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml b/middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml deleted file mode 100644 index 29a035d7..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/crossdomain.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - diff --git a/middleman-cli/lib/middleman-templates/html5/source/css/main.css b/middleman-cli/lib/middleman-templates/html5/source/css/main.css deleted file mode 100644 index 6ac6721c..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/css/main.css +++ /dev/null @@ -1,294 +0,0 @@ -/*! HTML5 Boilerplate v4.3.0 | MIT License | http://h5bp.com/ */ - -/* - * What follows is the result of much research on cross-browser styling. - * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, - * Kroc Camen, and the H5BP dev community and team. - */ - -/* ========================================================================== - Base styles: opinionated defaults - ========================================================================== */ - -html { - color: #222; - font-size: 1em; - line-height: 1.4; -} - -/* - * Remove text-shadow in selection highlight: h5bp.com/i - * These selection rule sets have to be separate. - * Customize the background color to match your design. - */ - -::-moz-selection { - background: #b3d4fc; - text-shadow: none; -} - -::selection { - background: #b3d4fc; - text-shadow: none; -} - -/* - * A better looking default horizontal rule - */ - -hr { - display: block; - height: 1px; - border: 0; - border-top: 1px solid #ccc; - margin: 1em 0; - padding: 0; -} - -/* - * Remove the gap between images, videos, audio and canvas and the bottom of - * their containers: h5bp.com/i/440 - */ - -audio, -canvas, -img, -svg, -video { - vertical-align: middle; -} - -/* - * Remove default fieldset styles. - */ - -fieldset { - border: 0; - margin: 0; - padding: 0; -} - -/* - * Allow only vertical resizing of textareas. - */ - -textarea { - resize: vertical; -} - -/* ========================================================================== - Browse Happy prompt - ========================================================================== */ - -.browsehappy { - margin: 0.2em 0; - background: #ccc; - color: #000; - padding: 0.2em 0; -} - -/* ========================================================================== - Author's custom styles - ========================================================================== */ - - - - - - - - - - - - - - - - - -/* ========================================================================== - Helper classes - ========================================================================== */ - -/* - * Image replacement - */ - -.ir { - background-color: transparent; - border: 0; - overflow: hidden; - /* IE 6/7 fallback */ - *text-indent: -9999px; -} - -.ir:before { - content: ""; - display: block; - width: 0; - height: 150%; -} - -/* - * Hide from both screenreaders and browsers: h5bp.com/u - */ - -.hidden { - display: none !important; - visibility: hidden; -} - -/* - * Hide only visually, but have it available for screenreaders: h5bp.com/v - */ - -.visuallyhidden { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; -} - -/* - * Extends the .visuallyhidden class to allow the element to be focusable - * when navigated to via the keyboard: h5bp.com/p - */ - -.visuallyhidden.focusable:active, -.visuallyhidden.focusable:focus { - clip: auto; - height: auto; - margin: 0; - overflow: visible; - position: static; - width: auto; -} - -/* - * Hide visually and from screenreaders, but maintain layout - */ - -.invisible { - visibility: hidden; -} - -/* - * Clearfix: contain floats - * - * For modern browsers - * 1. The space content is one way to avoid an Opera bug when the - * `contenteditable` attribute is included anywhere else in the document. - * Otherwise it causes space to appear at the top and bottom of elements - * that receive the `clearfix` class. - * 2. The use of `table` rather than `block` is only necessary if using - * `:before` to contain the top-margins of child elements. - */ - -.clearfix:before, -.clearfix:after { - content: " "; /* 1 */ - display: table; /* 2 */ -} - -.clearfix:after { - clear: both; -} - -/* - * For IE 6/7 only - * Include this rule to trigger hasLayout and contain floats. - */ - -.clearfix { - *zoom: 1; -} - -/* ========================================================================== - EXAMPLE Media Queries for Responsive Design. - These examples override the primary ('mobile first') styles. - Modify as content requires. - ========================================================================== */ - -@media only screen and (min-width: 35em) { - /* Style adjustments for viewports that meet the condition */ -} - -@media print, - (-o-min-device-pixel-ratio: 5/4), - (-webkit-min-device-pixel-ratio: 1.25), - (min-resolution: 120dpi) { - /* Style adjustments for high resolution devices */ -} - -/* ========================================================================== - Print styles. - Inlined to avoid required HTTP connection: h5bp.com/r - ========================================================================== */ - -@media print { - * { - background: transparent !important; - color: #000 !important; /* Black prints faster: h5bp.com/s */ - box-shadow: none !important; - text-shadow: none !important; - } - - a, - a:visited { - text-decoration: underline; - } - - a[href]:after { - content: " (" attr(href) ")"; - } - - abbr[title]:after { - content: " (" attr(title) ")"; - } - - /* - * Don't show links for images, or javascript/internal links - */ - - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - - thead { - display: table-header-group; /* h5bp.com/t */ - } - - tr, - img { - page-break-inside: avoid; - } - - img { - max-width: 100% !important; - } - - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - - h2, - h3 { - page-break-after: avoid; - } -} diff --git a/middleman-cli/lib/middleman-templates/html5/source/css/normalize.css b/middleman-cli/lib/middleman-templates/html5/source/css/normalize.css deleted file mode 100644 index 42e24d68..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/css/normalize.css +++ /dev/null @@ -1,527 +0,0 @@ -/*! normalize.css v1.1.3 | MIT License | git.io/normalize */ - -/* ========================================================================== - HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -/** - * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. - */ - -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. - * Known issue: no IE 6 support. - */ - -[hidden] { - display: none; -} - -/* ========================================================================== - Base - ========================================================================== */ - -/** - * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using - * `em` units. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-size: 100%; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Address `font-family` inconsistency between `textarea` and other form - * elements. - */ - -html, -button, -input, -select, -textarea { - font-family: sans-serif; -} - -/** - * Address margins handled incorrectly in IE 6/7. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/** - * Address `outline` inconsistency between Chrome and other browsers. - */ - -a:focus { - outline: thin dotted; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* ========================================================================== - Typography - ========================================================================== */ - -/** - * Address font sizes and margins set differently in IE 6/7. - * Address font sizes within `section` and `article` in Firefox 4+, Safari 5, - * and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -h2 { - font-size: 1.5em; - margin: 0.83em 0; -} - -h3 { - font-size: 1.17em; - margin: 1em 0; -} - -h4 { - font-size: 1em; - margin: 1.33em 0; -} - -h5 { - font-size: 0.83em; - margin: 1.67em 0; -} - -h6 { - font-size: 0.67em; - margin: 2.33em 0; -} - -/** - * Address styling not present in IE 7/8/9, Safari 5, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -blockquote { - margin: 1em 40px; -} - -/** - * Address styling not present in Safari 5 and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address differences between Firefox and other browsers. - * Known issue: no IE 6/7 normalization. - */ - -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -/** - * Address styling not present in IE 6/7/8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address margins set differently in IE 6/7. - */ - -p, -pre { - margin: 1em 0; -} - -/** - * Correct font family set oddly in IE 6, Safari 4/5, and Chrome. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - _font-family: 'courier new', monospace; - font-size: 1em; -} - -/** - * Improve readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/** - * Address CSS quotes not supported in IE 6/7. - */ - -q { - quotes: none; -} - -/** - * Address `quotes` property not supported in Safari 4. - */ - -q:before, -q:after { - content: ''; - content: none; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* ========================================================================== - Lists - ========================================================================== */ - -/** - * Address margins set differently in IE 6/7. - */ - -dl, -menu, -ol, -ul { - margin: 1em 0; -} - -dd { - margin: 0 0 0 40px; -} - -/** - * Address paddings set differently in IE 6/7. - */ - -menu, -ol, -ul { - padding: 0 0 0 40px; -} - -/** - * Correct list images handled incorrectly in IE 7. - */ - -nav ul, -nav ol { - list-style: none; - list-style-image: none; -} - -/* ========================================================================== - Embedded content - ========================================================================== */ - -/** - * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. - * 2. Improve image quality when scaled in IE 7. - */ - -img { - border: 0; /* 1 */ - -ms-interpolation-mode: bicubic; /* 2 */ -} - -/** - * Correct overflow displayed oddly in IE 9. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* ========================================================================== - Figures - ========================================================================== */ - -/** - * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. - */ - -figure { - margin: 0; -} - -/* ========================================================================== - Forms - ========================================================================== */ - -/** - * Correct margin displayed oddly in IE 6/7. - */ - -form { - margin: 0; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct color not being inherited in IE 6/7/8/9. - * 2. Correct text not wrapping in Firefox 3. - * 3. Correct alignment displayed oddly in IE 6/7. - */ - -legend { - border: 0; /* 1 */ - padding: 0; - white-space: normal; /* 2 */ - *margin-left: -7px; /* 3 */ -} - -/** - * 1. Correct font size not being inherited in all browsers. - * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, - * and Chrome. - * 3. Improve appearance and consistency in all browsers. - */ - -button, -input, -select, -textarea { - font-size: 100%; /* 1 */ - margin: 0; /* 2 */ - vertical-align: baseline; /* 3 */ - *vertical-align: middle; /* 3 */ -} - -/** - * Address Firefox 3+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -button, -input { - line-height: normal; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. - * Correct `select` style inheritance in Firefox 4+ and Opera. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - * 4. Remove inner spacing in IE 7 without affecting normal text inputs. - * Known issue: inner spacing remains in IE 6. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ - *overflow: visible; /* 4 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * 1. Address box sizing set to content-box in IE 8/9. - * 2. Remove excess padding in IE 8/9. - * 3. Remove excess padding in IE 7. - * Known issue: excess padding remains in IE 6. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ - *height: 13px; /* 3 */ - *width: 13px; /* 3 */ -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Remove inner padding and border in Firefox 3+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * 1. Remove default vertical scrollbar in IE 6/7/8/9. - * 2. Improve readability and alignment in all browsers. - */ - -textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ -} - -/* ========================================================================== - Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/middleman-cli/lib/middleman-templates/html5/source/favicon.ico b/middleman-cli/lib/middleman-templates/html5/source/favicon.ico deleted file mode 100644 index be74abd69ad6a32de7375df13cab9354798e328f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 766 zcmZQzU}RuqP*4zHU}Runc)`TLAjZJJpuxbvpuoVu;J^TqXJNnvB%~D>6crR0_!JBo zST#Kv7)?_d7+hN!7y@Q6FoZ2*U`X7_z?y!Tfg|Sx18?CO2I2B646=>4;l>FP2F_3= z0w!RFK!gF97Gzlhp|!Ruf*4FWMIcI0ko9!3prD|D#qK}|Uu5+TCqY4#)jJ&_e4(yY zTNQ6BHDPS+%CwV%Msz5NSa{>s70Ety;Bm3XHF@Yt^b%t5!pe7ZhYY1>&!P z8ZRg)43=MM2vskj29jR2DhSGFnFHaUZ~_Z3<$$%XTD1o3ZUN6*5b0H`_O>tz3aFid zaaXN66C|j57X)^#TD2NP-w85L4Gj$q?OwI&1c(kR7GwnZHFnkNt6&D$20=mV-FqfO znP7_J_FlN_K?1C|_rhHd;tQWS1#>-!D=5%=9U3@buAo5dRR{w{+HQuiAT(DKgocq~ Ug)kO`7Dh21A_gYm31NU30N^@`#sB~S diff --git a/middleman-cli/lib/middleman-templates/html5/source/humans.txt b/middleman-cli/lib/middleman-templates/html5/source/humans.txt deleted file mode 100644 index d9e1bb98..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/humans.txt +++ /dev/null @@ -1,15 +0,0 @@ -# humanstxt.org/ -# The humans responsible & technology colophon - -# TEAM - - -- -- - -# THANKS - - - -# TECHNOLOGY COLOPHON - - HTML5, CSS3 - Normalize.css, jQuery, Modernizr diff --git a/middleman-cli/lib/middleman-templates/html5/source/img/.gitignore b/middleman-cli/lib/middleman-templates/html5/source/img/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/middleman-cli/lib/middleman-templates/html5/source/index.html.erb b/middleman-cli/lib/middleman-templates/html5/source/index.html.erb deleted file mode 100644 index 9af2d2d5..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/index.html.erb +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: HTML5 Boilerplate Middleman ---- - - -

Hello world! This is HTML5 Boilerplate.

diff --git a/middleman-cli/lib/middleman-templates/html5/source/js/main.js b/middleman-cli/lib/middleman-templates/html5/source/js/main.js deleted file mode 100644 index 8b137891..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/js/main.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/middleman-cli/lib/middleman-templates/html5/source/js/plugins.js b/middleman-cli/lib/middleman-templates/html5/source/js/plugins.js deleted file mode 100644 index 728680b0..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/js/plugins.js +++ /dev/null @@ -1,24 +0,0 @@ -// Avoid `console` errors in browsers that lack a console. -(function() { - var method; - var noop = function () {}; - var methods = [ - 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', - 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', - 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', - 'timeStamp', 'trace', 'warn' - ]; - var length = methods.length; - var console = (window.console = window.console || {}); - - while (length--) { - method = methods[length]; - - // Only stub undefined methods. - if (!console[method]) { - console[method] = noop; - } - } -}()); - -// Place any jQuery/helper plugins in here. diff --git a/middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js b/middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js deleted file mode 100644 index 73f33fb3..00000000 --- a/middleman-cli/lib/middleman-templates/html5/source/js/vendor/jquery-1.11.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f -}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("