Search code examples
asp.net-mvcgrailsgroovygspsitemesh

What is the Grails GSP equivalent of ASP's ContentPlaceHolder?


I've been playing around a lot with the templating/layout concepts in Grails GSP. I've ben using layouts/content blocks for imitating ASP's master page behavior.

For example, I am using the tag <g:pageProperty /> in a template to leave a "placeholder" which can be overridden using a <content> tag:

myTemplate.gsp:

<body>
    <g:pageProperty name="page.topDiv" />
</body>


myPage.gsp:

<html>
    <head>
        <meta name="layout" content="myTemplate"></meta>
    </head>
    <body>
        <content tag="topDiv">
           My top div
        </content>
    </body>
</html>

This works great for "appending" content to some spot within a template. However, I really want the behavior I can get in ASP.NET's master pages... which is to provide a "default" rendering of some content, and allow optional overriding. In an ASP.NET Master page, it would look like this:

myMaster.master:

<asp:ContentPlaceHolder id="something" runat="server">
   <div>Default text/html here</div>
</asp:ContentPlaceHolder>


someOtherPage.aspx:

<asp:Content contentPlaceHolderId="something" runat="server">
    Overriden content here!!  I don't need to override this though :)
</asp:Content>


My Question:
Can I do this same default/overriding behavior in Grails' GSP?


Solution

  • There are a few different days you could accomplish this. The g:pageProperty is equivalent to the Sitemesh decorator:getProperty tag, so you can use a default attribute to indicate the default text to use. For example:

    <g:pageProperty name="page.topDiv" default="Default text/html here"/>
    

    However, I don't know of a clean way to get HTML content in there. You could use a g:if tag to test for that property and specify default behavior if it doesn't exist:

        <g:if test="${pageProperty(name:'page.topDiv')}">
            <g:pageProperty name="page.topDiv"/>
        </g:if>
        <g:else>
            <div>Default text/html here</div>
        </g:else>
    

    The default content could also live in an external template gsp. The render method could then be used to display that content in the default attribute of g:pageProperty:

    <g:pageProperty name="page.topDiv" default="${render(template:'topDiv')}"/>
    

    Where in this case, the default content would be located in _topDiv.gsp.