View previous topic :: View next topic |
Author |
Message |
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Sun Apr 25, 2010 10:08 pm Post subject: Check if {block name="foo"} was defined? |
|
|
Suppose I have this code in my parent.tpl:
Code: | <div id="content">
{block name='content'}Default content{/block}
</div>
<div id="gallery">
{block name='gallery'}Default content{/block}
</div> |
And now I want any of the <div> sections to be rendered only when their corresponding named block was defined in the child template. In other words instead of the default content I would like the whole <div> section to be ignored. Something like this:
Code: | {if $smarty.is_block_defined.content}
<div id="content">
{block name='content'}Default content should never be shown{/block}
</div>
{/if}
{if $smarty.is_block_defined.gallery}
<div id="gallery">
{block name='gallery'}Default content should never be shown{/block}
</div>
{/if} |
Of course this doesn't work but is there a way to achieve this? Or should I switch to using {capture} and {include} instead of {extends} and {block}? |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Mon Apr 26, 2010 1:49 pm Post subject: |
|
|
Code: | And now I want any of the <div> sections to be rendered only when their corresponding named block was defined in the child template. |
It this defeats the purpose template inheritance, so I'd recommend against using extends/block for this, or inherit from another template that fits your requirements. |
|
Back to top |
|
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Mon Apr 26, 2010 5:14 pm Post subject: |
|
|
mohrt wrote: | Code: | And now I want any of the <div> sections to be rendered only when their corresponding named block was defined in the child template. |
It this defeats the purpose template inheritance, so I'd recommend against using extends/block for this, or inherit from another template that fits your requirements. |
I have just noticed that the block structures are compiled into a single template so no conditional structures will work here. Can you say more why this defeats the purpose of template inheritance? I have found a few sites describing various implementations of template inheritance and while non of them provided conditionals around blocks I found no information why they should not be used. So far I see that conditionals would simplify code in my case. Otherwise I see the following solutions:
1. Move <div id="content"> and <div id="gallery"> away from parent.tpl and put them in child templates. However, this will mean more code writing in each child template. There will be many child templates for "content" and only one for "gallery". If I want sometime in the future to add a class to the <div> or perhaps wrap it around another <div> with a name specific to the "content" child templates, I would need to make the change in all my child templates.
2. Have two separate parent templates: one for content and one for gallery. However, that would result in repeated code in 2 templates, which is not optimal. These 2 templates would differ only in the name of the id in <div>. I could move the repeated code to a separate template and include it, or even inherit it but that would increase the overall complexity.
3. Switch to capture and include - but that would mean giving up the simplicity of the new {block} tags.
Each of these solutions does not look as clear and simple as the ability to define 2 conditional statements around the <div> tags as I posted above. It is possible that I don't understand well the whole idea behind inheritance, because it doesn't seem to improve or simplify code in my case. Perhaps there is yet another, better and simpler solution that I haven't thought of? |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Apr 27, 2010 1:10 am Post subject: |
|
|
What I mean is:
Quote: | I want any of the <div> sections to be rendered only when their corresponding named block was defined in the child template. |
A parent template depending on something in the child template is not inheritance. The parent should not care what the child does with the inherited content.
A good purpose for inheritance is where you have content present in all pages (header, footer, etc.) and you want to add/alter just parts of the page. The parent defines the alter-able areas with blocks.
Maybe what you should do is put the <div> content inside the block, and require all child templates to present the block elements, even if it is just to remove them. |
|
Back to top |
|
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Tue Apr 27, 2010 6:23 am Post subject: |
|
|
mohrt wrote: | What I mean is:
Quote: | I want any of the <div> sections to be rendered only when their corresponding named block was defined in the child template. |
A parent template depending on something in the child template is not inheritance. The parent should not care what the child does with the inherited content.
A good purpose for inheritance is where you have content present in all pages (header, footer, etc.) and you want to add/alter just parts of the page. The parent defines the alter-able areas with blocks.
Maybe what you should do is put the <div> content inside the block, and require all child templates to present the block elements, even if it is just to remove them. |
Thanks for the explanation, I need to get some experience in using inheritance to be more comfortable with it. In smarty 2 I used simple includes and for exceptional pages like the gallery in this example I would simply pass an additional variable via the include to the header ("parent") template and the header template would act differently based on the variable. Using inheritance a different approach is needed. I will use the <div> tags in the child templates then, it seems most logical.
BTW, is string syntax without quotes safe to use:
Code: | {block name=content} |
Smarty has no problem with it as long as the string has no special characters. Are you planning on removing this feature in the future or is it safe to use it? |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Apr 27, 2010 1:40 pm Post subject: |
|
|
It should be safe so long as the string is just a-zA-Z_
And yes inheritance is a much different approach than {include} header and footer files. Quite liberating actually. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Apr 27, 2010 5:07 pm Post subject: |
|
|
Another thing I forgot, you can nest blocks. So something like this parent:
Code: | {block name="div"}
<div id="content">
{block name="content"}
default content
{/block}
</div>
{/block} |
And your child template:
Code: | {block name="content"}foobar{/block} <-- will be wrapped in <div> tags |
OR
Code: | {block name="div"}{/block} <-- make everything empty |
|
|
Back to top |
|
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Tue Apr 27, 2010 6:09 pm Post subject: |
|
|
mohrt wrote: | Another thing I forgot, you can nest blocks. |
Wow, that makes a lot of difference, I haven't thought of that! I'll play with nested blocks but I already see they should be the best solution for this specific problem. Thanks! |
|
Back to top |
|
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Tue Apr 27, 2010 6:25 pm Post subject: |
|
|
BTW, isn't is about time to start putting together documentation about the new features and concepts? Even if it were in some form of a growing wiki. Less people would need to ask questions in this forum, for example the readme doesn't mention nested blocks and there are some new features which are unknown to a new user. To my mind, smarty 3 is ready to be used in production, I would consider it in RC state at the moment. But I am hesitant to use features not covered in readme. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Tue Apr 27, 2010 7:18 pm Post subject: |
|
|
Yes a lot needs to be done yet. Documentation has been started. Next release will be RC1 I'm pretty confident. |
|
Back to top |
|
wrygiel Smarty n00b
Joined: 18 Dec 2014 Posts: 1
|
Posted: Thu Dec 18, 2014 6:18 pm Post subject: |
|
|
Fortunately, this seems to be working correctly:
Code: | {capture assign='content'}{block 'content'}{/block}{/capture}
{if $content}
<div id="content">
{$content}
</div>
{/if}
|
|
|
Back to top |
|
claassen Smarty n00b
Joined: 09 Oct 2013 Posts: 3
|
Posted: Tue Oct 10, 2017 2:38 pm Post subject: |
|
|
This is exactly what the hide flag is for:
parent.tpl
Code: | {block name="content" hide}
<div id="content">
{$smarty.block.child}
</div>
{/block}
|
child_with_content.tpl
Code: | {extends file="parent.tpl"}
{block name="content"}
Child specific content
{/block}
|
child_without_content.tpl
Code: | {extends file="parent.tpl"}
{* No {block} here *}
|
|
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Wed Oct 11, 2017 11:31 am Post subject: |
|
|
claassen wrote: | This is exactly what the hide flag is for: |
Documentation says "Option Flags (in child templates only):".
I guess that's the source of confusion. |
|
Back to top |
|
|