Подтвердить что ты не робот

Изменение активного класса ссылки с помощью twitter bootstrap css в 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, класс активен. Это подчеркивает активную вкладку с помощью CSS файла twitter bootstrap. Теперь это будет нормально работать, если я посетил бы www.page.com/, но не тогда, когда я бы посетил www.page.com/login, например. Он по-прежнему выделял бы домашнюю ссылку как активную вкладку.

Конечно, я мог бы легко сделать это с помощью Javascript/jQuery, но я бы предпочел не использовать это в этой ситуации.

Там уже работает решение для ruby ​​on rails, но я не знаю, как преобразовать его в python/jinja (я довольно новичок в jinja/flask, никогда не работал с рубином вообще)

4b9b3361

Ответ 1

Вы смотрели на это? 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>

Ответ 2

Вот еще один простой способ, если у вас есть меню, распространяемые по всей странице. Этот способ использует встроенные операторы 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" %}

Ответ 3

Для пользователей jinja/flask/bootstrap:

Если вы определяете свой nav, как в блоге, http://getbootstrap.com/examples/blog/ просто назначьте идентификаторы вашим ссылкам, которые соответствуют вашим аргументам url_for, и вам просто нужно изменить шаблон макета, остальные просто работают #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>

В нижней части шаблона base/layout просто добавьте этот

<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>

используйте функцию parent(), чтобы получить элемент li вместо ссылки.

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

Ответ 4

Добавьте следующий CSS где-нибудь на своей странице:

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

Теперь для каждого шаблона определите page_name, например:

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

Это кажется намного проще и проще, чем другие варианты.

РЕДАКТИРОВАТЬ:

Почти год спустя я возвращаюсь, чтобы исправить это намного проще, потому что установка имени страницы на каждой странице довольно неэффективна.

Вместо этого создайте такую функцию:

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

Это позволит вам неявно передавать переменные в jinja, в этом случае мы передаем запрос на доступ к request.url_rule который содержит маршрут, к которому обращается пользователь. В предыдущей версии мы просто изменили {{ page_name|default("'/'"|safe) }} на "{{ request.url_rule|safe }}". Гораздо чище.

Ответ 5

Мне понравился подход @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 - это кошмар безопасности. Вы должны использовать CSP на своем сайте (например, Flask-Talisman), который не позволяет использовать встроенный JS. С data-* не сложно сделать это безопасным способом.

NB. Если у вас есть несколько ссылок, ведущих на одну и ту же текущую страницу, и вы хотите, чтобы только ОДНА из них была помечена как "активная", то этот подход может не сработать для вас.