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.
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