Compare strings in templates - go-templates

I have the following template:
{{if . eq "login failed"}}
<span class="text-error">Incorrect username or password</span>
{{else if . eq "login success"}}
<span class="text-success">You have successfully logged in!</span>
{{end}}
I am passing a string when I execute the template.
However, I get the following error:
executing "login.html" at <.>: can't give argument to non-function .
How do I compare the strings within the template?

eq is function, not an operator. It is called with the form: eq <x> <y> (not <x> eq <y>).
You can fix your template by moving the operands from the the sides of eq to after it:
{{if eq . "login failed"}}
<span class="text-error">Incorrect username or password</span>
{{else if eq . "login success"}}
<span class="text-success">You have successfully logged in!</span>
{{end}}

To compare if two strings equal :
{{ if eq .Status "Approved" }}
...Do something
{{ else }}
...Do something else
{{ end }}
To compare if two strings not equal :
{{ if ne .Status "" }} // If status is not empty
...Do something
{{ else }}
...Do something else
{{ end }}
There are more golang HTML template directives here at : https://pkg.go.dev/text/template#hdr-Actions

Related

vuejs different v-ifs from a previous select

I am trying to display two different divs according to a select options, but I am only getting the first v-if. When I select "de", I do get the first div content, but I also get it when I select fr, instead of the second div.
I can't get my head around this. Any ideas of what I am getting wrong?
This goes on inside a form:
<select v-model="source" :key="source">
<option :value="de">de</option>
<option :value="fr">fr</option>
</select><br><br>
<div class="characters">
<div v-if="source === de" class="deChars" :key="source">
<h5>Special German characters:</h5>
<li v-for="character in deChars" :key="character">{{ character }}</li>
</div>
<div v-else-if="source === fr" class="frChars" :key="source">
<h5>Special French characters:</h5>
<li v-for="character in frChars" :key="character">{{ character }}</li>
</div>
<br>
</div>
on the script section I am using the options api with the data property source=" ", and two arrays for deChars and frChars.
note: those :key="source" I added to make sure it gets read when the source value changes.
The data properties:
data(){
return {
original: "",
translation: "",
source: "",
target: "en",
deChars: ["ä", "Ä", "é", "ö", "Ö", "ü", "Ü", "ß"],
frChars: ["à", "â", "ç", "é", "è", "ê", "ë", "î", "ï", "ô", "û", "ü", "œ"]
}
},
Thank you so much!
Try to remove the binding sign since it seems that de and fr are not declared as properties and they're just raw string :
<select v-model="source" >
<option value="de">de</option>
<option value="fr">fr</option>
</select>
then do v-if="source === 'de'" and v-else-if="source === 'fr'"
It seems that the problem was with the select options. THe binding seemed to mess about. Once I got rid of that, it works perfectly. So thanks for that Boussadjra. However, if on the v-if I change the de and fr to strings, it does not work. WHich is why I am adding this comment as the solution.

How can I conditionally set a variable in a Go template based on an expression which may cause an error if not wrapped with an if statement

