Django:現在のページのリンクを太字にするより良い方法はありますか
-
06-07-2019 - |
質問
リンクのリストを含むbase.htmlテンプレートがあります。
例:
<div id="sidebar1">
<ul>
<li><a href="/" title="">Index</a></li>
<li><a href="/stuff/" title="" class="current">Stuff</a></li>
<li><a href="/about/" title="">About Me</a></li>
<li><a href="/contact/" title="">Contact Me</a></li>
</div>
それから、views.pyには、index.html、stuff.html、about.html、contact.htmlのそれぞれの定義があります。これらの各テンプレートは、単にbase.htmlテンプレートから派生し、それぞれのタイトルとコンテンツを設定します。
私の質問は、上記の/ stuffについてです。
現在のページにそのクラス属性を持たせたい。
current_page =&quot; about&quot;のように、各ビューで異なる変数を設定できます。そして、各リンクの各クラス要素の {%ifequal%}
とテンプレートで比較を行いますが、それは作業が重複しているように見えます(余分なビュー変数のため)。
もっと良い方法はありますか?たぶん、テンプレートが自動的に入力されたビュー関数名を取得する方法があれば、余分な変数を設定する必要はないでしょうか?また、多くのifequalsのように見えます。
解決
これを行うためのエレガントな方法があります。どこかからコピーしたもので、どこにいるか覚えていればいいので、彼らに信用を与えることができます。 8-)
次のように、各ページ(またはセクション内のすべてのページ)に id
を割り当てます。
In index.html: <body id='section-intro'>...
In faq.html: <body id='section-faq'>...
In download.html: <body id='section-download'>...
そして、対応するリンクの id
:
<li id='nav-intro'><a href="./">Introduction</a></li>
<li id='nav-faq'><a href="./faq.html">FAQ</a></li>
<li id='nav-download'><a href="./download.html">Download</a></li>
そして、CSSで次のようなルールを設定します:
#section-intro #nav-intro,
#section-faq #nav-faq,
#section-download #nav-download {
font-weight: bold;
/* And whatever other styles the current link should have. */
}
したがって、これは現在のページが属するリンクのスタイルを制御するためにほとんど宣言的な方法で動作します。アクションでそれを見ることができます: http://entrian.com/source-search/
セットアップすると、非常にクリーンでシンプルなシステムになります。理由は次のとおりです。
- リンクのテンプレートマークアップを台無しにする必要はありません
- 大きなbigい
switch
ステートメントやif / else / else
ステートメントを使用してしまうことはありません - セクションへのページの追加Just Works [TM]
- 見た目を変えることは、マークアップではなくCSSを変更することだけを意味します。
Djangoを使用していませんが、このシステムはどこでも動作します。あなたの場合、「それぞれのタイトルとコンテンツを設定する」場所 body id
も設定する必要があります。他のDjangoマークアップは必要ありません。
このアイデアは、他の状況にも簡単に拡張できます。 &quot;ダウンロードページ自体を除くすべてのページのサイドバーにダウンロードリンクが必要です。&quot;次のようにCSSでそれを行うことができます:
#section-download #sidebar #download-link {
display: none;
}
サイドバーHTMLに条件付きテンプレートマークアップを配置する代わりに。
他のヒント
HavenはDjangoを使用していませんが、 Kohana (PHP)とRailsで同じ問題に対処しました。
小花でやること:
<li><a href="/admin/dashboard" <?= (get_class($this) == 'Dashboard_Controller') ? "class=\"active\"" : NULL ?>>Dashboard</a></li>
<li><a href="/admin/campaigns" <?= (get_class($this) == 'Campaigns_Controller') ? "class=\"active\"" : NULL ?>>Campaigns</a></li>
<li><a href="/admin/lists" <?= (get_class($this) == 'Lists_Controller') ? "class=\"active\"" : NULL ?>>Lists</a></li>
Railsで行うこと:
<li><a href="/main" <%= 'class="active"' if (controller.controller_name == 'main') %>>Overview</a></li>
<li><a href="/notifications" <%= 'class="active"' if (controller.controller_name == 'notifications') %>>Notifications</a></li>
<li><a href="/reports" <%= 'class="active"' if (controller.controller_name == 'reports') %>>Reports</a></li>
ifequalsの繰り返しを避けながら、それを行う方法は2、3しかありません。
-
Javascript。 (jQuery)のラインに沿ったもの:
var parts = window.location.pathname.split('/'); var page = parts[parts.length-1]; $('#sidebar1 a[href*=' + page + ']').addClass('current');
-
タイトルとURLが関連付けられたページのリストを含むようにビューを変更し、テンプレートに{%for%}ループを作成します。これにより、そのリストが処理され、単一の{%ifequal%} 。
オプション2は、私が立っている場所のお気に入りです。すべてのページのロジックが同じで、テンプレートのみが異なる場合、各ページにFlatPagesモデルを使用することを検討できます。ロジックが異なり、異なるモデルが必要な場合は、何らかのメニューアプリの使用を検討してください。恥知らずなプラグイン:自分のメニューアプリ
request
コンテキストプロセッサを追加する場合、それは非常に簡単です:
settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth' # admin app wants this too
)
これで、リクエストパスを含む HttpRequest
にアクセスできます。現在のページを強調表示するのは、パスがリンクのリンク先と一致するかどうか、つまり、あなたがすでにそこにいるかどうかをチェックするだけの簡単なことです:
<li><a class="{% if request.path == '/' %}current{% endif %}" href="/">Index</a></li>
<li><a class="{% if request.path == '/stuff/' %}current{% endif %}" href="/stuff/">Stuff</a></li>
<li><a class="{% if request.path == '/about/' %}current{% endif %}" href="/about/">About Me</a></li>
<li><a class="{% if request.path == '/contact/' %}current{% endif %}" href="/contact/">Contact Me</a></li>