Wednesday March 30, 2005
I’ve been doing a bunch of work on Collaboa in the past few nights, mainly bringing it up to date with the latest Rails and a general major overhaul.
One of the problems with previous versions was the there was no validation of user inputted Markdown and since BlueCloth has a habit of blowing up in the face of users whenever the syntax isn’t complete. Left out backticks, for inline code, are in particular troublesome.
So I wanted to check that the syntax was proper through Rails’ validation methods before saving anything and giving the user he ability to fix his syntax errors. The following was the simplest solution I came up with.
protected
def validate
errors.add("content", "has #{invalid_markdown_syntax(self.content)}") »
unless invalid_markdown_syntax(self.content).nil?
end
private
def invalid_markdown_syntax(text)
begin
BlueCloth.new(text).to_html
return nil
rescue BlueCloth::FormatError => e
return e
end
end
Since I want to display the syntax error to the user, I’ll have to return the error that BlueCloth raised so I can display it in the validation failure message and return nothing (nil) if BlueCloth didn’t choke on anything. This way the following text will be displayed on Markdown formatting errors (typing ``foo` is something BlueCloth will usually choke on): "Content has bad markdown format near “foo”: No “`” found before end".
UPDATE Jeremy stepped up and offered a much better solution to the problem, which follows the “Ruby Way” (and/or Rails way) of dealing with it, see the comments below
Mar 30 at 18:07
Introduce a class method you can reuse to declare other Markdown validations:
The validation is slow because it has to do the Markdown render to check for validity. TODO: check validity only if the source has changed since the last render; cache generated HTML.
Mar 30 at 18:09
Imagine that code beautifully indented and correctly marked up. Imagine all the people.
Mar 30 at 18:21
Jeremy, I imagined it so hard I edited your comment to look slightly better (with the code formatting).
This is really a better solution for the problem, and I wouldn’t have to repeat myself, nor step outside of the valides_* pattern. Thanks man!
Apr 01 at 06:20
Were you to mix in some of Rails’ Ajax helpers here, I think you’d have a big leap forward in usability. I’m thinking along the lines of hooking the preview up to an Ajax action that sends the Markdown to the server and displays validation errors and a preview in the form. This would also allow you to set an “is valid” flag on the client, preventing embarassingly formatted posts.
For bonus points, you could throw in something like the quicklink bar in Wordpress, except with shortcuts for whatever markup language you’re using. Besides the whole browser crashing and nuking your work, I think this would be a vast step forward in usability.