Grails(8)Guide Book Chapter 7 The Web Layer Groovy Server Pages

Grails(8)Guide Book Chapter 7 The Web Layer Groovy Server Pages
7.1.13 Asynchronous Request Processing
7.2 Groovy Server Pages(GSP)
7.2.1 GSP Basics
GSP supports the usage of <% %> scriptlet blocks to embed Groovy code.(discouraged)

<%= %> syntax to output values.

7.2.1.1 Variables and Scopes
<%now = new Date() %>
<%=now%>
We define a variable, and use that later in the same page.

application - The javax.servlet.ServletContext instance
applicationContext - The Spring ApplicationContext instance
flash - The flash object
grailsApplication - The GrailsApplication instance
out - The response writer for writing to the output stream
params - The params object for retrieving request parameters
request - The HttpServletRequest instance
response - The HttpServletResponse
session - The HttpSession instance
webRequest - The GrailsWebRequest instance

7.2.1.2 Logic and Iteration
<% [1,2,3,4].each { num ->  %>
     <p><%="Hello ${num}!" %></p>
<% } %>

<% if (params.hello == 'true' ) %>
     <%="hello!"%>
<% else %>
     <%= "Goodbye!" %>

I found there is no end tag in the GSP above. It will confuse me.

7.2.1.3 Page Directives
The import directive lets us import classes into the page.
<%@ page import="java.awt.*" %>
<%@ page contentType="text/json" %>

7.2.1.4 Expressions
A GSP expression is similar to a JSP EL expression. ${expr}

Hello ${params.name}

7.2.2 GSP Tags
7.2.2.1 Variables and Scopes
<g:set var="now" value="${new Date()}" />    // set java.util.Date instance

<g:set var="myHTML">
     Some re-usable code on: ${new Date()}
</g:set>                                                      //set html content

<g:set var="bookService" bean="bookService" />  //set service bean

There are following scopes>
page - Scoped to the current page (default)
request -
flash
session
application

<g:set var="now" value="${new Date()}" scope="request" />

7.2.2.2 Logic and Iteration
<g:if test="${session.role == 'admin'}">
     …snip...
</g:if>
<g:else>
     …snip...
</g:else>

<g:each in="${[1,2,3]}" var="num">
     <p>Number ${num}</p>
</g:each>

7.2.2.3 Search and Filtering
Stephen King's Books:
<g:findAll in="${books}" expr="it.author == 'Stephen King' ">
     <p>Title: ${it.title}</p>
</g:findAll>

The expr attribute contains a Groovy expression that can be used as a filter.

<g:grep in="${books}" filter="NonFictionBooks.class">
     <p>Title: ${it.title}</p>
</g:grep>
filter by Class?

7.2.2.4 Links and Resources
<g:link action="show" id="1">Book 1</g:link>
<g:link action="show" id="${currentBook.id}">${currentBook.name}</g:link>

<g:link controller="book">Book Home</g:link>

<g:link controller="book" action="list"> Book List</g:link>


<g:link url="[action: 'list', controller: 'book']"> Book List</g:link>

<g:link params="[sort: 'title', order: 'sac', author: currentBook.author]"
           action="list">Book List</g:link>

7.2.2.5 Forms and Fields
Form Basics
<g:form name="myForm" url="[controller: 'book', action: 'list']">…</g:form>

Form Fields
textField
passwordField
checkBox
radio      - For input fields of type 'hidden'
hiddenField
select

Each of these allows GSP expressions for the value part.
<g:textField name="username" value="${user.username}" />

Multiple Submit Buttons
<g:actionSubmit value="Update" action="update" />

7.2.2.6 Tags as Method Calls

7.2.3 Views and Templates
Template Basics
Grails uses the convention of placing an underscore before the name of a view to identify it as a template.

grails-app/views/book/_bookTemplate.gsp

<div class="book" id="${book?.id}">
     <div>Title: ${book?.title}</div>
     <div>Author: ${book?.author?.name}</div>
</div>

