|
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 |
mobbkopf Smarty n00b
Joined: 28 Mar 2006 Posts: 4
|
Posted: Tue Mar 28, 2006 1:26 pm Post subject: How to create objects dynamically |
|
|
Hi there,
a few days ago I found that I'd appreciate the idea of creating and using PHP objects from within my template, thus making the whole project more transparent. The main idea is that each PHP file the user calls "only" initializes the database connection and Smarty and displays the template the user wants to see. All other functions are template-independent and organized within classes; the single templates are able to "load" the classes they need, thus making the project scalable and service friendly.
So, first here's what I had to code:
Code: |
<?php
// /Smarty/plugins.compiler.use.php
function smarty_compiler_use($tag_attrs, &$compiler)
{
$_params = $compiler->_parse_attrs($tag_attrs);
if (!isset($_params['object'])) {
$compiler->_syntax_error("use: missing 'object' parameter", E_USER_WARNING);
return;
}
$_params['object'] = str_replace("'", "", $_params['object']);
$found = false;
foreach ($compiler->plugins_dir as $value)
if (!$found && file_exists($value . DIRECTORY_SEPARATOR . 'object.' . $_params['object'] . '.php'))
$found = $value;
if ($found === false) {
$compiler->_syntax_error("use: can't find file 'object." . $_params['object'] . ".php'", E_USER_WARNING);
return;
}
return "require_once('" . $found . DIRECTORY_SEPARATOR . "object." . $_params['object'] . ".php'); "
."$" . $_params['object'] . " = new " . $_params['object'] . "; "
."\$this->assign_by_ref('" . $_params['object'] . "', $" . $_params['object'] . "); ";
}
?>
|
That's all. Now I'm able to build templates this way:
Code: |
{use object="Terminkalender"}
{include file="_msgtable_open.tpl" title="Terminkalender"}
<table width="100%" cellspacing="10">
{foreach from=$Terminkalender->Termine item=termin}
<tr><td width="25%" align="center">{$termin.Von} - {$termin.Bis}:</td><td align="left">{$termin.Titel}</td></tr>
{foreachelse}
<tr><td colspan="2" align="center">Zur Zeit sind keine Termine eingetragen.</td></tr>
{/foreach}
</table>
{include file="_msgtable_close.tpl"}
|
This code snippet makes use from a calendar class to put all entries into a table. Be aware that you MUST 'assign_by_ref' the object if you want to loop through a class member this way!
Up to now, I'm fetching all my database result sets into class member arrays when using them with {foreach} or {section}. But I hope there's a better solution to come...
That's just my five cents. Neither it's the reinvention of the wheel nor it was my purpose to replace PEAR, but it's a small, light-weight solution that fulfills all my needs. I shared it because I thought in some cases it could be useful. Comments are welcome!
Best regards,
Patrick |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Tue Mar 28, 2006 6:34 pm Post subject: |
|
|
Hi.
Your method not-withstanding, I personally, I believe in a service layer (ie. a view) above the template. Views should fetch data, instantiate classes and what-not. Templates should not be aware of such details -- they should only know the allowable namespace of fields that they can place.
Now, how you implement that view space is up-to-you. You can certainly do it with another level of templates that then bind objects to rendering templates -- but I would tend to try to keep these concerns separated in some meaningful way.
Just my 2c. |
|
Back to top |
|
mobbkopf Smarty n00b
Joined: 28 Mar 2006 Posts: 4
|
Posted: Fri Mar 31, 2006 4:57 pm Post subject: |
|
|
Hi.
Maybe I should have told a bit more about the environmental conditions that made me coding this plugin.
First of all: My templates are NOT aware of the details happening in the background, like database queries and so on. The classes I instantiatie this way provide the api the template has access to, allowing the template designer to use only what he needs. He's neither able to execute SQL statements directly nor to access private class variables or functions.
So you like talking about layers better, I see? Okay, here we go: I made a "root" template for each page I wanted to show, including everything that you would refer to as "display logic", e. g. all {if} clauses, {foreach}s and so on. This template contains nearly no HTML code but only the "display logic", respectively the page main layout. Refer to these "root" templates as the view layer, if you like to. From these root templates I {include} the "real" templates each containing just a little piece of (HTML) code.
Maybe this solution fails if it comes to building sites containing 100+ pages, but on the club site (around 50 pages) I used this plugin on it works perfectly.
The main challenge within this project for me was to find an acceptable way to allow the webmaster (who is not into PHP) to change the pages easily. First I thought about introducing an XML based "page layout description file", but discarded this solution because of the huge effort it would have required to program an teach this new language to the webmaster.
I like this solution. With the {use object} directive, the template designer really opens the namespace he wants to work with.
Regards
Patrick |
|
Back to top |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Sat Apr 01, 2006 1:44 am Post subject: |
|
|
Ahh. Yes, a fuller explanation helps me see why you are doing that. I should say I didn't mean to disparage your technique but was interested in a fuller discussion of the implications.
Greetings! |
|
Back to top |
|
mobbkopf Smarty n00b
Joined: 28 Mar 2006 Posts: 4
|
Posted: Sat Apr 01, 2006 8:17 pm Post subject: |
|
|
Hi there,
sorry for causing that trouble Yes, I "abuse" Smarty this way because from my point of view there are only benefits I profit from.
The "root" template is also the place where I do ALL the link and GET/POST variable handling in order to keep the PHP code clean and independent from such things (nothing worse than declaring the used variable names in two or three places; ever debugged such a structure?). BTW, the PHP classes I use this way are Smarty independent also (check out the "Smarty Sample App" in the General Forum and you will understand what I'm talking about).
Best Regards
Patrick |
|
Back to top |
|
erstwh1le Smarty n00b
Joined: 27 Apr 2006 Posts: 1
|
Posted: Thu Apr 27, 2006 4:19 am Post subject: |
|
|
this might be a solution to an issue i was having which is:
can you make Smarty aware of what variables are being referenced in a template befor the template is rendered? The idea is that you could load a template, have Smarty pull all of the different content variables in the template, and the send those to a query generator which would generate an sql query on the fly, return the array of appropriate content, and then have Smarty render the template - allows arbitrary templates to be defined without having to make up a new sql query to fill it each time. |
|
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
|
|