nanoc3 3.2.0a1 → 3.2.0a2

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 (58) hide show
  1. data/ChangeLog +2 -2
  2. data/NEWS.md +14 -0
  3. data/README.md +20 -12
  4. data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
  5. data/lib/nanoc3/base/compilation/checksum_store.rb +130 -0
  6. data/lib/nanoc3/base/compilation/checksummer.rb +68 -0
  7. data/lib/nanoc3/base/compilation/compiled_content_cache.rb +57 -0
  8. data/lib/nanoc3/base/{compiler.rb → compilation/compiler.rb} +255 -55
  9. data/lib/nanoc3/base/{compiler_dsl.rb → compilation/compiler_dsl.rb} +11 -6
  10. data/lib/nanoc3/base/{dependency_tracker.rb → compilation/dependency_tracker.rb} +62 -92
  11. data/lib/nanoc3/base/{filter.rb → compilation/filter.rb} +0 -0
  12. data/lib/nanoc3/base/compilation/item_rep_proxy.rb +87 -0
  13. data/lib/nanoc3/base/compilation/outdatedness_checker.rb +86 -0
  14. data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +43 -0
  15. data/lib/nanoc3/base/{rule.rb → compilation/rule.rb} +8 -2
  16. data/lib/nanoc3/base/{rule_context.rb → compilation/rule_context.rb} +17 -14
  17. data/lib/nanoc3/base/directed_graph.rb +8 -0
  18. data/lib/nanoc3/base/errors.rb +9 -17
  19. data/lib/nanoc3/base/plugin_registry.rb +1 -1
  20. data/lib/nanoc3/base/result_data/item_rep.rb +447 -0
  21. data/lib/nanoc3/base/{code_snippet.rb → source_data/code_snippet.rb} +7 -22
  22. data/lib/nanoc3/base/{data_source.rb → source_data/data_source.rb} +0 -0
  23. data/lib/nanoc3/base/{item.rb → source_data/item.rb} +20 -30
  24. data/lib/nanoc3/base/{layout.rb → source_data/layout.rb} +7 -26
  25. data/lib/nanoc3/base/source_data/site.rb +314 -0
  26. data/lib/nanoc3/base/store.rb +126 -0
  27. data/lib/nanoc3/base.rb +26 -15
  28. data/lib/nanoc3/cli/base.rb +2 -1
  29. data/lib/nanoc3/cli/commands/compile.rb +116 -48
  30. data/lib/nanoc3/cli/commands/create_item.rb +0 -1
  31. data/lib/nanoc3/cli/commands/create_layout.rb +0 -1
  32. data/lib/nanoc3/cli/commands/create_site.rb +11 -1
  33. data/lib/nanoc3/cli/commands/debug.rb +11 -6
  34. data/lib/nanoc3/cli/commands/info.rb +1 -2
  35. data/lib/nanoc3/cli/commands/update.rb +0 -1
  36. data/lib/nanoc3/cli/commands/watch.rb +27 -32
  37. data/lib/nanoc3/cli/logger.rb +2 -2
  38. data/lib/nanoc3/data_sources/filesystem.rb +1 -6
  39. data/lib/nanoc3/extra/auto_compiler.rb +2 -3
  40. data/lib/nanoc3/extra/deployers/rsync.rb +1 -0
  41. data/lib/nanoc3/extra/validators/links.rb +45 -26
  42. data/lib/nanoc3/filters/asciidoc.rb +58 -0
  43. data/lib/nanoc3/filters/colorize_syntax.rb +47 -9
  44. data/lib/nanoc3/filters/less.rb +6 -0
  45. data/lib/nanoc3/filters/sass.rb +8 -5
  46. data/lib/nanoc3/filters.rb +2 -0
  47. data/lib/nanoc3/helpers/blogging.rb +8 -0
  48. data/lib/nanoc3/helpers/html_escape.rb +37 -7
  49. data/lib/nanoc3/helpers/link_to.rb +15 -4
  50. data/lib/nanoc3/helpers/rendering.rb +6 -2
  51. data/lib/nanoc3/tasks/clean.rb +0 -4
  52. data/lib/nanoc3.rb +1 -1
  53. data/nanoc3.gemspec +42 -0
  54. metadata +35 -19
  55. data/lib/nanoc3/base/checksummer.rb +0 -40
  56. data/lib/nanoc3/base/compiled_content_cache.rb +0 -86
  57. data/lib/nanoc3/base/item_rep.rb +0 -537
  58. data/lib/nanoc3/base/site.rb +0 -490
