T0mcat
T0mcat

Reputation: 61

Groovy's StreamingTemplateEngine throws MissingPropertyException when rendering PHP template

in a Jenkins Pipeline we deploy a PHP site which has config files in PHP - format. Now we want to use the StreamingTemplateEngine for creating these config Files with different content (lets say different databases for dev- and prod stages). In PHP variables are prefixed with $ - signs which now collides with the $ - sign marked placeholders from the StreamingTemplateEngine. That means it throws an exception when reaching a PHP Variable, that should be left as it is.

I think an example makes it more clear:

Template File test.php.template:

<?php
$my_php_config_variable = "${StreamingTemplateEnginePlaceholder}"
?>

Groovy Code Snippet:

import groovy.text.StreamingTemplateEngine

def placeholders = [
    "StreamingTemplateEnginePlaceholder": "SOME_VALUE",
]
def templateContent = new File('test.php.template').text

def engine = new StreamingTemplateEngine()
def configContent = engine.createTemplate(templateContent).make(placeholders).toString()

println configContent

Now the resulting configContent string should be:

<?php
$my_php_config_variable = "SOME_VALUE"
?>

But the engine throws this Exception:

Exception in thread "main" groovy.text.TemplateExecutionException: Template execution error at line 2:
         1: <?php
     --> 2: $my_php_config_variable = "${StreamingTemplateEnginePlaceholder}"
         3: ?>

    at SimpleGroovyScript.run(SimpleGroovyScript.groovy:10)
    at SimpleGroovyScript.main(SimpleGroovyScript.groovy)
Caused by: groovy.lang.MissingPropertyException: No such property: my_php_config_variable for class: groovy.tmp.templates.StreamingTemplateScript1
    ... 2 more

saying, "$my_php_config_variable" is missing in the placeholder map.

Now our questions are:

1.) Can the PHP vars in the template somehow be marked to be left as is for the TemplateEngine?

OR

2.) Can the Engine somehow simply ignore "missing" placeholders in the placeholder map and leave the strings as is?

Thx in advance for every hint! T0mcat

Upvotes: 2

Views: 1327

Answers (1)

Szymon Stepniak
Szymon Stepniak

Reputation: 42224

You have to escape $ in your template:

<?php
\$my_php_config_variable = "${StreamingTemplateEnginePlaceholder}"
?>

If you want to use StreamingTemplateEngine to render this template you will have to update your code a little bit. StreamingTemplateEngine leaves escape characters in rendered output, so you will have to replace \$ with $ in the rendered template:

import groovy.text.StreamingTemplateEngine

def placeholders = [
  "StreamingTemplateEnginePlaceholder": "SOME_VALUE",
]
def templateContent = new File('test.php.template').text

def engine = new StreamingTemplateEngine()
def configContent = engine.createTemplate(templateContent)
    .make(placeholders)
    .toString()
    .replaceAll('\\\\\\\$', '\\\$')

println configContent

Output:

<?php
$my_php_config_variable = "SOME_VALUE"
?>

There is a bug report GROOVY-8701 documenting this issue. One of the future releases of Groovy 2.5.x should contain a fix for that so there is no replacing \$ with $ needed anymore.

Alternatively you can use GStringTemplateEngine - in this case no replacing escape character needed:

import groovy.text.GStringTemplateEngine

def placeholders = [
  "StreamingTemplateEnginePlaceholder": "SOME_VALUE",
]
def templateContent = new File('test.php.template').text

def engine = new GStringTemplateEngine()
def configContent = engine.createTemplate(templateContent)
    .make(placeholders)
    .toString()

println configContent

Output:

<?php
$my_php_config_variable = "SOME_VALUE"
?>

Upvotes: 1

Related Questions