Template Toolkit: evaluating template statements inside a WRAPPER block? - template-toolkit

Alright, I have looked over the manual for more than two hours now, also tried to find a solution in the badger book, but couldn't come up with anything that works.
The following is the wrapper (body.tt), well you get the idea:
[%- PROCESS 'const.tt' -%]
<?xml version="1.0" encoding="utf-8"?>
Loads of HTML
[%- content -%]
More HTML
The wrapped templates look like this:
[% WRAPPER 'body.tt' %]
Other HTML
[%- bar -%]
More other HTML
[% END %]
And finally const.tt looks like this:
[% bar = 'foo' %]
... and for some reason the instance of bar inside the wrapped template does not get evaluated. Any ideas how I could get that evaluated?
I have tried:
[%- content | eval -%]
... which did not work.
Note, that in the wrapped template (2nd block above) I want to be able to evaluate the variable bar from const.tt without having to add another PROCESS 'const.tt' to that template. After all the variable should be available from body.tt.
And I forgot to mention: Template Toolkit version 2.22

Here is why what you tried doesn't work.
As http://template-toolkit.org/docs/manual/Directives.html#section_WRAPPER explains, your wrapped content is evaluated first, and then body.tt is processed with the already evaluated template passed in as content. Therefore content is finished before content.tt is loaded.
That said, there is a way to do it, but it is a little ugly. Here is your content:
%- PROCESS 'body.tt' -%]
[%- WRAPPER body -%]
Other HTML
[%- bar -%]
More other HTML
[% END %]
Here is body.tt:
[%- PROCESS 'content.tt' -%]
[% BLOCK body -%]
<?xml version="1.0" encoding="utf-8"?>
Loads of HTML
[%- content -%]
More HTML
[% END -%]
And content.tt did not change:
[% bar = 'foo' %]
While this works, I make no promises about the sanity of the person who has to maintain it later.

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 />")

Rails: How not to escape in "<title>" tag

I developed Rails app.
Characters such as & are escaped to & in <title> tag.
For example,foo & bar is displayed such as foo & bar in the title.
When I use raw, it can be displayed as I expect. But I don't want to use raw because the data will be inputted by the user.
I'd like to display like this post (Pls see only title. Contents is nothing to do with my question). & is displayed in the title in spite of inputted by the user.
My code is as below.
application.html.erb
<head>
<title><%= full_title(yield(:title)) %></title>
...
application_helper.rb
def full_title(page_title = '')
base_title = "app name"
if page_title.empty?
base_title
else
page_title + " | " + base_title
end
end
I added provide in some view files, such as show.html.erb.
<% provide(:title, #schedule.title) %> #this title is inputted by user
Is it possible to escape it, but allow some characters unescaped?
You ask how to avoid escaping, but it sounds like what you really want is for browsers to display "&" instead of "&".
If you use your browser's "View Source" feature on the page you said looked right, you will see that it begins with:
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/QAPage">
<head>
<title>symfony2 - Symfony 2, Twig: how not to escape field value (used with backbonejs & symfony 2) - Stack Overflow</title>
Observe that ampersand is entity-encoded as & just the way it "should" be.
Observe that the document begins with a DOCTYPE declaration. A document that begins with something else will probably trigger the browser's quirks mode for compatibility.
Use your browser's "View Source" function on your Rails application. Does the document begin with a DOCTYPE declaration? (<DOCTYPE html> is good.) Does the sequence & appear on its own? (If you see &amp; or similar, you're encoding an already-encoded string.)

Razor - How do I output the current cshtml filename

For debugging purposes, I would like to output an HTML comment indicating the filename of the current cshtml file at the beginning and end of every cshtml file.
For example, I'd like so that when I view the source of the generated webpage, I would see something like this:
<!-- BEGIN _Layout.cshtml -->
... some headings and such ...
<!-- BEGIN About.cshtml -->
... generated content from the About.cshtml ...
<!-- END About.cshtml -->
... some footers and such ...
<!-- END _Layout.cshtml -->
I'm fairly new to this platform, so I'm not even sure what the right terminology is for this, let alone where in the API to look. I'm hoping that at the very least I can edit all of my cshtml files and reference some object at runtime that contains the filename as a property, in a syntax similar to:
<!-- BEGIN #Object.OptionalProperty.OptionalSubProperty.Filename -->
Or, alternatively, a way to modify the rendering engine so that it automatically does this at the beginning and end of every rendered file.
Thank you so much for your time and responses.

How to render html content with erb tags in rails?

I'm writing simple cms engine, and having a problem with dynamic content rendering, for example I prepare some page content with erb tags and helpers, how I can evaluate them in my view?
Thanks.
if i understand you correctly, you want to store snippets that contain ERB markup somewhere and at runtime evaluate them in your real templates of your rails app.
in this case, i think you will have to invoke ERB by hand. this is not really hard:
require 'erb'
name = "Rasmus"
template_string = "My name is <%= name %>"
template = ERB.new template_string
puts template.result # prints "My name is Rasmus"
read more in this nice writeup http://rrn.dk/rubys-erb-templating-system

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