grooscript & grails 3
Jorge Franco Leza
Greach - Madrid - April 8th 2016
About me
Developer
Between Madrid & Sevilla
jorge.franco.leza@gmail.com
@jfrancoleza
About grooscript
Apache 2 library
In github, contribute!
Groovy code to javascript
Just a tool, not a framework
Use with Node.js or other java frameworks
Last version 1.2.3
Gradle plugin
http://grooscript.org/gradle/tasks.html
plugins {

id "org.grooscript.conversion" version "1.2.3"

}
Convert files
grooscript {

source = ['src/main/groovy/gs']

destination = 'grails-app/assets/javascripts/generated'

initialText = '//Grooscript converted file'

}
bootRun.dependsOn 'convertThread'

compileGroovy.dependsOn 'convert'
task convertMyScript(type: org.grooscript.gradle.ConvertTask) {

source = ['src/main/groovy/MyScript.groovy']

mainContextScope = ['$']

destination = 'src/main/webapp/js'

includeDependencies = true

}
Groovy markup templates
templates {

templatesPath = 'grails-app/views/gtpl'

templates = ['list-links.gml']

destinationFile = 'grails-app/assets/javascripts/' +

'generated/Templates.js'

}



bootRun.dependsOn 'templatesThread'

compileGroovy.dependsOn 'templatesJs'
* can’t use groovy markup templates with g:render
p model.title

ul(class: "list-links") {

model.list.each { item ->

li {

a(href: item.url) {

p item.text

}

}

}

}
import org.grooscript.templates.Templates



Templates.applyTemplate('list-links.gml',

[title: 'Controllers', list: [

[url: 'grails.org', text: 'Grails'],

[url: 'grooscript.org', text: 'grooscript']

]]

)
list-links.gml
Spy file changes
spy {

files = [

'grails-app/assets/stylesheets/app.css',

'grails-app/views/reload/index.gsp'

]



onChanges = { list ->

//Or simpler http request

springWebsocketTo('http://localhost:8080/stomp')

.data('reload').onChannel('/app/reload')

}

}



bootRun.dependsOn 'spyChanges'
Grails 3 plugin
compile "org.grails.plugins:grooscript:1.2.2"
Setup
<!doctype html>

<html>

<head>

<asset:stylesheet src="application.css"/>

<asset:javascript src="jquery-2.2.0.min.js"/>

<asset:javascript src="grooscript-grails.js"/>



<g:layoutHead/>

</head>

<body>



<g:layoutBody/>

<asset:deferredScripts/>



</body>

</html>
Groovy code
<asset:javascript src="generated/Hello"/>
<grooscript:code>

import gs.Hello



$('body').append '''<footer><p>

<a href="http://grooscript.org">Grooscript Home</a> &&

<a href="https://twitter.com/grooscript">Twitter</a>

</p></footer>'''

new Hello().world()

</grooscript:code>
<grooscript:code>

def sing = { name ->

console.log 'Singing...' + name

}



Closure doSomething = { mapOfClosures ->

mapOfClosures.each { key, value ->

value(key)

}

}



$(document).ready doSomething([groovy: sing, grails: sing, grooscript: sing])

</grooscript:code>
Templates
<grooscript:template>

ul {

5.times { number ->

li number + " li item"

}

}

</grooscript:template>
Websockets
class ReloadController {



def index() { }



@MessageMapping("/reload")

@SendTo("/topic/reload")

protected String colors() {

return 'reload!'

}

}
compile "org.grails.plugins:grails-spring-websocket:2.3.0"
<!doctype html>

<html>

<head>

<meta name="layout" content="main"/>

<title>Reloading</title>

<asset:javascript src="spring-websocket" />

</head>

<body>

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

<p class="reload-message">Change something in this gsp
or in application.css!</p>

</body>

</html>
<grooscript:initSpringWebsocket>

println 'Websocket is up!'

GrooscriptGrails.sendWebsocketMessage '/app/colors'

</grooscript:initSpringWebsocket>



<grooscript:onServerEvent path="/topic/colors">

allCubes(data)

</grooscript:onServerEvent>



<grooscript:template functionName="allCubes" onLoad="false" itemSelector="body">

table(id: "all-cubes") {

data.eachWithIndex { row, i ->

tr {

row.eachWithIndex { color, j ->

td(id: 'row-' + i + '-' + j,

class: 'cube ' + colors[color],

onmouseover: 'touch(' + i + ', ' + j + ')')

}

}

}

}

