Multiple layout section override ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Multiple layout section override ?

Albert Kam
I am aware that i can use macros for layouting, for example, a main layout that contains header, left body section, center body section, footer.

Based on the examples i have googled, like this one here http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html, i can use <#nested> in the main layout for dynamic values for other templates that use this main layout macro.

But in my case, i would like the other templates to be able to 'override' more than 1 <#nested>, for example, providing the content of left body section -and- center body section (like apache tiles).

Is this supported, or maybe is there any other approaches to do this ?

--
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Daniel Dekany
Wednesday, March 6, 2013, 2:46:26 PM, Albert Kam wrote:

> I am aware that i can use macros for layouting, for example, a main
> layout that contains header, left body section, center body section, footer.
>
> Based on the examples i have googled, like this one here
> http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html,
> i can use <#nested> in the main layout for dynamic values for other
> templates that use this main layout macro.
>
> But in my case, i would like the other templates to be able to
> 'override' more than 1 <#nested>, for example, providing the content
> of left body section -and- center body section (like apache tiles).
>
> Is this supported, or maybe is there any other approaches to do this ?

Sadly, there's still no built-in solution for this. I have seen two
approaches to work this around. First is passing macros to the layout
macro:

  <#macro myHeading>
    ...
  </#macro>

  <#macro myFooter>
    ...
  </#macro>

  <@myApp.page heading=myHeading body=myFooter>
    ... this is the body ...
  </@myApp.page>

It's kind of noisy though. So I would rather implement this (some
deeper FreeMarker knowledge is needed):

  <@myApp.page>
    <@block name="heading">
      ...
    </@block>
    <@block name="body">
      ...
    </@block>
    <@block name="footer">
      ...
    </@block>
  </@myApp.page>

Here @block has to be implemented by you, in Java
(TemplateDirectiveModel). The layout macro need to push a
TemplateHashModel into a stack that's stored in a custom Environment
attribute, then call #nested. Then, @block should capture the content
generated inside its body, get the topmost TemplateHashModel from said
stack, and put the captured content into with block name (like
"heading") as the key.

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Albert Kam
Thanks for the ideas.

I have tried the macro solution from your reply, seems great !

the layout file :
<#macro defaultHeader>
defaultHeader here
</#macro>

<#macro defaultFooter>
defaultFooter here
</#macro>

<#macro layout header=defaultHeader footer=defaultFooter>
<@header />
<#nested>
<@footer />
</#macro>

the 'page' file that overrides a header n provide a body as usual:
<#macro overrideHeader>
header overriden
</#macro>

<@layout header=overrideHeader>
body overriden
</@layout>

The output is :
header overriden
body overriden
defaultFooter here

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

I have not tried the java directive yet. I would like to clarify some points before trying it out :

> The layout macro need to push a TemplateHashModel into a stack that's stored in a custom Environment attribute, 
How to do this inside the macro, is it by using #assign directive to store to the global variable so it can be fetched later from the TemplateDirectiveModel's Environment via the getGlobalVariable() ?
If yes, how do i assign a 'hash' to a global variable ? And i dont see any stack in the Environment api doc.

> then call #nested. 
This is as simple as providing <#nested> in the macro, correct ?

> Then, @block should capture the content generated inside its body, get the topmost TemplateHashModel from said
stack, and put the captured content into with block name (like"heading") as the key.
So, this means that the <#nested> in the layout doesnt produce any output at all.
And to produce the header, body, footer, i have to loop all the captured contents stored in the global variable, correct ?
And if this is so, what is the convenient way to provide a default content for a section that might not be overriden ?

Thank you so much !


On Sat, Mar 9, 2013 at 7:53 AM, Daniel Dekany <[hidden email]> wrote:
Wednesday, March 6, 2013, 2:46:26 PM, Albert Kam wrote:

> I am aware that i can use macros for layouting, for example, a main
> layout that contains header, left body section, center body section, footer.
>
> Based on the examples i have googled, like this one here
> http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html,
> i can use <#nested> in the main layout for dynamic values for other
> templates that use this main layout macro.
>
> But in my case, i would like the other templates to be able to
> 'override' more than 1 <#nested>, for example, providing the content
> of left body section -and- center body section (like apache tiles).
>
> Is this supported, or maybe is there any other approaches to do this ?

