Skip to content

Instantly share code, notes, and snippets.

@MarkNijhof
Created December 6, 2010 14:19
Show Gist options
  • Save MarkNijhof/730334 to your computer and use it in GitHub Desktop.
Save MarkNijhof/730334 to your computer and use it in GitHub Desktop.
require 'date'
require 'rack'
require 'rdiscount'
module Dorsey
class Article < Hash
Defaults = {
:publish_date => "",
:body => "",
:summary => "",
:file => "",
:url => ""
}
def initialize article_file, config
self[:file] = article_file
self[:disqus] = config[:disqus]
@config = config
load_article article_file
end
def [] key
return self[:__slug] || self[:title].slugize if key == :slug
super
end
def method_missing m, *args, &blk
self[m.to_sym] || super
end
protected
def markdown text
if (options = @config[:markdown])
Markdown.new(text.to_s.strip, *(options.eql?(true) ? [] : options)).to_html
else
text.strip
end
end
def get_summary body
body =~ @config[:summary_delimiter] ? body.split(@config[:summary_delimiter]).first : body
end
def load_article article_file
raw_meta_data, body = File.read(article_file).split(/\n\n/, 2)
self[:body] = markdown body
self[:summary] = markdown(get_summary(body))
self.update abstract_meta_data(article_file, raw_meta_data)
generate_url
end
def abstract_meta_data article_file, raw_meta_data
meta_data = YAML.load(raw_meta_data).inject({}) {|h, (k,v)| h.merge(k.to_sym => v) }
article_file =~ /\/(\d{4}-\d{2}-\d{2})[^\/]*$/
(date = $1)
meta_data[:date_as_date] = Date.parse(date.gsub('/', '-')) rescue Date.today
meta_data[:date] = @config[:date].call meta_data[:date_as_date]
meta_data = rename_slug_key meta_data
meta_data
end
def rename_slug_key meta_data
meta_data[:__slug] = meta_data[:slug] if !meta_data[:slug].nil?
meta_data.delete :slug
meta_data
end
def generate_url
url = File.join @config[:host], @config[:article_prefix]
self[:url] = File.join url, path
end
def path
"/#{self[:date_as_date].strftime("%Y/%m/%d/#{self[:slug]}")}/"
end
end
end
get '/blog/*' do
$header_for = 'blog'
articles = $blog_dorsey.get_by_slug params[:splat][0]
return haml(:'blog/article', :locals => { :title => "Cre8ive Thought - #{articles[0].title}", :post => articles[0]} ) if articles.count == 1
return haml(:'blog/archive', :locals => { :title => "Cre8ive Thought - #{params[:splat][0]}", :posts => articles, :slug => params[:splat][0] } ) if articles.count > 1
haml(:'404', :locals => { :title => "Cre8ive Thought - Not Found", :slug => params[:splat][0] } )
end
module Dorsey
class Articles < Array
def initialize config
@config = config
load_articles article_files @config[:article_path]
end
protected
def article_files articles_path
Dir["#{articles_path}/*.txt"].sort_by {|entry| File.basename(entry) }
end
def load_articles article_files
article_files.each { |file| self << Article.new(file, @config) }
end
end
end
module Dorsey
class Config < Hash
Defaults = {
:article_prefix => "",
:host => "",
:article_path => "articles",
:summary_delimiter => /\n/,
:summary_length => 150,
:markdown => :smart,
:url => "",
:disqus => "",
:date => lambda {|now| now.strftime("%d/%m/%Y") }
}
def initialize obj
self.update Defaults
self.update obj
end
def set key, val = nil, &blk
if val.is_a? Hash
self[key].update val
else
self[key] = block_given?? blk : val
end
end
end
end
$blog_dorsey = Dorsey::Server.new do
set :article_path, './blog/articles'
set :article_prefix, "blog"
set :host, "http://cre8ivethought.com/"
set :disqus, "some_disqus_id"
set :date, lambda {|now| now.strftime("%B #{now.day.ordinal} %Y") }
end
["/blog/?", "/blog/index/?"].each do |route|
get route do
$header_for = 'blog'
haml(:'blog/index', :locals => { :title => "Cre8ive Thought", :articles => $blog_dorsey.articles})
end
end
module Dorsey
class Server
attr_reader :config
attr_reader :articles
def initialize config = {}, &blk
@config = config.is_a?(Dorsey::Config) ? config : Dorsey::Config.new(config)
@config.instance_eval(&blk) if block_given?
@articles = Articles.new(@config).reverse
puts ">> Dorsey Server Initialized, reading from: #{@config[:article_path]} found #{@articles.count} articles"
end
def get_by_slug slug
slug =~ /^(.+)\/$/
slug = $1 || slug
self.articles.select{ |item| item[:url] =~ /#{slug}/ }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment