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">×</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">×</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 %}