middleman-core 4.1.0.rc.1 → 4.1.0.rc.2

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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/features/asset_hash.feature +44 -6
  4. data/features/asset_host.feature +1 -0
  5. data/features/automatic_image_sizes.feature +18 -5
  6. data/fixtures/asset-hash-host-app/source/index.html.erb +1 -1
  7. data/fixtures/asset-host-app/config.rb +1 -0
  8. data/fixtures/asset-host-app/source/asset_host.html.erb +9 -0
  9. data/fixtures/automatic-image-size-app/source/markdown-sizes.html.markdown +1 -0
  10. data/lib/middleman-core/application.rb +68 -58
  11. data/lib/middleman-core/builder.rb +24 -18
  12. data/lib/middleman-core/callback_manager.rb +8 -1
  13. data/lib/middleman-core/contracts.rb +13 -102
  14. data/lib/middleman-core/core_extensions.rb +6 -0
  15. data/lib/middleman-core/core_extensions/collections/lazy_step.rb +1 -1
  16. data/lib/middleman-core/core_extensions/data.rb +3 -2
  17. data/lib/middleman-core/core_extensions/default_helpers.rb +5 -5
  18. data/lib/middleman-core/core_extensions/external_helpers.rb +6 -11
  19. data/lib/middleman-core/core_extensions/file_watcher.rb +1 -1
  20. data/lib/middleman-core/core_extensions/front_matter.rb +1 -0
  21. data/lib/middleman-core/core_extensions/i18n.rb +4 -4
  22. data/lib/middleman-core/core_extensions/inline_url_rewriter.rb +150 -0
  23. data/lib/middleman-core/core_extensions/routing.rb +22 -28
  24. data/lib/middleman-core/core_extensions/show_exceptions.rb +1 -7
  25. data/lib/middleman-core/extension.rb +19 -2
  26. data/lib/middleman-core/extension_manager.rb +2 -0
  27. data/lib/middleman-core/extensions.rb +12 -0
  28. data/lib/middleman-core/extensions/asset_hash.rb +21 -20
  29. data/lib/middleman-core/extensions/asset_host.rb +9 -10
  30. data/lib/middleman-core/extensions/automatic_image_sizes.rb +1 -1
  31. data/lib/middleman-core/extensions/cache_buster.rb +6 -12
  32. data/lib/middleman-core/extensions/gzip.rb +2 -2
  33. data/lib/middleman-core/extensions/lorem.rb +1 -1
  34. data/lib/middleman-core/extensions/minify_css.rb +2 -2
  35. data/lib/middleman-core/extensions/minify_javascript.rb +2 -2
  36. data/lib/middleman-core/extensions/relative_assets.rb +6 -12
  37. data/lib/middleman-core/preview_server.rb +11 -9
  38. data/lib/middleman-core/preview_server/server_hostname.rb +2 -2
  39. data/lib/middleman-core/rack.rb +1 -1
  40. data/lib/middleman-core/renderers/kramdown.rb +1 -1
  41. data/lib/middleman-core/renderers/less.rb +3 -4
  42. data/lib/middleman-core/renderers/markdown.rb +2 -8
  43. data/lib/middleman-core/renderers/redcarpet.rb +1 -1
  44. data/lib/middleman-core/renderers/sass.rb +8 -11
  45. data/lib/middleman-core/renderers/stylus.rb +1 -5
  46. data/lib/middleman-core/sitemap/extensions/ignores.rb +5 -4
  47. data/lib/middleman-core/sitemap/extensions/import.rb +12 -15
  48. data/lib/middleman-core/sitemap/extensions/move_file.rb +3 -3
  49. data/lib/middleman-core/sitemap/extensions/proxies.rb +4 -4
  50. data/lib/middleman-core/sitemap/extensions/redirects.rb +16 -28
  51. data/lib/middleman-core/sitemap/extensions/request_endpoints.rb +17 -35
  52. data/lib/middleman-core/sitemap/extensions/traversal.rb +5 -5
  53. data/lib/middleman-core/sitemap/resource.rb +16 -16
  54. data/lib/middleman-core/sitemap/store.rb +42 -31
  55. data/lib/middleman-core/sources.rb +9 -9
  56. data/lib/middleman-core/sources/source_watcher.rb +14 -10
  57. data/lib/middleman-core/step_definitions/server_steps.rb +12 -4
  58. data/lib/middleman-core/template_context.rb +1 -1
  59. data/lib/middleman-core/template_renderer.rb +74 -75
  60. data/lib/middleman-core/util.rb +19 -16
  61. data/lib/middleman-core/util/data.rb +86 -82
  62. data/lib/middleman-core/version.rb +1 -1
  63. data/middleman-core.gemspec +1 -0
  64. metadata +19 -39
  65. data/features/cli/preview_server-hook.feature +0 -17
  66. data/features/cli/preview_server.feature +0 -536
  67. data/features/cli_extension.feature +0 -14
  68. data/features/cli_init.feature +0 -89
  69. data/fixtures/asset-hash-host-app/config.rb +0 -4
  70. data/fixtures/preview-server-app/bin/dns_server.rb +0 -33
  71. data/fixtures/preview-server-app/config.rb +0 -0
  72. data/fixtures/preview-server-app/source/index.html.erb +0 -1
  73. data/fixtures/preview-server-app/source/layout.erb +0 -9
  74. data/fixtures/preview-server-app/source/layouts/custom.erb +0 -8
  75. data/fixtures/preview-server-app/source/real.html +0 -1
  76. data/fixtures/preview-server-app/source/real/index.html.erb +0 -5
  77. data/fixtures/preview-server-app/source/should_be_ignored.html +0 -1
  78. data/fixtures/preview-server-app/source/should_be_ignored2.html +0 -1
  79. data/fixtures/preview-server-app/source/should_be_ignored3.html +0 -1
  80. data/fixtures/preview-server-app/source/static.html +0 -1
  81. data/fixtures/preview-server-hook-app/config.rb +0 -19
  82. data/fixtures/preview-server-hook-app/source/index.html.erb +0 -9
  83. data/lib/middleman-core/middleware/inline_url_rewriter.rb +0 -109
