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.
Files changed (99) hide show
  1. data/ChangeLog +31 -1
  2. data/LICENSE +1 -1
  3. data/README +63 -3
  4. data/Rakefile +59 -12
  5. data/bin/nanoc +7 -199
  6. data/lib/nanoc.rb +83 -12
  7. data/lib/nanoc/base/asset.rb +113 -0
  8. data/lib/nanoc/base/asset_defaults.rb +21 -0
  9. data/lib/nanoc/base/asset_rep.rb +277 -0
  10. data/lib/nanoc/base/binary_filter.rb +44 -0
  11. data/lib/nanoc/base/code.rb +41 -0
  12. data/lib/nanoc/base/compiler.rb +46 -34
  13. data/lib/nanoc/base/core_ext/hash.rb +51 -7
  14. data/lib/nanoc/base/core_ext/string.rb +8 -0
  15. data/lib/nanoc/base/data_source.rb +253 -20
  16. data/lib/nanoc/base/defaults.rb +30 -0
  17. data/lib/nanoc/base/enhancements.rb +9 -84
  18. data/lib/nanoc/base/filter.rb +109 -6
  19. data/lib/nanoc/base/layout.rb +91 -0
  20. data/lib/nanoc/base/notification_center.rb +66 -0
  21. data/lib/nanoc/base/page.rb +94 -126
  22. data/lib/nanoc/base/page_defaults.rb +20 -0
  23. data/lib/nanoc/base/page_rep.rb +318 -0
  24. data/lib/nanoc/base/plugin.rb +57 -9
  25. data/lib/nanoc/base/proxies/asset_proxy.rb +29 -0
  26. data/lib/nanoc/base/proxies/asset_rep_proxy.rb +26 -0
  27. data/lib/nanoc/base/proxies/layout_proxy.rb +25 -0
  28. data/lib/nanoc/base/proxies/page_proxy.rb +35 -0
  29. data/lib/nanoc/base/proxies/page_rep_proxy.rb +28 -0
  30. data/lib/nanoc/base/proxy.rb +37 -0
  31. data/lib/nanoc/base/router.rb +72 -0
  32. data/lib/nanoc/base/site.rb +219 -88
  33. data/lib/nanoc/base/template.rb +64 -0
  34. data/lib/nanoc/binary_filters/image_science_thumbnail.rb +28 -0
  35. data/lib/nanoc/cli.rb +1 -0
  36. data/lib/nanoc/cli/base.rb +219 -0
  37. data/lib/nanoc/cli/cli.rb +16 -0
  38. data/lib/nanoc/cli/command.rb +105 -0
  39. data/lib/nanoc/cli/commands/autocompile.rb +80 -0
  40. data/lib/nanoc/cli/commands/compile.rb +273 -0
  41. data/lib/nanoc/cli/commands/create_layout.rb +85 -0
  42. data/lib/nanoc/cli/commands/create_page.rb +85 -0
  43. data/lib/nanoc/cli/commands/create_site.rb +327 -0
  44. data/lib/nanoc/cli/commands/create_template.rb +76 -0
  45. data/lib/nanoc/cli/commands/help.rb +69 -0
  46. data/lib/nanoc/cli/commands/info.rb +114 -0
  47. data/lib/nanoc/cli/commands/switch.rb +141 -0
  48. data/lib/nanoc/cli/commands/update.rb +91 -0
  49. data/lib/nanoc/cli/ext.rb +37 -0
  50. data/lib/nanoc/cli/logger.rb +66 -0
  51. data/lib/nanoc/cli/option_parser.rb +168 -0
  52. data/lib/nanoc/data_sources/filesystem.rb +645 -224
  53. data/lib/nanoc/data_sources/filesystem_combined.rb +495 -0
  54. data/lib/nanoc/extra/auto_compiler.rb +265 -0
  55. data/lib/nanoc/extra/context.rb +22 -0
  56. data/lib/nanoc/extra/core_ext/hash.rb +54 -0
  57. data/lib/nanoc/extra/core_ext/time.rb +13 -0
  58. data/lib/nanoc/extra/file_proxy.rb +29 -0
  59. data/lib/nanoc/extra/vcs.rb +48 -0
  60. data/lib/nanoc/extra/vcses/bazaar.rb +21 -0
  61. data/lib/nanoc/extra/vcses/dummy.rb +20 -0
  62. data/lib/nanoc/extra/vcses/git.rb +21 -0
  63. data/lib/nanoc/extra/vcses/mercurial.rb +21 -0
  64. data/lib/nanoc/extra/vcses/subversion.rb +21 -0
  65. data/lib/nanoc/filters/bluecloth.rb +13 -0
  66. data/lib/nanoc/filters/erb.rb +6 -22
  67. data/lib/nanoc/filters/erubis.rb +14 -0
  68. data/lib/nanoc/filters/haml.rb +7 -23
  69. data/lib/nanoc/filters/markaby.rb +5 -5
  70. data/lib/nanoc/filters/maruku.rb +14 -0
  71. data/lib/nanoc/filters/old.rb +19 -0
  72. data/lib/nanoc/filters/rdiscount.rb +13 -0
  73. data/lib/nanoc/filters/rdoc.rb +5 -4
  74. data/lib/nanoc/filters/redcloth.rb +14 -0
  75. data/lib/nanoc/filters/rubypants.rb +14 -0
  76. data/lib/nanoc/filters/sass.rb +13 -0
  77. data/lib/nanoc/helpers/blogging.rb +170 -0
  78. data/lib/nanoc/helpers/capturing.rb +59 -0
  79. data/lib/nanoc/helpers/html_escape.rb +23 -0
  80. data/lib/nanoc/helpers/link_to.rb +69 -0
  81. data/lib/nanoc/helpers/render.rb +47 -0
  82. data/lib/nanoc/helpers/tagging.rb +52 -0
  83. data/lib/nanoc/helpers/xml_sitemap.rb +58 -0
  84. data/lib/nanoc/routers/default.rb +54 -0
  85. data/lib/nanoc/routers/no_dirs.rb +66 -0
  86. data/lib/nanoc/routers/versioned.rb +79 -0
  87. metadata +112 -22
  88. data/lib/nanoc/base/auto_compiler.rb +0 -132
  89. data/lib/nanoc/base/layout_processor.rb +0 -33
  90. data/lib/nanoc/base/page_proxy.rb +0 -31
  91. data/lib/nanoc/base/plugin_manager.rb +0 -33
  92. data/lib/nanoc/data_sources/database.rb +0 -259
  93. data/lib/nanoc/data_sources/trivial.rb +0 -145
  94. data/lib/nanoc/filters/markdown.rb +0 -13
  95. data/lib/nanoc/filters/smartypants.rb +0 -13
  96. data/lib/nanoc/filters/textile.rb +0 -13
  97. data/lib/nanoc/layout_processors/erb.rb +0 -35
  98. data/lib/nanoc/layout_processors/haml.rb +0 -38
  99. data/lib/nanoc/layout_processors/markaby.rb +0 -16
