nanoc 4.1.6 → 4.2.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -1
  4. data/NEWS.md +11 -4
  5. data/lib/nanoc/base/checksummer.rb +135 -46
  6. data/lib/nanoc/base/compilation/compiler.rb +18 -28
  7. data/lib/nanoc/base/compilation/dependency_tracker.rb +22 -32
  8. data/lib/nanoc/base/compilation/filter.rb +2 -4
  9. data/lib/nanoc/base/entities.rb +1 -0
  10. data/lib/nanoc/base/entities/content.rb +14 -3
  11. data/lib/nanoc/base/entities/document.rb +14 -6
  12. data/lib/nanoc/base/entities/item.rb +0 -31
  13. data/lib/nanoc/base/entities/item_rep.rb +1 -1
  14. data/lib/nanoc/base/entities/lazy_value.rb +36 -0
  15. data/lib/nanoc/base/entities/pattern.rb +3 -2
  16. data/lib/nanoc/base/entities/site.rb +2 -0
  17. data/lib/nanoc/base/memoization.rb +17 -10
  18. data/lib/nanoc/base/repos/compiled_content_cache.rb +1 -1
  19. data/lib/nanoc/base/repos/data_source.rb +10 -6
  20. data/lib/nanoc/base/services/executor.rb +22 -22
  21. data/lib/nanoc/base/services/item_rep_router.rb +4 -5
  22. data/lib/nanoc/base/views.rb +0 -1
  23. data/lib/nanoc/base/views/item_rep_view.rb +3 -9
  24. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +4 -11
  25. data/lib/nanoc/base/views/view.rb +1 -0
  26. data/lib/nanoc/base/views/view_context.rb +5 -1
  27. data/lib/nanoc/cli/commands/compile.rb +0 -6
  28. data/lib/nanoc/data_sources.rb +5 -5
  29. data/lib/nanoc/data_sources/filesystem.rb +219 -90
  30. data/lib/nanoc/extra/checking/check.rb +1 -2
  31. data/lib/nanoc/extra/checking/checks.rb +2 -0
  32. data/lib/nanoc/extra/checking/checks/css.rb +6 -14
  33. data/lib/nanoc/extra/checking/checks/html.rb +6 -14
  34. data/lib/nanoc/extra/checking/checks/internal_links.rb +14 -3
  35. data/lib/nanoc/extra/checking/checks/w3c_validator.rb +28 -0
  36. data/lib/nanoc/extra/deployers/fog.rb +134 -78
  37. data/lib/nanoc/extra/link_collector.rb +14 -18
  38. data/lib/nanoc/filters/sass.rb +3 -3
  39. data/lib/nanoc/helpers.rb +1 -0
  40. data/lib/nanoc/helpers/capturing.rb +16 -58
  41. data/lib/nanoc/helpers/child_parent.rb +51 -0
  42. data/lib/nanoc/helpers/filtering.rb +0 -1
  43. data/lib/nanoc/helpers/html_escape.rb +5 -0
  44. data/lib/nanoc/helpers/link_to.rb +2 -0
  45. data/lib/nanoc/helpers/rendering.rb +3 -4
  46. data/lib/nanoc/rule_dsl/action_provider.rb +20 -4
  47. data/lib/nanoc/rule_dsl/recording_executor.rb +3 -1
  48. data/lib/nanoc/rule_dsl/rule_context.rb +0 -1
  49. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +4 -1
  50. data/lib/nanoc/spec.rb +217 -0
  51. data/lib/nanoc/version.rb +1 -1
  52. data/test/base/test_data_source.rb +4 -2
  53. data/test/base/test_dependency_tracker.rb +5 -11
  54. data/test/data_sources/test_filesystem.rb +605 -69
  55. data/test/extra/checking/checks/test_internal_links.rb +25 -0
  56. data/test/extra/deployers/test_fog.rb +0 -177
  57. data/test/filters/test_less.rb +9 -4
  58. data/test/helpers/test_capturing.rb +38 -212
  59. data/test/helpers/test_link_to.rb +0 -205
  60. data/test/helpers/test_xml_sitemap.rb +2 -1
  61. metadata +7 -12
  62. data/lib/nanoc/base/views/site_view.rb +0 -14
  63. data/lib/nanoc/data_sources/filesystem_unified.rb +0 -101
  64. data/test/data_sources/test_filesystem_unified.rb +0 -559
  65. data/test/helpers/test_breadcrumbs.rb +0 -60
  66. data/test/helpers/test_filtering.rb +0 -112
  67. data/test/helpers/test_html_escape.rb +0 -26
  68. data/test/helpers/test_rendering.rb +0 -147
  69. data/test/helpers/test_tagging.rb +0 -92
  70. data/test/helpers/test_text.rb +0 -18