Sadly, there's still no built-in solution for this. I have seen two
approaches to work this around. First is passing macros to the layout
macro:

  <#macro myHeading>
    ...
  </#macro>

  <#macro myFooter>
    ...
  </#macro>

  <@myApp.page heading=myHeading body=myFooter>
    ... this is the body ...
  </@myApp.page>

It's kind of noisy though. So I would rather implement this (some
deeper FreeMarker knowledge is needed):

  <@myApp.page>
    <@block name="heading">
      ...
    </@block>
    <@block name="body">
      ...
    </@block>
    <@block name="footer">
      ...
    </@block>
  </@myApp.page>

Here @block has to be implemented by you, in Java
(TemplateDirectiveModel). The layout macro need to push a
TemplateHashModel into a stack that's stored in a custom Environment
attribute, then call #nested. Then, @block should capture the content
generated inside its body, get the topmost TemplateHashModel from said
stack, and put the captured content into with block name (like
"heading") as the key.

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user



--
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Tony Schwartz
In reply to this post by Albert Kam

What I have done is this:

<#macro layout>
    <html>
        <body>
        </body>

</#macro>




On Wed, 6 Mar 2013 20:46:26 +0700, Albert Kam  wrote:  I am aware that i
can use macros for layouting, for example, a main layout that contains
header, left body section, center body section, footer.
 Based on the examples i have googled, like this one here
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[1], i can use  in the main layout for dynamic values for other templates
that use this main layout macro.
 But in my case, i would like the other templates to be able to 'override'
more than 1 , for example, providing the content of left body section -and-
center body section (like apache tiles).
 Is this supported, or maybe is there any other approaches to do this ?

 --
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
 Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)  

Tony Schwartz
[hidden email]
 

Links:
------
[1]
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Tony Schwartz

Sorry about that previous post!  I accidentally sent the email, I just love
coding in a bad browser based email client!




What I have done in the past is this:


<#-- DEFINE THE MACRO -->
<#macro layout>
    <html>
        <body>
        <div id="head"><#nested "head" /></div>
        <div id="content"><#nested "content" /></div>
        </body>
    </html>
</#macro>



<#-- NOW, CALL THE MACRO -->
<@layout ; section>
        <#if section = "head">
                Write your header section here.
        <#elseif section = "content" >
                Write your content section here.
        <#else>
                Unsupported section??
        </#if>
</@layout>








On Sat, 09 Mar 2013 08:09:05 -0500, Tony Schwartz
<[hidden email]> wrote:

> What I have done is this:
>
> <#macro layout>
>     <html>
>         <body>
>         </body>
>
> </#macro>
>
>
>
>
> On Wed, 6 Mar 2013 20:46:26 +0700, Albert Kam  wrote:  I am aware that i
> can use macros for layouting, for example, a main layout that contains
> header, left body section, center body section, footer.
>  Based on the examples i have googled, like this one here
>
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
> [1], i can use  in the main layout for dynamic values for other templates
> that use this main layout macro.
>  But in my case, i would like the other templates to be able to
'override'
> more than 1 , for example, providing the content of left body section
-and-

> center body section (like apache tiles).
>  Is this supported, or maybe is there any other approaches to do this ?
>
>  --
> Do not pursue the past. Do not lose yourself in the future.
> The past no longer is. The future has not yet come.
>  Looking deeply at life as it is in the very here and now,
> the practitioner dwells in stability and freedom.
> (Thich Nhat Hanh)  
>
> Tony Schwartz
> [hidden email]
>  
>
> Links:
> ------
> [1]
>
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html

--
Tony Schwartz
[hidden email]

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Albert Kam
Thanks for the guide Tony !

Actually i have thought of using the loop variable param, 
but i wonder how to provide the default section content,
since what i intended is to override some sections as needed, and use the default sections if not 'overriden'

Example :
for page1.ftl, i want to supply the body only, but use the default left-panel, default header n default footer
for page2.ftl, i want to supply both the body and left-panel, and still use the default header n default footer




On Sat, Mar 9, 2013 at 8:13 PM, Tony Schwartz <[hidden email]> wrote:

Sorry about that previous post!  I accidentally sent the email, I just love
coding in a bad browser based email client!




What I have done in the past is this:


<#-- DEFINE THE MACRO -->
<#macro layout>
    <html>
        <body>
                <div id="head"><#nested "head" /></div>
                <div id="content"><#nested "content" /></div>
        </body>
    </html>
</#macro>



