middleman 3.0.0.alpha.2 → 3.0.0.alpha.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gitignore +2 -0
  2. data/.yardopts +5 -0
  3. data/CHANGELOG +5 -0
  4. data/README.md +3 -0
  5. data/Rakefile +0 -2
  6. data/bin/middleman +36 -33
  7. data/features/auto_layout.feature +37 -0
  8. data/features/builder.feature +1 -0
  9. data/features/chained_templates.feature +15 -0
  10. data/features/content_for.feature +16 -0
  11. data/features/directory_index.feature +1 -0
  12. data/features/front-matter.feature +2 -1
  13. data/features/partials.feature +35 -0
  14. data/features/support/env.rb +3 -3
  15. data/fixtures/chained-app/config.rb +0 -0
  16. data/fixtures/chained-app/data/article.yml +2 -0
  17. data/fixtures/chained-app/source/index.html.markdown.erb +8 -0
  18. data/fixtures/different-engine-layout/config.rb +0 -0
  19. data/fixtures/different-engine-layout/source/index.html.haml +1 -0
  20. data/fixtures/different-engine-layout/source/layout.erb +9 -0
  21. data/fixtures/engine-matching-layout/config.rb +0 -0
  22. data/fixtures/engine-matching-layout/source/index.html.erb +1 -0
  23. data/fixtures/engine-matching-layout/source/layout.erb +9 -0
  24. data/fixtures/indexable-app/source/.htaccess +1 -0
  25. data/fixtures/manual-layout-missing/config.rb +1 -0
  26. data/fixtures/manual-layout-missing/source/index.html.erb +1 -0
  27. data/fixtures/manual-layout-override/config.rb +3 -0
  28. data/fixtures/manual-layout-override/source/index.html.erb +1 -0
  29. data/fixtures/manual-layout-override/source/layouts/another.erb +9 -0
  30. data/fixtures/manual-layout-override/source/layouts/custom.erb +9 -0
  31. data/fixtures/manual-layout/config.rb +1 -0
  32. data/fixtures/manual-layout/source/index.html.erb +1 -0
  33. data/fixtures/manual-layout/source/layouts/custom.erb +9 -0
  34. data/fixtures/multiple-layouts/config.rb +0 -0
  35. data/fixtures/multiple-layouts/source/index.html.erb +1 -0
  36. data/fixtures/multiple-layouts/source/layout.erb +9 -0
  37. data/fixtures/multiple-layouts/source/layout.haml +6 -0
  38. data/fixtures/no-layout/config.rb +0 -0
  39. data/fixtures/no-layout/source/index.html.erb +1 -0
  40. data/fixtures/partials-app/config.rb +0 -0
  41. data/fixtures/partials-app/source/_locals.erb +1 -0
  42. data/fixtures/partials-app/source/_main.erb +1 -0
  43. data/fixtures/partials-app/source/_main.haml +1 -0
  44. data/fixtures/partials-app/source/index.html.erb +3 -0
  45. data/fixtures/partials-app/source/locals.html.erb +1 -0
  46. data/fixtures/partials-app/source/second.html.haml +3 -0
  47. data/fixtures/partials-app/source/shared/_footer.erb +1 -0
  48. data/fixtures/partials-app/source/shared/_header.erb +1 -0
  49. data/fixtures/partials-app/source/sub/_local.erb +1 -0
  50. data/fixtures/partials-app/source/sub/index.html.erb +3 -0
  51. data/fixtures/test-app/config.rb +6 -0
  52. data/fixtures/test-app/source/.htaccess +1 -0
  53. data/fixtures/test-app/source/content_for_erb.html.erb +5 -0
  54. data/fixtures/test-app/source/content_for_haml.html.haml +4 -0
  55. data/fixtures/test-app/source/content_for_slim.html.slim +4 -0
  56. data/fixtures/test-app/source/images/Chrome_Logo.svg +231 -0
  57. data/fixtures/test-app/source/images/cfb_tomb-perennial-energy.svgz +0 -0
  58. data/fixtures/test-app/source/index.html.haml +3 -0
  59. data/fixtures/test-app/source/layouts/content_for.erb +4 -0
  60. data/lib/middleman.rb +90 -105
  61. data/lib/middleman/base.rb +254 -239
  62. data/lib/middleman/builder.rb +51 -46
  63. data/lib/middleman/cache.rb +57 -0
  64. data/lib/middleman/cli.rb +7 -10
  65. data/lib/middleman/core_extensions/assets.rb +3 -3
  66. data/lib/middleman/core_extensions/compass.rb +25 -45
  67. data/lib/middleman/core_extensions/data.rb +14 -12
  68. data/lib/middleman/core_extensions/default_helpers.rb +11 -10
  69. data/lib/middleman/core_extensions/{features.rb → extensions.rb} +66 -20
  70. data/lib/middleman/core_extensions/front_matter.rb +16 -13
  71. data/lib/middleman/core_extensions/rendering.rb +224 -4
  72. data/lib/middleman/core_extensions/routing.rb +15 -12
  73. data/lib/middleman/core_extensions/sitemap.rb +6 -191
  74. data/lib/middleman/core_extensions/sprockets.rb +3 -2
  75. data/lib/middleman/extensions/asset_host.rb +34 -0
  76. data/lib/middleman/extensions/automatic_image_sizes.rb +38 -0
  77. data/lib/middleman/{features → extensions}/automatic_image_sizes/fastimage.rb +0 -0
  78. data/lib/middleman/extensions/cache_buster.rb +59 -0
  79. data/lib/middleman/extensions/directory_indexes.rb +62 -0
  80. data/lib/middleman/extensions/lorem.rb +130 -0
  81. data/lib/middleman/extensions/minify_css.rb +15 -0
  82. data/lib/middleman/{features → extensions}/minify_css/cssmin.rb +0 -0
  83. data/lib/middleman/extensions/minify_javascript.rb +54 -0
  84. data/lib/middleman/extensions/relative_assets.rb +46 -0
  85. data/lib/middleman/extensions/sitemap_tree.rb +38 -0
  86. data/lib/middleman/guard.rb +48 -35
  87. data/lib/middleman/renderers/erb.rb +3 -13
  88. data/lib/middleman/renderers/haml.rb +13 -0
  89. data/lib/middleman/renderers/liquid.rb +3 -3
  90. data/lib/middleman/renderers/markdown.rb +10 -12
  91. data/lib/middleman/renderers/sass.rb +3 -9
  92. data/lib/middleman/sitemap/page.rb +106 -0
  93. data/lib/middleman/sitemap/store.rb +141 -0
  94. data/lib/middleman/sitemap/template.rb +57 -0
  95. data/lib/middleman/step_definitions.rb +6 -0
  96. data/lib/middleman/step_definitions/builder_steps.rb +45 -0
  97. data/{features → lib/middleman}/step_definitions/generator_steps.rb +6 -6
  98. data/{features/step_definitions/middleman_steps.rb → lib/middleman/step_definitions/server_steps.rb} +3 -3
  99. data/lib/middleman/templates/default/source/index.html.erb +1 -1
  100. data/lib/middleman/version.rb +7 -1
  101. data/middleman-x86-mingw32.gemspec +1 -1
  102. data/middleman.gemspec +5 -3
  103. metadata +359 -381
  104. data/bin/mm-build +0 -9
  105. data/bin/mm-init +0 -9
  106. data/bin/mm-server +0 -9
  107. data/features/step_definitions/builder_steps.rb +0 -52
  108. data/features/tiny_src.feature +0 -15
  109. data/lib/middleman/features/asset_host.rb +0 -32
  110. data/lib/middleman/features/automatic_image_sizes.rb +0 -34
  111. data/lib/middleman/features/cache_buster.rb +0 -55
  112. data/lib/middleman/features/directory_indexes.rb +0 -59
  113. data/lib/middleman/features/lorem.rb +0 -126
  114. data/lib/middleman/features/minify_css.rb +0 -11
  115. data/lib/middleman/features/minify_javascript.rb +0 -50
  116. data/lib/middleman/features/relative_assets.rb +0 -42
  117. data/lib/middleman/features/sitemap_tree.rb +0 -34
