jinja2: render template without extend - jinja2

How I can render template without extend? i have simple renderer and i want after findout this request is ajax just render goal data
my template:
{% extends "base.html" %}
{% load i18n %}
{% block extrahead %}
{% endblock extrahead %}
{% block content %}
<div class="itemBg">
<div class="itemTop">
<div class="itemDown">
<div class="rowContainer">
<div class="show att">
{{ msg }}
</div>
</div>
</div></div></div>
{% endblock %}
only i want this in render response for ajax request.
<div class="itemBg">
<div class="itemTop">
<div class="itemDown">
<div class="rowContainer">
<div class="show att">
{{ msg }}
</div>
</div>
</div></div></div>
this is my render interface
from flask import current_app, render_template
def render(template, **context):
"""
"""
return render_template(path(template), **context)

You are looking for the null-master fallback trick. Since request is available in the Jinja2 context, if you are using a library that sets the appropriate header you can simply do this:
{% if not request.is_xhr %}{% extends "base.html" %}{% endif -%}
{% load i18n %}
{% block content %}
<div class="itemBg">
<div class="itemTop">
<div class="itemDown">
<div class="rowContainer">
<div class="show att">
{{ msg }}
</div>
</div>
</div></div></div>
{% endblock %}

Put the block you want for AJAX in a separate template.
When you get an AJAX request, just render that new template. For non-AJAX requests, include it in the one that extends base.html.

Related

Django DRY - How to extend two .html files inside a Django Template?

