nanoc 4.1.6 → 4.2.0b1

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 (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