When creating a Go template, you can give it a name, like in this example, "my_home_template":
var tmplHome = template.Must(template.New("my_home_template").Funcs(funcMap).ParseFiles("templates/base.tmpl", "templates/content_home.tmpl"))
How can I get that template name and use it inside the actual template file?
Ultimately I just want to define a convenient css class, like so:
<body class="my_home_template">
Here's a working solution, taking mkopriva's advice:
When executing a template, pass some custom parameter with dummy data. Here, I just create a "PageHome" parameter to pass to the template, and value is a simple "1", but it could be any value:
tmplHome.ExecuteTemplate(w, "base", map[string]interface{}{"PageHome": "1", "Data": events, "UserFirstName": &u.FirstName, "UserProfilePic": &u.ProfilePic})
Then, inside the template itself, a simple if statement to check if the parameter exists, and do something accordingly:
{{ if .PageHome }}
<body class="PageHome">
{{ else }}
<body>
{{ end }}
All my other template executions don't pass a "PageHome" parameter at all, so the if statement never passes as true for them.
There's probably a more advanced solution using a functions via a template function map, and having a consistent "PageType":"something" parameter in all template executions, but in the end you still have to define a parameter per template execution and still have to build up if statements in your templates anyways.
Related
I have a problem with a Jinja2 template I'm writing (called from Ansible).
The resultant file is a JSON file that I will send to an API (either with Ansible URI module or with curl). The template looks like this and basically works:
{
"description" : "my description",
"pipeline": "{% include 'root/pipeline.j2' %}"
}
The problem is that the content of root/pipeline.j2 is quite complex and includes multiple lines, quote characters and any number of other things that make the json file I'm creating invalid. What I want to do is parse the included file through a filter to convert it to a JSON valid string; something like this:
{
"description" : "my description",
"pipeline": "{% include 'root/pipeline.j2' | to_json %}"
}
But that doesn't work, probably because the filter is acting on the filename, not the included content.
Just for a little clarity when I create the template at the moment I see pipeline gets set to something like this:
"pipeline": "input {
"input1" {
<snipped>
"
It should appear thus:
"pipeline": "input {\n \"input1\" {<snipped>"
NB: I'm only giving the first couple of lines and I am using 'snipped' where I have remove the rest of the config.
Can anyone tell me how I can use an include within a jinja2 template that renders the result as a single line valid json string?
Thanks in advance for any assistance.
I finally managed to find a solution to my own question. Within the template that provides the JSON that is an API payload I am now setting a variable to the content of the pipeline template, which makes it easy to filter it with to_json:
{% set pipeline = lookup('template', 'root/pipeline.j2') %}
{
"description" : "my description",
"pipeline": {{ pipeline | to_json }}
}
I will leave this quesiton answer open for a while in case anyone can supply a better answer or explain why this is not a good one.
Thanks.
I am using datatables for a table in Slim 3 and am trying to link to another page. I can do a link using path_for and "hard code" the variable I want to send, but don't know how to send a variable from datatables.
This is the old code i was using
return '<a href=edit.php?trnum=' + full.trnum + '>Edit or Review</a>';
And this is the slim code I'm using inside twig
return '<a href={{ path_for('edit', {'trannum' : 123}) }}>Edit or Review</a>';
I need to replace the '123' with full.trnum. Everything I try sends the literal string. How do I escape the {{ }} in order to send this variable?
Thats not that easy and beautiful to archieve, because the {{ }} stuff will get parsed by twig, which is on serverside and the full.trnum is (as far as I see) JavaScript, therefore gets executed on clientside.
You could set a placeholder in the path_for-method and then later replace this with the actual value.
Similar to this:
var urlWithPlaceholder = '{{ path_for('edit', {trannum: '%trannum%'}) }}';
var url = urlWithPlaceholder.replace('%trannum%', full.trnum);
return 'Edit or Review';
I am experimenting with Go's templates.
I am curious: is it possible to do the following: {{$myVariable := randomStringFunc | saveFunc}}
Where:
$myVariable - randomly chosen variable name
randomStringFunc - function that generates random strings
TRICKY: saveFunc - a function that saves the variable name and its value
I have looked into capture-or-assign-golang-template-output-to-variable but I am not sure how and if it can help me achieve my goal.
EDIT
In the end I would like to have a mapping between the variable name that is defined in the template and the value that is assigned to it:
var variableMapping map[string]string
After template execution the content of variableMapping should be something like:
{
"$myVariable:"randomString1",
"$anotherVariable":"5",
"$thirdVariableInMyTemplate":"false"
}
One simple thing:
I want to combine the {s name="*"} and {link file="*"} blocks.
src="{link file='{s name='sFooterPaymentsIcon'}{/s}'}"
The problems should be the
'
signs.
How can I do that?
You can try assign a new variable and pass that on file parameter, like:
{assign var="my_file" value="{s name='sFooterPaymentsIcon'}{/s}"}
and then
src="{link file="$my_file"}"
You can do it this way:
//Assign snippet value to variable $snippetLink, in case variable is empty - assign LinkInCaseSnippetEmpty
{assign var='snippetLink' value='LinkInCaseSnippetEmpty'|snippet:'TheNameOfSnippet':"Namespace/If/Need"}
//assign source from variable $snippetLink
src="{link file=$my_file}"
In one line:
src="{link file='LinkInCaseSnippetEmpty'|snippet:'TheNameOfSnippet':'Namespace/If/Need'}"
{s} is for for text-snippets and should not be used for configuration-variables. If you need to make an include configurable, you should create a plugin for that.
The plugin should have a frontend-subscriber and make the file-include configurable via backend configuration-form. In the subscriber you can pass the configuration-value for the file-include to the frontend-view.
In my template, I would like to include some default meta tags (90% of the time). However, when a specific property is set, I would like to show a different set of text.
I know I can set an anonymous struct and set a property with either "default" or "some-x". However, this means, I need to add an anonymous struct to 90% of my handlers that just currently pass nil.
Is there way to do something like
{{if eq . nil}}
// default meta tag
{{else if eq .MetaValue "some-x"}}
//other
{{end}}
If I try something like my above code, it compiles but doesn't do what I want. Appreciate any suggestions on how to handle it properly without adding a lot of boiler plate.
Thanks!
{{if not .}}
output when . is nil or otherwise empty including
false, 0, and any array, slice, map, or string of length zero
{{else if eq .MetaValue "some-x"}}
// some-x case
{{else}}
// other case
{{end}}
If you want to ensure you're only checking against nil and not 0, false, the empty string, or any other falsey type, you can use the kindIs function to accomplish this.
{{ if kindIs "invalid" . }}
// only if variable is literally nil. falsey values will fallthrough.
{{ else if eq .MetaValue "some-x" }}
// other
{{ else }}
// final case, if any
{{ end }}
I've been recently facing an issue with identifying nil vs 0 values in a Helm Chart (which uses Go templates, including sprig) and haven't found any solutions posted, so I thought I'd add mine here.
I came up with a kind of ugly solution which is to quote the value and then check for a string that matches "<nil>" (with quotes, so you'd actually be checking (quote .Values.thing | eq "\"<nil>\"")). This allows differentiating tests against empty values vs defined 0 values. In my case, I was trying to build a config file where some default options were non-0, so when 0 was explicitly set, I wanted to know that 0 was set instead of just omitted.
Hopefully this can be a help to someone else.
It would be nice to have a better way to do this, but so far I haven't found anything that doesn't require creating and adding my own template functions.