Mustache/Hogan JS: Is it possible to reference parent tags within a list? - templating

I have a use case where I'd like to access parent tags within list loop sections in a Mustache/Hogan JS template.
For example, this is my data structure:
var data = {
users: [{name: "John", age: 100},{name: "Max", age: 80}],
meta: {membership: "full"}
};
..and this is my Mustache/Hogan JS template:
{{#users}}
h1 Hello there, {{name}}
{{/users}}
..which renders as:
<h1>Hello there, John</h1>
<h1>Hello there, Max</h1>
This is all well and good, but is it possible for me to access the meta.membership parent variable within the {{#users}...{{/users}} section? It seems that the tags are limited to the local context, so I can't output the value of the meta.membership tag while iterating over users.
Ideally I want to know if something like this is possible:
{{#users}}
h1 Hello there, {{name}}
p You have a {{meta.membership}} membership
{{/users}}
Desired result:
<h1>Hello there, John</h1>
<p>You have a full membership</p>
<h1>Hello there, Max</h1>
<p>You have a full membership</p>
Thanks in advance

PEBKAC!
It turns out Hogan JS does support the Context Bubbling spec so my desired input as per the question does in fact evaluate to my desired output! :) I was just having problems getting this to work as expected because I was dealing with a heavily nested dataset & several Mustache includes so I had made a few silly errors along the way that were giving me blank outputs.
All good now - though I think I'd better go find me a Hogan debugger to save from further frustration in the future... ;)

{{#users}}
h1 Hello there, {{name}}
p You have a {{#meta.membership}} membership
{{/users}}
OR
{{#users #meta}}
h1 Hello there, {{name}}
p You have a {{membership}} membership
{{/users}}
Try it... Could work since the structure of the data-array would allow it to work

Related

Displaying user input html with newlines

I have comments section in my application where users enter input in a text area. I want to prevent the line breaks they enter but also display html as a string. For example, if comment.body is
Hello, this is the code: <a href='foo'>foo</a>
Bye
I want it to be displayed just as above. The same with anything else, including iframe tags.
The closest I got is:
= simple_format(comment.body)
but it sanitizes html code and it's not displayed. Example: foo <iframe>biz</iframe> bar is displayed as:
foo biz bar
What should I do to achieve what I want?
Just use it without any method, it will be rendered as plain text:
= comment.body
Using your second example, the output will be:
foo <iframe>biz</iframe> bar
To make \n behave as <br>, you can use CSS:
.add-line {
white-space: pre-wrap;
}
And use it in your view:
.add-line = comment.body
Using your first example:
comment.body = "Hello, this is the code: <a href='foo'>foo</a>\n\nBye"
The output will be:
Hello, this is the code: <a href='foo'>foo</a>
Bye
Having done something similar in the past, I think you must first understand why HTML is sanitized from user input.
Imagine I wrote the following into a field that accepted HTML and displays this to the front page.
<script>alert('Hello')</script>
The code would execute for anyone visiting the front-page and annoyingly trigger a JS alert for every visitor.
Maybe not much of an issue yet, but imagine I wrote some AJAX request that sent user session IDs to my own server. Now this is an issue... because people's sessions are being hijacked.
Furthermore, there is a full JavaScript based exploitation framework called BeEF that relies on this type of website exploit called Cross-site Scripting (XSS).
BeEF does extremely scary stuff and is worth taking a look at when considering user generated HTML.
http://guides.rubyonrails.org/security.html#cross-site-scripting-xss
So what to do? Well if you checked in your DB you'd see that the tags are actually being stored, but like you pointed out aren't displayed.
You could .html_safe the content, but again I strongly advise against this.
Maybe instead you should write an alternative .html_safe method yourself, something like html_safe_whitelisted_tags.
As for removing newlines, you say you want to display as is. So replacing /n with <br>, as pointed out by Michael, would be the solution for you.
comment.body.gsub('\n', '<br />').html_safe_whitelisted_tags
HTML safe allows the html in the comment to be used as html, but would skip the newlines, so doing a quick replace of \n with <br /> would cover the new lines
comment.body.gsub("\n", "<br />").html_safe
If you want the html to be displayed instead of rendered then checkout CGI::escapeHTML(), then do the gsub so that the <br /> does not get escaped.
CGI::escapeHTML(comment.body).gsub("\n", "<br />")

Searching for contents between two specified tags

I installed Nokogiri into a Rails project and it can currently run "Nokogiri HTML Parser Example" with no issues.
I'm trying to create a Rails project that will parse a movie script from IMDB, conduct a word count, then display the most occurring words from that section. I've identified that the scripts are kept in a "table":
<table width=100% border=0 cellpadding=5 class=scrtext><tr><td class=scrtext><pre><html><head></head><body>
<b>PERSON1</b>
They say some dialogue
<b>PERSON2</b>
They say some more
</pre></table>
I would like to exclude the text within the <b>/<b> brackets as well.
I've been setting this up like the example above in the controller, and have gotten as far as taking in the URL:
#Save as a temp. file
tmp_file = open('http://www.imsdb.com/scripts/Authors-Anonymous.html')
#Parse the temp. file
doc = Nokogiri::HTML(tmp_file)
I'm having difficulty understanding how to set the CSS constraints to grab this table. I understand that it's between those <pre>/<pre> tags, and I've followed a number of tutorials for this but I still don't understand how to set up those constraints.
I feel that the code following this should be something like this, but I'm not awfully sure:
doc.search("//pre")
How do I set up Nokogiri's CSS constraints to pull the content between two tags such as <pre></pre>, and then filter out irrelevant tags such as <b></b> that will occur within the output?
You can use the css method selector: doc.css('pre b') which will get every <b> tag(s) inside every <pre> tag(s):
doc.css('pre b').each do |b_tag|
# b_tag will be a String containg like `<b>this text is bold</b>`
end
It might not be the most elegant solution but it did the trick for me.
In the controller, I defined the following:`
def index
page = [THE_URL]
doc = Nokogiri::HTML(open(page))
#content = doc.css('b').remove
#content = doc.css('pre')
puts #content
end
and then in the View;
<%=#content %>

Simple webpage to show statuses

I am writing few automation tests. What I want to do is to create some kind of super simple web page which will show the statuses of all the test runs. For example if test passed - there will be green button near this application name, red button in case of fail accordingly. What is the most simple and straightforward way to accomplish this task? Again, I just need a column of names with green or red button near each test name.
I already created a text file which is being updated with 0 or 1 in case of success and fail. The first idea was to base the web page on this file, but I have no idea how.
The file looks like that (if it's relevant):
APP1 0
APP2 1
APP2 1
.
.
.
You can just modify your program to output html instead of plain text.
Your example will become something like this.
<!DOCTYPE html>
<html>
<head>
<title>Report</title>
</head>
<body>
<table>
<tr><td>APP1</td> <td><img src="red.png"/></td></tr>
<tr><td>APP2</td> <td><img src="green.png"/></td></tr>
<tr><td>APP2</td> <td><img src="green.png"/></td></tr>
......
</table>
</body>
</html>
It's very easy to achieve this, just open the file and write all the html code until <table> then execute all your tests and for each one output a table row. When you have write all of them just close the remaining tags.
Obviously if you can't modify your program then you need to start from the output file that you already have, read one line at a time and split the app name from the result, then proceed as explained before.

How to loop through properties in a tab and display them using Razor?

I have a Document Type, that has a tab with some properties.
The properties are Upload types, and Simple Editor types.
(Users are supposed to upload images with some image text).
I have not grouped the "Upload" and "Simple Editor" properties, so how do i do this?
Next question,
I want to loop through each group (there should be 3 currently) and display them on my website.
The markup should look like the following:
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
..
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
...
I would like to use Razor for this. Thanks in advance!
For the first part, using the Razor model, you can't. The content object that you get on the front end only contains the properties, the tabs are not included, as they're only really for organising things in the back office.
You CAN get that information using the Umbraco API, but it's pretty database intensive and could potentially be quite slow if you have a lot of properties/tabs.
You'd be better grouping them yourself in your Razor Macro.
for the second part, you can acces the properties of a page via #Model.property. For example:
<div>
<div>#Model.simpleProperty</div>
</div>

Raw Mako template included in another in Pylons

I'm trying to include a raw Mako template to make it appear in a textarea with Pylons.
In Pylons, I know I can include one Mako template in another like this:
<html>
<body>
Here is some HTML. Now, I want to include a template.
<%include file="${c.a_mako_template}" />
</body>
</html>
Is there a way that I can do the same thing, but have the template appear as raw markup rather than passing through Mako renderer? I'm imagining something like:
<%include file="${c.a_mako_template}" render="false" />
If that sort of thing is impossible, is the best route to write a Pylons controller that does the inclusion at a later stage?
Could I somehow wrap the file to be included in <%text> tags on the fly, perhaps using <% def>?
I've figured out a sort of workable solution. It still has one rough bit, but it works.
<%
path = '/path/to/file/'
f = open(path + c.sourcefile, 'r')
text_to_edit = f.read()
f.close()
%>
<textarea id="code">
${text_to_edit}
</textarea>
The first part is just a chunk of Python embedded in the template. It opens the file and extracts the text, thereby bypassing Mako.
The rough bit is the hardcoded path. I'll have to pass that as c.path, or something like that.

Resources