nanoc2 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/ChangeLog +3 -0
  2. data/LICENSE +19 -0
  3. data/README +75 -0
  4. data/Rakefile +76 -0
  5. data/bin/nanoc2 +26 -0
  6. data/lib/nanoc2.rb +73 -0
  7. data/lib/nanoc2/base.rb +26 -0
  8. data/lib/nanoc2/base/asset.rb +117 -0
  9. data/lib/nanoc2/base/asset_defaults.rb +21 -0
  10. data/lib/nanoc2/base/asset_rep.rb +282 -0
  11. data/lib/nanoc2/base/binary_filter.rb +44 -0
  12. data/lib/nanoc2/base/code.rb +41 -0
  13. data/lib/nanoc2/base/compiler.rb +67 -0
  14. data/lib/nanoc2/base/core_ext.rb +2 -0
  15. data/lib/nanoc2/base/core_ext/hash.rb +78 -0
  16. data/lib/nanoc2/base/core_ext/string.rb +8 -0
  17. data/lib/nanoc2/base/data_source.rb +286 -0
  18. data/lib/nanoc2/base/defaults.rb +30 -0
  19. data/lib/nanoc2/base/filter.rb +93 -0
  20. data/lib/nanoc2/base/layout.rb +91 -0
  21. data/lib/nanoc2/base/notification_center.rb +66 -0
  22. data/lib/nanoc2/base/page.rb +132 -0
  23. data/lib/nanoc2/base/page_defaults.rb +20 -0
  24. data/lib/nanoc2/base/page_rep.rb +324 -0
  25. data/lib/nanoc2/base/plugin.rb +71 -0
  26. data/lib/nanoc2/base/proxies.rb +5 -0
  27. data/lib/nanoc2/base/proxies/asset_proxy.rb +29 -0
  28. data/lib/nanoc2/base/proxies/asset_rep_proxy.rb +26 -0
  29. data/lib/nanoc2/base/proxies/layout_proxy.rb +25 -0
  30. data/lib/nanoc2/base/proxies/page_proxy.rb +35 -0
  31. data/lib/nanoc2/base/proxies/page_rep_proxy.rb +28 -0
  32. data/lib/nanoc2/base/proxy.rb +37 -0
  33. data/lib/nanoc2/base/router.rb +72 -0
  34. data/lib/nanoc2/base/site.rb +274 -0
  35. data/lib/nanoc2/base/template.rb +64 -0
  36. data/lib/nanoc2/binary_filters.rb +1 -0
  37. data/lib/nanoc2/binary_filters/image_science_thumbnail.rb +28 -0
  38. data/lib/nanoc2/cli.rb +9 -0
  39. data/lib/nanoc2/cli/base.rb +132 -0
  40. data/lib/nanoc2/cli/commands.rb +10 -0
  41. data/lib/nanoc2/cli/commands/autocompile.rb +80 -0
  42. data/lib/nanoc2/cli/commands/compile.rb +312 -0
  43. data/lib/nanoc2/cli/commands/create_layout.rb +85 -0
  44. data/lib/nanoc2/cli/commands/create_page.rb +85 -0
  45. data/lib/nanoc2/cli/commands/create_site.rb +323 -0
  46. data/lib/nanoc2/cli/commands/create_template.rb +76 -0
  47. data/lib/nanoc2/cli/commands/help.rb +69 -0
  48. data/lib/nanoc2/cli/commands/info.rb +125 -0
  49. data/lib/nanoc2/cli/commands/switch.rb +141 -0
  50. data/lib/nanoc2/cli/commands/update.rb +91 -0
  51. data/lib/nanoc2/cli/logger.rb +72 -0
  52. data/lib/nanoc2/data_sources.rb +2 -0
  53. data/lib/nanoc2/data_sources/filesystem.rb +707 -0
  54. data/lib/nanoc2/data_sources/filesystem_combined.rb +495 -0
  55. data/lib/nanoc2/extra.rb +6 -0
  56. data/lib/nanoc2/extra/auto_compiler.rb +285 -0
  57. data/lib/nanoc2/extra/context.rb +22 -0
  58. data/lib/nanoc2/extra/core_ext.rb +2 -0
  59. data/lib/nanoc2/extra/core_ext/hash.rb +54 -0
  60. data/lib/nanoc2/extra/core_ext/time.rb +13 -0
  61. data/lib/nanoc2/extra/file_proxy.rb +29 -0
  62. data/lib/nanoc2/extra/vcs.rb +48 -0
  63. data/lib/nanoc2/extra/vcses.rb +5 -0
  64. data/lib/nanoc2/extra/vcses/bazaar.rb +21 -0
  65. data/lib/nanoc2/extra/vcses/dummy.rb +20 -0
  66. data/lib/nanoc2/extra/vcses/git.rb +21 -0
  67. data/lib/nanoc2/extra/vcses/mercurial.rb +21 -0
  68. data/lib/nanoc2/extra/vcses/subversion.rb +21 -0
  69. data/lib/nanoc2/filters.rb +16 -0
  70. data/lib/nanoc2/filters/bluecloth.rb +13 -0
  71. data/lib/nanoc2/filters/erb.rb +19 -0
  72. data/lib/nanoc2/filters/erubis.rb +14 -0
  73. data/lib/nanoc2/filters/haml.rb +21 -0
  74. data/lib/nanoc2/filters/markaby.rb +14 -0
  75. data/lib/nanoc2/filters/maruku.rb +14 -0
  76. data/lib/nanoc2/filters/old.rb +19 -0
  77. data/lib/nanoc2/filters/rainpress.rb +13 -0
  78. data/lib/nanoc2/filters/rdiscount.rb +13 -0
  79. data/lib/nanoc2/filters/rdoc.rb +23 -0
  80. data/lib/nanoc2/filters/redcloth.rb +14 -0
  81. data/lib/nanoc2/filters/relativize_paths.rb +16 -0
  82. data/lib/nanoc2/filters/relativize_paths_in_css.rb +16 -0
  83. data/lib/nanoc2/filters/relativize_paths_in_html.rb +16 -0
  84. data/lib/nanoc2/filters/rubypants.rb +14 -0
  85. data/lib/nanoc2/filters/sass.rb +18 -0
  86. data/lib/nanoc2/helpers.rb +9 -0
  87. data/lib/nanoc2/helpers/blogging.rb +217 -0
  88. data/lib/nanoc2/helpers/capturing.rb +63 -0
  89. data/lib/nanoc2/helpers/filtering.rb +54 -0
  90. data/lib/nanoc2/helpers/html_escape.rb +25 -0
  91. data/lib/nanoc2/helpers/link_to.rb +113 -0
  92. data/lib/nanoc2/helpers/render.rb +49 -0
  93. data/lib/nanoc2/helpers/tagging.rb +56 -0
  94. data/lib/nanoc2/helpers/text.rb +38 -0
  95. data/lib/nanoc2/helpers/xml_sitemap.rb +63 -0
  96. data/lib/nanoc2/routers.rb +3 -0
  97. data/lib/nanoc2/routers/default.rb +54 -0
  98. data/lib/nanoc2/routers/no_dirs.rb +66 -0
  99. data/lib/nanoc2/routers/versioned.rb +79 -0
  100. metadata +185 -0
