1

I am new to latte template engine and fiddle around with it since some days. I found a lot of nice and usefull things to make my projects easier and cleaner. But there is one thing I did not find or miss an idea how to handle it.

Lets imagine my sites has this basic layout template:

<header><h1>{$title}</h1></header>
<nav n:inner-foreach="$navigation as $link">
<a href="{$link->url}" n:class="$link->active ? active" n:attr="data-icon: $link->icon">{$link->name}</a>
</nav>
<aside>{include aside}</aside>
<aside>{include aside}</aside>
<aside>{include aside}</aside>
<content>{include content}<content>
<footer>{include footer}</footer>

the content is handled within another template for each site. every one of them looks like this:

{layout 'layout.tpl'}
{$navigation[3]->active=true}
{$title="this page title"}

{block content}
    <p>here comes the content</p>
{/block}

{block aside}
    <p>here is f.e. a sidebar</p>
{/block}

{block aside}
    <p>this is some adverticement</p>
{/block}

now my question is this: how can I use one or more blocks of "aside" within my template which are defined as "block". the best solution whould be something like: "block aside[]" and I handle it inside the main template somehow with a loop. Is there an usefull way to do it? I dont want to use it with variables like the navigation because the content is defined within the template.

thx for ideas and greetings Makka

Makkapitew
  • 11
  • 4
  • What do you expect to achieve by having multiple blocks with the same name? Why not just have a single `aside` block in the child template containing both sidebar and advertisement? – Jan Tojnar Jul 03 '21 at 22:10
  • because depending on css the aside-blocks can appear left and/or right. html5 allow multiple aside-sections. – Makkapitew Jul 03 '21 at 23:42
  • Sure, but you only have a single aside in the layout. If you want multiple ones, you will need to distinguish them somehow (e.g. by adding a class) and at that point you can just use differently named blocks. – Jan Tojnar Jul 04 '21 at 00:48
  • that was my question ... how can i do this, but without using another assignment method than every other block. (i editted the first post for better clarity) – Makkapitew Jul 04 '21 at 06:24
  • Well, I still question the benefit of doing that rather than having different blocks with different names. I posted an answer with a hack that achieves what you say you want but that still sounds like [XY problem](https://xyproblem.info/). – Jan Tojnar Jul 04 '21 at 12:29
  • The answer to your question is quite simple: i know my customers. They want / should later create templates for the content (and the asides) on their own and I know what a lack of understanding there will be if the method is different for different areas. – Makkapitew Jul 05 '21 at 08:10

1 Answers1

0

Well, you could do something like, abusing dynamic block names:

{var $maxAside = 10}
{for $i = 0; $i < $maxAside; $i++}
  {ifset aside-$i}
    {include "aside-$i"}
  {else}
    {breakIf true}
  {/ifset}
{/for}

and define blocks like {block "aside-{++$i}"}…{/block} but I would not recommend this because it just adds pointless complexity.

Either, majority of the asides will be the same and then you could have just used a single aside block for them:

{block aside}
  <section>
    <p>here is f.e. a sidebar</p>
  </section>

  <section>
    <p>this is some adverticement</p>
  </section>
{/block}

Or you you will want to be distinguishing them somehow (e.g. styling them differently) and then you would assign them classes, at which point you can just use different blocks:

<aside class="sidebar" n:ifset="sidebar">{include sidebar}</aside>
<aside class="advertisement" n:ifset="advertisement">{include advertisement}</aside>

Unless you are matching them using :nth-child CSS selector. But that is fragile because you would now need to match the order to the one defined in the CSS.


The problem only starts to become interesting when you have a hierarchy of pages where the pages inherit asides from pages in parent layers. But then it is still nicer to use template inheritance.

Jan Tojnar
  • 5,306
  • 3
  • 29
  • 49
  • The first part of your answer seems to be what I'm looking for. Thanks a lot for this. Can you explain to me what you mean by "pointless complexity"? At first glance, I don't see any great problems. – Makkapitew Jul 05 '21 at 08:19
  • The second part is also a nice solution that I had already thought of. I just define a set of names for the asides and treat them as normal blocks. But then I hear my customer asking: "I still need an area named X, Y and Z". Or maybe that can be done simply by giving him an editable list of names. – Makkapitew Jul 05 '21 at 08:27
  • The main complexity is the need to manually increase the counter. Also it will likely be less efficient than just having a static list of blocks (but probably not too much, would have to measure). – Jan Tojnar Jul 05 '21 at 11:57
  • Editable list of names would be nice since you could just do ``, that is probably the easiest solution. – Jan Tojnar Jul 05 '21 at 12:02
  • Alternately, you could define [custom](https://latte.nette.org/en/develop#toc-user-defined-tags) `aside` tag, using the [`block` macro](https://github.com/nette/latte/blob/39c62d20a4c36a60835da6a0ed2d1df76979a20a/src/Latte/Macros/BlockMacros.php#L53) as a starting point. – Jan Tojnar Jul 05 '21 at 12:08
  • After trying around a little, I think the best solution for my needs is to have the editable list of names for the sidebars. This can be created very easily, I can check for allowed names and control their order and there is the possibility to deactivate and reuse it (e.g. for special offers) without touching the template. And the block is defined like any other block. Many thanks for your help and ideas @jan-tojnar I use it like this: `{foreach $asideNames as $sidebar}{/foreach}` – Makkapitew Jul 05 '21 at 15:14