Fork me on GitHub

Building Bricks

An article by Gaspard Bucher

zena extension modules

This tutorial will drive you through writing a special model for zena with custom content, and do this by creating a proper brick.

First, prepare a folder for your brick. Let’s call it “gardening”.

1. write your model

Write the code in gardening/models/plant.rb.

class Plant < Page
  zafu_readable :water_level

  def self.ksel
    "A" # klass selector cannot be "P"
        # "P" is a for Project: NPP => Project
        # with this "A" selector: NPA => Plant

  def water_level
    # funky, obscure, top-secret ruby code

2. (optional) custom content

If you need a custom table (dynamic attributes are not enough), you can write a migration and version/content classes:

Write the migration in gardening/migration/001_create_plant.rb

class CreatePlant < ActiveRecord::Migration
  def self.up
    create_table "plant_contents", :options => 'type=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci' do |t|
      t.column "version_id", :integer # << mandatory !!
      t.column "brand", :string, :limit => 60, :default => "", :null => false

  def self.down
    drop_table "plant_contents"

Write the version and content classes:


class PlantVersion < Version
  def self.content_class


class PlantContent < ActiveRecord::Base
  zafu_readable :brand

These two models help zena find the correct version/content when loading a “Plant”.

3. your brick is now

  + models
    + plant.rb 
    + plant_version.rb
    + plant_content.rb
  + migration
    + 001_create_plant.rb

You could further personnalise zena by adding rules inside the “zafu” folder or patch zena files by writing content inside “patch” (see the “captcha” brick as an example).

4. activate

Drop your “gardening” brick into a bricks/ subdirectory in a zena app.

Migrate the database:

# rake zena:migrate

Migrations are “scoped”: zena maintains a migration version for each brick. So a brick vendor might update the brick someday and add a migration in the “migration” folder of his brick. This is fine. Running zena:migrate again will update the database accordingly.

5. (deactivate)

Some day you realize this brick is a bad idea and you want to remove all traces of this thing:

# rake zena:migrate VERSION=0 BRICK=gardening

And then remove the “gardening” folder out of the “bricks” folder.


You now have a new class called “Plant” which you can use just as any other class. You can write a custom edit tab by creating a template called Plant-+edit (Plant scope, “+edit” mode), you can access/set the custom plant content by using c_brand, c_brand=, etc.