# HoboFields -- Rich Types This doctest describes the rich types bundled with HoboFields, and the process by which you can create and register your own types. Our test requires to prepare the testapp: {.hidden} doctest_require: 'prepare_testapp' >> ActiveRecord::Migration.create_table :articles do |t| t.text :body t.string :status end >> {.hidden} ## `to_html` method The rich types provide a `to_html` method. If you are using the full Hobo stack you don't need to be aware of this unless you're defining your own rich types -- the `` tag uses `to_html` to render a rich type. If you are not using DRYML and Rapid, you can simply call `to_html` in your views, e.g.
<%= @post.body.to_html %>
If you ever decide to change from, say, plain text to markdown formatted, your view won't need to change. ## Defining your own Rich Type Defining a rich type is very simple. We'll show an example here before we go through the bundled types so that you start with the idea that there's really nothing sophisticated going on here. This class defines the methods `to_html` to customize the way the type is rendered, and `validate` to provide a custom validation. It also defined the `COLUMN_TYPE` constant to tell the migration generator what underlying type should represent these values in the database. # Loud text always renderd in caps. # It's rude to shout too much so it's not allowed to be # longer than 100 characters >> class LoudText < String COLUMN_TYPE = :string HoboFields.register_type(:loud, self) def validate "is too long (you shouldn't shout that much)" if length > 100 end def format # make sure we have enough exclamation marks self =~ /!!!$/ ? self + "!!!" : self end def to_html(xmldoctype = true) upcase end end >> >> LoudText.new("foO "FOO> LoudText.new("foO false If you place this class in `app/rich_types/loud_text.rb`, Hobo will load it automatically. That's all there is to it. Defining `to_html`, `format` and `validate` are optional, defining `COLUMN_TYPE` and calling `HoboFields.register_type` are not. We inherit from String in this instance. This does not work for all types -- for example, with Fixnum, you should inherit from `DelegateClass(Fixnum)` instead. The format function is added as a before\_validation hook. Ensure that multiple invocations of your format function is safe -- shout.format.format should return the same as shout.format. You can use `LoudText` in your model with fields do shout :loud end ## Bundled types Here we'll give a quick overview of the bundled types. Remember that along with the specific features the type provides (e.g. validation), the simple fact that the type exists is also useful in the other layers of Hobo. For example `HoboFields::Types::PasswordString` doesn't add any features to `String`, but the fact that a specific type exists for passwords means that the view layer can automatically render an ``. ### `HoboFields::Types::EmailAddress` Provides validation of correct email address format. >> good = HoboFields::Types::EmailAddress.new("foo@baa.com") >> bad = HoboFields::Types::EmailAddress.new("foo.baa.com") >> !!good.valid? => true >> good.validate => nil >> !!bad.valid? => false >> bad.validate => "is invalid" >> nasty = HoboFields::Types::EmailAddress.new("foo<nasty>@baa.com") >> nasty.to_html => "foo<nasty>&lt;nasty&gt; at baa dot com" >> nasty.to_html.html_safe? => true ### `HoboFields::Types::HtmlString` `HtmlString` provides no special behavior. The main reason for using this type is that the `to_html` method does not do any html-escaping. Use this for columns that store raw HTML in the database. # no safety treatments are done by `to_html`. # even if `nasty.to_html` is actually unsafe, it is marked as html_safe. >> nasty = HoboFields::Types::HtmlString.new("p1

p2

p3p4p5<script>p6p8") >> nasty.to_html => "p1

p2

p3p4p5<script>p6p8" >> nasty.to_html.html_safe? => true >> class Article < ActiveRecord::Base fields do body HoboFields::Types::HtmlString end attr_accessible :body end >> article = Article.create!(:body => ">>p1

p2

p3p4p5<script>p6p8") # some unsafe html fragements are removed on save, # but there's no guarantees that it is well-formed >> article.body => ">>p1

p2

p3p4p5<script>p6p8" >> article.body == article.body.to_html => true >> article.body.to_html.html_safe? => true ### `HoboFields::Types::MarkdownString` `HoboFields::Types::MarkdownString` provides a `to_html` that renders markdown syntax into html. It requires the bluecloth gem. >> markdown = HoboFields::Types::MarkdownString.new %( This is a heading ================= And text can be *emphasised* ) >> markdown.to_html => "

This is a heading

\n\n

And text can be emphasised

" >> markdown.to_html.html_safe? => true # some unsafe html fragements are removed by `to_html`, # but there's no guarantees that it is well-formed >> markdown = HoboFields::Types::MarkdownString.new(">>p1p8") >> nasty.to_html => "p1

p2

p3p4p5<script>p6p8" >> nasty.to_html.html_safe? => true ### `HoboFields::Types::RawMarkdownString` # no safety treatments are done by `to_html`. # even if `markdown.to_html` is actually unsafe, it is marked as html_safe. >> markdown = HoboFields::Types::RawMarkdownString.new(">>p1