@@ -2,6 +2,7 @@ module Nanoc::Helpers
2
2
  autoload 'Blogging', 'nanoc/helpers/blogging'
3
3
  autoload 'Breadcrumbs', 'nanoc/helpers/breadcrumbs'
4
4
  autoload 'Capturing', 'nanoc/helpers/capturing'
5
+ autoload 'ChildParent', 'nanoc/helpers/child_parent'
5
6
  autoload 'Filtering', 'nanoc/helpers/filtering'
6
7
  autoload 'HTMLEscape', 'nanoc/helpers/html_escape'
7
8
  autoload 'LinkTo', 'nanoc/helpers/link_to'
@@ -25,40 +25,6 @@ module Nanoc::Helpers
25
25
  # <%= content_for(@item, :summary) || '(no summary)' %>
26
26
  # </div>
27
27
  module Capturing
28
- # @api private
29
- class CapturesStore
30
- def initialize
31
- @store = {}
32
- end
33
-
34
- def []=(item, name, content)
35
- @store[item.identifier] ||= {}
36
- @store[item.identifier][name] = content
37
- end
38
-
39
- def [](item, name)
40
- @store[item.identifier] ||= {}
41
- @store[item.identifier][name]
42
- end
43
-
44
- def reset_for(item)
45
- @store[item.identifier] = {}
46
- end
47
- end
48
-
49
- class ::Nanoc::Int::Site
50
- # @api private
51
- def captures_store
52
- @captures_store ||= CapturesStore.new
53
- end
54
-
55
- # @api private
56
- def captures_store_compiled_items
57
- require 'set'
58
- @captures_store_compiled_items ||= Set.new
59
- end
60
- end
61
-
62
28
  # @overload content_for(name, params = {}, &block)
63
29
  #
64
30
  # Captures the content inside the block and stores it so that it can be
@@ -114,17 +80,19 @@ module Nanoc::Helpers
114
80
  content = capture(&block)
115
81
 
116
82
  # Prepare for store
117
- store = @site.unwrap.captures_store
83
+ snapshot_contents = @item.reps[:default].unwrap.snapshot_contents
84
+ capture_name = "__capture_#{name}".to_sym
118
85
  case existing_behavior
119
86
  when :overwrite
120
- store[@item, name.to_sym] = ''
87
+ snapshot_contents[capture_name] = ''
121
88
  when :append
122
- store[@item, name.to_sym] ||= ''
89
+ snapshot_contents[capture_name] ||= ''
123
90
  when :error
124
- if store[@item, name.to_sym] && store[@item, name.to_sym] != content
91
+ if snapshot_contents[capture_name] && snapshot_contents[capture_name] != content
92
+ # FIXME: get proper exception
125
93
  raise "a capture named #{name.inspect} for #{@item.identifier} already exists"
126
94
  else
127
- store[@item, name.to_sym] = ''
95
+ snapshot_contents[capture_name] = ''
128
96
  end
129
97
  else
130
98
  raise ArgumentError, 'expected :existing_behavior param to #content_for to be one of ' \
@@ -132,38 +100,28 @@ module Nanoc::Helpers
132
100
  end
133
101
 
134
102
  # Store
135
- @site.unwrap.captures_store_compiled_items << @item.unwrap
136
- store[@item, name.to_sym] << content
103
+ snapshot_contents[capture_name] << content
137
104
  else # Get content
138
- # Get args
139
105
  if args.size != 2
140
106
  raise ArgumentError, 'expected 2 arguments (the item ' \
141
107
  "and the name of the capture) but got #{args.size} instead"
142
108
  end
143
- item = args[0].is_a?(Nanoc::ItemWithRepsView) ? args[0].unwrap : args[0]
109
+ item = args[0]
144
110
  name = args[1]
145
111
 
112
+ rep = item.reps[:default].unwrap
113
+
146
114
  # Create dependency
147
115
  if @item.nil? || item != @item.unwrap
