Jade variable rendering inside tag specifications - node.js

I have a Jade page like so:
table
th Site Name
th Deadline
th Delete Transaction
- if (transactions != null)
each item in transactions
tr
td= item.item_name
td
span(id='countdown' + item.timeout + ')= item.timeout
td
span(style='cursor: pointer;', onclick='deleteTransaction("=item.uniqueId")')= "X"
button(id='confirmButton', onclick='confirm();')Confirm
As you can see in both the span attribute I try to put a local variable in two different ways and it doesn't work. Concerning the first way, I receive a token ILLEGAL error, while the second simply writes in my JavaScript something like deleteTransaction("=item.uniqueId");. I know the answer is something really stupid, but again and again Jade doc (even if it has improved) doesn't help me.
Thanks

To quote the docs:
Suppose we have the user local { id: 12, name: 'tobi' } and we wish to create an anchor tag with href pointing to "/user/12" we could use regular javascript concatenation:
a(href='/user/' + user.id)= user.name
Ergo:
span(id='countdown' + item.timeout)= item.timeout
// ...
span(style='cursor: pointer;', onclick='deleteTransaction("' + item.uniqueId + '")')= "X"
Quoting again:
or we could use jade's interpolation, which I added because everyone using Ruby or CoffeeScript seems to think this is legal js..:
a(href='/user/#{user.id}')= user.name
And so:
span(style='cursor: pointer;', onclick='deleteTransaction("#{item.uniqueId}")')= "X"
As a general tip that you'll use every day of your programming life: balance your quotes. Just like brackets and parentheses, every quotation mark must either open a new quotation or close an already-open quotation (of the same kind, i.e. double-quotes close double-quotes, single-quotes close single-quotes). To borrow your code:
span(id='countdown' + item.timeout + ')= item.timeout
// ^
// |
// What's this guy doing? ---------+
Even though Jade is a templating language and perhaps not a "real" programming language this rule, just as in HTML (also not a programming language), will serve you well.

Related

Is this the right way to implement my own filter in twig? (I want *minimal* whitespace between tags, not *no* whitespace between tags)

I know that apply spaceless "isn't about optimisation", in Symfony's words. But dammit, I dislike extraneous whitespace from being in my served files.
So I'm keen to use it.
But... I don't like how it reduces
<span>1</span>
<span>2</span>
to
<span>1</span><span>2</span>
As that results in the browser displaying 12, rather than 1 2.
In my mind whitespace between tags should be reduced to a single space, not to nothing.
<span>1</span>
<span>2</span>
->
<span>1</span> <span>2</span>
So I thought I'd make a custom filter, minimizeWhitespace, and wrap my templates with <% apply minimizeWhitespace %>
This is what I came up with:
function minimizeWhitespace($s)
{
return new \Twig\Markup(preg_replace('/\s+/', ' ', $s->__toString()), 'UTF-8');
}
$TWIG_env->addFilter(
new \Twig\TwigFilter('minimizeWhitespace', 'minimizeWhitespace')
);
This feels messy though - I'm taking their \Twig\Markup object, converting it to a string, running my regexp on it, and then creating a new \Twig\Markup object to return.
Is there a better way?

After you've found an a WebDriver element, how can you apply an xpath on that element to narrow it down further?

Here's the situation:
My HTML code's structure looks something like this:
XPATH1
XPATH1 + XPATH2
XPATH1 + XPATH3
XPATH1
XPATH1 + XPATH2
XPATH1 + XPATH3
I need to access those sub-paths. So I"m trying to get all XPATH1s into a list first and then trying to iterate over it.
Unfortunately, this is yielding duplicates for me.
I've got the following code in Python:
elements_list = driver.find_elements_by_xpath(XPATH1)
for element in element_list:
var1 = element.find_element_by_xpath(XPATH2) #We need XPATH1/XPATH2
var2 = element.find_element_by_xpath(XPATH3)
#lots more sub-paths
I suspect that what is happening is, element.find_element_by_xpath(XPATH2) does NOT apply to the element's XPATH. Instead it applies it universally on the page and fetches the whole list of XPATH2s.
I can't use XPATH1 + XPATH2 either because then it's still going to path to each element.
How can I access each element on this page using a for loop?
Also, is there any use of element.find_element_by_xpath function? It seems practically useless because the xpath gets applied to the entire page.
This is because you didn't specify CONTEXT NODE.
Note you should start your XPATH2 and XPATH3 with the dot that stands for "current context" (XPATH1):
elements_list = driver.find_elements_by_xpath('//div')
for element in element_list:
var1 = element.find_element_by_xpath('./a')
var2 = element.find_element_by_xpath('.//p')
This Selenium behavior inherent for search by XPath only. With other methods as find_element_by_css_selector, find_element_by_name, etc... context node should not be specified, so element.find_element_by_css_selector('a') will work fine
Another way of solving this, besides the way Andersson pointed out, is the following:
total_count = len(driver.find_elements_by_xpath(XPATH1))
for i in range(1,total_count+1):
var1 = element.find_element_by_xpath("("+ XPATH1 + ")[{0}]".format(i) + XPATH2)
var2 = element.find_element_by_xpath("("+ XPATH1 + ")[{0}]".format(i) + XPATH3)
Basically, we type in the absolute path by putting XPATH1 in brackets and iterating over it with an index.

Jade - Print many variables in one line

I am trying to print several variables that i have passed from the controller to view in one line.
The content of the variables is like "xyz", where tag is a valid html tag.
What i am doing now is -
div
!= (notification.content + notification._.publishedDate.format('MMMM Do, YYYY'))
However this prints the div on two lines.
The html content generated is -
<div>
<p>School is closed tomorrow link</p>
March 7th, 2016
</div>
Additionally i cannot do -
p= (notification.content + notification._.publishedDate.format('MMMM Do, YYYY'))
Because the output is this then in HTML -
<p><p>School is closed tomorrow&nbsp;<a href="http://www.booking.com">link</a></p>March 7th, 2016</p>
Hey!
See some ways to display your message using Jade/HTML.
Please, test these ways and use the best on your project:
Declaring Variables
// Variable with `<p></p>`
- var notification = {content: '<p>School is closed tomorrow link</p>', publishedDate: '2016-03-07'}
// Variable withOUT `<p></p>`
- var test = {content: 'The message link', publishedDate: '2016-03-07'}
1) Return Escaped Text
div #{notification.content} #{notification.publishedDate}
// Return | escaped string:
// <p>School is closed tomorrow link</p> 2016-03-07
2) Return HTML Code (unescaped | real tags)
div !{notification.content} !{notification.publishedDate}
// Return | unescaped (2 lines)
// School is closed tomorrow link
// 2016-03-07
3) Return HTML Code Inline (unescaped too)
You need modify the array entries. See the var "test" above (on Declaring Variables):
div: p !{test.content} !{test.publishedDate}
// Return | unescaped (1 line)
// The message link 2016-03-07
If works for you, try apply your own variables and rules.
I'm learning about Jade. I hope to help you.
- Any doubts comment here or talk with me #devromulobastos