<#-- NOW, CALL THE MACRO -->
<@layout ; section>
        <#if section = "head">
                Write your header section here.
        <#elseif section = "content" >
                Write your content section here.
        <#else>
                Unsupported section??
        </#if>
</@layout>








On Sat, 09 Mar 2013 08:09:05 -0500, Tony Schwartz
<[hidden email]> wrote:
> What I have done is this:
>
> <#macro layout>
>     <html>
>         <body>
>         </body>
>
> </#macro>
>
>
>
>
> On Wed, 6 Mar 2013 20:46:26 +0700, Albert Kam  wrote:  I am aware that i
> can use macros for layouting, for example, a main layout that contains
> header, left body section, center body section, footer.
>  Based on the examples i have googled, like this one here
>
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
> [1], i can use  in the main layout for dynamic values for other templates
> that use this main layout macro.
>  But in my case, i would like the other templates to be able to
'override'
> more than 1 , for example, providing the content of left body section
-and-
> center body section (like apache tiles).
>  Is this supported, or maybe is there any other approaches to do this ?
>
>  --
> Do not pursue the past. Do not lose yourself in the future.
> The past no longer is. The future has not yet come.
>  Looking deeply at life as it is in the very here and now,
> the practitioner dwells in stability and freedom.
> (Thich Nhat Hanh)
>
> Tony Schwartz
> [hidden email]
>
>
> Links:
> ------
> [1]
>
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html

--
Tony Schwartz
[hidden email]

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user



--
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Tony Schwartz

I have also done that successfully by setting up a namespace and defining
default macros that can be overridden.

What I have done is basically this:


#############
# layout.ftl
#############

<#macro heading>
        DEFAULT HEADING
</#macro>

<#macro content>
        DEFAULT CONTENT
</#macro>

<#macro leftNav>
        DEFAULT LEFT NAV
</#macro>


<#macro doLayout>
    <html>
        <body>
        <div id="head"><@heading /></div>
        <div id="leftNav"><@leftNav /></div>
        <div id="content"><@content /></div>
        </body>
    </html>
</#macro>

#############
# END layout.ftl
#############




#############
# page.ftl
#############
<#import "layout.ftl" as layout />


<#macro heading>
        MY IMPLEMENTATION OF THE HEADING
</#macro>
<#assign heading = heading in layout /><#-- THIS PUSHES THE heading MACRO
INTO THE layout NAMESPACE (OVERRIDING THE ORIGINAL heading MACRO) -->


<#macro content>
        MY IMPLEMENTATION OF THE CONTENT
</#macro>
<#assign content = content in layout /><#-- THIS PUSHES THE content MACRO
INTO THE layout NAMESPACE (OVERRIDING THE ORIGINAL content MACRO) -->


<#-- NOW, CALL THE LAYOUT - the default leftNav is used, but this page
overrides the content and heading sections -->
<@layout.doLayout />

#############
# END page.ftl
#############







On Sat, 9 Mar 2013 20:29:13 +0700, Albert Kam  wrote:  Thanks for the
guide Tony !
 Actually i have thought of using the loop variable param,  but i wonder
how to provide the default section content, since what i intended is to
override some sections as needed, and use the default sections if not
'overriden'
 Example : for page1.ftl, i want to supply the body only, but use the
default left-panel, default header n default footer for page2.ftl, i want
to supply both the body and left-panel, and still use the default header n
default footer

 On Sat, Mar 9, 2013 at 8:13 PM, Tony Schwartz  wrote:

 Sorry about that previous post! I accidentally sent the email, I just
love
 coding in a bad browser based email client!

 What I have done in the past is this:

 Write your header section here.

 Write your content section here.

 Unsupported section??

 On Sat, 09 Mar 2013 08:09:05 -0500, Tony Schwartz
  wrote:
 > What I have done is this:
 >
 >
 >
 >
 >
 >
 >
 >
 >
 >
 >
 > On Wed, 6 Mar 2013 20:46:26 +0700, Albert Kam wrote: I am aware that i
 > can use macros for layouting, for example, a main layout that contains
 > header, left body section, center body section, footer.
 > Based on the examples i have googled, like this one here
 >

http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[3]
 > [1], i can use in the main layout for dynamic values for other
