Sunday, September 27, 2009

A Poor Man's CMS on CouchDB

‹prev | My Chain | next›

Today, I continue my effort to add a poor man's CMS into my Sinatra / CouchDB application. I need to get the catch-all resource to convert the content in a CouchDB document from textile into HTML. An RSpec example describing this:
  context "with an associated CouchDB document" do
before(:each) do
RestClient.
stub!(:get).
and_return('{"content":"*bar*"}')
end

it "should convert textile in the CouchDB doc to HTML" do
get "/foo-bar"
last_response.
should have_selector("strong", :content => "bar")
end
end
To get that to pass, I parse the JSON from CouchDB and use RedCloth to convert the textile in the example into HTML:
get %r{^/([\-\w]+)$} do |doc_id|
begin
data = RestClient.get "#{@@db}/#{doc_id}"
@doc = JSON.parse(data)
rescue RestClient::ResourceNotFound
pass
end
RedCloth.new(@doc['content']).to_html
end
With that working, I would like to insert that HTML into the normal page layout of the site:
    it "should insert the document into the normal site layout" do
get "/foo-bar"
last_response.
should have_selector("title", :content => "EEE Cooks")
end
Getting that to pass is quite easy as Sinatra's haml method is capable of doing just this:
get %r{^/([\-\w]+)$} do |doc_id|
begin
data = RestClient.get "#{@@db}/#{doc_id}"
@doc = JSON.parse(data)
rescue RestClient::ResourceNotFound
pass
end
haml RedCloth.new(@doc['content']).to_html
end
I contemplate adding a feature that will suppress document without a published attribute or add wiki-like intra-document linking ability. Eventually, I come to my senses and listen to the voice whispering YAGNI in my ear. I want a poor-man's CMS, nothing more.

So that should do the trick. To verify that it really is working, I check out the /about-us resource currently in the application:



As expected, it is not found. With my poor-man's CouchDB-based CMS in place, I need to add a CouchDB document with an about-us document ID:



With that, I can then reload the /about-us resource and:



With that mini-feature complete, I will move on to implementing an ingredient index page, which should be quite easy to do with CouchDB map-reduce.

No comments:

Post a Comment