<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jakob Külzer &#187; Scaffolding</title>
	<atom:link href="http://www.jakusys.de/blog/tag/scaffolding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jakusys.de/blog</link>
	<description>Ninja Coding Monkey goes Canada</description>
	<lastBuildDate>Sun, 02 Jan 2011 20:12:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Grails Scaffolding In-Depth</title>
		<link>http://www.jakusys.de/blog/2008/12/grails-scaffolding-in-depth/</link>
		<comments>http://www.jakusys.de/blog/2008/12/grails-scaffolding-in-depth/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 15:12:51 +0000</pubDate>
		<dc:creator>Jakob Külzer</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[Scaffolding]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.jakusys.de/blog/?p=487</guid>
		<description><![CDATA[Much of Grails power and ability to crank out applications can be accounted to its scaffolding mechanism for creating CRUD interfaces within no time. However, the default scaffolding templates provide only a simple boilerplate and fail to convince for more sophisticated forms. I spent quite some time in the previous weeks writing scaffolding templates. A [...]]]></description>
			<content:encoded><![CDATA[<p>Much of Grails power and ability to crank out applications can be accounted to its scaffolding mechanism for creating <a title="Wikipedia: CRUD" href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" target="_blank">CRUD</a> interfaces within no time. However, the default scaffolding templates provide only a simple boilerplate and fail to convince for more sophisticated forms. I spent quite some time in the previous weeks writing scaffolding templates. A lot of this process was trial and error, browsing source code and bothering <a title="Tomás Lin's Blog about Flex &amp; Grails" href="http://fbflex.wordpress.com/" target="_blank">Tomás Lin</a>. I still have to find good documentation on this, so I'm posting my findings here in the hope to help people leveraging Grails even more. If you are just trying to understand how scaffolding works to building something more advanced, this is for you.</p>
<p><span id="more-487"></span></p>
<h2>Scaffolding in a Nutshell</h2>
<p>I assume that you know what Grails and its scaffolding mechanism is about, but I'll just summarize it here.</p>
<p>In a nutshell scaffolding is Grails ability to create controllers and views for domain classes. It analyzes the structure of the domain objects and creates all the files and logic required for simple CRUD functionality. If you have some domain classes all you have to do is type the following from within your project directory:</p>
<pre>$ grails generate-all</pre>
<p>This will create controllers and views for all domain classes found. Note that there are generate-views and generate-controller commands as well.</p>
<p>However you'll soon find out that the default templates which are used to create all the files may not fit your needs. Grails offers a separate <a title="Grails install-template" href="http://grails.org/doc/1.0.x/ref/Command%20Line/install-templates.html" target="_blank">command to copy the default templates</a> into your project directory:</p>
<pre>$ grails install-templates</pre>
<p>This will create a new folder src/templates in your project, holding an copy of the default templates, all yours to modify and adapt.</p>
<h2>Grails Scaffolding Templates</h2>
<p>Before we dive into the details of scaffolding, you need to understand the different templates and what they are for. Running the install-templates command will give you the following files withing your project directory:</p>
<pre>src/templates
|-- artifacts
|   |-- Controller.groovy
|   |-- DomainClass.groovy
|   |-- Script.groovy
|   |-- Service.groovy
|   |-- TagLib.groovy
|   |-- Tests.groovy
|   `-- WebTest.groovy
|-- scaffolding
|   |-- <span style="color: #000000;"><strong>Controller.groovy</strong></span>
|   |-- <strong>create.gsp</strong>
|   |-- <strong>edit.gsp</strong>
|   |-- <strong>list.gsp</strong>
|   |-- <strong>renderEditor.template</strong>
|   `-- <strong>show.gsp</strong>
`-- war
    `-- web.xml</pre>
<p>The files relevant for the scaffolding process are in the scaffolding directory and have been highlighted with <span style="color: #000000;"><strong>bold font</strong></span>. So, what are those files for? Let's examine them one by one.</p>
<p>The first one is <strong>Controller.groovy</strong>. This file is used to create the controllers for your domain classes. The syntax in this file may appear a bit weird in the beginning but after all it's just a <a title="Groovy Templates" href="http://groovy.codehaus.org/Groovy+Templates" target="_blank">groovy template</a> (I really encourage you to read this!). With this in mind reading the templates gets very easy. In the Controller.groovy you basically will find all the actions you would expect from your scaffolded controllers and some groovy template markup.</p>
<p>Next are the GSP files, <strong>create.gsp</strong>, <strong>edit.gsp</strong>, <strong>list.gsp</strong> and <strong>show.gsp</strong>. Those are obviously used to render the GSP markup required for your CRUD views. At a first glance lots of magic happen in those files. We'll cover the details in just a minute.</p>
<p>Finally there is the <strong>renderEditor.template</strong>. This file is used when rendering the HTML forms. Basically what happens in here is a translation of a type like Date or byte[] to their according form elements like a date picker or a file upload button.</p>
<h2>The Scaffolding Process</h2>
<p>Alright, so what happens when you issue generate-all for a domain class? There are a couple of players involved in this game. As most obvious besides the templates we just saw there are the actual scripts,  generate-all, generate-views or generate-controller which reside under $GRAILS_HOME/scripts. These scripts instantiate a DefaultGrailsTemplateGenerator which basically is a wrapper around Groovy's <a title="Groovy Template" href="http://groovy.codehaus.org/api/groovy/text/Template.html" target="_blank">Template</a> and <a title="Groovy TemplateEngine" href="http://groovy.codehaus.org/api/groovy/text/TemplateEngine.html" target="_blank">TemplateEngine</a> and binds together all the pieces we've encountered so far. You won't find any Javadocs about this class, so you'll have to browse the Grails sourcecode if you're interested. The DefaultGrailsTemplateGenerator then calls the actual templates.</p>
<p>One key aspect for creating really powerful scaffolding code is to understand what is handed into the templates by the DefaultGrailsTemplateGenerator. It took me quite some time and some source code browsing to figure this out. First there is a variable called propertyName. There isn't anything magical about it, just the name for a variable. However you will encounter this variable all over the templates. For example if scaffolding is run for a class called "User" propertyName would be "user" (note the lower case "u") and all variables of type "User" would be called "user" in the scaffolded output.</p>
<p>Then there is an instance of <a title="Grails DefaultGrailsDomainClass" href="http://grails.org/doc/1.0.3/api/org/codehaus/groovy/grails/commons/GrailsDomainClass.html" target="_blank">DefaultGrailsDomainClass</a> which is handed into the template as a variable called <strong>domainClass</strong>. This class variable plays a major role in scaffolding as it allows you to access all kinds of information about the domain class the scaffolding process is handling. You can get information about the GORM mappings, the associations the class has and even the other side of the associations, which is crucial when building more complex forms and more. And yes, i really encourage you to read the Javadocs for this class.</p>
<p>Depending on whether views or controllers are generated either the create.gsp, list.gsp, edit.gsp and show.gsp or Controller.groovy are used as template.</p>
<h3>Generating a Controller</h3>
<p>When generating controllers the Controller.groovy file is used as template. What you will end up with is a new file named after your Class containing the usual actions required for CRUD. There is not much magic happening in here; the template is pretty straight forward and just creates calls for the different GORM methods. Read it to get a feeling for this.</p>
<h3>Generating Views</h3>
<p>However when generating views, things get more interesting. In the views and the renderEditor.template the domainClass property is actually used to determine information about collections.</p>
<p>So let's dive into the details of how the views are generated. If you look at the templates you'll see that all of them create a list of properties available for a domain class by querying the domainClass variable:</p>
<pre>props = domainClass.properties.findAll { !excludedProps.contains(it.name) }</pre>
<p>All that remains to do now is to iterate over those properties, determine whether they should be visible and call the renderEditor to actually render the required code. The following block of code has been copied from the edit template and has been commented by me to clarify:</p>
<pre>props.each { p -&gt;
    cp = domainClass.constrainedProperties[p.name]
    display = (cp ? cp.display : true) <strong>// Determine visibility</strong>
    if(display) { %&gt;
    &lt;tr class="prop"&gt;
        &lt;td valign="top" class="name"&gt;
            &lt;label for="${p.name}"&gt;${p.naturalName}:&lt;/label&gt;
        &lt;/td&gt;
        &lt;td valign="top" class="value \${hasErrors(bean:${domainClass.propertyName},field:'${p.name}','errors')}"&gt;
            ${renderEditor(p)}  <strong>// Call render editor to render correct form element</strong>
        &lt;/td&gt;
    &lt;/tr&gt;</pre>
<p>This is basically what happens in all the templates. A list of properties is generated and iterated over. One piece is still missing: the renderEditor.template.</p>
<p>As stated earlier, the renderEditor.template translates the type of a property into the appropriate form control. The way this happens is disappointingly simple; open up the file in your favorite editor and you will find a big block of if-statements like this:</p>
<pre>&lt;%  if(property.type == Boolean.class || property.type == boolean.class)
        out &lt;&lt; renderBooleanEditor(domainClass,property)
    else if(Number.class.isAssignableFrom(property.type) || (property.type.isPrimitive() &amp;&amp; property.type != boolean.class))
        out &lt;&lt; renderNumberEditor(domainClass,property)
    else if(property.type == String.class)
        out &lt;&lt; renderStringEditor(domainClass,property)
    else if(property.type == Date.class || property.type == java.sql.Date.class || property.type == java.sql.Time.class)
        out &lt;&lt; renderDateEditor(domainClass,property)
...</pre>
<p>and further below the methods called by the if-statements:</p>
<pre>...
    private renderByteArrayEditor(domainClass,property) {
        return "&lt;input type=\"file\" id=\"${property.name}\" name=\"${property.name}\" /&gt;"
    }

    private renderManyToOne(domainClass,property) {
        if(property.association) {
            return "&lt;g:select optionKey=\"id\" from=\"\${${property.type.name}.list()}\" name=\"${property.name}.id\" value=\"\${${domainClass.propertyName}?.${property.name}?.id}\" ${renderNoSelection(property)}&gt;&lt;/g:select&gt;"
        }
    }
...</pre>
<p>So in the rendering process for each property the type will be matched in the if statements and the appropriate function is called to render out some HTML/GSP code.</p>
<h2>Conclusion</h2>
<p>Creating scaffolding templates is not hard. It requires some knowledge about the involved technologies and concepts but I hope this post gives you a fair understanding of what is going on. If you still have any questions, feel free to comment or drop me an email.</p>
<p>As always, comments are welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jakusys.de/blog/2008/12/grails-scaffolding-in-depth/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

