How do I inject actual html from the model to the template? - django

In my admin, I have a text area where the user can input html:
<ul>
<li>blah</li>
</ul>
<p>
Stuffs
</p>
When I push the above to my template and I view the source of the page, I get:
<ul>
<li>blah</li>
</ul>
<p>
Stuffs
</p>
What should I do with my output so that I see actual html in the page source?

you need the 'safe' filter. As it's autoescaped.
{{ my_html|safe }}

See the template tags documentation here, check the autoescape tag description.

By “text area”, do you mean a <textarea>?
Because if so, escaping < to < (et al) is what you must do inside a textarea or any other HTML element: Django is doing the Right Thing. You see the correct, decoded version of the text on the page; who cares what the source looks like?
If you don't escape the contents of a textarea you are not only generating invalid HTML, you're also opening yourself to attacks where the user inputs:
</textarea>
<script>
steal(document.cookie);
location.href= 'russian malware site';
// etc.
</script>

Related

Javascript returns the same id for every iterated element in html

I have website which i build using Django where every visitor can leave their message or press a like button on any comment. I would like to show how many of a comment has been liked by the user.
As each comment is unique, I think to access the comment_id attribute which I wrote in the html part. I then use a simple js function to retrieve the id. The problem is, although html is showing unique id for each comment, Javascript still return the same id, that is the id of the first comment that is written on the page. Can someone tell me where is my mistake in this case?
Thank you in advance for your help.
my code in js:
function likeButton(){ let el = document.getElementById("chat-icon-thumbsup") alert(el.attributes["comment_id"].value) };
my html code, which is looping the datatable records "comment" from a datatable in Django framework:
{% for comment_ in comments %} <strong> {{ comment_.name }} - {{ comment_.date_added }} <button><i comment_id="{{ comment_.comment_id }}" id="chat-icon-thumbsup" class="fa fa-fw fa-thumbs-up" title="like this comment" onclick="likeButton()"></i></button> {{ comment_.nr_of_likes }} <br/> </strong> {{ comment_.body }} <br/> {% endfor %}
image 1: here you see when I inspect the DOM elements, it retrieves different "comment_id"
enter image description here
image 2 and image 3: every button pressed in the comment line alerting the same id, which is 16
enter image description here
I tried to google any possible same problem, but no solutions found
In HTML an ID should be unique on every page. JS will therefore only return the first field it finds with that ID. What you should be using is a class-name that defines your field, like this for example:
<i id="comment_{{ comment_.comment_id }}" class="fa fa-fw fa-thumbs-up chat-icon-thumbsup" ....>
Then you can use document.getElementsByClassName("chat-icon-thumbsup"), there is a reason why it's called getElementById as singular and not getElementsById

How to avoid that Django adds url link to every html element that follows the link

i would like to achieve something very basic in Django but can't find out what I am doing wrong. On my apps "index.html", I would like to add a button which redirects to another html template ("site.html") with other content. I added the following to "index.html" which is working:
<body>
<h2>foo</h2>
{% block content %}
<button><a href="{% url 'site' %}"/>Click</button>
{% endblock %}
<p>bar</p>
</body>
Clicking on the button gets me to "site.html", however all html items which I add on "index.html", for example the paragraph "bar" would also get rendered as hyperlink.
I tried creating different Django blocks or making different html sections but that doesn't fix it.
Thank you for your help.
You're missing a closing anchor </a> tag after your element.
<body>
<h2>foo</h2>
{% block content %}
<button>Click</button>
{% endblock %}
<p>bar</p>
</body>
I will note that I'm not sure it's "correct" to have an anchor tag within a button. I think you're better off styling your anchor tag to appear as a button.

Rendering in django template paragraph behaves weird

I have the following code in my template:
<p>{{ form.end_at }}</p>
<p>{{ form.weekdays }}</p>
It renders as follows:
<p><input type="text" name="end_at"></p>
<p></p>
<ul>
<li>..</li>
..
</ul>
<p></p>
So why does the first call places the input in the p and the second creates two p tags instead of placing the ul in the p as well?
It's not Django doing this, its the browser "normalizing" what it sees as invalid markup. According to HTML spec, <p> tags can't contain <ul> tags:
List elements (in particular, ol and ul elements) cannot be children
of p elements.
The spec recommends either closing the paragraph before staring the list: <p>...</p><ul>...</ul><p>...</p> (which is exactly what the browser did) or to use <div> instead of <p>.
To test, try downloading the page using wget and opening in a text editor - you'll see that the generated markup is what you told Django to render, no extra tags added.

flatiron implementing WP style plates

How would I insert my navigation into my html file as following. (sort of wordpress style)
home.html:
<html>
<body>
(I dont know what to put here for nav)
<div main>
</div>
</body>
<html>
nav.html
<nav>
<img scr="logo.png">
<ul>
<li>home</li>
</ul>
</nav>
And then how do I implement the template on the with plates?
Note:
I'm using flatiron,plates,director
Plates doesn't support a way to inject html into another string.
It's used to bind DATA to your markup.
The easiest solution would be using files which can be concatenated in a sequence to form the page you want.
Example:
header.html
disclaimer.html
page1.html
page2.html
page3.html
footer.html
After choosing which components you need (let's say header.html, page2.html and footer.html) you can use plates to bind your data to the page markup and send everything back to the client.
Plates does support partials, see https://github.com/flatiron/plates#partials.
And here's another method (probably from before Plates had explicit support for partials):
https://stackoverflow.com/a/10076623/263447

django display textfields

I have a form with textfields in Django, and users enter texts line by line.
When I look at the entries in admin side, I saw exactly how user wrote it but when I display it on my website, in Django templates, it just joins the sentences and I couldn't display the text line by line anymore.
To illustrate, user enters text as
-bla
-bla1
-bla2
However, it looks like in my page as
-bla1-bla2-bla3
This is my code in the template:
<div>
<p>
{{ rev.myTextField }}
</p>
</div>
In HTML, newlines between text don't imply a newline in display; you need to use HTML to insert the newline. The most straightforward way is with the <br /> tag, although there are other methods as well.
Django has a template filter for this: use |linebreaks. Here's the Documentation.
So, change:
{{ rev.myTextField }}
to:
{{ rev.myTextField|linebreaks }}
Try "safe" tag
{{ rev.myTextField|safe }}
using
{{ rev.myTextField|linebreaks }}
disables <small> tag, its better to use
{{ rev.myTextField|linebreaksbr }}
it just put <br> tag, not <p>