7

TwitterBootstrapでdjangoを使用しています。私の現在のビューは、提供されている例の1つに似ています。例を見ると、ユーザーがサイドバーのリンクの1つをクリックして、それぞれが同じサイドバーで囲まれたさまざまなビューを表示していることが想像できます。選択したリンクが、コードを使用した例のように強調表示されると想像できます。

<li class="active"><a href="/sample/link/here/">Link</a></li>

アクティブなクラスは、正しいメニュー項目にアタッチする必要があります。この「アクティブ」クラスを正しいメニュー項目に割り当てるにはどうすればよいですか?もともと、私は自分のビューから変数を使用してjqueryで割り当てようとしました:

$(document).ready(function() {
    $("#{{ current_view }}_nav").addClass('active');
});

<li id="linkone_nav"><a href="/sample/link/here/">Link</a></li>

しかし、これは面倒なようです。ビューからテンプレートにIDを渡す必要があります。同様に管理するIDがたくさんあります。このアクティブなクラスを割り当てるためのより良い/より好ましい方法はありますか?

4

7 に答える 7

7

base.htmlプロジェクトを他のテンプレートによって拡張されたテンプレートに編成した場合、たとえばappname/pagename.html、テンプレート中心のアプローチを使用して、アクティブなナビゲーション要素を強調表示できます。

このアプローチには、いくつかのデカップリングの利点があります。これについては、この回答の最後で詳しく説明しました。

このアプローチは、サイトのほとんどまたはすべてで同じままである幅広いナビゲーションアイテムを処理するのに非常に役立つことがわかりました。データストアから収集したアイテムの動的リストをレンダリングするなど、より詳細なナビゲーション要素にはおそらく適切なソリューションではありません。

テンプレートで、base.html各ナビゲーション要素にブロックを追加し、ブロックに一意の名前を付けます。

<ul class="nav">
  <li class="{% block navbar_class-home %}{% endblock %}">
    <a href="#">Home</a>
  </li>
  <li class="{% block navbar_class-about %}{% endblock %}">
    <a href="#">About</a>
  </li>
  <li class="{% block navbar_class-pricing %}{% endblock %}">
    <a href="#">Pricing</a>
  </li>
</ul>

テンプレートで、appname/pagename.htmlnav要素の1つをアクティブに見せたい場合はactive、コンテンツとして使用して適切なブロックをオーバーライドします。たとえば、「About」アイテムを強調表示するには、次のようにします。

{% block navbar_class-about %} active {% endblock %}

そのテンプレートをレンダリングするビューを使用すると、次のようにレンダリングされます。

<ul class="nav">
  <li class="">
    <a href="#">Home</a>
  </li>
  <li class=" active ">
    <a href="#">About</a>
  </li>
  <li class="">
    <a href="#">Pricing</a>
  </li>
</ul>

これにより、JavaScriptに依存しない初期レンダリングが提供されます。(シングルページアプリを実行している場合は、JavaScriptを使用してナビゲーションバークラスを変更できます。)

多くの場合(すべてではありません)、これはビューロジックからのより良い分離プレゼンテーションになる可能性があります。

  • ビューを変更してサイトナビゲーションデータをテンプレートコンテキストに添付することはできますが、そうすると、プレゼンテーションがビューレイヤーに強力に結合され、再利用可能なアプリの作成やサードパーティのアプリの統合がより困難になります。

    ビューはすでに名前付きテンプレートを選択しています。これは、ナビゲーション関連の情報をテンプレートレイヤーに既に渡していることを意味します。必要なのはそれだけかもしれません。

  • テンプレートコンテキストプロセッサを使用してビューに関する情報を取得できますが、これにより、テンプレートレイヤー内にとどまるのではなく、システムの別のレイヤーに強力な結合が移動します。

于 2012-12-14T17:07:41.413 に答える
7

#サンプルコードでのhrefの使用は、問題を曇らせていると思います。実際のシナリオは実際の実際のリンクであり、アクティブなURLに基​​づいてそれらを自動的に強調表示すると想定しています。それが正しければ、次のようにします。

{% url something as url %}
<li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Link1</a></li>

ここで、「something」は、URLパターンまたはビューへの点線のパスなどの名前です。これは、明らかにURLを逆にしていることを前提としているため、静的URLを使用している場合は、ハードコーディングするだけです。

