Making blogging easy
Creating advanced Typo plugins
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
endI 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
endCouldn’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
endThere’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
endEdit 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
endThis 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
...
endViews
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.
Powered by Typo – Thème Frédéric de Villamil | Photo Glenn
