module RubySlippers module Engine class Site def initialize config @config = config end def [] *args @config[*args] end def []= key, value @config.set key, value end def index type = :html articles = type == :html ? self.articles.reverse : self.articles {:articles => articles.map do |article| Article.new article, @config end}.merge archives end def archives filter = "" entries = ! self.articles.empty?? self.articles.select do |a| filter !~ /^\d{4}/ || File.basename(a) =~ /^#{filter}/ end.reverse.map do |article| Article.new article, @config end : [] return :archives => Archives.new(entries, @config) end def article route Article.new("#{Paths[:articles]}/#{route.join('-')}.#{self[:ext]}", @config).load end def tagged tag articles = self.articles.collect do |article| Article.new article, @config end.select do |article| article[:tags].index(tag.humanize.downcase) if article[:tags] end {:articles => articles, :tagged => tag} end def / self[:root] end def go route, env = {}, type = :html route << self./ if route.empty? type, path = type =~ /html|xml|json/ ? type.to_sym : :html, route.join('/') context = lambda do |data, page| Context.new(data, @config, path, env).render(page, type) end body, status = if Context.new.respond_to?(:"to_#{type}") if route.first =~ /\d{4}/ case route.size when 1..3 context[archives(route * '-'), :archives] when 4 context[article(route), :article] else http 400 end elsif route.first == "tagged" context[tagged(route.last), :tagged] elsif respond_to?(path) context[send(path, type), path.to_sym] elsif (repo = @config[:github][:repos].grep(/#{path}/).first) && !@config[:github][:user].empty? context[Repo.new(repo, @config), :repo] else context[{}, path.to_sym] end else http 400 end rescue NoMethodError, Errno::ENOENT => e return :body => http(404).first, :type => :html, :status => 404 else return :body => body || "", :type => type, :status => status || 200 end protected def http code [@config[:error].call(code), code] end def articles self.class.articles self[:ext] end def self.articles ext Dir["#{Paths[:articles]}/*.#{ext}"].sort_by {|entry| File.basename(entry) } end end end end