DjangoのHTML表記まとめ

# はじめに
個人的まとめ

# 変数

## 変数の展開

```html
{{ var }}
```

- **`{{ 変数名 }}`**

## テンプレートへの変数の渡し方

```python
def index(request):
    context = {'var': 'Hello'}
    return render(request, 'myhtml/index.html', context)
```

```html
<!DOCTYPE html>
<html>
	<head>
	    <meta charset="utf-8" />
	    <title>index</title>
	    <meta name="viewport" content="width=device-width, initial-scale=1">
	</head>
	<body>
	    <p>{{ var }}</p>
	</body>
</html>
```

- **`head`**タグはメタデータを書くところなので実際に表示されるわけではない
- **`p`**タグは一つの段落を表す

```html
<!DOCTYPE html>
<html>
	<head>
	    <meta charset="utf-8" />
	    <title>index</title>
	    <meta name="viewport" content="width=device-width, initial-scale=1">
	</head>
	<body>
	    <p>Hello</p>
	</body>
</html>
```

# テンプレートタグ

- Djangoにはプログラミング言語の予約語に相当する、テンプレートタグと呼ばれるものがある
- テンプレートタグは**`{% タグ名 %}`**と記述する

## **if文**

```html
{% if s == "django" and n != 5 %}
    <p>おはよう</p>
{% elif n != 5 or b is True %}
    <p>こんにちは</p>
{% elif b is not True %}
    <p>こんばんは</p>
{% else %}
    <p>ハロー</p>
{% endif %}
```

- **`==`**や**`!=`**、**`is`**が使用可能
- **`and`**や**`or`**、**`not`**も使用可能
- **`s=="django"`**だとエラーが出る。**`s == "django"`**のようにスペースを空けないとダメ

## **for文**

### リスト

`**list_ = [ "hello", "world", "!" ]**`のとき、

```html
{% for i in list_ %}
  <p>{{ i }}</p>
  <hr>
{% endfor %}
```

```html
<p>hello</p>
<hr>
<p>world</p>
<hr>
<p>!</p>
<hr>
```
![Screen Shot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1639185/3bbb205a-4695-1c43-6161-5cac73555d5a.png)



- **`hr`**タグは段落の意味的な区切りを表す。あくまで意味的な区切りであって、表示的な区切りではないので単に水平線を引きたいならばCSSを使う

### 辞書

**`dic = {"A":"APPLE","B":"BANANA","C":"CHERRY"}`**のとき、

```html
{% for k, v in dic.items %}
  <p>{{ k }}{{ v }}</p>
{% endfor %}
```

- 辞書の名前の後ろに**`.items`**をつけるのを忘れないように

### リストの中身がないときに別の内容を表示

```html
{% for i in list_ %}
  <p>{{ i }}</p>
{% empty %}
  <p>the list is empty.</p>
{% endfor %}
```

- **`{% empty %}`**節を加えることでリストの中身が空だった場合に別の内容を表示できる

```html
{% if i %}
  {% for i in list_ %}
    <p>{{ i }}</p>
  {% endfor %}
{% else %}
  <p>the list is empty.</p>
{% endif %}
```

- 上記のようにもできるが、**`{% empty %}`**節を使った方が見やすい

### リストのうちの一部を表示

```html
{% for i in list_|slice:"2:5" %}
    <p>{{i}}</p>
{% endfor %}
```

- **`slice`**フィルタを用いることで、リストの一部を表示することができる
- 上の場合はリストの2番目から4番目までが表示される
- **`":5"`**とすれば最初から4番目まで、**`"2:"`**とすれば2番目から最後までが表示
- **`for i in list_|slice:"2:5"`**は3箇所ともくっつけて書かないとだめ。                                                    **`for i in list_ | slice: "2:5"`**などとするとエラーになる

### ループの最初だけ別の処理を行う

```html
{% for i in list_ %}
    {% if forloop.first %}
         <p>This is first time. {{ i }}</p>
    {% else %}
         <p>{{ i }}</p>
    {% endif %}
{% endfor %}
```

- **`forloop.first`**は1回目のループの場合は**`True`**を、それ以外の場合には**`False`**を返す
- if文と組みあわせるとループの最初だけ別の処理をさせることができる

### ループの最後だけ別の処理を行う

```html
{% for i in list_ %}
    {% if forloop.last %}
         <p>This is last time. {{ i }}</p>
    {% else %}
         <p>{{ i }}</p>
    {% endif %}
{% endfor %}
```