@@ -0,0 +1,25 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::LayoutProxy is a proxy object for a layout (Nanoc::Layout).
4
+ class LayoutProxy < Proxy
5
+
6
+ # Requests the layout 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 == :content
13
+ @obj.content
14
+ elsif real_key == :path
15
+ @obj.path
16
+ elsif real_key == :mtime
17
+ @obj.mtime
18
+ else
19
+ super(key)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,35 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::PageProxy is a proxy object for a page (Nanoc::Page).
4
+ class PageProxy < Proxy
5
+
6
+ # Requests the page 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 == :parent
15
+ @obj.parent.nil? ? nil : @obj.parent.to_proxy
16
+ elsif real_key == :children
17
+ @obj.children.map { |page| page.to_proxy }
18
+ elsif real_key == :content # backward compatibility
19
+ @obj.reps.find { |r| r.name == :default }.content
20
+ elsif real_key == :path # backward compatibility
21
+ @obj.reps.find { |r| r.name == :default }.web_path
22
+ else
23
+ super(key)
24
+ end
25
+ end
26
+
27
+ # Returns the page representation with the given name.
28
+ def reps(name)
29
+ rep = @obj.reps.find { |r| r.name == name }
30
+ rep.nil? ? nil : rep.to_proxy
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,28 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::PageRepProxy is a proxy object for a page representation
4
+ # (Nanoc::PageRep).
5
+ class PageRepProxy < Proxy
6
+
7
+ # Requests the page 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 == :content
16
+ @obj.content
17
+ elsif real_key == :path
18
+ @obj.web_path
19
+ elsif real_key == :page
20
+ @obj.page.to_proxy
21
+ else
22
+ super(key)
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,37 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::Proxy is used when making data available to pages and layouts.
4
+ # It provides an easy way to access data without the risk of accidentally
5
+ # calling destructive methods.
6
+ class Proxy
7
+
8
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
9
+
10
+ # Creates a proxy for the given object.
11
+ def initialize(obj)
12
+ @obj = obj
13
+ end
14
+
15
+ # Requests the attribute with the given name. +key+ can be a string or a
16
+ # symbol, and it can contain a trailing question mark (which will be
17
+ # stripped).
18
+ def [](key)
19
+ real_key = key.to_s.sub(/\?$/, '').to_sym
20
+
21
+ @obj.attribute_named(real_key)
22
+ end
23
+
24
+ # Sets a given attribute. The use of setting an object's attributes is not
25
+ # recommended but may be necessary in some cases.
26
+ def []=(key, value)
27
+ @obj.attributes[key.to_sym] = value
28
+ end
29
+
30
+ # Used for requesting attributes without accessing the proxy like a hash.
31
+ def method_missing(method, *args)
32
+ self[method]
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,72 @@
1
+ module Nanoc
2
+
3
+ # A Nanoc::Router is an abstract superclass that determines the paths of
4
+ # page and asset representations, both the path on the disk (relative to the
5
+ # site's output directory) and the path as it appears on the web site.
6
+ class Router < Plugin
7
+
8
+ # Creates a new router for the given site.
9
+ def initialize(site)
10
+ @site = site
11
+ end
12
+
13
+ # Returns the routed path for the given page representation, including the
14
+ # filename and the extension. It should start with a slash, and should be
15
+ # relative to the web root (i.e. should not include any references to the
16
+ # output directory). There is no need to let this method handle custom
17
+ # paths.
18
+ #
19
+ # Subclasses must implement this method.
20
+ def path_for_page_rep(page_rep)
21
+ raise NotImplementedError.new("Nanoc::Router subclasses must implement #path_for_page_rep.")
22
+ end
23
+
24
+ # Returns the routed path for the given asset representation, including
25
+ # the filename and the extension. It should start with a slash, and should
26
+ # be relative to the web root (i.e. should not include any references to
27
+ # the output directory). There is no need to let this method handle custom
28
+ # paths.
29
+ #
30
+ # Subclasses must implement this method.
31
+ def path_for_asset_rep(asset_rep)
32
+ raise NotImplementedError.new("Nanoc::Router subclasses must implement #path_for_asset_rep.")
33
+ end
34
+
35
+ # Returns the web path for the given page or asset representation, i.e.
36
+ # the page or asset rep's custom path or routed path with index filenames
37
+ # stripped.
38
+ def web_path_for(obj)
39
+ # Get actual path
40
+ path ||= obj.attribute_named(:custom_path)
41
+ if obj.is_a?(Nanoc::PageRep) # Page rep
42
+ path ||= path_for_page_rep(obj)
43
+ else # Asset rep
44
+ path ||= path_for_asset_rep(obj)
45
+ end
46
+
47
+ # Try stripping each index filename
48
+ @site.config[:index_filenames].each do |index_filename|
49
+ if path[-index_filename.length..-1] == index_filename
50
+ # Strip and stop
51
+ path = path[0..-index_filename.length-1]
52
+ break
53
+ end
54
+ end
55
+
56
+ # Return possibly stripped path
57
+ path
58
+ end
59
+
60
+ # Returns the disk path for the given page or asset representation, i.e.
61
+ # the page or asset's custom path or routed path relative to the output
62
+ # directory.
63
+ def disk_path_for(obj)
64
+ @site.config[:output_dir] + (
65
+ obj.attribute_named(:custom_path) ||
66
+ (obj.is_a?(Nanoc::PageRep) ? path_for_page_rep(obj) : path_for_asset_rep(obj))
67
+ )
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -1,51 +1,191 @@
1
1
  module Nanoc
