Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Proposed changes to new {block} tag and use of {assignment}

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests
View previous topic :: View next topic  
Author Message
zimboden
Smarty Rookie


Joined: 10 Feb 2010
Posts: 19

PostPosted: Fri Feb 19, 2010 9:59 pm    Post subject: Proposed changes to new {block} tag and use of {assignment} Reply with quote

Proposal

Rethink the implementation of {blocks} to make them more flexible and powerful while maintaining the paradigm of parent/child inheritance.

Currently the Smarty {block} tags have acheived parity with Django's. However, the implementation could be more flexible and dynamic while still remaining intuitive.
More flexibility would include:

1) allow the reference to block tags elsewhere in the template without redeclaring them.
2) allowing variable creation within a block context
3) allow assignment to capture blocks of text like {capture}
4) Ability to create "generic" child blocks which can intelligently replace selected portions of the parent block.

I think that the tags $smarty.block.parent and $smarty.block.child, as well as the ability to nest blocks goes a long way towards making template inheritance in Smarty competitive with other template inheritance schemes, but I am proposing increased functionality to make Smarty template inheritance the best template inheritance available.

Here are the proposed changes:


1) Allow for the arbitrary referencing of block objects (and their assigned variables) as:
Code:

$smarty.block.blockname(the entire rendered block) or $smarty.block.blockname.variablename

Include a relational reference as well from within a block tag:
Code:

$smarty.block.parent.variablename, $smarty.block.child.variablename


Block references within other blocks could create circularity, but block variable references should not.

2) Allow for specialized behavior of the {assign} tag within the block context to assign variables available only within the chain of block inheritance.

parent.tpl
Code:

{block name="content"}
{assign var='id' value='pretty_div' /}
{/block}


child.tpl
Code:

{extends file='parent.tpl'}
{block name="content"}
Some text around parent's assigned variable
{$block.parent.id}
{/block}



3) Assigned variables would be accessible only with their block or withing related blocks by the block dot operator:
Code:

$block.parent.variablename, $block.child.variablename.



4) Allow for the arbitrary reference of variables created by {assign} within blocks by the expression: $block.blockname.variablename, regardless of whether the variable reference is within a block of the same name or not in a block at all:

parent.tpl
Code:

{block name="content"}
{assign var='id' value='pretty_div' /}
{/block}


child.tpl
Code:

{extends file='parent.tpl'}
{block name="differentblockname"}
{$block.content.id}
{/block}


<h3> {$block.content.id}</h3>
Here the reference is not within a block at all.



5) Allow {assign} to become wrapper tag around content to capture (like {capture} tag):
Code:

{assign var="name"}
Some content to assign to the variable name.
{/assign}


6) Keep single-tag {assign} but self-close {assign var="name" value="somecontent" /}

7) Replace or keep existing {$smarty.block.parent}. Proposed functionality of assign would effectively replace their use.


Annotated example of the new assignment functionality:

parent.tpl
Code:


1.{block name="div"}
2.   {assign var='id' value='pretty_div' /}
3.   {assign var="divcontents" /}
4.      {block name="textarea"}
5.         {assign var='contents' value=$contents /}
6.         {assign var='id' value='form_element_title' /}
7.         {$block.div.preamble}{$block.child.childcontents}
      {/block}
   {/assign}
   
{/block}


child.tpl
Code:

1.{extends file='parent.tpl'}
2.{block name="textarea"}
3.   <textarea id={$block.parent.id}>
4.      {$block.parent.contents}
   </textarea>
5.   {assign var="childcontents"}
      Here are some child contents that need to go to parent
   {/assign}
{/block}

6.{block name="div"}
7.   {assign var='preamble' value='$block.textarea.id' scope="global" /}
8.   <div id="{$block.parent.id}">
9.      {$block.parent.divcontents}
   </div>
{/block}
{/block}


parent.tpl
1. outer block tag. See order of evaluation below.
2. self-closing {assign} tag gets assigned to enclosing block: $block.div.id = "pretty_div"
3. {assign} captures block of text. Note carefully (see evaluation order below) that we first evaluate all assignments from inner-nested block tags to outer ones. We are assigning a * block reference* to a variable here. The final value of this block will not be resolved until the block itself is evaluated.
4. declare a block object with name "textarea"
5. assign $block.textarea.contents to a variable created from php or arbitrary smarty template variable. We always evaluate these variables first.
6. simple assignment to $block.textarea.id
7. reference to variable assigned child of the outer nested block, followed by a reference to a variable declared (or overwritten) in the matching child block.

child.tpl
1. we create parent/child relationship between files
2. we create a block object
3. static text with reference to variable declared in parent block
4. reference to variable declared in parent block
5. variable assignment to $block.textarea.childcontents
6. new block object
7. Throwing a curve ball here. Variable assignment with another block's variable.
8. reference to variable declared in parent block
9. reference to variable declared in parent block



Possible Evaluation Order:

I know these things aren't easy. Before making this proposal, I tried to think through the order of declaration/evaluation to see if it was non-circular.




create block objects and chains
--------------------------------
parent:div -> child:div
parent:textarea -> child:textarea




evaluate each block object's assignments first parent, then child
------------------------------------------------
parent:div
--------------
id = "pretty_div"
divcontents &= parent:textarea

child:div
-----------
preamble &= block.textarea.id (not yet defined)


parent:textarea
---------------
contents = $contents(non-block variable)
id = 'form_element_title'

child:textarea
-------------
childcontents = "Here are some..."

Any clashing assignments to same variable name: child assignment overrides parent's.




Process block replacement
------------------------------------------------
Start with innermost block in parent file closest to child (we only have one level here)

parent:textarea
------------------
$contents 'form_element_title' &= block.textarea.id = 'form_element_title'

child:textarea
------------------
<textarea id={$block.parent.id}>
{$block.parent.contents}
</textarea>

resolves to:

<textarea id='form_element_title'>
$contents
</textarea>

$contents above resolves to it's value "some value"

child replaces parent, so parent.textarea becomes:


<textarea id='form_element_title'>
"some value"
</textarea>



Next outermost block in parent file is parent:div

parent:div
---------------
No content. This block only contained assignments.

child.div
-----------------
<div id="{$block.parent.id}">
{$block.parent.divcontents}
</div>

resolves to:

<div id="pretty_div">
&parent:textarea
</div>

resolves to our final HTML output:

*********************

<div id="pretty_div">
<textarea id='form_element_title'>
"some value"
</textarea>
</div>

*********************

Notice what happened in the intential mistake above in the parent:textarea block: we referenced some assign values, {$block.div.preamble}{$block.child.childcontents}, but they were overriden by the child block. If we wanted to keep them we would have just not assigned childcontents, but kept the static text in the child block.
Back to top
View user's profile Send private message
mohrt
Administrator


Joined: 16 Apr 2003
Posts: 7368
Location: Lincoln Nebraska, USA

PostPosted: Fri Feb 19, 2010 10:21 pm    Post subject: Reply with quote

Thanks for the input. Instead of just throwing out new ideas for template inheritance, I'd like to see use-cases for each proposed feature. It may be that a lot of these features are unnecessary, or there could be a better way to approach a certain problem.
Back to top
View user's profile Send private message Visit poster's website
zimboden
Smarty Rookie


Joined: 10 Feb 2010
Posts: 19

PostPosted: Sat Feb 20, 2010 1:18 am    Post subject: Reply with quote

Yes, you're absolutely right. I will put together use cases next week. Thanks for your consideration.

Again, not knocking all the hard work you put into {blocks}. I just keep running into situations where I have to do what feels like work-arounds. Like you said, maybe my approach needs improvement and not Smarty Confused
Back to top
View user's profile Send private message
EdgyEft
Smarty n00b


Joined: 19 Sep 2006
Posts: 4

PostPosted: Mon Apr 12, 2010 1:47 pm    Post subject: Reply with quote

Hi,

I've another (quite simple) feature request.


The parent block should also accept prepend or append attribute, which then propagates this default to the child tags.

For example: When I have a parent template with
...
<title>{block name='title'}Title of My Site{/block}</title>
...

And a bunch of child templates
with
{block name='title' append} :: Title Of Page{/block} the append is required in each and every child page and it will be eventually be forgotten by someone.

So my proposal is to have
<title>{block name='title' append}Title of My Site{/block}</title>

and all child templates can do
{block name='title'} :: Title Of Page{/block}

if one child template wants to override the default it should be able to do so with
{block name='title' replace}Title Of Page{/block}
or
{block name='title' prepend}Title Of Page :: {/block}


Maybe an extra optional parameter no-override on parent blocks so child blocks cant override prepend/append/replace..., but a I don't see a real use case here...
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Feature Requests All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP