#javascript #jquery #django #django-templates
#javascript #jquery #django #django-шаблоны
Вопрос:
Я хочу создать меню, в котором я могу установить одну ссылку, выделенную с помощью тега {% block %}. У меня есть что-то подобное в моем Javascript:
<loop>
$('#a-div').append('{% block ' variable ' %} <a href...</a> {% endblock %}')
<endloop>
В исходном коде это отображается как «{% block Home %}»
Как я могу заставить jQuery добавлять это не как строку, а как тег шаблона?
Ответ №1:
Вы не можете. По крайней мере, без выполнения AJAX-запроса к шаблону Django. В вашем случае это было бы медленно и приводило бы к ненужным дополнительным запросам. Оно того просто не стоит. Вы можете вставлять фрагменты из шаблонов Django с помощью jQuery, используя, например, функцию jQuery load
. Но вы не можете заменить конкретный {% block %}
тег, потому что ко времени запуска jQuery шаблон уже обработан (и ссылки на теги блоков удалены). Но это не та ситуация, когда вы должны делать это в любом случае.
Почему бы вам не выделить меню с помощью класса CSS? Вот мое обычное решение этой проблемы:
- Создайте файл с именем
base_extras.py
в одной из вашихtemplatetags
папок. Если у вас его нет, создайте его в соответствующей папке. -
Внутри
base_extras.py
вставьте этот код:from django import template from django.core.urlresolvers import reverse register = template.Library() @register.simple_tag def navactive(request, urls): if request.path in ( reverse(url) for url in urls.split() ): return "active" return ""
-
Теперь в вашем шаблоне, в ваших меню в вашем базовом шаблоне, сделайте что-то вроде этого:
<ul class="menu"> <li class="home {% navactive request 'home' %}"><a href="{% url home %}">Home</a></li> <li class="contact {% navactive request 'contact' %}"><a href="{% url contact %}">Contact</a></li> <li class="signup {% navactive request 'signup' %}"><a href="{% url signup %}">Sign up</a></li> </ul>
-
Это приведет к тому, что меню, в котором в данный момент находится ваш URL, будет иметь
active
класс. Затем в вашем CSS просто добавьте специальный класс для элемента меню сactive
, чтобы он выглядел немного иначе, чем другие меню.ul.menu li.active {background: red; color: white;}
И если вам понадобится изменить активное меню с помощью jQuery, вы можете просто удалить active
класс во всех меню и добавить его во вновь выбранные меню:
$('ul.menu li').removeClass('active').find('.home').addClass('active'); // for example
Комментарии:
1. Спасибо, мне действительно понравилось это решение. Но на самом деле это не решает мою проблему. Вероятно, мне следует объяснить немного лучше. Я получаю имя и цель ссылки меню из запроса ajax. итак, в моем цикле for я хочу использовать название ссылки меню в качестве названия блока. Я делаю это просто для развлечения, поэтому я осознаю, что это может быть очень глупым поступком.
2. @Pecock: К сожалению, это невозможно, AFAIK. Единственным способом было бы отправить запрос jQuery к другому шаблону Django и вставить возвращаемое содержимое в правильное положение с помощью
id
илиclass
, или как угодно. Но вы не сможете добавлять новые блоки или обновлять старые блоки в своем коде django с помощью jQuery.3. Что ж, спасибо, ребята. Я вроде бы нашел решение, но оно плохое. Я только что передал переменную «active_menu» из шаблона и сохранил ее в скрытом поле. Затем сравнил его в меню. В следующий раз я обязательно сделаю это лучше
Ответ №2:
Вы не можете сделать это таким образом. Теги шаблона Django обрабатываются на стороне сервера еще до отправки страницы в браузер. Javascript (включая jQuery), с другой стороны, вызывается в браузере после получения страницы с сервера.
Что вы можете сделать, так это предварительно перенести содержимое {% block %}
тега в переменную JS и использовать его в коде jQuery:
var blockContent = "{% block Home %} ... {% endblock %}";
// ...
$("#a-div").append(blockContent);
Если вам нужно выбрать более одного блока (как вы, кажется, указали в предоставленном вами примере кода), вы могли бы прибегнуть к массиву предварительно обработанных блоков.
Ответ №3:
Лучше всего создать прокси-представление, которое выполняет текущий ваш AJAX-запрос, обрабатывает результаты, как это сделал бы javascript, а затем возвращает все, что вы пытаетесь получить из системы шаблонов Django.
Затем, вместо текущего вызова AJAX, вы вызываете свой собственный view вместо этого. Django выполняет обработку в представлении, как и должно быть, вы получаете точный контроль над тем, что возвращается в ваш javascript, и это все еще только один (на стороне клиента) вызов сервера.