nanoc 2.0.4 → 2.1
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.
- data/ChangeLog +31 -1
- data/LICENSE +1 -1
- data/README +63 -3
- data/Rakefile +59 -12
- data/bin/nanoc +7 -199
- data/lib/nanoc.rb +83 -12
- data/lib/nanoc/base/asset.rb +113 -0
- data/lib/nanoc/base/asset_defaults.rb +21 -0
- data/lib/nanoc/base/asset_rep.rb +277 -0
- data/lib/nanoc/base/binary_filter.rb +44 -0
- data/lib/nanoc/base/code.rb +41 -0
- data/lib/nanoc/base/compiler.rb +46 -34
- data/lib/nanoc/base/core_ext/hash.rb +51 -7
- data/lib/nanoc/base/core_ext/string.rb +8 -0
- data/lib/nanoc/base/data_source.rb +253 -20
- data/lib/nanoc/base/defaults.rb +30 -0
- data/lib/nanoc/base/enhancements.rb +9 -84
- data/lib/nanoc/base/filter.rb +109 -6
- data/lib/nanoc/base/layout.rb +91 -0
- data/lib/nanoc/base/notification_center.rb +66 -0
- data/lib/nanoc/base/page.rb +94 -126
- data/lib/nanoc/base/page_defaults.rb +20 -0
- data/lib/nanoc/base/page_rep.rb +318 -0
- data/lib/nanoc/base/plugin.rb +57 -9
- data/lib/nanoc/base/proxies/asset_proxy.rb +29 -0
- data/lib/nanoc/base/proxies/asset_rep_proxy.rb +26 -0
- data/lib/nanoc/base/proxies/layout_proxy.rb +25 -0
- data/lib/nanoc/base/proxies/page_proxy.rb +35 -0
- data/lib/nanoc/base/proxies/page_rep_proxy.rb +28 -0
- data/lib/nanoc/base/proxy.rb +37 -0
- data/lib/nanoc/base/router.rb +72 -0
- data/lib/nanoc/base/site.rb +219 -88
- data/lib/nanoc/base/template.rb +64 -0
- data/lib/nanoc/binary_filters/image_science_thumbnail.rb +28 -0
- data/lib/nanoc/cli.rb +1 -0
- data/lib/nanoc/cli/base.rb +219 -0
- data/lib/nanoc/cli/cli.rb +16 -0
- data/lib/nanoc/cli/command.rb +105 -0
- data/lib/nanoc/cli/commands/autocompile.rb +80 -0
- data/lib/nanoc/cli/commands/compile.rb +273 -0
- data/lib/nanoc/cli/commands/create_layout.rb +85 -0
- data/lib/nanoc/cli/commands/create_page.rb +85 -0
- data/lib/nanoc/cli/commands/create_site.rb +327 -0
- data/lib/nanoc/cli/commands/create_template.rb +76 -0
- data/lib/nanoc/cli/commands/help.rb +69 -0
- data/lib/nanoc/cli/commands/info.rb +114 -0
- data/lib/nanoc/cli/commands/switch.rb +141 -0
- data/lib/nanoc/cli/commands/update.rb +91 -0
- data/lib/nanoc/cli/ext.rb +37 -0
- data/lib/nanoc/cli/logger.rb +66 -0
- data/lib/nanoc/cli/option_parser.rb +168 -0
- data/lib/nanoc/data_sources/filesystem.rb +645 -224
- data/lib/nanoc/data_sources/filesystem_combined.rb +495 -0
- data/lib/nanoc/extra/auto_compiler.rb +265 -0
- data/lib/nanoc/extra/context.rb +22 -0
- data/lib/nanoc/extra/core_ext/hash.rb +54 -0
- data/lib/nanoc/extra/core_ext/time.rb +13 -0
- data/lib/nanoc/extra/file_proxy.rb +29 -0
- data/lib/nanoc/extra/vcs.rb +48 -0
- data/lib/nanoc/extra/vcses/bazaar.rb +21 -0
- data/lib/nanoc/extra/vcses/dummy.rb +20 -0
- data/lib/nanoc/extra/vcses/git.rb +21 -0
- data/lib/nanoc/extra/vcses/mercurial.rb +21 -0
- data/lib/nanoc/extra/vcses/subversion.rb +21 -0
- data/lib/nanoc/filters/bluecloth.rb +13 -0
- data/lib/nanoc/filters/erb.rb +6 -22
- data/lib/nanoc/filters/erubis.rb +14 -0
- data/lib/nanoc/filters/haml.rb +7 -23
- data/lib/nanoc/filters/markaby.rb +5 -5
- data/lib/nanoc/filters/maruku.rb +14 -0
- data/lib/nanoc/filters/old.rb +19 -0
- data/lib/nanoc/filters/rdiscount.rb +13 -0
- data/lib/nanoc/filters/rdoc.rb +5 -4
- data/lib/nanoc/filters/redcloth.rb +14 -0
- data/lib/nanoc/filters/rubypants.rb +14 -0
- data/lib/nanoc/filters/sass.rb +13 -0
- data/lib/nanoc/helpers/blogging.rb +170 -0
- data/lib/nanoc/helpers/capturing.rb +59 -0
- data/lib/nanoc/helpers/html_escape.rb +23 -0
- data/lib/nanoc/helpers/link_to.rb +69 -0
- data/lib/nanoc/helpers/render.rb +47 -0
- data/lib/nanoc/helpers/tagging.rb +52 -0
- data/lib/nanoc/helpers/xml_sitemap.rb +58 -0
- data/lib/nanoc/routers/default.rb +54 -0
- data/lib/nanoc/routers/no_dirs.rb +66 -0
- data/lib/nanoc/routers/versioned.rb +79 -0
- metadata +112 -22
- data/lib/nanoc/base/auto_compiler.rb +0 -132
- data/lib/nanoc/base/layout_processor.rb +0 -33
- data/lib/nanoc/base/page_proxy.rb +0 -31
- data/lib/nanoc/base/plugin_manager.rb +0 -33
- data/lib/nanoc/data_sources/database.rb +0 -259
- data/lib/nanoc/data_sources/trivial.rb +0 -145
- data/lib/nanoc/filters/markdown.rb +0 -13
- data/lib/nanoc/filters/smartypants.rb +0 -13
- data/lib/nanoc/filters/textile.rb +0 -13
- data/lib/nanoc/layout_processors/erb.rb +0 -35
- data/lib/nanoc/layout_processors/haml.rb +0 -38
- data/lib/nanoc/layout_processors/markaby.rb +0 -16
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Nanoc
|
|
2
|
+
|
|
3
|
+
# Nanoc::PageDefaults represent the default attributes for all pages in the
|
|
4
|
+
# site. If a specific page attribute is requested, but not found, then the
|
|
5
|
+
# page defaults will be queried for this attribute. (If the attribute
|
|
6
|
+
# doesn't even exist in the page defaults, hardcoded defaults will be used.)
|
|
7
|
+
class PageDefaults < Defaults
|
|
8
|
+
|
|
9
|
+
# Saves the page defaults in the database, creating it if it doesn't exist
|
|
10
|
+
# yet or updating it if it already exists. Tells the site's data source to
|
|
11
|
+
# save the page defaults.
|
|
12
|
+
def save
|
|
13
|
+
@site.data_source.loading do
|
|
14
|
+
@site.data_source.save_page_defaults(self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
module Nanoc
|
|
2
|
+
|
|
3
|
+
# A Nanoc::PageRep is a single representation (rep) of a page (Nanoc::Page).
|
|
4
|
+
# A page can have multiple representations. A representation has its own
|
|
5
|
+
# attributes and its own output file. A single page can therefore have
|
|
6
|
+
# multiple output files, each run through a different set of filters with a
|
|
7
|
+
# different layout.
|
|
8
|
+
#
|
|
9
|
+
# A page representation is observable. The following events will be
|
|
10
|
+
# notified:
|
|
11
|
+
#
|
|
12
|
+
# * :compilation_started
|
|
13
|
+
# * :compilation_ended
|
|
14
|
+
# * :filtering_started
|
|
15
|
+
# * :filtering_ended
|
|
16
|
+
#
|
|
17
|
+
# The compilation-related events have one parameters (the page
|
|
18
|
+
# representation); the filtering-related events have two (the page
|
|
19
|
+
# representation, and a symbol containing the filter class name).
|
|
20
|
+
class PageRep
|
|
21
|
+
|
|
22
|
+
# The page (Nanoc::Page) to which this representation belongs.
|
|
23
|
+
attr_reader :page
|
|
24
|
+
|
|
25
|
+
# A hash containing this page representation's attributes.
|
|
26
|
+
attr_accessor :attributes
|
|
27
|
+
|
|
28
|
+
# This page representation's unique name.
|
|
29
|
+
attr_reader :name
|
|
30
|
+
|
|
31
|
+
# Creates a new page representation for the given page and with the given
|
|
32
|
+
# attributes.
|
|
33
|
+
#
|
|
34
|
+
# +page+:: The page (Nanoc::Page) to which the new representation will
|
|
35
|
+
# belong.
|
|
36
|
+
#
|
|
37
|
+
# +attributes+:: A hash containing the new page representation's
|
|
38
|
+
# attributes. This hash must have been run through
|
|
39
|
+
# Hash#clean before using it here.
|
|
40
|
+
#
|
|
41
|
+
# +name+:: The unique name for the new page representation.
|
|
42
|
+
def initialize(page, attributes, name)
|
|
43
|
+
# Set primary attributes
|
|
44
|
+
@page = page
|
|
45
|
+
@attributes = attributes
|
|
46
|
+
@name = name
|
|
47
|
+
|
|
48
|
+
# Get page content from page
|
|
49
|
+
@content = { :pre => nil, :post => nil }
|
|
50
|
+
|
|
51
|
+
# Reset flags
|
|
52
|
+
@compiled = false
|
|
53
|
+
@modified = false
|
|
54
|
+
@created = false
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns a proxy (Nanoc::PageRepProxy) for this page representation.
|
|
58
|
+
def to_proxy
|
|
59
|
+
@proxy ||= PageRepProxy.new(self)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns true if this page rep's output file was created during the last
|
|
63
|
+
# compilation session, or false if the output file did already exist.
|
|
64
|
+
def created?
|
|
65
|
+
@created
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Returns true if this page rep's output file was modified during the last
|
|
69
|
+
# compilation session, or false if the output file wasn't changed.
|
|
70
|
+
def modified?
|
|
71
|
+
@modified
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Returns true if this page rep has been compiled, false otherwise.
|
|
75
|
+
def compiled?
|
|
76
|
+
@compiled
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns true if this page rep's output file is outdated and must be
|
|
80
|
+
# regenerated, false otherwise.
|
|
81
|
+
def outdated?
|
|
82
|
+
# Outdated if we don't know
|
|
83
|
+
return true if @page.mtime.nil?
|
|
84
|
+
|
|
85
|
+
# Outdated if compiled file doesn't exist
|
|
86
|
+
return true if !File.file?(disk_path)
|
|
87
|
+
|
|
88
|
+
# Get compiled mtime
|
|
89
|
+
compiled_mtime = File.stat(disk_path).mtime
|
|
90
|
+
|
|
91
|
+
# Outdated if file too old
|
|
92
|
+
return true if @page.mtime > compiled_mtime
|
|
93
|
+
|
|
94
|
+
# Outdated if layouts outdated
|
|
95
|
+
return true if @page.site.layouts.any? do |l|
|
|
96
|
+
l.mtime.nil? or l.mtime > compiled_mtime
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Outdated if page defaults outdated
|
|
100
|
+
return true if @page.site.page_defaults.mtime.nil?
|
|
101
|
+
return true if @page.site.page_defaults.mtime > compiled_mtime
|
|
102
|
+
|
|
103
|
+
# Outdated if code outdated
|
|
104
|
+
return true if @page.site.code.mtime.nil?
|
|
105
|
+
return true if @page.site.code.mtime > compiled_mtime
|
|
106
|
+
|
|
107
|
+
return false
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Returns the path to the output file, including the path to the output
|
|
111
|
+
# directory specified in the site configuration, and including the
|
|
112
|
+
# filename and extension.
|
|
113
|
+
def disk_path
|
|
114
|
+
@disk_path ||= @page.site.router.disk_path_for(self)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Returns the path to the output file as it would be used in a web
|
|
118
|
+
# browser: starting with a slash (representing the web root), and only
|
|
119
|
+
# including the filename and extension if they cannot be ignored (i.e.
|
|
120
|
+
# they are not in the site configuration's list of index files).
|
|
121
|
+
def web_path
|
|
122
|
+
@web_path ||= @page.site.router.web_path_for(self)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Returns the attribute with the given name. This method will look in
|
|
126
|
+
# several places for the requested attribute:
|
|
127
|
+
#
|
|
128
|
+
# 1. This page representation's attributes;
|
|
129
|
+
# 2. The attributes of this page representation's page;
|
|
130
|
+
# 3. The page defaults' representation corresponding to this page
|
|
131
|
+
# representation;
|
|
132
|
+
# 4. The page defaults in general;
|
|
133
|
+
# 5. The hardcoded page defaults, if everything else fails.
|
|
134
|
+
def attribute_named(name)
|
|
135
|
+
# Check in here
|
|
136
|
+
return @attributes[name] if @attributes.has_key?(name)
|
|
137
|
+
|
|
138
|
+
# Check in page
|
|
139
|
+
return @page.attributes[name] if @page.attributes.has_key?(name)
|
|
140
|
+
|
|
141
|
+
# Check in page defaults' page rep
|
|
142
|
+
page_default_reps = @page.site.page_defaults.attributes[:reps] || {}
|
|
143
|
+
page_default_rep = page_default_reps[@name] || {}
|
|
144
|
+
return page_default_rep[name] if page_default_rep.has_key?(name)
|
|
145
|
+
|
|
146
|
+
# Check in site defaults (global)
|
|
147
|
+
page_defaults_attrs = @page.site.page_defaults.attributes
|
|
148
|
+
return page_defaults_attrs[name] if page_defaults_attrs.has_key?(name)
|
|
149
|
+
|
|
150
|
+
# Check in hardcoded defaults
|
|
151
|
+
return Nanoc::Page::DEFAULTS[name]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Returns the page representation content at the given stage.
|
|
155
|
+
#
|
|
156
|
+
# +stage+:: The stage at which the content should be fetched. Can be
|
|
157
|
+
# either +:pre+ or +:post+. To get the raw, uncompiled content,
|
|
158
|
+
# use Nanoc::Page#content.
|
|
159
|
+
def content(stage=:pre)
|
|
160
|
+
compile(stage == :post, true, false)
|
|
161
|
+
|
|
162
|
+
@content[stage]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Returns the layout used for this page representation.
|
|
166
|
+
def layout
|
|
167
|
+
# Check whether layout is present
|
|
168
|
+
return nil if attribute_named(:layout).nil?
|
|
169
|
+
|
|
170
|
+
# Find layout
|
|
171
|
+
@layout ||= @page.site.layouts.find { |l| l.path == attribute_named(:layout).cleaned_path }
|
|
172
|
+
raise Nanoc::Errors::UnknownLayoutError.new(attribute_named(:layout)) if @layout.nil?
|
|
173
|
+
|
|
174
|
+
@layout
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Compiles the page representation and writes the result to the disk. This
|
|
178
|
+
# method should not be called directly; please use Nanoc::Compiler#run
|
|
179
|
+
# instead, and pass this page representation's page as its first argument.
|
|
180
|
+
#
|
|
181
|
+
# The page representation will only be compiled if it wasn't compiled
|
|
182
|
+
# before yet. To force recompilation of the page rep, forgetting any
|
|
183
|
+
# progress, set +from_scratch+ to true.
|
|
184
|
+
#
|
|
185
|
+
# +also_layout+:: true if the page rep should also be laid out and
|
|
186
|
+
# post-filtered, false if the page rep should only be
|
|
187
|
+
# pre-filtered.
|
|
188
|
+
#
|
|
189
|
+
# +even_when_not_outdated+:: true if the page rep should be compiled even
|
|
190
|
+
# if it is not outdated, false if not.
|
|
191
|
+
#
|
|
192
|
+
# +from_scratch+:: true if all compilation stages (pre-filter, layout,
|
|
193
|
+
# post-filter) should be performed again even if they
|
|
194
|
+
# have already been performed, false otherwise.
|
|
195
|
+
def compile(also_layout, even_when_not_outdated, from_scratch)
|
|
196
|
+
# Don't compile if already compiled
|
|
197
|
+
return if @content[also_layout ? :post : :pre] and !from_scratch
|
|
198
|
+
|
|
199
|
+
# Skip unless outdated
|
|
200
|
+
unless outdated? or even_when_not_outdated
|
|
201
|
+
if also_layout
|
|
202
|
+
Nanoc::NotificationCenter.post(:compilation_started, self)
|
|
203
|
+
Nanoc::NotificationCenter.post(:compilation_ended, self)
|
|
204
|
+
end
|
|
205
|
+
return
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Reset flags
|
|
209
|
+
@compiled = false
|
|
210
|
+
@modified = false
|
|
211
|
+
@created = false
|
|
212
|
+
|
|
213
|
+
# Forget progress if requested
|
|
214
|
+
@content = { :pre => nil, :post => nil } if from_scratch
|
|
215
|
+
|
|
216
|
+
# Check for recursive call
|
|
217
|
+
if @page.site.compiler.stack.include?(self)
|
|
218
|
+
@page.site.compiler.stack.push(self)
|
|
219
|
+
raise Nanoc::Errors::RecursiveCompilationError.new
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Start
|
|
223
|
+
@page.site.compiler.stack.push(self)
|
|
224
|
+
Nanoc::NotificationCenter.post(:compilation_started, self) if also_layout
|
|
225
|
+
|
|
226
|
+
# Pre-filter if necesary
|
|
227
|
+
if @content[:pre].nil?
|
|
228
|
+
do_filter(:pre)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Post-filter if necessary
|
|
232
|
+
if @content[:post].nil? and also_layout
|
|
233
|
+
do_layout
|
|
234
|
+
do_filter(:post)
|
|
235
|
+
|
|
236
|
+
# Update status
|
|
237
|
+
@compiled = true
|
|
238
|
+
unless attribute_named(:skip_output)
|
|
239
|
+
@created = !File.file?(self.disk_path)
|
|
240
|
+
@modified = @created ? true : File.read(self.disk_path) != @content[:post]
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Write if necessary
|
|
244
|
+
write unless attribute_named(:skip_output)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Stop
|
|
248
|
+
Nanoc::NotificationCenter.post(:compilation_ended, self) if also_layout
|
|
249
|
+
@page.site.compiler.stack.pop
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
private
|
|
253
|
+
|
|
254
|
+
# Runs the content through the filters in the given stage.
|
|
255
|
+
def do_filter(stage)
|
|
256
|
+
# Get content if necessary
|
|
257
|
+
content = (stage == :pre ? @page.content : @content[:post])
|
|
258
|
+
|
|
259
|
+
# Get filters
|
|
260
|
+
check_for_outdated_filters
|
|
261
|
+
filters = attribute_named(stage == :pre ? :filters_pre : :filters_post)
|
|
262
|
+
|
|
263
|
+
# Run each filter
|
|
264
|
+
filters.each do |filter_name|
|
|
265
|
+
# Create filter
|
|
266
|
+
klass = Nanoc::Filter.named(filter_name)
|
|
267
|
+
raise Nanoc::Errors::UnknownFilterError.new(filter_name) if klass.nil?
|
|
268
|
+
filter = klass.new(self)
|
|
269
|
+
|
|
270
|
+
# Run filter
|
|
271
|
+
Nanoc::NotificationCenter.post(:filtering_started, self, klass.identifier)
|
|
272
|
+
content = filter.run(content)
|
|
273
|
+
Nanoc::NotificationCenter.post(:filtering_ended, self, klass.identifier)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Set content
|
|
277
|
+
@content[stage] = content
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Runs the content through this rep's layout.
|
|
281
|
+
def do_layout
|
|
282
|
+
# Don't layout if not necessary
|
|
283
|
+
if attribute_named(:layout).nil?
|
|
284
|
+
@content[:post] = @content[:pre]
|
|
285
|
+
return
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Create filter
|
|
289
|
+
klass = layout.filter_class
|
|
290
|
+
raise Nanoc::Errors::CannotDetermineFilterError.new(layout.path) if klass.nil?
|
|
291
|
+
filter = klass.new(self)
|
|
292
|
+
|
|
293
|
+
# Layout
|
|
294
|
+
Nanoc::NotificationCenter.post(:filtering_started, self, klass.identifier)
|
|
295
|
+
@content[:post] = filter.run(layout.content)
|
|
296
|
+
Nanoc::NotificationCenter.post(:filtering_ended, self, klass.identifier)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Writes the compiled content to the disk.
|
|
300
|
+
def write
|
|
301
|
+
# TODO add ruby 1.9 support
|
|
302
|
+
FileUtils.mkdir_p(File.dirname(self.disk_path))
|
|
303
|
+
File.open(self.disk_path, 'w') { |io| io.write(@content[:post]) }
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Raises an error when the outdated 'filters' attribute is used.
|
|
307
|
+
def check_for_outdated_filters
|
|
308
|
+
unless attribute_named(:filters).nil?
|
|
309
|
+
raise Nanoc::Errors::NoLongerSupportedError.new(
|
|
310
|
+
'The `filters` property is no longer supported; please use ' +
|
|
311
|
+
'`filters_pre` instead.'
|
|
312
|
+
)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
end
|
data/lib/nanoc/base/plugin.rb
CHANGED
|
@@ -1,19 +1,67 @@
|
|
|
1
1
|
module Nanoc
|
|
2
|
+
|
|
3
|
+
# Nanoc::Plugin is the superclass for all plugins, such as filters
|
|
4
|
+
# (Nanoc::Filter), binary filters (Nanoc::BinaryFilter), routers
|
|
5
|
+
# (Nanoc::Router), data sources (Nanoc::DataSource) and VCSes
|
|
6
|
+
# (Nanoc::Extra::VCS). Each plugin has one or more unique identifiers, and
|
|
7
|
+
# several methods in this class provides functionality for finding plugins
|
|
8
|
+
# with given identifiers.
|
|
2
9
|
class Plugin
|
|
3
10
|
|
|
11
|
+
MAP = {}
|
|
12
|
+
|
|
4
13
|
class << self
|
|
5
|
-
attr_accessor :_identifiers
|
|
6
|
-
end
|
|
7
14
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
# Sets or returns the identifiers for this plugin.
|
|
16
|
+
#
|
|
17
|
+
# When given a list of identifier symbols, sets the identifiers for
|
|
18
|
+
# this plugin. When given nothing, returns an array of identifier
|
|
19
|
+
# symbols for this plugin.
|
|
20
|
+
def identifiers(*identifiers)
|
|
21
|
+
# Initialize
|
|
22
|
+
@identifiers = [] unless instance_variables.include?('@identifiers')
|
|
23
|
+
|
|
24
|
+
if identifiers.empty?
|
|
25
|
+
@identifiers
|
|
26
|
+
else
|
|
27
|
+
@identifiers = identifiers
|
|
28
|
+
@identifiers.each { |i| register(i, self) }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Sets or returns the identifier for this plugin.
|
|
33
|
+
#
|
|
34
|
+
# When given an identifier symbols, sets the identifier for this plugin.
|
|
35
|
+
# When given nothing, returns the identifier for this plugin.
|
|
36
|
+
def identifier(identifier=nil)
|
|
37
|
+
# Initialize
|
|
38
|
+
@identifiers = [] unless instance_variables.include?('@identifiers')
|
|
39
|
+
|
|
40
|
+
if identifier.nil?
|
|
41
|
+
@identifiers.first
|
|
42
|
+
else
|
|
43
|
+
@identifiers = [ identifier ]
|
|
44
|
+
register(identifier, self)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Registers the given class +klass+ with the given name. This will allow
|
|
49
|
+
# the named method to find the class.
|
|
50
|
+
def register(name, klass)
|
|
51
|
+
MAP[klass.superclass] ||= {}
|
|
52
|
+
MAP[klass.superclass][name.to_sym] = klass
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Returns the the plugin with the given name. Only subclasses of this
|
|
56
|
+
# class will be searched. For example, calling this method on
|
|
57
|
+
# Nanoc::Filter will cause only Nanoc::Filter subclasses to be searched.
|
|
58
|
+
def named(name)
|
|
59
|
+
MAP[self] ||= {}
|
|
60
|
+
MAP[self][name.to_sym]
|
|
61
|
+
end
|
|
12
62
|
|
|
13
|
-
def self.identifier(identifier=nil)
|
|
14
|
-
self._identifiers = [] unless instance_variables.include?('@_identifiers')
|
|
15
|
-
identifier.nil? ? self.identifiers.first : self.identifiers(identifier)
|
|
16
63
|
end
|
|
17
64
|
|
|
18
65
|
end
|
|
66
|
+
|
|
19
67
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Nanoc
|
|
2
|
+
|
|
3
|
+
# Nanoc::AssetProxy is a proxy object for an asset (Nanoc::Asset).
|
|
4
|
+
class AssetProxy < Proxy
|
|
5
|
+
|
|
6
|
+
# Requests the asset attribute with the given name. +key+ can be a string
|
|
7
|
+
# or a symbol, and it can contain a trailing question mark (which will be
|
|
8
|
+
# stripped).
|
|
9
|
+
def [](key)
|
|
10
|
+
real_key = key.to_s.sub(/\?$/, '').to_sym
|
|
11
|
+
|
|
12
|
+
if real_key == :mtime
|
|
13
|
+
@obj.mtime
|
|
14
|
+
elsif real_key == :path # backward compatibility
|
|
15
|
+
@obj.reps.find { |r| r.name == :default }.web_path
|
|
16
|
+
else
|
|
17
|
+
super(key)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns the asset representation with the given name.
|
|
22
|
+
def reps(name)
|
|
23
|
+
rep = @obj.reps.find { |r| r.name == name }
|
|
24
|
+
rep.nil? ? nil : rep.to_proxy
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Nanoc
|
|
2
|
+
|
|
3
|
+
# Nanoc::AssetRepProxy is a proxy object for an asset representation
|
|
4
|
+
# (Nanoc::AssetRep).
|
|
5
|
+
class AssetRepProxy < Proxy
|
|
6
|
+
|
|
7
|
+
# Requests the asset representation attribute with the given name. +key+
|
|
8
|
+
# can be a string or a symbol, and it can contain a trailing question mark
|
|
9
|
+
# (which will be stripped).
|
|
10
|
+
def [](key)
|
|
11
|
+
real_key = key.to_s.sub(/\?$/, '').to_sym
|
|
12
|
+
|
|
13
|
+
if real_key == :name
|
|
14
|
+
@obj.name
|
|
15
|
+
elsif real_key == :path
|
|
16
|
+
@obj.web_path
|
|
17
|
+
elsif real_key == :asset
|
|
18
|
+
@obj.asset.to_proxy
|
|
19
|
+
else
|
|
20
|
+
super(key)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|