2

I'm using Smarty and PHP. If I have a template (either as a file or as a string), is there some way to get smarty to parse that file/string and return an array with all the smarty variables in that template?

e.g.: I want something like this:

$mystring = "Hello {$name}. How are you on this fine {$dayofweek} morning";
$vars = $smarty->magically_parse( $string );
// $vars should now be array( "name", "dayofweek" );

The reason I want to do this is because I want users to be able to enter templates themselves and then fill them in at a later date. Hence I need to be able to get a list of the variables that are in this templates.

Let's assume that I'm only doing simple variables (e.g.: no "{$object.method}" or "{$varaible|function}"), and that I'm not including any other templates.

hakre
  • 193,403
  • 52
  • 435
  • 836
Amandasaurus
  • 58,203
  • 71
  • 188
  • 248

5 Answers5

4

If you need variables hidden in things like {if $var%2} I'd go with this kind of code :

preg_match_all('`{[^\\$]*\\$([a-zA-Z0-9]+)[^\\}]*}`', $string, $result);
$vars = $result[1];

If you also want to catch things like that : {if $var != $var2} a better version follows

function getSmartyVars($string){
  // regexp
  $fullPattern = '`{[^\\$]*\\$([a-zA-Z0-9]+)[^\\}]*}`';
  $separateVars = '`[^\\$]*\\$([a-zA-Z0-9]+)`';

  $smartyVars = array();
  // We start by extracting all the {} with var embedded
  if(!preg_match_all($fullPattern, $string, $results)){
    return $smartyVars;
  }
  // Then we extract all smarty variables
  foreach($results[0] AS $result){
    if(preg_match_all($separateVars, $result, $matches)){
      $smartyVars = array_merge($smartyVars, $matches[1]);
    }
  }
  return array_unique($smartyVars);
}
Arkh
  • 8,416
  • 40
  • 45
  • 2
    It should be noted, that its not wise to "parse" html, smarty or any other source code for that matter, with regular expressions. You will falsely catch variables that were comented out for example. Not everything we do has to be wise though. – enrey Oct 25 '13 at 14:10
3

It looks like there isn't an inbuilt way to do this.

Amandasaurus
  • 58,203
  • 71
  • 188
  • 248
  • From http://stackoverflow.com/questions/716916/print-all-variables-available-in-a-smarty-template // If no parameter is given, an array of all assigned variables are returned. $all_tpl_vars = $smarty->getTemplateVars(); – Lexib0y Nov 10 '15 at 08:08
2

Normally I'm against regular expressions, but this looks like a valid case to me. You could use preg_match_all() to do that (If you only want variables like ${this}):

preg_match_all('\{\$(.*?)\}', $string, $matches, PREG_PATTERN_ORDER);
$variableNames = $matches[1];
soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • 3
    Notes: (1) Smarty variables are {$var}, not ${var}. (2) `$matches` will be an array of arrays, so you will have to iterate over `$matches[0]` to access full matches. (3) It might be easier to capture the contents of `{` and `}` using parantheses, then accessing it using `$matches[1]` instead of using `substr()` on the full matches. – Ferdinand Beyer Oct 27 '09 at 10:27
  • You could just do $variableNames = $matches[1]; . If you want to loop over the result like you are doing, you need to use the PREG_SET_ORDER flag I think. – Tom Haigh Oct 27 '09 at 11:15
  • @Tom: Thx, it was PREG_PATTERN_ORDER, and reduced the code to two lines. – soulmerge Oct 27 '09 at 11:26
  • PREG_PATTERN_ORDER is the default, I meant that for your previous example to work you needed to specify PREG_SET_ORDER. But PREG_PATTERN_ORDER is better here – Tom Haigh Oct 27 '09 at 11:39
  • yeah that's what I was thinking of doing, I was just hoping that there would be an easy builtin smarty way of doing it. – Amandasaurus Oct 27 '09 at 11:41
  • @Rory: smarty does the processing in a single giant function, so the code for matching the variables is not isolated, but burrowed into that one. So my guess is that the function you are looking for does not exist. – soulmerge Oct 27 '09 at 12:04
1
{debug}

I realize this thread is old, but this is the built-in solution.

thomasrye
  • 41
  • 2
-1

I think what you're looking for is the debugging console.

This console shows you all variables used within the templates involved in your webpage.

Arno
  • 745
  • 4
  • 17