Grooscript
Grails

Introduction

The plugin converts your Groovy code to javascript, allowing to use your Groovy code in your gsp files.

If you want to convert groovy files to javascript, use groovy templates on the client side, generate require.js modules from your groovy code. Don’t forget to use gradle plugin. You can use both plugins in your grails 3 project, and you must use both if you use grooscript:component tag.

So, your groovy code will run in your browser!

Important

If you have any ideas on how to

  • improve this plugin,

  • statically compile your templates,

  • or improve component options,

  • or anything else…​

don’t hesitate to open an issue or improvement on Github or email me at grooscript@gmail.com.

I have created this documentation with asciidoctor!

Requisites

This plugin works with Grails 3. It also need assets pipeline and the cache plugin.

  • Use <asset:deferredScripts/> in your gsp files with grooscript tags.

  • You don’t have to import grosscript-grails.js when you use grooscript tags, plugin does for you.

  • The plugin don’t need jquery, but you can work with it.

To use the plugin just add it to your grails 3 dependencies in your build.gradle:

dependencies {
    ...
    compile "org.grails.plugins:grooscript:1.3.0"
    ...
}

What is new in 1.3.0

  • Use grails events between server and client using websockets.

  • No need to add grooscript libs in your gsp’s.

  • Removed jquery as dependency.

  • Removes grooscript:remoteDomain feature.

  • Improve file generation of components for the jar / war, no need execute a task, gradle plugin does it automatically.

  • Add more tests.

What is new in 1.2.x

  • New tag for reload pages in development

What is new in 1.2

  • Use groovy classes as web components in your gsp’s

What is new in 1.1.x

  • Generation of remote domain classes code for production

  • Set the websockets endpoint name

  • Upgrade grooscript version

  • Fixes

Changes version 1.0.0

  • Stable release 1.0.0 to work with grails 3.

  • Use grooscript version 1.1.1

Grooscript

This little framework is the engine of the plugin. It converts Groovy code to javascript. You don’t need to know Grooscript, the plugin does the work for you. But you can take a look to http://grooscript.org/doc.html to get more info. Grooscript compiles the code, inspects the AST tree, and generates the javascript code.

Spring bean

There is grooscriptConverter bean to convert Groovy code to javascript. You can inject it in your grails artifacts:

class MyController {

    def grooscriptConverter

    def index() {
        def jsCode = grooscriptConverter.toJavascript('any groovy code')
        def jsCode = grooscriptConverter.toJavascript('any groovy code', conversionOptions)
    }
}

All conversion done with bean or tags use classpath ''src/main/groovy'' by default.

Grails helpers

Grooscript and this plugin offer some helpers to work with html, javascript or grails from your groovy code.

You can use the GrooscriptGrails class from your groovy code, in grooscript tags or groovy code. The code will run only in your browser (client side), no server calls will be made.

package org.grooscript.grails.util

class GrooscriptGrails {
    static findComponentById(String id) (1)
    static void doRemoteCall(String controller, String action, Map params, Closure onSuccess, Closure onFailure) (2)
    static void sendWebsocketMessage(String channel, message) (3)
    static void notifyEvent(String eventName, data) (4)
}
1 Finf a component by id
2 Do a remote ajax call
3 Send a message to server via websockets
4 Send a grails event

Example (calls addBook on controller books):

<grooscript:code>
	GrooscriptGrails.doRemoteCall('books', 'addBook', [title: 'A title'],
                                      { println 'All was Ok' },
                                      { println 'Error adding book' })
</grooscript:code>

Tags

This plugin offers a few tags, when you use that tags, some javascript dependencies will be added, all manages by asset pipeline plugin.

<grooscript:code>

You can put your Groovy code in gsp’s using this tag. The groovy code is converted to javascript code and inserted in your page with a asset.script tag. In Groovy code inside, maybe Grails can try use it, for example if you put '${something}'. If your code use other sources of your application, then that dependency will be converted too. A little cleanup is done in generated code, if your code references something that don’t find in the context, then be sure will be available in execution time in the client side.

Generated code is prepared to run with other generated code, not for be called from javascript. For example if you create a function that expects a groovy map, then you can have problems if a javascript object is passed. There is no problem with strings or numbers, but if you get a javascript array or object, then no groovy map and list functions. Also if you convert an object, and you want to create in your javascript code, var item = new Item(); doesn’t work, you have to do var item = Item();. All goes smooth if you do all in Groovy, for example converting a script like:

<grooscript:code>
    def sing = { name ->
        console.log 'Singing...' + name
    }

    def doSomething = { mapOfClosures ->
        mapOfClosures.each { key, value ->
            value(key)
        }
    }

    $(document).ready doSomething([groovy: sing, grails: sing, grooscript: sing])
</grooscript:code>

<grooscript:template>

You can create html templates using this tag. A template is a piece of groovy code that will be executed inside a html builder. So you generate javascript code that will run as a DSL(HtmlBuilder). In groovy exists some html builders, this is a simple one, that is available inside grooscript js libs. For example:

<grooscript:template>
    ul {
        5.times { number ->
            li "${number} li item"
        }
    }
</grooscript:template>

This tag transform the code in a javascript function that returns html code. The options of this tag are:

onLoad