- **`forloop.last`**は最後のループの場合は**`True`**を、それ以外の場合には**`False`**を返す
- if文と組みあわせるとループの最初だけ別の処理をさせることができる
- もちろん、**`forloop.first`**と**`forloop.last`**は同時に使うこともできる

### ループカウントを取得する

```html
{% for i in list_ %}
    <p>index:{{ forloop.counter0 }}/
    count:{{ forloop.counter }}/
    value:{{ i }}</p>
{% endfor %}
```

- **`forloop.counter0`**はループの回数を`**0**`からカウントアップする
    - 1回目のループなら**`0`**、2回目のループなら**`1`**、N回目なら**`N-1`**になる
    - Pythonの**`enumerate`**と同じ働きをする
- **`forloop.counter`**はループの回数を**`1`**からカウントアップする
    - 1回目のループなら**`1`**、2回目のループなら**`2`**、N回目なら**`N`**になる

### ループカウントを逆順で取得する

```html
{% for i in list_ %}
    <p>index:{{ forloop.revcounter0 }}/
    count:{{ forloop.revcounter }}/
    value:{{ i }}</p>
{% endfor %}
```

- **`forloop.revcounter0`**はループの回数を**`N`**からカウントダウンする
    - 1回目のループなら**`N`**、2回目のループなら**`N-1`**、N回目なら**`1`**になる
    - Pythonの**`enumerate`**と同じ働きをする
- **`forloop.revcounter`**はループの回数を**`N-1`**からカウントダウンする
    - 1回目のループなら**`N-1`**、2回目のループなら**`N-2`**、N回目なら**`0`**になる

### ループの特定の回数のところで別の処理をする

```html
{% for i in list_ %}
    {% if forloop.counter|divisibleby:'3' %}
        <p>this is a multiple of three.{{forloop.counter}}</p>
    {% else %}
        <p>{{i}}</p>
    {% endif %}
{% endfor %}
```

- **`forloop.counter`**とif文を組み合わせるとループの特定の回数のところで別の処理をする、といったことが実現できる
- **`divisibleby`**フィルターは値が引数の値で割り切れる場合に**`True`**を返す
- 上記の例では3回ごとに違う処理をしている

## 挿入

```html
{% include "other_template.file" %}
```

- 別のテンプレートを挿入する
- 各ページに同じもの（アイコン画像、外部のjsファイル、cssファイルなど）を配置するときなどに便利
- 一箇所を書き換えるだけで良くなるのでメンテナンス性が向上する

### 利用例

一部のページのみjQueryを必要とするとき、

```html
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
```

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>template</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {% include "js_parts.html" %}
</head>
<body>
    <p>Hello World!</p>
</body>
</html>
```

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>template</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
		<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
</head>
<body>
    <p>Hello World!</p>
</body>
</html>
```

## ブロック化

- ヘッダーやフッター、サイドバーなど複数のページで共通するパーツをブロック化することでメンテナンス性が向上する
- **`{% block ブロック名 %}`**と**`{% endblock %}`**で囲ったところがひとつのブロックになる
- ブロック名は他のものと名前が被らなければなんでもいい
- 下記の例では**`index1.html`**は**`base.html`**を**`extends`**タグを使って継承し、**`my_title`**ブロックに任意の文字列を入れてカスタマイズを加えている
- **`index2.html`**は**`index1.html`**をさらに継承し、**`index2`**ブロックに任意の文字列を入れてカスタマイズを加えている

```html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{% block my_title %}タイトル{% endblock %}</title>
    </head>
    <body>
        <header>
            {% block my_header %}
            <p>ヘッダー</p>
            {% endblock %}
        </header>

        {% block my_body %}
        <p>ボディ</p>
        {% endblock %}
        
        <footer>
            {% block my_footer %}
            <p>フッター</p>
            {% endblock %}
        </footer>
    </body>
</html>
```

```html
{% extends 'myhtml/base.html' %}

{% block my_title %}トップページ{% endblock %}

{% block my_body %}

    <p>トップページです</p>

    {% block index %}
    <p>インデックス１</p>
    {% endblock %}
    
{% endblock %}
```

```html
{% extends 'myhtml/index1.html' %}

{% block index %}
<p>インデックス２</p>
{% endblock %}
```

# 参考
[これだけは知っておきたいDjangoテンプレートの基本文法](https://e-tec-memo.herokuapp.com/article/67/)