GAE Django webapp2 template render - django

I have a question on template render in GAE. I would like to import a text file and write it to a html file. In this text file, I have used html symbols to tag new lines new paragraphs. It worked well with webapp. However, the same expression does not work with webapp2. So please give me some suggestions.
Thank you!
import webapp2
text_file2 = open('text1.txt','r')
x = text_file2.read()
html = html + template.render(templatepath + 'A.html', {'model_attributes':'Overview','text_paragraph':x})

I don't believe that the problem is webapp2 as much as it is Django 1.2, which is, I believe, the default version that you get with GAE as of a recent release of the SDK. The Django 1.2 templating engine differs from the 0.96 version in that it automatically HTML-escapes the content of template variables, and that is probably changing what you expect to see in your render page.
To fix it, you should add the |safe filter to the variable substitution in your template. So, if your template has something like this:
{{ text_paragraph }}
it should look like this:
{{ text_paragraph|safe }}
You can find out more information about this, including more options for dealing with Django's HTML-escaping here
And here is the official Django documentation on the safe filter.

Related

Use object variable in base.html of Django

I come from Ruby on Rails and I am trying to learn Django. There are multiple things that puzzle me when it comes to how to solve simple things. I have a sidebar in which I would like to have a link to a random item.
My first thought was to use:
Random headline
Although it works perfectly fine to run Headline.objects.order_by('?')[0].id in the shell, this causes an error in Django:
Could not parse the remainder: '('?')[0].id' from 'Headline.objects.order_by('?')[0].id'
which I find very weird since 'Headline.objects.order_by('?')[0].id' creates a number (id) and if I put the same number in as
Random headline
it works perfectly fine.
Another option would be to create this previously in the template, like
{% rand_id = Headline.objects.order_by('?')[0].id %}
Random headline
which is I would hotfix it in Rails - but this doesn't work. The third option (which is better than the 2nd) is to put the variable in the view. However, this is not really viable since this code is in the sidebar and I cannot pass this in every view (DRY!).
So, I figure out I should use context templates, which I - after reading up on it find overly complicated for something as simple as this.
Is there really no good, simple way to solve this problem? Or am I "thinking too much rails"?
In your case a custom template tag would be just fine.
https://docs.djangoproject.com/en/4.0/howto/custom-template-tags/#writing-custom-template-tags
from django import template
from django.utils.html import format_html
register = template.Library()
#register.simple_tag
def random_headline_link():
random_headline = Headline.objects.order_by('?')[0]
headline_url = reverse('headline_detail', args=[random_headline.id,])
return format_html('Random headline', url=headline_url)
{% random_headline_link %}
<!-- the rest is not needed anymore, as it is all coupled together in the templatetag -->
Or if you only like/need the URL, you could use the following templatetag code.
from django import template
register = template.Library()
#register.simple_tag
def random_headline_url():
random_headline = Headline.objects.order_by('?')[0]
return reverse('headline_detail', args=[random_headline.id,])
Random headline

how to remove html tags in django template on browser while showing to user

As shown in figure i used {{options|safe}} for rendering options in my django 3.0 polls application even though it is rendering like that and i don't know how to remove the tags from rendered string, thanks for help in advance
regarding tag error
To remove tags, I would recommend using Mozilla's bleach library.
In order to remove tags only in the front-end, not the data itself, you can easily create a custom template filter and clean the tags inside it.
Another cool idea would be to have list of enabled HTML tags that can be used (like making text bold with <b>...</b>) and then render the input as a valid html:
{{ options|remove_tags|safe }}
Example for a custom template filter:
#register.filter
def remove_tags(value):
return bleach.clean(value, tags=["b", "i"])

Is it possible to change django's template tag {{?