2
+
3
+ # A Nanoc::Site is the in-memory representation of a nanoc site. It holds
4
+ # references to the following site data:
5
+ #
6
+ # * +pages+ is a list of Nanoc::Page instances representing pages
7
+ # * +assets+ is a list of Nanoc::Asset instances representing assets
8
+ # * +page_defaults+ is a Nanoc::PageDefaults instance representing page
9
+ # defaults
10
+ # * +asset_defaults+ is a Nanoc::AssetDefaults instance representing asset
11
+ # defaults
12
+ # * +layouts+ is a list of Nanoc::Layout instances representing layouts
13
+ # * +templates+ is a list of Nanoc::Template representing templates
14
+ # * +code+ is a Nanoc::Code instance representing custom site code
15
+ #
16
+ # In addition, each site has a +config+ hash which stores the site
17
+ # configuration. This configuration hash can have the following keys:
18
+ #
19
+ # +output_dir+:: The directory to which compiled pages and assets will be
20
+ # written. This path is relative to the current working
21
+ # directory, but can also be an absolute path.
22
+ #
23
+ # +data_source+:: The identifier of the data source that will be used for
24
+ # loading site data.
25
+ #
26
+ # +router+:: The identifier of the router that will be used for determining
27
+ # page and asset representation paths.
28
+ #
29
+ # +index_filenames+:: A list of filenames that will be stripped off full
30
+ # page and asset paths to create cleaner URLs (for
31
+ # example, '/about/' will be used instead of
32
+ # '/about/index.html'). The default value should be okay
33
+ # in most cases.
34
+ #
35
+ # A site also has several helper classes:
36
+ #
37
+ # * +router+ is a Nanoc::Router subclass instance used for determining page
38
+ # and asset paths.
39
+ # * +data_source+ is a Nanoc::DataSource subclass instance used for managing
40
+ # site data.
41
+ # * +compiler+ is a Nanoc::Compiler instance that compiles page and asset
42
+ # representations.
43
+ #
44
+ # The physical representation of a Nanoc::Site is usually a directory that
45
+ # contains a configuration file, site data, and some rake tasks. However,
46
+ # different frontends may store data differently. For example, a web-based
47
+ # frontend would probably store the configuration and the site content in a
48
+ # database, and would not have rake tasks at all.
2
49
  class Site