@@ -0,0 +1,13 @@
1
+ module Middleman::Renderers::Haml
2
+ class << self
3
+ def registered(app)
4
+ require "haml"
5
+ app.send :include, ::Haml::Helpers
6
+
7
+ app.ready do
8
+ init_haml_helpers
9
+ end
10
+ end
11
+ alias :included :registered
12
+ end
13
+ end
@@ -2,15 +2,15 @@ module Middleman::Renderers::Liquid
2
2
  class << self
3
3
  def registered(app)
4
4
  # Liquid is not included in the default gems,
5
- # but we'll support it if necessary.
5
+ # but we'll support it if available.
6
6
  begin
7
7
  require "liquid"
8
8
 
9
9
  app.after_configuration do
10
- Liquid::Template.file_system = Liquid::LocalFileSystem.new(self.source_dir)
10
+ Liquid::Template.file_system = Liquid::LocalFileSystem.new(source_dir)
11
11
 
12
12
  provides_metadata %r{\.liquid$} do |path|
13
- @locals.merge!(:data => data.to_h)
13
+ { :locals => { :data => data.to_h } }
14
14
  end
15
15
  end
16
16
  rescue LoadError
@@ -1,13 +1,17 @@
1
1
  module Middleman::Renderers::Markdown
2
2
  class << self
