Django puts spaces in first Line of TextField - django

I'm creating a webapp where I can present a documentation. In my documentations I often have some code snippets so I used prism (https://prismjs.com/) to format the text I enter in a textfield on the admin page.
The Problem is that whenever I enter code in the textfield it makes spaces on the first line like that:
import { Pipe, PipeTransform } from '#angular/core';
import { UserService } from '../user.service';
My code looks likt this:
Template:
<pre><code class="language-{{ subdoc.language }}">
{{ subdoc.code }}
</code></pre>

Remove the spaces/tab characters before {{ subdoc.code }}
You must be exhausted in coding. Most of the time we think the complicated coding is where something's wrong but in your case it's the HTML.
you sure know how <pre> tag works. Now understand the difference between this
<pre><code class="language-{{ subdoc.language }}">
{{ subdoc.code }}
</code></pre>
and this
<pre><code class="language-{{ subdoc.language }}">
{{ subdoc.code }}
</code></pre>
Happy coding ;)

Related

Django ignore TemplateSyntaxError. Vue Syntax

I'm building a pwa on top of django.
In the pwa.html I use valid vue syntax:
{{ counter() }}
or
{{ el| removehtml() | truncate(40) }}
Works flawless in a non Django project.
I get an TemplateSyntaxError on runserver, how can I ignore this, cause this is valid for vue syntax.
I found 2 solutions:
either in vue with delimiters:
el: '#app',
delimiters: ['[[', ']]'],
data: {
message: ...
}
...
than in template [[ vuefunc() ]] instead of default {{ vuefunct() }}
or with django verbatim
{% verbatim %}
{{ vuefunct() }}
{% endverbatim %}
Please note that Django does not use Jinja. It has its own template syntax, explained here in the documentation.
If you have any exposure to other text-based template languages, such
as Smarty or Jinja2, you should feel right at home with Django’s
templates.
The syntax may look like Jinja, but the functions could be different.

Flask url_for in form action

I have a wtform in my html file, something like this:
{{ wtf.quick_form(form, action="/add/", method="post", extra_classes="form-horizontal",
role="form", form_type="basic") }}
(I actually notice I can omit action). So this works.
Now - if I change it to
action="{{ url_for('add') }}"
, I'm ending up in this url:
http://127.0.0.1:5000/add/%7B%7B%20url_for('add')%20%7D%7D
If I just create a link in html like so:
link
It does work and it gets me to /add/. I was wondering what the difference is.
Thanks!
instead of
action="{{ url_for('add') }}"
try to assign the output of url_for('add') function/helper to action
action=url_for('add')
without {{ and }}
so
{{ wtf.quick_form(form, action=url_for('add'), method="post", extra_classes="form-horizontal", role="form", form_type="basic") }}
Remember not to put commas in the tags ;)

WTForms use quotes in Jinja2

