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

Escaping AngularJS variables in smarty3?

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


Joined: 12 Oct 2003
Posts: 13

PostPosted: Wed Nov 26, 2014 11:49 am    Post subject: Escaping AngularJS variables in smarty3? Reply with quote

Hi all,

smarty will process this: "{$somevar}" > smarty
smarty will not process: " { $somevar } " > javascript (native)

BUT I NEED SMARTY TO IGNORE {{ }} too so that I have:
smarty will process this: "{{$somevar}}" > smarty
smarty will not process: " {{ $somevar }} " > javascript (angularjs)

Can anyone help with this. The simple solution would be to go into the Smarty code itself and somehow add double curly to act the same as single curly braces.

*********************
AN EXAMPLE OF ALL THREE IN SAME HTML TEMPLATE THAT SHOULD WORK:

<div ng-app="">
{$smarty.get.id}
<div ng-controller="MyCtrl" onclick="function() { alert 'clicked'; } "> {{ hi }} </div>
</div>


LEGEND:
smarty - I left NO spaces left and right from { and } > WORKS, SMARTY!
javascript - I left spaces left and right from { and } > WORKS, JAVASCRIPT!
angularjs - I left spaces left and right from {{ and }} > DOES NOT WORK, ANGULARJS!!
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Wed Nov 26, 2014 12:23 pm    Post subject: Reply with quote

That's alot of problem you're trying to create for yourself.
Don't do that.
Back to top
View user's profile Send private message
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Wed Nov 26, 2014 1:24 pm    Post subject: Reply with quote

Thanks for reply.

I will use AngularJS a lot on my new project, Smarty will serve static pages and AngularJS will provide additional layer of functionality, so I really need this to make work without changing smarty or angularjs delimiters.

I assume that Smarty users will use AngularJS, we waited a long time to have JS escaped automatically, and maybe there is an easy way to overcome this.
Back to top
View user's profile Send private message
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Wed Nov 26, 2014 1:33 pm    Post subject: Reply with quote

In file: /libs/sysplugins/smarty_internal_templatelexer.php

I can see here a lot of functions defined for "auto_literal" configuration option, so I must add here those double curly braces.