What do I want?
I want to extend cards/apps.html inside addstudents.html so that I don't need to write the chucks of codes multiple times. What can I do to extends multiple .html files inside DJANGO template?
Error I am getting
'extends' cannot appear more than once in the same template
WHAT TO DO?
NOTE: I don't want to use {% include %}, because the situation/condition isn't suitable.
SOME INFORMATION YOU MAY NEED...
Inside cards/apps.html
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{{card_title}}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
Inside addstudents.html
{% extends 'layouts/panel.html' %}
{% extends 'apps/card.html' %}
{% load static %}
{% block content %}
{% with card_title='My Card TITLE' %}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock %}
{% endblock %}
What's inside layouts/panel.html
layouts/panel.html contains some menu and navbars items [including CSS, bootstrap and JS dependencies].
What's apps/card.html?
apps/card.html contains the code-snippet of HTML and Bootstrap CARD. And I don't want to write this code multiple times. That's why I want it to be manipulated via Django Template Tags.
HOPE YOU UNDERSTOOD
I don't think this is directly possible. But here is a work around. In the view which handles addstudents.html, add has_card to the context as True.
views.py
def app_students(request):
# Your code
return render(request, 'addstudents.html', {'has_card': True})
layouts/panel.html
[...]
{% if has_card %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{{card_title}}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
</div>
{% endif %}
[...]
addstudents.html
{% extends 'layouts/panel.html' %}
{% with card_title='My Card TITLE' %}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock %}
So this, if has_card doesn't exist, won't have the card_body block, but if it does exist as a truthy value, then it will.
I'm not sure if it fits your need.
One way could be to split the responsibilities a bit between the different templates.
From given information it could be possible to put bootstrap/layout stuff in cards/apps.html and add additional blocks for childs to override to just handle the forms and view specific information.
To clarify the inheritance that may resolve the problem:
layouts/panel.html -> apps/card.html -> addstudents.html
The apps/card.html overrides block content from layout/panel.html and adds additional blocks which are used by the addstudents.html.
It can also be seen as, in words: addstudents.html extends card.html which extends panel.html.
Afaik you can extend as many times you want, but not use extends twice in the same template.
cards/apps.html
{% extends 'layouts/panel.html' %}
{% block content %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">{% block card_title %}{% endblock %}</h6>
</div>
<div class="card-body">
{% block card_body %}
{% endblock %}
</div>
{% endblock content %}
addstudents.html
{% extends 'apps/card.html' %}
{% block card_title}My Card TITLE{% endblock card_title%}
{% block card_body %}
...SOME FORM, .... SOME PARAGRAPH
{% endblock card_body %}
Worth mention is also {{ block.super }} which can be quite useful sometimes if you need to render a "parent".

How to use different css for queryset objects?

I have different styles of heading in a 5- column layout newspaper template. I want to apply different css to the title of each column. The queryset is the {% block content %}How can I iterate over the queryset objects and apply different css to each {{ post.title }} variable? Note: html truncated for brevity.
<div class="content">
<div class="columns">
{% block content %}
{% endblock %}
</div>
<div class="column">
<div class="head">
<span class="headline hl1">May the Force be with you</span>
<p><span class="headline hl2">Let go your conscious self and act on instinct</span></p>
</div>
</div>
</div>
i think that {% cicle %} will help you.
{% for o in some_list %}
<div class="{% cycle 'class1' 'class2' 'class3' %}">
...
</div>
{% endfor %}
more about built-in template tags you could read
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#cycle

is there any way to apply different class in the forloop of Jinja template

i'm an beginer to Jinja. I have a problem when i want to apply different style in Jinja forloop. I had searched the web but couldn't find a solution.
In python i pass a list to Jinja template as below:
my_list = [
{"Message": "this is sender message",
"Des": 1
},
{ "Message": "this is receiver message",
"Des": 0
} ]
...
render_template(
messages = my_list
)
In template, i want to apply different style according to message.Des .
{% for message in messages %}
{% if message.Des==1 %}
<div class="sender_message">
{% else %}
<div class="receiver_message">
{% endif %}
<div>
<img src={{ url_for("static", filename="img/info.jpg") }} width="36px" height="36px">
</div>
<div>
<pre>
{{message.Message}}
</pre>
</div>
<div class="clear"></div>
</div>
{% endfor %}
But, as the forloop doesn't support continue/break, above code doesn't work.
Here I want to know, is there a way to implement the same function? Many thanks to you!
You can apply different styles based on the message.Des value. Use the variable as your div id value.
Here is the code.
{% for message in messages %}
{% if message.Des==1 %}
<div class="sender_message">
{% else %}
<div class="receiver_message">
{% endif %}
<div>
<img src={{ url_for("static", filename="img/info.jpg") }} width="36px" height="36px">
</div>
<div id={{message.Des}}>
<pre>
{{message.Message}}
</pre>
</div>
<div class="clear"></div>
</div>
{% endfor %}

Django - Generalising a Template with Optional Sidebar

I have a working solution for a template that allows for optional sidebars. Depending on the options selected by the user; significant DOM manipulations occur.
The working solution is unnecessarily large and features some code duplication. It also doesn't extend nicely.
I'm looking for a far more generic solution. One that allows for easier extending or abstracting so as to not have to repeat myself for every page that features a sidebar.
The Working Solution
{% extends "app/base.html" %}
{% load wagtailcore_tags %}
{% block content %}
{% if self.sidebar == "left" %}
<div class="row">
<div class="4u 12u(mobile)">
{% include "app/includes/sidebar.html" with sidebar_items=self.sidebar_items.all %}
</div>
<div class="8u 12u(mobile) important(mobile)">
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
</div>
</div>
{% elif self.sidebar == "right" %}
<div class="row">
<div class="8u 12u(mobile)">
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
</div>
<div class="4u 12u(mobile)">
{% include "app/includes/sidebar.html" with sidebar_items=self.sidebar_items.all %}
</div>
</div>
{% else %}
<article class="box post">
{% include "app/includes/banner.html" with feed_image=self.feed_image only %}
{{ self.body|richtext }}
{% include "app/includes/related_links.html" with related_links=self.related_links.all only %}
</article>
{% endif %}
{% endblock %}
{% block content %} is first defined here in app/base.html:
<div id="main-wrapper">
<div class="container">
<!-- <article class="box post"> -->
{% block content %}{% endblock %}
<!-- {% include 'app/includes/prev_next.html' %} -->
<!-- </article> -->
</div>
</div>
And sidebar.html looks like this:
{% load wagtailimages_tags %}
{% for sidebar_item in sidebar_items %}
<section class="box">
{% image sidebar_item.image original as img %}
<img src="{{ img.url }}" alt="" />
<header>
<h3>{{ sidebar_item.title }}</h3>
</header>
<p>{{ sidebar_item.body }}</p>
{% if sidebar_item.button_text %}
<footer>
{{ sidebar_item.button_text }}
</footer>
{% endif %}
</section>
{% endfor %}
My initial attempt at generalising it was to try to do all of the conditionals in app/base.html but I faced issues when it came to optionally the location of {{ block content }}.
Any help greatly appreciated.
If the condition to decide type of sidebar are being decided and supplied by the views.py function serving the page, then the best approach would be to simply make different template for each different page.
This solution sounds overly simple, but if correctly modularized(in terms of all the common code being kept in a basefile and being extended as and when needed), this would be the best approach. Even though the number of other templates might increase, it will give shorter load times because of smaller HTML snippets.
In case you do not want the conditional decisions being handled by views.py , you can alternatively use AJAX, and asynchronously change the template being viewed without causing a reload.
Hope this helps!

How to arrange content into grid view dynamically?

I want to arrange the following Figure1 content into horizon grid view, here content coming into vertical so, how to arrange into horizontal grid view, like Figure2
Figure1:
Figure2:
Here I only required the css class in div, Please tell the css class to arrange the grid into horizontal form.
Jinja2 Templates
_data_grid.html
This template, takes rows(number of data, like in the following Figure2 we have 5 data), and columns(Image Name, Type, Status, public, protected, Formate, size, Action), All these info comes from the database and django framework.
{% load i18n %}
{% with table.needs_form_wrapper as needs_form_wrapper %}
<div class="table_wrapper">
{% if needs_form_wrapper %}<form action="{{ table.get_full_url }}" method="POST">{% csrf_token %}{% endif %}
{% with columns=table.get_columns rows=table.get_rows %}
{% block grid %}
<grid id="{{table.slugify_name}}">
<div>
{% block grid_caption %}
<h3 class='table_title'>{{ table }}</h3>
{{ table.render_table_actions }}
{% endblock grid_caption %}
</div>
</br>
</br>
</br>
</br>
{% block grid_body %}
<div>
{% for row in rows %}
{{ row.render }}
{% empty %}
{{ table.get_empty_message }}
{% endfor %}
</div>
{% endblock grid_body %}
</grid>
{% endblock grid %}
{% endwith %}
{% if needs_form_wrapper %}</form>{% endif %}
</div>
{% endwith %}
_data_grid_cell.html
This template is used to fill the content,
{% if cell.inline_edit_mod and cell.update_allowed %}
{% else %}
{% if cell.inline_edit_available and cell.update_allowed %}
{% else %}
<ul>{{ cell.value }}</ul>
{% endif %}
{% endif %}
If you want to code the css your self flexbox will be what you are looking for. But I will be easier and probably cleaner to use css frameworks like Bootstrap, your code should look somthing like this, then you can add django template tags:
<div class="container">
<div class="row">
<div class="col-sm-4 col-md-4"><!--block 1--></div>
<div class="col-sm-4 col-md-4"><!--block 2--></div>
<div class="col-sm-4 col-md-4"><!--block 3--></div>
<div class="col-sm-4 col-md-4"><!--block 4--></div>
</div>
</div>
Check (Bootstrap Grid) for more details and explanation for the css classes.