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