@@ -0,0 +1,71 @@
1
+ module Nanoc2
2
+
3
+ # Nanoc2::Plugin is the superclass for all plugins, such as filters
4
+ # (Nanoc2::Filter), binary filters (Nanoc2::BinaryFilter), routers
5
+ # (Nanoc2::Router), data sources (Nanoc2::DataSource) and VCSes
6
+ # (Nanoc2::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.
9
+ class Plugin
10
+
11
+ MAP = {}
12
+
13
+ class << self
14
+
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
+ if !instance_variables.include?('@identifiers') && !instance_variables.include?(:'@identifiers')
23
+ @identifiers = []
24
+ end
25
+
26
+ if identifiers.empty?
27
+ @identifiers
28
+ else
29
+ @identifiers = identifiers
30
+ @identifiers.each { |i| register(i, self) }
31
+ end
32
+ end
33
+
34
+ # Sets or returns the identifier for this plugin.
35
+ #
36
+ # When given an identifier symbols, sets the identifier for this plugin.
37
+ # When given nothing, returns the identifier for this plugin.
38
+ def identifier(identifier=nil)
39
+ # Initialize
40
+ if !instance_variables.include?('@identifiers') && !instance_variables.include?(:'@identifiers')
41
+ @identifiers = []
42
+ end
43
+
44
+ if identifier.nil?
45
+ @identifiers.first
46
+ else
47
+ @identifiers = [ identifier ]
48
+ register(identifier, self)
49
+ end
50
+ end
51
+
52
+ # Registers the given class +klass+ with the given name. This will allow
53
+ # the named method to find the class.
54
+ def register(name, klass)
55
+ MAP[klass.superclass] ||= {}
56
+ MAP[klass.superclass][name.to_sym] = klass
57
+ end
58
+
59
+ # Returns the the plugin with the given name. Only subclasses of this
60
+ # class will be searched. For example, calling this method on
61
+ # Nanoc2::Filter will cause only Nanoc2::Filter subclasses to be searched.
62
+ def named(name)
63
+ MAP[self] ||= {}
64
+ MAP[self][name.to_sym]
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,5 @@
1
+ require 'nanoc2/base/proxies/asset_proxy'
2
+ require 'nanoc2/base/proxies/asset_rep_proxy'
3
+ require 'nanoc2/base/proxies/layout_proxy'
4
+ require 'nanoc2/base/proxies/page_proxy'
5
+ require 'nanoc2/base/proxies/page_rep_proxy'
@@ -0,0 +1,29 @@
1
+ module Nanoc2
2
+
3
+ # Nanoc2::AssetProxy is a proxy object for an asset (Nanoc2::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 Nanoc2
2
+
3
+ # Nanoc2::AssetRepProxy is a proxy object for an asset representation
4
+ # (Nanoc2::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
@@ -0,0 +1,25 @@
1
+ module Nanoc2
2
+
3
+ # Nanoc2::LayoutProxy is a proxy object for a layout (Nanoc2::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 Nanoc2
2
+
3
+ # Nanoc2::PageProxy is a proxy object for a page (Nanoc2::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 Nanoc2
2
+
3
+ # Nanoc2::PageRepProxy is a proxy object for a page representation
4
+ # (Nanoc2::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 Nanoc2
2
+
3
+ # Nanoc2::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 =~ /^__/ || m.to_s == 'object_id' }
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 Nanoc2
2
+
3
+ # A Nanoc2::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("Nanoc2::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("Nanoc2::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?(Nanoc2::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?(Nanoc2::PageRep) ? path_for_page_rep(obj) : path_for_asset_rep(obj))
67
+ )
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,274 @@
1
+ module Nanoc2
2
+
3
+ # A Nanoc2::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 Nanoc2::Page instances representing pages
7
+ # * +assets+ is a list of Nanoc2::Asset instances representing assets
8
+ # * +page_defaults+ is a Nanoc2::PageDefaults instance representing page
9
+ # defaults
10
+ # * +asset_defaults+ is a Nanoc2::AssetDefaults instance representing asset
11
+ # defaults
12
+ # * +layouts+ is a list of Nanoc2::Layout instances representing layouts
13
+ # * +templates+ is a list of Nanoc2::Template representing templates
14
+ # * +code+ is a Nanoc2::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 Nanoc2::Router subclass instance used for determining page
38
+ # and asset paths.
39
+ # * +data_source+ is a Nanoc2::DataSource subclass instance used for managing
40
+ # site data.
41
+ # * +compiler+ is a Nanoc2::Compiler instance that compiles page and asset
42
+ # representations.
43
+ #
44
+ # The physical representation of a Nanoc2::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.
49
+ class Site
50
+
51
+ # The default configuration for a site. A site's configuration overrides
52
+ # these options: when a Nanoc2::Site is created with a configuration that
53
+ # lacks some options, the default value will be taken from
54
+ # +DEFAULT_CONFIG+.
55
+ DEFAULT_CONFIG = {
56
+ :output_dir => 'output',
57
+ :data_source => 'filesystem',
58
+ :router => 'default',
59
+ :index_filenames => [ 'index.html' ]
60
+ }
61
+
62
+ attr_reader :config
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 Nanoc2::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)
72
+ # Load configuration
73
+ @config = DEFAULT_CONFIG.merge(config.clean)
74
+
75
+ # Create data source
76
+ @data_source_class = Nanoc2::DataSource.named(@config[:data_source])
77
+ raise Nanoc2::Errors::UnknownDataSourceError.new(@config[:data_source]) if @data_source_class.nil?
78
+ @data_source = @data_source_class.new(self)
79
+
80
+ # Create compiler
81
+ @compiler = Compiler.new(self)
82
+
83
+ # Load code (necessary for custom routers)
84
+ load_code
85
+
86
+ # Create router
87
+ @router_class = Nanoc2::Router.named(@config[:router])
88
+ raise Nanoc2::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 = []
100
+ end
101
+
102
+ # Loads the site data. This will query the Nanoc2::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.
109
+ def load_data(force=false)
110
+ # Don't load data twice
111
+ @data_loaded ||= false
112
+ return if @data_loaded and !force
113
+
114
+ # Load all data
115
+ @data_source.loading do
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]) }
184
+ end
185
+
186
+ # Set site
187
+ @pages.each { |p| p.site = self }
188
+
189
+ # Setup child-parent links
190
+ @pages.each do |page|
191
+ # Get parent
192
+ parent_path = page.path.sub(/[^\/]+\/$/, '')
193
+ parent = @pages.find { |p| p.path == parent_path }
194
+ next if parent.nil? or page.path == '/'
195
+
196
+ # Link
197
+ page.parent = parent
198
+ parent.children << page
199
+ end
200
+
201
+ # Build page representations
202
+ @pages.each { |p| p.build_reps }
203
+ end
204
+
205
+ # Loads this site's asset defaults.
206
+ def load_asset_defaults
207
+ # Get page defaults
208
+ @asset_defaults = @data_source.asset_defaults
209
+
210
+ # Set site
211
+ @asset_defaults.site = self
212
+ rescue NotImplementedError
213
+ @asset_defaults = AssetDefaults.new({})
214
+ @asset_defaults.site = self
215
+ end
216
+
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
222
+
223
+ # Set site
224
+ @assets.each { |a| a.site = self }
225
+
226
+ # Build asset representations
227
+ @assets.each { |p| p.build_reps }
228
+ rescue NotImplementedError
229
+ @assets = []
230
+ end
231
+
232
+ # Loads this site's layouts.
233
+ def load_layouts
234
+ # Get layouts
235
+ @layouts = @data_source.layouts
236
+
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
242
+
243
+ # Set site
244
+ @layouts.each { |l| l.site = self }
245
+ end
246
+
247
+ # Loads this site's templates.
248
+ def load_templates
249
+ # Get templates
250
+ @templates = @data_source.templates
251
+
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
257
+
258
+ # Set site
259
+ @templates.each { |t| t.site = self }
260
+ end
261
+
262
+ # Raises a warning about an outdated data source method.
263
+ def warn_data_source(class_name, method_name, is_array)
264
+ warn(
265
+ "DEPRECATION WARNING: In nanoc 2.1, DataSource##{method_name} " +
266
+ "should return #{is_array ? 'an array of' : 'a' } " +
267
+ "Nanoc2::#{class_name} object#{is_array ? 's' : ''}. Future " +
268
+ "versions will not support these outdated data sources."
269
+ )
270
+ end
271
+
272
+ end
273
+
274
+ end