Howto generate json with smarty?
Asked Answered
U

7

21

In Smarty, is there a standard function or an easy way to generate json from an array, as json_encode() does in php?

I could not see it in Smarty documentation, wanted to ask here.

Unbosom answered 16/8, 2009 at 22:37 Comment(2)
Smarty is translated into PHP after all... so why not save a step, right ? :)Christiachristian
@Al, comment flagged, requirements are set by companies we work for, not by mere mortals like us. and dealing with comments like yours is worse than those requirements. cheers.Unbosom
V
94

Now deprecated

This should work. The @ makes smarty run the modifier against the whole array, otherwise it does it for each element.

{$myarray|@json_encode}

If $escape_html is enabled, you will need to use nofilter:

{$myarray|@json_encode nofilter}
Vortex answered 15/9, 2009 at 12:1 Comment(6)
I didn't know about the @ modifier! This answered the question.Seen
As a note, to pass args you need the numerical value. Ie, JSON_UNESCAPED_SLASHES is 64. So, {$myarray|@json_encode:64 nofilter} would leave slashes un-escaped. https://mcmap.net/q/658464/-json_encode-expects-parameter-2-to-be-long-string-givenDisarming
This is now deprecated with smarty 4.3.4Albrecht
@Albrecht Care to share with us what has replaced it? I could not find this in the documentation.Columbite
Unfortunately, nofilter doesn't escape apostrophes/single quotes, or double quotes, so for me it still produces invalid JSON.Columbite
@DaveMunger, looking at my code, I simply registered it myself: $smarty->registerPlugin('modifier', 'json_encode', function($json) { return json_encode($json, JSON_THROW_ON_ERROR); });Albrecht
C
11

While {$myarray|@json_encode} does in fact emit the array encoded in json, it also escapes special characters, making the array unusable in javascript.

To avoid escaping special characters and also be able to use the array in javascript use the nofilter flag:

{$myarray|@json_encode nofilter}
Charlottetown answered 25/4, 2014 at 19:4 Comment(1)
This only applies if your Smarty class has $escape_html set to true. I mean, it SHOULD be if you're doing it right, but still.Transpontine
P
6

You have to use json_encode() in your php code then assign the value to smarty using $smarty->assign() function. After that you have to parse that value in your template file using javascript.

code snippet:

{literal}
<script>
var json = JSON.parse('{/literal}{$your_json_encoded_array}{literal}');
//another statement
</script>
{/literal}
Polite answered 21/2, 2011 at 6:49 Comment(0)
W
2

While {$myarray|@json_encode nofilter} will work, there is a security hole here since we are doing variable escaping. Variable escaping (via nofilter) is highly discouraged because malicious code can be displayed and executed easily.

There is another approach to consider, using the 'javascript' escaping and replacing '&quot;' with ":

{literal}const my_javascript_array = JSON.parse(`{/literal}{json_encode($myarray)|escape:'javascript'}{literal}`.replaceAll('&quot;', '"'));

It is a bit convoluted, but you will thank yourself down the line for learning this trick :)

Wallin answered 21/7, 2021 at 15:14 Comment(0)
G
1
{literal}
<script type="text/javascript">
<!--
var newVar ={/literal}{$myarray|@json_encode nofilter};{literal}
// -->
</script>
{/literal}

My solution

Grisly answered 19/3, 2018 at 7:6 Comment(0)
A
1

Now with smarty 4.3.4, the @json_encode build in modifier is deprecated. You'll need to write your own modifier:

$smarty->registerPlugin('modifier', 'json_encode', function($json) {
   return json_encode($json, JSON_THROW_ON_ERROR);
});

Then you can use it in the template:

<script type="text/javascript">
  // we are setting some variables

  // nofilter disables html entity escaping
  var variables = {$variables|json_encode nofilter}; 
</script>
<!-- if you need to write the json_encoded string as html data attribute add |escape:'html' : -->
<script type="text/javascript" data-userinfo="{$variables|json_encode|escape:'html'}" src="..."></script>

Albrecht answered 8/11, 2023 at 0:6 Comment(0)
C
0

I don't know of any. You could assign the json_encode()'s result to a smarty variable in your 'php code' with $smarty->assign( ... ), and then use it in your template.

Also there is a Smarty extension for json_decode(). It shouldn't be hard to write your own extension for the opposite based on this.

Christiachristian answered 16/8, 2009 at 22:50 Comment(1)
I thought there would be a way like {$var|json_encode}, Thanks anyways.Unbosom

© 2022 - 2024 — McMap. All rights reserved.