@@ -3,46 +3,48 @@ require 'active_support/core_ext/hash/deep_merge'
3
3
  require 'monitor'
4
4
  require 'hamster'
5
5
 
6
+ require 'middleman-core/extensions'
7
+
6
8
  # Files on Disk
7
- Middleman::Extensions.register :sitemap_ondisk, auto_activate: :before_configuration do
9
+ ::Middleman::Extensions.register :sitemap_ondisk, auto_activate: :before_configuration do
8
10
  require 'middleman-core/sitemap/extensions/on_disk'
9
- Middleman::Sitemap::Extensions::OnDisk
11
+ ::Middleman::Sitemap::Extensions::OnDisk
10
12
  end
11
13
 
12
14
  # Files on Disk (outside the project root)
13
- Middleman::Extensions.register :sitemap_import, auto_activate: :before_configuration do
15
+ ::Middleman::Extensions.register :sitemap_import, auto_activate: :before_configuration do
14
16
  require 'middleman-core/sitemap/extensions/import'
15
- Middleman::Sitemap::Extensions::Import
17
+ ::Middleman::Sitemap::Extensions::Import
16
18
  end
17
19
 
18
20
  # Endpoints
19
- Middleman::Extensions.register :sitemap_endpoint, auto_activate: :before_configuration do
21
+ ::Middleman::Extensions.register :sitemap_endpoint, auto_activate: :before_configuration do
20
22
  require 'middleman-core/sitemap/extensions/request_endpoints'
21
- Middleman::Sitemap::Extensions::RequestEndpoints
23
+ ::Middleman::Sitemap::Extensions::RequestEndpoints
22
24
  end