3
3
  def registered(app)
4
- app.send :include, InstanceMethods
5
-
4
+ app.set :markdown_engine, nil
5
+
6
6
  begin
7
7
  require "maruku"
8
8
  app.set :markdown_engine, :maruku
9
9
  rescue LoadError
10
- app.set :markdown_engine, nil
10
+ begin
11
+ require "rdiscount"
12
+ app.set :markdown_engine, :rdiscount
13
+ rescue LoadError
14
+ end
11
15
  end
12
16
 
13
17
  app.set :markdown_engine_prefix, ::Tilt
@@ -15,7 +19,9 @@ module Middleman::Renderers::Markdown
15
19
  app.after_configuration do
16
20
  unless markdown_engine.nil?
17
21
  if markdown_engine.is_a? Symbol
18
- markdown_engine = markdown_tilt_template_from_symbol(markdown_engine)
22
+ engine = engine.to_s
23
+ engine = engine == "rdiscount" ? "RDiscount" : engine.camelize
24
+ markdown_engine = markdown_engine_prefix.const_get("#{engine}Template")
19
25
  end
20
26
 
21
27
  ::Tilt.prefer(markdown_engine)
@@ -24,12 +30,4 @@ module Middleman::Renderers::Markdown
24
30
  end
25
31
  alias :included :registered
26
32
  end
27
-
28
- module InstanceMethods
29
- def markdown_tilt_template_from_symbol(engine)
30
- engine = engine.to_s
31
- engine = engine == "rdiscount" ? "RDiscount" : engine.camelize
32
- markdown_engine_prefix.const_get("#{engine}Template")
33
- end
34
- end
35
33
  end
@@ -10,10 +10,8 @@ module Middleman::Renderers::Sass
10
10
  end
11
11
  alias :included :registered
12
12
  end
13
-
13
+
14
14
  class SassPlusCSSFilenameTemplate < ::Sprockets::Sass::SassTemplate
15
- self.default_mime_type = "text/css"
16
-
17
15
  # Add exception messaging
18
16
  def evaluate(context, locals, &block)
19
17
  begin
@@ -28,16 +26,14 @@ module Middleman::Renderers::Sass
28
26
  location_of_sass_file = if @context.build?