</grooscript:template>
Remote model
package rest
import grails.rest.Resource



@Resource(uri='/books', formats=['json'])

class Book {



String title

String author

}
* only json
<grooscript:code>

import rest.Book



def drawBooks = {

Book.list().then { list ->

$('#bookList').html ''

list.each {

appendBookToList(it)

}

}

}



def appendBookToList = { book ->

$('#bookList').append('<p>Title: '+book.title+' - Author: ‘
+ (book.author?: 'unknown') +'</p>')

}



def addBook = {

def title = $('#title').val()

def author = $('#author').val()

new Book(title: title, author: author).save().then {

appendBookToList(it)

}

}



$(document).ready {

drawBooks()

}


</grooscript:code>
Components
http://webcomponents.org
<asset:javascript src="webcomponents.min.js"/>
Custom elements - Shadow dom
<grooscript:component src="components.Counter" name="my-counter"/>
<p>Hello World!</p>

<my-counter></my-counter>

<my-counter value="3"></my-counter>
package components



class Counter {

static style = ''' 

div {

width: 100px;

}

'''

static renderAfter = ['inc', 'dec']

int value = 0

void inc() {

value++

}

void dec() {

value--

}

def render() {

div {

h1 value.toString()

p {

button(onclick: 'dec', '-')

button(onclick: 'inc', '+')

}

}

}

}
Links
Homepage: http://grooscript.org
Documentation: http://grooscript.org/doc
Github: http://github.com/chiquitinxx/grooscript
Demos: http://github.com/chiquitinxx/grooscript-demos
Gradle plugin: http://github.com/chiquitinxx/grooscript-gradle-plugin
Grails 3 plugin: http://grooscript.org/grails3-plugin/
All together: https://github.com/chiquitinxx/grails3-demo-grooscript
grooscript@gmail.com
@grooscript
Thank you!

