Flask Python HTML - flask

I'm trying to render my home HTML file to my main flask python project, but when I run it, it gives this error "jinja2.exceptions.TemplateSyntaxError: unexpected '%'" could somebody help? It will be a pleasure. Currently using PyCharm IDE for this project.
<html>
<head>
<title></title>
</head>
<body>
{{% for post in posts %}}
<h1>{{post.title}}</h1>
<p>By {{post.author}} on {{post.date_posted}}</p>
<p>By {{post.content}}</p>
{{%end for%}}
</body>

When doing conditional statements, it must be enclosed with the following syntax:
{% if true %}
When passing variables to the template, you use the double braces:
<span>MyVar has the value: {{ myvar }}</span>
Another thing to note is that the end for should be endfor

Flask syntax is like {% code %}... not {{% code %}}({{}} just for vars to template) and is {% endfor %} instead of: {{%end for%}}.

Related

Adjust bootstrap within jinja template (Flask Framework)

I would like to adjust default bootstrap class formatting within jinja template. The only thing, what I want to do, is to change the color of the h1 element. But unfortunately, it is still black.
I am using flask and render_template module.
I have following code in template:
{% extends "bootstrap/base.html" %}
{% block head %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="bootstrap_adjust.css">
{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>Hello, Vaclav!</h1>
</div>
</div>
{% endblock %}
boostrap_adjust.css looks like this:
h1{
color:blue;
}
Thank you for any advice!
Vaclav
I ll try to answer the question "how to adjust an element using a .css file instead of styling it directly?"
Go in your base.html file, i.e. the file you extend from, and in the header tag, at the end of all the other stylesheets create a Jinja2 block like so
{% block stylesheets %}
{% endblock stylesheets %}
Second step would be to call this block in your child templates and pass your .css files in there instead of passing it in the head block.
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="bootstrap_adjust.css">
{% endblock stylesheets %}
Give it a try and let us know!
I finally found working solution here:
https://stackoverflow.com/questions/34664156/flask-bootstrap-custom-theme
So in my case this works:
{% block styles %}
{{ super() }}
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='bootstrap_adjust.css')}}">
{% endblock %}
.css file is placed in the folder static. But be careful, static is not part of the path in filename parameter, because url_for('static') looks automatically in this folder.
Thank you all for your willing to help!
Adding a custom CSS file:
{% block styles %}
{{super()}}
<link rel="stylesheet"
href="{{url_for('.static', filename='mystyle.css')}}">
{% endblock %}
Please Read the documentation on Flask-Bootstrap and have a good understanding of super classes.
This is the Link - Flask-Bootstrap

Django templates, including page(s) that injects code into parent block