@@ -30,10 +30,18 @@ module Nanoc3
30
30
  # * `visit_ended` — indicates that the compiler has finished visiting the
31
31
  # item representation and that the requested attributes or content have
32
32
  # been fetched (either successfully or with failure)
33
+ #
34
+ # * `processing_started` — indicates that the compiler has started
35
+ # processing the specified object, which can be an item representation
36
+ # (when it is compiled) or a layout (when it is used to lay out an item
37
+ # representation or when it is used as a partial)
38
+ #
39
+ # * `processing_ended` — indicates that the compiler has finished processing
40
+ # the specified object.
33
41
  class Compiler
34
42
 
35
- # The name of the file where cached compiled content will be stored
36
- COMPILED_CONTENT_CACHE_FILENAME = 'tmp/compiled_content'
43
+ # @return [Nanoc3::Site] The site this compiler belongs to
44
+ attr_reader :site
37
45
 
38
46
  # The compilation stack. When the compiler begins compiling a rep or a
39
47
  # layout, it will be placed on the stack; when it is done compiling the
@@ -42,16 +50,12 @@ module Nanoc3
42
50
  # @return [Array] The compilation stack
43
51
  attr_reader :stack
44
52
 
45
- # The list of compilation rules that will be used to compile items. This
46
- # array will be filled by {Nanoc3::Site#load_data}.
47
- #
48
- # @return [Array<Nanoc3::Rule>] The list of item compilation rules
53
+ # @return [Array<Nanoc3::Rule>] The list of item compilation rules that
54
+ # will be used to compile items.
49
55
  attr_reader :item_compilation_rules
50
56
 
51
- # The list of routing rules that will be used to give all items a path.
52
- # This array will be filled by {Nanoc3::Site#load_data}.
53
- #
54
- # @return [Array<Nanoc3::Rule>] The list of item routing rules
57
+ # @return [Array<Nanoc3::Rule>] The list of routing rules that will be
58
+ # used to give all items a path.
55
59
  attr_reader :item_routing_rules
56
60
 
57
61
  # The hash containing layout-to-filter mapping rules. This hash is
@@ -60,6 +64,10 @@ module Nanoc3
60
64
  # @return [Hash] The layout-to-filter mapping rules
61
65
  attr_reader :layout_filter_mapping
62
66
 
67
+ # @return [Proc] The code block that will be executed after all data is
68
+ # loaded but before the site is compiled
69
+ attr_accessor :preprocessor
70
+
63
71
  # Creates a new compiler fo the given site
64
72
  #
65
73
  # @param [Nanoc3::Site] site The site this compiler belongs to
@@ -73,62 +81,81 @@ module Nanoc3
73
81
  @layout_filter_mapping = OrderedHash.new
74
82
  end
75
83
 
76
- # Compiles (part of) the site and writes out the compiled item
77
- # representations.
78
- #
79
- # @param [Nanoc3::Item] item The item that should be compiled, along with
80
- # its dependencies. Pass `nil` if the entire site should be compiled.
84
+ # Compiles the site and writes out the compiled item representations.
81
85
  #
82
- # @option params [Boolean] :force (false) true if the rep should be
83
- # compiled even if it is not outdated, false if not
86
+ # Previous versions of nanoc (< 3.2) allowed passing items to compile, and
87
+ # had a “force” option to make the compiler recompile all pages, even
88
+ # when not outdated. These arguments and options are, as of nanoc 3.2, no
89
+ # longer used, and will simply be ignored when passed to {#run}.
84
90
  #
85
- # @return [void]
86
- def run(item=nil, params={})
87
- # Parse params
88
- params[:force] = false if !params.has_key?(:force)
89
-
91
+ # @overload run
92
+ # @return [void]
93
+ def run(*args)
90
94
  # Create output directory if necessary
91
95
  FileUtils.mkdir_p(@site.config[:output_dir])
92
96
 