Given that i already have a large angularjs based code with template tag as {{ - is it possible to change django's template tag to maybe {[{ .. ?
Update
Perhaps dynamically patch it
import re
import django.template.base
django.template.base.VARIABLE_TAG_END = '}]}'
django.template.base.VARIABLE_TAG_START = '{[{'
django.template.base.tag_re = re.compile(ur'(\{\%.*?\%\}|\{\[\{.*?\}\]\}|\{\#.*?\#\})')
reload(django.template)
Put this in __init__.py of your any apps and see if it works.
No simple way currently, they are hardcoded:
VARIABLE_TAG_START = '{{'
VARIABLE_TAG_END = '}}'
Anyway, you could patch your local installation or forked version.

gae_mini_profiler {% profiler_includes %} gives Invalid block tag: 'profiler_includes'

I am attempting to install gae_mini_profiler in my django-nonrel app
I placed the {% profiler_includes %} tag at the bottom of my base.html
It results in a
Exception Type: TemplateSyntaxError
Exception Value: Invalid block tag: 'profiler_includes'
I placed
from gae_mini_profiler import profiler
application = profiler.ProfilerWSGIMiddleware(application)
at the bottom of djangoppengine/main/__init__.py
I followed all the other instructions at https://github.com/kamens/gae_mini_profiler#start
What am I doing wrong?
I solved this by changing gae_mini_profiler/templatetags.py to be a true template tag library.
To do this create a package called templatetags, and then move(and rename) the templatetags.py module to profiler_tags.py.
Inside of profiler_tags.py make the following changes:
Change:
from google.appengine.ext import webapp
register = webapp.template.create_template_register()
To:
from django.template import Library
register = Library()
Change:
path = os.path.join(os.path.dirname(__file__), "templates/includes.html")
To:
path = os.path.join(os.path.dirname(__file__), "../templates/includes.html")
In your settings file add gae_mini_profiler to your list of installed apps.
Remove all references to
template.register_template_library('gae_mini_profiler.templatetags')
In your templates whereever you had {% profiler_includes %} you then need to add a load block
{% load profiler_tags %}
I think that is all of the changes, but need to go check my git log.
Are you using the new Python 2.7 runtime for GAE? If so, the django template setup is slightly different and gae_mini_profiler hasn't been upgraded yet (anyone is welcome to submit this fix, haven't gotten to it yet).
It should be easy to work around as the only thing you need to do is find a way to render the HTML string returned by gae_mini_profiler.templatetags.profiler_includes() anywhere in your page. There are a number of methods of accomplishing this if the built-in template tag isn't working as-is. You could simply call the function in your base request handler and pass the resulting html into your base template if absolutely necessary (although this is admittedly a gross hack).
We'll hopefully have Python 2.7 working w/ gae_mini_profiler shortly. If you're not on Python 2.7, I'm not sure what the issue is as I'd expect the current code to work...

How can you use Django template tags in a Jinja2 template?

There are a number of off-the-shelf Django packages that offer template tags, and I'd like to use them in my project despite the fact that it uses Jinja2.
I've seen some workarounds that allow other template engines to use Django tags. These involve creating a mini-template in a string, and passing it to the Django template processor along with the current context. Here are two example of what I'm talking about: Mako templates using Django template tags and Jinja2 templates using Django template tags.
I'm wondering if there's a less hackish solution.
what about moving problem to python's scope
and importing one python's function into another, this way:
in your_jinja_templatetags.py
from some_django_templatetags import somefilter as base_somefilter
#library.filter
def somefilter(value):
return base_somefilter(value)
Unfortunately Django template tags are not directly translatable to Jinja.
Django Template tags can do many different things, and are usually implemented as functions. Fortunately, Jinja can register these functions as globals and call them. This works for "simple" template tags out of the box.
If you are using the official Django Jinja2 backend, see https://docs.djangoproject.com/en/4.1/topics/templates/#django.template.backends.jinja2.Jinja2 to find out how to register a function (in this case your template tag) as a global. Once this is done, you can call the function from within your template as {{ your_tag_function() }}. Remember to pass whatever arguments the template tag function needs!
I like to use the https://github.com/niwinz/django-jinja backend, myself- if you are using this backend, see https://niwi.nz/django-jinja/latest/#_custom_filters_globals_constants_and_tests for how to register a function as a global.
Unfortunately, this only works for "simple" tags out of the box. Some tags are "inclusion tags" or otherwise depend on the Django Template Engine. Since Django Templates can't be rendered within the Jinja engine, you have to do a bit more work to translate these types of tags. You will need to look at the source code to tell the difference and see what they are doing.
What I usually do for the more complicated tags is create a "jinja_functions.py" script in my Django app, then in that script I import the original template tag. Then I write a function that wraps it- calling the original function, getting back usually a dictionary, and then using that dict to render a string which is returned... most tags are simple enough I just use an f string or .format to format them with the results of the dict.
Then I register my new wrapper function as a jinja global and use it in my jinja templates!
The following is an example of where I re-implemented the template tags provided by https://github.com/timonweb/django-tailwind for use with jinja. I combined both the tailwind_css and tailwinf_preload_css tags into a single function, tailwind_css, which I register with Jinja as a global as per the instructions above, then I can call that function as {{ tailwind_css(prefetch=True) }} or {{ tailwind_css() }} within my templates.
from django.templatetags.static import static
from tailwind import get_config
from tailwind.utils import is_path_absolute
def tailwind_css(v=None, prefetch=False):
tailwind_css_path = get_config("TAILWIND_CSS_PATH")
if not is_path_absolute(tailwind_css_path):
tailwind_css_path = static(tailwind_css_path)
if v:
tailwind_css_path = f"{tailwind_css_path}?v={v}"
if prefetch:
rel = 'rel="preload"'
as_str = ' as="style"'
else:
rel = 'rel="stylesheet"'
as_str = ""
return f'<link {rel} href="{tailwind_css_path}"{as_str}>'
In conclusion it works well out of the box for "simple" tags because you can just register them as global functions in Jinja... but for "include" tags or other tags that rely on the Django Template engine, you will have to write your own function :( But usually its not too much work!