templates
 > that use this main layout macro.
 > But in my case, i would like the other templates to be able to
 'override'
 > more than 1 , for example, providing the content of left body section
 -and-
 > center body section (like apache tiles).
 > Is this supported, or maybe is there any other approaches to do this ?
 >
 > --
 > Do not pursue the past. Do not lose yourself in the future.
 > The past no longer is. The future has not yet come.
 > Looking deeply at life as it is in the very here and now,
 > the practitioner dwells in stability and freedom.
 > (Thich Nhat Hanh)
 >
 > Tony Schwartz
 > [hidden email] [4]
 >
 >
 > Links:
 > ------
 > [1]
 >

http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[5]

 --
 Tony Schwartz
 [hidden email] [6]


------------------------------------------------------------------------------
 Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
 Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
 endpoint security space. For insight on selecting the right partner to
 tackle endpoint security challenges, access the full report.
 http://p.sf.net/sfu/symantec-dev2dev [7]
 _______________________________________________
 FreeMarker-user mailing list
 [hidden email] [8]
 https://lists.sourceforge.net/lists/listinfo/freemarker-user [9]

 --
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
 the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)  

Tony Schwartz
[hidden email]
 

Links:
------
[1] mailto:[hidden email]
[2] mailto:[hidden email]
[3]
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[4] mailto:[hidden email]
[5]
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[6] mailto:[hidden email]
[7] http://p.sf.net/sfu/symantec-dev2dev
[8] mailto:[hidden email]
[9] https://lists.sourceforge.net/lists/listinfo/freemarker-user

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Albert Kam
Great info Tony ! Thanks for sharing this.


On Sat, Mar 9, 2013 at 8:57 PM, Tony Schwartz <[hidden email]> wrote:

I have also done that successfully by setting up a namespace and defining
default macros that can be overridden.

What I have done is basically this:


#############
# layout.ftl
#############

<#macro heading>
        DEFAULT HEADING
</#macro>

<#macro content>
        DEFAULT CONTENT
</#macro>

<#macro leftNav>
        DEFAULT LEFT NAV
</#macro>


<#macro doLayout>
    <html>
        <body>
                <div id="head"><@heading /></div>
                <div id="leftNav"><@leftNav /></div>
                <div id="content"><@content /></div>
        </body>
    </html>
</#macro>

#############
# END layout.ftl
#############




#############
# page.ftl
#############
<#import "layout.ftl" as layout />


<#macro heading>
        MY IMPLEMENTATION OF THE HEADING
</#macro>
<#assign heading = heading in layout /><#-- THIS PUSHES THE heading MACRO
INTO THE layout NAMESPACE (OVERRIDING THE ORIGINAL heading MACRO) -->


<#macro content>
        MY IMPLEMENTATION OF THE CONTENT
</#macro>
<#assign content = content in layout /><#-- THIS PUSHES THE content MACRO
INTO THE layout NAMESPACE (OVERRIDING THE ORIGINAL content MACRO) -->


<#-- NOW, CALL THE LAYOUT - the default leftNav is used, but this page
overrides the content and heading sections -->
<@layout.doLayout />

#############
# END page.ftl
#############







On Sat, 9 Mar 2013 20:29:13 +0700, Albert Kam  wrote:  Thanks for the
guide Tony !
 Actually i have thought of using the loop variable param,  but i wonder
how to provide the default section content, since what i intended is to
override some sections as needed, and use the default sections if not
'overriden'
 Example : for page1.ftl, i want to supply the body only, but use the
default left-panel, default header n default footer for page2.ftl, i want
to supply both the body and left-panel, and still use the default header n
default footer

 On Sat, Mar 9, 2013 at 8:13 PM, Tony Schwartz  wrote:

 Sorry about that previous post! I accidentally sent the email, I just
love
 coding in a bad browser based email client!

 What I have done in the past is this:

 Write your header section here.

 Write your content section here.

 Unsupported section??

 On Sat, 09 Mar 2013 08:09:05 -0500, Tony Schwartz
  wrote:
 > What I have done is this:
 >
 >
 >
 >
 >
 >
 >
 >
 >
 >
 >
 > On Wed, 6 Mar 2013 20:46:26 +0700, Albert Kam wrote: I am aware that i
 > can use macros for layouting, for example, a main layout that contains
 > header, left body section, center body section, footer.
 > Based on the examples i have googled, like this one here
 >

http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[3]
 > [1], i can use in the main layout for dynamic values for other
