Django ブログサイト templates/base.html テンプレート共通

2020/07/04 (更新:2020/11/19)

テンプレート共通です。
複数のテンプレートに分割し構成しています。
最下位クラスに投稿者の拡張テンプレートを配置し、投稿者毎にカスタマイズできる構成にしています。

base.html
 └── post_base.html
         │  (include) category_summary
         │  (include) post_favor
         └── 各画面・言語のテンプレート
                 └── 投稿者の拡張テンプレート

コード

ライブラリはCDNを使用します。

base.html

{% load i18n static %}
<!DOCTYPE html>{% get_current_language as LANGUAGE_CODE %}
<html lang="{{ LANGUAGE_CODE|default:"ja" }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="{% block meta_description %}{% endblock %}">
<link href="{% static 'apple-touch-icon.png' %}" rel="apple-touch-icon">
<link rel="icon" type="image/png" href="{% static 'android-touch-icon.png' %}" sizes="192x192">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'blog/css/style.css' %}">
{% block extra_css %}{% endblock %}
<title>{% block head_title %}{% endblock %}</title>
</head>
<body>
  <div>
    {% block main %}{% endblock %}
  </div>
  <footer class="blog-footer mt-5">
    {% block footer_text %}
      <p class="mb-0">2020 Tassk team</p>
    {% endblock %}
  </footer>
  <div id="alert_modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="alert_container"></div>
      </div>
    </div>
  </div>
  <div id="overlay" style="display:none;">
    <div id="spinner">
      <div class="spinner-border" role="status">
        <span class="sr-only">Loading...</span>
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <script src="{% static 'blog/js/script.js' %}"></script>
  <script>
    base = {
      redirect_url: "{% url 'blog:redirect_view' %}",
    };
  </script>
  {% block extra_js %}{% endblock %}
</body>
</html>

カスタムテンプレートタグcategory_summaryよりカテゴリーブロックを出力します。
カスタムテンプレートタグblog_favorよりおすすめブロックを出力します。

blog_base.html

{% extends 'blog/base.html' %}
{% load i18n app_tags %}
{% block head_title %}{% block head_author_title %}{{ view.kwargs.author.title_text }}{% endblock %}{% endblock %}
{% block meta_description %}{% endblock %}
{% block main %}
  <div class="container">
    <header class="blog-header py-3">
      <div class="row flex-nowrap justify-content-between align-items-center">
        <div class="col-6 pt-1">
          <a class="blog-header-logo text-dark" href="{% url 'blog:index' view.kwargs.author_name %}">{% block main_title %}{% block main_author_title %}{{ view.kwargs.author.title_text }}{% endblock %}{% endblock %}</a>
        </div>
        <div class="col-6 d-flex justify-content-end align-items-center">
          <div class="row w-100">
            <div class="col text-right" style="min-width:8rem;">
              <form action="{% url 'set_language' %}" method="POST">
                {% csrf_token %}
                <input name="next" type="hidden" value="{{ redirect_to }}">
                {% if view.kwargs.available_languages %}
                  {% get_language_info_list for view.kwargs.available_languages as languages %}
                  {% if languages|length > 1 %}
                    <div class="input-group">
                      <select name="language" class="form-control">
                          {% get_current_language as LANGUAGE_CODE %}
                          {% for language in languages %}
                              <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
                                  {{ language.name_local }} ({{ language.code }})
                              </option>
                          {% endfor %}
                      </select>
                      <div class="input-group-append">
                        <input type="submit" class="btn btn-outline-secondary" value="Go">
                      </div>
                    </div>
                  {% else %}
                    <input type="submit" class="btn btn-light" value="{{ languages.0.name_local }}">
                    <input name="language" type="hidden" value="{{ languages.0.code }}">
                  {% endif %}
                {% endif %}
              </form>
            </div>
            <div class="col" style="min-width:8rem;">
              <form action="{% url 'blog:search' view.kwargs.author_name %}" method="GET">
                <input type="search" class="form-control ds-input" id="header-search" name="keyword" placeholder="Search..." autocomplete="off">
              </form>
          </div>
        </div>
      </div>
    </header>
  </div>
  <main class="container mt-3">
    <div class="row">
      <div class="col-md-8 blog-main">
        <div id="alert_container">
          {% for message in messages %}
            <div class="alert {{ message.tags }} alert-dismissible fade show" id="default_alert" role="alert">
              <div class="message-text">{{ message }}</div>
              <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
          {% endfor %}
          <div class="alert alert-dismissible fade show" id="default_alert" role="alert" style="display:none;">
            <div class="message-text"></div>
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
        </div>
        {% block blog_main %}{% endblock %}
      </div>
      <aside class="col-md-4 blog-sidebar">
        <div class="position-sticky">
          {% block aside1 %}
            <div class="p-3 mb-3 bg-light rounded">
              <p class="mb-0">
                {% block author_aside %}{% endblock %}
              </p>
            </div>
          {% endblock %}
          {% block aside2 %}
            <div class="mb-3">
              {% category_summary view.kwargs.author.id %}
            </div>
          {% endblock %}
          {% block aside3 %}
            <div>
              {% post_favor view.kwargs.author.id 3 %}
            </div>
          {% endblock %}
        </div>
      </aside>
    </div>
  </main>
{% endblock %}