Grooscript and Grails 3

  • 1.
    grooscript & grails3 Jorge Franco Leza Greach - Madrid - April 8th 2016
  • 2.
    About me Developer Between Madrid& Sevilla jorge.franco.leza@gmail.com @jfrancoleza
  • 3.
    About grooscript Apache 2library In github, contribute! Groovy code to javascript Just a tool, not a framework Use with Node.js or other java frameworks Last version 1.2.3
  • 4.
    Gradle plugin http://grooscript.org/gradle/tasks.html plugins {
 id"org.grooscript.conversion" version "1.2.3"
 }
  • 5.
    Convert files grooscript {
 source= ['src/main/groovy/gs']
 destination = 'grails-app/assets/javascripts/generated'
 initialText = '//Grooscript converted file'
 } bootRun.dependsOn 'convertThread'
 compileGroovy.dependsOn 'convert' task convertMyScript(type: org.grooscript.gradle.ConvertTask) {
 source = ['src/main/groovy/MyScript.groovy']
 mainContextScope = ['$']
 destination = 'src/main/webapp/js'
 includeDependencies = true
 }
  • 6.
    Groovy markup templates templates{
 templatesPath = 'grails-app/views/gtpl'
 templates = ['list-links.gml']
 destinationFile = 'grails-app/assets/javascripts/' +
 'generated/Templates.js'
 }
 
 bootRun.dependsOn 'templatesThread'
 compileGroovy.dependsOn 'templatesJs' * can’t use groovy markup templates with g:render
  • 7.
    p model.title
 ul(class: "list-links"){
 model.list.each { item ->
 li {
 a(href: item.url) {
 p item.text
 }
 }
 }
 } import org.grooscript.templates.Templates
 
 Templates.applyTemplate('list-links.gml',
 [title: 'Controllers', list: [
 [url: 'grails.org', text: 'Grails'],
 [url: 'grooscript.org', text: 'grooscript']
 ]]
 ) list-links.gml
  • 8.
    Spy file changes spy{
 files = [
 'grails-app/assets/stylesheets/app.css',
 'grails-app/views/reload/index.gsp'
 ]
 
 onChanges = { list ->
 //Or simpler http request
 springWebsocketTo('http://localhost:8080/stomp')
 .data('reload').onChannel('/app/reload')
 }
 }
 
 bootRun.dependsOn 'spyChanges'
  • 9.
    Grails 3 plugin compile"org.grails.plugins:grooscript:1.2.2"
  • 10.
    Setup <!doctype html>
 <html>
 <head>
 <asset:stylesheet src="application.css"/>
 <asset:javascriptsrc="jquery-2.2.0.min.js"/>
 <asset:javascript src="grooscript-grails.js"/>
 
 <g:layoutHead/>
 </head>
 <body>
 
 <g:layoutBody/>
 <asset:deferredScripts/>
 
 </body>
 </html>
  • 11.
    Groovy code <asset:javascript src="generated/Hello"/> <grooscript:code>
 importgs.Hello
 
 $('body').append '''<footer><p>
 <a href="http://grooscript.org">Grooscript Home</a> &&
 <a href="https://twitter.com/grooscript">Twitter</a>
 </p></footer>'''
 new Hello().world()
 </grooscript:code> <grooscript:code>
 def sing = { name ->
 console.log 'Singing...' + name
 }
 
 Closure doSomething = { mapOfClosures ->
 mapOfClosures.each { key, value ->
 value(key)
 }
 }
 
 $(document).ready doSomething([groovy: sing, grails: sing, grooscript: sing])
 </grooscript:code>
  • 12.
    Templates <grooscript:template>
 ul {
 5.times {number ->
 li number + " li item"
 }
 }
 </grooscript:template>
  • 13.
    Websockets class ReloadController {
 
 defindex() { }
 
 @MessageMapping("/reload")
 @SendTo("/topic/reload")
 protected String colors() {
 return 'reload!'
 }
 } compile "org.grails.plugins:grails-spring-websocket:2.3.0"
  • 14.
    <!doctype html>
 <html>
 <head>
 <meta name="layout"content="main"/>
 <title>Reloading</title>
 <asset:javascript src="spring-websocket" />
 </head>
 <body>
 <grooscript:reloadOn path="/topic/reload"/>
 <p class="reload-message">Change something in this gsp or in application.css!</p>
 </body>
 </html>
  • 15.
    <grooscript:initSpringWebsocket>
 println 'Websocket isup!'
 GrooscriptGrails.sendWebsocketMessage '/app/colors'
 </grooscript:initSpringWebsocket>
 
 <grooscript:onServerEvent path="/topic/colors">
 allCubes(data)
 </grooscript:onServerEvent>
 
 <grooscript:template functionName="allCubes" onLoad="false" itemSelector="body">
 table(id: "all-cubes") {
 data.eachWithIndex { row, i ->
 tr {
 row.eachWithIndex { color, j ->
 td(id: 'row-' + i + '-' + j,
 class: 'cube ' + colors[color],
 onmouseover: 'touch(' + i + ', ' + j + ')')
 }
 }
 }
 }
 </grooscript:template>
  • 16.
    Remote model package rest importgrails.rest.Resource
 
 @Resource(uri='/books', formats=['json'])
 class Book {
 
 String title
 String author
 } * only json
  • 17.
    <grooscript:code>
 import rest.Book
 
 def drawBooks= {
 Book.list().then { list ->
 $('#bookList').html ''
 list.each {
 appendBookToList(it)
 }
 }
 }
 
 def appendBookToList = { book ->
 $('#bookList').append('<p>Title: '+book.title+' - Author: ‘ + (book.author?: 'unknown') +'</p>')
 }
 
 def addBook = {
 def title = $('#title').val()
 def author = $('#author').val()
 new Book(title: title, author: author).save().then {
 appendBookToList(it)
 }
 }
 
 $(document).ready {
 drawBooks()
 } 
 </grooscript:code>
  • 18.
    Components http://webcomponents.org <asset:javascript src="webcomponents.min.js"/> Custom elements- Shadow dom <grooscript:component src="components.Counter" name="my-counter"/> <p>Hello World!</p>
 <my-counter></my-counter>
 <my-counter value="3"></my-counter>
  • 19.
    package components
 
 class Counter{
 static style = ''' 
 div {
 width: 100px;
 }
 '''
 static renderAfter = ['inc', 'dec']
 int value = 0
 void inc() {
 value++
 }
 void dec() {
 value--
 }
 def render() {
 div {
 h1 value.toString()
 p {
 button(onclick: 'dec', '-')
 button(onclick: 'inc', '+')
 }
 }
 }
 }
  • 20.
    Links Homepage: http://grooscript.org Documentation: http://grooscript.org/doc Github:http://github.com/chiquitinxx/grooscript Demos: http://github.com/chiquitinxx/grooscript-demos Gradle plugin: http://github.com/chiquitinxx/grooscript-gradle-plugin Grails 3 plugin: http://grooscript.org/grails3-plugin/ All together: https://github.com/chiquitinxx/grails3-demo-grooscript grooscript@gmail.com @grooscript
  • 21.