93
- # Load necessary data
94
- compiled_content_cache = CompiledContentCache.new(COMPILED_CONTENT_CACHE_FILENAME)
95
- compiled_content_cache.load
96
- dependency_tracker.load_graph
97
-
98
- # Get items and reps to compile
99
- items = item ? ([ item ] + dependency_tracker.successors_of(item)).uniq : @site.items
100
- reps = items.map { |i| i.reps }.flatten
101
-
102
- # Determine which reps need to be recompiled
103
- reps.each { |r| r.force_outdated = true } if params[:force]
104
- dependency_tracker.propagate_outdatedness
105
- forget_dependencies_if_outdated(items)
106
-
107
97
  # Compile reps
98
+ load
108
99
  dependency_tracker.start
109
100
  compile_reps(reps)
110
101
  dependency_tracker.stop
111
-
112
- # Store necessary data
113
- compiled_content_cache.store
114
- @site.store_checksums
115
- dependency_tracker.store_graph
102
+ store
116
103
  ensure
117
104
  # Cleanup
118
105
  FileUtils.rm_rf(Nanoc3::Filter::TMP_BINARY_ITEMS_DIR)
119
106
  end
120
107
 
108
+ # Load the helper data that is used for compiling the site.
109
+ #
110
+ # @api private
111
+ #
112
+ # @return [void]
113
+ def load
114
+ return if @loaded
115
+ @loaded = true
116
+
117
+ stores.each { |s| s.load }
118
+
119
+ # Preprocess
120
+ load_rules
121
+ preprocess
122
+ site.setup_child_parent_links
123
+ build_reps
124
+ route_reps
125
+
126
+ # Determine which reps need to be recompiled
127
+ dependency_tracker.propagate_outdatedness
128
+ forget_dependencies_if_outdated(items)
129
+ end
130
+
131
+ # Store the modified helper data used for compiling the site.
132
+ #
133
+ # @api private
134
+ #
135
+ # @return [void]
136
+ def store
137
+ stores.each { |s| s.store }
138
+ end
139
+
121
140
  # Returns the dependency tracker for this site, creating it first if it
122
141
  # does not yet exist.
123
- #
142
+ #
143
+ # @api private
144
+ #
124
145
  # @return [Nanoc3::DependencyTracker] The dependency tracker for this site
125
146
  def dependency_tracker
126
- @dependency_tracker ||= Nanoc3::DependencyTracker.new(@site.items + @site.layouts)
147
+ @dependency_tracker ||= begin
148
+ dt = Nanoc3::DependencyTracker.new(@site.items + @site.layouts)
149
+ dt.compiler = self
150
+ dt
151
+ end
127
152
  end
128
153
 
129
154
  # Finds the first matching compilation rule for the given item
130
155
  # representation.
131
156
  #
157
+ # @api private
158
+ #
132
159
  # @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
133
160
  #
134
161
  # @return [Nanoc3::Rule, nil] The compilation rule for the given item rep,
@@ -141,6 +168,8 @@ module Nanoc3
141
168
 
142
169
  # Finds the first matching routing rule for the given item representation.
143
170
  #
171
+ # @api private
172
+ #
144
173
  # @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
145
174
  #
146
175
  # @return [Nanoc3::Rule, nil] The routing rule for the given item rep, or
@@ -156,6 +185,8 @@ module Nanoc3
156
185
  # returned. The result is a hash containing the corresponding rule for
157
186
  # each snapshot.
158
187
  #
188
+ # @api private
189
+ #
159
190
  # @return [Hash<Symbol, Nanoc3::Rule>] The routing rules for the given rep
160
191
  def routing_rules_for(rep)
161
192
  rules = {}
@@ -171,6 +202,8 @@ module Nanoc3
171
202
 
172
203
  # Finds the filter name and arguments to use for the given layout.
173
204
  #
205
+ # @api private
206
+ #
174
207
  # @param [Nanoc3::Layout] layout The layout for which to fetch the filter.
175
208
  #
176
209
  # @return [Array, nil] A tuple containing the filter name and the filter
@@ -182,8 +215,146 @@ module Nanoc3
182
215
  nil
183
216
  end
184
217
 