23
25
 
24
26
  # Proxies
25
- Middleman::Extensions.register :sitemap_proxies, auto_activate: :before_configuration do
27
+ ::Middleman::Extensions.register :sitemap_proxies, auto_activate: :before_configuration do
26
28
  require 'middleman-core/sitemap/extensions/proxies'
27
- Middleman::Sitemap::Extensions::Proxies
29
+ ::Middleman::Sitemap::Extensions::Proxies
28
30
  end
29
31
 
30
32
  # Redirects
31
- Middleman::Extensions.register :sitemap_redirects, auto_activate: :before_configuration do
33
+ ::Middleman::Extensions.register :sitemap_redirects, auto_activate: :before_configuration do
32
34
  require 'middleman-core/sitemap/extensions/redirects'
33
- Middleman::Sitemap::Extensions::Redirects
35
+ ::Middleman::Sitemap::Extensions::Redirects
34
36
  end
35
37
 
36
38
  # Move Files
37
- Middleman::Extensions.register :sitemap_move_files, auto_activate: :before_configuration do
39
+ ::Middleman::Extensions.register :sitemap_move_files, auto_activate: :before_configuration do
38
40
  require 'middleman-core/sitemap/extensions/move_file'
39
- Middleman::Sitemap::Extensions::MoveFile
41
+ ::Middleman::Sitemap::Extensions::MoveFile
40
42
  end
41
43
 
42
44
  # Ignores
43
- Middleman::Extensions.register :sitemap_ignore, auto_activate: :before_configuration do
45
+ ::Middleman::Extensions.register :sitemap_ignore, auto_activate: :before_configuration do
44
46
  require 'middleman-core/sitemap/extensions/ignores'
45
- Middleman::Sitemap::Extensions::Ignores
47
+ ::Middleman::Sitemap::Extensions::Ignores
46
48
  end
47
49
 
48
50
  require 'middleman-core/contracts'
@@ -73,6 +75,7 @@ module Middleman
73
75
  def initialize(app)
74
76
  @app = app
75
77
  @resources = []
78
+ @rebuild_reasons = [:first_run]
76
79
  @update_count = 0
77
80
 
78
81
  @resource_list_manipulators = ::Hamster::Vector.empty
@@ -113,9 +116,10 @@ module Middleman
113
116
 
114
117
  # Rebuild the list of resources from scratch, using registed manipulators
115
118
  # @return [void]
116
- Contract Maybe[Symbol] => Any
117
- def rebuild_resource_list!(name=nil)
119
+ Contract Symbol => Any
120
+ def rebuild_resource_list!(name)
118
121
  @lock.synchronize do
122
+ @rebuild_reasons << name
119
123
  @app.logger.debug "== Requesting resource list rebuilding: #{name}"
120
124
  @needs_sitemap_rebuild = true
121
125
  end
@@ -196,29 +200,36 @@ module Middleman
196
200
  def ensure_resource_list_updated!
197
201
  @lock.synchronize do
198
202
  return unless @needs_sitemap_rebuild
199
- @needs_sitemap_rebuild = false
200
203
 
201
- @app.logger.debug '== Rebuilding resource list'
204
+ ::Middleman::Util.instrument 'sitemap.update', reasons: @rebuild_reasons.uniq do
205
+ @needs_sitemap_rebuild = false
206
+
207
+ @app.logger.debug '== Rebuilding resource list'
208
+
209
+ @resources = []
202
210
 
203
- @resources = []
211
+ @resource_list_manipulators.each do |m|
212
+ ::Middleman::Util.instrument 'sitemap.manipulator', name: m[:name] do
213
+ @app.logger.debug "== Running manipulator: #{m[:name]}"
214
+ @resources = m[:manipulator].send(m[:custom_name] || :manipulate_resource_list, @resources)
204
215
 
