Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.
Namespaces support

 
Post new topic   Reply to topic    Smarty Forum Index -> Smarty 3
View previous topic :: View next topic  
Author Message
saboya
Smarty Rookie


Joined: 24 Jun 2010
Posts: 6

PostPosted: Thu Jun 24, 2010 4:08 pm    Post subject: Namespaces support Reply with quote

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
View user's profile Send private message
saboya
Smarty Rookie


Joined: 24 Jun 2010
Posts: 6

PostPosted: Thu Jun 24, 2010 4:17 pm    Post subject: Reply with quote

Another post so I can post a link...
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 4509
Location: Hamburg / Germany

PostPosted: Thu Jun 24, 2010 8:38 pm    Post subject: Reply with quote

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
Code:
{foo::method()}


This modification is in the SVN now.
Back to top
View user's profile Send private message
saboya
Smarty Rookie


Joined: 24 Jun 2010
Posts: 6

PostPosted: Thu Jun 24, 2010 8:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Thu Jun 24, 2010 9:50 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
saboya
Smarty Rookie


Joined: 24 Jun 2010
Posts: 6

PostPosted: Thu Jun 24, 2010 10:21 pm    Post subject: Reply with quote

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
View user's profile Send private message
Michael White
Smarty Rookie


Joined: 08 Oct 2009
Posts: 20

PostPosted: Sun Apr 03, 2011 5:43 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Lemon Juice
Smarty Pro


Joined: 24 May 2006
Posts: 105

PostPosted: Tue Apr 05, 2011 6:59 am    Post subject: Reply with quote

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
View user's profile Send private message
dlcsoftwaresolutions
Smarty n00b


Joined: 24 Jan 2012
Posts: 1

PostPosted: Tue Jan 24, 2012 5:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
SlowFox
Smarty Regular


Joined: 02 Oct 2006
Posts: 42

PostPosted: Sun Dec 23, 2012 5:09 pm    Post subject: Reply with quote

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
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 4509
Location: Hamburg / Germany

PostPosted: Sun Dec 23, 2012 7:21 pm    Post subject: Reply with quote

Namespace will be supported in template syntax with the upcomming major version 3.2
Back to top
View user's profile Send private message
SlowFox
Smarty Regular


Joined: 02 Oct 2006
Posts: 42

PostPosted: Sun Dec 23, 2012 11:23 pm    Post subject: Reply with quote

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
View user's profile Send private message
rudder
Smarty Rookie


Joined: 20 Oct 2009
Posts: 10

PostPosted: Mon Mar 18, 2013 11:57 pm    Post subject: Reply with quote

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
View user's profile Send private message
rjkip
Smarty n00b


Joined: 29 Jul 2013
Posts: 1

PostPosted: Mon Jul 29, 2013 11:21 am    Post subject: Reply with quote

Another solution would be to use the constant() PHP function as a modifier:

Code:

{"Your\Class::CONSTANT"|constant}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    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