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
@@ -1,3 +1,4 @@
1
+ require "active_support/core_ext/hash/deep_merge"
1
2
  require 'find'
2
3
 
3
4
  module Middleman::CoreExtensions::Sitemap
@@ -10,6 +11,8 @@ module Middleman::CoreExtensions::Sitemap
10
11
 
11
12
  module InstanceMethods
12
13
  def initialize
14
+ super
15
+
13
16
  file_changed do |file|
14
17
  sitemap.touch_file(file)
15
18
  end
@@ -17,21 +20,19 @@ module Middleman::CoreExtensions::Sitemap
17
20
  file_deleted do |file|
18
21
  sitemap.remove_file(file)
19
22
  end
20
-
21
- super
22
23
  end
23
24
 
24
25
  def sitemap
25
- @sitemap ||= SitemapStore.new(self)
26
+ @sitemap ||= ::Middleman::Sitemap::Store.new(self)
26
27
  end
27
28
 
28
29
  # Keep a path from building
29
30
  def ignore(path)
30
- sitemap.ignore_path(path)
31
+ sitemap.ignore(path)
31
32
  end
32
33
 
33
34
  def reroute(url, target)
34
- sitemap.set_path(url, target)
35
+ sitemap.proxy(url, target)
35
36
  end
36
37
 
37
38
  def provides_metadata(matcher=nil, &block)
@@ -40,190 +41,4 @@ module Middleman::CoreExtensions::Sitemap
40
41
  @_provides_metadata
41
42
  end
42
43
  end
