lib/shinmun/blog.rb in shinmun-0.5.2 vs lib/shinmun/blog.rb in shinmun-0.9

- old
+ new

@@ -2,177 +2,124 @@ ROOT = File.expand_path(File.dirname(__FILE__) + '/../..') class Blog < Kontrol::Application include Helpers - attr_accessor :config, :store, :posts, :pages + attr_accessor :config + attr_reader :posts, :pages, :posts_by_date, :posts_by_category, :posts_by_tag %w[ base_path title description language author categories ].each do |name| define_method(name) { @config[name.to_sym] } end # Initialize the blog def initialize(path) super @config = {} - @store = GitStore.new(path) - @store.handler['md'] = PostHandler.new - @store.handler['rhtml'] = ERBHandler.new - @store.handler['rxml'] = ERBHandler.new + @templates = {} + + load_posts + load_pages + sort_posts end def self.init(path) path = File.expand_path(path) Dir.mkdir(path) - FileUtils.cp_r "#{ROOT}/assets", path + FileUtils.cp_r "#{ROOT}/public", path FileUtils.cp_r "#{ROOT}/templates", path FileUtils.cp "#{ROOT}/config.ru", path + FileUtils.cp "#{ROOT}/.gems", path Dir.mkdir("#{path}/posts") Dir.mkdir("#{path}/pages") - Dir.mkdir("#{path}/comments") - Dir.mkdir("#{path}/public") - - FileUtils.ln_s("../assets", "#{path}/public/assets") - - Dir.chdir(path) do - `git init` - `git add .` - `git commit -m 'init'` - end end - def load_template(file) - store['templates/' + file] - end - def render(name, vars = {}) super(name, vars.merge(:blog => self)) end - def pages - store.tree('pages').values.select { |v| Post === v } - end + def reload_changed_files + (@posts + @pages.values).each do |post| + if post.changed? + post.load + @changed = true + end + end - def posts - store.tree('posts').values.select { |v| Post === v }.sort_by { |p| p.date.to_s }.reverse + sort_posts if @changed end def call(env) - if ENV['RACK_ENV'] == 'production' - store.load if store.changed? - else - store.load(true) - end - + reload_changed_files # if ENV['RACK_ENV'] != 'production' super end - def url - "http://#{request.host}" - end + def load_pages + @pages = {} - def symbolize_keys(hash) - hash.inject({}) do |h, (k, v)| - h[k.to_sym] = v - h + Dir["#{ path }/pages/*.md"].each do |file| + page = Post.new(:file => file) + @pages[page.name] = page end end - def transaction(message, &block) - store.transaction(message, &block) - end - - def post_file(post) - 'posts' + post_path(post) + '.' + post.type - end - - def page_file(post) - 'pages' + page_path(post) + '.' + post.type - end - - def comment_file(post) - 'comments/' + post_path(post) + '.yml' - end - - def create_post(attr) - post = Post.new(attr) - path = post_file(post) - - transaction "create post `#{post.title}'" do - store[path] = post + def load_posts + @posts = Dir["#{ path }/posts/**/*.md"].map do |file| + Post.new(:file => file) end - - post end - - def create_page(attr) - post = Post.new(attr) - path = page_file(post) - - transaction "create page `#{post.title}'" do - store[path] = post + + def sort_posts + @posts = @posts.sort_by { |post| post.date.to_s }.reverse + + @posts_by_category = Hash.new do |hash, category| + hash[category] = [] end - - post - end - - def comments_for(post) - store[comment_file post] || [] - end - - def create_comment(post, params) - path = comment_file(post) - comments = comments_for(post) - comment = Comment.new(params) - transaction "new comment for `#{post.title}'" do - store[path] = comments + [comment] + @posts_by_tag = Hash.new do |hash, tag| + hash[tag] = [] end + + @posts_by_date = Hash.new do |hash, year| + hash[year] = Hash.new do |hash_months, month| + hash_months[month] = Hash.new + end + end - comment + @posts.each do |post| + post.tag_list.each { |tag| @posts_by_tag[tag] << post } + @posts_by_category[post.category] << post if post.category + @posts_by_date[post.year][post.month][post.name] = post + end end - def find_page(name) - pages.find { |p| p.name == name } + def url + "http://#{request.host}" end - def find_post(year, month, name) - posts.find { |p| p.year == year and p.month == month and p.name == name } + def symbolize_keys(hash) + hash.inject({}) do |h, (k, v)| + h[k.to_sym] = v + h + end end def find_category(permalink) - name = categories.find { |name| urlify(name) == permalink } - - { :name => name, - :posts => posts.select { |p| p.category == name }, - :permalink => permalink } + categories.find { |name| urlify(name) == permalink } end - def recent_posts - posts[0, 20] - end - - # Return all posts for a given month. - def posts_for_month(year, month) - posts.select { |p| p.year == year and p.month == month } - end - # Return all posts with any of given tags. def posts_with_tags(tags) return [] if tags.nil? or tags.empty? tags = tags.split(',').map { |t| t.strip } if tags.is_a?(String) - - posts.select do |post| - tags.any? do |tag| - post.tag_list.include?(tag) - end - end + + tags.map { |tag| posts_by_tag[tag] }.flatten.uniq end - # Return all archives as tuples of [year, month]. + # Return all archives as tuples of [year, month, posts]. def archives posts.map { |p| [p.year, p.month] }.uniq.sort end end