# encoding: utf-8 # === The boot process === # # 1) load the app # 2) load the rules (controllers / globs mapping) # 3) load & instantiate all the renderable items # 4) render all the items (here the filters & layouting run) # 5) match the routes, write the files require "yaml" require "fileutils" module Ace class RawItem attr_accessor :path, :metadata, :content def initialize(path) @data = File.read(path) end def parse pieces = @data.split(/^-{3,5}\s*$/) if pieces.size < 3 raise RuntimeError.new( "The file '#{content_filename}' appears to start with a metadata section (three or five dashes at the top) but it does not seem to be in the correct format." ) end # Parse self.metadata = YAML.load(pieces[1]).inject(Hash.new) { |metadata, pair| metadata.merge(pair[0].to_sym => pair[1]) } || Hash.new self.content = pieces[2..-1].join.strip end end # This class represents the items which will be # eventually rendered like concrete posts, tags etc. class Item @@subclasses ||= Array.new def self.inherited(subclass) @@subclasses << subclass end @@instances ||= Array.new def self.instances @@instances end def self.before_filters @before_filters ||= Array.new end def self.before(filter, *args) self.before_filters << filter.new(*args) end def self.after_filters @after_filters ||= Array.new end def self.after(filter, *args) self.after_filters << filter.new(*args) end def self.create(metadata, content) self.new(metadata, content).tap(&:register) end # Content can be anything, not just a string. attr_accessor :metadata, :content attr_accessor :original_path def initialize(metadata, content) @metadata = metadata @content = content end def config @config ||= begin YAML::load_file("config.yml").inject(Hash.new) do |hash, pair| hash.merge!(pair[0].to_sym => pair[1]) end end end def register instances = self.class.instances unless instances.include?(self) self.class.instances << self end end def unregister self.class.instances.delete(self) end def render output = self.class.before_filters.inject(self.content) do |buffer, filter| filter.call(self, buffer) end self.class.after_filters.inject(output) do |buffer, filter| filter.call(self, buffer) end end attr_writer :output_path def output_path @output_path ||= begin unless self.original_path.nil? self.original_path.sub("content", "output") end end end def save! content = self.render.chomp # so filters can influence output_path FileUtils.mkdir_p File.dirname(self.output_path) File.open(self.output_path, "w") do |file| file.puts content end end end class Asset < Item end module Helpers def link_to(anchor, path_or_item, options = nil) end end end