nanoc2 2.2.3
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 +3 -0
- data/LICENSE +19 -0
- data/README +75 -0
- data/Rakefile +76 -0
- data/bin/nanoc2 +26 -0
- data/lib/nanoc2.rb +73 -0
- data/lib/nanoc2/base.rb +26 -0
- data/lib/nanoc2/base/asset.rb +117 -0
- data/lib/nanoc2/base/asset_defaults.rb +21 -0
- data/lib/nanoc2/base/asset_rep.rb +282 -0
- data/lib/nanoc2/base/binary_filter.rb +44 -0
- data/lib/nanoc2/base/code.rb +41 -0
- data/lib/nanoc2/base/compiler.rb +67 -0
- data/lib/nanoc2/base/core_ext.rb +2 -0
- data/lib/nanoc2/base/core_ext/hash.rb +78 -0
- data/lib/nanoc2/base/core_ext/string.rb +8 -0
- data/lib/nanoc2/base/data_source.rb +286 -0
- data/lib/nanoc2/base/defaults.rb +30 -0
- data/lib/nanoc2/base/filter.rb +93 -0
- data/lib/nanoc2/base/layout.rb +91 -0
- data/lib/nanoc2/base/notification_center.rb +66 -0
- data/lib/nanoc2/base/page.rb +132 -0
- data/lib/nanoc2/base/page_defaults.rb +20 -0
- data/lib/nanoc2/base/page_rep.rb +324 -0
- data/lib/nanoc2/base/plugin.rb +71 -0
- data/lib/nanoc2/base/proxies.rb +5 -0
- data/lib/nanoc2/base/proxies/asset_proxy.rb +29 -0
- data/lib/nanoc2/base/proxies/asset_rep_proxy.rb +26 -0
- data/lib/nanoc2/base/proxies/layout_proxy.rb +25 -0
- data/lib/nanoc2/base/proxies/page_proxy.rb +35 -0
- data/lib/nanoc2/base/proxies/page_rep_proxy.rb +28 -0
- data/lib/nanoc2/base/proxy.rb +37 -0
- data/lib/nanoc2/base/router.rb +72 -0
- data/lib/nanoc2/base/site.rb +274 -0
- data/lib/nanoc2/base/template.rb +64 -0
- data/lib/nanoc2/binary_filters.rb +1 -0
- data/lib/nanoc2/binary_filters/image_science_thumbnail.rb +28 -0
- data/lib/nanoc2/cli.rb +9 -0
- data/lib/nanoc2/cli/base.rb +132 -0
- data/lib/nanoc2/cli/commands.rb +10 -0
- data/lib/nanoc2/cli/commands/autocompile.rb +80 -0
- data/lib/nanoc2/cli/commands/compile.rb +312 -0
- data/lib/nanoc2/cli/commands/create_layout.rb +85 -0
- data/lib/nanoc2/cli/commands/create_page.rb +85 -0
- data/lib/nanoc2/cli/commands/create_site.rb +323 -0
- data/lib/nanoc2/cli/commands/create_template.rb +76 -0
- data/lib/nanoc2/cli/commands/help.rb +69 -0
- data/lib/nanoc2/cli/commands/info.rb +125 -0
- data/lib/nanoc2/cli/commands/switch.rb +141 -0
- data/lib/nanoc2/cli/commands/update.rb +91 -0
- data/lib/nanoc2/cli/logger.rb +72 -0
- data/lib/nanoc2/data_sources.rb +2 -0
- data/lib/nanoc2/data_sources/filesystem.rb +707 -0
- data/lib/nanoc2/data_sources/filesystem_combined.rb +495 -0
- data/lib/nanoc2/extra.rb +6 -0
- data/lib/nanoc2/extra/auto_compiler.rb +285 -0
- data/lib/nanoc2/extra/context.rb +22 -0
- data/lib/nanoc2/extra/core_ext.rb +2 -0
- data/lib/nanoc2/extra/core_ext/hash.rb +54 -0
- data/lib/nanoc2/extra/core_ext/time.rb +13 -0
- data/lib/nanoc2/extra/file_proxy.rb +29 -0
- data/lib/nanoc2/extra/vcs.rb +48 -0
- data/lib/nanoc2/extra/vcses.rb +5 -0
- data/lib/nanoc2/extra/vcses/bazaar.rb +21 -0
- data/lib/nanoc2/extra/vcses/dummy.rb +20 -0
- data/lib/nanoc2/extra/vcses/git.rb +21 -0
- data/lib/nanoc2/extra/vcses/mercurial.rb +21 -0
- data/lib/nanoc2/extra/vcses/subversion.rb +21 -0
- data/lib/nanoc2/filters.rb +16 -0
- data/lib/nanoc2/filters/bluecloth.rb +13 -0
- data/lib/nanoc2/filters/erb.rb +19 -0
- data/lib/nanoc2/filters/erubis.rb +14 -0
- data/lib/nanoc2/filters/haml.rb +21 -0
- data/lib/nanoc2/filters/markaby.rb +14 -0
- data/lib/nanoc2/filters/maruku.rb +14 -0
- data/lib/nanoc2/filters/old.rb +19 -0
- data/lib/nanoc2/filters/rainpress.rb +13 -0
- data/lib/nanoc2/filters/rdiscount.rb +13 -0
- data/lib/nanoc2/filters/rdoc.rb +23 -0
- data/lib/nanoc2/filters/redcloth.rb +14 -0
- data/lib/nanoc2/filters/relativize_paths.rb +16 -0
- data/lib/nanoc2/filters/relativize_paths_in_css.rb +16 -0
- data/lib/nanoc2/filters/relativize_paths_in_html.rb +16 -0
- data/lib/nanoc2/filters/rubypants.rb +14 -0
- data/lib/nanoc2/filters/sass.rb +18 -0
- data/lib/nanoc2/helpers.rb +9 -0
- data/lib/nanoc2/helpers/blogging.rb +217 -0
- data/lib/nanoc2/helpers/capturing.rb +63 -0
- data/lib/nanoc2/helpers/filtering.rb +54 -0
- data/lib/nanoc2/helpers/html_escape.rb +25 -0
- data/lib/nanoc2/helpers/link_to.rb +113 -0
- data/lib/nanoc2/helpers/render.rb +49 -0
- data/lib/nanoc2/helpers/tagging.rb +56 -0
- data/lib/nanoc2/helpers/text.rb +38 -0
- data/lib/nanoc2/helpers/xml_sitemap.rb +63 -0
- data/lib/nanoc2/routers.rb +3 -0
- data/lib/nanoc2/routers/default.rb +54 -0
- data/lib/nanoc2/routers/no_dirs.rb +66 -0
- data/lib/nanoc2/routers/versioned.rb +79 -0
- metadata +185 -0
@@ -0,0 +1,286 @@
|
|
1
|
+
module Nanoc2
|
2
|
+
|
3
|
+
# Nanoc2::DataSource is responsible for loading data. It is the (abstract)
|
4
|
+
# superclass for all data sources. Subclasses must at least implement the
|
5
|
+
# data reading methods (+pages+, +page_defaults+, +layouts+, +templates+,
|
6
|
+
# and +code+); all other methods involving data manipulation are optional.
|
7
|
+
#
|
8
|
+
# Apart from the methods for loading and storing data, there are the +up+
|
9
|
+
# and +down+ methods for bringing up and tearing down the connection to the
|
10
|
+
# data source. These should be overridden in subclasses. The +loading+
|
11
|
+
# method wraps +up+ and +down+.
|
12
|
+
#
|
13
|
+
# The +setup+ method is used for setting up a site's data source for the
|
14
|
+
# first time. This method should be overridden in subclasses.
|
15
|
+
class DataSource < Plugin
|
16
|
+
|
17
|
+
# Creates a new data source for the given site.
|
18
|
+
def initialize(site)
|
19
|
+
@site = site
|
20
|
+
@references = 0
|
21
|
+
end
|
22
|
+
|
23
|
+
# Loads the data source when necessary (calling +up+), yields, and unloads
|
24
|
+
# the data source when it is not being used elsewhere. All data source
|
25
|
+
# queries and data manipulations should be wrapped in a +loading+ block;
|
26
|
+
# it ensures that the data source is loaded when necessary and makes sure
|
27
|
+
# the data source does not get unloaded while it is still being used
|
28
|
+
# elsewhere.
|
29
|
+
def loading
|
30
|
+
# Load if necessary
|
31
|
+
up if @references == 0
|
32
|
+
@references += 1
|
33
|
+
|
34
|
+
yield
|
35
|
+
ensure
|
36
|
+
# Unload if necessary
|
37
|
+
@references -= 1
|
38
|
+
down if @references == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
########## Loading and unloading
|
42
|
+
|
43
|
+
# Brings up the connection to the data. This is an abstract method
|
44
|
+
# implemented by the subclass. Depending on the way data is stored, this
|
45
|
+
# may not be necessary. This is the ideal place to connect to the
|
46
|
+
# database, for example.
|
47
|
+
#
|
48
|
+
# Subclasses may implement this method.
|
49
|
+
def up
|
50
|
+
end
|
51
|
+
|
52
|
+
# Brings down the connection to the data. This is an abstract method
|
53
|
+
# implemented by the subclass. This method should undo the effects of
|
54
|
+
# +up+.
|
55
|
+
#
|
56
|
+
# Subclasses may implement this method.
|
57
|
+
def down
|
58
|
+
end
|
59
|
+
|
60
|
+
########## Creating/updating
|
61
|
+
|
62
|
+
# Creates the bare minimum essentials for this data source to work. This
|
63
|
+
# action will likely be destructive. This method should not create sample
|
64
|
+
# data such as a default home page, a default layout, etc. For example, if
|
65
|
+
# you're using a database, this is where you should create the necessary
|
66
|
+
# tables for the data source to function properly.
|
67
|
+
#
|
68
|
+
# Subclasses must implement this method.
|
69
|
+
def setup
|
70
|
+
not_implemented('setup')
|
71
|
+
end
|
72
|
+
|
73
|
+
# Removes all data stored by this data source. This method undoes the
|
74
|
+
# effects of the +setup+ method.
|
75
|
+
#
|
76
|
+
# Subclasses must implement this method.
|
77
|
+
def destroy
|
78
|
+
not_implemented('destroy')
|
79
|
+
end
|
80
|
+
|
81
|
+
# Updated the content stored in this site to a newer version. A newer
|
82
|
+
# version of a data source may store content in a different format, and
|
83
|
+
# this method will update the stored content to this newer format.
|
84
|
+
#
|
85
|
+
# Subclasses may implement this method.
|
86
|
+
def update
|
87
|
+
end
|
88
|
+
|
89
|
+
########## Pages
|
90
|
+
|
91
|
+
# Returns the list of pages (represented by Nanoc2::Page) in this site.
|
92
|
+
# This is an abstract method implemented by the subclass.
|
93
|
+
#
|
94
|
+
# Subclasses must implement this method.
|
95
|
+
def pages
|
96
|
+
not_implemented('pages')
|
97
|
+
end
|
98
|
+
|
99
|
+
# Saves the given page in the data source, creating it if it doesn't exist
|
100
|
+
# yet and updating the existing copy otherwise.
|
101
|
+
#
|
102
|
+
# Subclasses must implement this method.
|
103
|
+
def save_page(page)
|
104
|
+
not_implemented('save_page')
|
105
|
+
end
|
106
|
+
|
107
|
+
# Changes the path of the given page to the given new path. When changing
|
108
|
+
# a page's path, this method must be used (save_page will not work).
|
109
|
+
#
|
110
|
+
# Subclasses must implement this method.
|
111
|
+
def move_page(page, new_path)
|
112
|
+
not_implemented('move_page')
|
113
|
+
end
|
114
|
+
|
115
|
+
# Removes the given page from the data source.
|
116
|
+
#
|
117
|
+
# Subclasses must implement this method.
|
118
|
+
def delete_page(page)
|
119
|
+
not_implemented('delete_page')
|
120
|
+
end
|
121
|
+
|
122
|
+
########## Assets
|
123
|
+
|
124
|
+
# Returns the list of assets (represented by Nanoc2::Asset) in this site.
|
125
|
+
# This is an abstract method implemented by the subclass.
|
126
|
+
#
|
127
|
+
# Subclasses must implement this method.
|
128
|
+
def assets
|
129
|
+
not_implemented('assets')
|
130
|
+
end
|
131
|
+
|
132
|
+
# Saves the given asset in the data source, creating it if it doesn't
|
133
|
+
# exist yet and updating the existing copy otherwise.
|
134
|
+
#
|
135
|
+
# Subclasses must implement this method.
|
136
|
+
def save_asset(asset)
|
137
|
+
not_implemented('save_asset')
|
138
|
+
end
|
139
|
+
|
140
|
+
# Changes the path of the given asset to the given new path. When changing
|
141
|
+
# a asset's path, this method must be used (save_asset will not work).
|
142
|
+
#
|
143
|
+
# Subclasses must implement this method.
|
144
|
+
def move_asset(asset, new_path)
|
145
|
+
not_implemented('move_asset')
|
146
|
+
end
|
147
|
+
|
148
|
+
# Removes the given asset from the data source.
|
149
|
+
#
|
150
|
+
# Subclasses must implement this method.
|
151
|
+
def delete_asset(asset)
|
152
|
+
not_implemented('delete_asset')
|
153
|
+
end
|
154
|
+
|
155
|
+
########## Page defaults
|
156
|
+
|
157
|
+
# Returns the page defaults (represented by Nanoc2::PageDefaults) of this
|
158
|
+
# site. This is an abstract method implemented by the subclass.
|
159
|
+
#
|
160
|
+
# Subclasses must implement this method.
|
161
|
+
def page_defaults
|
162
|
+
not_implemented('page_defaults')
|
163
|
+
end
|
164
|
+
|
165
|
+
# Saves the given page defaults in the data source.
|
166
|
+
#
|
167
|
+
# Subclasses must implement this method.
|
168
|
+
def save_page_defaults(page_defaults)
|
169
|
+
not_implemented('save_page_defaults')
|
170
|
+
end
|
171
|
+
|
172
|
+
########## Asset defaults
|
173
|
+
|
174
|
+
# Returns the asset defaults (represented by Nanoc2::AssetDefaults) of this
|
175
|
+
# site. This is an abstract method implemented by the subclass.
|
176
|
+
#
|
177
|
+
# Subclasses must implement this method.
|
178
|
+
def asset_defaults
|
179
|
+
not_implemented('asset_defaults')
|
180
|
+
end
|
181
|
+
|
182
|
+
# Saves the given asset defaults in the data source.
|
183
|
+
#
|
184
|
+
# Subclasses must implement this method.
|
185
|
+
def save_asset_defaults(asset_defaults)
|
186
|
+
not_implemented('save_asset_defaults')
|
187
|
+
end
|
188
|
+
|
189
|
+
########## Layouts
|
190
|
+
|
191
|
+
# Returns the list of layouts (represented by Nanoc2::Layout) in this site.
|
192
|
+
# This is an abstract method implemented by the subclass.
|
193
|
+
#
|
194
|
+
# Subclasses must implement this method.
|
195
|
+
def layouts
|
196
|
+
not_implemented('layouts')
|
197
|
+
end
|
198
|
+
|
199
|
+
# Saves the given layout in the data source, creating it if it doesn't
|
200
|
+
# exist yet and updating the existing copy otherwise.
|
201
|
+
#
|
202
|
+
# Subclasses must implement this method.
|
203
|
+
def save_layout(layout)
|
204
|
+
not_implemented('save_layout')
|
205
|
+
end
|
206
|
+
|
207
|
+
# Changes the path of the given layout to the given new path. When
|
208
|
+
# changing a layout's path, this method must be used (save_layout will not
|
209
|
+
# work).
|
210
|
+
#
|
211
|
+
# Subclasses must implement this method.
|
212
|
+
def move_layout(layout, new_path)
|
213
|
+
not_implemented('move_layout')
|
214
|
+
end
|
215
|
+
|
216
|
+
# Removes the given layout from the data source.
|
217
|
+
#
|
218
|
+
# Subclasses must implement this method.
|
219
|
+
def delete_layout(layout)
|
220
|
+
not_implemented('delete_layout')
|
221
|
+
end
|
222
|
+
|
223
|
+
########## Templates
|
224
|
+
|
225
|
+
# Returns the list of templates (represented by Nanoc2::Template) in this
|
226
|
+
# site. This is an abstract method implemented by the subclass.
|
227
|
+
#
|
228
|
+
# Subclasses must implement this method.
|
229
|
+
def templates
|
230
|
+
not_implemented('templates')
|
231
|
+
end
|
232
|
+
|
233
|
+
# Saves the given template in the data source, creating it if it doesn't
|
234
|
+
# exist yet and updating the existing copy otherwise.
|
235
|
+
#
|
236
|
+
# Subclasses must implement this method.
|
237
|
+
def save_template(template)
|
238
|
+
not_implemented('save_template')
|
239
|
+
end
|
240
|
+
|
241
|
+
# Changes the name of the given template to the given new name. When
|
242
|
+
# changing a template's name, this method must be used (save_template will
|
243
|
+
# not work).
|
244
|
+
#
|
245
|
+
# Subclasses must implement this method.
|
246
|
+
def move_template(template, new_name)
|
247
|
+
not_implemented('move_template')
|
248
|
+
end
|
249
|
+
|
250
|
+
# Removes the given template from the data source.
|
251
|
+
#
|
252
|
+
# Subclasses must implement this method.
|
253
|
+
def delete_template(template)
|
254
|
+
not_implemented('delete_template')
|
255
|
+
end
|
256
|
+
|
257
|
+
########## Code
|
258
|
+
|
259
|
+
# Returns the custom code (represented by Nanoc2::Code) for this site.
|
260
|
+
# This is an abstract method implemented by the subclass. This can be code
|
261
|
+
# for custom filters, routers, and more, but pretty much any code can
|
262
|
+
# be put in there (global helper functions are very useful).
|
263
|
+
#
|
264
|
+
# Subclasses must implement this method.
|
265
|
+
def code
|
266
|
+
not_implemented('code')
|
267
|
+
end
|
268
|
+
|
269
|
+
# Saves the given code in the data source.
|
270
|
+
#
|
271
|
+
# Subclasses must implement this method.
|
272
|
+
def save_code(code)
|
273
|
+
not_implemented('save_code')
|
274
|
+
end
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def not_implemented(name)
|
279
|
+
raise NotImplementedError.new(
|
280
|
+
"#{self.class} does not override ##{name}, which is required for " +
|
281
|
+
"this data source to be used."
|
282
|
+
)
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Nanoc2
|
2
|
+
|
3
|
+
# Nanoc2::Defaults represent the default attributes for a given set of
|
4
|
+
# objects in the site. It is basically a hash with an optional modification
|
5
|
+
# time.
|
6
|
+
class Defaults
|
7
|
+
|
8
|
+
# Th site where this set of defaults belongs to.
|
9
|
+
attr_accessor :site
|
10
|
+
|
11
|
+
# A hash containing the default attributes.
|
12
|
+
attr_reader :attributes
|
13
|
+
|
14
|
+
# The time when this set of defaults was last modified.
|
15
|
+
attr_reader :mtime
|
16
|
+
|
17
|
+
# Creates a new set of defaults.
|
18
|
+
#
|
19
|
+
# +attributes+:: The hash containing the metadata that individual objects
|
20
|
+
# will override.
|
21
|
+
#
|
22
|
+
# +mtime+:: The time when the defaults were last modified (optional).
|
23
|
+
def initialize(attributes, mtime=nil)
|
24
|
+
@attributes = attributes.clean
|
25
|
+
@mtime = mtime
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Nanoc2
|
2
|
+
|
3
|
+
# Nanoc2::Filter is responsible for filtering pages and textual assets
|
4
|
+
# (binary assets are filtered using Nanoc2::BinaryFilter). It is the
|
5
|
+
# (abstract) superclass for all textual filters. Subclasses should override
|
6
|
+
# the +run+ method.
|
7
|
+
class Filter < Plugin
|
8
|
+
|
9
|
+
# Deprecated
|
10
|
+
EXTENSIONS_MAP = {}
|
11
|
+
|
12
|
+
# Creates a new filter for the given object (page or asset) and site.
|
13
|
+
#
|
14
|
+
# +kind+:: The kind of object that is passed. Can be either +:page+ or
|
15
|
+
# +:asset+.
|
16
|
+
#
|
17
|
+
# +obj_rep+:: A proxy for the page or asset representation (Nanoc2::PageRep
|
18
|
+
# or Nanoc2::AssetRep) that should be compiled by this filter.
|
19
|
+
#
|
20
|
+
# +obj+:: A proxy for the page or asset's page (Nanoc2::Page or
|
21
|
+
# Nanoc2::Asset).
|
22
|
+
#
|
23
|
+
# +site+:: The site (Nanoc2::Site) this filter belongs to.
|
24
|
+
#
|
25
|
+
# +other_assigns+:: A hash containing other variables that should be made
|
26
|
+
# available during filtering.
|
27
|
+
def initialize(obj_rep, other_assigns={})
|
28
|
+
# Determine kind
|
29
|
+
@kind = obj_rep.is_a?(Nanoc2::PageRep) ? :page : :asset
|
30
|
+
|
31
|
+
# Set object
|
32
|
+
@obj_rep = obj_rep
|
33
|
+
@obj = (@kind == :page ? @obj_rep.page : @obj_rep.asset)
|
34
|
+
|
35
|
+
# Set page/asset and page/asset reps
|
36
|
+
if @kind == :page
|
37
|
+
@page = @obj
|
38
|
+
@page_rep = @obj_rep
|
39
|
+
else
|
40
|
+
@asset = @obj
|
41
|
+
@asset_rep = @obj_rep
|
42
|
+
end
|
43
|
+
|
44
|
+
# Set site
|
45
|
+
@site = @obj.site
|
46
|
+
|
47
|
+
# Set other assigns
|
48
|
+
@other_assigns = other_assigns
|
49
|
+
end
|
50
|
+
|
51
|
+
# Runs the filter. This method returns the filtered content.
|
52
|
+
#
|
53
|
+
# +content+:: The unprocessed content that should be filtered.
|
54
|
+
#
|
55
|
+
# Subclasses must implement this method.
|
56
|
+
def run(content)
|
57
|
+
raise NotImplementedError.new("Nanoc2::Filter subclasses must implement #run")
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns a hash with data that should be available.
|
61
|
+
def assigns
|
62
|
+
@assigns ||= @other_assigns.merge({
|
63
|
+
:_obj_rep => @obj_rep,
|
64
|
+
:_obj => @obj,
|
65
|
+
:page_rep => @kind == :page ? @page_rep.to_proxy : nil,
|
66
|
+
:page => @kind == :page ? @page.to_proxy : nil,
|
67
|
+
:asset_rep => @kind == :asset ? @asset_rep.to_proxy : nil,
|
68
|
+
:asset => @kind == :asset ? @asset.to_proxy : nil,
|
69
|
+
:pages => @site.pages.map { |obj| obj.to_proxy },
|
70
|
+
:assets => @site.assets.map { |obj| obj.to_proxy },
|
71
|
+
:layouts => @site.layouts.map { |obj| obj.to_proxy },
|
72
|
+
:config => @site.config,
|
73
|
+
:site => @site
|
74
|
+
})
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns the filename associated with the item that is being filtered.
|
78
|
+
# The returned filename is in the format "page <path> (rep <name>)".
|
79
|
+
def filename
|
80
|
+
if assigns[:layout]
|
81
|
+
"layout #{assigns[:layout].path}"
|
82
|
+
elsif assigns[:page]
|
83
|
+
"page #{assigns[:_obj].path} (rep #{assigns[:_obj_rep].name})"
|
84
|
+
elsif assigns[:asset]
|
85
|
+
"asset #{assigns[:_obj].path} (rep #{assigns[:_obj_rep].name})"
|
86
|
+
else
|
87
|
+
'?'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Nanoc2
|
2
|
+
|
3
|
+
# A Nanoc2::Layout represents a layout in a nanoc site. It has content,
|
4
|
+
# attributes (for determining which filter to use for laying out a page), a
|
5
|
+
# path (because layouts are organised hierarchically), and a modification
|
6
|
+
# time (to speed up compilation).
|
7
|
+
class Layout
|
8
|
+
|
9
|
+
# Default values for layouts.
|
10
|
+
DEFAULTS = {
|
11
|
+
:filter => 'erb'
|
12
|
+
}
|
13
|
+
|
14
|
+
# The Nanoc2::Site this layout belongs to.
|
15
|
+
attr_accessor :site
|
16
|
+
|
17
|
+
# The raw content of this layout.
|
18
|
+
attr_reader :content
|
19
|
+
|
20
|
+
# A hash containing this layout's attributes.
|
21
|
+
attr_reader :attributes
|
22
|
+
|
23
|
+
# This layout's path, starting and ending with a slash.
|
24
|
+
attr_reader :path
|
25
|
+
|
26
|
+
# The time when this layout was last modified.
|
27
|
+
attr_reader :mtime
|
28
|
+
|
29
|
+
# Creates a new layout.
|
30
|
+
#
|
31
|
+
# +content+:: The raw content of this layout.
|
32
|
+
#
|
33
|
+
# +attributes+:: A hash containing this layout's attributes.
|
34
|
+
#
|
35
|
+
# +path+:: This layout's path, starting and ending with a slash.
|
36
|
+
#
|
37
|
+
# +mtime+:: The time when this layout was last modified.
|
38
|
+
def initialize(content, attributes, path, mtime=nil)
|
39
|
+
@content = content
|
40
|
+
@attributes = attributes.clean
|
41
|
+
@path = path.cleaned_path
|
42
|
+
@mtime = mtime
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns a proxy (Nanoc2::LayoutProxy) for this layout.
|
46
|
+
def to_proxy
|
47
|
+
@proxy ||= LayoutProxy.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the attribute with the given name.
|
51
|
+
def attribute_named(name)
|
52
|
+
return @attributes[name] if @attributes.has_key?(name)
|
53
|
+
return DEFAULTS[name]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the filter class needed for this layout.
|
57
|
+
def filter_class
|
58
|
+
Nanoc2::Filter.named(attribute_named(:filter))
|
59
|
+
end
|
60
|
+
|
61
|
+
# Saves the layout in the database, creating it if it doesn't exist yet or
|
62
|
+
# updating it if it already exists. Tells the site's data source to save
|
63
|
+
# the layout.
|
64
|
+
def save
|
65
|
+
@site.data_source.loading do
|
66
|
+
@site.data_source.save_layout(self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Moves the layout to a new path. Tells the site's data source to move the
|
71
|
+
# layout.
|
72
|
+
def move_to(new_path)
|
73
|
+
@site.data_source.loading do
|
74
|
+
@site.data_source.move_layout(self, new_path)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Deletes the layout. Tells the site's data source to delete the layout.
|
79
|
+
def delete
|
80
|
+
@site.data_source.loading do
|
81
|
+
@site.data_source.delete_layout(self)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def inspect
|
86
|
+
"<#{self.class} path=#{self.path}>"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|