Building Modules

tsnow edited this page Jun 30, 2011 · 6 revisions
Clone this wiki locally

This guide covers how to create and package modules for BrowserCMS. Modules are the primary way to expand the functionality of the BrowserCMS core project. After reading this guide, you should understand how to:

  • Create a new module
  • Add blocks and portlets
  • Add new controllers
  • How to modify core modules using open classes
  • Package and Test your module in another CMS project.

This guide is for BrowserCMS 3.3. It is still being updated and is a Guide needing updating for 3.3

Getting Started

The guide is going to walk how a new module can be created from scratch. The goal for our sample module will be to add some Pet Store functionality to BrowserCMS, and allow editors to create new products and users to browse a product catalog. This module will be built to show off some of the most common techniques used to add dynamic behavior to BrowserCMS projects.

To start a new module, run the following command:

$ bcms module bcms_pet_store	

This will create a browsercms project, which will be structured to help test your module as its being built. The module command will a project design to be packaged as gem for reuse. Note that the name of any module must start with bcms_ or the files won’t be generated correctly.

Generated Files

After the project has been created, there are a number of files which are created. Here’s a brief list of the notable files and their purpose.

File Purpose
.gitignore Contains a list of files which will not be checked into git
bcms_pet_store.gemspec An initial gemspec to package the module as a gem.
lib/bcms_pet_store.rb Used for requiring files not in the app/ loadpath. You may need to update this if you add new files under lib.
public/bcms/bcms_petstore/ A directory for public files which should be copied into projects that use this module.
lib/bcms_pet_store/routes.rb A place to define routes for this module, like content blocks. These routes will be included in projects that use this gem.
lib/bcms_pet_store/engine.rb Engine used to configure the module

Note the gemspec, license (LGPL) and copywrite files specific to BrowserMedia, therefore you will likely want to edit these later to reflect your own purposes.

Creating Blocks

One of the most common reason to creating a module is to define one or more Content blocks that can be added to projects. For our Pet Store example, we will create a Product block which will represent a purchasable good in our Store. Run the following command inside the project.

$ rails generate cms:content_block product name:string price:integer description:html

This is the exact same generator used to create content blocks for any BrowserCMS project. You can run rake db:migrate and see this block in the CMS Admin UI.

Defining routes for the module

Each content block will have its own routes for the Admin UI, which the generator will place into the config/routes.rb. This works fine for a BrowserCMS project, but not as a module as the config/routes.rb file won’t be packaged in the gem. To fix this, we need to move the route from the config/routes.rb to the lib/bcms_pet_store/routes.rb. Open the latter file and alter to look like this:

module Cms::Routes
  def routes_for_bcms_pet_store
    namespace(:cms) do |cms|
       cms.content_blocks :products

Then edit the +config/routes.rb file to look like this:

BcmsPetStore::Application.routes.draw do

By doing this, we are defining our routes in a reusuable way, both for the gem as well as the bcms_pet_store project for testing. All routes that you want to make available to projects should be defined in the lib/bcms_pet_store/routes.rb file, which developers will add to their routes by calling map.routes_for_bcms_pet_store.

Restart your server and verify that you see that the routes still work.

Displaying Products in our Site

Now that we have our product data, we can use the Admin UI to create some sample product data. But how do we display our products to our site visitors. In a typical Rails project, you might create a controller that looks up the products and shows them in a view. However, in a BrowserCMS project we probably want to take advantage of displaying products on CMS page which can be styled by our CMS editors.

To do this, we need to use portlets.

Copying files into projects.

  • rails/init.rb

Adds the gem root to the rails paths, adds all migration files to the list of files that will be copied into any application using the module when script/generate browser_cms is run, and adds all files in public/bcms/bcms_[module name]/ to the list of files that will be copied into any application using the module when script/generate browser_cms is run.

Conventions When Building Your Module

Build your module as if you were building a rails application that does whatever you want.

That said, there are some conventions that tend to make things easier.

First, place any files that are used as configuration files for public assets (for example, the fckeditor) in the public/bcms_config/[module_name] directory and have the gem only copy them if they are not already there. For example you can add code like the following to the rails/init.rb file.

unless File.exists?("#{Rails.root}/public/bcms_config/fckeditor/fckstyles.xml")
  Cms.add_generator_paths gem_root, "public/bcms_config/fckeditor/fckstyles.xml"  

This will make the required configuration file available to the fckeditor, but it won’t overwrite it (or even ask you if you want to overwrite it) every time you run script/generate browser_cms for your application.

Make sure when you add routes (typically as a side effect of generating content_blocks), that you move them from the config/routes.rb to lib/bcms_module_name/routes.rb. Otherwise, they won’t be included in the project.

Also, if you add migrations, uncomment the following line in lib/generators/bcms_module_name/install/install_generator.rb

  1. Edit this to add the name of the migration to be copied into the project.
    copy_migration_file ‘DATESTAMP_create_name_of_content_block.rb’

Testing Your Gem

We strongly encourage the creation of unit, functional, and integration tests as part of your module.

We also suggest that you test your gem against a BrowserCMS application. To do this, first run

bcms module_tester -m demo

wherever (I use /var/tmp). Edit the config/environment.rb file to include the line

gem.config 'bcms_[module name]'

then run the app locally and make sure your module works as expected.