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

Cascading template directories + including parent?

 
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 -> Smarty 3
View previous topic :: View next topic  
Author Message
fidian
Smarty Rookie


Joined: 12 Jul 2010
Posts: 10

PostPosted: Mon Jul 12, 2010 8:36 pm    Post subject: Cascading template directories + including parent? Reply with quote

I understand I can set template_dirs to an array of directories to scan. Let's assume I set it to look in AAA, BBB, then CCC. In my various directories, I have the following:

CCC/template.html
This is my {$source|default:"CCC"} template.

Now, I can use {include file="template.html"} and it will scan AAA (finding nothing), BBB (again, nothing), and succeed with finding CCC/template.html. This is great, and really helps me out.

In our situation, we have various directories cascade based on what web site we are viewing. By default, we stick generic templates further up the tree, like in the CCC directory. Sometimes we want to override a single variable or a little bit of functionality in AAA or BBB. Ideally, I would like to use things like this:

BBB/template.html
{include file="parent:template.html" source="BBB"}

I know this doesn't work, but I would like for the BBB template to set the $source variable and then include the next template that is found in template_dirs. We could also have AAA override template.html like this:

AAA/template.html
I do not call my parent. This is only for {$source|default:"AAA"} and it's (non-existent) children.

Does anyone know how I could achieve something like this? Is there a plugin somewhere, or would anyone know of a good spot where I could hook code in to accomplish this?

-- edit: fixed last template thing, then fixed the first template


Last edited by fidian on Mon Jul 12, 2010 10:18 pm; edited 2 times in total
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Mon Jul 12, 2010 9:11 pm    Post subject: Reply with quote

I didn't follow all that Smile but you may want to look into Smarty 3 template inheritance. It may help you cascade your template changes in a much more elegant manner.
Back to top
View user's profile Send private message Visit poster's website
fidian
Smarty Rookie


Joined: 12 Jul 2010
Posts: 10

PostPosted: Mon Jul 12, 2010 10:57 pm    Post subject: Reply with quote

Sorry for not explaining my problem clearly - I've also fixed the example templates above. Basically, I want to override templates, which is completely solved by having an array for template_dir. My next issue is where I want to partially override a template without needing to have a differently named template. It's a little hard to explain and I apologize for not being able to do it well.

Let's say I have those three web sites for clients CCC, BBB, and AAA. We want BBB to look a lot like CCC, and AAA should look a lot like BBB. The template directories for the different clients are shown as below. We'll assume that the directory 'CCC' is the correct path for the templates for client CCC.

Client CCC (the top parent):
$template_dirs = array('CCC');

Client BBB (override some of CCC's templates):
$template_dirs = array('BBB', 'CCC');

Client AAA (override some of AAA's templates):
$template_dirs = array('AAA', 'BBB', 'CCC');

This is all built with common code that knows about the various clients and who they "extend". Also, in this common code, it will do something like $smarty->display('template.html'); If we are in the CCC client, it should display CCC/template.html. If we are in BBB, it will look for and display BBB/template.html; falling back to CCC/template.html when the BBB template is not there.

What I really want to do is to pass parameters to a parent template, but leave most of the templates alone in the parent. Let's say I have a template that starts the HTML of a web page. One of its parameters is $js, which is a space delimited list of additional JavaScript files that need to be loaded. So, now I have my template file called CCC/html_start.html:

Code:

<html><head><title>{$title|default:"CCC Site"}</title>
{$js=$js|trim}
{$js=' '|explode:$js}
{foreach $js as $jsFile}
    <script language="JavaScript" src="$jsFile"></script>
{/foreach}
</head><body>


For this example, let's also say that CCC/template.html looks like this.

Code:

{include file="page_start.html" title="Spiffy Page"}
<p>Lots and lots of content go here.  Many things that will be frequently
updated.  We only want one copy for ease of maintenance.</p>
{include file="page_end.html"}


When I say $smarty->display('template.html') for client AAA, Smarty will not find AAA/template.html nor BBB/template.html, but will find CCC/template.html and write out the HTML header, page content, and footer. Client AAA wants the title changed and a JavaScript file added. I could move the content from template.html into template_content.html and then copy the dumbed-down version of CCC/template.html to AAA/template.html and change the first line:

Code:

{include file="page_start.html" title="AAA Page" js="my_file.js"}
{include file="template_content.html"}
{include file="page_end.html"}


Now I can $smarty->display('template.html') and have it work as desired in both AAA and CCC.

But, a week or two later, BBB changes their templates and makes a fancy UI element and now needs more JavaScript whenever their element is shown. The tricky part is that AAA will also need to get this JavaScript added as well, since they are using the pretty widget by default. I could now copy CCC/template.html to BBB/template.html, modify them, and then also modify AAA/template.html to include the new file.

The three-child scenario here is a bit limited. I could have an arbitrary number of children, and children can be moved around to new parents (up or down the chain) as it seems appropriate. The JavaScript files that need to be included will also change as the children get moved.

My whole problem would be eliminated if I could just include the parent's template. For instance, if I had AAA/template.html and it could add to the $js variable:

Code:

{include_my_parent_template js="my_file.js $js"}


And now BBB/template.html

Code:

{include_my_parent_template js="bbb_tricky_widget $js"}


This way it is the same filename for any client, plus all children could inherit and pass variables to parent templates in order for the child's UI tweaks to work.

I had looked at the template inheritance, but I would need to have different names for all of the children or something odd to achieve the ultimate goal of allowing a child to include its parent's template by continuing the scan through the template_dir array. It would give me the flexibility I need so I can arbitrarily swap AAA's and BBB's order and have the inclusion of the parent template work.
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Mon Jul 12, 2010 11:50 pm    Post subject: Reply with quote

Template inheritance is a completely different thought process than the tradition include header/footer approach. But, it is highly efficient and easy to maintain. So for example, we first assemble a "base" template that is the default for any situation:

base.tpl:

Code:
<html>
  <head>
      <title>my title</title>
  </head>
  <body>
       my body
  </body>
</html>


Now, we decide what elements in the page are changeable, and we surround those with block elements:

Code:
<html>
  <head>
      <title>{block name="title"}my title{/block}</title>
  </head>
  <body>
       {block name="body"}my body{/block}
  </body>
</html>



And now, we can use this base.tpl as a basis and only deal with the content that is changed:

client.tpl:

Code:
{extends file="base.tpl"}
{block name="title"}Client Title{/block}
{block name="body"}Client Body{/block}


That is the basics. You can see how clients can re-use the bulk of the code, and replace just the blocks they want to. You can also daisy-chain the inheritance, and make things as granular as you like. The beauty you don't need to deal with separate includes for headers/footers, etc. You just inherit a single template and replace the bits and pieces (blocks.) You can always add blocks to parent templates to make things as flexible as you like. I would suggest this approach.


Alternately, you could create a custom template resource, and make it pick up templates however you wish.
Back to top
View user's profile Send private message Visit poster's website
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 -> Smarty 3 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