<li{% if request.path == "/my/full/url/path/" %} class="active"{% endif %}><a href="/my/full/url/path/">Link1</a></li>
于 2012-08-16T17:31:44.327 に答える
2

より少ないコードで、より良いソリューション。Bootstrapでうまくいきます。「addClass」クエリを変更するだけで、メニュー項目を選択できます。

Javascriptで、次の関数を作成します。

var highlight_menu = function(path) {
    /* Highlight current link */    
    $('.nav li').removeClass('active');
    $('.nav li:has(a[href="' + path + '"])').addClass('active')
};

base.htmlで、現在のパスを使用してJS関数を呼び出します。

<script>
    highlight_menu('{{request.path}}');
</script>
于 2013-07-24T21:15:17.550 に答える
1

FWIW、Twitter Bootstrapページ自体には、Scrollspyプラグインを使用して提供されるこの機能があります。

それ以外の場合は、メニューのクリックイベントを聞くことができます。

$('.nav').on('click', 'li:has(a[href^="#"])', function (e) {
  $('.nav li').removeClass('active');
  $(this).addClass('active');
});
于 2012-08-16T15:58:05.607 に答える
0

メニューの包含スニペットを作成します。

<li class="{% if opt=='link1' %} active{% endif %}"><a href="#/?opt=link1">Link1</a></li>
<li class="{% if opt=='link2' %} active{% endif %}"><a href="#/?opt=link2">Link2</a></li>
<li class="{% if opt=='link3' %} active{% endif %}"><a href="#/?opt=link3">Link3</a></li>
...

基本テンプレートに次のように含めます。

{% include "menu.html" with opt=request.GET.opt %}

ご覧のとおり、$(document).ready(...)を使用する必要はありません。

TEMPLATE_CONTEXT_PROCESSORSにリクエストを追加することを忘れないでください。

TEMPLATE_CONTEXT_PROCESSORS = (
  # ...
  'django.core.context_processors.request',
  # ...
)
于 2012-08-16T15:52:12.937 に答える
0

Djangoの問題を解決するには、次のアプローチを検討してください。

javascriptを使用しなくても正常に動作します。純粋なDjangoを使用するだけで、メニューオプションを強調表示する必要があるほとんどの状況に対処できるはずです。

この例では、Bootstrap 4を使用していますが、重要ではありません。あなたはあなた自身のCSSを使うことができ、あなたは大丈夫でしょう。ここでの考え方は、request.resolver_match.url_nameをurl_nameとして使用して、必要なものを実現することを示すことです。

{% with request.resolver_match.url_name as url_name %}
   <ul class="navbar-nav mr-auto">
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 1' %}">Menu option 1</a>
      </li>
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 2' %}">Menu option 2</a>
      </li>
   </ul>
{% endwith %}
于 2020-10-20T03:47:26.090 に答える
0

そのためにsimple_tagを使用しました。多分誰かがそれが役に立つと思うでしょう。

ファイルisactive.pyを作成し、アプリテンプレートパスのレベルのtemplatetagsディレクトリに配置します。

from django import template
from django import urls
register = template.Library()

@register.simple_tag
def isactive(page_name, request_url):
    rev_url = ''
    try:     
        rev_url = urls.reverse(page_name)
    except:
        return ''
    if (rev_url == request_url):
            return 'active'
    return ''

そしてあなたのhtmlテンプレートで

{% load isactive %}

スタティックをロードした後、メニューに

<a href="{% url 'my_table_list' %}" class="nav-link {% isactive 'my_table_list' request.path %}">

レンダリング時-djangoは関数isactiveを実行しています。ここで、最初のパラメーターはページの名前で、もう1つはパスです。isactive関数内で、名前が解決されて比較されます。一致すると、アクティブな文字列が返され、結果のhtmlに配置されます。あなたはすべてのナビゲーションリンクにその呼び出しを置く必要があります。

ページの名前は、アプリのurls.pyのurlpatternsから取得されます

urlpatterns = (
    ...
    path("my_table/list/", views.mytableListView.as_view(), name="my_table_list"),
    ....
于 2021-07-01T08:42:27.253 に答える