Typo official weblog

Making blogging easy

2 days ago, there was a guy called Fish who joined us while I was idling on #typo. He was asking for a gallery plugin for his Typo blog. As I’m a photographer, having such a plugin had been on my TODO list for like years now, so I told him I would do a quick proof of concept during my daily train commute. A few hours later, when I went back home, the plugin was working. It was very simple, displaying files uploaded on a Typo blog with thumbnail, pagination, medium size and large size displayed in a lightbox. Indeed, it wasn’t enough, and Fish came back asking for multiple albums and picture selection, caption, so I came back to work. As a developper, Fish could probably have done it himself, but I’m more familiar with Typo internals, and even I didn’t know how far I could go with Typo plugin integration.

Tonight, during my daily commute, I extended my gallery plugin with full admin and frontend integration. The gallery is not working yet, but the biggest part is working: integrating a complexe plugin in a Typo blog. I wanted to share this with you as a HOWTO.

Before trying this, please be sure you’re using Typo HEAD as Friday April the 8th, or a Typo version above 6.0.4 (even though it’s not released yet) as you’ll need the route.rb modification I had to do.

Creating the plugin

As Typo plugins are just plain Rails plugins, creation is kinda trivial.

./script/rails generate plugin typo_sample_plugin

You’re now going to create some folders to reflect a Rails application tree:

cd vendor/plugins/typo_sample_plugin
mkdir -p app/controllers/admin app/models app/helpers/admin config app/views/admin

Good, you’re now ready to code the main stuff. Edit your new plugin, and let’s go!

Making your code accessible

Now, you’re going to make Typo access your code. Edit your init.rb file and add the following:

PLUGIN_NAME = 'typo_sample_plugin'
PLUGIN_PATH = "#{::Rails.root.to_s}/vendor/plugins/#{PLUGIN_NAME}"
PLUGIN_CONTROLLER_PATH = "#{PLUGIN_PATH}/app/controllers"
PLUGIN_VIEWS_PATH = "#{PLUGIN_PATH}/app/views"
PLUGIN_HELPER_PATH = "#{PLUGIN_PATH}/app/helpers"
PLUGIN_MODELS_PATH = "#{PLUGIN_PATH}/app/models" 

config.autoload_paths += %W(#{TypoSamplePlugin::PLUGIN_CONTROLLER_PATH}  \
                            #{TypoSamplePlugin::PLUGIN_HELPER_PATH}      \
                            #{TypoSamplePlugin::PLUGIN_VIEWS_PATH}       \
                            #{TypoSamplePlugin::PLUGIN_MODELS_PATH}

ActionView::Base.send(:include, TypoSamplePlugin::Helper)

The routing

Unless Rails generators, your plugin won’t be allowed to change routes.rb. We want our end users to remove them if they don’t want them anymore. So we’re going to create our own config/routes.rb. It’s going to look like this:

ActionController::Routing::Routes.draw do |map|
  map.connect 'sample_plugin/:action', :controller => 'typo_sample', :action => 'index'
  
  %w{ sample_plugin }.each do |i|
    map.connect "/admin/#{i}", :controller => "admin/#{i}", :action => 'index'
    map.connect "/admin/#{i}/:action/:id", :controller => "admin/#{i}", :action => nil, :id => nil
  end
end

I know, we’re still using Rails 2 routing DSL. It’s bad but Rails 3 can’t handle everything we do.

The first block is for your frontend controllers, the second one for the admin. Easy as pie isn’t it?

The models

She’s a model and she’s looking good. I’d like to take her home that’s understood.

Add your models files in app/models exactly like on any Rails application. You can use any Active Record relations you want and access or extend existing Typo models.

To create your database schema, edit your init.rb file, and add the following code:

unless ::TypoSamplePlugin.table_exists?
  ActiveRecord::Schema.create_table(TypoSamplePlugin.table_name) do |t|
    t.column :name,  :string
    t.column :description,  :text
  end
end

Couldn’t be easy heh? Now let’s switch to the front and back office thing.

The front thing

Controllers

To be able to display your content within your Typo blog layout, every front end controller will need the following code:

class TypoSamplePluginController < ActionController::Base 
  unloadable
  layout :theme_layout
  before_filter :template_root
    
  def template_root
    self.class.view_paths = ::ActionController::Base.view_paths.dup.unshift(TypoSamplePlugin::PLUGIN_VIEWS_PATH)
  end
  
  def theme_layout
    File.join("#{::Rails.root.to_s}/themes/#{Blog.default.theme}/views", Blog.default.current_theme.layout(self.action_name))
  end
    
end

There’s certainly a cleaner way to do it by not repeating the code, but I’ll dig it later.

Views

Nothing special here. Really.

The backend thing

OK, now you want to give your plugin a fancy back office? Let’s go.

Adding your module to the admin

Edit your init.rb. In your model creation block, add the following:

admin = Profile.find_by_label('admin')
admin.modules << :typosampleplugin
admin.save
  
publisher = Profile.find_by_label('publisher')
publisher.modules << :typosampleplugin
publisher.save    

This will update both admin and publisher profiles giving them the rights to access your plugin admin.

Now, let’s add them to the access control list (and the menu as well). This is still in init.rb

AccessControl.map :require => [ :admin, :publisher, :contributor ]  do |map|
  map.project_module :typosampleplugin, nil do |project|
    project.menu    "My plugin meny",  { :controller => "admin/typo_sample_plugin" }
    project.submenu "My submenu", {:controller => "admin/typo_sample_plugin_other" }
  end
end

Edit your lib/typosampleplugin.rb and add the following:

module Helper
  def class_typosampleplugin
  return class_selected_tab if controller.controller_name  =~ /typo_sample_plugin/
  class_tab  
  end
end

This will allow you to manage the tabs highligh in the admin.

Controllers

Your controllers will go to app/controllers/admin and will all look like this, pretty like normal admin controller:

module Admin; end

class Admin::TypoSamplePluginController < Admin::BaseController
  layout 'administration'
  unloadable

  ...
end
Views

Typo plugins admin views look like normal admin views. Minimum code is:

<% @page_heading = _('Sample plugin') %>
<% subtabs_for(:typosampleplugin) %>

You can access any admin helper like saveorcancel or linktonew.

Here we are (born to be kings). I’ll release Typo Gallery when I finish it, which could happen very soon as I’m thinking about quiting Flickr to host my photos somewhere like I used to do with Wordpress + Gallery2 in the past, many, many cycles ago.

Published on 08/04/2011 at 17h08 under . Tags , , ,

Powered by Typo – Thème Frédéric de Villamil | Photo Glenn