Markaby is a Ruby library that lets you write HTML in Ruby. It's built into the Camping framework as the templating engine. To create elements, you call a method of that name.

# In Camping, you don't have to set up the Builder.
# I'll leave it out in the other examples.
mab = Markaby::Builder.new
mab.p "This is a paragraph."
mab.div "I can do the same thing with a div."

To nest your HTML, you can pass a block.

form :method => 'post' do
legend 'Import stuff'
textarea :name => 'queries', :rows => '25', :cols => '100'
input :type => 'submit', :value => 'Import!'
end

[A side note, the textarea method inserts some whitespace by default. Very annoying, so if you know how to get rid of it in a non-hacky way, please let me know.]

It uses lots of metaprogramming trickery to make your life a whole lot easier. For example, you can add an arbitrary class to an element by calling the class name as a method.

div.example "This div will be of class example."

The class methods can also be chained.

div.example.special "This div will be of class example _and_ special."

You can do the same thing with an id by simply appending a bang (!) to the class name.

div.main_content! "This div will have the id main_content."

But what if you want a variable class name? I can't just tack the variable name on because the magic will mean that the class will be the name of the variable, not the value.

%w[one two three].each {|c| puts mab.p.c.to_s}

That's not going to work. It will output this.

<p class="c"/>
<p class="c"/>
<p class="c"/>

Ruby's send method to the rescue.

%w[one two three].each {|c| puts mab.p.send(c)}

This correctly outputs this.

<p class="one"/>
<p class="two"/>
<p class="three"/>

Turns out I don't go through the most rigorous process to decide what technology to use. I've been using Camping for quite a while now, on a couple of small internal projects. I know there are other lightweight Ruby frameworks out there, such as Sinatra and Ramaze. So, why did I choose Camping? Why? Simply because Camping seems more interesting, and things should be fun. And maybe that question is part of the answer, _why.
Now that you've got JQuery in your Camping application, one of the things you might want to do is take advantage of JQuery's AJAX capabilities. I'm going to assume you're familiar with AJAX, and JQuery's implementation of it, and just talk about how to get it going in Camping. If it's foreign to you, you might want to look at a handy AJAX and JQuery tutorial. To save me from having to make up an actual interesting example, I'm going to write a hideously incomplete todo list application, much of it ripped off and JQuery-fied from Jan Lehnardt's CouchDB ...
[read more]
I've written here and here about serving static files with Camping, but each time I've set up a new route for each resource type. You can serve all static files with a single route by following the instructions on the wiki. Here's the code that's presented there. module Camping::Controllers class Static < R '/static/(.+)' TYPES = {'.css' => 'text/css', '.js' => 'text/javascript', '.jpg' => 'image/jpeg'} PATH = File.expand_path(File.dirname(__FILE__)) def get(path) @headers['Content-Type'] = TYPES[path[/\.\w+$/, 0]] || "text/plain" unless path.include? ".." # prevent directory traversal attacks @headers['X-Sendfile'] = "#{PATH}/static/#{path}" else @status = "403" "403 - Invalid path" end end end ...
[read more]
Camping is great, yeah. JQuery too. Maybe you want to use them together? Here's how. First, you need to set up a route for your JQuery. I've talked about sending static files with Camping before, so this is just a modification of that. [You can serve static files more sensibly than setting up a route for each type. Maybe one day I'll write about that.] In your controller: module MyApp::Controllers class Index < R '/' def get render :index end end class JQuery < R '/resources/jquery.js' def get current_dir = File.expand_path(File.dirname(__FILE__)) @headers['Content-Type'] = "text/javascript" @headers['X-Sendfile'] = "#{current_dir}/resources/jquery.js" end end end ...
[read more]
Camping interprets every request to the server using the paths in the controllers, so if you want to serve static files, like external stylesheets or images, you need to provide a controller for them. Take this bit of Markaby: img :src => 'images/logo.png' This will get interpreted by Camping and end up with this HTML: <img src='images/logo.png' /> When the browser reads that, it will send a GET request to the Camping server looking for logo.png, that Camping will try to match against the controller paths. If you haven't set one up, you'll get an error. So, in your ...
[read more]
If you want to pass information to a Camping controller, all you have to do is define the class like this: class Index < R '/(\d+)' get(id) Now whatever was matched by the regex \d+ can be retrieved by the variable id. If you want to pass more than one variable, just chain them like this: class Index < R '/(\d+)/(\w+)' get(id, action) Each of your regex groups will be passed as a variable. If you forget to add the arguments to the get method, you'll get an error like this:

Camping Problem!

MyApp::Controllers::Index.GET

ArgumentError wrong number of arguments ...

[read more]