I am developing a website using Flask on the back-end and Jinja for templating. Every page should have the same image as part of the Open Graph Protocol, except for one of them, where I want to customize the url with something peculiar to that page.
The child template (like all other templates) extends base, but only this one will ever have a value set for the variable ob_image_url, therefore I need to check if that value exists and if not set a default value.
When the child page.html template is rendered, I am always getting the default value and not the one for that page. Where am I messing it up?
Thanks!
base.html
{% block og_image %}{% endblock %}
{% if not og_image_url %}
{% set og_image_url = url_for('static', filename='img/logo.png', _external=True) %}
{% endif %}
<meta property="og:image" content="{{og_image_url}}" />
page.html
{% extends "base.html" %}
{% block og_image %}
{% if obj and obj.image %}
{% set og_image_url = obj.image %}
{% endif %}
{% endblock %}
Related
I am a little confused about what {% extends base %} is extending at the start of index.html in Bokeh server application packages.
Examples of this can be seen in:
Bokeh Docs: Embedding in Templates
{% extends base %}
{% block contents %}
<div>
<p> Hello {{ user_id }}, AKA '{{ last_name }}, {{ first_name }}'! </p>
</div>
{% endblock %}
Bokeh Server Application Examples
Example code from the Gapminder package in templates/index.html
{% extends base %}
{% block title %}Bokeh Gapminder Example{% endblock %}
{% block postamble %}
<style>
{% include 'styles.css' %}
</style>
{% endblock %}
What is this "base" that is being extended?
I see that there is a "contents" block, "title" block, and "postamble" block from the above examples.
How do I know what other jinja blocks I can modify?
Thanks.
I am new to Flask and trying to add a background image to all of the pages of my web app. I have saved the background image as 'background-image.jpg' in an 'images' folder within a 'static' folder, in the project. Here is my 'base.html' file which is extended to all my other files.
{% extends 'bootstrap/base.html' %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/custom-styles.css') }}">
{% block title %}
Flog
{% endblock %}
{% block head %}
{{ ckeditor.load() }}
{{ super() }}
{% endblock %}
{% block navbar %}
{% include '_navbar.html' %}
{% endblock %}
{% block content %}
<div class="jumbotron background-img">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}" role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block sub_content %}
{% endblock %}
</div>
{% endblock %}
And here is my css file, saved in a 'css' folder within the 'static' folder named 'custom-styles.css'.
.background-img{
background-image: url('..images/background-image.jpg');
}
When I run the app, the jumbotron is working but it just shows a grey box and no background image. Is anybody able to tell me what I am doing wrong?
Thanks.
.background-img{
background-image: url('../images/background-image.jpg');
}
Try adding the forward slash after the two periods, it looks like it might just be an issue with how the css file is accessing the images folder.
The path to your background image needs to be correct. If that file is a static file then you need the static file path for the background image.
For example, if the path for background-image.jpg is:
path-to-static/images/background-image.jpg
Then instead of ..images/background-image.jpg you would need to use:
.background-img{
background-image: url('/static/images/background-image.jpg');
}
That is, I believe, the default path to static files, though you can make configuration changes to that location.
Using the sf2.6.4 and the Twig templating system, I have a weird behaviour with the tag 'use'.
With a simple base template defining a default navbar and header content :
{# base.html.twig #}
<html lang="fr">
<head></head>
<body>
{% block navbar %}<hr> nav bar foo bar<hr>{% endblock %}
<!-- a default header -->
{% block header %}
{% include 'AppBundle:TestingTwigUse:header.html.twig' %}
{% endblock %}
</body>
With the given default header.html.twig template :
{# header.html.twig #}
{% block header_container %}
{% block header_title %}<h1>Default title</h1>{% endblock %}
{% block header_content %}
<div>
This default text header, blablabla...
</div>
{% endblock %}
{% endblock %}
When I try to build an index template, inheriting the base one and overiding the header content using 'use' tag like following :
{# index.html.twig #}
{% extends "AppBundle:TestingTwigUse:base.html.twig" %}
{% block header %}
{% use 'AppBundle:TestingTwigUse:header.html.twig' %}
{% block header_container %}
{{ parent() }}
{% block header_content %}
***** child template specific content ****
{% endblock %}
{% endblock %}
{% endblock %}
I have the strange following result with header_content block twice :
***** child template specific content **** ***** child template specific content ****
any idea ?
I thinkg the problem is you have two header_content blocks - one in the index.twig.html, second in the parent() call. Second definition overrides first which leads to duplications after compilation.
If you want to override the default text - you should remove parent() call. If you want to update (append) the default text - you should refactor your blocks structure to avoid identical names.
UPD Try following index
{# index.html.twig #}
{% extends "AppBundle:TestingTwigUse:base.html.twig" %}
{% block header_content %}
***** child template specific content ****
{% endblock %}
UPD 2 Check this solution
I found a solution. Use the block() function to get the child's block
content and pass it to header.html.twig as a variable in the include
statement
Finaly two solutions :
With 'use', we can get the part we want to keep but loosing inheritance :
{% block header %}
{% use 'AppBundle:TestingTwigUse:header.html.twig' with header_title as parent_header_title %}
{% block header_title %}
{{ block('parent_header_title') }}
{% endblock %}
***** child template specific content ****
{% endblock %}
The one is 'embeb' that combines include AND extends behaviour :
{% block header %}
{% embed 'AppBundle:TestingTwigUse:header.html.twig' %}
{% block header_content %}
***** child template specific content ****
{% endblock %}
{% endembed %}
{% endblock %}
I'm trying to specify a variable in a child template and access it from another template which is included in the parent template.
Here's what I'm trying to do (code trimmed to the bare minimum):
child.html
{% set var = 'foo' %}
{% extends 'base.html' %}
base.html
{% include 'bar.html' %}
bar.html
{{ var }}
At this point, I render the child.html file and nothing is output.
This is what I've tried:
If I specify the variable in the base.html file instead of the child.html file, it works.
If I pass the variable in my render call, it works. template.render(var = 'foo')
Chaging the base.html file to be {% include 'bar.html' with context %} doesn't fix it.
I am able to access the variable in my base.html file just fine, and in fact, I've managed to create a workaround by adding {% set foo = var %} to my base.html, and changing bar.html to {{ foo }}
So concisely put, my question is: Is there a way for a template that's included in a parent template to access a variable set in a child template? (Without having to define a new variable in the parent file like my workaround)
I was able to get this by passing the variable within the child block on the parent template.
Ex. I have active_page declared on my child template pricing.html.
At first, I was not able to access active_page within my included file navbar-alt.html but when I set the variables inside of the navbar block it worked.
{% block wrapper %}
<div id="wrapper">
{% block navbar %}
{% set navigation_bar = [
('/what-we-do', 'what-we-do', 'what we do'),
('/pricing', 'pricing', 'pricing'),
('/demo', 'demo', 'demo'),
('http://indico.readme.io/v1.0/docs', 'docs', 'docs')
] -%}
{% set active_page = active_page|default('index') -%}
{% if "dashboard" not in request.path %}
{% include 'includes/navbar-alt.html' %}
{% else %}
{% include 'includes/navbar.html' %}
{% endif %}
{% endblock navbar %}
{% if "dashboard" in request.path %}
{% block sidebar %}
{% include 'includes/sidebar.html' %}
{% endblock sidebar %}
{% endif %}
{% block content_wrapper %}
<div id="content">
{% block content %}{% endblock content %}
</div>
{% endblock content_wrapper %}
{% include 'includes/flashes.html' %}
</div>
{% endblock wrapper %}
Original inspiration:
Jinja Tricks
Hi I have a Django Model like below
class Staff(models.Model):
name = models.CharField(max_length = 200)
url = models.CharField(max_length = 200)
URL's are generated from another website and they are like in the databse
www.foo.com/xxx-yyy
www.foo.com/xxx-zzz
When I use a django template like below, link goes to a related url like an extension of my current URL
{% extends "index.html" %}
{% load markup %}
{% block right %}
<h1>Names</h1>
{% for i in persons %}
<p>{{i.name}}</p>
{% endfor %}
{% endblock %}
It goes to mycurrent.url.com/www.foo.com/xxx-yyy
Ok it is fixed by adding http:// before
like;
{% extends "index.html" %}
{% load markup %}
{% block right %}
<h1>Names</h1>
{% for i in persons %}
<p>{{i.name}}</p>
{% endfor %}
{% endblock %}