Here is a simple jsfiddle. I'm trying to add the class-names a and b, but what I get is an empty class. For example, if I change it to
{{ bindAttr class="str:a:b}}
I get a
Furthermore, is it possible to add some other (default) classnames too ?
{{ bindAttr class"str className1 className2"}}
Of course! Your syntax is just a bit wrong. The syntax for adding a default class is only :className. Here is a simple jsfiddle to show you.
What your first line of code actually states is that if str is true, then assign class 'a' to the element, otherwise class 'b' (which is why you only get 'a' as the assigned class). An example of conditional classes is in an updated version of your jsfiddle here.
Related
I'm using this http://www.xpathtester.com/xpath/5a30592045b6aa5089faf909261ede0b XPath tester, which returns exactly what I want. For some reason it removes my full query, but if you use it, it works.
*/h3[contains(string(), "Description")]/following-sibling::p[1]
But in real life, I get nothing from my variable.
I'm trying to get the data after <h3>Description</h3>, in this case a paragraph <p>.
HTML
$feed_item=
<div class="outer-feed"><ul>
<li><strong>Severity:</strong> <span class="label label-info">Low</span></li>
</ul>
<h3>Description</h3>
<p>The lack of validation of configuration parameters used in SQL queries caused various SQL injection vectors.</p>
...
Here's my XPath
$description_node = $xpath->query('*/h3[contains(string(), "Description")]/following-sibling::p[1]', $feed_item);
$description = "description: " . $description_node->item(0)->textContent;
and var_dump
object(DOMNodeList)#1654 (1) { ["length"]=> int(0) }
And the error
Notice
: Trying to get property 'textContent' of non-object in
What confuses me is that I can get Severity from the same HTML by using this:
$severity_node = $xpath->query('*/li[contains(string(), "Severity:")]', $feed_item);
$severity = preg_replace('/Severity:\W*/u', '', $severity_node->item(0)->textContent);
My first thought was to scale back to just the H3 and output that.
$description_node = $xpath->query('*/h3[contains(string(), "Description")]', $feed_item);
object(DOMNodeList)#1654 (1) { ["length"]=> int(0) } // doesn't contain anything
Given that the following are identical but the first works and the second doesn't, what could be the problem?
$severity_node = $xpath->query('*/li[contains(string(), "Severity:")]', $feed_item);
$description_node = $xpath->query('*/h3[contains(string(), "Description")]', $feed_item);
Why is one working and not the other. And what is the best way to troubleshoot things like this. It seems to work on the xpathtester. What could I be doing wrong that causes this problem in PHP?
Try with this XPath:
//h3[text()="Description"]/following::p[1]
A query starting */h3[...] will only work if the context item when it is invoked is the grandparent of the h3 element. You've given no information about the context item, so I suspect it is something different.
You ask the question(s): "Why is one working and not the other. And what is the best way to troubleshoot things like this. It seems to work on the xpathtester. What could I be doing wrong that causes this problem in PHP?"
Well, the first thing is to understand that XPath expressions may depend on the context item, and that the same expression evaluated with different context items is going to give different results. Once you understand that concept, it hopefully becomes a lot clearer.
I'm using lexpyrocms parser as a package installed with composer along with a codeigniter framework with HMVC, wich allows me to use {{pseudo-variable}} in my templates/views.
I have a very weird behavior whith the parser syntax in my view :
I have this simple $modules array as data that I can print_r() in the view/template
$modules =
Array (
[users] => stdClass Object ( [id_mdl] => 8 [name_mdl] => users ),
[actions] => stdClass Object ( [id_mdl] => 9 [name_mdl] => actions )
);
If I use basic Lex syntax, I can display the name_mdl without problem with
{{modules}} {{name_mdl}} {{/modules}} => output 'users' and 'actions'
but when I use the conditional 'if' inside the loop, I get a wrong matching when I test if a variable exists :
{{modules}}
{{name_mdl}}
{{/modules}}
this outputs correctly users actions
{{modules}}
{{if exists name_mdl}}
name_mdl OK {{name_mdl}}
{{endif}}
{{/modules}}
but this does not output anything : /
{{modules}}
{{if not exists name_mdl}}
name_mdl NOT OK {{name_mdl}}
{{endif}}
{{/modules}}
This outputs 'name_mdl NOT OK users
name_mdl NOT OK actions'
the parser displays correctly a variable it just recused as existing in the condition..
I've searched a bit everywhere but it looks like an orphan problem, can't find a clue anywhere ..
Well.. I managed to get rid of this strange behavior, but I'm not sure which part of the changement I've made solved the problem ...So for what it's worth :
The error I faced was that in a loop {{list_of_things}}{{/list_of_things}} the checking of an existing variable with conditional if exists wasn't possible, though the display of this variable worked fine :
{{list_of_things}}
{{ list_name }} <-- display the list_name of each entry
{{ if exists list_name }}
The condition was never met, tough the data 'list_name' can be displayed above
{{ endif }}
{{/list_of_things}}
I did two things after that, and got rid-off the problem...
1- I moved the declaration of the Lex Parser $this->parser = new Lex\Parser();
from my front controller application/modules/my_module/module_controller.php
into the constructor of my extending core controller class application/core/MY_Controller.php
2- I cleaned up my views folder cause there where some double file from earlier development :
to be noted : the view called was and is application/modules/my_module/views/theme/my_template.php
before :
modules/my_module/views/
my_template.php
modules/my_module/views/theme/
my_template.php
after :
modules/my_module/views/
modules/my_module/views/theme/
my_template.php
So my best guess is that HMVC messed a bit the Lex Parser with the 'loaded_paths', and that two views with the same name in the same module (even though not in the same directory) can lead to unexpected behavior .. but I don't see why the hell that would change the conditionals of the parser ...
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.
Considering this code example and this post
...
<xf:action>
<xf:setvalue
iterate="instance('fr-send-submission-params')/#*"
ref="."
value="event(name(context()))"/>
</xf:action>
...
How can refer to current iterated position? Like value="position()"
Can i use this position as variable to xpath expressions? Like ref="/AnotherElement[position()]"
The following works:
<xf:action iterate="instance('fr-send-submission-params')/#*">
<xf:var name="p" value="position()"/>
<xf:setvalue ref="." value="$p"/>
</xf:action>
I don't think you can get away just with xf:setvalue, because ref changes the evaluation context of the expression to a single item which means that position() returns 1 within value.
A warning as I see that you iterate on attributes: I don't think that attribute position is guaranteed to be consistent.
Update:
The following works if you have elements, but then you need to have knowledge of the items iterated within the xf:setvalue:
<xf:setvalue
event="DOMActivate"
iterate="value"
ref="."
value="count(preceding-sibling::value) + 1"/>
So I think that the option with an enclosing action is much clearer.
I'm parsing through a HTML document and I need a class name of a div. I know a part of the class name (that never changes) but I need the full class name.
Here's the code I use:
$doc = new DOMDocument;
$doc->loadHTMLFile('http://some_website.com');
$xpath = new DOMXPath($doc);
$classname_of_the_div=$xpath->query('//div[#class="part_of_the_class_name_that_never_changes"]');
When I var_dump() the $classname_of_the_div and $classname_of_the_div->item(0) the result is:
object(DOMNodeList)#3 (1) { ["length"]=> int(0) }
NULL
I know that $classname_of_the_div=$xpath->evaluate('string(//div[#class="part_of_the_class_name_that_never_changes"])'); gives me the content of the div but how do I get the full class name?
P.S.: The part of the classname is separated from the rest of the class name by white spaces, so it's not really a part of the class. The div has just several classes.
I mean the div has several class names like - I want to select it by "class2" for example and receive the
full class string including "class1 class2 class3"
Then, an XPath expression like
//div[#class="part_of_the_class_name_that_never_changes"]
will never yield a result, save for the situation that a particular div element only has one class, that is, the one "that never changes". That's because the XPath expression above means:
Select div elements that have a class attribute whose string value
exactly corresponds to "part_of_the_class_name_that_never_changes".
But imagine the following situation:
<div class="part_of_the_class_name_that_never_changes other_class1 other_class2"/>
Then, you would need to change the expression to:
//div[contains(#class,'part_of_the_class_name_that_never_changes')]/#class
The expression means:
Look for div elements that have a class attribute whose string
value contains the string
"part_of_the_class_name_that_never_changes" and return the attribute
value.