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日
