Skip to content

Instantly share code, notes, and snippets.

@travishaynes
Created January 4, 2012 19:43
Show Gist options
  • Save travishaynes/1561682 to your computer and use it in GitHub Desktop.
Save travishaynes/1561682 to your computer and use it in GitHub Desktop.
Middleman In Memory Blog
require 'sqlite3'
require 'active_record'
require 'slim'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => ":memory:"
)
class CreateBlogsTable < ActiveRecord::Migration
def self.up
suppress_messages do
create_table :blogs do |t|
t.string :title
t.string :root
t.string :posts_path
t.string :site_url
t.timestamps
end
end
end
end
class CreatePostsTable < ActiveRecord::Migration
def self.up
suppress_messages do
create_table :posts do |t|
t.integer :blog_id
t.string :title
t.string :author
t.string :body
t.string :href
t.string :url
t.string :template
t.timestamps
end
end
end
end
class Blog < ActiveRecord::Base
after_create :reload!
has_many :posts, :dependent => :destroy
validates :title, presence: true, uniqueness: true
validates :root, presence: true
validates :posts_path, presence: true
validates :site_url, presence: true
public
# loads the posts from the filesystem
def reload!
# destroy deleted templates
self.posts.each do |post|
post.destroy unless File.exists?(post.template)
end
# reload the existing templates, and create the new ones
Dir[File.join(self.root, self.posts_path)].each do |file|
post = self.posts.find_by_template(file)
if post.nil?
self.posts.create!(:template => file) unless File.directory?(file)
else
post.reload!
end
end
self
end
end
class Post < ActiveRecord::Base
belongs_to :blog
after_create :reload!
validates_presence_of :template
public
# loads the contents of the post from the template
def reload!
# read the contents of the template
contents = File.read(self.template)
# set the href (relative path)
self.href = self.template.gsub(self.blog.root, "")
self.href = self.href.rpartition('.html')[0..1].join
# set the url
self.url = File.join(self.blog.site_url, self.href)
# load the attributes of the post into the blog post
attributes = YAML.load(contents.rpartition("\n---\n")[0..1].join)
# make sure the updated_at attribute is set to the created_at attribute,
# unless it is defined
attributes["updated_at"] = attributes["updated_at"] || attributes["created_at"]
# render the body of the post
template = contents.rpartition("\n---\n")[2]
attributes["body"] = Slim::Template.new { template }.render
# update the post's attributes
update_attributes(attributes)
self
end
end
CreateBlogsTable.up
CreatePostsTable.up
@travishaynes
Copy link
Author

To use this in your Middleman project, add this to your config.rb:

Blog.create!(
  title: "Blog Title",
  root: File.expand_path("../source", __FILE__),
  posts_path: "sub/path/to/the/blog/**/*",
  site_url: "http://your.website.com"
)

The trailing "**/*" in the posts path tells it to recursively search for any file under that path to use as the posts. You could narrow it down to only Haml files, for example, by changing it to "**/*,haml".

@travishaynes
Copy link
Author

Additionally, here are some helpers that I use for my views (also in the config.rb file):

helpers do
  def blog
    # reload blog contents without having to restart the server
    Blog.find_by_title("Blog Title").reload!
  end

  def is_post?
    !post.nil?
  end

  def post
    Post.find_by_href("/#{env['PATH_INFO']}")
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment