When I suggested that you write your own blog software, I had no idea that some people would actually take me seriously!
So here’s another tidbit to help you on your way: custom Textile tags.
As a developer, it’s nice to use Textile or Markdown for text entry. Simple tags will be converted to HTML, which will save typing and automatically apply some typographic rules.

But it can go one step further if you’re using RedCloth. You can subclass RedCloth and add methods that define your own tags. This is a great way to add shortcuts for complicated sets of HTML or inject hooks for CSS and Javascript.
To create Figure A, I used a technique mentioned by Garrett Dimon in a Digital Web article. It involves a div enhanced with a few CSS classes, enclosing a caption and an image. In addition, I have the power to make it small, medium, or large. A more complete solution would even allow for alternate backgrounds and placement.
But that’s a lot to type every time I want to reference a captioned image! Instead, I wrote a custom Textile tag to do it for me.
Here’s the custom tag I use:
figure(med). RedCloth 3 Logo | redcloth3-title.jpg
Let’s break it down:
figure is the custom tag name. It’s a hook into a textile_figure method in my application’s subclass of RedCloth.med is a CSS class that will be applied to the div that wraps the figure. This gives me easy control over the size of the figure, and could even be used to pass multiple classes for other effects.In that single line, I have all the information I need to construct a figure. Those 50 characters will result in over 200 characters of HTML. I can also use a few lines of Ruby to assign an auto-incrementing figure letter (“Figure A”) and reuse the caption as an alt tag for the image.
First, choose a color for your subclass. CaneSugarBrownCloth? MintJulepGreenCloth? It could take hours.
Next, create a file for your subclass. I put yellow_cloth.rb in the lib directory and required it from environment.rb.
unless RedCloth
require 'RedCloth'
end
class YellowCloth < RedCloth
# ...
Next, define your custom method. I have a simple ruby tag that applies a CSS class for use with my code highlighter.
def textile_ruby( tag, atts, cite, content )
# TODO Use the arguments to build some HTML
# and return a string.
end
The arguments passed in can be reused or ignored.
tag is the name of the tag passed in (ruby in this case).atts is a pre-assembled string with passed CSS classes, IDs, hard-coded styles, and language identifiers. If you want to augment this, you’ll need to parse the string and append your own CSS classes (I did this for the figure tag).cite is rarely used.content This is the actual code, text, or paragraph that follows the tag. In the figure tag, I decided to parse this further and use the elements as the caption and image name.The figure tag is more complicated.
figure class to any CSS classes passed in. In order to do this, I need to parse the atts and extract existing CSS classes.content on the pipe and use the elements as the caption and image name. You could prepend a filepath onto the image name if all your images are stored in the same place.def textile_figure(tag, atts, cite, content)
span_class = ""
if atts =~ /class="([^\"]+)"/
span_class = $1
end
(caption, img_url) = content.split("|").map { |w| w.strip! }
figure_name = "Figure " + @figure_counter.chr
figure_id = figure_name.downcase.gsub(" ", "-")
@figure_counter += 1
# TODO Construct the HTML
end
Finally, here’s the code to setup the counter:
def initialize(*args)
@figure_counter = ?A
super
end
To use your new class, you can override the built-in textilize helper or write a before_save callback on your model to convert the text to HTML with your custom subclass.
before_save :textilize_body
def textilize_body
self.body_html = YellowCloth.new(self.body).to_html
end
The entire code can be downloaded: yellow_cloth.rb