205
- @resource_list_manipulators.each do |m|
206
- @app.logger.debug "== Running manipulator: #{m[:name]}"
207
- @resources = m[:manipulator].send(m[:custom_name] || :manipulate_resource_list, @resources)
216
+ # Reset lookup cache
217
+ reset_lookup_cache!
208
218
 
209
- # Reset lookup cache
210
- reset_lookup_cache!
219
+ # Rebuild cache
220
+ @resources.each do |resource|
221
+ @_lookup_by_path[resource.path] = resource
222
+ @_lookup_by_destination_path[resource.destination_path] = resource
223
+ end
211
224
 
212
- # Rebuild cache
213
- @resources.each do |resource|
214
- @_lookup_by_path[resource.path] = resource
215
- @_lookup_by_destination_path[resource.destination_path] = resource
225
+ invalidate_resources_not_ignored_cache!
226
+ end
216
227
  end
217
228
 
218
- invalidate_resources_not_ignored_cache!
219
- end
229
+ @update_count += 1
220
230
 
221
- @update_count += 1
231
+ @rebuild_reasons = []
232
+ end
222
233
  end
223
234
  end
224
235
 
@@ -15,10 +15,10 @@ module Middleman
15
15
  include Contracts
16
16
 
17
17
  # Types which could cause output to change.
18
- OUTPUT_TYPES = [:source, :locales, :data]
18
+ OUTPUT_TYPES = [:source, :locales, :data].freeze
19
19
 
20
20
  # Types which require a reload to eval ruby
21
- CODE_TYPES = [:reload]
21
+ CODE_TYPES = [:reload].freeze
22
22
 
23
23
  Matcher = Or[Regexp, RespondTo[:call]]
24
24
 
@@ -213,12 +213,12 @@ module Middleman
213
213
  # Manually poll all watchers for new content.
214
214
  #
215
215
  # @return [void]
216
- Contract Any
216
+ Contract ArrayOf[Pathname]
217
217
  def find_new_files!
218
- return unless @update_count != @last_update_count
218
+ return [] unless @update_count != @last_update_count
219
219
 
220
220
  @last_update_count = @update_count
221
- watchers.each(&:poll_once!)
221
+ watchers.reduce([]) { |sum, w| sum + w.poll_once! }
222
222
  end
223
223
 
224
224
  # Start up all listeners.
@@ -257,11 +257,11 @@ module Middleman
257
257
  #
258
258
  # @param [nil,Regexp] matcher A Regexp to match the change path against
259
259
  Contract Maybe[Matcher] => Any
260
- def changed(matcher=nil, &block)
260
+ def changed(matcher=nil, &_block)
261
261
  on_change OUTPUT_TYPES do |updated, _removed|
262
262
  updated
263
263
  .select { |f| matcher.nil? ? true : matches?(matcher, f) }
264
- .each { |f| block.call(f[:relative_path]) }
264
+ .each { |f| yield f[:relative_path] }
265
265
  end
266
266
  end
267
267
 
@@ -269,11 +269,11 @@ module Middleman
269
269
  #
270
270
  # @param [nil,Regexp] matcher A Regexp to match the change path against
271
271
  Contract Maybe[Matcher] => Any
272
- def deleted(matcher=nil, &block)
272
+ def deleted(matcher=nil, &_block)
273
273
  on_change OUTPUT_TYPES do |_updated, removed|
274
274
  removed
275
275
  .select { |f| matcher.nil? ? true : matches?(matcher, f) }
276
- .each { |f| block.call(f[:relative_path]) }
276
+ .each { |f| yield f[:relative_path] }
277
277
  end
278
278
  end
279
279
 
@@ -91,7 +91,7 @@ module Middleman
91
91
 
92
92
  stop_listener! if @listener
93
93
 
94
- update([], @files.values)
94
+ update([], @files.values.map { |source_file| source_file[:full_path] })
95
95
 
96
96
  poll_once!
97
97
 