43
-
44
- class SitemapStore
45
- def initialize(app)
46
- @app = app
47
- @source = File.expand_path(@app.views, @app.root)
48
- @map = {}
49
- @context_map = {}
50
- @source_map = {}
51
- @ignored_paths = false
52
- @generic_paths = false
53
- @proxied_paths = false
54
-
55
- # build_static_map
56
- end
57
-
58
- # Check to see if we know about a specific path
59
- def path_exists?(path)
60
- path = path.sub(/^\//, "")
61
- @map.has_key?(path)
62
- end
63
-
64
- def path_is_proxy?(path)
65
- path = path.sub(/^\//, "")
66
- return false if !path_exists?(path)
67
- @map[path].is_a?(String)
68
- end
69
-
70
- def path_target(path)
71
- path = path.sub(/^\//, "")
72
- @map[path]
73
- end
74
-
75
- def path_context(path)
76
- path = path.sub(/^\//, "")
77
- @context_map[path]
78
- end
79
-
80
- def set_path(path, target=true)
81
- path = path.sub(/^\//, "")
82
- target = target.sub(/^\//, "") if target.is_a?(String)
83
-
84
- @map[path] = target
85
-
86
- @ignored_paths = false if target === false
87
- @generic_paths = false if target === true
88
- @proxied_paths = false if target.is_a?(String)
89
- end
90
-
91
- def set_context(path, options={}, block=nil)
92
- path = path.sub(/^\//, "")
93
- @context_map[path] = {
94
- :options => options,
95
- :block => block
96
- }
97
- end
98
-
99
- def get_context(path)
100
- path = path.sub(/^\//, "")
101
- @context_map[path]
102
- end
103
-
104
- def ignore_path(path)
105
- set_path(path, false)
106
- @ignored_paths = false
107
- end
108
-
109
- def each(&block)
110
- @map.each do |k, v|
111
- yield(k, v)
112
- end
113
- end
114
-
115
- def all_paths
116
- @map.keys
117
- end
118
-
119
- def all_values
120
- @map.values
121
- end
122
-
123
- def ignored_path?(path)
124
- path = path.sub(/^\//, "")
125
- ignored_paths.include?(path)
126
- end
127
-
128
- def ignored_paths
129
- @ignored_paths ||= begin
130
- ignored = []
131
- each do |k, v|
132
- ignored << k if v === false
133
- end
134
- ignored
135
- end
136
- end
137
-
138
- def generic_path?(path)
139
- path = path.sub(/^\//, "")
140
- generic_paths.include?(path)
141
- end
142
-
143
- def generic_paths
144
- @generic_paths ||= begin
145
- generic = []
146
- each do |k, v|
147
- generic << k if v === true
148
- end
149
- generic
150
- end
151
- end
152
-
153
- def proxied_path?(path)
154
- path = path.sub(/^\//, "")
155
- proxied_paths.include?(path)
156
- end
157
-
158
- def proxied_paths
159
- @proxied_paths ||= begin
160
- proxied = []
161
- each do |k, v|
162
- proxied << k if v.is_a?(String)
163
- end
164
- proxied
165
- end
166
- end
167
-
168
- def touch_file(file)
169
- add_file(file)
170
- end
171
-
172
- def remove_file(file)
173
- path = file_to_path(file)
174
- remove_path(path) if path
175
- end
176
-
177
- def remove_path(path)
178
- path = path.sub(/^\//, "")
179
- @map.delete(path) if path_exists?(path)
180
- @context_map.delete(path) if @context_map.has_key?(path)
181
- end
182
-
183
- def source_map
184
- @source_map
185
- end
186
-
187
- protected
188
- def build_static_map
189
- Find.find(@source) do |file|
190
- add_file(file)
191
- end
192
- end
193
-
194
- def file_to_path(file)
195
- file = File.expand_path(file, @app.root)
196
-
197
- prefix = @source + "/"
198
- return false unless file.include?(prefix)
199
-
200
- path = file.sub(prefix, "")
201
- path = @app.extensionless_path(path)
202
-
203
- @source_map[path] = file
204
- path
205
- end
206
-
207
- def add_file(file)
208
- return false if file == @source ||
209
- file.match(/^\./) ||
210
- file.match(/\/\./) ||
211
- (file.match(/\/_/) && !file.match(/\/__/)) ||
212
- File.directory?(file)
213
-
214
- path = file_to_path(file)
215
-
216
- add_path(path) if path && !path_exists?(path)
217
- end
218
-
219
- def add_path(path)
220
- return false if path.match(%r{^layout}) ||
221
- path.match(%r{^layouts/})
222
-
223
- # @app.logger.debug :sitemap_update, Time.now, path if @app.logging?
224
- set_path(path)
225
-
226
- true
227
- end
228
- end
229
44
  end
@@ -38,10 +38,11 @@ module Middleman::CoreExtensions::Sprockets
38
38
  end
39
39
 
40
40
  # add paths to js_env (vendor/assets/javascripts)
41
- map "/#{self.js_dir}" do
41
+ map "/#{js_dir}" do
42
42
  run js_env
43
43
  end
44
44
 
45
+ sass.each { |k, v| ::Sprockets::Sass.options[k] = v }
45
46
  css_env = Middleman::CoreExtensions::Sprockets::StylesheetEnvironment.new(self)
46
47
 
47
48
  vendor_dir = File.join("vendor", "assets", "stylesheets")
@@ -58,7 +59,7 @@ module Middleman::CoreExtensions::Sprockets
58
59
  css_env.append_path File.join(spec.full_gem_path, app_dir)
59
60
  end
60
61
 
61
- map("/#{self.css_dir}") do
62
+ map("/#{css_dir}") do
62
63
  run css_env
63
64
  end
64
65
  end
@@ -0,0 +1,34 @@
1
+ module Middleman::Extensions
2
+ module AssetHost
3
+ class << self
4
+ def registered(app)
5
+ app.set :asset_host, false
6
+
7
+ app.compass_config do |config|
8
+ if asset_host.is_a?(Proc)
9
+ config.asset_host(&asset_host)
10
+ end
11
+ end
12
+
13
+ app.send :include, InstanceMethods
14
+ end
15
+ alias :included :registered
16
+ end
17
+
18
+ module InstanceMethods
19
+ def asset_url(path, prefix="")
20
+ original_output = super
21
+
22
+ valid_extensions = %w(.png .gif .jpg .jpeg .svg .svgz .js .css)
23
+
24
+ asset_prefix = if asset_host.is_a?(Proc)
25
+ asset_host.call(original_output)
26
+ elsif asset_host.is_a?(String)
27
+ asset_host
28
+ end
29
+
30
+ File.join(asset_prefix, original_output)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ module Middleman::Extensions
2
+ module AutomaticImageSizes
3
+ class << self
4
+ def registered(app)
5
+ require "middleman/extensions/automatic_image_sizes/fastimage"
6
+
7
+ app.send :include, InstanceMethods
8
+ end
9
+ alias :included :registered
10
+ end
11
+
12
+ module InstanceMethods
13
+ def image_tag(path, params={})
14
+ if !params.has_key?(:width) && !params.has_key?(:height) && !path.include?("://")
15
+ params[:alt] ||= ""
16
+ http_prefix = http_images_path rescue images_dir
17
+
18
+ begin
19
+ real_path = File.join(source, images_dir, path)
20
+ full_path = File.expand_path(real_path, root)
21
+ http_prefix = http_images_path rescue images_dir
22
+ if File.exists? full_path
23
+ dimensions = ::FastImage.size(full_path, :raise_on_failure => true)
24
+ params[:width] = dimensions[0]
25
+ params[:height] = dimensions[1]
26
+ end
27
+ rescue
28
+ # $stderr.puts params.inspect
29
+ end
30
+ end
31
+
32
+ super(path, params)
33
+ end
34
+ end
35
+ end
36
+
37
+ register :automatic_image_sizes, AutomaticImageSizes
38
+ end
@@ -0,0 +1,59 @@
1
+ module Middleman::Extensions
2
+ module CacheBuster
3
+ class << self
4
+ def registered(app)
5
+ app.send :include, InstanceMethods
6
+
7
+ app.compass_config do |config|
8
+ config.asset_cache_buster do |path, real_path|
9
+ real_path = real_path.path if real_path.is_a? File
10
+ real_path = real_path.gsub(File.join(root, build_dir), source)
11
+ if File.readable?(real_path)
12
+ File.mtime(real_path).strftime("%s")
13
+ else
14
+ $stderr.puts "WARNING: '#{File.basename(path)}' was not found (or cannot be read) in #{File.dirname(real_path)}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ alias :included :registered
20
+ end
21
+
22
+ module InstanceMethods
23
+ def asset_url(path, prefix="")
24
+ http_path = super
25
+
26
+ if http_path.include?("://") || !%w(.css .png .jpg .jpeg .svg .svgz .js .gif).include?(File.extname(http_path))
27
+ http_path
28
+ else
29
+ begin
30
+ prefix = images_dir if prefix == http_images_path
31
+ rescue
32
+ end
33
+
34
+ real_path_static = File.join(prefix, path)
35
+
36
+ if build?
37
+ real_path_dynamic = File.join(build_dir, prefix, path)
38
+ real_path_dynamic = File.expand_path(real_path_dynamic, root)
39
+ http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
40
+ elsif sitemap.exists?(real_path_static)
41
+ page = sitemap.page(real_path_static)
42
+ if !page.template?
43
+ http_path << "?" + File.mtime(result[0]).strftime("%s")
44
+ else
45
+ # It's a template, possible with partials. We can't really know when
46
+ # it's updated, so generate fresh cache buster every time durin
47
+ # developement
48
+ http_path << "?" + Time.now.strftime("%s")
49
+ end
50
+ end
51
+
52
+ http_path
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ register :cache_buster, CacheBuster
59
+ end
@@ -0,0 +1,62 @@
1
+ module Middleman::Extensions
2
+ module DirectoryIndexes
3
+ class << self
4
+ def registered(app)
5
+ app.send :include, InstanceMethods
6
+ app.before do
7
+ next if sitemap.exists?(@original_path)
8
+
9
+ prefix = @original_path.sub(/\/$/, "")
10
+ indexed_path = prefix + "/" + index_file
11
+
12
+ extensioned_path = prefix + File.extname(index_file)
13
+ is_ignored = ignored_directory_indexes.include?(extensioned_path)
14
+
15
+ if !sitemap.exists?(indexed_path) && !is_ignored
16
+ parts = @original_path.split("/")
17
+ last_part = parts.last
18
+ last_part_ext = File.extname(last_part)
19
+
20
+ if last_part_ext.blank?
21
+ # This is a folder, redirect to index
22
+ @request_path = extensioned_path
23
+ end
24
+ end
25
+ end
26
+
27
+ app.build_reroute do |destination, request_path|
28
+ index_ext = File.extname(index_file)
29
+ new_index_path = "/#{index_file}"
30
+
31
+ if ignored_directory_indexes.include?(request_path)
32
+ false
33
+ elsif request_path =~ /#{new_index_path}$/
34
+ false
35
+ else
36
+ [
37
+ destination.sub(/#{index_ext.gsub(".", "\\.")}$/, new_index_path),
38
+ request_path
39
+ ]
40
+ end
41
+ end
42
+ end
43
+ alias :included :registered
44
+ end
45
+
46
+ module InstanceMethods
47
+ def ignored_directory_indexes
48
+ @_ignored_directory_indexes ||= []
49
+ end
50
+
51
+ def page(url, options={}, &block)
52
+ if options.has_key?(:directory_index) && !options["directory_index"]
53
+ ignored_directory_indexes << url
54
+ else
55
+ super
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ register :directory_indexes, DirectoryIndexes
62
+ end