I've got the following WTForms class:
from flask_wtf import FlaskForm
from wtforms import SelectField
class MonitorLevel(FlaskForm):
monitor = SelectField('Monitor', choices=MONITOR_CHOICES)
Which can be rendered using the following jinja2-code:
{{ form.monitor() }}
However, I want to execute a JS-script when the value changes, so I've added the following:
{{ form.monitor(**{'onchange': 'sendForm();'}) }}
Which works fine, but now I want to pass a variable (which is a string), as an argument:
{{ form.monitor(**{'onchange': 'sendForm("{}");'.format(variable)}) }}
However, this renders as:
<select id="monitor" name="monitor" onchange="sendForm("name");">...</select>
So, I tried to escape this using the safe function, but this doesn't work. I've also tried to escape the quote by: \", but that doesn't work as well.
Any ideas of adding a quote in the value of the dict?
Thanks in advance,
From the WTForms documentation https://wtforms.readthedocs.io/en/2.3.x/widgets/#widget-building-utilities :
WTForms uses MarkupSafe to escape unsafe HTML characters before rendering. You can mark a string using markupsafe.Markup to indicate that it should not be escaped.
Without using markupsafe.Markup I had the same error:
{{ input_field(**{'#click': '"show=true"'})|safe }}
gives
<input #click=""show=true"">
instead of
<input #click="'show=true'">
Using the markupsafe module inside the Jinja2 template:
{{ input_field(**{'#click': markupsafe.Markup("show=true")})|safe }}
does the job:
<input #click="show=true">
Be careful: WTForm encloses the string in the double quotes ", so you need to take a usual care about the " inside your string.
BAD WAY
{{ input_field(**{'#click': markupsafe.Markup('console.log("show=true")')})|safe }}
will result in
<input #click="console.log("show=true")">
which is wrong (one string is not inside the other).
GOOD WAY
{{ input_field(**{'#click': markupsafe.Markup("console.log('show=true')")})|safe }}
will give
<input #click="console.log('show=true')"
This behavior is normal, WTForms use escape(s, quote=True) to render HTML attributes values (escape documentation)
You can look function def html_params(**kwargs): on Github directly fore more informations.
Basically you don't have to change your code because :
Javascript still works like a charm, your browser transforms HTML entities on the fly (sendForm() is run onchange).
onchange="sendForm("name");" is NOT valid HTML attribute if you print it without escape(s, quote=True).

Error return truncatechars & safe by using Built-in template tags and filters

I try to Truncates the string and remove the html tags,
First, when I write it this way.
{{ post.context|safe }}
or
{{ post.context |truncatechars:100 }}
The left navigation bar shows normal.
But when I write this, this part of the HTML is gone.
{{ post.context |truncatechars:100|safe }}
But I can still find this Html in the source code.
So what can I do to get the correct results?thank you
If you just want to safely show content with HTML formatting.
{{ post.context|safe }}
If you truncate then some HTML tags may not get closed tag and you will get an irregular view.
If you want to strip HTML tags, you can strip by striptags and truncate characters using slice filters.
{{post.context|striptags|slice:':300'}}
Although it's kinda late to answer if you want to show the safe code with tags then use {{ post.context|truncatewords_html:30|safe }} or {{ post.content|truncatechars_html:100|safe }}. This won't break your code and will display your desired content.
No need to struggle around. You need to combine truncate, safe, and striptags
Respect the order below:
{{ string_variable|striptags|safe|truncate(100) }}
Does that help you?

Django templates - split string to array

I have a model field, which stores a list of URLs (yeah, I know, that's wrong way) as url1\nurl2\nurl3<...>. I need to split the field into an array in my template, so I created the custom filter:
#register.filter(name='split')
def split(value, arg):
return value.split(arg)
I use it this way:
{% with game.screenshots|split:"\n" as screens %}
{% for screen in screens %}
{{ screen }}<br>
{% endfor %}
{% endwith %}
but as I can see, split doesn't want to work: I get output like url1 url2 url3 (with linebreaks if I look at the source). Why?
Django intentionally leaves out many types of templatetags to discourage you from doing too much processing in the template. (Unfortunately, people usually just add these types of templatetags themselves.)
This is a perfect example of something that should be in your model not your template.
class Game(models.Model):
...
def screenshots_as_list(self):
return self.screenshots.split('\n')
Then, in your template, you just do:
{% for screen in game.screenshots_as_list %}
{{ screen }}<br>
{% endfor %}
Much more clear and much easier to work with.
Functionality already exists with linkebreaksbr:
{{ value|linebreaksbr }}
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#linebreaksbr
Hm, I have partly solved this problem. I changed my filter to:
#register.filter(name='split')
def split(value, arg):
return value.split('\n')
Why it didn't work with the original code?
I wanted to split a list of words to get a word count, and it turns out there is a filter for that:
{{ value|wordcount }}
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#wordcount
Apart from whether your original solution was the right approach, I guess the original code did not work because the meaning of the \n is not the same in Python code as it is in HTML: In Python code it means the escaped newline character, in HTML it is just the two separate characters \ and n.
So passing as input parameter \n from the HTML template to the Python code is equivalent to splitting on the Python string \\n: a literal \ followed by a n.