3
50
 
51
+ # The default configuration for a site. A site's configuration overrides
52
+ # these options: when a Nanoc::Site is created with a configuration that
53
+ # lacks some options, the default value will be taken from
54
+ # +DEFAULT_CONFIG+.
4
55
  DEFAULT_CONFIG = {
5
- :output_dir => 'output',
6
- :eruby_engine => 'erb',
7
- :data_source => 'filesystem'
56
+ :output_dir => 'output',
57
+ :data_source => 'filesystem',
58
+ :router => 'default',
59
+ :index_filenames => [ 'index.html' ]
8
60
  }
9
61
 
10
62
  attr_reader :config
11
- attr_reader :compiler, :data_source
12
- attr_reader :code, :pages, :page_defaults, :layouts, :templates
13
-
14
- # Creating a Site object
15
-
16
- def self.from_cwd
17
- File.file?('config.yaml') ? new : nil
18
- end
19
-
20
- def initialize
63
+ attr_reader :compiler, :data_source, :router
64
+ attr_reader :page_defaults, :asset_defaults
65
+ attr_reader :pages, :assets, :layouts, :templates, :code
66
+
67
+ # Returns a Nanoc::Site object for the site specified by the given
68
+ # configuration hash +config+.
69
+ #
70
+ # +config+:: A hash containing the site configuration.
71
+ def initialize(config)
21
72
  # Load configuration
22
- @config = DEFAULT_CONFIG.merge((YAML.load_file('config.yaml') || {}).clean)
73
+ @config = DEFAULT_CONFIG.merge(config.clean)
23
74
 
24
75
  # Create data source
25
- @data_source_class = PluginManager.data_source_named(@config[:data_source])
26
- error "Unrecognised data source: #{@config[:data_source]}" if @data_source_class.nil?
76
+ @data_source_class = Nanoc::DataSource.named(@config[:data_source])
77
+ raise Nanoc::Errors::UnknownDataSourceError.new(@config[:data_source]) if @data_source_class.nil?
27
78
  @data_source = @data_source_class.new(self)
28
79
 
29
80
  # Create compiler