templates
 > that use this main layout macro.
 > But in my case, i would like the other templates to be able to
 'override'
 > more than 1 , for example, providing the content of left body section
 -and-
 > center body section (like apache tiles).
 > Is this supported, or maybe is there any other approaches to do this ?
 >
 > --
 > Do not pursue the past. Do not lose yourself in the future.
 > The past no longer is. The future has not yet come.
 > Looking deeply at life as it is in the very here and now,
 > the practitioner dwells in stability and freedom.
 > (Thich Nhat Hanh)
 >
 > Tony Schwartz
 > [hidden email] [4]
[5]

 --
 Tony Schwartz
 [hidden email] [6]


------------------------------------------------------------------------------
 Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
 Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
 endpoint security space. For insight on selecting the right partner to
 tackle endpoint security challenges, access the full report.
 http://p.sf.net/sfu/symantec-dev2dev [7]
 _______________________________________________
 FreeMarker-user mailing list
 [hidden email] [8]
 https://lists.sourceforge.net/lists/listinfo/freemarker-user [9]

 --
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
 the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

Tony Schwartz
[hidden email]


Links:
------
[1] mailto:[hidden email]
[2] mailto:[hidden email]
[3]
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[4] mailto:[hidden email]
[5]
http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html
[6] mailto:[hidden email]
[7] http://p.sf.net/sfu/symantec-dev2dev
[8] mailto:[hidden email]
[9] https://lists.sourceforge.net/lists/listinfo/freemarker-user

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user



--
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Daniel Dekany
In reply to this post by Albert Kam
Saturday, March 9, 2013, 2:00:38 PM, Albert Kam wrote:

> Thanks for the ideas.
>
> I have tried the macro solution from your reply, seems great !
>
> the layout file :
> <#macro defaultHeader>
> defaultHeader here
> </#macro>
>
> <#macro defaultFooter>
> defaultFooter here
> </#macro>
>
> <#macro layout header=defaultHeader footer=defaultFooter>
> <@header />
> <#nested>
> <@footer />
> </#macro>
>
> the 'page' file that overrides a header n provide a body as usual:
> <#macro overrideHeader>
> header overriden
> </#macro>
>
> <@layout header=overrideHeader>
> body overriden
> </@layout>
>
> The output is :
> header overriden
> body overriden
> defaultFooter here
>
> ------------------
>
> I have not tried the java directive yet. I would like to clarify
> some points before trying it out :
>
>> The layout macro need to push a TemplateHashModel into a stack that's stored in a custom Environment attribute,
> How to do this inside the macro, is it by using #assign directive
> to store to the global variable so it can be fetched later from the
> TemplateDirectiveModel's Environment via the getGlobalVariable() ?
> If yes, how do i assign a 'hash' to a global variable ? And i dont
> see any stack in the Environment api doc.

You can't, or at least, shouldn't implement the more technical parts
of this in FTL. FTL, being an MVC View language, really just meant to
get everything ready from the data-model or from a directive/method
that was implemented in Java. So certainly you need to write a few
directives like:

- <@my.setBlock name="whatever">output will be captured here</@my.push>
  which stores the captured output into the top hash of said stack.

- my.blocks.whatever: get an earlier set block from the top hash of
  the stack.

- For convenience, maybe: <@my.printBlock name="whatever" />
  which is basically <#noesacpe>${my.blocks.whatever}</#noescape>.

- <@my.collectBlocks>...</@>
  which pushes a new empty hash into said stack, then pops it at the
  end

Then can use these when writing macros and just forgat about the
technical parts.

As of the technical parts... freemarker.core.Environment has a
set/getCustomAttribute method. There's no restriction regarding the
type of the attribute value, so there *you* can implement that stacks.

As of the hash thing... My quick idea was that the stack items are
themselves TemplateHashModelEx instances, so that you can easily
access them from the templates, but this really and unimportant
detail, and above I haven't even used it in that form. Because above
my.blocks is a TemplateHashModelEx that shows the topmost stack item.

Anyway, this should really be a core feature of FreeMarker, but I
don't think I will have time to implement this in the near future,
so...

>> then call #nested.
> This is as simple as providing <#nested> in the macro, correct ?

Yes.

>> Then, @block should capture the content generated inside its body, get the topmost TemplateHashModel from said
> stack, and put the captured content into with block name (like"heading") as the key.
> So, this means that the <#nested> in the layout doesnt produce any output at all.

Yes.

> And to produce the header, body, footer, i have to loop all the
> captured contents stored in the global variable, correct ?

Well, I would put them into that stack that's stored in an Envionment
attribute, but that's similar to a global variable in its scope and
life-cycle.

