My First Plugin
Introduction
ColdBox supports custom plugins created by YOU!! You can now extend the power of the framework to any application specific task that you would like to do. How? Well, all you need is to create the plugin cfc in your plugins convention folder or in your external plugins location folder. After that its just a matter of calling it from anywhere you want. This guide will show you how, but if you have not read the Plugins Guide I recommend you read it first.
Creating the plugin component
The first step to creating your own plugin would be to plan it and decide what you need to do (Your job, not mine!). Based on that first step, the second step is to create the cfc. Below is a hello world plugin template. In the ColdBox distribution you can find a collection of snippets that will make these steps take 5 seconds and I am not lying!!
<cfcomponent name="hello" hint="This is a hello plugin" extends="coldbox.system.plugin" output="false" cache="true" cachetimeout="20"> <!------------------------------------------- CONSTRUCTOR -------------------------------------------> <cffunction name="init" access="public" returntype="hello" output="false"> <cfargument name="controller" type="any" required="true"> <cfset super.Init(arguments.controller) /> <cfset setpluginName("Hello Plugin")> <cfset setpluginVersion("1.0")> <cfset setpluginDescription("This is a hello plugin.")> <!--- Any constructor code you want ---> <cfreturn this> </cffunction> <!------------------------------------------- PUBLIC -------------------------------------------> <cffunction name="sayhello" output="false" access="public" returntype="string" hint="Say hello"> <cfreturn "Hello there, my name is #getPluginName()# #getPluginVersion()#"> </cffunction> <cffunction name="sayHelloFromEvent" output="false" access="public" returntype="string" hint="Say hello from event object"> <!--- Get Event Context ---> <cfset var event = controller.getRequestService().getContext()> <!--- Return the name in the event context ---> <cfreturn "Hello there, my name is #event.getValue("name","")#"> </cffunction> <!------------------------------------------- PRIVATE -------------------------------------------> </cfcomponent>
Where do I save it?
Since version 2.5.0 you can now have the option of creating a plugins directory under your application root. This special folder is used by the ColdBox conventions to find any custom plugin. So you can just place it there if you want. However, you have another option for custom ColdBox plugins, via an external location path defined in the configuration file. So to recap, the ways to use custom plugins are:
- Via a convention directory: plugins by default
- Via the MyPluginsLocation setting in your configuration file.
The External Location Approach
All you need to do is in your application's coldbox.xml declare the MyPluginsLocation setting to the path where you stored your plugin. This path is an instantiation path and not a real physical path. ColdBox will use this path as a prefix to find your external custom plugins. Example: If you would use a createObject method call to instantiate the custom plugin the path would be: myapp.customplugins.hello Then the MyPluginsLocation would be: myapp.customplugins. This way you can package your custom plugins, have them live outside the application, etc.
<Setting name="MyPluginsLocation" value="myapp.customplugins" />
The Caching Parameters
Since ColdBox is built with a solid object cache foundation, your plugins can also be cached if needed. You will do this by adding some meta data attributes to the cfcomponent tag. By default plugins WILL NOT be cached, unless you specifically use the cache meta data attribute. Caching of plugins simulates persistence, so remember this if you are planning plugins that can maintain their own persistence. This is a true flexible and awesome feature. Persistence controlled by the framework for you.
| ATTRIBUTE | TYPE | DESCRIPTION |
| cache | boolean | A true or false will let the framework know whether to cache this plugin object or not. |
| cachetimeout | numeric | The timeout of the object in minutes. This is an optional attribute and if it is not used, the framework defaults to the default object timeout in the cache settings. You can place a 0 in order to tell the framework to cache the plugin for the entire application timeout controlled by coldfusion. |
| cacheLastAccessTimeout | numeric | The last access timeout of the object in minutes if using last access timeouts. This is an optional attribute and if it is not used, the framework defaults to the default last object timeout in the cache settings. |
The Inheritance
As you can see from the code above, all plugins need to extend coldbox.system.plugin. Thanks to this inheritance, every plugin is now part of the framework life cycle. It will have access to all necessary methods and data channels the framework provides. For an in depth look at all the inherited properties, methods and behaviors please look at the Reserved Words & Methods Guide and the Live API
Your Methods
You have now seen what your plugin object is and what its parents are. So you can now build private/public methods that will make your plugin specific. So code away and create your own methods...
Below is a sample method:
<cffunction name="hello" output="false" access="public" returntype="string" hint="Say hello"> <cfreturn "Hello there, my name is #getpluginName()# #getpluginVersion()# and I am running on #getSetting("codename",true)# version #getSetting("version", true)#"> </cffunction>
One thing you can count on for any plugin is that the '''init()''' method, which is the constructor, will always be called when the plugin is created.
Getting access to the request context
You also have the ability to get the request context from within a plugin, all you need to do is use the following code:
<cfset var event = getController().getRequestService().getContext()>
This asks the request service to give you the current request context. You can then manipulate the event object as needed.
How to call the plugins?
Now that you have created your plugin, you are ready to use it. You can call it from your event handlers/layouts/views or even other plugins by using the following methods:
- getPlugin(plugin='plugin name',customPlugin=true, [newInstance])
- getMyPlugin(plugin='plugin name', [newInstance])
So if you need to get a custom plugin, just pass the custom plugin boolean flag as true to the getPlugin() method. The newInstance argument, tells the plugin factory to give you a new fresh instance of that plugin. If not, you could be potentially getting a cached plugin. The default value is false.
Below is a sample:
<cfscript> myPlugin = getPlugin(plugin="hello",customPlugin=true); myPlugin.sayHello(); //or you can even do event.setValue("My Hello", getPlugin("hello",true).sayHello() ); </cfscript> //or <cfoutput>#getPlugin("hello",true).sayHello()#</cfoutput> <!--- GET MY PLUGIN SYNTAX ---> <cfscript> myPlugin = getMyPlugin("hello"); myPlugin.sayHello(); //or you can even do event.setValue("My Hello", getMyPlugin("hello").sayHello() ); </cfscript> //or <cfoutput>#getMyPlugin("hello").sayHello()#</cfoutput>
Conclusion
As you can see from this example, ColdBox Plugins are extremely flexible and easy to build. You can extend the framework to any application specific task you need, you can build security filters, AJAX widgets, extend the core plugins, and much more. This is giving true power to the developer to extend the framework not only programmatically but visually. So get to it!!