Is it possible to include a template (with include django template tag) within another template and "inject" some content to the page that includes (parent) through block tag, or something similar?
Let's say I have the following file structure within my project:
App/
(...)
templates/
base.html
index.html
_include1.html
_include2.html
_include3.html
_include4.html
Code for base.html:
<!DOCTYPE html>
<html>
<head lang="en">
(...)
</head>
<body>
<script type="application/javascript">
$(function () {
{% block extra_script %}
{% endblock %}
});
</script>
Code for index.html:
{% extends "base.html" %}
{% load static %}
(...)
<div class="row gutter">
<div>
{% include "_include1.html" with object=object%}
</div>
<div>
{% include "_include2.html" with object=object %}
</div>
<div>
{% include "_include3.html" with object=object %}
</div>
<div>
{% include "_include4.html" with object=object %}
</div>
</div>
And in each _include*.html I would like to call some specific JS function (for example), but I want to place it in the parents (index.html or base.html, doesn't matter in my case) extra_script block. I searched in the documentation, other questions and didn't find a way to do this with the include syntax.
I've done something similar but through extends tag. However I don't want to define a block in the index.html or base.html for each page that I need to include ({% bloc include_* %}.
So the solution that I have now (and works) is to define a script in each included page like this (_include1.html):
<div>
(...)
</div>
<script>
$(function () {
//Code that should be placed within parents script page (this is just an example)
var a = function (){
(...)
};
a();
});
</script>
However I think there's a better way to do this, by making use of django templates engine, and without having to define a block for each page that needs to be included. Also I would like to have all my js code in a single place (parents <script> tag) instead of being scattered all over the place (like it is with the presented solution).
Can anyone give some input or ideas towards this?
Thanks!
Try to use django-sekizai for that purpose.
With sekizai, you can define a JavaScript block just before the </body>:
{% render_block "js" %}
And then whenever you need to add JavaScript to that block, you write this:
{% addtoblock "js" %}
<script type="text/javascript">
// your JavaScript
</script>
{% endaddtoblock %}
If there are duplicates of the content in the {% addtoblock %} blocks, they will be used only once.

Django url get request with parameter

I have following HTML file
<!DOCTYPE html>
<body>
{% for champion in champions %}
{{champion}}
{% endfor %}
</body>
</html>
And these are my URLS
urlpatterns = patterns('', url(r'^select_champion/$', views.select_champion, name='select_champion'),
url(r'^guide_form/(?P<champion>\w+)/$', views.guide_form, name='guide_form'),
url(r'^create_guide/$', views.create_guide, name='create_guide'),
url(r'^get_guide/(?P<id>\d+)/$', views.get_guide, name='get_guide'),
url(r'^guide_list/(?P<champion>\w+)/$', views.get_guide_list, name='get_guide_list'),
)
When I try to select a champion I get following Error:
Reverse for 'guide_form' with arguments '()' and keyword arguments
'{}' not found. 1 pattern(s) tried:
['guides/guide_form/(?P\w+)/$']
When I change this line
{{champion}}
To this
{{champion}}
I don't get an Error but the wrong URL is called of course. I want to select a champion and want the champ to be delivered per url so a guide can be written about him in the guide form.
Do you have any suggestion on how to solve my problem?
Almost there, you need:
{{ champion }}
Your url pattern has a keyword argument champion, and the value is the template variable {{ champion }}. The url tag understands the template context, so you don't need {{ }} around the variable; instead pass it in directly as an argument to the url tag.
It should be like this
<!DOCTYPE html>
<body>
{% for champion in champions %}
{{champion}}
{% endfor %}
</body>
</html>

Reuse a block of code in several places in jinja2

I have this html snippet which needs to be used in lots of places in the jinja2 templates:
<div class="usedalot">{{ somevalue }}</div>
for example, in template1.html, template2.html. template3.html, this code is repeated several places
<!-- template1.html, template2.html. template3.html -->
<div class="usedalot">{{ somevalue }}</div>
......
<div class="usedalot">{{ somevalue }}</div>
....
<div class="usedalot">{{ somevalue }}</div>
......
Instead of copying and pasting, is there someway to use this code snippet as a block? The jinja2 template inheritance (with blocks) do not seem to solve this problem.
What you are looking for is called a macro.
Macros are placed in separate files (e.g., macros.html).
{% macro usedalot(somevalue) %}
<div class="usedalot">{{ somevalue }}</div>
{% endmacro %}
You can then import your macros in other templates
{% from 'macros.html' import usedalot %}
and then use them whenever needed
{{ usedalot(1) }}
This will output
<div class="usedalot">1</div>
As of Jinja 2.8, you can also now use block assignments to map a block (still can only be defined once) to a variable that can be used multiple times in the document.
Documentation is at: Block assignments
I just used the feature to drop my HTML page title block into both the title element as well as the meta property for Facebook's opengraph:title attribute.
{% set title_s %}{% block title %}MY DEFAULT TITLE{% endblock %}{% endset %}
<head>
<meta property="og:title" content="{{ title_s }}" />
<title>{{ title_s }}</title>
...
</head>
This seems to me to be a much more clean solution than defining a macro.

build website for mobile and pc with django

I am trying to develop a website for mobile and pc browser with django.
and I am trying to figure out a best structure of the views and templates.
there is what I have tried:
1) use different url ( like http://example.com/mobile/ and http://example.com/ OR
http://example.com/?c=mobile ) to distinguish mobile and pc, and map them to different view which set different templates.
2) in the view set different template according to USER_CLIENT
3) use a wrapper layer of the view, the actual view just return the data to the wrapper, the wrapper set the different template.
Is there a common way to handle this in django? any suggestions and comments?
Use Django's "sites" framework for a mobile version at http://m.example.com.
I would recommended solution 3; using a decorator to inspect the clients User Agent and returning à different template in case of a mobile agent.
Have the decorator take two arguments: the normal template, and the mobile template.
From your view, return a dict The decorator may pass to the rendering function as context. There is a decorator called 'render_to' that does this very well, Google for it.
To deal with the use case where users want the full version, even when browsing from a mobile device, you may use a redirecting view that sets a cookie your decorator may check for.
best practice: use minidetector to add the extra info to the request, then use django's built in request context to pass it to your templates like so.
from django.shortcuts import render_to_response
from django.template import RequestContext
def my_view_on_mobile_and_desktop(request)
.....
render_to_response('regular_template.html',
{'my vars to template':vars},
context_instance=RequestContext(request))
then in your template you are able to introduce stuff like:
<html>
<head>
{% block head %}
<title>blah</title>
{% if request.mobile %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
{% else %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
{% endif %}
</head>
<body>
<div id="navigation">
{% include "_navigation.html" %}
</div>
{% if not request.mobile %}
<div id="sidebar">
<p> sidebar content not fit for mobile </p>
</div>
{% endif %>
<div id="content">
<article>
{% if not request.mobile %}
<aside>
<p> aside content </p>
</aside>
{% endif %}
<p> article content </p>
</aricle>
</div>
</body>
</html>