nanoc 1.5 → 1.6

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 CHANGED
@@ -1,11 +1,25 @@
1
- == 1.5
1
+ nanoc Release Notes
2
+ ===================
3
+
4
+ 1.6
5
+ ---
6
+
7
+ * Added support for post-layout filters
8
+ * Added support for getting a File object for the page, so you can now e.g.
9
+ easily get the modification time for a given page (`@page.file.mtime`).
10
+ * Cleaned up the source code a lot
11
+ * Removed deprecated asset-copying functionality
12
+
13
+ 1.5
14
+ ---
2
15
 
3
16
  * Added support for custom filters
4
17
  * Improved Liquid support -- Liquid is now a first-class nanoc citizen
5
18
  * Deprecated assets -- use something like rsync instead
6
19
  * Added eruby_engine option, which can be 'erb' or 'erubis'
7
20
 
8
- == 1.4
21
+ 1.4
22
+ ---
9
23
 
10
24
  * nanoc now supports ERB (as well as Erubis); Erubis no longer is a dependency
11
25
  * meta.yaml can now have haml_options property, which is passed to Haml
@@ -14,12 +28,14 @@
14
28
  * Pages now know in what order they should be compiled, eliminating the need
15
29
  for custom page ordering [Dennis Sutch]
16
30
 
17
- == 1.3.1
31
+ 1.3.1
32
+ -----
18
33
 
19
34
  * The contents of the 'assets' directory are now copied into the output
20
35
  directory specified in 'config.yaml'
21
36
 
22
- == 1.3
37
+ 1.3
38
+ ---
23
39
 
24
40
  * The @pages array now also contains uncompiled pages
25
41
  * Pages with 'skip_output' set to true will not be outputted
@@ -29,9 +45,10 @@
29
45
  * nanoc now warns before overwriting in create_site, create_page and
30
46
  create_template (but not in compile)
31
47
 
32
- == 1.2
48
+ 1.2
49
+ ---
33
50
 
34
- * Sites now have an 'assets' directory, whose contents are copied to the
51
+ * Sites now have an 'assets' directory, whose contents are copied to the
35
52
  'output' directory when compiling [Soryu]
36
53
  * Added support for non-eRuby layouts (Markaby, Haml, Liquid, ...)
37
54
  * Added more filters (Markaby, Haml, Liquid, RDoc [Dmitry Bilunov])
@@ -41,16 +58,19 @@
41
58
  * Page attributes can now be accessed using dot notation, i.e. @page.title as
42
59
  well as @page[:title]
43
60
 
44
- == 1.1.3
61
+ 1.1.3
62
+ -----
45
63
 
46
64
  * Fixed bug which would cause layoutless pages to be outputted incorrectly
47
65
 
48
- == 1.1.2
66
+ 1.1.2
67
+ -----
49
68
 
50
69
  * Backup files (files ending with a “~”) are now ignored
51
70
  * Fixed bug which would cause subpages not to be generated correctly
52
71
 
53
- == 1.1
72
+ 1.1
73
+ ---
54
74
 
55
75
  * Added support for nested layouts
56
76
  * Added coloured logging
@@ -59,12 +79,14 @@
59
79
  directory they are in [Colin Barrett]
60
80
  * It is now possible to access @page in the page’s content file
61
81
 
62
- == 1.0.1
82
+ 1.0.1
83
+ -----
63
84
 
64
85
  * Fixed a bug which would cause a “no such template” error to be displayed
65
86
  when the template existed but compiling it would raise an exception
66
87
  * Fixed bug which would cause pages not to be sorted by order before compiling
67
88
 
68
- == 1.0
89
+ 1.0
90
+ ---
69
91
 
70
92
  * Initial release
@@ -23,6 +23,8 @@ module Nanoc
23
23
  :layout => 'default'
24
24
  }
25
25
 
26
+ attr_reader :config, :stack, :pages
27
+
26
28
  def initialize
27
29
  @filters = {}
28
30
  end
@@ -38,17 +40,23 @@ module Nanoc
38
40
  # Require all Ruby source files in lib/
39
41
  Dir['lib/*.rb'].each { |f| require f }