@@ -180,17 +180,19 @@ module Middleman
180
180
  # Manually trigger update events.
181
181
  #
182
182
  # @return [void]
183
- Contract Any
183
+ Contract ArrayOf[Pathname]
184
184
  def poll_once!
185
185
  updated = ::Middleman::Util.all_files_under(@directory.to_s)
186
186
  removed = @files.keys.reject { |p| updated.include?(p) }
187
187
 
188
188
  update(updated, removed)
189
189
 
190
- return unless @waiting_for_existence && @directory.exist?
190
+ if @waiting_for_existence && @directory.exist?
191
+ @waiting_for_existence = false
192
+ listen!
193
+ end
191
194
 
192
- @waiting_for_existence = false
193
- listen!
195
+ updated + removed
194
196
  end
195
197
 
196
198
  # Work around this bug: http://bugs.ruby-lang.org/issues/4521
@@ -200,7 +202,7 @@ module Middleman
200
202
  def to_s
201
203
  "#<Middleman::SourceWatcher:0x#{object_id} type=#{@type.inspect} directory=#{@directory.inspect}>"
202
204
  end
203
- alias_method :inspect, :to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
205
+ alias inspect to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
204
206
 
205
207
  protected
206
208
 
@@ -254,17 +256,19 @@ module Middleman
254
256
  end
255
257
 
256
258
  execute_callbacks(:on_change, [
257
- valid_updates,
258
- valid_removes,
259
- self
260
- ]) unless valid_updates.empty? && valid_removes.empty?
259
+ valid_updates,
260
+ valid_removes,
261
+ self
262
+ ]) unless valid_updates.empty? && valid_removes.empty?
261
263
  end
262
264
 
265
+ Contract IsA['Middleman::SourceFile'] => Any
263
266
  def add_file_to_cache(f)
264
267
  @files[f[:full_path]] = f
265
268
  @extensionless_files[strip_extensions(f[:full_path])] = f
266
269
  end
267
270
 
271
+ Contract IsA['Middleman::SourceFile'] => Any
268
272
  def remove_file_from_cache(f)
269
273
  @files.delete(f[:full_path])
270
274
  @extensionless_files.delete(strip_extensions(f[:full_path]))
@@ -4,22 +4,23 @@ require 'capybara/cucumber'
4
4
 
5
5
  Given /^a clean server$/ do
6
6
  @initialize_commands = []
7
+ @activation_commands = []
7
8
  end
8
9
 
9
10
  Given /^"([^\"]*)" feature is "([^\"]*)"$/ do |feature, state|
10
- @initialize_commands ||= []
11
+ @activation_commands ||= []
11
12
 
12
13
  if state == 'enabled'
13
- @initialize_commands << lambda { activate(feature.to_sym) }
14
+ @activation_commands << lambda { activate(feature.to_sym) }
14
15
  end
15
16
  end
16
17
 
17
18
  Given /^"([^\"]*)" feature is "enabled" with "([^\"]*)"$/ do |feature, options_str|
18
- @initialize_commands ||= []
19
+ @activation_commands ||= []
19
20
 
20
21
  options = eval("{#{options_str}}")
21
22
 
22
- @initialize_commands << lambda { activate(feature.to_sym, options) }
23
+ @activation_commands << lambda { activate(feature.to_sym, options) }
23
24
  end
24
25
 
25
26
  Given /^"([^\"]*)" is set to "([^\"]*)"$/ do |variable, value|
@@ -41,6 +42,7 @@ Given /^the Server is running$/ do
41
42
  ENV['MM_ROOT'] = root_dir
42
43
 
43
44
  initialize_commands = @initialize_commands || []
45
+ activation_commands = @activation_commands || []
44
46
 
45
47
  @server_inst = ::Middleman::Application.new do
46
48
  config[:watcher_disable] = true
@@ -49,6 +51,12 @@ Given /^the Server is running$/ do
49
51
  initialize_commands.each do |p|
50
52
  instance_exec(&p)
51
53
  end
54
+
55
+ app.after_configuration_eval do
56
+ activation_commands.each do |p|
57
+ config_context.instance_exec(&p)
58
+ end
59
+ end
52
60
  end
53
61
 
54
62
  Capybara.app = ::Middleman::Rack.new(@server_inst).to_app
@@ -162,7 +162,7 @@ module Middleman
162
162
  return nil unless current_path
163
163
  sitemap.find_resource_by_destination_path(current_path)
164
164
  end
165
- alias_method :current_page, :current_resource
165
+ alias current_page current_resource
166
166
 
167
167
  protected
168
168
 
@@ -28,6 +28,75 @@ module Middleman
28
28
  @_cache ||= Cache.new
29
29
  end
30
30
 
31
+ # Find a layout on-disk, optionally using a specific engine
32
+ # @param [String] name
33
+ # @param [Symbol] preferred_engine
34
+ # @return [String]
35
+ Contract IsA['Middleman::Application'], Or[String, Symbol], Symbol => Maybe[IsA['Middleman::SourceFile']]
36
+ def self.locate_layout(app, name, preferred_engine=nil)
37
+ resolve_opts = {}
38
+ resolve_opts[:preferred_engine] = preferred_engine unless preferred_engine.nil?
39
+
40
+ # Check layouts folder
41
+ layout_file = resolve_template(app, File.join(app.config[:layouts_dir], name.to_s), resolve_opts)
42
+
43
+ # If we didn't find it, check root
44
+ layout_file = resolve_template(app, name, resolve_opts) unless layout_file
45
+
46
+ # Return the path
47
+ layout_file
48
+ end
49
+
50
+ # Find a template on disk given a output path
51
+ # @param [String] request_path
52
+ # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine.
53
+ # @return [String, Boolean] Either the path to the template, or false
54
+ Contract IsA['Middleman::Application'], Or[Symbol, String], Maybe[Hash] => Maybe[IsA['Middleman::SourceFile']]
55
+ def self.resolve_template(app, request_path, options={})
56
+ # Find the path by searching
57
+ relative_path = Util.strip_leading_slash(request_path.to_s)
58
+
59
+ # By default, any engine will do
60
+ preferred_engines = []
61
+
62
+ # If we're specifically looking for a preferred engine
63
+ if options.key?(:preferred_engine)
64
+ extension_class = ::Tilt[options[:preferred_engine]]
65
+
66
+ # Get a list of extensions for a preferred engine
67
+ preferred_engines += ::Tilt.mappings.select do |_, engines|
68
+ engines.include? extension_class
69
+ end.keys
70
+ end
71
+
72
+ preferred_engines << '*'
73
+ preferred_engines << nil if options[:try_static]
74
+
75
+ found_template = nil
76
+
77
+ preferred_engines.each do |preferred_engine|
78
+ path_with_ext = relative_path.dup
79
+ path_with_ext << ('.' + preferred_engine) unless preferred_engine.nil?
80
+
81
+ globbing = preferred_engine == '*'
82
+
83
+ # Cache lookups in build mode only
84
+ file = if app.build?
85
+ cache.fetch(path_with_ext, preferred_engine) do
86
+ app.files.find(:source, path_with_ext, globbing)
87
+ end
88
+ else
89
+ app.files.find(:source, path_with_ext, globbing)
90
+ end
91
+
92
+ found_template = file if file && (preferred_engine.nil? || ::Tilt[file[:full_path]])
93
+ break if found_template
94
+ end
95
+
96
+ # If we found one, return it
97
+ found_template
98
+ end
99
+
31
100
  # Custom error class for handling
32
101
  class TemplateNotFound < RuntimeError; end
33
102
 
@@ -132,14 +201,13 @@ module Middleman
132
201
  # Look for :layout of any extension
133
202
  # If found, use it. If not, continue
134
203
  locate_layout(:layout, layout_engine)
