Caramel: a RedCloth enabler for RailsCaramel is a Ruby on Rails plugin that facilitates conversion of Textile input to HTML via RedCloth.
Problem:If you have a text field, say 'content', in your model and you intend to use that text field to contain the HTML for your web pages, then either the user of your web app must know HTML or else you'll have to convert the user's input from some other format like Textile.
The latter solution is quite attractive, and on top of that there is a great Ruby gem out there that does this conversion for you in a very easy way! It's called RedCloth and it works with Markdown as well.
But if you store the Textile markup in the database and convert it using RedCloth, you end up with a lot of processing overhead which will almost certainly get scary if your website gets popular. On the other hand, if you convert the Textile and then save the HTML to the database, you're back to forcing the user to learn HTML if he/she ever wants to go back to make edits.
Solution:Store BOTH Textile and HTML! Sure, this doubles the amount of data you have to store in the database, but storage is much more affordable than man-hours and per-request processing expenditures.
But who wants to go to the trouble of defining a before_save callback with RedCloth configs for each and every HTML-based column in your database? Enter Caramel.
Caramel is designed to make it very easy to instruct your model on which database columns will be used to store the Textile markup and which columns will be used to store the HTML. Caramel adds a method to ActiveRecord which looks for certain naming conventions in your tables (or responds to the developer's configuration within the model) and then sets up a before_save callback based on your model.
Installation:Get to the command line, navigate to your plugins directory on your rails app, and then type in the following to install Caramel via anonymous checkout:
svn checkout http://caramel-plugin.googlecode.com/svn/trunk/ caramelNote: This will install the very latest version of Caramel, which might be untested or even unstable. As stable, tested versions become available, I will make an effort to post milestones here. Until then, please feel free to use the trunk version, which as of writing seems very stable although untested.
Please also see the Usage section below, since you'll have to make some accommodations in your database.
Usage:For any columns in your database that you would like use for HTML, simply create a column for Textile storage and a column for HTML storage:
create_table :web_pages do |t|
t.column :content, :string
t.column :content_html, :string
end...and in your model, Caramel takes care of the rest with 1 method call:
class WebPage < ActiveRecord::Base
endIf you want more control over the way that Caramel behaves, of if you simply don't want to use Caramel's naming conventions, you can specify which columns to use (and how to treat them) as follows:
class WebPage < ActiveRecord::Base
@@html_columns = [
Sweets::HTMLColumn.new(:raw => :my_textile_column, :cooked => :my_html_column, :redcloth_options => [:lite_mode])
endNote that :redcloth_options (optional) accepts any options that can be read as restrictions for RedCloth.new.
Development Roadmap:The biggest changes I would like to make in the near future are as follows:
Write some tests! I'm new to test-driven-development and to testing as well, so although the current implementation has been tested well in production, I see the value of writing a separate test suite and intend to get one rolling in order to facilitate other items in the dev roadmap: Have the caramelize method accept a block for config rather than reading configuration from a @@ class variable (see activescaffold plugin for a clean example of what I'm talking about). Write an installer for the plugin which generates a migration file and a model file for storing all the HTML in a single table with polymorphic associations instead of requiring that the Textile and the HTML both be in separate columns for each table.