148
- Nanoc::Int::NotificationCenter.post(:visit_started, item)
149
- Nanoc::Int::NotificationCenter.post(:visit_ended, item)
116
+ dependency_tracker = @config._context.dependency_tracker
117
+ dependency_tracker.bounce(item.unwrap)
150
118
 
151
- # This is an extremely ugly hack to get the compiler to recompile the
152
- # item from which we use content. For this, we need to manually edit
153
- # the content attribute to reset it. :(
154
- # FIXME: clean this up
155
- unless @site.unwrap.captures_store_compiled_items.include?(item)
156
- @site.unwrap.captures_store.reset_for(item)
157
- item.forced_outdated = true
158
- @site.unwrap.compiler.reps[item].each do |r|
159
- r.snapshot_contents = { last: item.content }
160
- raise Nanoc::Int::Errors::UnmetDependency.new(r)
161
- end
119
+ unless rep.compiled?
120
+ raise Nanoc::Int::Errors::UnmetDependency.new(rep)
162
121
  end
163
122
  end
164
123
 
165
- # Get content
166
- @site.unwrap.captures_store[item, name.to_sym]
124
+ rep.snapshot_contents["__capture_#{name}".to_sym]
167
125
  end
168
126
  end
169
127
 
@@ -0,0 +1,51 @@
1
+ module Nanoc::Helpers
2
+ # Provides functionality for fetching the children and the parent of a given
3
+ # item. This works for both full identifiers and legacy identifiers.
4
+ module ChildParent
5
+ # Returns the parent of the given item.
6
+ #
7
+ # For items with legacy identifiers, the parent is the item where the
8
+ # identifier contains one less component than the identifier of the given
9
+ # item. For # example, the parent of the “/projects/nanoc/” item is the
10
+ # “/projects/” item.
11
+ #
12
+ # For items with full identifiers, the parent is the item where the
13
+ # identifier contains one less component than the identifier of the given
14
+ # item, and ends with any extension. For example, the parent of the
15
+ # “/projects/nanoc.md” item could be the “/projects.md” item, or the
16
+ # “/projects.html” item, etc. Note that the parent is ambiguous for items
17
+ # that have a full identifier; only the first candidate parent item will be
18
+ # returned.
19
+ def parent_of(item)
20
+ if item.identifier.legacy?
21
+ item.parent
22
+ else
23
+ path_without_last_component = item.identifier.to_s.sub(/[^\/]+$/, '').chop
24
+ @items[path_without_last_component + '.*']
25
+ end
26
+ end
27
+
28
+ # Returns the children of the given item.
29
+ #
30
+ # For items with legacy identifiers, the children are the items where the
31
+ # identifier contains one more component than the identifier of the given
32
+ # item. For example, the children of the “/projects/” item could be
33
+ # “/projects/nanoc/” and “/projects/cri/”, but not “/about/” nor
34
+ # “/projects/nanoc/history/”.
35
+ #
36
+ # For items with full identifiers, the children are the item where the
37
+ # identifier starts with the identifier of the given item, minus the
38
+ # extension, followed by a slash. For example, the children of the
39
+ # “/projects.md” item could be the “/projects/nanoc.md” and
40
+ # “/projects/cri.adoc” items , but not “/about.md” nor
41
+ # “/projects/nanoc/history.md”.
42
+ def children_of(item)
43
+ if item.identifier.legacy?
44
+ item.children
45
+ else
46
+ pattern = item.identifier.without_ext + '/*'
47
+ @items.find_all(pattern)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -40,7 +40,6 @@ module Nanoc::Helpers
40
40
  items: @items,
41
41
  layouts: @layouts,
42
42
  config: @config,
43
- site: @site,
44
43
  content: @content,
45
44
  }
46
45
  filter = klass.new(assigns)
@@ -34,6 +34,11 @@ module Nanoc::Helpers
34
34
  buffer = eval('_erbout', block.binding)
35
35
  buffer << escaped_data
36
36
  elsif string
37
+ unless string.is_a? String
38
+ raise ArgumentError, 'The #html_escape or #h function needs either a ' \
39
+ "string or a block to HTML-escape, but #{string.class} was given"
40
+ end
41
+
37
42
  string
38
43
  .gsub('&', '&amp;')
39
44
  .gsub('<', '&lt;')
@@ -122,6 +122,7 @@ module Nanoc::Helpers
122
122
  else
123
123
  path = target.path
124
124
  if path.nil?
125
+ # TODO: get proper error
125
126
  raise "Cannot get the relative path to #{target.inspect} because this target is not outputted (its routing rule returns nil)"
126
127
  end
127
128
  end
@@ -134,6 +135,7 @@ module Nanoc::Helpers
134
135
  # Get source and destination paths
135
136
  dst_path = Pathname.new(path)
136
137
  if @item_rep.path.nil?
138
+ # TODO: get proper error
137
139
  raise "Cannot get the relative path to #{path} because the current item representation, #{@item_rep.inspect}, is not outputted (its routing rule returns nil)"
138
140
  end
139
141
  src_path = Pathname.new(@item_rep.path)
@@ -80,8 +80,8 @@ module Nanoc::Helpers
80
80
  raise Nanoc::Int::Errors::UnknownLayout.new(identifier) if layout.nil?
81
81
 
82
82
  # Visit
83
- Nanoc::Int::NotificationCenter.post(:visit_started, layout)
84
- Nanoc::Int::NotificationCenter.post(:visit_ended, layout)
83
+ dependency_tracker = @config._context.dependency_tracker
84
+ dependency_tracker.bounce(layout)
85
85
 
86
86
  # Capture content, if any
87
87
  captured_content = block_given? ? capture(&block) : nil
@@ -95,11 +95,10 @@ module Nanoc::Helpers
95
95
  layout: layout,
96
96
  layouts: @layouts,
97
97
  config: @config,
98
- site: @site,
99
98
  }.merge(other_assigns)
100
99
 
101
100
  # Get filter name
102
- filter_name, filter_args = *@site.unwrap.compiler.filter_name_and_args_for_layout(layout)
101
+ filter_name, filter_args = *@config._context.compiler.filter_name_and_args_for_layout(layout)
103
102
  raise Nanoc::Int::Errors::CannotDetermineFilter.new(layout.identifier) if filter_name.nil?
104
103
 
105
104
  # Get filter class
@@ -48,7 +48,14 @@ module Nanoc::RuleDSL
48
48
  end
49
49
 
50
50
  def postprocess(site, reps)
51
- view_context = Nanoc::ViewContext.new(reps: reps, items: site.items)
51
+ dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
52
+ view_context =
53
+ Nanoc::ViewContext.new(
54
+ reps: reps,
55
+ items: site.items,
56
+ dependency_tracker: dependency_tracker,
57
+ compiler: site.compiler,
58
+ )
52
59
  ctx = new_postprocessor_context(site, view_context)
53
60
 
54
61
  @rules_collection.postprocessors.each_value do |postprocessor|
@@ -58,10 +65,19 @@ module Nanoc::RuleDSL
58
65
 
59
66
  # @api private
60
67
  def new_preprocessor_context(site)
68
+ dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
69
+ view_context =
70
+ Nanoc::ViewContext.new(
71
+ reps: nil,
72
+ items: nil,
73
+ dependency_tracker: dependency_tracker,
74
+ compiler: nil,
75
+ )
76
+
61
77
  Nanoc::Int::Context.new(
62
- config: Nanoc::MutableConfigView.new(site.config, nil),
63
- items: Nanoc::MutableItemCollectionView.new(site.items, nil),
64
- layouts: Nanoc::MutableLayoutCollectionView.new(site.layouts, nil),
78
+ config: Nanoc::MutableConfigView.new(site.config, view_context),
79
+ items: Nanoc::MutableItemCollectionView.new(site.items, view_context),
80
+ layouts: Nanoc::MutableLayoutCollectionView.new(site.layouts, view_context),
65
81
  )
66
82
  end
67
83
 
@@ -39,7 +39,9 @@ module Nanoc
39
39
  routing_rule = routing_rules[snapshot_name]
40
40
  return nil if routing_rule.nil?
41
41
 
42
- basic_path = routing_rule.apply_to(rep, executor: nil, site: @site, view_context: nil)
42
+ dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
43
+ view_context = Nanoc::ViewContext.new(reps: nil, items: nil, dependency_tracker: dependency_tracker, compiler: nil)
44
+ basic_path = routing_rule.apply_to(rep, executor: nil, site: @site, view_context: view_context)
43
45
  if basic_path && !basic_path.start_with?('/')
44
46
  raise PathWithoutInitialSlashError.new(rep, basic_path)
45
47
  end
@@ -19,7 +19,6 @@ module Nanoc::RuleDSL
19
19
  items: Nanoc::ItemCollectionWithoutRepsView.new(site.items, view_context),
