265 lines
8 KiB
Markdown
265 lines
8 KiB
Markdown
status: #doc
|
||
Tags: #python/django
|
||
links:
|
||
Date: 2024-06-27
|
||
___
|
||
|
||
in django templates are html files that help to set a common pages or elements layout (for example blog posts) so that we don't need to make every page that we add to our site , we just need to add dynamic data and django handle the rest
|
||
|
||
# setup
|
||
|
||
There are two main ways to organize your template structure in Django: the default app-level way and a custom project-level approach.
|
||
|
||
## Option 1: App Level
|
||
|
||
- go to my_app folder and create templates folder
|
||
- now create my_app folder inside template folder
|
||
- now you can make your template here for example `home.html`
|
||
|
||
now you should have folder structure like this
|
||
```
|
||
|
||
├── my_project
|
||
│ ├── __init__.py
|
||
│ ├── settings.py
|
||
│ ├── urls.py
|
||
│ └── wsgi.py
|
||
| └── my_app
|
||
| ├── __init__.py
|
||
│ ├── admin.py
|
||
│ ├── apps.py
|
||
│ ├── models.py
|
||
│ ├── tests.py
|
||
│ └── views.py
|
||
| ├── templates
|
||
| ├── my_app
|
||
| ├── home.html
|
||
└── manage.py
|
||
```
|
||
|
||
> [!INFO]
|
||
>By default, the Django template loader will look for a `templates` folder within each app. But to
|
||
>avoid namespace issues, you also need to repeat the app name in a folder below that before
|
||
>adding your template file.
|
||
>
|
||
>This approach is demonstrated in the [official Django polls tutorial](https://docs.djangoproject.com/en/dev/intro/) and works just fine.
|
||
|
||
|
||
## Option 2: Project Level
|
||
|
||
- go to `setting.py` inside my_project folder
|
||
- inside `TEMPLATES` field find `"DIRS"` property and add `"templates"` to the list
|
||
``` python
|
||
# settings.py
|
||
TEMPLATES = [
|
||
{
|
||
...
|
||
"DIRS": ["templates"],
|
||
...
|
||
},
|
||
]
|
||
```
|
||
- now make `templates` folder inside my_project folder
|
||
- now you can make your template here for example `home.html`
|
||
|
||
now you should have folder structure like this
|
||
```
|
||
|
||
├── my_project
|
||
│ ├── __init__.py
|
||
|
||
│ ├── settings.py
|
||
│ ├── urls.py
|
||
│ └── wsgi.py
|
||
| └── my_app
|
||
| ├── __init__.py
|
||
│ ├── admin.py
|
||
│ ├── apps.py
|
||
│ ├── models.py
|
||
│ ├── tests.py
|
||
│ └── views.py
|
||
├── templates
|
||
| ├── home.html
|
||
└── manage.py
|
||
```
|
||
|
||
>[!info]
|
||
>if you have overridden `DIRS` in the `settings.py` file, the Django template loader will _first_ look there and _then_ look to `APP_DIRS` for an app-level `templates` directory. There is no "right" way to organize templates within your Django project
|
||
|
||
# using templates
|
||
|
||
|
||
![[urls and views#using templates]]
|
||
# variables
|
||
|
||
variables are changing value that we can use inside our template we usually get them from views
|
||
|
||
- how to use
|
||
```html
|
||
{{variable_name}}
|
||
```
|
||
|
||
>[!info]
|
||
>Variable names consist of any combination of alphanumeric characters and the underscore (`"_"`) but may not start with an underscore, and may not be a number. The dot (`"."`) also appears in variable sections
|
||
>Use a dot (`.`) to access attributes of a variable.
|
||
|
||
# filters
|
||
|
||
You can modify variables for display by using **filters**.
|
||
|
||
- Filters look like this: `{{ name|lower }}`. This displays the value of the `{{ name }}` variable after being filtered through the [`lower`](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#std-templatefilter-lower) filter, which converts text to lowercase. Use a pipe (`|`) to apply a filter.
|
||
|
||
- Filters can be “chained.” The output of one filter is applied to the next. `{{ text|escape|linebreaks }}` is a common idiom for escaping text contents, then converting line breaks to `<p>` tags.
|
||
|
||
- Some filters take arguments. A filter argument looks like this: `{{ bio|truncatewords:30 }}`. This will display the first 30 words of the `bio` variable.
|
||
|
||
- Filter arguments that contain spaces must be quoted; for example, to join a list with commas and spaces you’d use `{{ list|join:", " }}`.
|
||
|
||
## [`default`](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#std-templatefilter-default)
|
||
|
||
If a variable is false or empty, use given default. Otherwise, use the value of the variable. For example:
|
||
```django
|
||
{{ value|default:"nothing" }}
|
||
```
|
||
If `value` isn’t provided or is empty, the above will display “`nothing`”.
|
||
|
||
## [`length`](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#std-templatefilter-length)
|
||
|
||
Returns the length of the value. This works for both strings and lists. For example:
|
||
```django
|
||
{{ value|length }}
|
||
```
|
||
|
||
more filters [here](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#ref-templates-builtins-filters)
|
||
|
||
# tags
|
||
|
||
tags are used for logic operation it can be as simple as `if` or `for` loop or some bizarre one like `truncatewords_html` other tags are [here](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#ref-templates-builtins-tags)
|
||
|
||
## [for](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#for "Permalink to this headline")
|
||
|
||
Loop over each item in an array
|
||
|
||
```django
|
||
<ul>
|
||
{% for item in item_list %}
|
||
<li>{{ item.name }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
```
|
||
|
||
## [if](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#if)
|
||
|
||
The `{% if %}` tag evaluates a variable, and if that variable is “true” (i.e. exists, is not empty, and is not a false boolean value) the contents of the block are output:
|
||
|
||
- simple use case
|
||
```django
|
||
|
||
{% if athlete_list %}
|
||
Number of athletes: {{ athlete_list|length }}
|
||
{% elif athlete_in_locker_room_list %}
|
||
Athletes should be out of the locker room soon!
|
||
{% else %}
|
||
No athletes.
|
||
{% endif %}
|
||
|
||
```
|
||
|
||
- use with filters and operators
|
||
```django
|
||
{% if athlete_list|length > 1 %}
|
||
Team: {% for athlete in athlete_list %} ... {% endfor %}
|
||
{% else %}
|
||
Athlete: {{ athlete_list.0.name }}
|
||
{% endif %}
|
||
```
|
||
|
||
## [Comments](https://docs.djangoproject.com/en/5.0/ref/templates/language/#comments "Permalink to this headline")
|
||
|
||
To comment-out part of a line in a template, use the comment syntax: `{# #}`.
|
||
|
||
- For example, this template would render as `'hello'`:
|
||
|
||
```django
|
||
{# greeting #}hello
|
||
```
|
||
|
||
- A comment can contain any template code, invalid or not. For example:
|
||
```django
|
||
{# {% if foo %}bar{% else %} #}
|
||
```
|
||
|
||
This syntax can only be used for single-line comments (no newlines are permitted between the
|
||
`{#` and `#}` delimiters). If you need to comment out a multi-line portion of the template, see the [`comment`](https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#std-templatetag-comment) tag.
|
||
|
||
# template inheritance
|
||
|
||
template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines **blocks** that child templates can override
|
||
|
||
example we have this base.html:
|
||
```django
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<body>
|
||
<div id="content">
|
||
{% block content %}{% endblock %}
|
||
</div>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
and here is our child.html
|
||
```django
|
||
{% extends "base.html" %}
|
||
|
||
{% block content %}
|
||
{% for entry in blog_entries %}
|
||
<h2>{{ entry.title }}</h2>
|
||
<p>{{ entry.body }}</p>
|
||
{% endfor %}
|
||
{% endblock %}
|
||
```
|
||
|
||
and we have this in browser
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<body>
|
||
<div id="content">
|
||
<h2>Entry one</h2>
|
||
<p>This is my first entry.</p>
|
||
|
||
<h2>Entry two</h2>
|
||
<p>This is my second entry.</p>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
## how it work
|
||
|
||
|
||
- we call child.html
|
||
- django server read child.html template and see extends "base.html"
|
||
- it load base.html
|
||
- then it look at child.html if it see any block it overwrite base.html
|
||
- send page to client
|
||
|
||
>[!info]
|
||
>- if there is no overwrite from child.html the default values from base.html will be used
|
||
> - also you can use multi level of inheritance ex:child.html > parent.html > base.html
|
||
|
||
more at [here](https://docs.djangoproject.com/en/5.0/ref/templates/language/#template-inheritance)
|
||
|
||
|
||
|
||
|
||
|
||
---
|
||
# References
|
||
|
||
https://learndjango.com/tutorials/template-structure
|
||
https://docs.djangoproject.com/en/5.0/ref/templates/language/
|
||
https://docs.djangoproject.com/en/5.0/ref/templates/builtins/
|