40
42
 
41
- # Create output assets directory if necessary
43
+ # Create output directory if necessary
42
44
  FileUtils.mkdir_p(@config[:output_dir])
43
45
 
44
- # Copy assets to output directory
45
- copy_assets
46
+ # Get all pages
47
+ @pages = find_uncompiled_pages
48
+
49
+ # Filter, layout, and filter again
50
+ filter(:pre)
51
+ layout
52
+ filter(:post)
46
53
 
47
- # Compile and layout pages
48
- pages = find_uncompiled_pages
49
- pages = layout(compile(pages))
54
+ # Save pages
55
+ save_pages
50
56
  end
51
57
 
58
+ # Filter management
59
+
52
60
  def register_filter(name, &block)
53
61
  @filters[name.to_sym] = block
54
62
  end
@@ -57,137 +65,81 @@ module Nanoc
57
65
  @filters[name.to_sym]
58
66
  end
59
67
 
60
- def config
61
- @config
62
- end
63
-
64
68
  private
65
69
 
66
- # Returns the path for the given page
67
- def path_for_page(page)
68
- if page.attributes[:custom_path].nil?
69
- @config[:output_dir] + page.attributes[:path] +
70
- page.attributes[:filename] + '.' + page.attributes[:extension]
71
- else
72
- @config[:output_dir] + page.attributes[:custom_path]
73
- end
74
- end
75
-
76
- # Returns the layout for the given page
77
- def layout_for_page(page)
78
- if page.attributes[:layout].nil?
79
- { :type => :eruby, :content => "<%= @page.content %>" }
80
- else
81
- filenames = Dir["layouts/#{page.attributes[:layout]}.*"]
82
- filenames.ensure_single('layout files', page.attributes[:layout])
83
- filename = filenames[0]
84
-
85
- { :type => FILE_TYPES[File.extname(filename)], :content => File.read(filename) }
86
- end
87
- end
88
-
89
- def copy_assets
90
- # Check for assets
91
- if Dir['assets/*'].size > 0
92
- deprecate 'Asset-copying functionality is deprecated as of nanoc 1.5,' +
93
- 'and will be removed in nanoc 1.6. Please use a Rake task that' +
94
- 'copies assets using something like rsync instead.'
95
- end
96
-
97
- # Remove existing assets
98
- Dir['assets/*'].each do |f|
99
- FileUtils.remove_entry_secure(f.sub('assets/', @config[:output_dir] + '/'), true)
100
- end
101
-
102
- # Copy assets
103
- if File.directory?('assets') and !Dir['assets/*'].empty?
104
- FileUtils.cp_r(Dir['assets/*'], @config[:output_dir])
105
- end
106
- end
70
+ # Main methods
107
71
 
108
72
  def find_uncompiled_pages
109
73
  # Read all meta files
110
- pages = Dir['content/**/meta.yaml'].collect do |filename|
74
+ Dir['content/**/meta.yaml'].inject([]) do |pages, filename|
111
75
  # Read the meta file
112
- page = @global_page.merge(YAML.load_file_and_clean(filename))
76
+ hash = @global_page.merge(YAML.load_file_and_clean(filename))
113
77
 
114
78
  # Fix the path
115
- page[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')
79
+ hash[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')
80
+
81
+ # Convert to a Page instance
82
+ page = Page.new(hash, self)
116
83
 
117
84
  # Get the content filename
118
- content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]
119
- content_filenames.reject! { |f| f =~ /~$/ }
120
- content_filenames += Dir["#{File.dirname(filename)}/index.*"] # fallback for nanoc 1.0
121
- content_filenames.ensure_single('content files', File.dirname(filename))
122
- page[:_content_filename] = content_filenames[0]
85
+ page.content_filename = content_filename_for_meta_filename(filename)
123
86
 
124
- page
87
+ # Skip drafts
88
+ hash[:is_draft] ? pages : pages + [ page ]
125
89
  end
126
-
127
- # Ignore drafts
128
- pages.reject! { |page| page[:is_draft] }
129
-
130
- pages
131
90
  end
132
91
 
133
- def compile(pages)
134
- # Create page objects from given pages
135
- given_pages = []
136
- pages.each { |page| given_pages << Page.new(page) }
92
+ def filter(stage)
93
+ # Reset filter stack
94
+ @stack = []
137
95
 
138
- # Compile pages
139
- Page.compile(given_pages)
140
-
141
- given_pages
142
- end
143
-
144
- def layouted_page(page, pages)
145
- # Find layout
146
- layout = layout_for_page(page)
147
-
148
- # Build params
149
- if layout[:type] == :liquid
150
- public_page = page.to_liquid
151
- public_pages = pages.map { |p| p.to_liquid }
152
- else
153
- public_page = page.to_proxy
154
- public_pages = pages.map { |p| p.to_proxy }
155
- end
156
- params = { :assigns => { :page => public_page, :pages => public_pages } }
157
- params[:haml_options] = (page.attributes[:haml_options] || {}).symbolize_keys
158
-
159
- # Layout
160
- case layout[:type]
161
- when :eruby
162
- content = layout[:content].eruby(params)
163
- when :haml
164
- content = layout[:content].haml(params)
165
- when :markaby
166
- content = layout[:content].markaby(params)
167
- when :liquid
168
- content = layout[:content].liquid(params)
169
- else
170
- content = nil
96
+ # Prepare pages
97
+ @pages.each do |page|
98
+ page.stage = stage
99
+ page.is_filtered = false
171
100
  end
172
101
 
173
- content
102
+ # Filter pages
103
+ @pages.each { |page| page.filter! }
174
104
  end
175
105
 
176
- def layout(pages)
177
- pages.reject { |page| page.attributes[:skip_output] }.each do |page|
106
+ def layout
107
+ # For each page (ignoring drafts)
108
+ @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
178
109
  begin
179
- # Prepare layout content
180
- content = layouted_page(page, pages)
181
-
182
- # Write page with layout
183
- FileManager.create_file(path_for_page(page)) { content }
110
+ # Layout the page
111
+ page.layout!
184
112
  rescue => exception
185
- p = page.attributes[:_content_filename]
186
- l = page.attributes[:layout]
187
- handle_exception(exception, "layouting page '#{p}' in layout '#{l}'")
113
+ handle_exception(exception, "layouting page '#{page.content_filename}' in layout '#{page.attributes[:layout]}'")
188
114
  end
189
115
  end
190
116
  end
191
117
 
118
+ def save_pages
119
+ @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
120
+ # Write page with layout
121
+ FileManager.create_file(page.path) { page.content }
122
+ end
123
+ end
124
+
125
+ # Helper methods
126
+
127
+ def content_filename_for_meta_filename(filename)
128
+ # Find all files with base name of parent directory
129
+ content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]
130
+
131
+ # Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
132
+ content_filenames += Dir["#{File.dirname(filename)}/index.*"]
133
+
134
+ # Reject backups
135
+ content_filenames.reject! { |f| f =~ /~$/ }
136
+
137
+ # Make sure there is only one content file
138
+ content_filenames.ensure_single('content files', File.dirname(filename))
139
+
140
+ # Return the first (and only one)
141
+ content_filenames[0]
142
+ end
143
+
192
144
  end
193
145
  end
@@ -1,5 +1,7 @@
1
1
  class Hash
2
- # Cleans up the hash by performing the following operations:
2
+ # Cleans up the hash and returns the result. It performs the following
3
+ # operations:
4
+ #
3
5
  # * Values with keys ending in _at and _on are converted into Times and
4
6
  # Dates, respectively
5
7
  # * All keys are converted to symbols
@@ -1,8 +1,10 @@
1
1
  require 'yaml'
2
2
 
3
3
  module YAML
4
+
4
5
  # Loads a YAML file, cleans it using Hash#clean, and returns the result
5
6
  def self.load_file_and_clean(a_filename)
6
7
  (YAML.load_file(a_filename) || {}).clean
7
8
  end
9
+
8
10
  end
data/lib/nanoc/creator.rb CHANGED
@@ -6,7 +6,6 @@ module Nanoc
6
6
  ensure_nonexistant(a_sitename)
7
7
 