218
+ # @api private
219
+ #
220
+ # @return [Boolean] true if the object is outdated, false otherwise
221
+ def outdated?(obj)
222
+ outdatedness_checker.outdated?(obj)
223
+ end
224
+
225
+ # Returns the reason why the given object is outdated.
226
+ #
227
+ # @see Nanoc3::OutdatednessChecker#outdatedness_reason_for
228
+ #
229
+ # @api private
230
+ def outdatedness_reason_for(obj)
231
+ outdatedness_checker.outdatedness_reason_for(obj)
232
+ end
233
+
234
+ # Returns the Nanoc3::CompilerDSL that should be used for this site.
235
+ #
236
+ # @api private
237
+ def dsl
238
+ @dsl ||= Nanoc3::CompilerDSL.new(self)
239
+ end
240
+
241
+ # Loads this site’s rules.
242
+ #
243
+ # @api private
244
+ def load_rules
245
+ # Find rules file
246
+ rules_filename = [ 'Rules', 'rules', 'Rules.rb', 'rules.rb' ].find { |f| File.file?(f) }
247
+ raise Nanoc3::Errors::NoRulesFileFound.new if rules_filename.nil?
248
+
249
+ # Get rule data
250
+ @rules = File.read(rules_filename)
251
+
252
+ # Load DSL
253
+ dsl.instance_eval(@rules, "./#{rules_filename}")
254
+ end
255
+
256
+ # Runs the preprocessor.
257
+ #
258
+ # @api private
259
+ def preprocess
260
+ preprocessor_context.instance_eval(&preprocessor) if preprocessor
261
+ end
262
+
263
+ # FIXME get rid of this
264
+ #
265
+ # @api private
266
+ def rules_with_reference
267
+ rules = @rules
268
+ @rules_pseudo ||= begin
269
+ pseudo = Object.new
270
+ pseudo.instance_eval { @data = rules }
271
+ def pseudo.reference ; :rules ; end
272
+ def pseudo.data ; @data.inspect ; end
273
+ pseudo
274
+ end
275
+ end
276
+
277
+ # Creates the representations of all items as defined by the compilation
278
+ # rules.
279
+ #
280
+ # @api private
281
+ def build_reps
282
+ @site.items.each do |item|
283
+ # Find matching rules
284
+ matching_rules = item_compilation_rules.select { |r| r.applicable_to?(item) }
285
+ raise Nanoc3::Errors::NoMatchingCompilationRuleFound.new(item) if matching_rules.empty?
286
+
287
+ # Create reps
288
+ rep_names = matching_rules.map { |r| r.rep_name }.uniq
289
+ rep_names.each do |rep_name|
290
+ item.reps << ItemRep.new(item, rep_name)
291
+ end
292
+ end
293
+ end
294
+
295
+ # Determines the paths of all item representations.
296
+ #
297
+ # @api private
298
+ def route_reps
299
+ reps = @site.items.map { |i| i.reps }.flatten
300
+ reps.each do |rep|
301
+ # Find matching rules
302
+ rules = routing_rules_for(rep)
303
+ raise Nanoc3::Errors::NoMatchingRoutingRuleFound.new(rep) if rules[:last].nil?
304
+
305
+ rules.each_pair do |snapshot, rule|
306
+ # Get basic path by applying matching rule
307
+ basic_path = rule.apply_to(rep, :compiler => self)
308
+ next if basic_path.nil?
309
+
310
+ # Get raw path by prepending output directory
311
+ rep.raw_paths[snapshot] = @site.config[:output_dir] + basic_path
312
+
313
+ # Get normal path by stripping index filename
314
+ rep.paths[snapshot] = basic_path
315
+ @site.config[:index_filenames].each do |index_filename|
316
+ if rep.paths[snapshot][-index_filename.length..-1] == index_filename
317
+ # Strip and stop
318
+ rep.paths[snapshot] = rep.paths[snapshot][0..-index_filename.length-1]
319
+ break
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
325
+
326
+ # @param [Nanoc3::ItemRep] rep The item representation for which the
327
+ # assigns should be fetched
328
+ #
329
+ # @return [Hash] The assigns that should be used in the next filter/layout
330
+ # operation
331
+ def assigns_for(rep)
332
+ if rep.binary?
333
+ content_or_filename_assigns = { :filename => rep.filenames[:last] }
334
+ else
335
+ content_or_filename_assigns = { :content => rep.content[:last] }
336
+ end
337
+
338
+ content_or_filename_assigns.merge({
339
+ :item => rep.item,
340
+ :item_rep => rep,
341
+ :items => site.items,
342
+ :layouts => site.layouts,
343
+ :config => site.config,
344
+ :site => site
345
+ })
346
+ end
347
+
185
348
  private
