Tuesday, April 23, 2013

Using FreeMarker Templates in a Grails App

I've started in a new team at my job.  We're creating an admin system that is going to take the functionality of several disparate systems and put them all under one UI.  Since we're writing a whole new app from scratch that will interface with existing systems, we had our choice of technologies (within reason) and frameworks.  We ended up choosing Grails because we figured it would be easy to integrate with our other systems and provide us with easy to create RESTful services.

One of our requirements was to use FreeMarker to generate the HTML of our UI.  This is a  requirement because we're using FreeMarker in other areas and we've created a development tool that uses FreeMarker in addition to other front end technologies (JS, SASS).

The problem is that Grails wants to use GSPs (Grails Server Pages), which are like JSPs (and, in fact, compile down to JSPs).  Grails has the ability to incorporate third-party plugins into your project, and there's a FreeMarker plugin for Grails.  Unfortunately, the plugin was made for Grails 1.2 and we're trying to use Grails 2.2.1.  I tried for two days to try to get the FreeMarker plugin to work, but it just didn't seem to do anything.  It was a frustrating situation.

Having read a lot of Grails documentation over the last few days, I found that you could configure Grails similarly to how you configure a Spring application.  You put that configuration in the resources.groovy file.

import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver

// Place your Spring DSL code here
beans = {
 freemarkerConfig(FreeMarkerConfigurer) {
  templateLoaderPath = "/"
 }
 viewResolver(FreeMarkerViewResolver) {
  cache = "false"
  prefix = "bin/freemarker"
  suffix = ".ftl"
  exposeSpringMacroHelpers = "true"
 }
}


Spring configuration is, of course, XML and this is a Grails closure.  That part wasn't hard to convert.  You can find an example of how to configure FreeMarker in a Spring app looks like, here.  The only other thing we had to do was to put the line below into our BuildConfig.groovy file.

dependencies {
 ...
 runtime "org.freemarker:freemarker:latest.release"
 ...
}

Now, the only thing we had to figure out was where to put the FreeMarker templates.  At first, we had them in our views folder where the GSPs went, but we were getting 404s when we ran the app.  After some debugging (thanks Roy for helping debug!) we figured out that the template loader was looking for the templates in the web-app folder.  That was easy enough to fix, we copied our templates from the views folder over to the web-app folder.  After that, everything worked just fine!

So, to recap, we added a typical Spring configuration to the resources.groovy file, added the FreeMarker jar as a runtime dependency in the BuildConfig.groovy file and put our templates into the web-app folder (in the folder configured in the prefix of the viewResolver).

The solution was frustratingly simple after we figured it out.  I wrote this post because I researched and experimented on whether this was possible or not for over two days without any success.  Hopefully this helps anyone else who is trying to use FreeMarker in their Grails app.

If you're like me, though, you want to see more.  Here's an example of a generic Controller:

class ApplicationController {

    static defaultAction = "show"

    GrailsApplication grailsApplication

    def show() {
        [model: [version: getAppVersion()]]
    }

    private getAppVersion() {
        def metadata = grailsApplication.metadata
        return metadata['app.version']
    }
}

It has one public method, show.  We want that when you navigate to /app-name/application or /app-name/application/show that it displays the version of the app.  I created a template, /web-app/application/show.ftl.  Now, the template contents are:

hello world<br>
${model.version}


When I navigate to /app-name/application/show, I get:




Which is as expected.  Pretty slick.  We're still at the beginning, but this should allow us to borrow front -end devs from other teams since they'll already understand the view technology and we'll be using the same tools that their teams use.

Friday, April 12, 2013

Story: The Necromancer's Apprentice


This story is another Chuck Wendig Flash Fiction challenge.  It's a fun one, I hope you enjoy it!

-----------------------------------------------------------------

Max sat amongst the dead, whistling to himself.  He counted them one more time to make sure he had collected the twelve bodies his master had asked for.  He nodded with satisfaction when he saw that he'd gotten enough.

Max reflected how happy he was with his current role as a Necromancer's apprentice.  He'd tried other occupations, of course, but none of them gave him the job satisfaction that this one did.

He laughed as he thought about his tenure as an apprentice in the Thieves' Guild.  When the authorities brought down the whole guild, the rest of the thieves had pegged him as a mole, but he had just accidentally led the authorities back to the hideout after stealing the mayor's "Key to the City".  Who knew that the key didn't actually unlock any doors?

Then there was the time that he tried to join the Druidic Order.  The look on those Druid's faces was priceless when he walked into a society meeting wearing the chain mail he'd found on a dead bugbear.  He still found their dislike of metal armor silly.

Max walked over to the cabinet that held the spell components that his master would use to raise the corpses.  He pulled out a little of this and a bottle of that and placed them on the ceremonial table in the middle of the room.  Next, he grabbed the large cauldron and placed it on the table.

Laying out the spell components reminded him of his tenure as a cleric's apprentice in the Church of Slinne, the Goddess of Life.  He was still making payments to pay for the repairs caused by the fire he accidentally started with the ceremonial torches.

