|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
cactustit Smarty n00b
Joined: 26 Sep 2020 Posts: 2
|
Posted: Sat Sep 26, 2020 12:13 pm Post subject: Include AND Extend - With Plugin Example |
|
|
Preface
Obviously it is possible to create a template that is an extension of another with {extends} and {block}
It is also possible to include templates within another with {include}
Issue
What is not possible, is to include a template, while also extending parts of the template you are including.
Why?
Some may feel this complicates inheritance. For me, its the ideal solution to display a single piece of content or a set of contents that is surrounded by a shared element.
My workaround function
PHP
I access my smarty class from a wrapped function, here you can see the plugin functions I have added
Code: |
class MySmarty extends Smarty {
function __construct() {
parent::__construct();
$this->registerPlugin('block','bit', array($this, 'bit'));
$this->registerPlugin('block','bit_block', array($this, 'bit_block'));
}
var $bit_blocks = array();
/**
* Similar to include, but can extend blocks within the template.
* Either use the bit block as is with content directly inside to apply to the "content" block of the template you are extending,
* or manually add bit_block blocks inside of the bit block to chose which blocks to specify what blocks to add content to.
*
*/
function bit($params, $content, Smarty_Internal_Template $template, &$repeat)
{
if ($repeat){
$this->bit_blocks[] = array();
}else{
$blocks = array_pop($this->bit_blocks);
if (empty($this->bit_blocks)){
$this->bit_blocks = array();
}
if (empty($blocks)){
$blocks = array('content' => array('content' => $content, 'options' => array()));
}
$string = $this->left_delimiter . 'extends file="'.$params['file'].'"'.$this->right_delimiter."\n";
foreach($blocks as $block => $contents){
$options = '';
if (!empty($contents['options'])){
$options = ' ' . implode(' ', $contents['options']);
}
$string .= $this->left_delimiter . 'block name="'.$block.'"'.$options.$this->right_delimiter. $contents['content'] . $this->left_delimiter . '/block '.$this->right_delimiter;
}
$bit = $this->fetch("string:$string");
return $bit;
}
}
function bit_block($params, $content, Smarty_Internal_Template $template, &$repeat)
{
// Get normal short hand options such as append by adding block_append=True in bit_block params (add block_ before the option and make it =True for workaround of not beng able to do shorthand)
// only output on the closing tag
if(!$repeat){
$bit_keys = array_keys($this->bit_blocks);
$options = array();
$name = $params['name'];
unset($params['name']);
foreach($params as $param_key => $param_val){
if ($param_val === True){
$options[] = substr($param_key, 6);
}
}
$this->bit_blocks[end($bit_keys)][$name] = array('content' => $content, 'options' => $options);
}
}
}
|
Template
This is an example of a template (child.tpl) that is extending another (parent.tpl), which also has a "bit" (bit.tpl). Hopefully also including an example of normal {exends} can better distinguish the feature I am trying to present here.
parent.tpl
Code: |
<html>
<head>
</head>
<body>
{block name="content"}
{/block}
</body>
</html>
|
bit.tpl
Code: |
<div class="panel">
<h2>{block name="title"}</h2>
<div class="content">
{block name="content"}
</div>
</div>
|
child.tpl <-- this is where the feature in question occurs
Code: |
{extends file="parent.tpl"}
{block name="content"}
{bit file="bit.tpl"}
{bit_block name="title"}
Title goes here
{/bit_block}
{bit_block name="content"}
Content goes here
{/bit_block}
{/bit}
{/block}
|
Expected result
Code: |
<html>
<head>
</head>
<body>
<div class="panel">
<h2>Title goes here</h2>
<div class="content">
Content goes here
</div>
</div>
</body>
</html>
|
Closing
If there is enough interest in this feature, I would love it to be incorporated into smarty directly. However, if not feel free to use or extend my simple plugin. I worry that its a bit hacky and maybe not optimal. If I had better knowledge of how smarty works I might make a proper block function that works similar to {block} and can include file without having to hack a string template. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon Sep 28, 2020 4:34 pm Post subject: |
|
|
There's no interest. Really.
{extends} supposed to be used to replace main (content) block on a page. Several blocks, if you wish, in different ways (prepend/append/replace).
{include} supposed to be used for shared/reusable content blocks.
What you want to achieve is trivially achieved with existing functionality, if you dare to learn how to use engine properly.
You create a layout page, then extend it with different content pages. Multiple times, if you wish (f.e. main site layout >> forum layout >> topics list/thread posts list/etc.). |
|
Back to top |
|
cactustit Smarty n00b
Joined: 26 Sep 2020 Posts: 2
|
Posted: Tue Sep 29, 2020 3:40 am Post subject: |
|
|
Thank you,
I am aware of what can be achieved with multiple levels of extension, and how in my example specifically it could easily be done a different way as I've only included one bit.
This is for situations where I want to include content only in certain situations , and only in said situations does the encapsulating elements show, which I understand can be achieved with the block hide options, but in the case of mutliple of this situation, It feels messy to make multiple blocks with slightly varied names and with the same surrounding content just incase they are used.
I understand that my desired feature has many workarounds to achieve similar results, but I just felt this is a missing piece.
My original intension was to post this in a place more where I can just show my plugin incase anyone wants to use it or extend it but I felt that's wrong because it's not a very good one so I decided instead to post here. If anything I just wanted to hear if anyone else has similar experience to me, notably with the desire to extend a template within another template, and realising that it's not possible. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Tue Sep 29, 2020 9:59 am Post subject: |
|
|
You can use {include} inside {block}. And {extends} multiple templates at once. |
|
Back to top |
|
|
|
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
|
|