lib/nanoc/compiler.rb in nanoc-1.5 vs lib/nanoc/compiler.rb in nanoc-1.6
- old
+ new
@@ -21,10 +21,12 @@
:filters => [],
:is_draft => false,
:layout => 'default'
}
+ attr_reader :config, :stack, :pages
+
def initialize
@filters = {}
end
def run
@@ -36,158 +38,108 @@
@global_page = PAGE_DEFAULTS.merge(YAML.load_file_and_clean('meta.yaml'))
# Require all Ruby source files in lib/
Dir['lib/*.rb'].each { |f| require f }
- # Create output assets directory if necessary
+ # Create output directory if necessary
FileUtils.mkdir_p(@config[:output_dir])
- # Copy assets to output directory
- copy_assets
+ # Get all pages
+ @pages = find_uncompiled_pages
- # Compile and layout pages
- pages = find_uncompiled_pages
- pages = layout(compile(pages))
+ # Filter, layout, and filter again
+ filter(:pre)
+ layout
+ filter(:post)
+
+ # Save pages
+ save_pages
end
+ # Filter management
+
def register_filter(name, &block)
@filters[name.to_sym] = block
end
def filter_named(name)
@filters[name.to_sym]
end
- def config
- @config
- end
-
private
- # Returns the path for the given page
- def path_for_page(page)
- if page.attributes[:custom_path].nil?
- @config[:output_dir] + page.attributes[:path] +
- page.attributes[:filename] + '.' + page.attributes[:extension]
- else
- @config[:output_dir] + page.attributes[:custom_path]
- end
- end
+ # Main methods
- # Returns the layout for the given page
- def layout_for_page(page)
- if page.attributes[:layout].nil?
- { :type => :eruby, :content => "<%= @page.content %>" }
- else
- filenames = Dir["layouts/#{page.attributes[:layout]}.*"]
- filenames.ensure_single('layout files', page.attributes[:layout])
- filename = filenames[0]
-
- { :type => FILE_TYPES[File.extname(filename)], :content => File.read(filename) }
- end
- end
-
- def copy_assets
- # Check for assets
- if Dir['assets/*'].size > 0
- deprecate 'Asset-copying functionality is deprecated as of nanoc 1.5,' +
- 'and will be removed in nanoc 1.6. Please use a Rake task that' +
- 'copies assets using something like rsync instead.'
- end
-
- # Remove existing assets
- Dir['assets/*'].each do |f|
- FileUtils.remove_entry_secure(f.sub('assets/', @config[:output_dir] + '/'), true)
- end
-
- # Copy assets
- if File.directory?('assets') and !Dir['assets/*'].empty?
- FileUtils.cp_r(Dir['assets/*'], @config[:output_dir])
- end
- end
-
def find_uncompiled_pages
# Read all meta files
- pages = Dir['content/**/meta.yaml'].collect do |filename|
+ Dir['content/**/meta.yaml'].inject([]) do |pages, filename|
# Read the meta file
- page = @global_page.merge(YAML.load_file_and_clean(filename))
+ hash = @global_page.merge(YAML.load_file_and_clean(filename))
# Fix the path
- page[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')
+ hash[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')
+ # Convert to a Page instance
+ page = Page.new(hash, self)
+
# Get the content filename
- content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]
- content_filenames.reject! { |f| f =~ /~$/ }
- content_filenames += Dir["#{File.dirname(filename)}/index.*"] # fallback for nanoc 1.0
- content_filenames.ensure_single('content files', File.dirname(filename))
- page[:_content_filename] = content_filenames[0]
+ page.content_filename = content_filename_for_meta_filename(filename)
- page
+ # Skip drafts
+ hash[:is_draft] ? pages : pages + [ page ]
end
-
- # Ignore drafts
- pages.reject! { |page| page[:is_draft] }
-
- pages
end
- def compile(pages)
- # Create page objects from given pages
- given_pages = []
- pages.each { |page| given_pages << Page.new(page) }
+ def filter(stage)
+ # Reset filter stack
+ @stack = []
- # Compile pages
- Page.compile(given_pages)
+ # Prepare pages
+ @pages.each do |page|
+ page.stage = stage
+ page.is_filtered = false
+ end
- given_pages
+ # Filter pages
+ @pages.each { |page| page.filter! }
end
- def layouted_page(page, pages)
- # Find layout
- layout = layout_for_page(page)
-
- # Build params
- if layout[:type] == :liquid
- public_page = page.to_liquid
- public_pages = pages.map { |p| p.to_liquid }
- else
- public_page = page.to_proxy
- public_pages = pages.map { |p| p.to_proxy }
+ def layout
+ # For each page (ignoring drafts)
+ @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
+ begin
+ # Layout the page
+ page.layout!
+ rescue => exception
+ handle_exception(exception, "layouting page '#{page.content_filename}' in layout '#{page.attributes[:layout]}'")
+ end
end
- params = { :assigns => { :page => public_page, :pages => public_pages } }
- params[:haml_options] = (page.attributes[:haml_options] || {}).symbolize_keys
+ end
- # Layout
- case layout[:type]
- when :eruby
- content = layout[:content].eruby(params)
- when :haml
- content = layout[:content].haml(params)
- when :markaby
- content = layout[:content].markaby(params)
- when :liquid
- content = layout[:content].liquid(params)
- else
- content = nil
+ def save_pages
+ @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
+ # Write page with layout
+ FileManager.create_file(page.path) { page.content }
end
-
- content
end
- def layout(pages)
- pages.reject { |page| page.attributes[:skip_output] }.each do |page|
- begin
- # Prepare layout content
- content = layouted_page(page, pages)
+ # Helper methods
- # Write page with layout
- FileManager.create_file(path_for_page(page)) { content }
- rescue => exception
- p = page.attributes[:_content_filename]
- l = page.attributes[:layout]
- handle_exception(exception, "layouting page '#{p}' in layout '#{l}'")
- end
- end
+ def content_filename_for_meta_filename(filename)
+ # Find all files with base name of parent directory
+ content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]
+
+ # Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
+ content_filenames += Dir["#{File.dirname(filename)}/index.*"]
+
+ # Reject backups
+ content_filenames.reject! { |f| f =~ /~$/ }
+
+ # Make sure there is only one content file
+ content_filenames.ensure_single('content files', File.dirname(filename))
+
+ # Return the first (and only one)
+ content_filenames[0]
end
end
end