I have used the pyramid framework to build a large web application.
Among other things, this application allows the user to enter text into a text area form field. This text is then saved to a database and of course can be readout again and displayed later.
To display content I am using the Chameleon Template Engine.
This works fine, except that line breaking is not displayed correctly (not displayed at all). This is probably due to the fact that the newlines entered into the text area do not cause a new line in HTML when displayed through Chameleon. How can one fix this?
It does not help to replace the newlines by <br>-Tags because by default Chameleon escapes all HTML-Tags. I am aware of the fact that one can deactivate this feature, but I do not want to do that to avoid cross-site scripting.
You need to break the text into separate lines, then render this using a loop and <br/> tags:
<span tal:omit-tag=""
tal:repeat="line text_with_newlines.splitlines()">
${line}<br />
</span>
This uses the str.splitlines() method to split the text on newlines, then the loop adds a <br /> break tag after each line of the text.
You are quite right not doing this in the view, then forcing Chameleon to accept your inserted <br /> tags by setting the structure: flag. Luckily there is absolutely no need for that anyway.
Another possibility is to do something like the following:
import webhelpers.html.tags as t
s = t.literal(t.BR).join(s.split(t.NL))
You can of course create a helper function from it.
Related
In a project of mine I need to create an online encyclopedia. In order to do so, I need to create a page for each entry file, which are all written in Markdown, so I have to covert it to HTML before sending them to the website. I didn't want to use external libraries for this so I wrote my own python code that receives a Markdown file and returns a list with all the lines already formatted in HTML. The problem now is that I don't know how to inject this code to the template I have in Django, when I pass the list to it they are just printed like normal text. I know I could make my function write to an .html file but I don't think it's a great solution thinking about scalability.
Is there a way to dynamically inject HTML in Django? Is there a "better" approach to my problem?
You could use the safe filter in your template! So it would look like that.
Assuming you have your html in a string variable called my_html then in your template just write
{{ my_html | safe }}
And don’t forget to import it!
I have a postgresql db table called blog_post and in that table a column called post_main. That column stores the entire blog post article, including various HTML and DTML tags.
For reference (and yes, I know it's old), this is Zope 2.13 with PostgreSQL 8.1.19
For example:
<p>This is paragraph 1</p>
<dtml-var "blog.sitefiles.post.postimg1(_.None, _)">
<p>This is paragraph 2</p>
The dtml-var tag is telling Zope to insert the contents of the dtml-document postimg1 between the two paragraphs.
OK, no problem. I am storing this data without issue in the postgres db table, exactly as it was entered, and I am running a ZSQL Method via a <dtml-in zsqlmethod> tag that surrounds the entire dtml-document, in order to be able to call to the variables I need in the page.
Normally, and without either HTML code OR especially without DTML tags, it's no issue to insert the data into the web page. You do this via &dtml-varname; if you have no html tags and just want a plain text output, OR you do <dtml-var varname> if you want the data to be rendered and shown as proper html.
Here's the problem
Zope is just posting the <dtml-var "blog.sitefiles.post.postimg1(_.None, _)"> line to the html page instead of processing it like when I type it into the dtml-doc directly.
What I need:
I need the code stored in the post_main column (referenced above as varname) to be processed as if I typed it directly into the dtml-document, so that the <dtml-var> tags work the way they are supposed to work.
So, you have a variable that contains a DTML Document, and you want to execute that document and insert the results?
To be honest, I'm not sure that's possible in DTML alone, as it generally users don't want to execute code contained in strings. This is the same danger as exposing eval() or exec() of user supplied strings, as if someone can control the string they have arbitrary code execution on the Zope instance. It's the equivalent of storing PHP code in your database and executing that.
Frankly, I'm surprised you're using DTML on Zope 2.13 at all, rather than PageTemplates, but I assume you've got a good reason for it.
If you want to interpret the value of a DTML variable rather than just insert it, you'll need to explicitly do the interpreting, using something like:
from DocumentTemplate.DT_HTML import HTML
return HTML(trusted_dtml_string)
The problem with this is that you can't do it in a Script (Python) through the web, because of the security concerns. If you do this as an external method or filesystem code it's very likely that you'll allow arbitrary code execution on your server.
I'm afraid my only recommendation is to avoid doing this, it's very difficult to get it right and errors can be catastrophic. I'd strongly suggest you do not store DTML tags as part of your blog articles.
As an alternative, if you have a fixed number of delegations to DTML methods, I recommend writing a Python script, such as:
## Script (Python) "parse_variables"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=post, _
##title=
##
post = post.replace("##POST_IMAGE##", context.postimg(None, _))
return post
And then calling that with your variable that contains the user-supplied data, like <dtml-var expr="parse_variables(data, _)">
In my Django application, I call an external API, which returns XML. I would like to display this "minified" response as an indented multiline string on the page (a plus would be syntax highlighting). I tried to process the string in Python with toprettyxml() from xml.dom.minidom, and a few things with ElementTree, but it does not play along the Jinja2 rendering well (line breaks disappear and I only get a one line string, displayed inside <pre> tags).
What's the recommended way to display such code excerpt?
Should I use client-side rendering? Then, which library should I use?
Django version: 1.11.2
Python 3.6.1
This isn't anything to do with Python or Jinja2, but just down to how browsers render text within HTML.
If you want to preserve spacing and indentation, you need to wrap your content with <pre>...</pre> tags.
Currently coding a bbs-style app, I'm wondering what are the best practices to display text that user entered safely. Which means I don't want them to type javascript or things like that. For now I'm rendering in a pre, and forbid the "<" and ">" chars. Though I guess it is not the right way to do it. Plus the lines are cut while it shouldn't.
Could you please give me some hints on how to that ?
More informations : I'm storing those posts in a sqlite db using flask-sqlalchemy. So I don't want them to contain SQL-Injection (which I highly doubt it is possible to do with sqlalchemy)
If you are using the Jinja2 templates as set up by Flask, all content is auto-escaped by default for HTML characters; see Jinja2 setup in the templating documentation:
Unless customized, Jinja2 is configured by Flask as follows:
autoescaping is enabled for all templates ending in .html, .htm, .xml as well as .xhtml
a template has the ability to opt in/out autoescaping with the {% autoescape %} tag.
SQLAlchemy, used properly, indeed protects you from SQL injection attacks.
If you want newlines in user input to be translated to <br/> tags in the HTML output, you can use this Flask Snippet that adds a Jinja2 tag filter that does just that; translate newlines in an input variable into <br/> tags in the rendered output, while still escaping everything else. Multiple newlines are translated to <p> paragraph tags.
Add that snippet as a module to your project, make sure it is imported, then use the nl2br filter in your templates:
User text as paragraphs with line breaks:<br/>
{{ user_text | nl2br }}
Jinja's autoescape is turned on by default in Flask. Anything not explicitly marked safe will be escaped correctly.
http://flask.pocoo.org/docs/templating/#controlling-autoescaping
I use Bleach - http://bleach.readthedocs.org/ to strip HTML and only let through the tags I want to allow. It's really easy to use.
I am writing a google app engine web app using python and jinja2. Is there a simple lightweight textarea markup that I can use either for jinja2 or just generally for an HTML text area. I just want line breaks to come across and italics and bold and maybe one or two other things but I don't just want to mark is safe (and not autoescape the rest of it).
I am surprised that no one has asked a similar question and they probably have so maybe I'm just using the wrong keywords.
You could use TinyMCE to add markup features to a textarea. Visitors of your site (or administrators, if that's where you happen to use it) can then add HTML markup in a user-friendly way.
Alternatively, you could add a Markdown parser (or a similar language) that allows users to add markup using basic symbols. Your website would parse and process the content prior to displaying it.