186
349
 
350
+ def items
351
+ @items ||= @site.items
352
+ end
353
+
354
+ def reps
355
+ @reps ||= items.map { |i| i.reps }.flatten
356
+ end
357
+
187
358
  # Compiles the given representations.
188
359
  #
189
360
  # @param [Array] reps The item representations to compile.
@@ -196,19 +367,23 @@ module Nanoc3
196
367
  outdated_reps = Set.new
197
368
  skipped_reps = Set.new
198
369
  reps.each do |rep|
199
- target = (rep.outdated? || rep.item.outdated_due_to_dependencies?) ? outdated_reps : skipped_reps
370
+ target = (outdated?(rep) || dependency_tracker.outdated_due_to_dependencies?(rep.item)) ? outdated_reps : skipped_reps
200
371
  target.add(rep)
201
372
  end
202
373
 
203
374
  # Build graph for outdated reps
204
375
  content_dependency_graph = Nanoc3::DirectedGraph.new(outdated_reps)
205
376
 
377
+ # Listen to processing start/stop
378
+ Nanoc3::NotificationCenter.on(:processing_started, self) { |obj| @stack.push(obj) }
379
+ Nanoc3::NotificationCenter.on(:processing_ended, self) { |obj| @stack.pop }
380
+
206
381
  # Attempt to compile all active reps
207
382
  loop do
208
383
  # Find rep to compile
209
384
  break if content_dependency_graph.roots.empty?
210
385
  rep = content_dependency_graph.roots.each { |e| break e }
211
- @stack = [ rep ]
386
+ @stack = []
212
387
 
213
388
  begin
214
389
  compile_rep(rep)
@@ -226,6 +401,9 @@ module Nanoc3
226
401
  if !content_dependency_graph.vertices.empty?
227
402
  raise Nanoc3::Errors::RecursiveCompilation.new(content_dependency_graph.vertices)
228
403
  end
404
+ ensure
405
+ Nanoc3::NotificationCenter.remove(:processing_started, self)
406
+ Nanoc3::NotificationCenter.remove(:processing_ended, self)
229
407
  end
230
408
 
231
409
  # Compiles the given item representation.
@@ -239,15 +417,16 @@ module Nanoc3
239
417
  # @return [void]
240
418
  def compile_rep(rep)
241
419
  Nanoc3::NotificationCenter.post(:compilation_started, rep)
420
+ Nanoc3::NotificationCenter.post(:processing_started, rep)
242
421
  Nanoc3::NotificationCenter.post(:visit_started, rep.item)
243
422
 
244
- if !rep.outdated? && !rep.item.outdated_due_to_dependencies && compiled_content_cache[rep]
423
+ if !outdated?(rep) && !dependency_tracker.outdated_due_to_dependencies?(rep.item) && compiled_content_cache[rep]
245
424
  Nanoc3::NotificationCenter.post(:cached_content_used, rep)
246
425
  rep.content = compiled_content_cache[rep]
247
426
  else
248
427
  rep.snapshot(:raw)
249
428
  rep.snapshot(:pre, :final => false)
250
- compilation_rule_for(rep).apply_to(rep)
429
+ compilation_rule_for(rep).apply_to(rep, :compiler => self)
251
430
  rep.snapshot(:post) if rep.has_snapshot?(:post)
252
431
  rep.snapshot(:last)
253
432
  end
@@ -260,6 +439,7 @@ module Nanoc3
260
439
  raise e
261
440
  ensure
262
441
  Nanoc3::NotificationCenter.post(:visit_ended, rep.item)
442
+ Nanoc3::NotificationCenter.post(:processing_ended, rep)
263
443
  Nanoc3::NotificationCenter.post(:compilation_ended, rep)
264
444
  end
265
445
 
@@ -271,21 +451,41 @@ module Nanoc3
271
451
  # @return [void]
272
452
  def forget_dependencies_if_outdated(items)
273
453
  items.each do |i|
