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!
Related
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, _)">
I want to create 2 web pages which use the same code but I don't want to copy/paste the code in 2 places. I'm sure I don't need to have the same code in 2 different places to use it on multiple pages. Can someone suggest a way to avoid creating duplicate code?
If required, I can provide some sample code which I've already written.
For generating HTML on the frontend, you can use templates to create static content which can be used across multiple pages on your site.
For more information on how to use django templates, see: https://docs.djangoproject.com/en/1.9/topics/templates/
As for the backend, you'll need to write your code as re-usable as possible and then import/reuse as much as you can. Pylint has a check for similar/duplicate code:
For more information on Pylint similarities-checker, see: https://docs.pylint.org/features.html#similarities-checker
Use this built-in django template tag for that:
{% include "subtemplate.html" %}
I am using a markdown editor which is converted by
post_body = markdown(text_from_markdown_editor)
but when i render the html, the actual jinja2 code is displayed
This is a post by {{ post.author }}
instead of the actual value.
I've been seeing this issue come up a lot lately in various different places, both in relation to Jinja and Django Templates. There seems to be a fundamental misunderstanding (among some users) about how templates systems work and how that relates to Markdown text which is rendered to HTML and inserted into a template. I’ll try to explain this clearly. Note that while the answer below applies to most templating systems (including Jinja and Django), the examples use Jinja for illustrative purposes (after all, the original question specifically asks about Jinja). Simply adapt the code to match the API of your templating system of choice, and it should work just as well.
First of all, Markdown has no knowledge of template syntax. In fact, Markdown has been around longer than Jinja, Django or various other popular templating systems. Additionally, the Markdown Syntax Rules make no mention of template syntax. Therefore, your template syntax will not be processed simply by passing some Markdown text which contains template syntax through a Markdown parser. The template syntax needs to be processed separately by the template engine. For example:
from jinja2 import Environment
# Set up a new template environment
env = Environment()
# Create template with the markdown source text
template = env.from_string(text_from_markdown_editor)
# Render that template. Be sure to pass in the context (post in this instance).
template_processed_markdown = template.render(post=post)
# Now pass the Markdown text through the Markdown engine:
post_body = markdown(template_processed_markdown)
Note that the above first processes the template syntax, then parses the Markdown. In other words, the output of the template processing is still Markdown text with the tags replaced by the appropriate values. Only in the last line is the Markdown text converted to HTML by the Markdown parser. If you want the order of processing to be reversed, you will need to switch the code around to run the Markdown parser first and then pass the output of that through the template processor.
I assume that some of the confusion comes from people passing the Markdown text through a templating system. Shouldn’t that cause the template syntax to get processed? In short, No.
At its core, a templating system takes a template and a context. It then finds the various tags in the template and replaces those tags with the matching data provided in the context. However, the template has no knowledge about the data in the context and does no processing of that data. For example, this template:
Hello, {{ name }}!
And this context:
output = template(name='John')
Would result in the following output:
Hello, John!
However, if the context was this instead:
output = template(name='{(some_template_syntax)}')
then the output would be:
Hello, {{some_template_syntax}}!
Note that while the data in the context contained template syntax, the template did not process that data. It simply considered it a value and inserted it as-is into the template in the appropriate location. This is normal and correct behavior.
Sometimes however, you may have a legitimate need for a template to do some additional processing on some data passed to the template. For that reason, the template system offers filters. When given a variable in the context, the filter will process the data contained in that variable and then insert that processed data in the template. For example, to ensure that the name in our previous example is capitalized, the template would look like the following:
Hello, {{ name|capatalize }}!
Passing in the context output = template(name='john') (note that the name is lowercase), we then get the following output”
Hello, John!
Note, that the data in the name variable was processed by having the first letter capitalized, which is the function of Jinja’s built-in filter capitalize. However, that filter does not process template syntax, and therefore passing template syntax to that filter will not cause the template syntax to be processed.
The same concept applies to any markdown filter. Such a filter only parses the provided data as Markdown text and returns HTML text which is then placed into the template. No processing of template syntax would happen in such a scenario. In fact, doing so could result in a possible security issue, especially if the Markdown text is being provided by untrusted users. Therefore, any Markdown text which contains template syntax must have the template syntax processed separately.
However, there is a note of caution. If you are writing documentation which includes examples of Template syntax in them as code blocks (like the Markdown source for this answer), the templating system is not going to know the difference and will process those tags just like any template syntax not in a code block. If the Markdown processing was done first, so that the resulting HTML was passed to the templating system, that HTML would still contain unaltered template syntax within the code blocks which would still be processed by the templating system. This is most likely not what is desired in either case. As a workaround, one could conceivably create some sort of Markdown Extension which would add syntax processing to the Markdown processor itself. However, the mechanism for doing so would differ depending on which Markdown processor one is using and is beyond the scope of this question/answer.
I know that functions can't (shouldn't) be called directly from the template in Django.
But I can't find out how to properly call a simple function. Here is what I would like to do:
On my template I would like to have a hyperlink to paste all relevant information from the template to the clipboard using pyperclip. We frequently have to copy addresses from the database to paste into a word document or an email.
So, copy the data to a String variable and pass that variable to pyperclip.copy() using a hyperlink.
Seems easy enough but I can't find it out.
If you want to include Python code, use a custom template tag in Django.
It sounds like you want something a bit more complex, though. You won't be able to call pyperclip code on the client side -- there's just no Python execution environment in place.
Instead, look into using Javascript or Flash to copy data to the clipboard.
Is there way to find untranslated strings in the HTML templates of my Django application i.e. blocks of text that are not wrapped in trans and blocktrans tags.
Since we have many templates, it would be a very time-consuming process to go through them manually and check but if there isn't an option, I guess it has to be done the long and tedious way.
Thanks
Found this recently, but have not tried it yet.
Doc: http://www.technomancy.org/python/django-template-i18n-lint/
Code: https://github.com/rory/django-template-i18n-lint
Looks like it hasn't been updated in a year but it might provide a good starting spot.
You can use the builtin template parser to parse your templates, and recurse into all tags that are not instances of BlockTransTag