limb3_2007_4:en:packages:macro:template_composition

Templates composition (including, wrapping and reusing)

macro has a rich set of tools for template composition:

  • Including - inserting the content of other template into the current template
  • Wrapping - wrapping a part or the whole content of the current template into some particular point (so called slot) or points of another template
  • Reusing - using one piece of the current template several times in the same template

MACRO compiles templates as a whole! First macro processes composition tags such as include, wrap, into, apply and only then generates php-script of the compiled template. That's why template composition cost you almost nothing in terms of execution speed. This feature of macro makes it possible to extract any duplicating parts into separate templates and reuse them in different ways.

Including. Tag {{include}}

To include the contents of a template into particular point of the current template you can use tag {{include}}.

For example:

{{include file='header.phtml'/}}
[...content...]
{{include file='footer.phtml'/}}

file attribute of include tag contains either alias of template name or complete (absolute) file path. By default macro searches template in /template folder of your application. If you create an application with WEB_APP package of LIMB3 then macro will also looking for templates in /template folder of Limb3 packages (see LIMB_TEMPLATES_INCLUDE_PATH constant in limb/view/src/toolkit/lmbViewTools.class.php)

Please note that included template should be balanced. In macro balancing means that each opening tag should have a closing tag (if required) in the same template.

Wrapping

Basics of templates wrapping

Wrapping - is inserting a part of the current template into a particular place (slot) of the wrapper template (parent template)

There are three tags for wrapping:

  • Tag {{wrap}} - tells what file to wrap into. Has opening and closing tags. If you need to wrap the whole content of wrap tag into the wrapper template slot then wrap also specifies what slot to use by into attribute.
  • Tag {{slot}} - marks a point in template where the contents of other template can be inserted into.
  • Tag {{into}} - limits a portion of the current template that can be inserted into a slot in parent template

Let's consider a small example.

page.phtml - parent template with slot:

<html>
<head>
[...meta...]
</head>
<body>
 {{slot id='content'/}}
</body>
</html>

my_page.phtml - current template to be compiled:

{{wrap with='page.phtml' into='content'}}
[...content...]
{{/wrap}}

As we already said, wrap tag must have a closing tag that limits a portion of the current template that will be inserted into a slot in parent template. with attribute of wrap tag specifies path to parent template or its alias. with is a required attribute of wrap tag. into attribute points at id attribute of the corresponding slot tag. into attribute can be skipped in case of multiple wrapping (see below).

As result macro will produce the following html:

<html>
<head>
[...meta...]
</head>
<body>
 [...content...]
</body>
</html>

Multiple wrapping. Tag {{into}}

Sometimes we need to insert several parts of the current template into different slots of parent template. For such cases you can use tag {{into}}. A small example will make everything clear.

Let's suppose we have a parent or core template page.phtml:

<html>
<body>
  {{slot id='content'/}}
</body>
</html>

Let's also imagine that we have an extra layout.phtml template with two slots:

 <div id='header'>{{slot id='header'/}}</div>
 <div id='main'>{{slot id='main'/}}</div>

And display.phtml as current template:

{{wrap with='page.phtml' into='content'}}
 
{{wrap file='layout.phtml'}}
 {{into slot='header'}}My Header{{/into}}
 {{into slot='main'}}My Complex content{{/into}}
{{/wrap}}
 
{{/wrap}}

The result of the compilation of display.phtml is:

<html>
<body>
   <div id='header'>My Header</div>
   <div id='main'>My Complex content</div>
</body>
</html>

How exactly macro compiles display.phtml? At the beginning the initial wrap tag is processed and we get:

<html>
<body>
  {{wrap with='layout.html'}}
   {{into slot='header'}}My Header{{/into}}
   {{into slot='main'}}My Complex content{{/core:wrap}}
  {{/wrap}}
</body>
</html>

Then the second wrap tag is processed and we get approximately the following intermediate compiled template:

<html>
<body>
 
 <div id='header'>{{slot id='header'/}}</div>
 <div id='main'>{{slot id='main'/}}</div>
 
 {{into slot='header'}}My Header{{/into}}
 {{into slot='main'}}My Complex content{{/into}}
 
</body>
</html>

After into tags are processed we get the final result.

Multiple wrapping and including

If into tag can't find necessary slot in template that is specified by parent wrap, it tries to find that slot starting from the root of the compile time tree. You can also use into tag inside included template without parent wrap tag in the same template. Let's clarify all this by a small example.

Let's suppose we have a core template page.phtml:

<html>
<body>
  <div class='content'>
  {{slot id='content'/}}
  </div>
  {{slot id='js_code'/}}
</body>
</html>

Let's also imagine that we have an extra child.phtml template with the following content:

 Insert me!
 {{into slot='js_code'}}<script type="text/javascript" src="..."></script>{{/into}}

And display.phtml as current template:

{{wrap with='page.phtml' into='content'}}
<div class='cool'>{{include file='child.phtml'}}</div>
{{/wrap}}

As result is:

<html>
<body>
   <div class='content'>
    <div class='cool'>Insert me!</div>
   </div>
   <script type="text/javascript" src="..."></script>
</body>
</html>

Wrapping combinations can be even more complex, just don't loose yourself in your templates ;)

Reusing

There are situations when you need a portion of template to be rendered twice on the same page with different sets of data. For example, at catalog page you need to print featured products, recently added products and first page of total list of products. Off course, you can use include tag but there is an alternative in case if you don't want to extract an extra template.

Here is an example:

  {{template name="photo_tpl"}}
    <span class="date">{$item.ctime|date:"d.m.Y"}</span>
    <a href="/photo/item/{$item.id}" class="img"><img alt="{$item.title}" src="{$item.icon_file_url}"></a>
    <a href="/photo/item/{$item.id}" class="title">{$item.title}</a>
    <a href="#" class="author">{$item.member.nick}</a>
    <a href="{$item.thumbnail_file_url}" title="{$item.title}" class='preview'>preview</a>
  {{/template}}
 
  <h2>Best photos in section {$#category.title}</h2>
  {{list using="$#best_photos" as="$photo"}}
  <ul id='best_photos_list'>
    {{list:item}}
     <li>{{apply template="photo_tpl" item="$photo"/}}</li>
    {{/list:item}}
  </ul>
  {{/list}}
 
  <h2>All photos in section {$#category.title}</h2>
  {{list using="$#photos" as="$photo"}}
  <ul id='photos_list'>
    {{list:item}}
     <li>{{apply template="photo_tpl" item="$photo"/}}</li>
    {{/list:item}}
  </ul>
  {{/list}}

template tag does not render anything without apply. For compiled php-class template tag creates an extra method and apply tag renders a call for this method with some params. Note: template tag thus creates a local data scope, so you need to pass variables with apply tag parameters from current local score to template tag local score if required. In our example we passed item variable into template_id_photo_tpl

Обсуждение

Ваш комментарий. Вики-синтаксис разрешён:
  ____  ______  _   __  _      __   ___ 
 / __ \/_  __/ | | / / | | /| / /  / _ \
/ /_/ / / /    | |/ /  | |/ |/ /  / ___/
\___\_\/_/     |___/   |__/|__/  /_/
 
limb3_2007_4/en/packages/macro/template_composition.txt · Последние изменения: 2010/11/10 10:02 (внешнее изменение)