29
27
  File.expand_path(@context.build_dir, @context.root)
30
28
  else
31
- File.expand_path(@context.views, @context.root)
29
+ File.expand_path(@context.source, @context.root)
32
30
  end
33
31
 
34
32
  parts = basename.split('.')
35
33
  parts.pop
36
34
  css_filename = File.join(location_of_sass_file, @context.css_dir, parts.join("."))
37
35
 
38
- super.merge(
39
- :css_filename => css_filename
40
- )
36
+ super.merge(:css_filename => css_filename)
41
37
  end
42
38
  end
43
39
  ::Sprockets.register_engine ".sass", SassPlusCSSFilenameTemplate
@@ -45,8 +41,6 @@ module Middleman::Renderers::Sass
45
41
  ::Tilt.prefer(SassPlusCSSFilenameTemplate)
46
42
 
47
43
  class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate
48
- self.default_mime_type = "text/css"
49
-
50
44
  # Define the expected syntax for the template
51
45
  def syntax
52
46
  :scss
@@ -0,0 +1,106 @@
1
+ module Middleman::Sitemap
2
+ class Page
3
+ attr_accessor :store, :path, :proxied_to, :status
4
+
5
+ def initialize(store, path)
6
+ @store = store
7
+ @path = path
8
+ @status = :generic
9
+ @source_file = nil
10
+ @proxied_to = nil
11
+ end
12
+
13
+ def template?
14
+ if proxy?
15
+ store.page(proxied_to).template?
16
+ else
17
+ return false if source_file.nil?
18
+ !::Tilt[source_file].nil?
19
+ end
20
+ end
21
+
22
+ def source_file=(src)
23
+ @source_file = src
24
+ end
25
+
26
+ def source_file
27
+ if proxy?
28
+ store.page(proxied_to).source_file
29
+ else
30
+ @source_file
31
+ end
32
+ end
33
+
34
+ def template
35
+ @_template ||= ::Middleman::Sitemap::Template.new(self)
36
+ end
37
+
38
+ def ext
39
+ File.extname(path)
40
+ end
41
+
42
+ def mime_type
43
+ app.mime_type ext
44
+ end
45
+
46
+ def proxy?
47
+ @status == :proxy
48
+ end
49
+
50
+ def proxy_to(target)
51
+ @status = :proxy
52
+ @proxied_to = target
53
+ end
54
+
55
+ def generic?
56
+ @status == :generic
57
+ end
58
+
59
+ def make_generic
60
+ @status = :generic
61
+ end
62
+
63
+ def ignored?
64
+ @status == :ignored
65
+ end
66
+
67
+ def ignore
68
+ @status = :ignored
69
+ end
70
+
71
+ def touch
72
+ end
73
+
74
+ def custom_render(&block)
75
+ @_custom_renderer ||= nil
76
+ @_custom_renderer = block if block_given?
77
+ @_custom_renderer
78
+ end
79
+
80
+ def render(*args, &block)
81
+ return unless template?
82
+
83
+ if proxy?
84
+ # Forward blocks
85
+ forward_blocks = template.blocks.compact
86
+ forward_blocks << block if block_given?
87
+ store.page(proxied_to).template.render(*args) do
88
+ forward_blocks.each do |block|
89
+ instance_exec(&block)
90
+ end
91
+ end
92
+ elsif !custom_render.nil?
93
+ params = args.dup
94
+ params << block if block_given?
95
+ instance_exec(*params, &custom_renderer)
96
+ else
97
+ template.render(*args, &block)
98
+ end
99
+ end
100
+
101
+ protected
102
+ def app
103
+ @store.app
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,141 @@
1
+ module Middleman::Sitemap
2
+ class Store
3
+ attr_accessor :app
4
+
5
+ def initialize(app)
6
+ @app = app
7
+ @source = File.expand_path(@app.source, @app.root)
8
+ @pages = {}
9
+ end
10
+
11
+ # Check to see if we know about a specific path
12
+ def exists?(path)
13
+ @pages.has_key?(path.sub(/^\//, ""))
14
+ end
15
+
16
+ def set_context(path, opts={}, blk=nil)
17
+ page(path) do
18
+ template.options = opts
19
+ template.blocks = [blk]
20
+ end
21
+ end
22
+
23
+ def ignore(path)
24
+ page(path) { ignore }
25
+ app.cache.remove(:ignored_paths)
26
+ end
27
+
28
+ def proxy(path, target)
29
+ page(path) { proxy_to(target.sub(%r{^/}, "")) }
30
+ app.cache.remove(:proxied_paths)
31
+ end
32
+
33
+ def page(path, &block)
34
+ path = path.sub(/^\//, "").gsub("%20", " ")
35
+ @pages[path] = ::Middleman::Sitemap::Page.new(self, path) unless @pages.has_key?(path)
36
+ @pages[path].instance_exec(&block) if block_given?
37
+ @pages[path]
38
+ end
39
+
40
+ def each(&block)
41
+ @pages.each do |k, v|
42
+ yield k, v
43
+ end
44
+ end
45
+
46
+ def all_paths
47
+ @pages.keys
48
+ end
49
+
50
+ def ignored?(path)
51
+ ignored_paths.include?(path.sub(/^\//, ""))
52
+ end
53
+
54
+ def ignored_paths
55
+ app.cache.fetch :ignored_paths do
56
+ @pages.values.select(&:ignored?).map(&:path)
57
+ end
58
+ end
59
+
60
+ def generic?(path)
61
+ generic_paths.include?(path.sub(/^\//, ""))
62
+ end
63
+
64
+ def generic_paths
65
+ app.cache.fetch :generic_paths do
66
+ @pages.values.select(&:generic?).map(&:path)
67
+ end
68
+ end
69
+
70
+ def proxied?(path)
71
+ proxied_paths.include?(path.sub(/^\//, ""))
72
+ end
73
+
74
+ def proxied_paths
75
+ app.cache.fetch :proxied_paths do
76
+ @pages.values.select(&:proxy?).map(&:path)
77
+ end
78
+ end
79
+
80
+ def remove_file(file)
81
+ path = file_to_path(file)
82
+ return false unless path
83
+
84
+ path = path.sub(/^\//, "")
85
+ @pages.delete(path) if @pages.has_key?(path)
86
+ @context_map.delete(path) if @context_map.has_key?(path)
87
+ end
88
+
89
+ def file_to_path(file)
90
+ file = File.expand_path(file, @app.root)
91
+
92
+ prefix = @source + "/"
93
+ return false unless file.include?(prefix)
94
+
95
+ path = file.sub(prefix, "")
96
+ path = extensionless_path(path)
97
+
98
+ path
99
+ end
100
+
101
+ def touch_file(file)
102
+ return false if file == @source ||
103
+ file.match(/^\./) ||
104
+ (file.match(/\/\./) && !file.match(/\/\.htaccess/)) ||
105
+ (file.match(/\/_/) && !file.match(/\/__/)) ||
106
+ File.directory?(file)
107
+
108
+ path = file_to_path(file)
109
+
110
+ return false unless path
111
+
112
+ return false if path.match(%r{^layout}) ||
113
+ path.match(%r{^layouts/})
114
+
115
+ # @app.logger.debug :sitemap_update, Time.now, path if @app.logging?
116
+
117
+ # Add generic path
118
+ page(path).source_file = File.expand_path(file, @app.root)
119
+
120
+ true
121
+ end
122
+
123
+ protected
124
+ def extensionless_path(file)
125
+ app.cache.fetch(:extensionless_path, file) do
126
+ path = file.dup
127
+
128
+ end_of_the_line = false
129
+ while !end_of_the_line
130
+ if !::Tilt[path].nil?
131
+ path = path.sub(File.extname(path), "")
132
+ else
133
+ end_of_the_line = true
134
+ end
135
+ end
136
+
137
+ path
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,57 @@
1
+ module Middleman::Sitemap
2
+
3
+ class Template
4
+ attr_accessor :page, :options, :locals, :blocks#, :dependencies
5
+
6
+ def initialize(page)
7
+ @page = page
8
+ @options = {}
9
+ @locals = {}
10
+ @blocks = []
11
+ end
12
+
13
+ def path
14
+ page.path
15
+ end
16
+
17
+ def source_file
18
+ page.source_file
19
+ end
20
+
21
+ def store
22
+ page.store
23
+ end
24
+
25
+ def app
26
+ store.app
27
+ end
28
+
29
+ def ext
30
+ page.ext
31
+ end
32
+
33
+ def metadata
34
+ app.cache.fetch(:metadata, source_file) do
35
+ metadata = { :options => {}, :locals => {} }
36
+ app.provides_metadata.each do |callback, matcher|
37
+ next if !matcher.nil? && !source_file.match(matcher)
38
+ result = app.instance_exec(source_file, &callback)
39
+ metadata = metadata.deep_merge(result)
40
+ end
41
+ metadata
42
+ end
43
+ end
44
+
45
+ def render(opts={}, locs={}, &block)
46
+ opts = options.deep_merge(metadata[:options]).deep_merge(opts)
47
+ locs = locals.deep_merge(metadata[:locals]).deep_merge(locs)
48
+
49
+ blocks.compact.each do |block|
50
+ app.instance_eval(&block)
51
+ end
52
+
53
+ app.instance_eval(&block) if block_given?
54
+ app.render_template(source_file, locs, opts)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,6 @@
1
+ MIDDLEMAN_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
2
+ MIDDLEMAN_BIN_PATH = File.join(MIDDLEMAN_ROOT_PATH, "bin")
3
+
4
+ require "middleman/step_definitions/builder_steps"
5
+ require "middleman/step_definitions/generator_steps"
6
+ require "middleman/step_definitions/server_steps"
@@ -0,0 +1,45 @@
1
+ require 'fileutils'
2
+
3
+ Given /^app "([^\"]*)" is using config "([^\"]*)"$/ do |path, config_name|
4
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
5
+ config_path = File.join(target, "config-#{config_name}.rb")
6
+ config_dest = File.join(target, "config.rb")
7
+ FileUtils.cp(config_path, config_dest)
8
+ end
9
+
10
+ Given /^a built app at "([^\"]*)"$/ do |path|
11
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
12
+
13
+ build_target = File.join(target, "build")
14
+ FileUtils.rm_rf(build_target)
15
+
16
+ build_cmd = File.join(MIDDLEMAN_BIN_PATH, "middleman build")
17
+ `cd #{target} && #{build_cmd}`
18
+ end
19
+
20
+ Then /^cleanup built app at "([^\"]*)"$/ do |path|
21
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build")
22
+ FileUtils.rm_rf(target)
23
+ end
24
+
25
+ Given /^a built app at "([^\"]*)" with flags "([^\"]*)"$/ do |path, flags|
26
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
27
+ build_cmd = File.join(MIDDLEMAN_BIN_PATH, "middleman build")
28
+ `cd #{target} && #{build_cmd} #{flags}`
29
+ end
30
+
31
+ Then /^"([^\"]*)" should exist at "([^\"]*)"$/ do |target_file, path|
32
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
33
+ File.exists?(target).should be_true
34
+ end
35
+
36
+ Then /^"([^\"]*)" should exist at "([^\"]*)" and include "([^\"]*)"$/ do |target_file, path, expected|
37
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
38
+ File.exists?(target).should be_true
39
+ File.read(target).should include(expected)
40
+ end
41
+
42
+ Then /^"([^\"]*)" should not exist at "([^\"]*)"$/ do |target_file, path|
43
+ target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
44
+ File.exists?(target).should be_false
45
+ end