20
20
  layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context),
21
21
  config: Nanoc::ConfigView.new(site.config, view_context),
22
- site: Nanoc::SiteView.new(site, view_context),
23
22
  })
24
23
  end
25
24
 
@@ -59,12 +59,15 @@ module Nanoc::RuleDSL
59
59
  def new_rule_memory_for_rep(rep)
60
60
  # FIXME: What if #compilation_rule_for returns nil?
61
61
 
62
+ dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
63
+ view_context = @site.compiler.create_view_context(dependency_tracker)
64
+
62
65
  executor = Nanoc::RuleDSL::RecordingExecutor.new(rep, @rules_collection, @site)
63
66
  rule = @rules_collection.compilation_rule_for(rep)
64
67
 
65
68
  executor.snapshot(rep, :raw)
66
69
  executor.snapshot(rep, :pre, final: false)
67
- rule.apply_to(rep, executor: executor, site: @site, view_context: nil)
70
+ rule.apply_to(rep, executor: executor, site: @site, view_context: view_context)
68
71
  if executor.rule_memory.any_layouts?
69
72
  executor.snapshot(rep, :post)
70
73
  end
@@ -0,0 +1,217 @@
1
+ module Nanoc
2
+ # @api private
3
+ module Spec
4
+ class HelperContext
5
+ # @return [Nanoc::Int::DependencyTracker]
6
+ attr_reader :dependency_tracker
7
+
8
+ attr_reader :erbout
9
+
10
+ # @param [Module] mod The helper module to create a context for
11
+ def initialize(mod)
12
+ @mod = mod
13
+
14
+ @erbout = ''
15
+ @rule_memory = {}
16
+ @config = Nanoc::Int::Configuration.new.with_defaults
17
+ @reps = Nanoc::Int::ItemRepRepo.new
18
+ @items = Nanoc::Int::IdentifiableCollection.new(@config)
19
+ @layouts = Nanoc::Int::IdentifiableCollection.new(@config)
20
+ @dependency_tracker = Nanoc::Int::DependencyTracker.new(Object.new)
21
+ end
22
+
23
+ # Creates a new item and adds it to the site’s collection of items.
24
+ #
25
+ # @param [String] content The uncompiled item content
26
+ #
27
+ # @param [Hash] attributes A hash containing this item's attributes
28
+ #
29
+ # @param [Nanoc::Identifier, String] identifier This item's identifier
30
+ #
31
+ # @return [Nanoc::ItemWithRepsView] A view for the newly created item
32
+ def create_item(content, attributes, identifier)
33
+ item = Nanoc::Int::Item.new(content, attributes, identifier)
34
+ @items << item
35
+ Nanoc::ItemWithRepsView.new(item, view_context)
36
+ end
37
+
38
+ # TODO: document
39
+ def create_layout(content, attributes, identifier)
40
+ layout = Nanoc::Int::Layout.new(content, attributes, identifier)
41
+ @layouts << layout
42
+ Nanoc::LayoutView.new(layout, view_context)
43
+ end
44
+
45
+ # Creates a new representation for the given item.
46
+ #
47
+ # @param [Nanoc::ItemWithRepsView] item The item to create a represetation for
48
+ #
49
+ # @param [String] path The path of the `:last` snapshot of this item representation
50
+ def create_rep(item, path)
51
+ rep = Nanoc::Int::ItemRep.new(item.unwrap, :default)
52
+ rep.paths[:last] = path
53
+ @reps << rep
54
+ Nanoc::ItemRepView.new(rep, view_context)
55
+ end
56
+
57
+ # @return [Object] An object that includes the helper functions
58
+ def helper
59
+ mod = @mod
60
+ klass = Class.new(Nanoc::Int::Context) { include mod }
61
+ klass.new(assigns)
62
+ end
63
+
64
+ def item=(item)
65
+ @item = item ? item.unwrap : nil
66
+ end
67
+
68
+ def item_rep=(item_rep)
69
+ @item_rep = item_rep ? item_rep.unwrap : nil
70
+ end
71
+
72
+ # @return [Nanoc::MutableConfigView]
73
+ def config
74
+ assigns[:config]
75
+ end
76
+
77
+ # @return [Nanoc::ItemWithRepsView, nil]
78
+ def item
79
+ assigns[:item]
80
+ end
81
+
82
+ # @return [Nanoc::ItemRepView, nil]
83
+ def item_rep
84
+ assigns[:item_rep]
85
+ end
86
+
87
+ # @return [Nanoc::ItemCollectionWithRepsView]
88
+ def items
89
+ assigns[:items]
90
+ end
91
+
92
+ # @return [Nanoc::LayoutCollectionView]
93
+ def layouts
94
+ assigns[:layouts]
95
+ end
96
+
97
+ def rule_memory_for(obj)
98
+ @rule_memory.fetch(obj, [])
99
+ end
100
+
101
+ def update_rule_memory(obj, memory)
102
+ @rule_memory[obj] = memory
103
+ end
104
+
105
+ private
106
+
107
+ def view_context
108
+ Nanoc::ViewContext.new(
109
+ reps: @reps,
110
+ items: @items,
111
+ dependency_tracker: @dependency_tracker,
112
+ compiler: new_site.compiler,
113
+ )
114
+ end
115
+
116
+ def new_action_provider
117
+ Class.new(Nanoc::Int::ActionProvider) do
118
+ def self.for(_context)
119
+ raise NotImplementedError
120
+ end
121
+
122
+ def initialize(context)
123
+ @context = context
124
+ end
125
+
126
+ def rep_names_for(_item)
127
+ [:default]
128
+ end
129
+
130
+ def memory_for(obj)
131
+ @context.rule_memory_for(obj)
132
+ end
133
+
134
+ def snapshots_defs_for(_rep)
135
+ [Nanoc::Int::SnapshotDef.new(:last, false)]
136
+ end
137
+ end.new(self)
138
+ end
139
+
140
+ def new_compiler_for(site)
141
+ rule_memory_store = Nanoc::Int::RuleMemoryStore.new
142
+
143
+ dependency_store =
144
+ Nanoc::Int::DependencyStore.new(site.items.to_a + site.layouts.to_a)
145
+
146
+ checksum_store =
147
+ Nanoc::Int::ChecksumStore.new(site: site)
148
+
149
+ item_rep_repo = Nanoc::Int::ItemRepRepo.new
150
+
151
+ action_provider = new_action_provider
152
+
153
+ outdatedness_checker =
154
+ Nanoc::Int::OutdatednessChecker.new(
155
+ site: site,
156
+ checksum_store: checksum_store,
157
+ dependency_store: dependency_store,
158
+ rule_memory_store: rule_memory_store,
159
+ action_provider: action_provider,
160
+ reps: item_rep_repo,
161
+ )
162
+
163
+ params = {
164
+ compiled_content_cache: Nanoc::Int::CompiledContentCache.new,
165
+ checksum_store: checksum_store,
166
+ rule_memory_store: rule_memory_store,
167
+ dependency_store: dependency_store,
168
+ outdatedness_checker: outdatedness_checker,
169
+ reps: item_rep_repo,
170
+ action_provider: action_provider,
171
+ }
172
+
173
+ Nanoc::Int::Compiler.new(site, params)
174
+ end
175
+
176
+ def new_site
177
+ site = Nanoc::Int::Site.new(
178
+ config: @config,
179
+ code_snippets: [],
180
+ items: @items,
181
+ layouts: @layouts,
182
+ )
183
+ site.compiler = new_compiler_for(site)
184
+ site
185
+ end
186
+
187
+ def assigns
188
+ site = Nanoc::Int::Site.new(
189
+ config: @config,
190
+ code_snippets: [],
191
+ items: @items,
192
+ layouts: @layouts,
193
+ )
194
+ site.compiler = new_compiler_for(site)
195
+
196
+ {
197
+ config: Nanoc::MutableConfigView.new(@config, view_context),
198
+ item_rep: @item_rep ? Nanoc::ItemRepView.new(@item_rep, view_context) : nil,
199
+ item: @item ? Nanoc::ItemWithRepsView.new(@item, view_context) : nil,
200
+ items: Nanoc::ItemCollectionWithRepsView.new(@items, view_context),
201
+ layouts: Nanoc::LayoutCollectionView.new(@layouts, view_context),
202
+ _erbout: @erbout,
203
+ }
204
+ end
205
+ end
206
+
207
+ module HelperHelper
208
+ def ctx
209
+ @_ctx ||= HelperContext.new(described_class)
210
+ end
211
+
212
+ def helper
213
+ @_helper ||= ctx.helper
214
+ end
215
+ end
216
+ end
217
+ end