Idiosyncracy while extending django admin template - django

On my django site, I decided to just use the admin templates for the UI, but I made a few tweaks like the site name, color, etc. even my custom views just extend admin/base_site.html I did this by creating templates/admin/base_site.html with the following code:
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}{{ title }} | {% trans 'Company Name' %}{% endblock %}
{% block extrastyle %}
<style>
#header{ background-color: #a67d3d; border-bottom: solid 3px #f5deb3; }
#branding h1{ color: #fff; }
</style>
{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans 'My company' %}</h1>
{% endblock %}
{% block breadcrumbs %}
{% include "breadcrumb.html" %}
{% endblock %}
The entire admin site has my new title and colors. However, you can see I tried replacing the breadcrumbs bar with my own breadcrumb.html (which contains a custom nav bar). This only works on custom views that extend admin/base_site.html. the normal admin views don't replace the breadcrumbs (but they do have the new colors, company title, etc.). I can't figure out why this one piece isn't working? Moreover, I have a few custom change_form.html files. These also have the style changes, but no custom nav bar. But, if I put in the breadcrumbs block in these pages, it shows up just fine on those pages.

I worked around this by copying the original base.html file into my project's '/templates/admin/' folder, deleted the breadcrumbs block, added a "mynav" block, put my navbar there. This way my nav bar shows up on all pages, and when the lower pages try to put in a breadcrumb there's no block for them and it doesn't show up.
I don't like doing it this way but i can't think of another way. The way suggested by lazerscience would work, but I'd have to do an include in every single template (change_form, change_list, etc.). For others, i should mention, there is a "nav-global" block, but my navbar uses lists/css/jscript to display slideout menus and these menus weren't showing up if i put it in that block, not sure exactly why.

The other admin templates, eg. change_form.html override the breadcrumbs block themselves, so you need to override it also in these templates (=override them and define your block in there).

Related

Using custom fonts in TinyMCE API for editor in django admin

