web-dev-qa-db-ja.com

Twitterでリンクのアクティブクラスを変更するbootstrap css in python / flask

私のページから次のHTMLスニペットを取得しましたtemplate.html

<ul class='nav'>
    <li class="active"><a href='/'>Home</a></li>
    <li><a href='/lorem'>Lorem</a></li>

    {% if session['logged_in'] %}
        <li><a href="/account">Account</a></li>
        <li><a href="/projects">Projects</a>
        <li><a href="/logout">Logout</a></li>
    {% endif %}

    {% if not session['logged_in'] %}
        <li><a href="/login">Login</a></li>
        <li><a href="/register">Register</a></li>
    {% endif %}
</ul>

2行目を見るとわかるように、アクティブなクラスがあります。これにより、Twitter bootstrap cssファイルでアクティブなタブが強調表示されます。これで、www.page.com/ですが、いつ訪れるかはわかりませんwww.page.com/login 例えば。それでも、ホームリンクがアクティブなタブとして強調表示されます。

もちろん、Javascript/jQueryでこれを簡単に行うことができますが、この状況では使用しません。

既に Ruby on Rails の実用的な解決策)がありますが、それをpython/jinjaに変換する方法がわかりません(私はjinja/flaskが比較的新しいので、 Rubyでまったく機能しなかった)

33
Azeirah

これを見た? http://jinja.pocoo.org/docs/tricks/

アクティブなメニュー項目の強調表示

多くの場合、アクティブなナビゲーション項目のあるナビゲーションバーが必要です。これは簡単に実現できます。子テンプレートのブロック外の割り当てはグローバルであり、レイアウトテンプレートが評価される前に実行されるため、子テンプレートでアクティブなメニュー項目を定義できます。

{% extends "layout.html" %}
{% set active_page = "index" %}

その後、レイアウトテンプレートはactive_pageにアクセスできます。さらに、その変数のデフォルトを定義することは理にかなっています:

{% set navigation_bar = [
    ('/', 'index', 'Index'),
    ('/downloads/', 'downloads', 'Downloads'),
    ('/about/', 'about', 'About')
] -%}

{% set active_page = active_page|default('index') -%}
...
<ul id="navigation">
    {% for href, id, caption in navigation_bar %}
    <li{% if id == active_page %} class="active"{% endif
    %}><a href="{{ href|e }}">{{ caption|e }}</a>
    </li>
{% endfor %}
</ul>

...

69
codegeek

ページ全体にメニューを配置している場合のもう1つの簡単な方法を次に示します。この方法では、インラインのifステートメントを使用して、クラスactiveを出力します。

<ul>

<li class="{{ 'active' if active_page == 'menu1' else '' }}">
<a href="/blah1">Link 1</a>
</li>

<li class="{{ 'active' if active_page == 'menu2' else '' }}">
<a href="/blah2"> Link 2 </a>
</li>

</ul>

アクティブなクラスはハイライト用です

それらをマークするには、すべてのページで変数を設定する必要があります

{% extends "master.html" %}
{% set active_page = "menu1" %}

または

{% set active_page = "menu2" %}
5
varun

jinja/flask/bootstrapユーザーの場合:

ブログの例のようにナビゲーションを定義する場合 http://getbootstrap.com/examples/blog/rl_for引数に一致するリンクにIDを割り当てるだけで、レイアウトテンプレートを変更するだけで、残りは#magicで機能します。

<nav class="blog-nav">
  <a id="allposts"  class="blog-nav-item" href="{{ url_for('allposts')}}">All Posts</a>
  <a id="index"     class="blog-nav-item" href="{{ url_for('index')}}">Index</a>
  <a id="favorites" class="blog-nav-item" href="{{ url_for('favorites')}}">Favorites</a>
</nav>

基本/レイアウトテンプレートの下部にこれを追加するだけです

<script>
  $(document).ready(function () {
  $("#{{request.endpoint}}").addClass("active"); })
</script>

正しい要素がアクティブに設定されます。

編集: 次のように、リストに要素を含むレイアウトがある場合:

<nav class="blog-nav">
  <ul class="nav navbar-nav">
    <li>
        <a id="allposts"  class="blog-nav-item" href="{{ url_for('allposts')}}">All Posts</a>
    </li>
    <li>
        <a id="index"     class="blog-nav-item" href="{{ url_for('index')}}">Index</a>
    </li>
    <li>
        <a id="favorites" class="blog-nav-item" href="{{ url_for('favorites')}}">Favorites</a>
    </li>
  </ul>
</nav>

使用 親() リンクの代わりにli要素を取得する関数。

<script>
    $(document).ready(function () {
    $("#{{request.endpoint}}").parent().addClass("active"); })
</script>
4
philmaweb

次のCSSをページのどこかに追加します。

a[href $= {{ page_name|default("'/'"|safe) }}]{ [INSERT YOUR ACTIVE STYLING HERE] }

次に、各テンプレートで_page_name_を定義します。次に例を示します。

_{% extends "template.html" %} {% set page_name = "gallery" %}_

これは、他のオプションよりもはるかにシンプルで簡単に構築できます。

編集:

すべてのページにページ名を設定するのはかなり非効率的であるため、ほぼ1年後、私はこれをはるかに簡単な修正にするために戻ります。

代わりに、次のような関数を作成します。

_@app.context_processor
def context_processor():
    out = {}
    out['request'] = request # Make sure you import request from flask
    return out
_

これにより、変数を暗黙的にジンジャに渡すことができます。この場合、ユーザーがアクセスしているルートを含む_request.url_rule_へのアクセス要求を渡します。以前のバージョンでは、{{ page_name|default("'/'"|safe) }}を_"{{ request.url_rule|safe }}"_に変更するだけです。ずっときれい。

0
0c370t

私は @ philmaweb のアプローチが好きでしたが、各要素のIDでエンドポイントを複製する必要がある理由は本当にありません。

base.js:

$(document).ready(function () {
    var scriptElement = $('#baseScript')[0];
    var path = scriptElement.getAttribute('data-path');
    $('a[href="'+path+'"]').addClass("active");
});

base.html

<script id="baseScript" src="{{ url_for('static', filename='js/base.js') }}"
data-path="{{ request.path }}"></script>

なぜこのスクリプトをインラインにしないのですか?もちろん可能ですが、インラインJSを許可することは セキュリティの悪夢 です。インラインJSを許可しないサイトでCSPを使用する必要があります(例: Flask-Talisman )。 data-*属性、これを安全な方法で行うことは難しくありません。

注意:同じ現在のページへのリンクが複数あり、そのうちの1つだけを「アクティブ」としてマークしたい場合、このアプローチは機能しない可能性があります。

0
Nick K9