Monday, 17 January 2011

Create your first grails plugin

Crucial to the success of grails, is its support for plugins. Grails was designed keeping pluggability in mind right from the start. Ease in development, testing, building and distribution of plugins has led to a larger community interest in the framework, with loads of plugins available for developers to choose from.

If you’ve worked with grails, chances are you’ve used at least one grails plugin such as hibernate, logging, acegi, grails UI, mail, searchable etc. Grails maintains a plugin repository that you can search to find a plugin most suitable for your requirements. But have you ever found yourself in a situation where you’re rewriting the same code in multiple views, or duplicating code between controllers and services and even between multiple grails applications? If yes, this could be your chance of trying your hand at a plugin!

I’m presenting a very basic tutorial to create a very simple grails plugin, with a service and a taglib that can be reused across grails applications.( find a download link for the source code of the sample plugin at the bottom of the page)

This sample is tested using the following specifications:
  1. grails version: grails-1.3.4
  2. JDK version: jdk1.6
Let’s get started.

1. Choose a folder for your plugin source code.
2. To create a plugin named ‘customplugin’, use the following command at the command prompt.
            grails create-plugin customplugin

This would create a structure such as this:

The plugin structure is almost exactly the same as a normal grails application. Thus you can add controllers, services, views, taglibs to your plugin just as you'd add them to a grails application. 

You will find an additional file CustompluginGrailsPlugin.groovy at the root folder. This is the file that contains all the information or metadata for your plugin. 

You can specify the version number, grails version that your plugin will work with, auther name, etc. Your plugin could depend on other plugins, for instance, you could write a plugin that works with database events which might need the hibernate plugin, such dependencies can be specified in this file. There are also several hooks (events) that are provided, which you can use to perform certain actions or load classes. For eg, if your plugin wants to make some changes/additions to the web.xml, you could plug that code in the doWithWebDescriptor closure provided. For the purpose of this tutorial, we are going to stick to the basics; we won't be using any of these hooks ( accounts for another article.. goes into my diary..)


3. Now let's create a service in the plugin. Use the following commands
           cd customplugin
     grails create-service conversion
4.  Add the following code to the conversionService. This service has two functions for converting value in celcius into fahrenheit, an
         class ConversionService {
    static transactional = false

    def convertCelciusToFahrenheit = { tempInCelcius ->
        def tempInFah = ((9.0/5.0) * tempInCelcius )+ 32
        return tempInFah
    }

    def convertFahrenheitToCelcius = { tempInFah ->
        def tempInCelcius = (tempInFah - 32) * (5.0/9.0)
        return tempInCelcius
    }
}

5. Let's also add a tag library to the plugin. This library can be used to display navigation bread crumbs at the top of all the pages in the application.
            grails create-tag-lib BreadCrumb
 Add the following code to the file BreadCrumbTagLib:
        class BreadCrumbTagLib {
   
    static namespace="brcr"
   
    def breadCrumb = {
        out << "<a href='${request.getContextPath()}'>Home</a>"
       
        if(controllerName)
            {
                out << " -> <a href='${request.getContextPath()}
/${controllerName}'>    \\
                ${controllerName}</a>"
               
                if(actionName)
                    out << " -> ${actionName} "
            }
    }
}
 Notice the namespace in the above code. If you do not provide any namespace, you should be able to use 'breadCrumb' using <g:breadCrumb>. But if you want to change that to something specific, you can provide a namespace. For this example, we would need to use:
  <brcr: breadCrumb />

6. We've added enough code to our plugin, let's package it now, use this command at the root folder of the plugin code:
       grails package-plugin
 You will see a file named grails-customplugin.zip at the root folder
7. To test if we're able to use the plugin correctly, let's now create a small grails application :
       grails create-app myapp

8. To install the plugin created in step 6:
       cd myapp
 grails install-plugin <path_to_the_plugin>\grails-customplugin.zip
9.  We will now create a simple controller to test the conversionService from the controller. We can simply consume the service by declaring a conversionService variable in the controller just as we do in a usual grails application. To create the controller:
        grails crete-controller convert
  add the following code to the controller:

         class ConvertController {
   
    def conversionService
   
    def index = {
        redirect(action:'convert')
    }
   
    def convert = {
        def result
       
        if(params.degrees)
            {
            result = convertionService.convertCelciusToFahrenhiet(params.degrees.toInteger())
            params.result= result
            }
       
        [result: result, degrees: params.degrees]
    }
}
10. Create the convert.gsp file in myapp/grails-app/views/convert folder which will take an input from the user in celcius, pass it on to the controller, which will call the service from the plugin and convert the value into fahrenheit and will send back the result to the view.

      convert.gsp
         <g:form action="convert" method="post" controller="convert"><br/>
Celcius : <input type="text"  class="text" size="60" id="degrees" name="degrees" value="${degrees}"/>
 <br/>
<div>
     <span class="button"><g:submitButton name="convert" class="save" value="Convert" /></span>

</div>
<div>
<g:if test="${result}"><br/>
 ${degrees} celcius is equal to ${result} fahrenheit
</g:if>
</div>
</g:form>   
To use the taglib, add <brcr:breadCrumb> to the layout file 'main.gsp' just before <g:layoutBody>.


11. Run the application using grails run-app and browse to http://localhost:8080/myapp/convert


 

There you go! you're first grails plugin in action

This is a very simple example for getting started with a basic skeleton for a plugin.
Hope you find this article helpful

Download plugin source code (customplugin.rar)
Download application source code (myapp.rar)



9 comments:

  1. Thanks for the post. Very nice and clear. Much appreciated. Thanks for sharing.

    ReplyDelete
  2. Good tutorial, that should help me a lot.
    One short thing:
    In step 9 you have "grails crete-controller convert". I think there is missing an 'a'. ;)

    ReplyDelete
  3. Thanks for the Plugin tutorial :-) Its great

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Thanks for the tutorial. since i am using grails 2.3.7, so grails install-plugin... doest work.
      Could you please tell me how to install the plugin through buildconfig.groovy?

      Delete
  5. I am attempting to do this example for grails 2.4.2 and I keep getting a spring error when it tries to map conversionService to the ConversionService. Any insight?

    framework.core.convert.ConversionService] for property 'conversionService': no matching editors or conversion strategy found

    ReplyDelete
    Replies
    1. 'conversionService' is matching with some spring services, change the name of the service

      Delete
  6. Thanks for the Plugin tutorial :-) Its great

    ReplyDelete
  7. Best Tutorial...I have ever seen for plugin......Thanks a Lot

    ReplyDelete