30
- @compiler = Compiler.new(self)
31
- @autocompiler = AutoCompiler.new(self)
32
-
33
- # Set not loaded
34
- @data_loaded = false
81
+ @compiler = Compiler.new(self)
82
+
83
+ # Load code (necessary for custom routers)
84
+ load_code
85
+
86
+ # Create router
87
+ @router_class = Nanoc::Router.named(@config[:router])
88
+ raise Nanoc::Errors::UnknownRouterError.new(@config[:router]) if @router_class.nil?
89
+ @router = @router_class.new(self)
90
+
91
+ # Initialize data
92
+ @page_defaults = PageDefaults.new({})
93
+ @page_defaults.site = self
94
+ @asset_defaults = AssetDefaults.new({})
95
+ @asset_defaults.site = self
96
+ @pages = []
97
+ @assets = []
98
+ @layouts = []
99
+ @templates = []
35
100
  end
36
101
 
102
+ # Loads the site data. This will query the Nanoc::DataSource associated
103
+ # with the site and fetch all site data. The site data is cached, so
104
+ # calling this method will not have any effect the second time, unless
105
+ # +force+ is true.
106
+ #
107
+ # +force+:: If true, will force load the site data even if it has been
108
+ # loaded before, to circumvent caching issues.
37
109
  def load_data(force=false)
110
+ # Don't load data twice
111
+ @data_loaded ||= false
38
112
  return if @data_loaded and !force
39
113
 
40
- # Load data
114
+ # Load all data
41
115
  @data_source.loading do
42
- @code = @data_source.code
43
- @pages = @data_source.pages.map { |p| Page.new(p, self) }
44
- @page_defaults = @data_source.page_defaults
45
- @layouts = @data_source.layouts
46
- @templates = @data_source.templates
116
+ load_code(force)
117
+ load_page_defaults
118
+ load_pages
119
+ load_asset_defaults
120
+ load_assets
121
+ load_layouts
122
+ load_templates
123
+ end
124
+
125
+ # Set loaded
126
+ @data_loaded = true
127
+ end
128
+
129
+ private
130
+
131
+ # Loads this site's code and executes it.
132
+ def load_code(force=false)
133
+ # Don't load code twice
134
+ @code_loaded ||= false
135
+ return if @code_loaded and !force
136
+
137
+ # Get code
138
+ @code = @data_source.code
139
+
140
+ # Fix code if outdated
141
+ if @code.is_a? String
142
+ warn_data_source('Code', 'code', false)
143
+ @code = Code.new(code)
144
+ end
145
+
146
+ # Set site
147
+ @code.site = self
148
+
149
+ # Execute code
150
+ # FIXME This could be dangerous when using nanoc as a framework
151
+ # (a separate ruby process should probably be forked, and the code
152
+ # should only be loaded in this forked process)
153
+ @code.load
154
+
155
+ # Set loaded
156
+ @code_loaded = true
157
+ end
158
+
159
+ # Loads this site's page defaults.
160
+ def load_page_defaults
161
+ # Get page defaults
162
+ @page_defaults = @data_source.page_defaults
163
+
164
+ # Fix page defaults if outdated
165
+ if @page_defaults.is_a? Hash
166
+ warn_data_source('PageDefaults', 'page_defaults', false)
167
+ @page_defaults = PageDefaults.new(@page_defaults)
168
+ end
169
+
170
+ # Set site
171
+ @page_defaults.site = self
172
+ end
173
+
174
+ # Loads this site's pages, sets up page child-parent relationships and
175
+ # builds each page's list of page representations.
176
+ def load_pages
177
+ # Get pages
178
+ @pages = @data_source.pages
179
+
180
+ # Fix pages if outdated
181
+ if @pages.any? { |p| p.is_a? Hash }
182
+ warn_data_source('Page', 'pages', true)
183
+ @pages.map! { |p| Page.new(p[:uncompiled_content], p, p[:path]) }
47
184
  end
48
185
 
186
+ # Set site
187
+ @pages.each { |p| p.site = self }
188
+
49
189
  # Setup child-parent links
50
190
  @pages.each do |page|
51
191
  # Get parent
@@ -58,84 +198,75 @@ module Nanoc
58
198
  parent.children << page
59
199
  end
60
200
 
