Передать нефритовые переменные из содержимого в заголовок страницы?

Я пытаюсь использовать Jade для включения переменных из блока контента в макет страницы большего размера. Я хочу поставить заголовок семантического контента для страницы <title> тег.


Я использую превосходный инструментарий http://roots.cx/ для создания сайта в Jade и Stylus.

У меня есть 2 файла: pagelayout.jade а также page142.jade,

pagelayout Файл содержит базовый шаблон страницы Jade (отредактирован для простоты):

!!!
html
   head
       title #{page.title} | My Great Site
body
   != content

page142 файл содержит некоторое уникальное содержание, которое будет включено в != content:

- var page = { title: 'Page 142' }
h1 Content header of page 142

Как я хочу, чтобы конечный HTML выглядел так:

<html><head><title>Page 142 | My Great Site</title></head>
<body><h1>Content header of page 142</h1></body></html>

На данный момент я получаю компилятор TypeError:

Cannot read property 'title' of undefined

Я предполагаю, что получаю эту ошибку, потому что область видимости переменных Jade, вероятно, работает только от шаблона к содержимому, а не наоборот.

Как передать переменные страницы из содержимого в макет страницы? Все найденные мной сообщения Stackru показывают только переменные, переходящие от макета страницы к содержимому.

1 ответ

Решение

Я видел, что Джефф уже ответил на это для вас в Твиттере, но ради Stackru я отвечу вам снова здесь.

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

В вашем layout.jade, вы можете сделать это:

html
  head
    block head
      title My Website
  body
    block content

И в твоем index.jade, вы можете сделать это:

extends layout

block head
  title A Specific Page of My Website

block content
  p Hello World!

Что произойдет, когда вы окажете index.jadeБудет ли он "видеть", что он расширяется layout.jade (Строка 1), а затем посмотреть, что он имеет block head сопровождается некоторым содержанием, поэтому он будет искать layout.jade за block head и замените найденный там контент своим собственным.

В зависимости от того, как настроен ваш проект Roots, это может работать, а может и не работать. Текущая стабильная версия Roots предоставляет собственную систему включений для шаблона Roots по умолчанию, который не зависит от любого механизма шаблонов.

Этот шаблон Roots по умолчанию используется $ roots new projectname,

Я не уверен, возможно ли перезаписать текущий шаблон проекта, или если в настоящее время возможно изменить способ работы механизма шаблонов (использует ли он систему включения Roots или свою собственную), но я знаю, что что минимальный шаблон Roots, используемый с $ roots new projectname --min сделает блок включенным в работу.

Итак, вы можете сделать одну из двух вещей здесь:

  1. Посоветуйтесь с Джеффом и посмотрите, возможно ли изменить систему включений на Jade
  2. Или воссоздайте проект используя $ roots new <projectname> --min

К вашему сведению, Джефф и я оба используем --min как наш предпочтительный шаблон, за исключением того, что я расширил его, включив в него разные кросс-браузерные полифилы

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

Теперь вам может быть интересно, если замена целого блока просто для изменения содержимого тега где-то в блоке немного неэффективна - она ​​неэффективна с точки зрения обслуживания - я не могу прокомментировать скорость обработки. Но если вы помните, что в Jade вы можете определить переменные, а в Jade вы можете поместить что-нибудь в блок - и вы объедините эти две конструкции - они станут намного более полезными.

Например, если я знаю, что собираюсь широко использовать Jade в проекте, я создам configuration.jade файл, в котором я перечисляю все переменные конфигурации / настроек в виде блока. Затем я включу этот файл в основной макет (это просто включает в себя установку заголовка для простоты):

config.jade:

- var siteTitle = "My Cool Website";

layout.jade:

block config
  include config

html
  head
    title #{siteTitle}
  body
    block content
      p Hello World

Причина, по которой мы include наш конфигурационный файл вместо того, чтобы просто определяться в верхней части нового макета, просто потому, что некоторым проектам требуется более одного макета, поэтому имеет смысл снять ответственность за хранение переменных конфигурации в другом файле, чтобы мы могли include их в любом макете мы хотим. Обратите внимание, однако, что мы include наш конфигурационный файл внутри block config, Это позволяет нам заменить этот блок переменными конфигурации внутри наших файлов, поэтому - если, возможно, у меня есть страница блога, которую я расширяю с layoutЯ мог бы написать это так:

blog.jade

extends layout

  block config
    - var siteTitle = "Blog - My Cool Website";

  block content
    each post in posts
      p #{post.content}

Видите, насколько это проще?:)

Другие вопросы по тегам