(Quick Reference)

5.9.1 A Fancy Example - Reference Documentation

Authors: Andres Almiray

Version: 1.2.0

5.9.1 A Fancy Example

This section demonstrates how an archetype can be created and put to good use for building applications.

#1 Create the archetype

The first step is to create the archetype project and its descriptor, which can be done by executing the following command

griffon create-archetype fancy
cd fancy

#2 Tweak the archetype descriptor

Locate the archetype descriptor (application.groovy) and open it in your favorite editor, paste the following snippet

import griffon.util.Metadata

includeTargets << griffonScript('CreateMvc')

target(name: 'createApplicationProject', description: 'Creates a new application project', prehook: null, posthook: null) { createProjectWithDefaults()

argsMap.model = 'MainModel' argsMap.view = 'MainView' argsMap.controller = 'MainController' createMVC()

createArtifact( name: mvcFullQualifiedClassName, suffix: 'Actions', type: 'MainActions', path: 'griffon-app/views')

createArtifact( name: mvcFullQualifiedClassName, suffix: 'MenuBar', type: 'MainMenuBar', path: 'griffon-app/views')

createArtifact( name: mvcFullQualifiedClassName, suffix: 'StatusBar', type: 'MainStatusBar', path: 'griffon-app/views')

createArtifact( name: mvcFullQualifiedClassName, suffix: 'Content', type: 'MainContent', path: 'griffon-app/views')

Metadata md = Metadata.getInstance(new File("${basedir}/application.properties")) installPluginExternal md, 'miglayout' }

setDefaultTarget(createApplicationProject)

This archetype overrides the default templates for Model, View and Controller that will be used for the initial MVC group. It also creates 4 additional files inside griffon-app/views. Finally it installs the latest version of the MigLayout plugin.

#3 Create the artifact templates

According to the conventions laid out in the archetype descriptor there must exist a file under templates/artifacts that matches each one of the specified artifact types, in other words we need the following files

MainModel.groovy

@artifact.package@import groovy.beans.Bindable
import griffon.util.GriffonNameUtils

class @artifact.name@ { @Bindable String status

void mvcGroupInit(Map args) { status = "Welcome to ${GriffonNameUtils.capitalize(app.config.application.title)}" } }

MainController.groovy

@artifact.package@class @artifact.name@ {
    def model
    def view

// void mvcGroupInit(Map args) { // // this method is called after model and view are injected // }

// void mvcGroupDestroy() { // // this method is called when the group is destroyed // }

def newAction = { evt = null -> model.status = 'New action' }

def openAction = { evt = null -> model.status = 'Open action' }

def saveAction = { evt = null -> model.status = 'Save action' }

def saveAsAction = { evt = null -> model.status = 'Save As action' }

def aboutAction = { evt = null -> model.status = 'About action' }

def quitAction = { evt = null -> model.status = 'Quit action' }

def cutAction = { evt = null -> model.status = 'Cut action' }

def copyAction = { evt = null -> model.status = 'Copy action' }

def pasteAction = { evt = null -> model.status = 'Paste action' } }

MainView.groovy

@artifact.package@build(@artifact.name.plain@Actions)
application(title: GriffonNameUtils.capitalize(app.config.application.title),
    pack: true,
    locationByPlatform:true,
    iconImage: imageIcon('/griffon-icon-48x48.png').image,
    iconImages: [imageIcon('/griffon-icon-48x48.png').image,
               imageIcon('/griffon-icon-32x32.png').image,
               imageIcon('/griffon-icon-16x16.png').image]) {
   menuBar(build(@artifact.name.plain@MenuBar))
   migLayout(layoutConstraints: 'fill')
   widget(build(@artifact.name.plain@Content), constraints: 'center, grow')
   widget(build(@artifact.name.plain@StatusBar), constraints: 'south, grow')
}

MainActions.groovy

@artifact.package@import groovy.ui.Console

actions { action( id: 'newAction', name: 'New', closure: controller.newAction, mnemonic: 'N', accelerator: shortcut('N'), smallIcon: imageIcon(resource:"icons/page.png", class: Console), shortDescription: 'New' ) action( id: 'openAction', name: 'Open...', closure: controller.openAction, mnemonic: 'O', accelerator: shortcut('O'), smallIcon: imageIcon(resource:"icons/folder_page.png", class: Console), shortDescription: 'Open' ) action( id: 'quitAction', name: 'Quit', closure: controller.quitAction, mnemonic: 'Q', accelerator: shortcut('Q'), ) action( id: 'aboutAction', name: 'About', closure: controller.aboutAction, mnemonic: 'B', accelerator: shortcut('B') )

action( id: 'saveAction', name: 'Save', closure: controller.saveAction, mnemonic: 'S', accelerator: shortcut('S'), smallIcon: imageIcon(resource:"icons/disk.png", class: Console), shortDescription: 'Save' ) action( id: 'saveAsAction', name: 'Save as...', closure: controller.saveAsAction, accelerator: shortcut('shift S') )

action(id: 'cutAction', name: 'Cut', closure: controller.cutAction, mnemonic: 'T', accelerator: shortcut('X'), smallIcon: imageIcon(resource:"icons/cut.png", class: Console), shortDescription: 'Cut' ) action(id: 'copyAction', name: 'Copy', closure: controller.copyAction, mnemonic: 'C', accelerator: shortcut('C'), smallIcon: imageIcon(resource:"icons/page_copy.png", class: Console), shortDescription: 'Copy' ) action(id: 'pasteAction', name: 'Paste', closure: controller.pasteAction, mnemonic: 'P', accelerator: shortcut('V'), smallIcon: imageIcon(resource:"icons/page_paste.png", class: Console), shortDescription: 'Paste' ) }

MainMenuBar.groovy

@artifact.package@import static griffon.util.GriffonApplicationUtils.*

menuBar = menuBar { menu(text: 'File', mnemonic: 'F') { menuItem(newAction) menuItem(openAction) separator() menuItem(saveAction) menuItem(saveAsAction) if( !isMacOSX ) { separator() menuItem(quitAction) } }

menu(text: 'Edit', mnemonic: 'E') { menuItem(cutAction) menuItem(copyAction) menuItem(pasteAction) }

if(!isMacOSX) { glue() menu(text: 'Help', mnemonic: 'H') { menuItem(aboutAction) } } }

MainContent.groovy

@artifact.package@label('Main content')

MainStatusBar.groovy

@artifact.package@label(id: 'status', text: bind { model.status })

#4 Package and install the archetype

This step is easily done with a pair of command invocations

griffon package-archetype
griffon install-archetype target/package/griffon-fancy-0.1.zip

#5 Use the archetype

Now that the archetype has been installed all that is left is put it to good use, like this

griffon create-app sample --archetype=fancy

This command should generate the following files in the application directory

  • griffon-app
    • controllers
      • sample
        • SampleController
    • models
      • sample
        • sampleModel
    • views
      • sample
        • SampleActions
        • SampleContent
        • SampleMenuBar
        • SampleStatusBar
        • SampleView

If you inspect the application.properties file you'll notice that the miglayout plugin has been installed too.

Archetypes can be versioned, installed and released in the same way plugins are.