DjangoとHTMXで超スムーズな言語スイッチャーの作り方
どこでも動作するスーパースムーズな言語スイッチャーが必要ですか?
Djangoにはset_language
という組み込みのヘルパー関数があり、与えられたURLを翻訳してユーザーをその翻訳したURLにリダイレクトします。とても便利です。少し作業をするだけで、HTMXともっと良く動作させることができます。
あなたが学ぶこと
このガイドでは以下を学びます:
- Djangoの組み込みの
set_language
関数がどのように動作するのか、そしてそれをどのように使用するのか prefix_default_language=False
をi18n_patterns
に設定してset_language
を修正する方法- HTMXを使って、言語スイッチャーを超スムーズなにする方法
準備
始める前に、ウェブサイトをローカライゼーションの準備をする必要があります。Djangoのローカライゼーションフレームワークを設定するためのTestdrive.ioのガイドをご覧ください。このガイドの残りの部分は、ローカライズしたプロジェクトを持ち、基本的な使い方がわかり、ただ言語スイッチャーが必要であると仮定します。
HTMXの事項については、HTMXがセットアップされ、使用可能であることを仮定します(もしまだであれば、僕のHTMXとGRUGスタックの残りの設定する方法のガイドを参照してください)。
set_language
の使い方
set_language
に関するドキュメンテーション によると:
便宜上、Djangoにはビューdjango.views.i18n.set_language() が含まれており、これによりユーザーの言語設定を行い、指定されたURL にリダイレクトするか、デフォルトでは前のページに戻ることができます。
ということは、任意のページでset_language
を使用することができるということを意味しています。すばらしいですね。ドキュメンテーションにはまた、set_language
を使用するHTMLテンプレートの例も含まれています:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
大事なポイントはいくつかあります:
set_language
がPOSTリクエストを必要とする
1 2 |
|
next
パラメータはオプショナル
1 2 3 |
|
language
パラメータが設定される必要があります
1 2 3 4 5 6 7 8 9 10 11 |
|
僕の使用法では、切り替える他の言語が1つしかないので、僕のテンプレートでは次のように使用しています:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
これは、settings.py
のLANGUAGESで言語のための各ボタンを生成します。ボタンは言語コードをlanguage
パラメータの値として送信します。set_language
はその値を使用して、あなたのサイトのユーザーの言語設定を設定します。
僕はまた、ボタンを画面の右下に固定するためにそれをスタイルしました。
次に必要なことはset_language
ビューが僕たちのプロジェクトレベルのurls.py
ファイルにあることを確認することだけです:
1 2 |
|
これで、あなたのサイトの現在、そして未来の全てのページで動作する言語スイッチャーができ上がりました。
一つ問題があります
最初にset_language
を使用したとき、問題がありました。僕はデフォルト言語から切り替えることができましたが、それに戻すことができませんでした。問題は、僕がi18n_patterns
にprefix_default_language=False
を設定していたことに関連していました。prefix_default_language=False
と設定すると、ユーザーがサイトのデフォルト言語にいるとき、urlsにen/
がpath
に追加されません(日本語に切り替えてみて、ドメインの後にja/
がパスの先頭に追加されることに注目してください)。これは既知のバグです。
問題を修正する二つの方法があります:
prefix_default_language
をTrue(デフォルトの値)に設定し、デフォルトの言語の言語コードが全てのURLに追加されることを受け入れる。set_language
を少し修正する。
set_language
がprefix_default_language=False
と共に動作するようにするためには、set_language
関数をコピーして修正を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
僕が上記で使用したHTML言語スイッチャーのように、リクエスト内にnext
パラメータが設定されていない場合では, next_url
は自動的に https://killianarts.online/ja/the/rest/of/the/path
またはhttps://killianarts.online/the/rest/of/the/path
に設定されます。追加したコードを使用すると、path
が抽出されて /ja/the/rest/of/the/path
または /the/rest/of/the/path
になります。それから、 /ja/the/rest/of/the/path
の場合, /ja
を取り除いて続きを使用します。 translate_url
関数が実際にURLを言語コードに基づいて正しいものに切り替える作業をします。
HTMXでスムーズにスワップ
デフォルトでは、ページ全体が上までスクロールした状態で再読み込みされます。HTMX属性を数個追加するだけで、他の言語へスムーズに移行し、スクロール位置を保持することができます(また、Googleマップのような他のDOM要素のスクリーン上の状態も保持します)。異なる言語への切り替えはシームレスに行います。
はじめに、Idiomorphライブラリが必要です。テンプレートファイル内でHTMXスクリプトインポートの後でこの行を追加します:
1 |
|
そして、フォームを変更します:
1 2 3 4 5 6 7 8 |
|
hx-post="{% url 'set_language' %}"
は、set_language
関数にHTMX POSTリクエストを作成します。
hx-target="body"
は、hx-post="{% url 'set_language' %}"
のレスポンスのターゲットを<body>
要素にします。
hx-push-url="true"
は、hx-post
がレスポンスで返すURLをブラウザのURLに更新します。 set_language
は単にHttpResponseRedirectを返し、別のurlに移動し、そのレスポンスを返します。
また、hx-post
、hx-target
、hx-push-url
をhx-boost="true"
と置き換えることもできます。これは全く同じことを行います。一般的な印象としては、すでに古いコードベースを持っている場合や、フォームがAJAXリクエストを使用するように簡単かつ迅速にアップグレードするようなことをしたい場合、hx-boost
の使用を人々が提案することを聞きます。新しいコードベースを作成したり、大幅なリファクタリングを行う場合、他の属性を使用する方が良いでしょう。なぜなら、ほとんどの場合それらが必要になるからです(例えば、おそらく異なるターゲットが必要で、そしてよくURLを押さないためには)。
この記事を書いている現在、上記の
set_language
のバグのため、僕が上記に追加した修正とともにprefix_default_language=False
を設定したい場合、hx-boost
の使用をお勧めします。理由は不明ですが、一部のページでhx-post
が400のエラーを返し、リダイレクトが完了しません。
hx-ext="morph"
は、僕達がIdiomorphを使用することができるようにします。
hx-swap
はリクエストへのレスポンスをどのように交換するかを決定します。これをinnerHTML
に設定すると、<body>
のinnerHTMLがレスポンスで置き換えられます。つまり、ページ全体を置き換えることになります。「ねえ、マイカ、ページ全体を置き換えるのであれば、なんでHTMXを使用するのか? なぜ普通のようにページ全体をリロードしないの?」って?
HTMXは<head>
を置き換えないので、CSSやJSなどのインポートはリロードされません。これにより、スタイルのないコンテントのフラッシュがない、より高速な切り替えが可能になります。
さらに、Idiomorphなど、他のクールなことも可能にします。 morph:
修飾子をinnerHTML
の前に置くと、交換方法がデフォルトの変形方法ではなく、Idiomorphを使用するようになります。Idiomorphを使用すると、言語を切り替えるときに、ビデオやGoogleマップのような動的な要素が状態を失うことはありません。絶対に必要な機能ではないけど、かっこいいです。
次は本質的なポイントです。 transition:true
は、HTMXが交換のためにビュートランジションAPIを使用するようにします。 set_language
により返される新しいページへの現在のページの遷移方法を変更するためにスタイリッシュなことをCSSで行うことができるけど、デフォルトの設定のままでいいです。
最後に、show:none
は現在のブラウザのスクロール状態を維持します。デフォルトでは、ブーストしたリンクとフォームはshow:top
にデフォルト設定されています。show:none
を使うと、スクロールした位置が変更されません。
僕でもできるように簡単でした
まとめると、HTMXの数行で、言語スイッチャーを大幅にアップグレードできます。今では、それは超スムーズで、ユーザーが邪魔されることなく、場所を失うことなく言語を切り替えることができます。それは、どちらの言語も学びたい人々や、僕の日本語がおかしくて分かりづらい日本人にとって役にたつでしょう。

Author
Added
2023年12月2日