Class: Nanoc3::ItemRep
- Inherits:
-
Object
- Object
- Nanoc3::ItemRep
- Defined in:
- lib/nanoc3/base/item_rep.rb
Overview
A single representation (rep) of an item (Item). An item can have multiple representations. A representation has its own output file. A single item can therefore have multiple output files, each run through a different set of filters with a different layout.
An item representation is observable. The following events will be notified:
:compilation_started:compilation_ended:filtering_started:filtering_ended
The compilation-related events have one parameters (the item representation); the filtering-related events have two (the item representation, and a symbol containing the filter class name).
Constant Summary
- OUTDATEDNESS_REASON_DESCRIPTIONS =
The descriptive strings for each outdatedness reason. This hash is used by the #outdatedness_reason method.
{ :no_mtime => 'No file modification time is available.', :forced => 'All pages are recompiled because of a `--force` flag given to the compilation command.', :no_raw_path => 'The routing rules do not specify a path where this item should be written to, i.e. the item representation will never be written to the output directory.', :not_written => 'This item representation has not yet been written to the output directory (but it does have a path).', :source_modified => 'The source file of this item has been modified since the last time this item representation was compiled.', :layouts_outdated => 'The source of one or more layouts has been modified since the last time this item representation was compiled.', :code_outdated => 'The code snippets in the `lib/` directory have been modified since the last time this item representation was compiled.', :config_outdated => 'The site configuration has been modified since the last time this item representation was compiled.', :rules_outdated => 'The rules file has been modified since the last time this item representation was compiled.', }
Instance Attribute Summary (collapse)
-
- (Boolean) binary
(also: #binary?)
readonly
True if this rep is currently binary; false otherwise.
-
- (Boolean) compiled
(also: #compiled?)
during the current or last compilation session; false otherwise.
-
- (Boolean) created
(also: #created?)
current or last compilation session; false otherwise.
-
- (Boolean) force_outdated
of the
--forcecommandline option); false otherwise. -
- (Nanoc3::Item) item
readonly
The item to which this rep belongs.
-
- (Boolean) modified
(also: #modified?)
last time it was compiled; false otherwise.
-
- (Symbol) name
readonly
The representation's unique name.
-
- (String) path
starts with a slash and it is relative to the output directory.
-
- (String) raw_path
working directory and includes the path to the output directory.
-
- (Boolean) written
(also: #written?)
readonly
been written during the current or last compilation session; false otherwise.
Instance Method Summary (collapse)
-
- (Hash) assigns
the content.
-
- (String) compiled_content(params = {})
Returns the compiled content from a given snapshot.
-
- (Object) content_at_snapshot(snapshot = :pre)
Deprecated
Deprecated.
Use #compiled_content instead.
-
- (String?) diff
Creates and returns a diff between the compiled content before the current compilation session and the content compiled in the current compilation session.
-
- (void) filter(filter_name, filter_args = {})
Runs the item content through the given filter with the given arguments.
-
- (void) forget_progress
Resets the compilation progress for this item representation.
-
- (ItemRep) initialize(item, name)
constructor
Creates a new item representation for the given item.
- - (Object) inspect
-
- (void) layout(layout_identifier)
Lays out the item using the given layout.
-
- (Boolean) outdated?
must be regenerated, false otherwise.
-
- (Hash?) outdatedness_reason
Calculates the reason why this item representation is outdated.
-
- (void) snapshot(snapshot_name)
Creates a snapshot of the current compiled item content.
-
- (void) write
Writes the item rep's compiled content to the rep's output file.
Constructor Details
- (ItemRep) initialize(item, name)
Creates a new item representation for the given item.
belong.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/nanoc3/base/item_rep.rb', line 89 def initialize(item, name) # Set primary attributes @item = item @name = name # Set binary @binary = @item.binary? # Initialize content and filenames initialize_content @old_content = nil # Reset flags @compiled = false @modified = false @created = false @written = false @force_outdated = false end |
Instance Attribute Details
- (Boolean) binary (readonly) Also known as: binary?
True if this rep is currently binary; false otherwise
48 49 50 |
# File 'lib/nanoc3/base/item_rep.rb', line 48 def binary @binary end |
- (Boolean) compiled Also known as: compiled?
during the current or last compilation session; false otherwise
63 64 65 |
# File 'lib/nanoc3/base/item_rep.rb', line 63 def compiled @compiled end |
- (Boolean) created Also known as: created?
current or last compilation session; false otherwise
58 59 60 |
# File 'lib/nanoc3/base/item_rep.rb', line 58 def created @created end |
- (Boolean) force_outdated
of the --force commandline option); false otherwise
45 46 47 |
# File 'lib/nanoc3/base/item_rep.rb', line 45 def force_outdated @force_outdated end |
- (Nanoc3::Item) item (readonly)
The item to which this rep belongs
38 39 40 |
# File 'lib/nanoc3/base/item_rep.rb', line 38 def item @item end |
- (Boolean) modified Also known as: modified?
last time it was compiled; false otherwise
53 54 55 |
# File 'lib/nanoc3/base/item_rep.rb', line 53 def modified @modified end |
- (Symbol) name (readonly)
The representation's unique name
41 42 43 |
# File 'lib/nanoc3/base/item_rep.rb', line 41 def name @name end |
- (String) path
starts with a slash and it is relative to the output directory. It does not include the path to the output directory. It will not include the filename if the filename is an index filename.
76 77 78 |
# File 'lib/nanoc3/base/item_rep.rb', line 76 def path @path end |
- (String) raw_path
working directory and includes the path to the output directory. It also includes the filename, even if it is an index filename.
81 82 83 |
# File 'lib/nanoc3/base/item_rep.rb', line 81 def raw_path @raw_path end |
- (Boolean) written (readonly) Also known as: written?
been written during the current or last compilation session; false otherwise
69 70 71 |
# File 'lib/nanoc3/base/item_rep.rb', line 69 def written @written end |
Instance Method Details
- (Hash) assigns
the content.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/nanoc3/base/item_rep.rb', line 179 def assigns if self.binary? content_or_filename_assigns = { :filename => @filenames[:last] } else content_or_filename_assigns = { :content => @content[:last] } end content_or_filename_assigns.merge({ :item => self.item, :item_rep => self, :items => self.item.site.items, :layouts => self.item.site.layouts, :config => self.item.site.config, :site => self.item.site }) end |
- (String) compiled_content(params = {})
Returns the compiled content from a given snapshot.
fetch the compiled content. By default, the returned compiled content will be the content compiled right before the first layout call (if any).
default snapshot if no snapshot is specified)
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/nanoc3/base/item_rep.rb', line 205 def compiled_content(params={}) # Notify Nanoc3::NotificationCenter.post(:visit_started, self.item) Nanoc3::NotificationCenter.post(:visit_ended, self.item) # Debug puts "*** Attempting to fetch content for #{self.inspect}" if $DEBUG # Require compilation raise Nanoc3::Errors::UnmetDependency.new(self) unless compiled? # Get name of last pre-layout snapshot snapshot_name = params[:snapshot] if @content[:pre] snapshot_name ||= :pre else snapshot_name ||= :last end # Check presence of snapshot if @content[snapshot_name].nil? warn "WARNING: The “#{self.item.identifier}” item (rep “#{self.name}”) does not have the requested snapshot named #{snapshot_name.inspect}.\n\n* Make sure that you are requesting the correct snapshot.\n* It is not possible to request the compiled content of a binary item representation; if this item is marked as binary even though you believe it should be textual, you may need to add the extension of this item to the site configuration’s `text_extensions` array.".make_compatible_with_env end # Get content @content[snapshot_name] end |
- (Object) content_at_snapshot(snapshot = :pre)
Use #compiled_content instead.
234 235 236 |
# File 'lib/nanoc3/base/item_rep.rb', line 234 def content_at_snapshot(snapshot=:pre) compiled_content(:snapshot => snapshot) end |
- (String?) diff
Creates and returns a diff between the compiled content before the current compilation session and the content compiled in the current compilation session.
content in diff(1) format, or nil if there is no previous compiled
content
399 400 401 402 403 404 405 406 |
# File 'lib/nanoc3/base/item_rep.rb', line 399 def diff if self.binary? nil else @diff_thread.join if @diff_thread @diff end end |
- (void) filter(filter_name, filter_args = {})
This method returns an undefined value.
Runs the item content through the given filter with the given arguments.
This method will replace the content of the :last snapshot with the
filtered content of the last snapshot.
This method is supposed to be called only in a compilation rule block (see CompilerDSL#compile).
representations' content through
the filter's #run method
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/nanoc3/base/item_rep.rb', line 261 def filter(filter_name, filter_args={}) # Get filter class klass = filter_named(filter_name) raise Nanoc3::Errors::UnknownFilter.new(filter_name) if klass.nil? # Check whether filter can be applied if klass.from_binary? && !self.binary? raise Nanoc3::Errors::CannotUseBinaryFilter.new(self, klass) elsif !klass.from_binary? && self.binary? raise Nanoc3::Errors::CannotUseTextualFilter.new(self, klass) end # Create filter filter = klass.new(assigns) # Run filter Nanoc3::NotificationCenter.post(:filtering_started, self, filter_name) source = self.binary? ? @filenames[:last] : @content[:last] result = filter.run(source, filter_args) if klass.to_binary? @filenames[:last] = filter.output_filename else @content[:last] = result end @binary = klass.to_binary? Nanoc3::NotificationCenter.post(:filtering_ended, self, filter_name) # Check whether file was written if self.binary? && !File.file?(filter.output_filename) raise RuntimeError, "The #{filter_name.inspect} filter did not write anything to the required output file, #{filter.output_filename}." end # Create snapshot snapshot(@content[:post] ? :post : :pre) unless self.binary? end |
- (void) forget_progress
This method returns an undefined value.
Resets the compilation progress for this item representation. This is necessary when an unmet dependency is detected during compilation. This method should probably not be called directly.
243 244 245 |
# File 'lib/nanoc3/base/item_rep.rb', line 243 def forget_progress initialize_content end |
- (Object) inspect
408 409 410 |
# File 'lib/nanoc3/base/item_rep.rb', line 408 def inspect "<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} binary=#{self.binary?} raw_path=#{self.raw_path} item.identifier=#{self.item.identifier}>" end |
- (void) layout(layout_identifier)
This method returns an undefined value.
Lays out the item using the given layout. This method will replace the
content of the :last snapshot with the laid out content of the last
snapshot.
This method is supposed to be called only in a compilation rule block (see CompilerDSL#compile).
should be laid out with
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/nanoc3/base/item_rep.rb', line 309 def layout(layout_identifier) # Check whether item can be laid out raise Nanoc3::Errors::CannotLayoutBinaryItem.new(self) if self.binary? # Create "pre" snapshot snapshot(:pre) unless @content[:pre] # Create filter layout = layout_with_identifier(layout_identifier) filter, filter_name, filter_args = filter_for_layout(layout) # Layout @item.site.compiler.stack.push(layout) Nanoc3::NotificationCenter.post(:filtering_started, self, filter_name) @content[:last] = filter.run(layout.raw_content, filter_args) Nanoc3::NotificationCenter.post(:filtering_ended, self, filter_name) @item.site.compiler.stack.pop # Create "post" snapshot snapshot(:post) end |
- (Boolean) outdated?
must be regenerated, false otherwise
173 174 175 |
# File 'lib/nanoc3/base/item_rep.rb', line 173 def outdated? !outdatedness_reason.nil? end |
- (Hash?) outdatedness_reason
Calculates the reason why this item representation is outdated. The
output will be a hash with a :type key, containing the reason why the
item is outdated in the form of a symbol, and a :description key,
containing a descriptive string that can be printed if necessary.
For documentation on the types that this method can return, check the OUTDATEDNESS<em>REASON</em>DESCRIPTIONS hash in this class.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/nanoc3/base/item_rep.rb', line 120 def outdatedness_reason # Get reason symbol reason = lambda do # Outdated if we don't know return :no_mtime if @item.mtime.nil? # Outdated if the dependency tracker says so return :forced if @force_outdated # Outdated if compiled file doesn't exist (yet) return :no_raw_path if self.raw_path.nil? return :not_written if !File.file?(self.raw_path) # Get compiled mtime compiled_mtime = File.stat(self.raw_path).mtime # Outdated if file too old return :source_modified if @item.mtime > compiled_mtime # Outdated if layouts outdated return :layouts_outdated if @item.site.layouts.any? do |l| l.mtime.nil? || l.mtime > compiled_mtime end # Outdated if code outdated return :code_outdated if @item.site.code_snippets.any? do |cs| cs.mtime.nil? || cs.mtime > compiled_mtime end # Outdated if config outdated return :config_outdated if @item.site.config_mtime.nil? return :config_outdated if @item.site.config_mtime > compiled_mtime # Outdated if rules outdated return :rules_outdated if @item.site.rules_mtime.nil? return :rules_outdated if @item.site.rules_mtime > compiled_mtime return nil end[] # Build reason symbol and description if reason.nil? nil else { :type => reason, :description => OUTDATEDNESS_REASON_DESCRIPTIONS[reason] } end end |
- (void) snapshot(snapshot_name)
This method returns an undefined value.
Creates a snapshot of the current compiled item content.
336 337 338 339 |
# File 'lib/nanoc3/base/item_rep.rb', line 336 def snapshot(snapshot_name) target = self.binary? ? @filenames : @content target[snapshot_name] = target[:last] end |
- (void) write
This method returns an undefined value.
Writes the item rep's compiled content to the rep's output file.
This method should not be called directly, even in a compilation block; the compiler is responsible for calling this method.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 |
# File 'lib/nanoc3/base/item_rep.rb', line 347 def write # Create parent directory FileUtils.mkdir_p(File.dirname(self.raw_path)) # Check if file will be created @created = !File.file?(self.raw_path) if self.binary? # Calculate hash of old content if File.file?(self.raw_path) hash_old = hash_for_file(self.raw_path) size_old = File.size(self.raw_path) end size_new = File.size(@filenames[:last]) hash_new = hash_for_file(@filenames[:last]) if size_old == size_new # Check if file was modified @modified = (size_old != size_new || hash_old != hash_new) # Copy if @modified FileUtils.cp(@filenames[:last], self.raw_path) end @written = true else # Remember old content if File.file?(self.raw_path) @old_content = File.read(self.raw_path) end # Write new_content = @content[:last] if @old_content != new_content File.open(self.raw_path, 'w') { |io| io.write(new_content) } end @written = true # Generate diff generate_diff # Check if file was modified @modified = File.read(self.raw_path) != @old_content end end |