I am trying to use TinyMCE API in Django admin for blog post editing.
It is working flawlessly. However, now I want to add custom fonts to my editor.
As per tinymce
documentation
for adding custom fonts I have followed all steps but still cannot figure out what is wrong.
Step-1: Add fonts as per menu option
admin/base.html:
font_formats:"Andale Mono=andale mono,times; ........ ; Montserrat = Montserrat , sans-serif",`
Step-2: Import fonts in tinymce
admin/base.html:
{% extends "admin/base.html" %}
{% load static %}
{% block footer %}
tinymce.init({
....
content_css: "{% static "TinyMCE/style.css" %}",
content_style:"#importurl('https://fonts.googleapis.com/css2family=Montserrat:ital,wght#0,400;0,600;1,400&display=swap');",
....
{% endblock %}
TinyMCE/style.css
#import url('https://fonts.googleapis.com/css2family=Montserrat:ital,wght#0,400;0,600;1,400&display=swap');
snapshot:
Step3: Import the font on the page
admin/base.html
{% block extrahead %}
<style>
#import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,400;0,600;1,400&display=swap');
* {font-family : 'Montserrat', sans-serif;}
</style>
{% endblock %}
snapshot:
Step4: Import the font on any published pages
I am using tailwind in my project and my default font is Monstserrat which is perfectly working over the site
style.css
#import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,400;0,600;1,400&display=swap');
body{
font-family: Montserrat, sans-serif;
}
Problem:
Although I see the custom font 'Montserrat' in the dropdown on tincymce editor but when I select it falls back to sans-serf.
You can see the snippet here:
Please note that I am not using django-tinymce package rather tinymce API.
Step-1:
Remove space between fonts
Montserrat=Montserrat,sans-serif
This is because font-family: 'Montserrat' would render correctly and not render with a space font-family: ' Montserrat'. In case of space the font will not load on the browser.
Step-2:
We dont have to specify content_style once we have specified content_css. In some cases it might be useful but there is no point to add both in this case. Plus do add a {% load static %} tag before your script
{% extends "admin/base.html" %}
{% load static %}
{% block footer %}
{{ block.super }}
{% load static %}
<script>
tinymce.init({
....
content_css: '{% static "TinyMCE/style.css" %}',
....
{% endblock %}
My problem is solved. Let me know if you have any questions.

Django how to dynamically add js and CSS in sub templates?

I am new to Django.
I have a basic template set up where I have base.html using {% block body %}{% endblock %} to include a sub template of index.html and test.html where they have {% extends 'base.html' %} at the top.
The base.html template includes Bootstrap. It is where the CSS and JS are included. index.html needs to include select2 but test.html does not.
I could use blocks here to solve my problem (adding CSS and JS block to base.html) but I see that as getting very messy very quickly.
Is there anyway I can use assets in Django to create a select2 asset and have that called in the sub template to register the needed JS and CSS with the parent template?
All I see is compression and numerous searches have, so far, come up empty.
It okay to add 2 more blocks in your base.html:
<some css>
{% block additional_css %}
{% endblock additional_css %}
...
<some js>
{% block additional_js %}
{% endblock additional_js %}
and the override them in any page extended from base.html:
{% extends "base.html" %}
{% block additional_css %}
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap-datetimepicker.min.css' %}">
{% endblock additional_css %}
...
{% block additional_js %}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.0/moment.min.js"></script>
<script type="text/javascript" src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
{% endblock additional_js %}
That is a good practice because in this case the scripts will load in the very end and if some of your added script require for example JQuery, you won't face any problems.
It doesn't make the code messy, it's flat and easy to explain. It's better to think how not to make JS messy, and as you pointed, there are several ways to do this, on of them is to compress all the JS.
There are a few options that I can think of
The first is the ugly way that involves an {% if include_my_js_please %} in the base.html that is ignored if the context variable isn't included and for obvious reasons, arguments would be had if this made its way into our production code
The second is the way that you say can get very messy but its the way we do it and works very well for us, we have an {% extended_head %} and {% extended_footer %} in the base.html and as you'd expect we use this sparingly when required. Although we are very careful about what is included into this.
The third way is to just include everything in the base.html and only worry about it when it actually becomes a problem (I can see both the pros and con's of this)
and the fourth and final way I can think of is to make use of the Forms Media class
Django allows you to associate different files – like stylesheets and scripts – with the forms and widgets that require those assets. For example, if you want to use a calendar to render DateFields, you can define a custom Calendar widget. This widget can then be associated with the CSS and JavaScript that is required to render the calendar. When the Calendar widget is used on a form, Django is able to identify the CSS and JavaScript files that are required, and provide the list of file names in a form suitable for easy inclusion on your Web page.
Obviously this doesn't work in all use cases

Django and tabbed navigationin templates

I am building a django project which among others has a customer model. Any customer can be a foreign key to some calendar entry models or some picture models. I want to be able to get in to a customers page (e.g domain/customoer/1) and be able to navigate to the different models the customer is related with (e.g all the pictures for the customer, all the calendar entries of the customer). I am using bootstrap for the "presentation of the site. My idea was to use tabs. So I created a pil for my main template the customer.html
<ul class="nav nav-pills">
<li class="active">Personal Data</li>
<li>History</li>
<li>Analysis</li>
<li>Diagnosis</li>
<li>Treatment</li>
<li>Appointments</li>
<li>Graphics</li>
</ul>
and i was thinking of including a template for each pill
<div class="tab-content">
<div id="personal-data" class="tab-pane active ">
<div id="history" class="tab-pane">History is in the making</div>
<div id="analysis" class="tab-pane">
{% include 'customer/analysis.html' with customer=customer %}
</div>
<div id="diagnosis" class="tab-pane">Diagnosis is differential</div>
<div id="treatment" class="tab-pane">Treatment what treatment??</div>
<div id="appointments" class="tab-pane">Ap point ment</div>
<div id="graphics" class="tab-pane">Now this is going to be hard!</div>
The templates in each tab can do different things like upload pics navigate to different pages etc.
When i hit on a pill the url (domain/customer/1/) won't change (naturally) to inform me to which tab i am at the moment. So my question is how can i know in which tab i am ath the moment? I want the user to be able to do different things from different tabs (upload pics etc) and I want to be able to redirect to the specific tab after the view is called? Maybe #id could be appended to the url to specify the tab, but it doesn't happen with bootstrap.
What is the best way to deal with tabs in django? Ajax maybe? Will I not have the same problem? Any ideas or lings would be nice too
I use template inheritance for this kind of thing. It's simple and flexible. For example, you can define your main navigation in your base template like so:
...
<li {% block news %}{% endblock %}>News</li>
<li {% block features %}{% endblock %}>Features</li>
<li {% block sport %}{% endblock %}>Sport</li>
...
Then, in your base templates for each of those apps you'd have something like:
<!-- news/base_news.html -->
{% extends 'base.html' %}
...
{% block news %}class="active"{% endblock %}
...

Template Django application extending template django project

I am quite a beginner in django and I need some advices.
I am trying as much as possible to create reusable django applications that will be used in several different projects. But I don't know how to proceed with templates.
If I have an application managing user, I think the template allowing to add, remove or list a user shall be located in the application and not in the project. Templates project should define headers, footers and general organisation (correct me if I'm wrong).
However, if I want to use template inheritance I will extend project template in my application template :
{% extends "base.html" %}
{% block content %}
...
{% endblock %}
So in developping my reusable application I make the assumption that my project will have a template called base.html with a block content, and in my mind this information should not be located at application level, but in project level. In some projects I will want to display users in block content, but not necessarily in others. I could want to display user information in several places in the same page for example...
How do you developp your application template to bypass this limitation ?
Thanks in advance,
Bill
What you are describing is probably best solved with custom template tags, specifically inclusion tags.
I would do a basic html template containing a header and a footer, and many reusable templates extending the basic one, containing the different layouts I would need. I would also create reusable components (tiles, datagrids...).
For the templates :
base.html
<!doctype HTML>
<html>
<head>
....
</head>
<body>
{% block content %}
</body>
</html>
3_columns.html
{% extends "project/base.html" %}
{% block content %}
<div class="line">
<div class="column">{% block col1 %}</div>
<div class="column">{% block col2 %}</div>
<div class="column">{% block col3 %}</div>
</div>
{% endblock %}
2_lines.html
{% extends "project/base.html" %}
{% block content %}
<div class="line">{% block line1 %}</div>
<div class="line">{% block line2 %}</div>
{% endblock %}
A basic custom component :
templatetags/custom.py
import django
from django.template.defaulttags import register
#register.inclusion_tag('components/custom.html')
def custom(params):
context = {
'a': params['a'],
'b': params['b']
}
return context
templates/components/custom.html
<div class="custom">
<label>{{ a }}
<input name={{ b }}
</label>
</div>
django-admin.py collectstatic
Read docs
Files are searched by using the enabled finders. The default is to look in all locations defined in STATICFILES_DIRS and in the 'static' directory of apps specified by the INSTALLED_APPS setting.

Django template inclusion

The template inheritance page on the django site doesn't really solve my problem (Django 1.2).
My base page looks like:
...
<div class="grid_12" id="content">
{% block content %}{% endblock %}
</div>
...
{% block javascript %}{% endblock %}
I have another template that defines content for these:
{% block content %}
animated sidebar
{% endblock %}
...
{% block javascript %}
alert('hello');
{% endblock %}
This is something like an animated sidebar, so I don't want to extend the base template since it's auxiliary to the main content of the page. If I just use "include", the entire thing is put where the "include" tag is placed - as a result the javascript doesn't run because it's included before one of its dependencies.
What's the best way to solve this?
EDIT
Sorry, I didn't make myself clear.
I have my content pages which render a template that extends "base.html". In "base.html" I want to include a sidebar template that needs to append blocks in "base.html". So I've tried just putting include "sidebar.html" into "base.html", but it just inserts the whole thing where the "include" tag is. What I want it to do is append the blocks in "base.html", which may themselves have been populated by "page.html".
Maybe it's important to say that "sidebar.html" is entirely static - i.e. there's no callable associated with it. So perhaps this question should really be "How can I include a static template into base.html so it will append to blocks in base.html regardless of the output of the actual view that processes the request?"
I think you mean you want to append to a block? You can put {{ block.super }} where you want the inherited content to go. e.g.:
{% block javascript %}
{{ block.super }}
alert('hello');
{% endblock %}
You should only use {% block foo %} tags to extend blocks in a base template, so I'm not clear what you mean when you say you don't want to extend it.
The code, as you've entered it, should render to
...
<div class="grid_12" id="content">
animated sidebar
</div>
...
alert(hello)
Unless you want to append the content (as in Matt's answer) it's not clear what you want to happen.
You shoud be using something like jQuery to trigger execution only after the page is fully loaded. Include jQuery library in the document header and then somewhere:
$(document).ready(function() {
//your code goes here
});