274
- if i.outdated? || i.outdated_due_to_dependencies?
454
+ if i.reps.any? { |r| outdated?(r) } || dependency_tracker.outdated_due_to_dependencies?(i)
275
455
  dependency_tracker.forget_dependencies_for(i)
276
456
  end
277
457
  end
278
458
  end
279
459
 
280
- # Returns the cache used for storing compiled content.
281
- #
460
+ # Returns a preprocessor context, creating one if none exists yet.
461
+ def preprocessor_context
462
+ @preprocessor_context ||= Nanoc3::Context.new({
463
+ :site => @site,
464
+ :config => @site.config,
465
+ :items => @site.items,
466
+ :layouts => @site.layouts
467
+ })
468
+ end
469
+
282
470
  # @return [CompiledContentCache] The compiled content cache
283
471
  def compiled_content_cache
284
- @compiled_content_cache ||= begin
285
- cache = Nanoc3::CompiledContentCache.new(COMPILED_CONTENT_CACHE_FILENAME)
286
- cache.load
287
- cache
288
- end
472
+ @compiled_content_cache ||= Nanoc3::CompiledContentCache.new
473
+ end
474
+
475
+ # @return [ChecksumStore] The checksum store
476
+ def checksum_store
477
+ @checksum_store ||= Nanoc3::ChecksumStore.new(:site => @site)
478
+ end
479
+
480
+ # @return [Nanoc3::OutdatednessChecker] The outdatedness checker
481
+ def outdatedness_checker
482
+ @outdatedness_checker ||= Nanoc3::OutdatednessChecker.new(:site => @site, :checksum_store => checksum_store)
483
+ end
484
+
485
+ # Returns all stores that can load/store data that can be used for
486
+ # compilation.
487
+ def stores
488
+ [ compiled_content_cache, checksum_store, dependency_tracker ]
289
489
  end
290
490
 
291
491
  end
@@ -5,11 +5,16 @@ module Nanoc3
5
5
  # Contains methods that will be executed by the site’s `Rules` file.
6
6
  class CompilerDSL
7
7
 
8
+ # @return [Nanoc3::Compiler] The compiler where this DSL belongs to.
9
+ attr_reader :compiler
10
+
8
11
  # Creates a new compiler DSL for the given compiler.
9
12
  #
13
+ # @api private
14
+ #
10
15
  # @param [Nanoc3::Site] site The site this DSL belongs to
11
- def initialize(site)
12
- @site = site
16
+ def initialize(compiler)
17
+ @compiler = compiler
13
18
  end
14
19
 
15
20
  # Creates a preprocessor block that will be executed after all data is
@@ -19,7 +24,7 @@ module Nanoc3
19
24
  #
20
25
  # @return [void]
21
26
  def preprocess(&block)
22
- @site.preprocessor = block
27
+ compiler.preprocessor = block
23
28
  end
24
29
 
25
30
  # Creates a compilation rule for all items whose identifier match the
@@ -63,7 +68,7 @@ module Nanoc3
63
68
 
64
69
  # Create rule
65
70
  rule = Rule.new(identifier_to_regex(identifier), rep_name, block)
66
- @site.compiler.item_compilation_rules << rule
71
+ compiler.item_compilation_rules << rule
67
72
  end
68
73
 
69
74
  # Creates a routing rule for all items whose identifier match the
@@ -108,7 +113,7 @@ module Nanoc3
108
113
 
109
114
  # Create rule
110
115
  rule = Rule.new(identifier_to_regex(identifier), rep_name, block, :snapshot_name => snapshot_name)
111
- @site.compiler.item_routing_rules << rule
116
+ compiler.item_routing_rules << rule
112
117
  end
113
118
 
114
119
  # Creates a layout rule for all layouts whose identifier match the given
@@ -136,7 +141,7 @@ module Nanoc3
136
141
  #
137
142
  # layout '/custom/', :haml, :format => :html5
138
143
  def layout(identifier, filter_name, params={})
139
- @site.compiler.layout_filter_mapping[identifier_to_regex(identifier)] = [ filter_name, params ]
144
+ compiler.layout_filter_mapping[identifier_to_regex(identifier)] = [ filter_name, params ]
140
145
  end
141
146
 
142
147
  private