Jade: Links inside a paragraph

I'm trying to author a few paragraphs with Jade, but finding it difficult when there are links inside a paragraph.
The best I can come up with, and I'm wondering if there's a way to do it with less markup:
p
span.
this is the start
of the para.
a(href="http://example.com") a link
span.
and this is the rest of
the paragraph.
As of jade 1.0 there's an easier way to deal with this, unfortunately I can't find it anywhere in the official documentation.
You can add inline elements with the following syntax:
#[a.someClass A Link!]
So, an example without going into multiple lines in a p, would be something like:
p: #[span this is the start of the para] #[a(href="http://example.com") a link] #[span and this is the rest of the paragraph]
You can also do nested inline elements:
p: This is a #[a(href="#") link with a nested #[span element]]
You can use a markdown filter and use markdown (and allowed HTML) to write your paragraph.
:markdown
this is the start of the para.
[a link](http://example.com)
and this is the rest of the paragraph.
Alternatively it seems like you can simply ouput HTML without any problems:
p
| this is the start of the para.
| a link
| and this is he rest of the paragraph
I wasn't aware of this myself and just tested it using the jade command line tool. It seems to work just fine.
EDIT:
It seems it can actually be done entirely in Jade as follows:
p
| this is the start of the para
a(href='http://example.com;) a link
| and this is the rest of the paragraph
Don't forget an extra space at the end of para (although you can't see it. and between | and. Otherwise it will look like this para.a linkand not para a link and
Another way to do it:
p
| this is the start of the para
a(href="http://example.com") a link
|
| this is the rest of the paragraph.
Another completely different approach, would be to create a filter, which has first stab at replacing links, and then renders with jade second
h1 happy days
:inline
p this can have [a link](http://going-nowhere.com/) in it
Renders:
<h1>happy days</h1><p>this can have <a href='http://going-nowhere.com/'>a link</a> in it</p>
Full working example: index.js (run with nodejs)
var f, jade;
jade = require('jade');
jade.filters.inline = function(txt) {
// simple regex to match links, might be better as parser, but seems overkill
txt = txt.replace(/\[(.+?)\]\((.+?)\)/, "<a href='$2'>$1</a>");
return jade.compile(txt)();
};
jadestring = ""+ // p.s. I hate javascript's non-handling of multiline strings
"h1 happy days\n"+
":inline\n"+
" p this can have [a link](http://going-nowhere.com/) in it"
f = jade.compile(jadestring);
console.log(f());
A more general solution would render mini sub-blocks of jade in a unique block (maybe identified by something like ${jade goes here}), so...
p some paragraph text where ${a(href="wherever.htm") the link} is embedded
This could be implemented in exactly the same way as above.
Working example of general solution:
var f, jade;
jade = require('jade');
jade.filters.inline = function(txt) {
txt = txt.replace(/\${(.+?)}/, function(a,b){
return jade.compile(b)();
});
return jade.compile(txt)();
};
jadestring = ""+ // p.s. I hate javascript's non-handling of multiline strings
"h1 happy days\n"+
":inline\n"+
" p this can have ${a(href='http://going-nowhere.com/') a link} in it"
f = jade.compile(jadestring);
console.log(f());
If your links come from a data source you can use:
ul
each val in results
p
| blah blah
a(href="#{val.url}") #{val.name}
| more blah
See interpolation
Edit: This feature was implemented and issue closed, see answer above.
I've posted an issue to get this feature added into Jade
https://github.com/visionmedia/jade/issues/936
Haven't had time to implement it though, more +1s may help !
This is the best I can come up with
-var a = function(href,text){ return "<a href='"+href+"'>"+text+"</a>" }
p this is an !{a("http://example.com/","embedded link")} in the paragraph
Renders...
<p>this is an <a href='http://example.com/'>embedded link</a> in the paragraph</p>
Works ok, but feels like a bit of a hack - there really should be a syntax for this!
I did not realize that jade requires a line per tag. I thought we can save space. Much better if this can be understood ul>li>a[class="emmet"]{text}
I had to add a period directly behind a link, like this:
This is your test [link].
I solved it like this:
label(for="eula").lbl.lbl-checkbox.lbl-eula #{i18n.signup.text.accept_eula}
| #{i18n.signup.links.eula}.
As suggested by Daniel Baulig, used below with dynamic params
| <a href=!{aData.link}>link</a>
Turns out there is (now at least) a perfectly simple option
p Convert a .fit file using Garmin Connect's export functionality.
p
| At Times Like These We Suggest Just Going:
a(ui-sref="app") HOME
|
Most simplest thing ever ;) but I was struggling with this myself for a few seconds. Anywho, you need to use an HTML entity for the "#" sign -> #
If you want to in include a link, let's say your/some email address use this:
p
a(href="mailto:me#myemail.com" target="_top") me#myemail.com

Drupal 6: How do you print Taxonomy Terms as a CSS Body Class?

In Drupal 6, how do you print a taxonomy term as a CSS body class?
I have found this snippet that lets you print almost every aspect of Drupal content as a body class, but it doesn't include taxonomy terms:
http://www.davidnewkerk.com/book/122
Being able to print taxonomy terms as a body class is essential for theming processes, so I am surprised that a solution is not readily available.
Check what variables are passed to the page template by either doing print_r($vars) or dpm($vars) in your page pre-process function or using the http://drupal.org/project/devel_themer module. The usage of dpm require you to install the devel module.
You will find that some themes will pass $taxonomy as a variable to page.tpl.php . If that is not the case you can find the taxonomy terms in the $node variable which is also available in the page.tpl.php in some themes.
(The above holds true for my fusion based theme acquia marina http://drupal.org/project/acquia_marina ). Once you have these taxonomy terms available you can easily print them out in your body classes.
After much hard work, I found a very easy way to do this.
On Drupal Snippets, there is a snippet that lets you print out the taxonomy terms applied to each page as text.
The only problem is that the snippet will print any spaces or punctuation that are in the taxonmy term, which is no good for body classess.
However, by adding a str_replace command, you can strip out all the spaces and punctuation.
I'm sure there are other people who wants to print taxonmy terms as body classes, so to save them the bother, here is the code that I used with the str_replace command added.
Put the following in template.php:
function getTerm($label, $vid, $link) {
$node = node_load(array('nid'=>arg(1)));
foreach((array)$node->taxonomy as $term){
if ($term->vid == $vid){
if ($link){
$link_set[] = l($term->name, taxonomy_term_path($term));
} else {
$link_set[] = $term->name;
}
}
}
if (!empty($link_set)){
$label = ($label) ? "<strong>$label </strong>" : "";
$link_set = $label.implode(', ', $link_set);
}
$link_set = str_replace(' ', '_', $link_set);
$link_set = str_replace('&', 'and', $link_set);
$link_set = strtolower($link_set);
return $link_set;
}
Put the following in Page.tpl.php:
<body class="taxonomy-<? print getTerm(false, 1, false);?>">
I hope this helps anyone who has the same problem.
Extra tips:
(1)In the code I have posted, the only punctuation that is striped out is the ampersand (i.e. '&').
If you have other punctuation to strip out use the following:
$link_set = str_replace('INSET_PUNCTUATION_HERE', 'INSERT_REPLACEMENT_HERE', $link_set);
Place this command under the other $link_set lines in the code I have posted for template.php.
(2) In the page.tpl.php code I have posted, the "taxonomy-" part places the words taxonomy and a dash before each body class term. You can edit this as you wish to get the results your require.

Resources