s

Stop! Haml Time!

Nov 23, 2008  -  Comments

Ok, first of all I have to apologize for the title of this post, but I couldn't resist the pun.

Anyway, as the title suggests, I've recently converted all of my erb pages on this site to haml. Haml is a DSL templating language uses to generate well-formed XHTML. The documentation site claims that you can become familiar with the syntax in about 20 minutes. I think, as long as you already know XHTML, you can pick it up in about 10 minutes. The concept is pretty simple. Each tag should be on its own line, and everything contained in that tag should be indented below it. If a tag doesn't have any other tags contained in it, then the content can be on the same line as the tag. Also, div is the default tag, so you can just pass an id or class name to output a div.

%p This is a paragraph tag.
%ul
  %li First list item
  %li Second list item
#id_name Content in div
.class_name Content in div

Will convert to (with beautiful formatting):

<p>This is a paragraph tag.</p>
<ul>
  <li>First list item</li>
  <li>Second list item</li>
</ul>
<div id="id_name">
  Content in div
</div>
<div class="class_name">
  Content in div
</div>

It's really easy to include rails evaluation and output blocks too.

- @posts.each do |post|
  %p
    Written by
    = post.author
  %p= post.date

Notice that there is no need for end when a block is done. When haml sees that the indentation has ended, it automatically ends the block.

You can also pass any attributes to an HTML tag via a ruby hash.

%img{:src => "/images/picture.png", :alt => "Picture", :title => "Picture"}

I think the coolest thing about Haml is how it can assign a class and unique id to an element simply by passing an ActiveRecord object within square brackets.

%div[@post]

Will output:

<div class="post" id="post_18"><div>

If you'd like to learn more, you can take a look at the online documentation, or you can look at the code for my site on Github.

Tagged: tutorialhamlxhtmlruby

Site Redesign

Nov 15, 2008  -  Comments

My site has received a much-needed facelift. The original "design" was something I just slapped together when I was first building the site. It was really an afterthought because I was only concerned with the functionality of the site, and not so much with how it looked.

Of course, this design is not something that I'm capable of. Luckily Andrew, one of the designers at Plexus, needed someone to code his personal site. So we worked out a deal to trade code for design. I think he did a great job. The only drawback was that he wanted me to put a gaudy link to his site in my footer. Sorry.

Tagged: plexusredesign

RESTful Routes Demystified

Sep 14, 2008  -  Comments

RESTful application design is a rails-standard way to structure your CRUD actions. It simplifies your controllers into 7 actions: index, show, new, create, edit, update, and destroy. Here are some basics for working with RESTful routes.

The simple way to get the default routes:

ActionController::Routing::Routes.draw do |map|
  map.resources :products
end

Route Options

Several options can be passed to the route to customize it. You can use the path_prefix option to customize the appearance of your URLs. The name_prefix option is used to change the way the routes are called. The controller option is used to specify a custom controller.

# start all of your URLs with /admin
# '/admin/projects/id/edit/index.html'
map.resources :products, :path_prefix => '/admin/index.html'

# start all of your routes with 'mng_'
# mng_products_path or mng_product_path(:id)
map.resources :products, :name_prefix => 'mng_'

# if you want your URLs to say '/products/id/index.html'
# but your controller is called 'store_products'
map.resources :products, :controller => 'store_products'

Adding Routes for Custom Actions

The resources method will generate the routes for the default REST actions, but what if you want to add your own actions to your controller? There are two options for adding custom routes: the member option is for routes that require an id to be passed, and the collection option is for actions that don't require an id. With each option, you must pass a hash with the action name and the HTTP method.

# return_policy_products_path => '/products/return_policy/index.html'
# submit_question_products_path => '/products/submit_question/index.html'
map.resources :products, :collection => {:return_policy => :get, :submit_question => :post}

# warranty_product_path(:id) => '/products/id/warranty/index.html'
map.resources :products, :member => {:warranty => :get}

Nested Routes

You can nest routes for objects that are related. Say the products have customer reviews with a has_many relationship. You can nest the resources call within the products route definition.

# product_reviews_path(:product_id) => '/products/product_id/reviews/index.html'
# product_review_path(:product_id, :id) => '/products/product_id/reviews/id/index.html'
# edit_product_review_path(:product_id, :id) => '/products/product_id/reviews/id/edit/index.html'
map.resources :products do |products|
  products.resources :reviews, :controller => 'customer_reviews'
end

Those are the basics, but there are a LOT more possibilities. If you're interested, there is a really great guide to all things routes.

Tagged: tutorialroutesrails

Code Golf: Seven-Segment Displays

Sep 08, 2008  -  Comments

Here is my submission for the Seven-Segment Displays challenge. Code size: 292 bytes.

x=gets.chop.split ''
a=' ### '
b='#    '
c='    #'
d='#   #'
e=' '*5
f='  '
g=[a]
h=[d]*3
i=[e]
j=[c]*3
k=[b]*3
l=g+h
m=g+j
n=m+g
y={0=>l+i+h+g,1=>i+j+i+j+i,2=>n+k+g,3=>m+n,4=>i+h+m+i,5=>g+k+n,6=>g+k+l+g,7=>m+i+j+i,8=>l+l+g,9=>l+n}
9.times{|i|puts x.collect{|n|y[n.to_i][i]+f}.join.chop.chop}

Tagged: code golfruby