If you use TextMate, you may be aware of the “Show Web Preview” menu item.
It can pipe the text of the current document through its own textile.rb script or through your custom script. I wrote a simple script that uses my subclass instead of RedCloth.
# script/textile.rb
require 'rubygems'
require 'yellow_cloth'
textile = ARGV[0] ? File.read(ARGV[0]) : STDIN.read
puts YellowCloth.new(textile).to_html
Then use the full path to this script as the argument to ‘Pipe text through’:
/Users/topfunky/repos/funkyblog/script/textile.rb
I’ll be speaking at both RailsConf Portland and RubyFringe.
After many requests, I’m proud to introduce the new PeepCode Unlimited plan that gives you a year of access to all PeepCode content. On sale for only $139 until March 21.
Merb is a great compliment to Rails or a capable web framework in its own right. A draft of the PeepCode PDF on Merb is now available (includes a free upgrade when the final is published in the next few weeks).
PeepCode has been growing quickly and we have a ton of new content in the works. Ryan Daigle’s Rails 2 PDF recently became the best-selling PeepCode product of all time. Cody Fauser’s ActiveMerchant PDF is already being called a must read.
Given the number of good blogging engines out there, I was skeptical of your post about building your own blog engine.
But lately at work I’ve been building one for our product Tumblon and it has been an interesting, rewarding experience—especially trying to build something that’s easy for people to use.
Your post certainly inspired me to create my own blog/CMS running on Slicehost. It’s quite interesting to see how many things I didn’t need in blog software. The only two things I would like to implement are future-posting and categorisation of posts. But both of these can wait for the time being.
But if you happen to post a mega-article which more than 25 or so figures, the figure labels start getting interesting! ;)
I would of used:
Yielding somewhat coherent Z, AA, AB figures, and would work with numbers just as well ;)
Great article, nice to see that RedCloth is easily extensible.
How would one go about creating custom inline tags? The method above only seems to work for tags on their own line.
Thanks.
This is going to be very useful. I especially need help with my html coding. All that I do seem to fail on me because I do not follow instructions clearly.
@Mikko Yes, it appears that my figure numbering solution does not scale!
For a client project we needed to build a friendly way to allow copy editors add various foreign characters in an easy manner so we did things like:
For example:
..etc.
Textile provided a nice starting point and we were able to easily extend this to provide this.
I also wrote my own blog software because of your recommendations. Thanks, it was a great experience!
D’oh! Why didn’t I think of this?
I tried writing my own … nearly got divorced, gave up and used Typo!
@Danners: You make this old typo maintainer very happy.
Hi! Really interesting. Thanks for sharing all this valuable knowledge. I read many good books (also your PDFs) and now I’m trying to write my own blog engine. Not an easy task.
This is great. I’d love to see some examples using Markdown instead of Textile!
Has anyone tried to extend the latest stable RedCloth gem? Maybe I’m just doing something dumb, but it appears that it breaks YellowCloth:
# Using RedCloth version 3.274 require 'RedCloth' => true class YellowCloth < RedCloth def textile_ruby( tag, atts, cite, content ) %(<pre><code class="ruby">#{content}</pre>) end end => nil YellowCloth.new(‘ruby. def blah()’).to_html => ”<p>ruby. def blah()</p>”@Chris: I have the same problem. I’ve been using the same technique for a while but my YellowCloth class doesn’t work with the latest build either.
I think the latest RedCloth gem (v3.290) is an extensive re-write to the previous versions and isn’t as easily extended as the version used in this article.
Just a quick follow-up on my previous comment. Those people using the latest version of RedCloth (v3.290) who wish to used customised textile markup and HTML output might be interested in this thread.
http://www.ruby-forum.com/topic/149632
I think Geoffrey’s technique works best in version v3.0.3 or v3.0.4.
Thanks. Very helpful
Than you for this information.
I’m about to start coding a blog engine. Your posts help me a lot to figure out how to code properly. Thank you.
Thanks a ton! Very well written article that was easy to follow. I definitely plan on implementing on my own blog, and hopefully it won’t lead to a divorce scare like @Danners!
Thank you for this article, it was a great experience !
Thanks for share us the great Archive!
Interesting post, thanks for all, where can I find more information about this.
I am not expert in CSS but with your explanations I manage to do it. It´s a good feeling to see the result. Thanks for the tutorial.
thanks for the information
Dear sir,
I, R.isher would like to introduce my company as a one stop solution provider in the niche area of “quality maintenance” for Buying houses, Textile Exporters and Textile Manufacturers. The group has 18 man years of textile domain experience ranging from production to selling, exporting and buying.
We are pioneer and leader in providing “quality maintenance/inspection services” to our clients. Moreover, we only introduced this line of service in the market.
We provide Quality assistance to Buying houses, Exporters and Manufacturers.
We provide our services on different models like ‘on-demand inspection’ and ‘dedicated inspection’ to buying houses, manufacturers and exporters.
We help manufactures to improve quality system for delivering quality goods.
OUR SALIENT FEATURES:
a. You engage us for assuring quality of your goods and that’s all you have to do rest is taken care by us. You only pay the time you require services for and not for the whole month salary of employees you hire as ‘quality analysts’ at present, thereby we help you in reducing your expenditure.
b. We are available round the clock through out the year so you need not to worry about the availability* and delays in your shipment or goods delivery. (* booking minimum one week before the inspection)
c. Since we are at service providing end we always ensure the best Technical and highly skillful Quality persons are placed.
d. Ensuring total peace of mind for you.
With PraZise you will get best quality delivery of your goods with least botheration.
For further inquiries please write to praZise@post.com
With Best Regards R.Isher Director PraZise Quality Solutions Delhi
very good article, and very good work, my great deal.
it is certain that this article deserves comment suplementaires very good job
it is certain that this article deserves comment suplementaires very good job
Its very interesting ! great post !
thanks for the information
very good article, and very good work
Thanks for sharing, very interesting, i will use it as soon as possible !