Re: [SMARTY-DEV] Integrating Smarty with Content Management System, questions and design issues (long posting)
| From: | Monte Ohrt | Date: | Wed, 20 Nov 2002 14:53:11 +0000 |
| Subject: | Re: [SMARTY-DEV] Integrating Smarty with Content Management System, questions and design issues (long posting) | ||
| References: | 1 | Groups: | php.smarty.dev |
| Request: | Send a blank email to php-smarty-dev+get-338@lists.php.net to get a copy of this message | ||
On Tue, 2002-11-19 at 17:26, Matthias Pigulla wrote:
> Hello everyone,
>
> I am involved in the development of a PHP based content management system.
> We have already got a stable engine for merging content and design at
> runtime and do some caching of the results. However, our templates still
> require some PHP coding experience, maybe even too tricky for (coding
> unexperienced) web designers >:).
>
> Thus, we chose to integrate a template engine which can be extended to fit
> our needs and which requires no PHP coding in the templates at all. Of
> course, this implies that we have to be able to hide our API calls in some
> custom tags.
>
> Currently, I am trying to make a feasibility study on integrating Smarty
> with our system. I have played around quite a bit now and have some
> questions. Maybe you have had similar problems and would like to share your
> experiences, solutions or workarounds.
>
> Should we find that Smarty is our best option, we would of course contribute
> our modifications or extensions to the project.
>
> 1. Template "inheritance"
>
> By now, we've implemented templates as PHP classes. Basically, there's a
> base class (lets say, "Template") which provides a "draw" method, which, in
> turn, calls methods like $this->head(), $this->navigation(),
> $this->mainContent()... Each of these is responsible for outputting a
> certain part of the page, however, this subdivision is completely up to you.
>
> This allows you to subclass your base template to override a specific part
> of your pages. Say you would like to change your navigation style, just
> subclass your base template and override the navigation() method. You just
> have to implement the "different" parts with no unnecessary code
> replication.
>
> Do you see any good way to implement such behavior with Smarty? We could
> have different templates for the default implementation of different parts
> (head, navigation, ...) and glue these together with the include directive.
> However, each of your templates would have to include these subtemplates in
> the appropriate place; you also could not simply add a new part by adding a
> method to the base class and calling it from the draw() method. Instead, you
> would have to change _all_ templates and add the "new" include directive.
> (Including the "new" part from an already included default file breaks for
> templates overriding this default file!)
You can probably still use something similar to your procedure, each
method would call its respective template. So $this->head() would
execute $smarty->display('head');
If you want one call to display() so your cache files are all together,
you could create an init.tpl file that loops through the templates you
want displayed like so:
$this->draw(array('head.tpl','main.tpl','foot.tpl'));
...
function draw ($templates) {
...
$smarty->assign('templates',$templates);
$smarty->display('init.tpl', $my_cache_id);
}
...
init.tpl
--------
{foreach from=$templates item=curr_tpl}
{include file=$curr_tpl}
{/foreach}
>
> 2. Applying modifiers on (custom) functions
>
> We would need to implement some custom functions for encapsulating our API
> calls in Smarty tags. Lets assume we have a custom "tag" used as follows:
>
> <h1>{cmscontent field="title"}</h1>
> <p>{cmscontent field="bodytext"}</p>
>
> Now I'd like to give the designer the ability to use Smarty modifiers.
> However, this is not possible with functions. This would require a change of
> the parsing process (I assume in _compile_tag in Smarty_Compiler around line
> 236), as {myfunc|modifier} is interpreted as a custom function
> "myfunc|modifier" and {myfunc | modifier} is interpreted as a function
> myfunc with (invalid) arguments. Even more difficult, modifiers are
> functions and are supposed to take their input as argument and return it
> modified; custom functions are required to write out their output at
> runtime. So I do not see a (direct) way to make this work.
>
> The problem is that some of the API calls are quite expensive, so I do not
> want to get everything in advance and assign it to template vars. A
> workaround would be something like
> ...{assigncmscontent field="title" var="vtitle"}{$vtitle|upper}, i. e. make
> the function assign a variable and use this later on. I consider this kind
> of cumbersome.
>
> Any ideas on this? Maybe I misunderstood something and should not use a
> custom function for this task?
What does cmscontent function do, just retrieve your variable? Can you
assign the content to the template, then access them like
{$cmscontent.title} {$cmscontent.bodytext|mymod} ?
>
> 3. (Custom) block functions with block code depending on their result
>
> As far as I can see, the current implementation of custom block functions
> does not allow your block function to set up variables that can be used at
> run time from within the block code.
>
> I would like to hide some kind of "iterator" concept from our API inside the
> block function, e. g.
> <ul>{iteratenavigation rootid="123" mode="preorder"
> var="navelement"}
> <li>{$navelement.text}</li>
> <!-- or even -->{cmscontent var=$navelement field="text"}
> {/iteratenavigation}</ul>
>
> The problem is that the code inside the block and its variables are
> evaluated first and the output is passed to the block function at runtime,
> so that there is no way of assigning variables in the block function and
> using them in the block. There is another posting related to this:
>
> http://marc.theaimsgroup.com/?l=smarty-general&m=103729427302672&w=29
>
> What was the design motivation for this?
Not sure, Andrei?
>
> I would like to insert code at the compile phase, that is replacing the
> block tags with code which is executed the same time the block content is
> interpreted. This way we could encapsulate iterating in the block functions,
> not only looping over or processing already-evaluated code.
>
> I presume I would have to subclass Smarty_Compiler, as it cannot (does not)
> map a {foo}...{/foo} pattern to compiler functions. However, as the compiler
> function interface is inappropriate anyway, the (better?) idea is to replace
> _compile_block_tag and make changes in the last few lines, i. e. do not
> write out the code to execute the block function at runtime, but instead
> call the block function at compile time and have it insert real do/while
> constructs into the compiled template.
>
> Of course, this might break compatibility? Where? Any solutions, ideas?
>
> [Glad to see you're still with me :)] Maybe I was not always clear enough
> with my thoughts or have uttered stupid thoughts? However, let me know, as I
> would be happy with every reply I get :) Btw, the line numbers I gave may be
> incorrect, as I just saw that there's a new release.
>
> Thanks in advance,
> Matthias
--
Monte Ohrt <monte@ispi.net>