middleman-core 4.0.0.alpha.6 → 4.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/features/asset_hash.feature +8 -1
- data/features/asset_host.feature +2 -13
- data/features/builder.feature +0 -2
- data/features/cli_init.feature +32 -0
- data/features/collections.feature +50 -0
- data/features/directory_index.feature +4 -5
- data/features/front-matter-neighbor.feature +20 -0
- data/features/helpers_link_to.feature +18 -0
- data/features/image_srcset_paths.feature +7 -0
- data/features/markdown_kramdown_in_haml.feature +2 -1
- data/features/minify_javascript.feature +1 -1
- data/features/multiple-sources.feature +8 -0
- data/fixtures/asset-hash-app/source/slim.html.slim +8 -0
- data/fixtures/asset-hash-app/source/subdir/index.html.erb +10 -1
- data/fixtures/asset-host-app/source/asset_host.html.erb +23 -1
- data/fixtures/collections-app/source/blog2/2011-01-01-new-article.html.markdown +2 -0
- data/fixtures/frontmatter-settings-neighbor-app/config.rb +19 -14
- data/fixtures/image-srcset-paths-app/image-srcset-paths.html.erb +1 -0
- data/fixtures/image-srcset-paths-app/images/blank.gif +0 -0
- data/fixtures/indexable-app/source/evil spaces.html +1 -1
- data/fixtures/large-build-app/config.rb +2 -0
- data/fixtures/large-build-app/source/spaces in file.html.erb +1 -1
- data/fixtures/more-traversal-app/source/layout.erb +1 -1
- data/fixtures/multiple-sources-with-duplicate-file-names-app/config.rb +2 -0
- data/fixtures/multiple-sources-with-duplicate-file-names-app/source/index.html.erb +1 -0
- data/fixtures/multiple-sources-with-duplicate-file-names-app/source2/index.html.erb +1 -0
- data/fixtures/traversal-app/source/.htaccess +0 -0
- data/fixtures/traversal-app/source/layout.erb +1 -1
- data/lib/middleman/rack.rb +1 -0
- data/lib/middleman-core/application.rb +15 -15
- data/lib/middleman-core/builder.rb +11 -7
- data/lib/middleman-core/cli/server.rb +86 -0
- data/lib/middleman-core/config_context.rb +1 -1
- data/lib/middleman-core/contracts.rb +0 -32
- data/lib/middleman-core/core_extensions/collections.rb +19 -17
- data/lib/middleman-core/core_extensions/data.rb +15 -17
- data/lib/middleman-core/core_extensions/default_helpers.rb +22 -1
- data/lib/middleman-core/core_extensions/file_watcher.rb +9 -7
- data/lib/middleman-core/core_extensions/front_matter.rb +2 -2
- data/lib/middleman-core/core_extensions/i18n.rb +11 -9
- data/lib/middleman-core/core_extensions/routing.rb +3 -4
- data/lib/middleman-core/extension.rb +179 -0
- data/lib/middleman-core/extension_manager.rb +8 -7
- data/lib/middleman-core/extensions/asset_hash.rb +14 -9
- data/lib/middleman-core/extensions/asset_host.rb +3 -1
- data/lib/middleman-core/extensions/gzip.rb +3 -2
- data/lib/middleman-core/extensions/lorem.rb +2 -2
- data/lib/middleman-core/extensions/relative_assets.rb +11 -5
- data/lib/middleman-core/file_renderer.rb +2 -2
- data/lib/middleman-core/logger.rb +1 -1
- data/lib/middleman-core/middleware/inline_url_rewriter.rb +9 -4
- data/lib/middleman-core/preview_server.rb +13 -9
- data/lib/middleman-core/rack.rb +2 -1
- data/lib/middleman-core/renderers/haml.rb +6 -0
- data/lib/middleman-core/renderers/kramdown.rb +1 -1
- data/lib/middleman-core/renderers/redcarpet.rb +1 -0
- data/lib/middleman-core/renderers/sass.rb +1 -1
- data/lib/middleman-core/renderers/slim.rb +1 -0
- data/lib/middleman-core/sitemap/extensions/ignores.rb +7 -4
- data/lib/middleman-core/sitemap/extensions/on_disk.rb +1 -1
- data/lib/middleman-core/sitemap/extensions/proxies.rb +13 -10
- data/lib/middleman-core/sitemap/extensions/redirects.rb +8 -7
- data/lib/middleman-core/sitemap/extensions/request_endpoints.rb +7 -6
- data/lib/middleman-core/sitemap/extensions/traversal.rb +3 -1
- data/lib/middleman-core/sitemap/resource.rb +14 -15
- data/lib/middleman-core/sitemap/store.rb +6 -5
- data/lib/middleman-core/sources/source_watcher.rb +29 -16
- data/lib/middleman-core/sources.rb +19 -21
- data/lib/middleman-core/step_definitions/builder_steps.rb +1 -1
- data/lib/middleman-core/step_definitions/server_steps.rb +3 -3
- data/lib/middleman-core/template_context.rb +8 -7
- data/lib/middleman-core/template_renderer.rb +2 -2
- data/lib/middleman-core/util.rb +57 -21
- data/lib/middleman-core/version.rb +1 -1
- data/lib/middleman-core.rb +2 -1
- data/middleman-core.gemspec +4 -1
- data/spec/middleman-core/core_extensions/data_spec.rb +41 -0
- data/spec/middleman-core/util_spec.rb +96 -0
- metadata +38 -8
- data/lib/middleman-core/util/hash_with_indifferent_access.rb +0 -103
- data/spec/middleman-core/binary_spec.rb +0 -15
- data/spec/middleman-core/path_match_spec.rb +0 -37
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'forwardable'
|
|
1
2
|
require 'active_support/core_ext/class/attribute'
|
|
2
3
|
require 'middleman-core/configuration'
|
|
3
4
|
require 'middleman-core/contracts'
|
|
@@ -81,6 +82,30 @@ module Middleman
|
|
|
81
82
|
# @return [Array<Module>] a list of all the helper modules this extension provides. Set these using {#helpers}.
|
|
82
83
|
class_attribute :defined_helpers, instance_reader: false, instance_writer: false
|
|
83
84
|
|
|
85
|
+
# @!attribute exposed_to_application
|
|
86
|
+
# @!scope class
|
|
87
|
+
# @api private
|
|
88
|
+
# @return [Hash<Symbol, Symbol>] a list of all the methods modules this extension exposes to app. Set these using {#expose_to_application}.
|
|
89
|
+
class_attribute :exposed_to_application, instance_reader: false, instance_writer: false
|
|
90
|
+
|
|
91
|
+
# @!attribute exposed_to_config
|
|
92
|
+
# @!scope class
|
|
93
|
+
# @api private
|
|
94
|
+
# @return [Hash<Symbol, Symbol>] a list of all the methods modules this extension exposes to config. Set these using {#expose_to_config}.
|
|
95
|
+
class_attribute :exposed_to_config, instance_reader: false, instance_writer: false
|
|
96
|
+
|
|
97
|
+
# @!attribute exposed_to_template
|
|
98
|
+
# @!scope class
|
|
99
|
+
# @api private
|
|
100
|
+
# @return [Hash<Symbol, Symbol>] a list of all the methods modules this extension exposes to templates. Set these using {#expose_to_template}.
|
|
101
|
+
class_attribute :exposed_to_template, instance_reader: false, instance_writer: false
|
|
102
|
+
|
|
103
|
+
# @!attribute exposed_to_template
|
|
104
|
+
# @!scope class
|
|
105
|
+
# @api private
|
|
106
|
+
# @return [Array<Any>] a list of method generators.
|
|
107
|
+
class_attribute :resources_generators, instance_reader: false, instance_writer: false
|
|
108
|
+
|
|
84
109
|
# @!attribute ext_name
|
|
85
110
|
# @!scope class
|
|
86
111
|
# @return [Symbol] the name this extension is registered under. This is the symbol used to activate the extension.
|
|
@@ -110,6 +135,19 @@ module Middleman
|
|
|
110
135
|
config.define_setting(key, default, description, options)
|
|
111
136
|
end
|
|
112
137
|
|
|
138
|
+
# Short-hand for simple Sitemap manipulation
|
|
139
|
+
# @example A generator which returns an array of resources
|
|
140
|
+
# resources :make_resources
|
|
141
|
+
# @example A generator which maps a path to a method
|
|
142
|
+
# resources make_resource: :make_it
|
|
143
|
+
# @example A generator which maps a path to a string
|
|
144
|
+
# resources make_resource: 'Hello'
|
|
145
|
+
# @param [Array] generators The generator definitions
|
|
146
|
+
def resources(*generators)
|
|
147
|
+
self.resources_generators ||= []
|
|
148
|
+
self.resources_generators += generators
|
|
149
|
+
end
|
|
150
|
+
|
|
113
151
|
# Declare helpers to be added the global Middleman application.
|
|
114
152
|
# This accepts either a list of modules to add on behalf
|
|
115
153
|
# of this extension, or a block whose contents will all
|
|
@@ -137,6 +175,68 @@ module Middleman
|
|
|
137
175
|
self.defined_helpers += modules
|
|
138
176
|
end
|
|
139
177
|
|
|
178
|
+
# Takes a method within this extension and exposes it globally
|
|
179
|
+
# on the main `app` instance. Used for very low-level extensions
|
|
180
|
+
# which many other extensions depend upon. Such as Data and
|
|
181
|
+
# File watching.
|
|
182
|
+
# @example with Hash:
|
|
183
|
+
# expose_to_application global_name: :local_name
|
|
184
|
+
# @example with Array:
|
|
185
|
+
# expose_to_application :method1, :method2
|
|
186
|
+
# @param [Array<Sumbol>, Hash<Symbol, Symbol>] symbols An optional list of symbols representing instance methods to exposed.
|
|
187
|
+
# @return [void]
|
|
188
|
+
def expose_to_application(*symbols)
|
|
189
|
+
self.exposed_to_application ||= {}
|
|
190
|
+
|
|
191
|
+
if symbols.first && symbols.first.is_a?(Hash)
|
|
192
|
+
self.exposed_to_application.merge!(symbols.first)
|
|
193
|
+
elsif symbols.is_a? Array
|
|
194
|
+
symbols.each do |sym|
|
|
195
|
+
self.exposed_to_application[sym] = sym
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Takes a method within this extension and exposes it inside the scope
|
|
201
|
+
# of the config.rb sandbox.
|
|
202
|
+
# @example with Hash:
|
|
203
|
+
# expose_to_config global_name: :local_name
|
|
204
|
+
# @example with Array:
|
|
205
|
+
# expose_to_config :method1, :method2
|
|
206
|
+
# @param [Array<Sumbol>, Hash<Symbol, Symbol>] symbols An optional list of symbols representing instance methods to exposed.
|
|
207
|
+
# @return [void]
|
|
208
|
+
def expose_to_config(*symbols)
|
|
209
|
+
self.exposed_to_config ||= {}
|
|
210
|
+
|
|
211
|
+
if symbols.first && symbols.first.is_a?(Hash)
|
|
212
|
+
self.exposed_to_config.merge!(symbols.first)
|
|
213
|
+
elsif symbols.is_a? Array
|
|
214
|
+
symbols.each do |sym|
|
|
215
|
+
self.exposed_to_config[sym] = sym
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Takes a method within this extension and exposes it inside the scope
|
|
221
|
+
# of the templating engine. Like `helpers`, but scoped.
|
|
222
|
+
# @example with Hash:
|
|
223
|
+
# expose_to_template global_name: :local_name
|
|
224
|
+
# @example with Array:
|
|
225
|
+
# expose_to_template :method1, :method2
|
|
226
|
+
# @param [Array<Sumbol>, Hash<Symbol, Symbol>] symbols An optional list of symbols representing instance methods to exposed.
|
|
227
|
+
# @return [void]
|
|
228
|
+
def expose_to_template(*symbols)
|
|
229
|
+
self.exposed_to_template ||= {}
|
|
230
|
+
|
|
231
|
+
if symbols.first && symbols.first.is_a?(Hash)
|
|
232
|
+
self.exposed_to_template.merge!(symbols.first)
|
|
233
|
+
elsif symbols.is_a? Array
|
|
234
|
+
symbols.each do |sym|
|
|
235
|
+
self.exposed_to_template[sym] = sym
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
140
240
|
# Reset all {Extension.after_extension_activated} callbacks.
|
|
141
241
|
# @api private
|
|
142
242
|
# @return [void]
|
|
@@ -190,6 +290,7 @@ module Middleman
|
|
|
190
290
|
@_helpers = []
|
|
191
291
|
@app = app
|
|
192
292
|
|
|
293
|
+
expose_methods
|
|
193
294
|
setup_options(options_hash, &block)
|
|
194
295
|
|
|
195
296
|
# Bind app hooks to local methods
|
|
@@ -197,6 +298,7 @@ module Middleman
|
|
|
197
298
|
bind_after_configuration
|
|
198
299
|
bind_before_build
|
|
199
300
|
bind_after_build
|
|
301
|
+
bind_ready
|
|
200
302
|
end
|
|
201
303
|
|
|
202
304
|
# @!method before_configuration
|
|
@@ -216,6 +318,10 @@ module Middleman
|
|
|
216
318
|
# Respond to the `after_build` event.
|
|
217
319
|
# If an `after_build` method is implemented, that method will be run after the builder runs.
|
|
218
320
|
|
|
321
|
+
# @!method ready
|
|
322
|
+
# Respond to the `ready` event.
|
|
323
|
+
# If an `ready` method is implemented, that method will be run after the app has finished booting up.
|
|
324
|
+
|
|
219
325
|
# @!method manipulate_resource_list(resources)
|
|
220
326
|
# Manipulate the resource list by transforming or adding {Sitemap::Resource}s.
|
|
221
327
|
# 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.
|
|
@@ -226,8 +332,28 @@ module Middleman
|
|
|
226
332
|
# @param [Array<Sitemap::Resource>] resources A list of all the resources known to the sitemap.
|
|
227
333
|
# @return [Array<Sitemap::Resource>] The transformed list of resources.
|
|
228
334
|
|
|
335
|
+
def add_exposed_to_context(context)
|
|
336
|
+
(self.class.exposed_to_template || {}).each do |k, v|
|
|
337
|
+
context.define_singleton_method(k, &method(v))
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
229
341
|
private
|
|
230
342
|
|
|
343
|
+
def expose_methods
|
|
344
|
+
(self.class.exposed_to_application || {}).each do |k, v|
|
|
345
|
+
app.define_singleton_method(k, &method(v))
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
(self.class.exposed_to_config || {}).each do |k, v|
|
|
349
|
+
app.config_context.define_singleton_method(k, &method(v))
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
(self.class.defined_helpers || []).each do |m|
|
|
353
|
+
app.template_context_class.send(:include, m)
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
231
357
|
# @yield An optional block that can be used to customize options before the extension is activated.
|
|
232
358
|
# @yieldparam Middleman::Configuration::ConfigurationManager] options Extension options
|
|
233
359
|
def setup_options(options_hash)
|
|
@@ -260,6 +386,53 @@ module Middleman
|
|
|
260
386
|
if ext.respond_to?(:manipulate_resource_list)
|
|
261
387
|
ext.app.sitemap.register_resource_list_manipulator(ext.class.ext_name, ext, ext.class.resource_list_manipulator_priority)
|
|
262
388
|
end
|
|
389
|
+
|
|
390
|
+
if ext.class.resources_generators && !ext.class.resources_generators.empty?
|
|
391
|
+
ext.app.sitemap.register_resource_list_manipulator(
|
|
392
|
+
:"#{ext.class.ext_name}_generator",
|
|
393
|
+
ext,
|
|
394
|
+
ext.class.resource_list_manipulator_priority,
|
|
395
|
+
:generate_resources
|
|
396
|
+
)
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def generate_resources(resources)
|
|
402
|
+
generator_defs = self.class.resources_generators.reduce({}) do |sum, g|
|
|
403
|
+
resource_definitions = if g.is_a? Hash
|
|
404
|
+
g
|
|
405
|
+
elsif g.is_a? Symbol
|
|
406
|
+
definition = method(g)
|
|
407
|
+
|
|
408
|
+
if definition.arity == 0
|
|
409
|
+
send(g)
|
|
410
|
+
else
|
|
411
|
+
send(g, resources)
|
|
412
|
+
end
|
|
413
|
+
else
|
|
414
|
+
{}
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
sum.merge(resource_definitions)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
resources + generator_defs.map do |path, g|
|
|
421
|
+
if g.is_a? Symbol
|
|
422
|
+
definition = method(g)
|
|
423
|
+
|
|
424
|
+
g = if definition.arity == 0
|
|
425
|
+
send(g)
|
|
426
|
+
else
|
|
427
|
+
send(g, resources)
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
::Middleman::Sitemap::StringResource.new(
|
|
432
|
+
app.sitemap,
|
|
433
|
+
path,
|
|
434
|
+
g
|
|
435
|
+
)
|
|
263
436
|
end
|
|
264
437
|
end
|
|
265
438
|
|
|
@@ -283,10 +456,16 @@ module Middleman
|
|
|
283
456
|
@app.after_build do |builder|
|
|
284
457
|
if ext.method(:after_build).arity == 1
|
|
285
458
|
ext.after_build(builder)
|
|
459
|
+
elsif ext.method(:after_build).arity == 2
|
|
460
|
+
ext.after_build(builder, builder.thor)
|
|
286
461
|
else
|
|
287
462
|
ext.after_build
|
|
288
463
|
end
|
|
289
464
|
end
|
|
290
465
|
end
|
|
466
|
+
|
|
467
|
+
def bind_ready
|
|
468
|
+
@app.ready(&method(:ready)) if respond_to?(:ready)
|
|
469
|
+
end
|
|
291
470
|
end
|
|
292
471
|
end
|
|
@@ -55,7 +55,7 @@ module Middleman
|
|
|
55
55
|
|
|
56
56
|
def activate_all
|
|
57
57
|
logger.debug 'Loaded extensions:'
|
|
58
|
-
instances = @activated.each_with_object([]) do |(ext_name, ext), sum|
|
|
58
|
+
@instances = @activated.each_with_object([]) do |(ext_name, ext), sum|
|
|
59
59
|
if ext.is_a?(Hash)
|
|
60
60
|
ext.each do |instance_key, instance|
|
|
61
61
|
logger.debug "== Extension: #{ext_name} #{instance_key}"
|
|
@@ -67,14 +67,15 @@ module Middleman
|
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
instances.each do |ext|
|
|
71
|
-
# Forward Extension helpers to TemplateContext
|
|
72
|
-
Array(ext.class.defined_helpers).each do |m|
|
|
73
|
-
@app.template_context_class.send(:include, m)
|
|
74
|
-
end
|
|
75
|
-
|
|
70
|
+
@instances.each do |ext|
|
|
76
71
|
::Middleman::Extension.activated_extension(ext)
|
|
77
72
|
end
|
|
78
73
|
end
|
|
74
|
+
|
|
75
|
+
def add_exposed_to_context(context)
|
|
76
|
+
@instances.each do |ext|
|
|
77
|
+
ext.add_exposed_to_context(context)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
79
80
|
end
|
|
80
81
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
require 'addressable/uri'
|
|
1
2
|
require 'middleman-core/util'
|
|
2
3
|
|
|
3
4
|
class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
4
|
-
option :exts, %w(.jpg .jpeg .png .gif .webp .js .css .otf .woff .eot .ttf .svg), 'List of extensions that get asset hashes appended to them.'
|
|
5
|
+
option :exts, %w(.jpg .jpeg .png .gif .webp .js .css .otf .woff .woff2 .eot .ttf .svg), 'List of extensions that get asset hashes appended to them.'
|
|
5
6
|
option :ignore, [], 'Regexes of filenames to skip adding asset hashes to'
|
|
6
7
|
|
|
7
8
|
def initialize(app, options_hash={}, &block)
|
|
@@ -9,7 +10,6 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
9
10
|
|
|
10
11
|
require 'digest/sha1'
|
|
11
12
|
require 'rack/mock'
|
|
12
|
-
require 'uri'
|
|
13
13
|
require 'middleman-core/middleware/inline_url_rewriter'
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -28,7 +28,8 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
28
28
|
|
|
29
29
|
Contract String, Or[String, Pathname], Any => Maybe[String]
|
|
30
30
|
def rewrite_url(asset_path, dirpath, _request_path)
|
|
31
|
-
|
|
31
|
+
uri = ::Addressable::URI.parse(asset_path)
|
|
32
|
+
relative_path = uri.path[0..0] != '/'
|
|
32
33
|
|
|
33
34
|
full_asset_path = if relative_path
|
|
34
35
|
dirpath.join(asset_path).to_s
|
|
@@ -36,10 +37,11 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
36
37
|
asset_path
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
return unless asset_page = app.sitemap.find_resource_by_path(full_asset_path)
|
|
40
|
+
return unless asset_page = app.sitemap.find_resource_by_destination_path(full_asset_path) || app.sitemap.find_resource_by_path(full_asset_path)
|
|
40
41
|
|
|
41
42
|
replacement_path = "/#{asset_page.destination_path}"
|
|
42
43
|
replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path
|
|
44
|
+
|
|
43
45
|
replacement_path
|
|
44
46
|
end
|
|
45
47
|
|
|
@@ -56,7 +58,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
56
58
|
# This is so by the time we get around to the text files (which may reference
|
|
57
59
|
# images and fonts) the static assets' hashes are already calculated.
|
|
58
60
|
resources.sort_by do |a|
|
|
59
|
-
if %w(.svg).include? a.ext
|
|
61
|
+
if %w(.svg .svgz).include? a.ext
|
|
60
62
|
0
|
|
61
63
|
elsif %w(.js .css).include? a.ext
|
|
62
64
|
1
|
|
@@ -73,9 +75,10 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
73
75
|
return if resource.ignored?
|
|
74
76
|
|
|
75
77
|
# Render through the Rack interface so middleware and mounted apps get a shot
|
|
76
|
-
response = @rack_client.get(
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
response = @rack_client.get(
|
|
79
|
+
URI.escape(resource.destination_path),
|
|
80
|
+
'bypass_inline_url_rewriter_asset_hash' => 'true'
|
|
81
|
+
)
|
|
79
82
|
|
|
80
83
|
raise "#{resource.path} should be in the sitemap!" unless response.status == 200
|
|
81
84
|
|
|
@@ -87,6 +90,8 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
|
|
87
90
|
|
|
88
91
|
Contract IsA['Middleman::Sitemap::Resource'] => Bool
|
|
89
92
|
def ignored_resource?(resource)
|
|
90
|
-
@ignore.any?
|
|
93
|
+
@ignore.any? do |ignore|
|
|
94
|
+
Middleman::Util.path_match(ignore, resource.destination_path)
|
|
95
|
+
end
|
|
91
96
|
end
|
|
92
97
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'addressable/uri'
|
|
1
2
|
require 'middleman-core/middleware/inline_url_rewriter'
|
|
2
3
|
|
|
3
4
|
class Middleman::Extensions::AssetHost < ::Middleman::Extension
|
|
@@ -18,7 +19,8 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension
|
|
|
18
19
|
|
|
19
20
|
Contract String, Or[String, Pathname], Any => String
|
|
20
21
|
def rewrite_url(asset_path, dirpath, _request_path)
|
|
21
|
-
|
|
22
|
+
uri = ::Addressable::URI.parse(asset_path)
|
|
23
|
+
relative_path = uri.path[0..0] != '/'
|
|
22
24
|
|
|
23
25
|
full_asset_path = if relative_path
|
|
24
26
|
dirpath.join(asset_path).to_s
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
class Middleman::Extensions::Gzip < ::Middleman::Extension
|
|
13
13
|
option :exts, %w(.js .css .html .htm), 'File extensions to Gzip when building.'
|
|
14
14
|
option :ignore, [], 'Patterns to avoid gzipping'
|
|
15
|
+
option :overwrite, false, 'Overwrite original files instead of adding .gz extension.'
|
|
15
16
|
|
|
16
17
|
class NumberHelpers
|
|
17
18
|
include ::Padrino::Helpers::NumberHelpers
|
|
@@ -73,11 +74,11 @@ class Middleman::Extensions::Gzip < ::Middleman::Extension
|
|
|
73
74
|
Contract String => [Maybe[String], Maybe[Num], Maybe[Num]]
|
|
74
75
|
def gzip_file(path)
|
|
75
76
|
input_file = File.open(path, 'rb').read
|
|
76
|
-
output_filename = path + '.gz'
|
|
77
|
+
output_filename = options.overwrite ? path : path + '.gz'
|
|
77
78
|
input_file_time = File.mtime(path)
|
|
78
79
|
|
|
79
80
|
# Check if the right file's already there
|
|
80
|
-
if File.exist?(output_filename) && File.mtime(output_filename) == input_file_time
|
|
81
|
+
if !options.overwrite && File.exist?(output_filename) && File.mtime(output_filename) == input_file_time
|
|
81
82
|
return [nil, nil, nil]
|
|
82
83
|
end
|
|
83
84
|
|
|
@@ -152,8 +152,8 @@ class Middleman::Extensions::Lorem < ::Middleman::Extension
|
|
|
152
152
|
color = options[:color]
|
|
153
153
|
|
|
154
154
|
if options[:random_color]
|
|
155
|
-
background_color = hex.
|
|
156
|
-
color = hex.
|
|
155
|
+
background_color = hex.sample(6).join
|
|
156
|
+
color = hex.sample(6).join
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
src << "/#{background_color.sub(/^#/, '')}" if background_color
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
require 'addressable/uri'
|
|
2
|
+
|
|
1
3
|
# Relative Assets extension
|
|
2
4
|
class Middleman::Extensions::RelativeAssets < ::Middleman::Extension
|
|
3
|
-
option :exts, %w(.css .png .jpg .jpeg .webp .svg .svgz .js .gif .ttf .otf .woff), 'List of extensions that get cache busters strings appended to them.'
|
|
5
|
+
option :exts, %w(.css .png .jpg .jpeg .webp .svg .svgz .js .gif .ttf .otf .woff .woff2), 'List of extensions that get cache busters strings appended to them.'
|
|
4
6
|
option :sources, %w(.htm .html .css), 'List of extensions that are searched for relative assets.'
|
|
5
7
|
option :ignore, [], 'Regexes of filenames to skip adding query strings to'
|
|
6
8
|
|
|
@@ -22,7 +24,11 @@ class Middleman::Extensions::RelativeAssets < ::Middleman::Extension
|
|
|
22
24
|
|
|
23
25
|
Contract String, Or[String, Pathname], Any => Maybe[String]
|
|
24
26
|
def rewrite_url(asset_path, dirpath, request_path)
|
|
25
|
-
|
|
27
|
+
uri = ::Addressable::URI.parse(asset_path)
|
|
28
|
+
|
|
29
|
+
return if uri.path[0..0] != '/'
|
|
30
|
+
|
|
31
|
+
relative_path = uri.host.nil?
|
|
26
32
|
|
|
27
33
|
full_asset_path = if relative_path
|
|
28
34
|
dirpath.join(asset_path).to_s
|
|
@@ -30,9 +36,9 @@ class Middleman::Extensions::RelativeAssets < ::Middleman::Extension
|
|
|
30
36
|
asset_path
|
|
31
37
|
end
|
|
32
38
|
|
|
33
|
-
return unless !full_asset_path.include?('//') && !asset_path.start_with?('data:')
|
|
34
|
-
|
|
35
39
|
current_dir = Pathname(request_path).dirname
|
|
36
|
-
Pathname(full_asset_path).relative_path_from(current_dir).to_s
|
|
40
|
+
result = Pathname(full_asset_path).relative_path_from(current_dir).to_s
|
|
41
|
+
|
|
42
|
+
result
|
|
37
43
|
end
|
|
38
44
|
end
|
|
@@ -28,7 +28,7 @@ module Middleman
|
|
|
28
28
|
# @param [Hash] opts
|
|
29
29
|
# @param [Class] context
|
|
30
30
|
# @return [String]
|
|
31
|
-
Contract Hash, Hash, Any, Proc => String
|
|
31
|
+
Contract Hash, Hash, Any, Maybe[Proc] => String
|
|
32
32
|
def render(locs={}, opts={}, context, &block)
|
|
33
33
|
path = @path.dup
|
|
34
34
|
|
|
@@ -102,7 +102,7 @@ module Middleman
|
|
|
102
102
|
# Get the template data from a path
|
|
103
103
|
# @param [String] path
|
|
104
104
|
# @return [String]
|
|
105
|
-
Contract
|
|
105
|
+
Contract String
|
|
106
106
|
def template_data_for_file
|
|
107
107
|
if @app.extensions[:front_matter]
|
|
108
108
|
@app.extensions[:front_matter].template_data_for_file(@path) || ''
|
|
@@ -39,7 +39,7 @@ module Middleman
|
|
|
39
39
|
def call(message, *args)
|
|
40
40
|
return if @instrumenting.is_a?(String) && @instrumenting != 'instrument' && !message.include?(@instrumenting)
|
|
41
41
|
|
|
42
|
-
evt = ActiveSupport::Notifications::Event.new(message, *args)
|
|
42
|
+
evt = ::ActiveSupport::Notifications::Event.new(message, *args)
|
|
43
43
|
info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms\n#{args.last}"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
require 'middleman-core/util'
|
|
2
|
-
require 'middleman-core/contracts'
|
|
3
1
|
require 'rack'
|
|
4
2
|
require 'rack/response'
|
|
3
|
+
require 'addressable/uri'
|
|
4
|
+
require 'middleman-core/util'
|
|
5
|
+
require 'middleman-core/contracts'
|
|
5
6
|
|
|
6
7
|
module Middleman
|
|
7
8
|
module Middleware
|
|
@@ -51,10 +52,13 @@ module Middleman
|
|
|
51
52
|
|
|
52
53
|
if path =~ /(^\/$)|(#{@source_exts_regex_text}$)/
|
|
53
54
|
if body = ::Middleman::Util.extract_response_text(response)
|
|
55
|
+
|
|
54
56
|
dirpath = Pathname.new(File.dirname(path))
|
|
55
57
|
|
|
56
58
|
rewritten = ::Middleman::Util.rewrite_paths(body, path, @exts) do |asset_path|
|
|
57
|
-
|
|
59
|
+
uri = ::Addressable::URI.parse(asset_path)
|
|
60
|
+
|
|
61
|
+
relative_path = uri.host.nil?
|
|
58
62
|
|
|
59
63
|
full_asset_path = if relative_path
|
|
60
64
|
dirpath.join(asset_path).to_s
|
|
@@ -76,7 +80,7 @@ module Middleman
|
|
|
76
80
|
[status, headers, response]
|
|
77
81
|
end
|
|
78
82
|
|
|
79
|
-
Contract IGNORE_DESCRIPTOR => Bool
|
|
83
|
+
Contract IGNORE_DESCRIPTOR, String => Bool
|
|
80
84
|
def should_ignore?(validator, value)
|
|
81
85
|
if validator.is_a? Regexp
|
|
82
86
|
# Treat as Regexp
|
|
@@ -89,6 +93,7 @@ module Middleman
|
|
|
89
93
|
File.fnmatch(value, validator)
|
|
90
94
|
else
|
|
91
95
|
# If some unknown thing, don't ignore
|
|
96
|
+
false
|
|
92
97
|
end
|
|
93
98
|
end
|
|
94
99
|
end
|
|
@@ -6,8 +6,6 @@ require 'middleman-core/rack'
|
|
|
6
6
|
# rubocop:disable GlobalVars
|
|
7
7
|
module Middleman
|
|
8
8
|
module PreviewServer
|
|
9
|
-
DEFAULT_PORT = 4567
|
|
10
|
-
|
|
11
9
|
class << self
|
|
12
10
|
extend Forwardable
|
|
13
11
|
|
|
@@ -17,9 +15,7 @@ module Middleman
|
|
|
17
15
|
# Start an instance of Middleman::Application
|
|
18
16
|
# @return [void]
|
|
19
17
|
def start(opts={})
|
|
20
|
-
@options = opts
|
|
21
|
-
@host = @options[:host] || '0.0.0.0'
|
|
22
|
-
@port = @options[:port] || DEFAULT_PORT
|
|
18
|
+
@options = opts
|
|
23
19
|
|
|
24
20
|
mount_instance(new_app)
|
|
25
21
|
logger.info "== The Middleman is standing watch at #{uri}"
|
|
@@ -75,6 +71,10 @@ module Middleman
|
|
|
75
71
|
end
|
|
76
72
|
|
|
77
73
|
unmount_instance
|
|
74
|
+
|
|
75
|
+
@webrick.shutdown
|
|
76
|
+
@webrick = nil
|
|
77
|
+
|
|
78
78
|
mount_instance(app)
|
|
79
79
|
|
|
80
80
|
logger.info '== The Middleman has reloaded'
|
|
@@ -90,7 +90,7 @@ module Middleman
|
|
|
90
90
|
private
|
|
91
91
|
|
|
92
92
|
def new_app
|
|
93
|
-
opts = @options
|
|
93
|
+
opts = @options.dup
|
|
94
94
|
|
|
95
95
|
::Middleman::Logger.singleton(
|
|
96
96
|
opts[:debug] ? 0 : 1,
|
|
@@ -103,6 +103,9 @@ module Middleman
|
|
|
103
103
|
config[:watcher_force_polling] = opts[:force_polling]
|
|
104
104
|
config[:watcher_latency] = opts[:latency]
|
|
105
105
|
|
|
106
|
+
config[:host] = opts[:host] if opts[:host]
|
|
107
|
+
config[:port] = opts[:port] if opts[:port]
|
|
108
|
+
|
|
106
109
|
ready do
|
|
107
110
|
match_against = [
|
|
108
111
|
%r{^config\.rb$},
|
|
@@ -114,12 +117,13 @@ module Middleman
|
|
|
114
117
|
# config.rb
|
|
115
118
|
files.watch :reload,
|
|
116
119
|
path: root,
|
|
117
|
-
|
|
118
|
-
match_against.none? { |m| file[:relative_path].to_s.match(m) }
|
|
119
|
-
}
|
|
120
|
+
only: match_against
|
|
120
121
|
end
|
|
121
122
|
end
|
|
122
123
|
|
|
124
|
+
@host = app.config[:host]
|
|
125
|
+
@port = app.config[:port]
|
|
126
|
+
|
|
123
127
|
app.files.on_change :reload do
|
|
124
128
|
$mm_reload = true
|
|
125
129
|
@webrick.stop
|
data/lib/middleman-core/rack.rb
CHANGED
|
@@ -82,6 +82,7 @@ module Middleman
|
|
|
82
82
|
request_path.force_encoding('UTF-8')
|
|
83
83
|
end
|
|
84
84
|
request_path = ::Middleman::Util.full_path(request_path, @middleman)
|
|
85
|
+
full_request_path = File.join(env['SCRIPT_NAME'], request_path) # Path including rack mount
|
|
85
86
|
|
|
86
87
|
# Run before callbacks
|
|
87
88
|
@middleman.run_hook :before
|
|
@@ -90,7 +91,7 @@ module Middleman
|
|
|
90
91
|
resource = @middleman.sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20'))
|
|
91
92
|
|
|
92
93
|
# Return 404 if not in sitemap
|
|
93
|
-
return not_found(res,
|
|
94
|
+
return not_found(res, full_request_path) unless resource && !resource.ignored?
|
|
94
95
|
|
|
95
96
|
# If this path is a binary file, send it immediately
|
|
96
97
|
return send_file(resource, env) if resource.binary?
|
|
@@ -48,6 +48,12 @@ module Middleman
|
|
|
48
48
|
# Add haml helpers to context
|
|
49
49
|
::Middleman::TemplateContext.send :include, ::Haml::Helpers
|
|
50
50
|
end
|
|
51
|
+
|
|
52
|
+
def add_exposed_to_context(context)
|
|
53
|
+
super
|
|
54
|
+
|
|
55
|
+
context.init_haml_helpers if context.respond_to?(:init_haml_helpers)
|
|
56
|
+
end
|
|
51
57
|
end
|
|
52
58
|
end
|
|
53
59
|
end
|
|
@@ -6,7 +6,7 @@ module Middleman
|
|
|
6
6
|
class KramdownTemplate < ::Tilt::KramdownTemplate
|
|
7
7
|
def evaluate(scope, *)
|
|
8
8
|
@output ||= begin
|
|
9
|
-
MiddlemanKramdownHTML.scope = ::Middleman::Renderers::Haml.last_haml_scope
|
|
9
|
+
MiddlemanKramdownHTML.scope = (defined?(::Middleman::Renderers::Haml) && ::Middleman::Renderers::Haml.last_haml_scope) ? ::Middleman::Renderers::Haml.last_haml_scope : scope
|
|
10
10
|
|
|
11
11
|
output, warnings = MiddlemanKramdownHTML.convert(@engine.root, @engine.options)
|
|
12
12
|
@engine.warnings.concat(warnings)
|
|
@@ -105,7 +105,7 @@ module Middleman
|
|
|
105
105
|
filename: eval_file,
|
|
106
106
|
line: line,
|
|
107
107
|
syntax: syntax,
|
|
108
|
-
custom: {
|
|
108
|
+
custom: (options[:custom] || {}).merge(middleman_context: ctx.app)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
if ctx.is_a?(::Middleman::TemplateContext) && file
|
|
@@ -3,12 +3,15 @@ module Middleman
|
|
|
3
3
|
module Extensions
|
|
4
4
|
# Class to handle managing ignores
|
|
5
5
|
class Ignores < Extension
|
|
6
|
+
# Expose `create_ignore` as `app.ignore`
|
|
7
|
+
expose_to_application ignore: :create_ignore
|
|
8
|
+
|
|
9
|
+
# Expose `create_ignore` to config as `ignore`
|
|
10
|
+
expose_to_config ignore: :create_ignore
|
|
11
|
+
|
|
6
12
|
def initialize(app, config={}, &block)
|
|
7
13
|
super
|
|
8
14
|
|
|
9
|
-
@app.add_to_config_context(:ignore, &method(:create_ignore))
|
|
10
|
-
@app.define_singleton_method(:ignore, &method(:create_ignore))
|
|
11
|
-
|
|
12
15
|
# Array of callbacks which can ass ignored
|
|
13
16
|
@ignored_callbacks = Set.new
|
|
14
17
|
|
|
@@ -18,7 +21,7 @@ module Middleman
|
|
|
18
21
|
# Ignore a path or add an ignore callback
|
|
19
22
|
# @param [String, Regexp] path Path glob expression, or path regex
|
|
20
23
|
# @return [void]
|
|
21
|
-
Contract Maybe[Or[String, Regexp]], Proc => Any
|
|
24
|
+
Contract Maybe[Or[String, Regexp]], Maybe[Proc] => Any
|
|
22
25
|
def create_ignore(path=nil, &block)
|
|
23
26
|
if path.is_a? Regexp
|
|
24
27
|
@ignored_callbacks << proc { |p| p =~ path }
|