> And if this is so, what is the convenient way to provide a default
> content for a section that might not be overriden ?

For example, <@my.printBlock name="whatever" /> could have optionally
nested content that provides the default value.

> Thank you so much !
>
>
> On Sat, Mar 9, 2013 at 7:53 AM, Daniel Dekany <[hidden email]> wrote:
> Wednesday, March 6, 2013, 2:46:26 PM, Albert Kam wrote:
>
>> I am aware that i can use macros for layouting, for example, a main
>> layout that contains header, left body section, center body section, footer.
>>
>> Based on the examples i have googled, like this one here
>> http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html,
>> i can use <#nested> in the main layout for dynamic values for other
>> templates that use this main layout macro.
>>
>> But in my case, i would like the other templates to be able to
>> 'override' more than 1 <#nested>, for example, providing the content
>> of left body section -and- center body section (like apache tiles).
>>
>> Is this supported, or maybe is there any other approaches to do this ?
>
> Sadly, there's still no built-in solution for this. I have seen two
> approaches to work this around. First is passing macros to the layout
> macro:
>
>   <#macro myHeading>
>     ...
>   </#macro>
>
>   <#macro myFooter>
>     ...
>   </#macro>
>
>   <@myApp.page heading=myHeading body=myFooter>
>     ... this is the body ...
>   </@myApp.page>
>
> It's kind of noisy though. So I would rather implement this (some
> deeper FreeMarker knowledge is needed):
>
>   <@myApp.page>
>     <@block name="heading">
>       ...
>     </@block>
>     <@block name="body">
>       ...
>     </@block>
>     <@block name="footer">
>       ...
>     </@block>
>   </@myApp.page>
>
> Here @block has to be implemented by you, in Java
> (TemplateDirectiveModel). The layout macro need to push a
> TemplateHashModel into a stack that's stored in a custom Environment
> attribute, then call #nested. Then, @block should capture the content
> generated inside its body, get the topmost TemplateHashModel from said
> stack, and put the captured content into with block name (like
> "heading") as the key.
>
> --
> Best regards,
>  Daniel Dekany
>
>
> ------------------------------------------------------------------------------
> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
> endpoint security space. For insight on selecting the right partner to
> tackle endpoint security challenges, access the full report.
> http://p.sf.net/sfu/symantec-dev2dev
> _______________________________________________
> FreeMarker-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>
>
>

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user
Reply | Threaded
Open this post in threaded view
|

Re: Multiple layout section override ?

Albert Kam
Thanks for clearing it up Daniel.
I am currently applying the macro solution for the time being as it works and i have more things to do for now.
I will be posting to this thread again if i manage to find the time to impl the custom block directive.

Regards from Jakarta,
Albert Kam


On Sun, Mar 10, 2013 at 6:42 PM, Daniel Dekany <[hidden email]> wrote:
Saturday, March 9, 2013, 2:00:38 PM, Albert Kam wrote:

> Thanks for the ideas.
>
> I have tried the macro solution from your reply, seems great !
>
> the layout file :
> <#macro defaultHeader>
> defaultHeader here
> </#macro>
>
> <#macro defaultFooter>
> defaultFooter here
> </#macro>
>
> <#macro layout header=defaultHeader footer=defaultFooter>
> <@header />
> <#nested>
> <@footer />
> </#macro>
>
> the 'page' file that overrides a header n provide a body as usual:
> <#macro overrideHeader>
> header overriden
> </#macro>
>
> <@layout header=overrideHeader>
> body overriden
> </@layout>
>
> The output is :
> header overriden
> body overriden
> defaultFooter here
>
> ------------------
>
> I have not tried the java directive yet. I would like to clarify
> some points before trying it out :
>
>> The layout macro need to push a TemplateHashModel into a stack that's stored in a custom Environment attribute,
> How to do this inside the macro, is it by using #assign directive
> to store to the global variable so it can be fetched later from the
> TemplateDirectiveModel's Environment via the getGlobalVariable() ?
> If yes, how do i assign a 'hash' to a global variable ? And i dont
> see any stack in the Environment api doc.

You can't, or at least, shouldn't implement the more technical parts
of this in FTL. FTL, being an MVC View language, really just meant to
get everything ready from the data-model or from a directive/method
that was implemented in Java. So certainly you need to write a few
directives like:

- <@my.setBlock name="whatever">output will be captured here</@my.push>
  which stores the captured output into the top hash of said stack.

