-
Notifications
You must be signed in to change notification settings - Fork 6
Adding plug in modules
OLF can be extended with new functionality in a modular fashion. This could be anything, from a data analyis module for next-gen sequencing data to a cookbook for your favourite lab cake. OLF modules are more or less identical to grails plug-ins. The only difference is that developers implementing an OLF module are aware of the concepts for extending OLF's menu, adding tabs or adding operations to existing data objects, as well as for creating new add-ins.
This being said, we want to go step by step through the creation of a new very simplistic OLF module for lab stock management.
##Creating a grails plug-in The creation of a grails plug-in is very well described in the [grails user documentation] (http://grails.org/doc/latest/guide/plugins.html#creatingAndInstallingPlugins). We will assume that you have configured grails correctly.
grails create-plugin modules/OpenLabStocksA new folder OpenLabStocks will appear that contains all you need to get started except of a few things.
You need to manually create a folder for the content modules OLF will need later under modules/your-plug-in/grails-app/

OpenLabFramework will automatically load all plug-ins found in the modules folder. Therefore you can control which plug-ins to add to your installation by removing folders you don't want to use. You should, however, keep at least OpenLabBackend, since it provides the essential base functionality.
##Adding new functionality Our new module needs to get a data entity of its own to keep track of the different chemicals etc. we want to manage. We therefore switch back to the OpenLabStock folder where we introduce a new domain class called StockItem:
grails create-domain-class org.openlab.stock.StockItemStockItem is a typical domain object and needs a little work:
package org.openlab.stock
import org.openlab.main.DataObject
class StockItem extends DataObject{
String name
String alternativeName
String description
boolean orderSoon
String toString(){
name
}
static mapping = {
table 'olfStockItem'
}
static constraints = {
}
}It should be noted that mapping a table name explicitly is necessary in OLF in contrast to ordinary grails applications. The reason for this lies in the hierarchical class structure of OLF, which is based on inheritance. Now we should also a controller class. Instead of adding controller with generate-controller (the way it's normally done), we just create one from hand. Add a new class StockItemController.groovy to grails-app/controllers:
package org.openlab.stock
class StockItemController {
def scaffold = true
}That's all? Yes, that's all. You are welcome to use generate-controller anyway to have the typical CRUD methods in here, but this comes at some disadavantages: You'll add redundancy, you'll loose clarity, and you'll have to propagate any changes in the scaffolding code to all classes that have their customized CRUD methods. What you should do however, is adding further methods to the controller, for instance:
package org.openlab.stock
class StockItemController {
def scaffold = true
def listStockItemsToOrder(){
def stockItemsToOrder = StockItem.findAllByOrderSoon(true)
render view: "list", model: [stockItemInstanceList: stockItemsToOrder, stockItemInstanceTotal: stockItemsToOrder.size()]
}
}
We just added an additional action to the method that lists only stock items that need to be ordered. We don't even have to create a new view since we can just re-use the existing list view with a custom model.
##Add OpenLabStock to the menu OpenLabStock is already fully functional. However, no-one can use it unless it can be reached via the menu. We therefore add a MenuModule. Place this file under grails-app/modules
package org.openlab.module.menu
import groovy.xml.MarkupBuilder
import org.openlab.module.MenuModule
class StockMenuModule implements MenuModule{
def getPriority()
{
6
}
def getMenu()
{
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
def controller = "stockItem"
xml.root
{
submenu(label: 'Lab Stocks')
{
menuitem(controller: controller, action: 'create', label: 'Create new Lab Stock')
menuitem(controller: controller, action: 'list', label: 'List Lab Stocks')
menuitem(controller: controller, action: 'listStockItemsToOrder', label: 'List Lab Stocks that need ordering')
}
}
return writer.toString()
}
}##First Results Let's look at the result of our hard work and start the web application. Switch to the OpenLabFrontend folder and execute
grails run-app

The beauty of grails and OLF is that scaffolding code handles both the database interaction and CRUD interactions without any additional work. Of course you'll have to invest a little more in order to get more complicated things done. However, all is possible since the hidden complexity of the underlying frameworks is at your finger tips.