8
8
  FileManager.create_dir a_sitename do
9
- FileManager.create_dir 'assets'
10
9
  FileManager.create_dir 'output'
11
10
 
12
11
  FileManager.create_file 'config.yaml' do
@@ -20,7 +19,7 @@ module Nanoc
20
19
  "# Built-in\n" +
21
20
  "layout: \"default\"\n" +
22
21
  "filters: []\n" +
23
- "filename: \"index\"\n" +
22
+ "filename: \"index\"\n" +
24
23
  "extension: \"html\"\n" +
25
24
  "\n" +
26
25
  "# Custom\n"
@@ -101,7 +100,7 @@ module Nanoc
101
100
 
102
101
  # Sanitize page name
103
102
  if a_pagename =~ /^[\/\.]+/
104
- $stderr.puts 'ERROR: page name starts with dots and/or slashes, aborting' unless $quiet == true
103
+ $stderr.puts 'ERROR: page name starts with dots and/or slashes, aborting' unless $quiet
105
104
  return
106
105
  end
107
106
 
@@ -109,12 +108,26 @@ module Nanoc
109
108
  template = a_params[:template] || 'default'
110
109
  begin
111
110
  template_meta = File.read("templates/#{template}/meta.yaml")
111
+
112
+ # Find all files
112
113
  template_content_filenames = Dir["templates/#{template}/#{template}.*"]
114
+
115
+ # Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
113
116
  template_content_filenames += Dir["templates/#{template}/index.*"]
117
+
118
+ # Reject backups
119
+ template_content_filenames.reject! { |f| f =~ /~$/ }
120
+
121
+ # Make sure there is only one content file
122
+ template_content_filenames.ensure_single('template files', template)
123
+
124
+ # Get the first (and only one)
114
125
  template_content_filename = template_content_filenames[0]
126
+
115
127
  template_index = File.read(template_content_filename)
116
- rescue
117
- $stderr.puts 'ERROR: no such template' unless $quiet == true
128
+ rescue => e
129
+ puts e.inspect
130
+ $stderr.puts 'ERROR: no such template' unless $quiet
118
131
  exit
119
132
  end
120
133
  template_meta = template_meta.eruby
@@ -1,4 +1,16 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
1
+ def try_require(s)
2
+ require s
3
+ rescue LoadError
4
+ end
5
+
6
+ def nanoc_require(s)
7
+ require s
8
+ rescue LoadError
9
+ $stderr.puts "ERROR: You need '#{s}' to compile this site." unless $quiet
10
+ exit
11
+ end
12
+
13
+ try_require 'rubygems'
2
14
 
3
15
  require 'fileutils'
4
16
 
@@ -8,11 +20,7 @@ def handle_exception(exception, text)
8
20
  $stderr.puts exception
9
21
  $stderr.puts exception.backtrace.join("\n")
10
22
  end
11
- exit
12
- end
13
-
14
- def deprecate(str)
15
- $stderr.puts 'DEPRECATION WARNING: ' + str unless $quiet
23
+ exit(1)
16
24
  end
17
25
 
18
26
  class FileLogger
@@ -1,10 +1,3 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- require 'erb'
6
- try_require 'erubis'
7
-
8
1
  class ERBContext
9
2
 
10
3
  def initialize(hash)
@@ -28,11 +21,13 @@ class String
28
21
 
29
22
  # Converts the string using Erubis
30
23
  def erubis(params={})
24
+ nanoc_require 'erubis'
31
25
  Erubis::Eruby.new(self).evaluate(params[:assigns] || {})
32
26
  end
33
27
 
34
28
  # Converts the string using ERB
35
29
  def erb(params={})
30
+ nanoc_require 'erb'
36
31
  ERB.new(self).result(ERBContext.new(params[:assigns] || {}).get_binding)
37
32
  end
38
33
 
@@ -1,19 +1,13 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'haml'
6
-
7
1
  class String
8
2
 
9
3
  # Converts the string using Haml
10
4
  def haml(params={})
5
+ nanoc_require 'haml'
6
+
11
7
  options = (params[:haml_options] || {})
