debuggable

 
Contact Us
 

How to Plugin'ize your app

Posted on 22/6/06 by Felix Geisendörfer

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

I think a lot of people, including me, are trying to create modularized websites where they can simply drop in a new folder and new functionality will start to appear on the site. The system I'm working on right now is called SpliceIt! and I've decided to use plugins as those modules. In this post I'll explain what plugins are for, how they are implemented in CakePHP and what I did to make them work according to my ideas ; ).

First of all: This is no official documentation of plugins and I think I have a different understanding of how they are supposed to be used then the developers. However, I'll try to clarify this difference as good as possible so you won't be pressured into accustom my bad habbits ; ). The first part is written so _psychic_ hopefully will be able to integrate it into the manual chapter for plugins which is empty right now, the second part will contain some unoffical things I do with plugins.

Ok let's get started:

What are plugins?

If you need a picture for what a plugin is, imagine it to be a mini-app. It has it's own folder for models, views and controllers, it has it's own AppController and AppModel, it is accessed as /plugin/controller/action and it's supposed to be an independent sub application. The most important thing that plugins share with their parent app is the configuration (also database connection for that matter). Otherwise they have almost all features a copied app folder would have.

How to create a plugin?

If you want to create a plugin you have to create a new folder inside app/plugins. The name of this folder will be the name of the plugin when you access it via /plugin/controller/action in your browser, for that reason I think you should use underscored plural terms like you do for controllers as a convention (not sure if this is official so).

Now that you have created this folder, create the following files / folders in it. [plugin] is the name of the plugin you are creating:

  • app/plugins/[plugin]/controllers
  • app/plugins/[plugin]/models
  • app/plugins/[plugin]/views
  • app/plugins/[plugin]/[plugin]_app_controller.php
  • app/plugins/[plugin]/[plugin]_app_model.php

Notice: plugins don't have their own: tmp, webroot, vendors or config folder.

Your [plugin]_app_controller.php and your [plugin]_app_model.php are the AppModel and AppController specific to the controllers/models of the plugin you create. They do extend the AppController / AppModel of your application and should look like this:

app/plugins/[plugin]/[plugin]_app_controller.php:


class [Plugin]AppController extends AppController
{
    // Custom [plugin]AppController code goes in here
}

app/plugins/[plugin]/[plugin]_app_model.php:


class [Plugin]AppModel extends AppModel
{
    // Custom [plugin]AppModel code goes in here
}

Important: AppController and AppModel are optional for a normal application, however they are not optional when you create a plugin. Plugins must have their [Plugin]AppController and [Plugin]AppModel in order to work!

Working with plugins

Now that you have the basic structure of your plugin set up, your just a few steps away from creating your first plugin controller. The only difference between a normal controller is that it rests in a different place (app/plugins/[plugin]/controllers/[controller]_controller.php) and that it extends [Plugin]AppController. The same thing goes for Models. Check out the example:

Plugin='Drinks', Controller='Beer':

class BeerController extends DrinksAppController
{
    var $name = 'Beer';
 
    // Controller logic goes here.
}

Plugin='Drinks', Model='Beer':

class BeerModel extends DrinksAppModel
{
    var $name = 'Beer';
 
    // Model specific functions / varaibles go here
}

There is nothing special about the ways you create views with plugins. Just create a folder app/plugins/drinks/views/beer and put your view files in there for the example from above.

Some useful tipps when working with plugins

You know the basics about plugins, but a couple more things are good to know when working with the for the first time:

  • When you don't have a [Plugin]AppController / [Plugin]AppModel you'll get missing Controller errors when trying to access a plugin controller via browser and the error message will tell you to create your controller in app/controllers
  • You can have a default controller with the name of your plugin. If you do that you can access it via /[plugin]/action. For example a plugin named users with a controller named users can be accessed like this: /users/add if there is no plugin called AddController in your [plugin]/controllers folder
  • Plugins will use the layouts from the app/views/layouts folder by default.
  • You can do inter-plugin communication by using $this->requestAction('/plugin/controller/action'); in your controllers
  • If you use requestAction, make sure controller / model names are as unique as possible. Otherwise you might get PHP "redefined class ..." errors.

Ok, time has run up and I decided to break this post into two parts. This one was the one trying to stay with the CakePHP standards, the next one will be about my dark side plugin practices and will follow in the next 1-2 days.

I hope this eases the use of plugins for people who haven't worked with them before. If you see any errors / have any suggestions please report them to me, so I can clean this post up for the manual as good as possible.

--Felix Geisendörfer aka the_undefined

 

You can skip to the end and add a comment.

RosSoft  said on Jun 22, 2006:

good article

scot lewis said on Jun 22, 2006:

Looking forward to the second half. I had the same idea not too long ago: take a big project and split it up into lously coupled plugins. Of course, I hit the fact that Cake plug-ins are meant to be uncoupled fairly hard. I ended up slicing the app up by using 3 letter prefixes to namespace the MVC for the individual portions. I know there's a better way, but I don't have time to find it at the moment. Hopefully you can do it for me. ;)

Tarique Sani said on Jun 24, 2006:

Thanks for writing this - saw it just as I was about to sit with the code to figure out how plugins worked in cakePHP. Saved me a lot of time

xentek said on Apr 02, 2007:

The thing I can't figure out is how to share models with a plugin. We have a registration plugin that we use across multiple sites, but want to use some of the models in the main application too.

Any idea?

Felix Geisendörfer said on Apr 02, 2007:

xentek:

Cake 1.1: Put loadPluginModels() above your controller declaration and it should work (Warning: You will not be able to have any Models with the same name throughout the app)

Cake 1.2: Put loadModel('Plugin.Model') above your controller declaration. Naming conflicts will only occur if your main app and your plugin use a Model named 'Model'.

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.