Now, though, he'd definitely found his niche.  He'd been with his master for almost a year now.  It was Max's longest term of employment by at least three months.

His reverie was interrupted by the sound of something gnawing on bone.  Max looked over at the bodies and saw one of his master's pet rats chewing on the femur of one of the more decomposed bodies.  He ran over and shooed the creature away, shaking his head.  He didn't know why his master kept those creatures around.

They did remind him of the time he apprenticed for a Ranger in the Hundart Forest.  The Ranger's companion, a very large wolverine named Scrappy, had never liked him.  His apprenticeship ended abruptly when he accidentally lit the creature's tail on fire.  It was also how he got the scars on his thigh.  Wolverine claws could do a lot of damage.  Good thing his former master had had a healing spell prepared at the time.

He heard his current master coming down the stone stairway and quickly finished organizing the table the way he knew his master liked.

"Good evening, Max," his master, Alacast, said as he approached the table.  "Is everything ready?"

"Oh, yes sir," Max excitedly answered.  "We've got twelve corpses of varying levels of decay all ready to be risen."

Alacast spent a moment looking over the dead.  "No trouble in the cemetery?"

That question reminded Max of how he'd met Alacast.  The Necromancer had sent his previous apprentice to the graveyard where Max had been working as a gravedigger's apprentice.  He'd interrupted the apprentice as he was robbing a grave.  Max had offered to help him dig up the body, but the apprentice had refused.  As Max leaned against the gravestone to watch the apprentice work, the stone shifted and fell into the grave, crushing the apprentice.  Alacast's magic had alerted him to his apprentice's demise and he'd hurried to the cemetery.  When he arrived a few minutes later and saw what had happened, he offered Max the apprenticeship.  Gravedigger work hadn't been for him, so he accepted.

Back in the present, Max answered, "No, sir.  The gravedigger was passed out drunk again."

His master nodded and returned to the table and began the chant that would raise the corpses into undead.  Max stood behind his master watching intently as he chanted.  Max knew that this spell would take some time, so he leaned back against the wall.

What Max hadn't realized was that it wasn't the wall right behind him, but rather a lit brazier.  The brazier fell over, knocking down the one next to it and so on until the dozen braziers around the room had all fallen over.  Max cursed himself when he saw that several of the corpses had caught fire.

Alacast stopped chanting and glanced over his shoulder at Max.  Sheepishly, Max said, "Sorry, master."

The Necromancer turned and knocked over the cauldron on the table in front of him, spilling the contents onto the remainder of the bodies that hadn't been burning but were now being eaten away by the acidic contents of the cauldron.

The two of them glanced at each other and broke out laughing.  Alacast, between chortles, said, "This is why we work well together, Max.  Birds of a feather are we.  At least they were already dead."

Max smiled and nodded.  He said, "I'll get the mess cleaned up, master, and fetch you a dozen new bodies."

Monday, April 1, 2013

Table Top Day


Along with millions of other gaming enthusiasts, I celebrated International Table Top Day recently.  I love playing games of all types and I've been playing board games since I was little.  When TableTop began on Geek & Sundry, I loved it.  I already liked Wil Wheaton a lot, but having him play some of my favorite games with other geeky celebrities was awesome.

I'll be the first to admit that I don't play board games as much as I'd like, but I think that's part of the point to International Table Top Day.  The point is to take time out of our busy lives to celebrate games and to get together with our friends to play our favorite games or to try new games with new people.

My wife and I decided to stop by The Source Comics and Games for Table Top Day because I'd heard that John Kovalic was planning on being there.  We went there and played a new game that we ended up liking enough to buy.  It's called "Hirelings: The Ascent".  It's kind of the reverse idea of the typical "dungeon delving" game.  You play as one of the hirelings of the heroes that delved into the dungeon and you're trying to escape after the party has all died.  You have the heroes' equipment and you use it to evade the monsters and get out of the dungeon before the dragon's fireball catches up to you.  It was pretty fun and we got to play with the game's creator.  I think we'll try it out with our five year old pretty soon.

The highlight, of course, of Table Top Day to me was meeting John Kovalic.  I've been following him on Twitter pretty much since I joined it and on Facebook for quite some time.  I love his art, Munchkin and Dork Tower.  Meeting him was awesome and he was so nice.  We chatted a bit about the game he was playing, about Apples to Apples and Munchkin.  He told my wife and I about a Disney version of Apples to Apples that we're going to try to find to play with our kids.  Plus, I got to get my picture taken with him AND he signed our copy of Munchkin and Apples to Apples!


Table Top (the show) has increased my already great love of games.  It's made me aware of games that I didn't know about before or made me interested in games that I wouldn't have thought I'd be interested in.  Table Top Day has done the same thing for me with a special interactive component.  I went to a great store that I don't go to often enough and bought a game that I tried there.  It was a great Table Top Day and I'm looking forward to the next one!













Inside Apples to Apples

The cover of my newly signed Munchkin box!