Here is the part of code I think could solve this:
$yy_global_pattern = "/
\G(\\{\\})|
\G(" . $this->ldel . "\\*([\S\s]*?)\\*" . $this->rdel . ")|
\G(" . $this->ldel . "\\s*strip\\s*" . $this->rdel . ")|
\G(" . $this->ldel . "\\s*\/strip\\s*" . $this->rdel . ")|
\G(" . $this->ldel . "\\s*literal\\s*" . $this->rdel . ")|
\G(" . $this->ldel . "\\s*(if|elseif|else if|while)\\s+)|
\G(" . $this->ldel . "\\s*for\\s+)|
\G(" . $this->ldel . "\\s*foreach(?![^\s]))|
\G(" . $this->ldel . "\\s*setfilter\\s+)|
\G(" . $this->ldel . "\\s*\/)|
\G(" . $this->ldel . "\\s*)|
\G((<script\\s+language\\s*=\\s*[\"']?\\s*php\\s*[\"']?\\s*>)|(<\\?(?:php\\w+|=|[a-zA-Z]+)?))|
\G(\\?>)|
\G(<\/script>)|
\G(\\s*" . $this->rdel . ")|
\G(<%)|
\G(%>)|
\G([\S\s])/iS";
Back to top
View user's profile Send private message
U.Tews
Administrator


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

PostPosted: Wed Nov 26, 2014 9:48 pm    Post subject: Reply with quote

See http://www.smarty.net/docs/en/language.escaping.tpl
Example 3.9.

You can set the Smarty delimiters to whatever you want.
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Thu Nov 27, 2014 3:04 am    Post subject: Reply with quote

You could change the smarty delimiters, but that might not be a valid choice either. Another plausible workaround would be to make a prefilter that translates {{ into %AJSL% and }} to %AJSR%, (or anything unique) then a post filter that translates them back again. Then during the compile step they won't get touched.
Back to top
View user's profile Send private message Visit poster's website
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Thu Nov 27, 2014 8:15 am    Post subject: Reply with quote

Thank you Mohrt for great idea!

Here is the solution, for others to use:

1. create in plugins directory: prefilter.angularjsescape.php

Code:
function smarty_prefilter_angularjsescape($source, Smarty_Internal_Template $smarty)
{
   $source = str_replace('{{', '%AJSL%', $source);
   $source = str_replace('}}', '%AJSR%', $source);
   return $source;
}



2. create in plugins directory: postfilter.angularjsescape.php

Code:
function smarty_postfilter_angularjsescape($source, Smarty_Internal_Template $template)
{
   $source = str_replace('%AJSL%', '{{', $source);
   $source = str_replace('%AJSR%', '}}', $source);
   return $source;
}



3. in your php file put this line before $smarty->display('....') line

Code:
$smarty->autoload_filters = array('pre' => array('angularjsescape'),'post' => array('angularjsescape'));




Now you can use angularjs within php smarty template without any worries.

Smarty now renders these as they were in template, will not hang smarty during parsing:
{{somevar}}
{{ somevar }}

ps. you do not have to leave space left or right from curly braces at all.


Last edited by kalinicm on Mon Dec 08, 2014 9:04 am; edited 2 times in total
Back to top
View user's profile Send private message
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Thu Nov 27, 2014 8:16 am    Post subject: Reply with quote

QUESTION:

Is there a way not to use:
Code:
$smarty->autoload_filters = array('pre' => array('angularjsescape'),'post' => array('angularjsescape'));


Can smarty automatically include those two files in plugins directory?
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Thu Nov 27, 2014 2:23 pm    Post subject: Reply with quote

You could add them to autoload_filters, see the manual.

Also, you should be able to use str_replace instead of preg_replace, it is much more efficient for simple string replacement.
Back to top
View user's profile Send private message Visit poster's website
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Fri Nov 28, 2014 7:22 am    Post subject: Reply with quote

Corrected to STR_REPLACE. Thanks.

Will add. Thank you all!
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Fri Nov 28, 2014 2:47 pm    Post subject: Reply with quote

kalinicm wrote:
Corrected to STR_REPLACE. Thanks.

Will add. Thank you all!



You need to fix your code examples above:

Code:
$source = str_replace('/{{/U', '%AJSL%', $source);


to

Code:
$source = str_replace('{{', '%AJSL%', $source);


they are still preg syntax.
Back to top
View user's profile Send private message Visit poster's website
kalinicm
Smarty Rookie


Joined: 12 Oct 2003
Posts: 13

PostPosted: Mon Dec 08, 2014 9:04 am    Post subject: Reply with quote

Thanks Mohrt.

Corrected the post.
Back to top
View user's profile Send private message
mohrt
Administrator


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

PostPosted: Tue Dec 09, 2014 3:41 pm    Post subject: Reply with quote

kalinicm wrote:
QUESTION:

Is there a way not to use:
Code:
$smarty->autoload_filters = array('pre' => array('angularjsescape'),'post' => array('angularjsescape'));


Can smarty automatically include those two files in plugins directory?


To answer this question, you must place them in autoload_filters() if you want them used on every invocation of smarty. Filters won't get automatically picked up just by existing in the plugins dir.
Back to top
View user's profile Send private message Visit poster's website
anandejju
Smarty n00b


Joined: 19 Feb 2016
Posts: 1

PostPosted: Fri Feb 19, 2016 11:34 pm    Post subject: Smarty vs Angularjs delimiter conflict Reply with quote

Hi instead of changing smarty standard delimeter, you can change angular js delimeter.

Code:

var myApp = angular.module('myApp', [], function($interpolateProvider) {
    $interpolateProvider.startSymbol('[[');
    $interpolateProvider.endSymbol(']]');
});


[/code]
Back to top
View user's profile Send private message
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 -> General 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