<g:render template="bookTempalte" model="[book: myBook]" />

<g:render template="bookTemplate" var="book" collection="${bookList}" />

Shared Templates
Pass more path to the render template
<g:render template="/shared/mySharedTemplate" />

The Template Namespace

Templates in Controllers and Tag Libraries
We can also render templates from controllers using the render controller method. This is useful for Ajax applications.

def bookData(){
     def b = Book.get(params.id)
     render(template: "bookTemplate", model: [book:b]) //first the book is the name in                                    //   template, second b is the variable.
}

Alternatively, more clear

def bookData(){
     def b = Book.get(params.id)
     String content = g.render(template: "bookTemplate", model: [book:b])
     render content
}

7.2.4 Layouts with Sitemesh
Creating Layouts
Grails leverages Sitemesh, a decorator engine. Layouts are located in the grails-app/views/layouts directory.

<html>
     <head>
          <title><g:layoutTitle default="An example decorator" /></title>
          <g:layoutHead />
     </head>
     <body onload="${pageProperty(name: 'body.onload')}">
          <div class="menu"> …snip…</menu>
               <div class="body">
                    <g:layoutBody />
               </div>
          </div>
     </body>
</html>

The key elements are as follow:
layoutTitle
layoutHead
layoutBody

Triggering Layouts
There are a few ways to trigger a layout. The simplest is to add a meta tag to the view:
<html>
     <head>
          <title>An Example Page</title>
          <meta name="layout" content="main" />
     </head>
     <body>This is my content!</body>
</html>

In this case a layout called grails-app/views/layouts/main.gsp

Specifying A Layout In A Controller
Another way to specify a layout is to specify the name of the layout by assigning a value to the "layout" property in a controller. For example,
class BookController {
     static layout = 'customer'
    
     def list() { … }
}

Then the layout grails-app/views/layouts/customer.gsp which will be applied to all views that the BookController delegates to.

static layout = 'custom/customer'
grails-app/views/layout/custom/customer.gsp template

Layout by Convention
layout by convention means that
class BookController {
     def list() { … }
}

grails-app/views/layouts/book.gsp will be applied to all views that the BookController delegates to.

Alternatively, we can create a layout called grails-app/views/layouts/book/list.gsp which will only be applied to the list action within the BookController.

The application default layout is
grails-app/views/layouts/application.gsp

This is configured in Config.groovy
grails.sitemesh.default.layout = 'myLayoutName'

Inline Layouts
<g:applyLayout name="myLayout" template="bookTemplate" collection="${books}" />

Server-Side Includes

7.2.5 Static Resources
7.2.5.1 Including resources using the resource tags
Pulling in resources with r:require
To use resources, we can indicate which resource modules it requires.

<r:require module="jquery" />

<r:require modules="query, main, blueprint, charting" />

Adding page-specific JavaScript code with r:script
<r:script dispostion="head">
     window.alert('This is at the end of <head>');
</r:script>

Linking to images with r:img
<r:img uri="/images/logo.png" />

7.2.5.2 Other resource tags
7.2.5.3 Declaring resources
7.2.5.6 Debugging
7.2.8 GSP Debugging
Viewing the generated source code
?showSource=true

7.3.6 Using JSP Tag Libraries
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

7.4.4 Mapping to Response Codes
static mappings = {
     "403"(controller: "errors", action: "forbidden")
     "404"(controller: "errors", action: "notFound")
     "500"(controller: "errors", action: "serverError")
}

static mappings = {
     "403"(view: "/errors/forbidden")
     "404"(view: "/errors/notFound")
     "500"(view: "/errors/serverError")
}

7.4.5 Mapping to HTTP methods
static mappings = {
     "/product/$id"(controller: "product") {
          action = [GET: "show", PUT: "update", DELETE:"delete", POST: "save"]
     }
}

7.4.6 Mapping Wildcards
static mappings = {
     "/images/*.jpg"(controller: "image")
}


References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html#asynchronousRequestProcessing


你可能感兴趣的:(groovy)