Question
How do I do something like this:
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
where $.Env.CERT_NAME may be nil/undefined. If it is nil, it gives this error:
at <ne $.Env.CERT_NAME "">: error calling ne: invalid type for comparison
Note: I have no control over the objects passed in to the Go template so have to solve this entirely within the template itself.
What I've tried
I tried to work around by first checking to see if it is non-empty:
{{ $use_ssl := ( ($.Env.CERT_NAME) && (ne $.Env.CERT_NAME "") ) }}
but it gives this error:
unexpected "&" in operand
So I switched to this, which is allowed syntactically:
{{ $use_ssl := (and ($.Env.CERT_NAME) (ne $.Env.CERT_NAME "") ) }}
but then I lose the short-circuit evaluation that I would get with the && operator and I'm back to getting this error again:
at <ne $.Env.CERT_NAME ...>: error calling ne: invalid type for comparison
Okay, I thought, if I can't do it in a nice one-liner, and Go doesn't have a ternary operator, that's fine, I'll just do it the idiomatic Go way, which is apparently if/else.
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := (ne $.Env.CERT_NAME "") }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
But then of course I run into scoping issues, because if inexplicably (or at least annoyingly) creates a new variable scope (unlike in Ruby/ERB templates that I am more used to), so apparently I can't even do this:
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := true }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}
without getting this error now:
undefined variable "$use_ssl"
"No sweat", I thought. I'll just declare the variable in the outside scope so it will have the correct scope and the inner scope will still be able to change that variable (the one with the outer scope). (That's how it works in Ruby, by the way.)
Nope, apparently all that does is create 2 different variables with the same name but different scopes (how's that for confusing!):
{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
{{ $use_ssl := true }}
# $use_ssl: {{ $use_ssl }}
{{ else }}
{{ $use_ssl := false }}
{{ end }}
# $use_ssl: {{ $use_ssl }}
# $use_ssl: true
# $use_ssl: false
I've also tried inlining the if statement like this:
{{ $use_ssl := if $.Env.CERT_NAME { true } }}
but that gives this error:
unexpected <if> in command
Apparently if statements can't be used as expressions in Go like they can in Ruby?
I also get syntax errors if I try the various alternatives to the ternary operator suggested in What is the idiomatic Go equivalent of C's ternary operator?, like:
c := map[bool]int{true: 1, false: 0} [5 > 4]
And sure, you can read variables from outer scopes in inner scopes with $.something but how do you set $.something in the inner scope?
If not like that, then how??
So what have I missed? Is this even possible in a Go template?
Go templates (I'm new to them) seem very limiting. Almost everything you can do in Go itself is not possible in a template. But hopefully there is a workaround...
http://play.golang.org/p/SufZdsx-1v has a clever workaround involving creating a new object with {{$hasFemale := cell false}} and then setting a value with $hasFemale.Set true, but how can I do something like that without having access to the code that evaluates the template (where they are calling template.FuncMap)?
Others who have tried and failed
https://groups.google.com/forum/#!topic/golang-nuts/MUzNZ9dbHrg
This is the biggest (and only) problem I have with Go. I simply do not understand why this functionality has not been implemented yet.
When the template package is used in a generic context (eg. Executing
an arbitrary template file with an arbitrary json file), you might not
have the luxury of doing precalculations.
https://github.com/golang/go/issues/10608
This is probably as designed, but it would be really nice if there was a way to get the changed $v outside of the conditional.
This is the #1 template question we get over at Hugo (https://github.com/spf13/hugo). We have added a hack [$.Scratch.Set "v1" 123] to work around it for now ...
Currently working solution
If you update the scope rather than declare a variable, either by using set or by using merge you will be able to access it outside of the if clause.
{{- if eq .podKind "core" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.corePods.nodeAffinity.matchNodePurpose }}
{{- else if eq .podKind "user" -}}
{{- $dummy := set . "matchNodePurpose" .Values.scheduling.userPods.nodeAffinity.matchNodePurpose }}
{{- end -}}
# Will now output what you decided within an if/else if clause
{{- .matchNodePurpose }}
Future solution (Available with Helm 2.10)
I came across the same question in the context of Helm templates which are go templates with some additional features pre-installed such as Sprig.
28 March 2018, in this pr a Terenary operator was added to Sprig, and in time Helm will have them as well solving the issue both you and I have.
terenary
true | ternary "b" "c" will return "b"
false | ternary "b" "c" will return "c"
Your fourth try would work if you'd use the assignment operator instead of the definition operator:
{{ $use_ssl := false }}
{{ if $.Env.CERT_NAME }}
{{ $use_ssl = true }} # notice the missing colon!
{{ else }}
{{ $use_ssl = false }}
{{ end }}
I think I may have found a workaround for my particular problem, though I would love to hear other answers that solve the problem more generally.
Came across this line in https://github.com/jwilder/nginx-proxy/blob/1e0b930/nginx.tmpl#L91:
{{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
which gave me another idea to try. I guess the solution is to use a combination of or and set extra temporary variables...
{{ $cert_name := or $.Env.CERT_NAME "" }}
{{ $use_ssl := ne $cert_name "" }}

Check if value exists in vuejs

I have data : 1,2,3,4,4,5 & my code like this:
<div id="looping" v-for="display in editlistAssesments">
{{display.test_id}}
</div>
My code if in php such as like this
$temp_id = array();
foreach($data as $data){
if(in_array($data ->test_id,$temp_id)){
echo" 1: no";
echo" 2: no";
echo" 3: no";
echo" 4: yes"; //because he have same value
echo" 5: no";
$temp_id[] = $data ->test_id;
}
}
how I can do that in loop vueJs..??
From my point of view, the best way is:
<div id="looping"
v-for="display in editlistAssesments">
<span v-if="typeof display.test_id !== 'undefined'">
{{display.test_id}}
</span>
</div>
Because if you use v-if="display.test_id" and the test_id value is 0 (boolean comparation) you will never see the display.text_id.
You can use also this another condition to check if is null or undefined: display.test_id != null (loose equality operator)
As far as I understand, you want to check if value is in array and then render it accordingly?
If so, you need a Vue custom filter. Something like this will do the trick:
var vm = new Vue({
el: 'body',
data: {
editlistAssesments: [1,2,3,4,4,5]
},
filters: {
ifInArray: function (value) {
return this.editlistAssesments.indexOf(value) > -1 ? 'Yes' : 'No';
}
},
});
And then use it like this:
<div id="looping" v-for="display in editlistAssesments">
<span v-text="display.test_id | ifInArray"></span>
<!-- bind Vue value to html element is better practice -->
</div>
Check docs for more information:
http://vuejs.org/guide/custom-filter.html

search form error

I'm webdesigner and I touch NOTHING in development, so, I really need your help (exam in school). So, indeed, I've made a search form in the same page. There a field to search by town (ville) and the results should be appareate in a div. Sometimes it works, but I really need to fix that.
The error: Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in C:\Program Files (x86)\EasyPHP-5.3.8.1\www\foodsurfing\index.php on line 55
There is the code
<?php
require_once('Connections/foodsurfing.php');
if(isset($_GET['recherche']))
$requete="SELECT * FROM fiche_membres WHERE ville LIKE '%".$_GET['recherche']."%'
LIMIT 0 , 1 ";
else
$requete="SELECT * FROM fiche_membres
LIMIT 1 , 1 ";
mysql_query("SET NAMES UTF8");
$resultat=mysql_query($requete);
if (false === $resultat) {
echo mysql_error();
}
?>
and the result's div
<div id="gmap_result_container">
<div class="gmap_result">
<?php while($fiche_membres=mysql_fetch_array($resultat)) {?> <p>
<a class="prenom"><?php echo($fiche_membres['prenom']); ?></a>
<a> , </a>
<a class="ville"><?php echo($fiche_membres['ville']); ?></a></p>
<img src="images/avatar_unknown.jpg">
<p><?php echo($fiche_membres['experience_culinaire']); ?></p>
<p><img src="images/ensavoirplus.png" name="roll" border="0" alt="En savoir plus" align="middle" class="ensavoirplus"></p>
<?php }?>
</div>
</div>
Thank you so much for your help !!
Glad to be into the community I just discover as beginner !
Warning says that the resource is not valid which is parameter of mysql_fetch_array() method. You have to verify the reference before retrieving rows.
if(isset($_GET['recherche']))
$requete="SELECT * FROM fiche_membres WHERE ville
LIKE '%" . mysql_real_escape_string($_GET['recherche']) . "%' LIMIT 0 , 1 ";
else
$requete="SELECT * FROM fiche_membres LIMIT 1 , 1 ";
$resultat=mysql_query($requete);
if($resultat)
{
while($fiche_membres=mysql_fetch_array($resultat))
{
//
}
}

How do I conditionally add an id attribute in TAL (PHPTAL)?

I'm creating a form elements template file in PHPTAL. I would like to be able to OPTIONALLY pass in an id attribute for a field...
So far the code looks like this:
<xml>
<tal:block metal:define-macro="text">
<label tal:condition="php: !isset(hideLabel) || isset(hideLabel) && !hideLabel">${field/label}</label>
<input name="${name}" type="text" value="${field/value}" />
<p tal:condition="exists:field/error">${field/error}</p>
</tal:block>
</xml>
This works as advertised. What I'd like to add is something, like
<input name="${name}" tal:attributes="id exists: id $id | $name" value="${field/value}" />
to allow me to optionally pass in an id from the METAL call...
Should I be doing it differently? I've tried using PHP: isset(id) ? $id : NULL and variations thereof, but just end up with an id="0" in the resultant HTML.
Any ideas?
In case anyone else needs it, one working answer is:
<xml>
<tal:block metal:define-macro="text">
<label tal:condition="not: exists:hideLabel">${field/label}</label>
<input name="${name}" tal:attributes="id id | nothing" type="text" value="${field/value}" />
<p tal:condition="exists:field/error">${field/error}</p>
</tal:block>
</xml>
Where passed in variables are id, name, an array named field, and hideLabel .
Note, that I've also managed to simplify the label test to something which I believe is more idiomatically TAL.
Set VAR at a DIV containing the soon to be used element:
div class="" tal:define="VAR context.property"
div class="" tal:attributes="class python:'grid_8 omega' if VAR else 'grid_8 alpha'"
in PHP:
<div id="contentCenter" tal:attributes="id
php:isset(variable)&&isset(variable.property)?'IDVALUE':NULL">