I am attempting to use markdown to avoid having to type HTML within my wiki form, but for some reason the form is displaying HTML code instead of the intended formatting.
My view function is as follows:
from django.shortcuts import render_to_response
from mywiki.wiki.models import Page
from django.http import HttpResponseRedirect
import markdown
def view_page(request, page_name):
try:
page = Page.objects.get(pk=page_name)
except Page.DoesNotExist:
return render_to_response('create.html', {'page_name':page_name})
content = page.content
return render_to_response('view.html', {'page_name':page_name, 'content':markdown.markdown(content)})
This is my view.html template:
{% extends 'base.html' %}
{% load wikilink %}
{% block title %}{{page_name}}{% endblock %}
{% block content %}
<h1>{{page_name}}</h1>
{{content|wikify}}
<hr/>
<a href='/mywiki/{{page_name}}/edit/'>Edit this page?</a>
{% endblock %}
And this is my base.html:
<html>
<head>
<title>{{% block title %}{% endblock %}</title>
</head>
<body>
<div>
Menu: <a href='/mywiki/Start/'>Start Page</a>
</div>
{% block content %}
{% endblock %}
</body>
</html>
I do have markdown installed, and my Django version is 1.4.1 (Mac).
Thanks.
Use Django's safe filter so as for your Html not to be escaped.
{{ content|safe }}
{% autoescape off %}
{{content|wikify}}
{% endautoescape %}
maybe ...
Related
I have the following structure of templates:
main.html
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% include 'heading.html' with title=title %} {# but this does not work since it is not a variable #}
</body>
</html>
heading.html
<p>
{{ title }}
</p>
page.html
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
How can I pass the title from page.html to heading.html? Ideally, it should be defined as a block like now, but alternatives are also welcome. I'd like to contain the solution within the templates if possible.
Clarification:
This is a minimal example, but I have multiple pages like main.html that share a larger header that has title and some other variables that I'd like defined in the child template (not necessarily as variable as long as the text is passed).
I could put the title into the view code, but this solution would just decrease the separation of displayed data from the logic.
Use a block around the include with variables, and then wrap {{ block.super }} in the with template tag.
main.html:
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% block with_variables %}
{% include 'heading.html' %}
{% endblock %}
</body>
</html>
page.html:
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
{% block with_variables %}
{% with title="variable title" %}
{{ block.super }}
{% endwith %}
{% endblock %}
You may name it {% block heading %}, or nest the whole main.html in {% block content %}.
instead of {% include %}, you might want to use custom template tags with returning html or extension like slippers
You don't need heading.html. You can use the context variable title directly; as long as you pass it to your render function in your view, e.g.:
views.py
def my_view(request):
context = {'title': 'Hello World!'}
return render(request, 'page.html', context=context)
main.html
<html>
<body>
<p>
This is my title:
{% block title %}{% endblock %}
</p>
</body>
</html>
page.html
{% extends 'main.html' %}
{% block title %}
<strong>{{title}}</strong>
{% endblock %}
If you have administrative rights to your Django installation, an easy and elegant solution would be to switch your Django's template renderer to Jinja2 instead using django-jinja as a backend.
The main advantage of Jinja2 for the needs of this question is that it supports assignment of a block to a variable through block assignments. Since Jinja2 is inspired by the Django template language, your existing templates will need few modifications, if any.
With Jinja2 as a template renderer, you can set the title variable with a block of HTML content in the child template:
page.html
{% extends 'main.html' %}
{% set title %}test title{% endset %}
The title variable will then work in the shared template:
main.html
<html>
<body>
<p>
Main template works: {{ title }}
</p>
{% include 'heading.html' %}
</body>
</html>
And it will also work in the included template:
heading.html
<p>
Included template also works: {{ title }}
</p>
Demo: https://replit.com/#blhsing/AlarmedCleverDebugmonitor
One possible solution is to split heading.html into two and add a {% block %} in-between, but this is an ugly workaround that is prone to bugs with unclosed tags.
I am searching for a better alternative.
main.html
...
{% include 'heading1.html' %} {# containing <p> #}
{% block title %}{% endblock %}
{% include 'heading2.html' %} {# containing </p> #}
...
Additionally, if white spaces are important, there has to be no new line between includes and the block.
add your title to the rendering context and it will be visible in page, main and included heading.
I'm trying to load different html files into the base.html and they're not showing. Any ideas?
<body class="bg">
<main class='text'>
{% block carousel %}
{% endblock %}
{% block info%}
{% endblock %}
{% block content %}
{% endblock %}
{% block mobile %}
{% endblock %}
</main>
</body>
I think you may be confusing template inheritance with template composition.
In template inheritance, you have a base page like base.html:
<body class="bg">
<main class='text'>
{% block carousel %}
{% endblock %}
{% block info%}
{% endblock %}
{% block content %}
{% endblock %}
{% block mobile %}
{% endblock %}
</main>
</body>
Then, you have a second template shoes.html that extends base.html. It inherits all the HTML from base.html, but fills in some custom content inside the blocks:
{% extends "base.html" %}
{% block carousel %}
<p>Carousel</p>
{% endblock %}
{% block info%}
<p>Info</p>
{% endblock %}
{% block content %}
<p>Content</p>
{% endblock %}
{% block mobile %}
<p>Mobile</p>
{% endblock %}
Therefore, when you render it inside your view:
views.py
from django.shortcuts import render
def index(request):
return render(request, 'polls/shoes.html', {})
you get this result:
<body class="bg">
<main class='text'>
<p>Carousel</p>
<p>Info</p>
<p>Content</p>
<p>Mobile</p>
</main>
</body>
I suspect that you have different HTML files named after each block (e.g. carousel.html, info.html). That's not how Django works (but it is how Ruby on Rails works). Is that what you were trying to do? If not, please update your question to clarify.
I can't expand the template base.html template header.html
Content base.html
<div id="main-container">
<!-- HEADER -->
{% block header %}{% endblock %}
<!-- END HEADER -->
</div>
Content header.html
{% extends "blog/base.html" %}
{% block header %}
<header id="header">
***
</header>
{% endblock %}
The output in the browser get the code:
<div id="main-container">
<!-- HEADER -->
<!-- END HEADER -->
Why not be able to extend the template?
Using {% include "blog/header.html"%} code inserted. using extends no.
Use Django 1.10.1
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
from django.shortcuts import render, get_object_or_404
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/index.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404 (Post, pk=pk)
return render(request, 'blog/base.html', {'post': post})
def header(request):
return render(request, 'blog/header.html')
Through
{% include "blog/header.html" %} works. So the way spelled out correctly.
Thought the error here:
def header(request):
return(request, 'blog/header.html')
def header(request):
render(request, 'blog/header.html')
def header(request):
return render_to_response (request, 'blog/header.html')
Not working (((
If you want to extend some template, you should render template with {% extends ... %} tag (in your case header.html), if you want to include something to renedered template, you should use {% include ... %} tag. You can make new template for particular page and ovreload {% block head %}, for example:
base.html:
{% block header %}
{% include 'std_header.html' %}
{% endblock %}
{% block content %}
{% endblock %}
{% block footer%}
{% endblock %}
And particular page, for example landing page will overload default header:
landing.html:
{% extends 'base.html' %}
{% block header %}
{% include 'landing_header.html' %}
{% endblock %}
{% block content %}
<!-- landing page content -->
{% endblock %}
So for view called landing_page you have to render landing.html template.
I think you would have confused between the include and extend in django templates.
Based on your file names, I assume that header.html is the partial which is to be included in the base.html and you are rendering base.html .
Django templating engine does not work this way.
Use include {% include "path/to/header.html" %} in base.html and juse have the header html in header.html.
here's my generalized question:
base.html :
<html>
<head>
{% if title %}
<title>{{title}}</title>
{% else %}
<title>test</title>
{% endif %}
</head>
<body>
{% block content %} {% endblock %}
</body>
</html>
How can I write a function that can directly create a block? maybe something like:
#app.route("/foo")
def foo():
content = "<h1>this is foo page</h1>"
return render_html("base.html", content = content)
You are trying to render HTML in your Jinja2 template without HTML escaping. By default, Jinja2 is configured to do automatic escaping of all variables you interpolate.
This means that
<h1>this is foo page</h1>
is actually rendered as
<h1>this is foo page</h1>
so you don't accidentally use HTML in your pages where you didn't mean to. This is very important to protect against Cross Site Scripting (XSS) attacks.
If you are going to bypass this automatic escaping, and deliberately insert HTML into your templates, you must make sure you know what you are doing - never allow unescaped user input to get into these variables.
With the background lesson and security warnings out of the way, if you do know what you are doing, you can explicitly mark values as "safe" in your template, so they will not be escaped. Just use Jinja2's builtin filter, safe, like so:
<body>
{{ content | safe }}
</body>
In your case, I think you also wanted to have a block, so you can override with template inheritance. For an example of that, play with this complete example app
test.py:
import flask
app = flask.Flask(__name__)
#app.route("/foo")
def foo():
content = "<h1>this is foo content</h1>"
return flask.render_template("base.html", content=content)
#app.route("/bar")
def bar():
content = "<h1>this is bar content</h1>"
return flask.render_template("child.html", content=content)
if __name__ == "__main__":
app.run(debug=True)
templates/base.html:
<html>
<head>
{% if title %}
<title>{{title}}</title>
{% else %}
<title>test</title>
{% endif %}
</head>
<body>
{% block content %}{{ content | safe }}{% endblock %}
</body>
</html>
templates/child.html:
{% extends "base.html" %}
{% block content %}
{{ super() }}
<h2>And this bit comes from the child template</h2>
{% endblock %}
view :
#app.route("/foo")
def foo():
content = "<h1>this is foo page</h1>"
return render_template("base.html", content = content)
base.html:
<html>
<head>
{% if title %}
<title>{{title}}</title>
{% else %}
<title>test</title>
{% endif %}
</head>
<body>
{% block content %}
{% if content %}
{{ content | safe }}
{% else %}
No content provided
{% endif %}
{% endblock %}
</body>
</html>
Is it possible to parse a django template and only render a specific tag ?
This snippet is close to what I'm looking for but it doesn't return the entire template.
Basically if I have this template as input
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
{% mycustomtag "args" %}
{% endblock content %}
</body>
</html>
and i want to only render mycustomtag this is the output Im looking for
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
<p>Result from mycustomtag</p>
{% endblock content %}
</body>
</html>
Thanks.
If I properly understand your question, then there is a way to do that, using the {% verbatim %} tag. It will be added in Django 1.5, but for now you can use it as your custom tag - here is the source: https://code.djangoproject.com/ticket/16318
The only drawback here is that you cannot use directly this template, it needs double rendering. If this is what you need - then everything is OK.
To use it, all you need to do is to enclose the other tags with {% verbatim %} :
{% load my_custom_tags %} <-- this is needed to load the 'verbatim' and 'mycustomtag' tags
{% verbatim %}
<html>
<title>{% block title%}{% endblock %}</title>
<body>
{% block content %}
{% endverbatim %}
{% mycustomtag "args" %}
{% verbatim %}
{% endblock content %}
</body>
</html>
{% endverbatim %}
I've made a simple test with this template:
#register.simple_tag
def mycustomtag(a):
return "<p>%s</p>" % a
....
from django.template import loader, Context
print loader.get_template("test.html").render(Context({}))
This prints the following:
<html>
<title>{%block title%}{%endblock%}</title>
<body>
{%block content%}
<p>args</p>
{%endblock content%}
</body>
</html>
Hope this could be helpful.