Given this Go text/template code:
Let's say:
{{ if eq .Foo "foo" }}
Hello, StackOverflow!
{{ else if eq .Foo "bar" }}
Hello, World!
{{ end }}
We get the following output in case Foo equals "foo":
Let's say:
Hello, StackOverflow!
(followed by a newline)
Is there a way to get rid of the extra newlines?
I would expect that this can be accomplished using the {{- and -}} syntax:
Let's say:
{{- if eq .Foo "foo" }}
Hello, StackOverflow!
{{- else if eq .Foo "bar" }}
Hello, World!
{{- end }}
However, that yields an illegal number syntax: "-" error.
In your first template, you have a newline after the static text "Let's say:", and the 2nd line contains only the {{if}} action, and it also contains a newline, and its body "Hello, StackOverflow!" starts in the 3rd line. If this is rendered, there will be 2 newlines between the 2 static texts, so you'll see an empty line (as you posted).
You may use {{- if... to get rid of the first newline, so when rendered, only 1 newline gets to the output, resulting in 2 different lines but no newlines between them:
Let's say:
{{- if eq .Foo "foo" }}
Hello, StackOverflow!
{{- else if eq .Foo "bar" }}
Hello, World!
{{- end }}
Output when Foo is "foo":
Let's say:
Hello, StackOverflow!
Output when Foo is "bar":
Let's say:
Hello, World!
Try it on the Go Playground.
Note that this was added in Go 1.6: Template, and is documented at text/template: Text and Spaces.
If you use the - sign at the closing of the actions -}}, you can even remove all the newlines:
Let's say:
{{- if eq .Foo "foo" -}}
Hello, StackOverflow!
{{- else if eq .Foo "bar" -}}
Hello, World!
{{- end -}}
Output when Foo is "foo" and Foo is "bar":
Let's say:Hello, StackOverflow!
Let's say:Hello, World!
Try this one on the Go Playground.
There is a new line because you're adding a new line after colons (:)
This works https://play.golang.org/p/k4lazGhE-r
Note I just start the first if right after the first colons
Related
I am trying to get the differences between two files with the following awk script:
awk 'NR==FNR{
a[$0]
next
}
{
if($0 in a)
delete a[$0]
else
a[$0]
}
END {
for(i in a) {
$0=i
sub(/[^.]*$/,substr(tolower($1),1,length($1)-1),$3)
print
}
}' [ab].yaml
The a.yaml file:
NAME_VAR: {{ .Data.data.name_var }}
SOME_VALUE: {{ .Data.data.some_value }}
ONE_MORE: {{ .Data.data.one_more }}
and the b.yaml file:
NAME_VAR: {{ .Data.data.name_var }}
SOME_VALUE: {{ .Data.data. }}
ONE_MORE: {{ .Data.data. }}
ADD_THIS: {{ .Data.data. }}
the script should merge the differences and replace what is contained in the curly brackets.
Something like this:
ADD_THIS: {{ .Data.data.add_this }}
SOME_VALUE: {{ .Data.data.some_value }}
ONE_MORE: {{ .Data.data.one_more }}
But it duplicates my output:
ADD_THIS: {{ .Data.data.add_this }}
SOME_VALUE: {{ .Data.data.some_value }}
ONE_MORE: {{ .Data.data.one_more }}
SOME_VALUE: {{ .Data.data.some_value }}
ONE_MORE: {{ .Data.data.one_more }}
the script should replace everything contained in the braces if there are new variables.
Assumptions:
the data component will always be one of .Data.data.<some_string> or .Data.data.
Taking a slightly different approach:
awk '
NR==FNR { a[$1]=$3
next
}
$1 in a { if ($3 == a[$1]) { # if $1 is an index of a[] and $3 is an exact match then ...
delete a[$1] # delete the a[] entry (ie, these 2 rows are identical so discard both)
}
else
if (length($3) > length(a[$1])) # if $1 is an index of a[] but $3 does not match, and $3 is longer then ...
a[$1]=$3 # update a[] with the new/longer entry
next # skip to next input line
}
{ a[$1]=$3 } # if we get here then $1 has not been seen before so add to a[]
END { for (i in a) { # loop throug indices
val=a[i] # make copy of value
sub(/[^.]*$/,tolower(i),val) # strip off everything coming after the last period and add the lowercase of our index
sub(/:$/,"",val) # strip the ":" off the end of the index
print i,"{{",val,"}}" # print our new output
}
}
' [ab].yaml
This generates:
SOME_VALUE: {{ .Data.data.some_value }}
ADD_THIS: {{ .Data.data.add_this }}
ONE_MORE: {{ .Data.data.one_more }}
NOTE: if the output needs to be re-ordered then it's like easier to pipe the results to the appropriate sort command
As for why OP's current code prints duplicate lines ...
Modify the END{...} block like such:
END { for (i in a)
print i,a[i]
}
This should show the code saves the inputs from both files but since no effort is made to match 'duplicates' (via a matching $1) the result is that both sets of inputs (now modified to look identical) are printed to stdout.
I have a Ansible line that fails linting:
tags: "{{ deployment_id | resource_tags('asg', base_resource_tags, deployment=deployment_id, deployment_env=deployment_env, deployment_name=deployment_name, purpose=deployment_purpose_tag, cpu_utilization=deployment_cpu_utilization_tag, disk_io_class=deployment_disk_io_tag, prom_exporters=deployment_prom_exporter_tags) | asg_tag_list }}"
How do I make this pass linting?
You need to use YAML Folding Scalars, > without quotes. Then add 'block chomping' 'strip'docs indicator to remove the trailing newline. The below example will work correctly, with each newline translating to a space. Adding quotes will break it e.g.
tags: >-
{{ deployment_id | resource_tags('asg', base_resource_tags, deployment=deployment_id,
deployment_env=deployment_env, deployment_name=deployment_name, Purpose=deployment_purpose_tag,
cpu_utilization=deployment_cpu_utilization_tag, disk_io_class=deployment_disk_io_tag,
prom_exporters=deployment_prom_exporter_tags) | asg_tag_list }}
I have this helm template for secret object:
...
data:
{{- range $key, $val := fromYaml .Values.secretmap }}
{{- $type := printf "%T" $val }}
{{ $key }}: {{ if eq $type "float64"}}{{ printf "%.0f" $val | b64enc | quote }}{{ else }}{{ $val | b64enc | quote }}{{ end }}
{{- end }}
kind: Secret
...
And I load it as follows:
helm template --set-file secretmap="secretmap.yaml"
I create the secretmap.yaml from env var like so:
env | sed -n "s/^K8S_SECRET_\(.*\)$/\1/p" | sed s/=/': '/ \ >secretmap.yaml
The problem is with multiline values.
When I set a multi-line pem key as env var, only the first line inserted to the secretmap.yaml.
How can I load multi-line env var correctly to a yaml so helm could create a secret of it?
I'd reach for a more powerful tool than a shell script to write out the secretmap.yaml file.
The Helm template itself looks fine. Assuming the content is valid YAML, it will echo it out, base64 encoding each value. You'd be happier if every node in the YAML were a string so you didn't have to reinterpret it based on a dynamic type lookup.
So the actual problem is generating the YAML file. You can take advantage of the fact that (a) YAML tries hard to make all valid JSON be valid YAML, and (b) almost every programming language includes JSON support in its standard library. (Or you can use Helm's fromJson function too.) Here's a minimal Python script that could write it out for you, in place of your sed command:
#!/usr/bin/env python3
import json
import os
PREFIX = 'K8S_SECRET_'
result = {}
for k in os.environ.keys():
if k.startswith(PREFIX):
kk = k[len(PREFIX):]
v = os.environ[k]
result[kk] = v
print(json.dumps(result))
Or, a denser one-liner based on jq
jq -n 'env | with_entries(select(.key | startswith("K8S_SECRET_")) | .key |= ltrimstr("K8S_SECRET_"))'
If the environment variables have newlines embedded in them, it's almost impossible to process this reliably with basic shell tools. As a minimal example try (bash/zsh specific syntax)
K8S_SECRET_FOO=$'bar\nK8S_SECRET_BAZ=quux' env
You want just one variable, but with the embedded newline, env will print this in a way indistinguishable from two separate variables.
For example, there is a function like that:
func TestFunc(str string) string {
return strings.Trim(str," ")
}
It runs in the example below:
{{ $var := printf "%s%s" "x" "y" }}
{{ TestFunc $var }}
Is there anyway to concatenate strings with operators in template ?
{{ $var := "y" }}
{{ TestFunc "x" + $var }}
or
{{ $var := "y" }}
{{ TestFunc "x" + {$var} }}
It gives unexpected "+" in operand error.
I couldnt find it in documentation (https://golang.org/pkg/text/template/)
There is not a way to concatenate strings with an operator because Go templates do not have operators.
Use the printf function as shown in the question or combine the calls in a single template expression:
{{ TestFunc (printf "%s%s" "x" "y") }}
If you always need to concatenate strings for the TestFunc argument, then write TestFunc to handle the concatenation:
func TestFunc(strs ...string) string {
return strings.Trim(strings.Join(strs, ""), " ")
}
{{ TestFunc "x" $var }}
In the laravel framework we can use blade to add PHP code in html file.
We are using both {{ }} and {{{ }}} syntax in blade files of Laravel.
What is the difference between them?
i have a code in a blade file like this
{{{ $errors->has('slider') ? 'has-error' : '' }}}
Before Laravel 5:
{{{ $var }}} escapes the contents of $var
{{ $var }} echoes $var unescaped
Since Laravel 5:
{{ $var }} AND {{{ $var }}} escape the contents of $var
{!! $var !!} echoes $var unescaped
There is no difference between {{ }} and {{{ }}} in Laravel 5 at all.
In version 4 it included the following two styles: “{{” and “{{{“. The double
curly bracket was a raw echo and the triple curly bracket escaped.
Currently in 5.0 both the double and triple curly brackets escape the
variable and a new “{!! $var !!}” is for raw.
https://laravel-news.com/2014/09/laravel-5-0-blade-changes/
{{{ renders HTML data but {{ shows data and elements without rendering.
ex :
$str = "<h3>Hello world!</h3>";
{{ $str }} output : <h3>Hello world!</h3>
{{{ $str }}} output : Hello world!
In Laravel 4 {{{ $var }}} is used to render data by escaping HTML entities that uses PHP htmlentities function to prevent XSS attacks.
{{ $var }} is used to render data without escaping HTML entities.
In Laravel 5 it slightly different you can use either {{ $var }} or {{{ $var }}} to escape data and to render unescaped data you can use {!! $var !!}.
Something I don't see mentioned here but which can be handy to know. If you have a translation text with a parameter that should become a Vue variable in the resulting html then the triple curly braces come in handy.
E.g.:
{{{ __('This window will close in :timeout seconds', ['timeout' => '#{{timeoutSecs}}']) }}}
Attempting this with any other combination of curly braces will throw some error.