135
- else
204
+ elsif layout_file = locate_layout(local_layout, layout_engine)
136
205
  # Look for specific layout
137
206
  # If found, use it. If not, error.
138
- if layout_file = locate_layout(local_layout, layout_engine)
139
- layout_file
140
- else
141
- raise ::Middleman::TemplateRenderer::TemplateNotFound, "Could not locate layout: #{local_layout}"
142
- end
207
+
208
+ layout_file
209
+ else
210
+ raise ::Middleman::TemplateRenderer::TemplateNotFound, "Could not locate layout: #{local_layout}"
143
211
  end
144
212
  end
145
213
 
@@ -152,25 +220,6 @@ module Middleman
152
220
  self.class.locate_layout(@app, name, preferred_engine)
153
221
  end
154
222
 
155
- # Find a layout on-disk, optionally using a specific engine
156
- # @param [String] name
157
- # @param [Symbol] preferred_engine
158
- # @return [String]
159
- Contract IsA['Middleman::Application'], Or[String, Symbol], Symbol => Maybe[IsA['Middleman::SourceFile']]
160
- def self.locate_layout(app, name, preferred_engine=nil)
161
- resolve_opts = {}
162
- resolve_opts[:preferred_engine] = preferred_engine unless preferred_engine.nil?
163
-
164
- # Check layouts folder
165
- layout_file = resolve_template(app, File.join(app.config[:layouts_dir], name.to_s), resolve_opts)
166
-
167
- # If we didn't find it, check root
168
- layout_file = resolve_template(app, name, resolve_opts) unless layout_file
169
-
170
- # Return the path
171
- layout_file
172
- end
173
-
174
223
  # Find a template on disk given a output path
175
224
  # @param [String] request_path
176
225
  # @param [Hash] options
@@ -179,55 +228,5 @@ module Middleman
179
228
  def resolve_template(request_path, options={})
180
229
  self.class.resolve_template(@app, request_path, options)
181
230
  end
182
-
183
- # Find a template on disk given a output path
184
- # @param [String] request_path
185
- # @option options [Boolean] :preferred_engine If set, try this engine first, then fall back to any engine.
186
- # @return [String, Boolean] Either the path to the template, or false
187
- Contract IsA['Middleman::Application'], Or[Symbol, String], Maybe[Hash] => Maybe[IsA['Middleman::SourceFile']]
188
- def self.resolve_template(app, request_path, options={})
189
- # Find the path by searching
190
- relative_path = Util.strip_leading_slash(request_path.to_s)
191
-
192
- # By default, any engine will do
193
- preferred_engines = []
194
-
195
- # If we're specifically looking for a preferred engine
196
- if options.key?(:preferred_engine)
197
- extension_class = ::Tilt[options[:preferred_engine]]
198
-
199
- # Get a list of extensions for a preferred engine
200
- preferred_engines += ::Tilt.mappings.select do |_, engines|
201
- engines.include? extension_class
202
- end.keys
203
- end
204
-
205
- preferred_engines << '*'
206
- preferred_engines << nil if options[:try_static]
207
-
208
- found_template = nil
209
-
210
- preferred_engines.each do |preferred_engine|
211
- path_with_ext = relative_path.dup
212
- path_with_ext << ('.' + preferred_engine) unless preferred_engine.nil?
213
-
214
- globbing = preferred_engine == '*'
215
-
216
- # Cache lookups in build mode only
217
- file = if app.build?
218
- cache.fetch(path_with_ext, preferred_engine) do
219
- app.files.find(:source, path_with_ext, globbing)
220
- end
221
- else
222
- app.files.find(:source, path_with_ext, globbing)
223
- end
224
-
225
- found_template = file if file && (preferred_engine.nil? || ::Tilt[file[:full_path]])
226
- break if found_template
227
- end
228
-
229
- # If we found one, return it
230
- found_template
231
- end
232
231
  end
233
232
  end