by default is true, so the function runs on document ready, and then you html code appears.

functionName

by default a random name is used. But you can define name of the function and use it.

itemSelector

jquery selector of the dom object where html code will be injected.

You can combine grooscript tags to create dynamic applications in the client side using groovy. The variable data is available inside the template tag, that is the param used in the template function call.

<div id="list"></div>

<grooscript:template onLoad="false" functionName="refreshList" itemSelector="#list">
    ul {
        data.each { book ->
            li {
                p 'Id: ' + book.id + ' Name: ' + book.title
            }
        }
    }
</grooscript:template>

<grooscript:code>
    $(document).ready {
        refreshList([[id: 1, title:'Groovy in Action'], [id: 2, title:'Grails in Action']])
    }
</grooscript:code>

<grooscript:initSpringWebsocket>

Websocket support explained below. With this tag you start websocket connections on the client.

<grooscript:initSpringWebsocket/>

<!-- or -->

<grooscript:initSpringWebsocket>
    println 'Connected! Websocket is up!'
</grooscript:initSpringWebsocket>

You can put groovy code inside the tag, and that code will run in your browser after websocket connection done. You can define the websocket entrypoint (default is /stomp) or activate debug:

<grooscript:initSpringWebsocket withDebug="true" endPoint="/hello"/>

<grooscript:onWebsocket>

You can react to websocket events from the server:

<grooscript:onWebsocket path="/topic/hello">
    $("#helloDiv").append '<p>'+data+'</p>'
</grooscript:onWebsocket>

<grooscript:onWebsocket path="/topic/books" type="Book">
    data.each { book ->
        $("#helloDiv").append '<p>'+book.coolFormat()+'</p>'
    }
</grooscript:onWebsocket>

type is optional parameter with the type name of the data that come from the server.

<grooscript:reloadOn>

You can activate page reload if a websocket message come from the server:

<grooscript:reloadOn path="/topic/reload"/>

If any message comes for that path, then the page reloads.

If you use reloadOn or onWebsocket, no need to start websocket connection with initSpringWebsocket tag

<grooscript:onGrailsEvent>

You can react to events launched in the server and the client. To use this feature, you need spring websockets working. Uses the grails 3 support of events, for example in a controller you can send events:

import grails.events.Events

class MyController implements Events {

    def doEvents() {
        notify "hello", "hello world!"
        render "Ok"
    }
}

And then react in to them in your gsp’s:

<grooscript:onGrailsEvent name="hello">
    console.log data
</grooscript:onEvent>

Can create events in your clients with GrooscriptGrails helper class:

<grooscript:code>
    GrooscriptGrails.notifyEvent('somethingHappened', 'First!')
</grooscript:code>

You can take a look at some example here

<grooscript:component>

Component

You can use your groovy classes as web components and use them in your gsp’s.

This is an incubating feature

Requisites

  • You have to define your class from src/main/groovy, not in grails-app.

  • grooscript is used to convert the class, so take care with library limitations http://grooscript.org.

  • You have to add webcomponents lib if browser don’t support it. That library is available in http://webcomponents.org/ or in the plugin (add with: <asset:javascript src="webcomponents.min.js"/>).

Create component class

package components

class Counter {
    static style = ''' (1)
        div {
            width: 100px;
        }
    '''
    static renderAfter = ['inc', 'dec'] (2)
    int value = 0
    void inc() {
        value++
    }
    void dec() {
        value--
    }
    def render() { (3)
        div {
            h1 value.toString()
            p {
                button(onclick: 'dec', '-') (4)
                button(onclick: 'inc', '+')
            }
        }
    }
}
1 You can define style to apply to the component. It’s shadow dom, so not affected by page css.
2 You can define methods that will execute render when executed with renderAfter.
3 Define the html of your component with a groovy dsl (Groovy template engine).
4 You can define component methods to execute in onXXX events with the name of the method as a string.

Use your component in your gsp’s

To use this component in your gsp’s you have to use component tag.

<grooscript:component src="components.Counter" name="my-counter"/>
  • scr is mandatory, full class name of the component.

  • name is optional to set the name of the tag to use the component. Some tag names are not allowed, as counter. If you don’t set the name of the tag will use the name of the class without upper case and with -'s (MyComp → my-comp)

All together

Then you can use your groovy component in your html, as a web component:

<html>
<head>
    <asset:javascript src="grooscript-grails.js"/>
    <asset:javascript src="webcomponents.min.js"/>
    <grooscript:component src="components.Counter" name="my-counter"/>
</head>

<body>
    <p>Hello World!</p>
    <my-counter></my-counter>
    <my-counter value="3"></my-counter> (1)
<asset:deferredScripts/>
1 You can set properties of your component. Also you can use content of the tag with a property content available in the groovy class at runtime.

Generate components for production

In development, class source is used to convert to javascript. In production source is not available, so just add grooscript gradle plugin > 1.3.0 that will do that work for you.

Helpers

You can access a component by id:

<my-counter id="first"></my-counter>
<script>
	GrooscriptGrails.findComponentById("first")
</script>

Demos or examples

Pending, please if you need a guide or better explanation in something, contact me.

Feedback

If you have ideas on how to improve the plugin or if you find any bugs, please open issues at Github or email me at grooscript@gmail.com.

Thank you!