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

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


Я использую отличный набор инструментов 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, вероятно, работает только от шаблона к содержимому, а не наоборот.

Как передать переменные страницы из контента в макет страницы? Все StackOverflow posts Я нашел только показ переменных, идущих со страницы макет к содержанию.


person hao_maike    schedule 04.01.2014    source источник


Ответы (1)


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

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}

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

person razorbeard    schedule 04.01.2014
comment
На самом деле я только что попытался это настроить, но, к сожалению, он все еще не работает: gist.github.com/anonymous/ 8250758 - person hao_maike; 04.01.2014
comment
Таким образом, способ перехода состоит в том, чтобы удалить строку макетов в app.coffee — извините, это немного сбивает с толку, в следующей версии, над которой мы работаем, это будет намного понятнее! - person Jeff Escalante; 04.01.2014
comment
Я исправил этот ответ с помощью небольшой хитрости, которую вы можете использовать, чтобы сделать ваши проекты красивыми и удобными в сопровождении. - person razorbeard; 11.02.2014