61
- # Set loaded
62
- @data_loaded = true
63
- end
64
-
65
- # Creating a new site on disk
66
-
67
- def self.create(sitename)
68
- # Check whether site exists
69
- error "A site named '#{sitename}' already exists." if File.exist?(sitename)
70
-
71
- FileUtils.mkdir_p sitename
72
- in_dir([sitename]) do
73
- # Create output
74
- FileManager.create_dir 'output'
75
-
76
- # Create config
77
- FileManager.create_file 'config.yaml' do
78
- "output_dir: \"output\"\n" +
79
- "data_source: \"filesystem\"\n"
80
- end
81
-
82
- # Create rakefile
83
- FileManager.create_file 'Rakefile' do
84
- "Dir['tasks/**/*.rake'].sort.each { |rakefile| load rakefile }\n" +
85
- "\n" +
86
- "task :default do\n" +
87
- " puts 'This is an example rake task.'\n" +
88
- "end\n"
89
- end
90
-
91
- # Create tasks
92
- FileManager.create_file 'tasks/default.rake' do
93
- "task :example do\n" +
94
- " puts 'This is an example rake task in tasks/default.rake.'\n" +
95
- "end\n"
96
- end
97
-
98
- # Setup site
99
- Site.from_cwd.setup
100
- end
201
+ # Build page representations
202
+ @pages.each { |p| p.build_reps }
101
203
  end
102
204
 
103
- # Compiling
205
+ # Loads this site's asset defaults.
206
+ def load_asset_defaults
207
+ # Get page defaults
208
+ @asset_defaults = @data_source.asset_defaults
104
209
 
105
- def compile
106
- @compiler.run
210
+ # Set site
211
+ @asset_defaults.site = self
212
+ rescue NotImplementedError
213
+ @asset_defaults = AssetDefaults.new({})
214
+ @asset_defaults.site = self
107
215
  end
108
216
 
109
- def autocompile(port)
110
- @autocompiler.start(port)
111
- end
217
+ # Loads this site's assets and builds each asset's list of asset
218
+ # representations.
219
+ def load_assets
220
+ # Get assets
221
+ @assets = @data_source.assets
112
222
 
113
- # Creating
223
+ # Set site
224
+ @assets.each { |a| a.site = self }
114
225
 
115
- def setup
116
- @data_source.loading { @data_source.setup }
226
+ # Build asset representations
227
+ @assets.each { |p| p.build_reps }
228
+ rescue NotImplementedError
229
+ @assets = []
117
230
  end
118
231
 
119
- def create_page(name, template_name='default')
120
- load_data
232
+ # Loads this site's layouts.
233
+ def load_layouts
234
+ # Get layouts
235
+ @layouts = @data_source.layouts
121
236
 
122
- template = @templates.find { |t| t[:name] == template_name }
123
- error "A template named '#{template_name}' was not found; aborting." if template.nil?
237
+ # Fix layouts if outdated
238
+ if @layouts.any? { |l| l.is_a? Hash }
239
+ warn_data_source('Layout', 'layouts', true)
240
+ @layouts.map! { |l| Layout.new(l[:content], l, l[:path] || l[:name]) }
241
+ end
124
242
 
125
- @data_source.loading { @data_source.create_page(name, template) }
243
+ # Set site
244
+ @layouts.each { |l| l.site = self }
126
245
  end
127
246
 
128
- def create_template(name)
129
- load_data
247
+ # Loads this site's templates.
248
+ def load_templates
249
+ # Get templates
250
+ @templates = @data_source.templates
130
251
 
131
- @data_source.loading {@data_source.create_template(name) }
132
- end
252
+ # Fix templates if outdated
253
+ if @templates.any? { |t| t.is_a? Hash }
254
+ warn_data_source('Template', 'templates', true)
255
+ @templates.map! { |t| Template.new(t[:content], t[:meta].is_a?(String) ? YAML.load(t[:meta]) : t[:meta], t[:name]) }
256
+ end
133
257
 
134
- def create_layout(name)
135
- load_data
258
+ # Set site
259
+ @templates.each { |t| t.site = self }
260
+ end
136
261
 
137
- @data_source.loading { @data_source.create_layout(name) }
262
+ # Raises a warning about an outdated data source method.
263
+ def warn_data_source(class_name, method_name, is_array)
264
+ warn(
265
+ "In nanoc 2.1, DataSource##{method_name} should return #{is_array ? 'an array of' : 'a' } Nanoc::#{class_name} object#{is_array ? 's' : ''}. Future versions will not support these outdated data sources.",
266
+ 'DEPRECATION WARNING'
267
+ )
138
268
  end
139
269
 
140
270
  end
271
+
141
272
  end