- my.blocks.whatever: get an earlier set block from the top hash of
  the stack.

- For convenience, maybe: <@my.printBlock name="whatever" />
  which is basically <#noesacpe>${my.blocks.whatever}</#noescape>.

- <@my.collectBlocks>...</@>
  which pushes a new empty hash into said stack, then pops it at the
  end

Then can use these when writing macros and just forgat about the
technical parts.

As of the technical parts... freemarker.core.Environment has a
set/getCustomAttribute method. There's no restriction regarding the
type of the attribute value, so there *you* can implement that stacks.

As of the hash thing... My quick idea was that the stack items are
themselves TemplateHashModelEx instances, so that you can easily
access them from the templates, but this really and unimportant
detail, and above I haven't even used it in that form. Because above
my.blocks is a TemplateHashModelEx that shows the topmost stack item.

Anyway, this should really be a core feature of FreeMarker, but I
don't think I will have time to implement this in the near future,
so...

>> then call #nested.
> This is as simple as providing <#nested> in the macro, correct ?

Yes.

>> Then, @block should capture the content generated inside its body, get the topmost TemplateHashModel from said
> stack, and put the captured content into with block name (like"heading") as the key.
> So, this means that the <#nested> in the layout doesnt produce any output at all.

Yes.

> And to produce the header, body, footer, i have to loop all the
> captured contents stored in the global variable, correct ?

Well, I would put them into that stack that's stored in an Envionment
attribute, but that's similar to a global variable in its scope and
life-cycle.

> And if this is so, what is the convenient way to provide a default
> content for a section that might not be overriden ?

For example, <@my.printBlock name="whatever" /> could have optionally
nested content that provides the default value.

> Thank you so much !
>
>
> On Sat, Mar 9, 2013 at 7:53 AM, Daniel Dekany <[hidden email]> wrote:
> Wednesday, March 6, 2013, 2:46:26 PM, Albert Kam wrote:
>
>> I am aware that i can use macros for layouting, for example, a main
>> layout that contains header, left body section, center body section, footer.
>>
>> Based on the examples i have googled, like this one here
>> http://wendefer.blogspot.com/2007/09/handy-tip-for-layouts-in-freemarker.html,
>> i can use <#nested> in the main layout for dynamic values for other
>> templates that use this main layout macro.
>>
>> But in my case, i would like the other templates to be able to
>> 'override' more than 1 <#nested>, for example, providing the content
>> of left body section -and- center body section (like apache tiles).
>>
>> Is this supported, or maybe is there any other approaches to do this ?
>
> Sadly, there's still no built-in solution for this. I have seen two
> approaches to work this around. First is passing macros to the layout
> macro:
>
>   <#macro myHeading>
>     ...
>   </#macro>
>
>   <#macro myFooter>
>     ...
>   </#macro>
>
>   <@myApp.page heading=myHeading body=myFooter>
>     ... this is the body ...
>   </@myApp.page>
>
> It's kind of noisy though. So I would rather implement this (some
> deeper FreeMarker knowledge is needed):
>
>   <@myApp.page>
>     <@block name="heading">
>       ...
>     </@block>
>     <@block name="body">
>       ...
>     </@block>
>     <@block name="footer">
>       ...
>     </@block>
>   </@myApp.page>
>
> Here @block has to be implemented by you, in Java
> (TemplateDirectiveModel). The layout macro need to push a
> TemplateHashModel into a stack that's stored in a custom Environment
> attribute, then call #nested. Then, @block should capture the content
> generated inside its body, get the topmost TemplateHashModel from said
> stack, and put the captured content into with block name (like
> "heading") as the key.
>
> --
> Best regards,
>  Daniel Dekany
>
>
> ------------------------------------------------------------------------------
> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
> endpoint security space. For insight on selecting the right partner to
> tackle endpoint security challenges, access the full report.
> http://p.sf.net/sfu/symantec-dev2dev
> _______________________________________________
> FreeMarker-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>
>
>

--
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user



--
Do not pursue the past. Do not lose yourself in the future.
The past no longer is. The future has not yet come.
Looking deeply at life as it is in the very here and now,
the practitioner dwells in stability and freedom.
(Thich Nhat Hanh)

------------------------------------------------------------------------------
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to
tackle endpoint security challenges, access the full report.
http://p.sf.net/sfu/symantec-dev2dev
_______________________________________________
FreeMarker-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/freemarker-user