12
8
  options[:locals] = params[:assigns] unless params[:assigns].nil?
9
+
13
10
  Haml::Engine.new(self, options).to_html
14
- rescue NameError
15
- $stderr.puts 'ERROR: String#haml failed (Haml not installed?)' unless $quiet
16
- exit
17
11
  end
18
12
 
19
13
  end
@@ -1,21 +1,22 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'liquid'
1
+ # Filter
6
2
 
7
3
  class String
8
4
 
9
- # Converts the string using Liquid
10
5
  def liquid(params={})
6
+ nanoc_require 'liquid'
7
+
11
8
  Liquid::Template.parse(self).render((params[:assigns] || {}).stringify_keys)
12
- rescue NameError
13
- $stderr.puts 'ERROR: String#liquid failed (Liquid not installed?)' unless $quiet
14
- exit
15
9
  end
16
10
 
17
11
  end
18
12
 
13
+ register_filter 'liquid' do |page, pages, config|
14
+ assigns = { :page => page, :pages => pages }
15
+ page.content.liquid(:assigns => assigns)
16
+ end
17
+
18
+ # Render tag
19
+
19
20
  begin
20
21
  class Nanoc::LiquidRenderTag < ::Liquid::Tag
21
22
  Syntax = /(['"])([^'"]+)\1/
@@ -44,8 +45,3 @@ begin
44
45
  Liquid::Template.register_tag('render', Nanoc::LiquidRenderTag)
45
46
  rescue NameError
46
47
  end
47
-
48
- register_filter 'liquid' do |page, pages, config|
49
- assigns = { :page => page, :pages => pages }
50
- page.content.liquid(:assigns => assigns)
51
- end
@@ -1,20 +1,10 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- require 'erb'
6
-
7
- try_require 'markaby'
8
-
9
1
  class String
10
2
 
11
3
  # Converts the string using Markaby
12
4
  # TODO perhaps add support for helpers
13
5
  def markaby(params={})
6
+ nanoc_require 'markaby'
14
7
  Markaby::Builder.new((params[:assigns] || {})).instance_eval(self).to_s
15
- rescue NameError
16
- $stderr.puts 'ERROR: String#markaby failed (Markaby not installed?)' unless $quiet
17
- exit
18
8
  end
19
9
 
20
10
  end
@@ -1,17 +1,9 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'bluecloth'
6
-
7
1
  class String
8
2
 
9
- # Converts the string to HTML using BlueCloth/Markdown.
3
+ # Converts the string using Markdown
10
4
  def markdown
5
+ nanoc_require 'bluecloth'
11
6
  BlueCloth.new(self).to_html
12
- rescue NameError
13
- $stderr.puts 'ERROR: String#markdown failed: BlueCloth not installed' unless $quiet
14
- exit
15
7
  end
16
8
 
17
9
  end
@@ -1,14 +1,10 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'rdoc/markup/simple_markup'
6
- try_require 'rdoc/markup/simple_markup/to_html'
7
-
8
1
  class String
9
2
 
10
3
  # Converts the string using RDoc
11
4
  def rdoc
5
+ nanoc_require 'rdoc/markup/simple_markup'
6
+ nanoc_require 'rdoc/markup/simple_markup/to_html'
7
+
12
8
  SM::SimpleMarkup.new.convert(self, SM::ToHtml.new)
13
9
  end
14
10
 
@@ -1,13 +1,8 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'haml'
6
-
7
1
  class String
8
2
 
9
3
  # Converts the string using Sass
10
4
  def sass
5
+ nanoc_require 'haml'
11
6
  Sass::Engine.new(self).render
12
7
  end
13
8
 
@@ -1,17 +1,9 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'rubypants'
6
-
7
1
  class String
8
2
 
9
3
  # Converts the string using RubyPants/SmartyPants
10
4
  def smartypants
5
+ nanoc_require 'rubypants'
11
6
  RubyPants.new(self).to_html
12
- rescue NameError
13
- $stderr.puts 'ERROR: String#smartypants failed (RubyPants not installed?)' unless $quiet
14
- exit
15
7
  end
16
8
 
17
9
  end
@@ -1,17 +1,9 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
-
5
- try_require 'redcloth'
6
-
7
1
  class String
8
2
 
9
3
  # Converts the string using RedCloth/Textile
10
4
  def textile
5
+ nanoc_require 'redcloth'
11
6
  RedCloth.new(self).to_html
12
- rescue NameError
13
- $stderr.puts 'ERROR: String#textile failed (RedCloth not installed?)' unless $quiet
14
- exit
15
7
  end
16
8
 
17
9
  end
data/lib/nanoc/page.rb CHANGED
@@ -1,64 +1,13 @@
1
- def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
2
-
3
- try_require 'rubygems'
4
- try_require 'liquid'
5
-
6
1
  module Nanoc
7
2
 
8
- # Page drop
9
-
10
- begin
11
- class PageDrop < ::Liquid::Drop
12
- def initialize(page)
13
- @page = page
14
- end
15
-
16
- def before_method(name)
17
- name == 'content' ? @page.content : @page.attributes[name.to_sym]
18
- end
19
- end
20
- rescue NameError
21
- class PageDrop
22
- def initialize(*args)
23
- $stderr.puts 'ERROR: Liquid not installed; cannot use Liquid in layouts.'
24
- exit
25
- end
26
- end
27
- end
28
-
29
- # Page proxy
30
-
31
- class PageProxy
32
- def initialize(page, params={})
33
- @page = page
34
- @do_compile = (params[:compile] != false)
35
- end
36
-
37
- def [](key)
38
- if key.to_sym == :content and @do_compile
39
- @page.content
40
- else
41
- if key.to_s.starts_with?('_')
42
- nil
43
- elsif key.to_s.ends_with?('?')
44
- @page.attributes[key.to_s[0..-2].to_sym]
45
- else
46
- @page.attributes[key]
47
- end
48
- end
49
- end
50
-
51
- def method_missing(method, *args)
52
- self[method]
53
- end
54
- end
55
-
56
- # Page
57
-
58
3
  class Page
59
4
 
60
- def initialize(hash={})
5
+ attr_accessor :stage, :is_filtered, :content_filename
6
+
7
+ def initialize(hash, compiler)
61
8
  @attributes = hash
9
+ @compiler = compiler
10
+ @stage = nil
62
11
  end
63
12
 
64
13
  def attributes
@@ -66,79 +15,159 @@ module Nanoc
66
15
  end
67
16
 
68
17
  def content
69
- compile
18
+ filter!
70
19
  @attributes[:content]
71
20
  end
72
21
 
22
+ def stage=(s) ; @stage = s ; puts 'NEW STAGE = ' + s.to_s ; end
23
+
73
24
  # Proxy/Liquid support
74
25
 
75
26
  def to_proxy(params={})
76
- PageProxy.new(self, :compile => params[:compile])
27
+ PageProxy.new(self, :filter => params[:filter])
77
28
  end
78
29
 
79
30
  def to_liquid
31
+ nanoc_require 'liquid'
80
32
  PageDrop.new(self)
81
33
  end
82
34
 
83
- # Compiling
35
+ # Helper methods
84
36
 
85
- def self.compile(pages)
86
- @@compilation_stack = []
87
- @@pages = pages
37
+ def path
38
+ if @attributes[:custom_path].nil?
39
+ @compiler.config[:output_dir] + @attributes[:path] +
40
+ @attributes[:filename] + '.' + @attributes[:extension]
41
+ else
42
+ @compiler.config[:output_dir] + @attributes[:custom_path]
43
+ end
44
+ end
88
45
 
89
- # Compile all pages
90
- pages.each { |page| page.compile }
46
+ def file
47
+ File.new(@content_filename)
91
48
  end
92
49
 
93
- def compile
50
+ def find_layout
51
+ if @attributes[:layout].nil?
52
+ { :type => :eruby, :content => "<%= @page.content %>" }
53
+ else
54
+ # Find all layouts
55
+ filenames = Dir["layouts/#{@attributes[:layout]}.*"]
56
+
57
+ # Reject backups
58
+ filenames.reject! { |f| f =~ /~$/ }
59
+
60
+ # Make sure there is only one content file
61
+ filenames.ensure_single('layout files', @attributes[:layout])
62
+
63
+ # Get the first (and only one)
64
+ filename = filenames[0]
65
+
66
+ { :type => Nanoc::Compiler::FILE_TYPES[File.extname(filename)], :content => File.read(filename) }
67
+ end
68
+ end
69
+
70
+ # Filtering
71
+
72
+ def filter!
73
+ # Get stack and list of other pages
74
+ stack = @compiler.stack
75
+ other_pages = @compiler.pages
76
+
94
77
  # Check for recursive call
95
- if @@compilation_stack.include?(self)
96
- # Print compilation stack
78
+ if stack.include?(self)
79
+ # Print stack
97
80
  unless $quiet
98
81
  $stderr.puts 'ERROR: Recursive call to page content.'
99
- print_compilation_stack
82
+ print_stack
100
83
  end
101
84
 
102
85
  exit
103
- # Compile if not yet compiled
104
- elsif @attributes[:content].nil?
105
- @@compilation_stack.pushing(self) do
86
+ end
87
+
88
+ # Get filters
89
+ if @stage == :pre
90
+ filters = @attributes[:filters_pre] || @attributes[:filters] || []
91
+ elsif @stage == :post
92
+ filters = @attributes[:filters_post] || []
93
+ else
94
+ puts '?????!!!!!!!!'
95
+ puts `pwd`
96
+ end
97
+
98
+ # Filter if not yet filtered
99
+ unless @is_filtered
100
+ stack.pushing(self) do
106
101
  # Read page
107
- content = File.read(@attributes[:_content_filename])
102
+ content = @attributes[:content] || File.read(@content_filename)
108
103
 
109
104
  begin
110
105
  # Get params
111
- page = self.to_proxy(:compile => false)
112
- pages = @@pages.map { |p| p.to_proxy }
106
+ page = self.to_proxy(:filter => false)
107
+ pages = other_pages.map { |p| p.to_proxy }
113
108
  config = $nanoc_compiler.config
114
109
 
115
110
  # Filter page
116
111
  @attributes[:content] = content
117
- @attributes[:filters].each do |filter_name|
112
+ filters.each do |filter_name|
118
113
  filter = $nanoc_compiler.filter_named(filter_name)
119
114
  if filter.nil?
120
115
  $stderr.puts 'WARNING: Unknown filter: ' + filter_name unless $quiet
121
116
  else
122
117
  @attributes[:content] = filter.call(page, pages, config)
118
+ @is_filtered = true
123
119
  end
124
120
  end
125
121
  rescue Exception => exception
126
- handle_exception(exception, "compiling page '#{@attributes[:_content_filename]}'")
122
+ handle_exception(exception, "filter page '#{@content_filename}'")
127
123
  end
128
124
  end
129
125
  end
130
126
  end
131
127
 
132
- def print_compilation_stack
133
- # Determine relevant part of compilation stack
134
- stack_begin = @@compilation_stack.index(self)
135
- stack_end = @@compilation_stack.size
136
- relevant_stack_part = @@compilation_stack.last(stack_end - stack_begin)
128
+ def layout!
129
+ # Get list of other pages
130
+ other_pages = @compiler.pages
131
+
132
+ # Find layout
133
+ layout = self.find_layout
134
+
135
+ # Build params
136
+ if layout[:type] == :liquid
137
+ public_page = self.to_liquid
138
+ public_pages = other_pages.map { |p| p.to_liquid }
139
+ else
140
+ public_page = self.to_proxy
141
+ public_pages = other_pages.map { |p| p.to_proxy }
142
+ end
143
+ params = { :assigns => { :page => public_page, :pages => public_pages } }
144
+ params[:haml_options] = (@attributes[:haml_options] || {}).symbolize_keys
145
+
146
+ # Layout
147
+ case layout[:type]
148
+ when :eruby
149
+ @attributes[:content] = layout[:content].eruby(params)
150
+ when :haml
151
+ @attributes[:content] = layout[:content].haml(params)
152
+ when :markaby
153
+ @attributes[:content] = layout[:content].markaby(params)
154
+ when :liquid
155
+ @attributes[:content] = layout[:content].liquid(params)
156
+ else
157
+ @attributes[:content] = nil
158
+ end
159
+ end
160
+
161
+ def print_stack
162
+ # Determine relevant part of stack
163
+ stack_begin = @compiler.stack.index(self)
164
+ stack_end = @compiler.stack.size
165
+ relevant_stack_part = @compiler.stack.last(stack_end - stack_begin)
137
166
 
138
- # Print relevant part of compilation stack
139
- $stderr.puts 'Page compilation stack:'
167
+ # Print relevant part of stack
168
+ $stderr.puts 'Page filter stack:'
140
169
  relevant_stack_part.each_with_index do |page, i|
141
- $stderr.puts "#{i} #{page.attributes[:_content_filename]}"
170
+ $stderr.puts "#{i} #{page.content_filename}"
142
171
  end
143
172
  end
144
173
 
@@ -0,0 +1,18 @@
1
+ try_require 'liquid'
2
+
3
+ module Nanoc
4
+
5
+ begin
6
+ class PageDrop < ::Liquid::Drop
7
+ def initialize(page)
8
+ @page = page
9
+ end
10
+
11
+ def before_method(name)
12
+ name == 'content' ? @page.content : @page.attributes[name.to_sym]
13
+ end
14
+ end
15
+ rescue NameError
16
+ end
17
+
18
+ end
@@ -0,0 +1,26 @@
1
+ module Nanoc
2
+ class PageProxy
3
+
4
+ def initialize(page, params={})
5
+ @page = page
6
+ @do_filter = (params[:filter] != false)
7
+ end
8
+
9
+ def [](key)
10
+ if key.to_sym == :content and @do_filter
11
+ @page.content
12
+ elsif key.to_sym == :file
13
+ @page.file
14
+ elsif key.to_s.ends_with?('?')
15
+ @page.attributes[key.to_s[0..-2].to_sym]
16
+ else
17
+ @page.attributes[key]
18
+ end
19
+ end
20
+
21
+ def method_missing(method, *args)
22
+ self[method]
23
+ end
24
+
25
+ end
26
+ end
data/lib/nanoc.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Nanoc
2
2
 
3
- VERSION = '1.5'
3
+ VERSION = '1.6'
4
4
 
5
5
  def self.ensure_in_site
6
6
  unless in_site?
@@ -27,6 +27,8 @@ module Nanoc
27
27
 
28
28
  end
29
29
 
30
+ require File.dirname(__FILE__) + '/nanoc/enhancements.rb'
31
+
30
32
  require File.dirname(__FILE__) + '/nanoc/creator.rb'
31
33
  require File.dirname(__FILE__) + '/nanoc/compiler.rb'
32
34
 
@@ -34,6 +36,7 @@ $nanoc_creator = Nanoc::Creator.new
34
36
  $nanoc_compiler = Nanoc::Compiler.new
35
37
 
36
38
  require File.dirname(__FILE__) + '/nanoc/core_ext.rb'
37
- require File.dirname(__FILE__) + '/nanoc/enhancements.rb'
38
39
  require File.dirname(__FILE__) + '/nanoc/filters.rb'
39
40
  require File.dirname(__FILE__) + '/nanoc/page.rb'
41
+ require File.dirname(__FILE__) + '/nanoc/page_drop.rb'
42
+ require File.dirname(__FILE__) + '/nanoc/page_proxy.rb'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: nanoc
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.5"
7
- date: 2007-09-10 00:00:00 +02:00
6
+ version: "1.6"
7
+ date: 2007-10-13 00:00:00 +02:00
8
8
  summary: a CMS that doesn't run on your server
9
9
  require_paths:
10
10
  - lib
@@ -56,6 +56,8 @@ files:
56
56
  - lib/nanoc/filters/textile_filter.rb
57
57
  - lib/nanoc/filters.rb
58
58
  - lib/nanoc/page.rb
59
+ - lib/nanoc/page_drop.rb
60
+ - lib/nanoc/page_proxy.rb
59
61
  - lib/nanoc.rb
60
62
  test_files: []
61
63