はじめに
僕がやめたいのは、HTMLテンプレートに記述してる赤枠みたいなやつ。
サーバのレスポンスによって表示する値を変える必要があるものは対象外です。
最近Djangoのプロジェクトに携わらせてもらっているのですが、HTMLが文字列のハードコードだらけで阿鼻叫喚中です。
なぜそこにそんなに違和感を抱いているかといいますと、
前のプロジェクトでは、HTML(JSP)はおろか、サーバーサイドでも文字列のハードコーディングは原則禁止されていたからです。
ちなみに、前プロジェクトはJavaのフレームワークSeasar2を使用した業務アプリ開発で、以下のような感じにしてました(LabelKeys.javaとかMessageKeys.javaとかもありますが、伝わればいいので省略)。
■HTMLに表示するものは「label.properties」にキーとバリューを定義し、Labels.javaにそこから取得するためのメソッドを定義
■メッセージ関連は「messages.properties」にキーとバリューを定義し、Messages.javaにそこから取得するためのメソッドを定義
■JSP, サーバーサイドは上記Labels.javaおよびMessages.javaを使用することで文字列のハードコーディングを抑制する
Djangoもカスタムテンプレートタグを作成できるので、その機能を使用して同じようなことをしたいと思ったわけです。
共通のlabel.pyを作成、各アプリケーションにもtemplatetags/label.pyを作成して各々のテンプレートで'{% load label %}'を差し込めばいけるなと思ってました。
しかし、せっかくなら全てのアプリケーションから使用できるラベルを作りたい!!!
と思ったので作ってみました。
バージョン情報
Django: 2.1.5
Python: 3.7.2
全てのアプリケーションから共通で使用できるラベルを作成
プロジェクト直下にlabelsフォルダを作って、そこにlabel.pyを作成。
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
@register.filter()
@stringfilter
def label(key):
value = label_keys.get(key)
if value is None:
value = ""
return value
label_keys = {
#########################
# 共通のラベルとか
#########################
'common_update': '更新',
'common_regiter': '登録',
'common_cancel': 'キャンセル',
'common_delete': '削除',
#########################
# app1のラベル
#########################
'app1_title': 'Qiita(テンプレート使用)',
'app1_description': 'Qiitaに投稿(テンプレート使用)',
}
各アプリケーションから使用できるようにsettings.pyのTEMPLATESに追記
'libraries'
がすでに記述されている場合は、そのなかに追記してあげてください。
...
..
.
TEMPLATES = [
{
...
..
.
'OPTIONS': {
...
..
.
'libraries': {
'label': 'labels.templatetags.label'
}
},
},
]
...
..
.
テンプレートから使用してみる
{% load label %}
にはsettings.pyに指定した値(今回はlabel)
その下の埋め込み変数は{{key | 使用するメソッド名}}
としてあげます。
できた(`・ω・´)
まあ、結局キー値をハードコードしてるんですけどね。。。( ´Д`)=3
エクセルファイルかなんかでキーバリュー管理して、関数で埋め込み変数を生成してあげたり、スクリプト使ってlabel.pyを自動生成したりできるので、個人的にはかなり嬉しいです。
参考