Как грамотно сделать меню в jade?

Не подскажите как грамотно реализовать меню

Пример:
есть 3 страницы
home.jade
about.jade
contact.jade

к каждой подключен include menu.jade
меню должно быть такого типа (класс active должен быть у li когда находимся на ее странице и пустая ссылка как в первом li Home):
ul.nav
        li.nav-item.active
            a(class='link', href='/') Home
        li.nav-item
           a(class='link', href='about.html') About
               span.label test
        li.nav-item
           a(class='link', href='contact.html') Contact

Как такое наиболее правильно можно реализовать чтобы на выходе получились 3 html с работающим меню, и возможно ли вынести тэг (a) чтобы не дублировать 3 раза.
  • Вопрос задан
  • 4469 просмотров
Решения вопроса 1
AirWorker
@AirWorker
Node.js full stack web dev
Реализация подобного рода вещей - сильная сторона Jade

Под такие задачи плохо подходит include. Используйте наследование. В родительском шаблоне определите все общие блоки, в дочерних шаблонах оставьте только то, что меняется

1. Создаем родительский шаблон, определяем блок контента и блок общих переменных, убираем дублирование в микс, этот микс вызываем в цикле, данные для цикла выносим отдельно:

//- filename: root.jade
- var nav = [{url: '/', name: 'Home'}, {url: 'about.html', name: 'About'}....];
doctype html
html(lang="en")
  block sharedVars
  head
    block title
  body
    ul.nav
      each i in nav
        +navItem(i.url, i.name, i.url == pageUrl)
    block content
mixin navItem(url, name, current)
  li.nav-item(class={active: current})
    a.link(href=url)= name


Очевидно, теперь родительский шаблон ждет переменную pageUrl.

2) Создаем шаблоны дочерних страниц, в них определяем родительский шаблон, контентные блоки и необходимые для родительского шаблона переменные.

extends root
append sharedVars
  - var pageUrl = '/';
block title
  | My title
block content
  h1 Мой заголовок
  .content
     p Hello World


Обратите внимание как передается переменная pageUrl из дочернего шаблона в родительский - через блок sharedVars. Этого нет в документации по Jade.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Расскажу как делаю я.

Сами пункты меню у лежат в отдельном json файле (многая инфа так хранится)

data/nav.json
[
  {
    "title": "Главная",
    "url": "home.html"
  },
  {
    "title": "Каталог",
    "url": "catalog.html"
  },
  {
    "title": "Акции",
    "url": "actions.html"
  }
]


Есть миксин для вывода меню, он может быть разной сложности в зависимости от задачи, покажу простой:
blocks/nav.jade
mixin nav(data, current)
    nav.nav&attributes(attributes)
        if(data && data.length)
            ul.nav__list
                each item, index in data
                    li.nav__item.nav-item(class=(index === current ? "nav-item--current" : undefined))
                         a(href=item.url).nav-item__link
                                span.nav-item__title #{item.title}


Этот миксин принимает 2 аргумента: массив с пунктами меню и индекс текущего пункта.

В части страницы, где меню выводится мы вызываем миксин

parts/header.jade
+nav(getData('nav'), currentNav)

А переменную currentNav, с индексом нужного на пункта меню, мы передаем непосредственно со страницы:

page.jade
extends layouts/_default
block head
    - pageTitle = 'Заголовок страницы';
block header
    - currentNav = 1;
block content


Для понимания кусочек layouts/_default
doctype html
html(lang="ru-RU" class="no-js")
    include ../parts/_head
    body
        block header
        include ../parts/_header
        .content#content
            block content
        block footer
        include ../parts/_footer
Ответ написан
litlleidiot
@litlleidiot
Фронт-Энд разработчик
Мне кажется нужно тогда хедер ручками то есть дурблировать и переносить в каждкую страницу и не делать хедер модулем
(самого волнует такой вопрос, жду ответа)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы