How to create reusable components for UI in Django - django

I am building a project in Django which has 5 different applications inside it. Some applications are falling under same pattern and some are not. Can I create a UI components using bootstrap on the top of all these applications to reuse over the entire project. Any help would be appreciated.. Thanks in advance

Usually that is done by creating a base template and making other templates inherit from it like this:
base.html
<html>
<head>
<title>Title</title>
</head>
<body>
<navbar> # example navbar that will be visible in each template that will extend this one
<ul>
Home
Contact
Something else
</ul>
</navbar>
{% block content %} # here is where the content of child templates will be seated
{% endblock %}
</body>
</html>
then you will make any other template and extend it with base.html
your_other_template.html
{% extends 'base.html' %} # this line makes sure your child templates inherit the html of your main template
{% block content %} # here is where you will place the content of your other templates
<h1> This is the content of a child template </h1>
{% endblock %}

Paste your component in an empty html file and then use an include statement to load that file into you template html.
https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#include
This way you can insert you components more dynamically throughout your project.

Related

Django asset manager for Views or template tags?

I come to Django having used the Yii2 PHP framework. One of the good features about that is it allows you to create asset files for CSS and JS which are then loaded into the base layout file at runtime. This allows you to keep the base template clean of CSS and JS markup within the head and at the bottom of the HTML document. The CSS and JS files you specify in the asset file are automatically placed in the correct position in the document and you can also specify dependencies if needed.
At the moment, with Django I am having to edit the base.html file manually which is not ideal.
I know you can use the Media class for forms, and in admin.py, which does a similar job. However, what I would like to do is to something like this (for example) in inclusion template tags or in a class based view perhaps.
Is this possible?
Many thanks!
UPDATE
Here is a similar question Is it possible to use django's custom template tags to insert code in other blocks in the template?
do you find block tag?
base.html
<head>
{% block extra_css %}{% endblock %}
<head>
view.html
{% extends 'base.html' %}
{% block extra_css %}
<link rel="stylesheet" href="YOUR URL">
{% endblock %}

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

Best practice for Django components

Django provides a means of collecting assets into its Widget framework, and in turn using a form to present it, but how about doing this outside the forms framework?
For example, let's say I just want a simple, self-enclosed web component that requires two .js files, a CSS file, a template, and is backed by a view to generate some data. This isn't a "form" because it's not intended to collect input. Rather, assume it's, say, a customized scrollbar. I can't seem to find the right match for this usage pattern even though it seems common and straight-forward.
To do this now seems to mean adding the CSS to the top-level template; the JS to the template (or script tags arbitrarily in the included document); and then rendering the form as an include. But wouldn't it be easier to have something like:
class ScrollBar(...):
template_name = ...
class Assets:
...
and then rendering it via a templatetag, but with the ability for a context processor or other hook to extract the assets into their appropriate places in the page?
Something like:
index.html:
<html>
<head>
...
{% compressed_css %}
</head>
<body>
...
{% compressed_js %}
{% block content %}
{% endblock %}
</body>
scrollbar-using-page.html
{% extends "index" %}
{% block content %}
{% scrollbar args %}
{% endblock %}
with the end result being the scrollbar's template is rendered with the specified args, and its JS and CSS are merged into the compressed_css and compressed_js areas, respectively, above?
I think we get there almost 100% via this approach, without the compressed_js/compressed_css sections, which raises the question of whether then we just included these in all shared pages. (Alternatively, we could use nested/inherited blocks.)
Adam

Django static file inheritance

Perhaps I'm coming at my problem with a WordPress mindset but what i'd like to achieve is the notion of a parent/child theme for Django projects. I think I can solve the template issue by defining two template directories
TEMPLATE_DIRS = (
'/home/Username/webapps/django/child/templates',
'/home/Username/webapps/django/parent/templates',
)
But is there a way to achieve this with the static files? For example, we add a new feature to the parent, update the parent app which updates the templates along with adding some new javascript, LESS, and images.
You don't need to specify two template directories. There is a concept of parent and child templates. All child templates extends the parent:
base.html (we often use this name for parent)
<html>
<head>
<!-- Some css, js stuff goes here-->
{% block extra_head %}
<!-- A block where child templates add more css and js stuff if needed -->
{% endblock extra_head %}
</head>
<body>
{% block body %}
<!-- body content here -->
{% endblock body %}
</body>
</html>
And then child template will extend the base.html as:
child.html
{% extends "base.html" %}
{% block body %}
<h1>Hello!</h1>
{% endblock body %}

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.