View previous topic :: View next topic |
Author |
Message |
saboya Smarty Rookie
Joined: 24 Jun 2010 Posts: 6
|
Posted: Thu Jun 24, 2010 4:08 pm Post subject: Namespaces support |
|
|
I've written a patch to support namespaced static object access within Smarty3 templates. I never did any lexer/parser work, so it's certainly not the best approach to the problem and probably has unknown bugs, but it'll enable you to use namespaces until a proper patch is created.
Features:
- Accepts spaces between namespaces / class name.
- Works with preceding backslash too.
Known bugs:
- The parser will not catch multiple backslash errors, like Namespace\\Class. A non-valid PHP compiled template will be generated with a PHP parse error.
* THIS MAY DESTROY YOUR COMPUTER, USE IT AT YOUR OWN RISK *
Usage: Download the zip and extract it into the sysplugins folder.
Patch for the lexer / parser definition:
http://www.hypertel.com.br/ns_patch.diff
Generated Lexer / Parser:
http://www.hypertel.com.br/lexerparser.zip
Last edited by saboya on Thu Jun 24, 2010 4:29 pm; edited 5 times in total |
|
Back to top |
|
saboya Smarty Rookie
Joined: 24 Jun 2010 Posts: 6
|
Posted: Thu Jun 24, 2010 4:17 pm Post subject: |
|
|
Another post so I can post a link... |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Jun 24, 2010 8:38 pm Post subject: |
|
|
We have decided not to integrate namespace support into the template syntax. The goal of Smarty is to speparate the design as much as possible from the business logic. With namespace syntax we would more and more of business logic into the templates.
Instead ou can register a class with optional namespace for the use in the template like:
Code: | $smarty->register->templateClass('foo','name\name2\myclass'); |
And use it in the template
This modification is in the SVN now. |
|
Back to top |
|
saboya Smarty Rookie
Joined: 24 Jun 2010 Posts: 6
|
Posted: Thu Jun 24, 2010 8:47 pm Post subject: |
|
|
While I agree the use of static calls within templates does not fit the business / design separation, I think the possibility of it hapenning and the introduction of namespaces in 5.3 will make the use of this resource problematic, since class resolution is now context-sensitive. In a complete usage of 5.3 situation, all classes will be namespaced, and you'd have to register all the classes you'd like to use.
Anyway, I did the patch after I saw the other topic, mostly out of curiosity about lexers / parsers and Smart 3. |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Thu Jun 24, 2010 9:50 pm Post subject: |
|
|
The design principles behind Smarty are not just separating business logic from presentation logic. It is also about separating PHP from the templates. Back in the early days of Smarty we made a big mistake by introducing {php}{/php} tags. This made it easy to embed PHP directly into the templates. This opened the gates to poor programming practices, as embedding PHP defeats the purpose of the separation, and lends itself to nasty template code that is difficult to debug and maintain.
Allowing static PHP classes in templates goes down this very same path. Suddenly the templates are bound to all the PHP syntax and business logic under the hood.
By registering the classes, we maintain our separation and we have fine-grained control of template security.
So, much the same that PHP variables and objects are not directly available in the templates, static classes do apply. We have decided that a simple static class is implicitly permissible (except in secure mode) much the same that direct access to a php function is permissible. Anything more, and you must register them. This should help keep the template syntax minimal, and minimize poor developer practices of direct access to PHP code from within templates.
If you need access to static classes in-template, register them. You can control exactly how they are registered, and from in-template you don't need to bother with the namespace they may apply to on the business logic side. |
|
Back to top |
|
saboya Smarty Rookie
Joined: 24 Jun 2010 Posts: 6
|
Posted: Thu Jun 24, 2010 10:21 pm Post subject: |
|
|
I think it's great you're not encouraging this type of use, since it does make the business / design separation more fuzzy. But I think if you're going to have this option, namespaces should be supported, or it would be better to not have it al all.
Again, I'm not using this kind of syntax in any way, the patch was created out of curiosity. |
|
Back to top |
|
Michael White Smarty Rookie
Joined: 08 Oct 2009 Posts: 20
|
Posted: Sun Apr 03, 2011 5:43 pm Post subject: |
|
|
Namespaces will become more and more prevalent in PHP code. In essence, they are little more than a "grouping" mechanism for classes that is replacing the older workaround of a project name prefix on the classes.
Things like Zend_, and Doctrine_ come to mind.
While it is good to encourage good practice and discourage bad practice, I think it is very difficult to argue that not supporting namespaces is going to automatically force good coding habits.
For example, say your business logic layer uses namespaces itself and you have a large number of classes that is often growing or maybe is different per project. I would find it more difficult and cumbersome to maintain a proper class/namespace mapping registry than to just follow some simple rules for which classes I do or do not allow use of from the templates. Not only this, but without namespace support you force developers to learn/remember a second name/alias for every class that is available inside templates. It seems much more intuitive (and easier to debug) if the real class names are used in the templates.
I truly believe that it should be up to the developer to make the decisions about what kind of code goes where as there are exceptions to every rule and forcing certain rules just results in ugly hacks and workarounds which can cause even bigger problems than the lack of separation between business logic and display code. |
|
Back to top |
|
Lemon Juice Smarty Pro
Joined: 24 May 2006 Posts: 109
|
Posted: Tue Apr 05, 2011 6:59 am Post subject: |
|
|
I agree. While generally not recommended there are certain cases when using namespaces is convenient. It is up to the developer to decide whether to use namespaces or not - the same as whether to use static::methods(). The template syntax should not be limiting in this regard. |
|
Back to top |
|
dlcsoftwaresolutions Smarty n00b
Joined: 24 Jan 2012 Posts: 1
|
Posted: Tue Jan 24, 2012 5:47 pm Post subject: |
|
|
The suggested fix above does not work. I figured I would update this thread because when I Google around looking for a solution to using namespaced statics in smarty I end up here in this thread.
The correct, current (as of Rev 4542) solution is to assign the static to a smarty variable using the registerClass method as follows:
<?php
...
$smarty->registerClass("FOO","\Fully\Qualified\Name\Foo");
...
?>
<html>
...
{FOO::StaticMethod()}
...
</html>
From the manual: http://www.smarty.net/docs/en/api.register.class.tpl |
|
Back to top |
|
SlowFox Smarty Regular
Joined: 02 Oct 2006 Posts: 55
|
Posted: Sun Dec 23, 2012 5:09 pm Post subject: |
|
|
mohrt wrote: | Back in the early days of Smarty we made a big mistake by introducing {php}{/php} tags |
Agreed.
Quote: | Allowing static PHP classes in templates goes down this very same path. Suddenly the templates are bound to all the PHP syntax and business logic under the hood |
But namespaces cover more than only static classes. I use class constants quite a lot in template in order to take decisions upon certain values. This appears to me as quite natural for presentation logic, e.g.:
Code: | {if $phone->type == PhoneNumber::Private}
{elseif $phone->type == PhoneNumber::Office}
{/if} |
Now I am in the middle of changing a big project into using namespaces - and suddenly all my class constants are unavailable in Smarty as they would need to be written as e.g.:
Code: | {if $phone->type == \Communication\PhoneNumber::Private}
{elseif $phone->type == \Communication\PhoneNumber::Office}
{/if} |
Of course I can register all necessary classes, but in the end this would affect couples of dozens of classes just for this usage. Is this really desireable? |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Sun Dec 23, 2012 7:21 pm Post subject: |
|
|
Namespace will be supported in template syntax with the upcomming major version 3.2 |
|
Back to top |
|
SlowFox Smarty Regular
Joined: 02 Oct 2006 Posts: 55
|
Posted: Sun Dec 23, 2012 11:23 pm Post subject: |
|
|
U.Tews wrote: | Namespace will be supported in template syntax with the upcomming major version 3.2 |
Ok, that's good news. All I've read in the forum and in the trunk source was about registering individual classes, therefore my question.
Edit: and as the original patch is no longer available I created my own to continue working in the meantime. No guarantee for whatsoever, but it does its job for me.
Edit2: support for "instanceof" added
Code: |
Index: smarty_internal_templateparser.y
===================================================================
--- smarty_internal_templateparser.y (revision 4688)
+++ smarty_internal_templateparser.y (working copy)
@@ -652,7 +652,7 @@
res = '!(1 & '.e1.' / '.e2.')';
}
-expr(res) ::= value(v1) INSTANCEOF(i) ID(id). {
+expr(res) ::= value(v1) INSTANCEOF(i) class(id). {
res = v1.i.id;
}
@@ -750,8 +750,21 @@
res = s;
}
+ // namespaces
+class(res) ::= ID(n) BACKSLASH class(c). {
+ res = n.'\\'.c;
+}
+
+class(res) ::= BACKSLASH class(c). {
+ res = '\\'.c;
+}
+
+class(res) ::= ID(c). {
+ res = c;
+}
+
// static class access
-value(res) ::= ID(c) DOUBLECOLON static_class_access(r). {
+value(res) ::= class(c) DOUBLECOLON static_class_access(r). {
if (!$this->security || isset($this->smarty->registered_classes[c]) || $this->smarty->security_policy->isTrustedStaticClass(c, $this->compiler)) {
if (isset($this->smarty->registered_classes[c])) {
res = $this->smarty->registered_classes[c].'::'.r;
Index: smarty_internal_templatelexer.plex
===================================================================
--- smarty_internal_templatelexer.plex (revision 4688)
+++ smarty_internal_templatelexer.plex (working copy)
@@ -61,6 +61,7 @@
'ANDSYM' => '"&"',
'QMARK' => '"?"',
'ID' => 'identifier',
+ 'BACKSLASH' => '\\',
'TEXT' => 'text',
'FAKEPHPSTARTTAG' => 'Fake PHP start tag',
'PHPSTARTTAG' => 'PHP start tag',
@@ -145,6 +146,7 @@
constant = /([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])/
attr = /\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*=\s*/
id = /[0-9]*[a-zA-Z_]\w*/
+backslash = /\\/
literalstart = /SMARTYldel\s*literal\s*SMARTYrdel/
literalend = /SMARTYldel\s*\/literal\s*SMARTYrdel/
stripstart = /SMARTYldelstripSMARTYrdel/
@@ -572,6 +574,9 @@
id {
$this->token = Smarty_Internal_Templateparser::TP_ID;
}
+backslash {
+ $this->token = Smarty_Internal_Templateparser::TP_BACKSLASH;
+}
integer {
$this->token = Smarty_Internal_Templateparser::TP_INTEGER;
}
|
|
|
Back to top |
|
rudder Smarty Rookie
Joined: 20 Oct 2009 Posts: 14
|
Posted: Mon Mar 18, 2013 11:57 pm Post subject: |
|
|
Really glad to hear 3.2 will support Namespaces, in particular, the following are really important:
- Using namespaced class constants and static variables
- Accessing namespaced static class methods.
Pretty much we do exactly what SlowFox does.[/list] |
|
Back to top |
|
rjkip Smarty n00b
Joined: 29 Jul 2013 Posts: 1
|
Posted: Mon Jul 29, 2013 11:21 am Post subject: |
|
|
Another solution would be to use the constant() PHP function as a modifier:
Code: |
{"Your\Class::CONSTANT"|constant}
|
|
|
Back to top |
|
Micke Smarty n00b
Joined: 21 Oct 2014 Posts: 1
|
Posted: Tue Oct 21, 2014 7:10 pm Post subject: Release 3.2 |
|
|
Can someone tell when (aproximetly) we can expect release of 3.2 version with namespaces support? |
|
Back to top |
|
|