Включение сценариев / содержимого в файл макета coffeekup Docpad после обращения к переменной данных шаблона 'content'

У меня возникают проблемы с извлечением сценариев конца страницы (или другого содержимого) из файла макета после вызова функции @content. Я использую шаблонизацию coffeekup и имею следующий файл макета default.html.coffee.

doctype 5
html ->

  head ->

    meta(charset:"utf-8")
    title("Docpad")
    if @document.description?
      meta(name:"description", content:@document.description)

    stylesheets = ['/styles/app.css']
    @getBlock('styles').add(stylesheets).toHTML()

  body ->

    div class:"row", ->
      div class:"large-12 columns", ->
        h1(class:"docs header", "Header")
        hr()

    @content
    @getBlock('scripts').toHTML()

Проблема, с которой я сталкиваюсь, заключается в том, что "@content" правильно выдает и отображает содержимое страницы только в том случае, если за ним ничего не следует (например, если строка @getBlock('scripts') выше, например, удалена или закомментирована). Однако с помощью приведенного выше кода вызов getBlock для сценариев завершается успешно, но "@content" не вставляет содержимое. Любая помощь приветствуется, спасибо.

1 ответ

Решение

Давайте посмотрим на скомпилированный javascript вашего кода. Мы можем использовать компилятор на coffeescript.org, чтобы сделать это:

doctype(5);

html(function() {
  head(function() {
    var stylesheets;
    meta({
      charset: "utf-8"
    });
    title("Docpad");
    if (this.document.description != null) {
      meta({
        name: "description",
        content: this.document.description
      });
    }
    stylesheets = ['/styles/app.css'];
    return this.getBlock('styles').add(stylesheets).toHTML();
  });
  return body(function() {
    div({
      "class": "row"
    }, function() {
      return div({
        "class": "large-12 columns"
      }, function() {
        h1({
          "class": "docs header"
        }, "Header");
        return hr();
      });
    });
    this.content;
    return this.getBlock('scripts').toHTML();
  });
});

Обратите внимание, как this.content это просто недействительное заявление. Как будто я сделал это: "a"; "b"; "c"; "d" ничего не будет делать ничего.

Использование или назначение кода, который вы представили, похоже, подразумевает недопонимание того, как работает CoffeeKup или CoffeeScript, поэтому позвольте мне оценить, что происходит и почему иногда это работает, а иногда нет.

Когда мы делаем div -> "blah" это сводится к div(function(){return "blah";}) который говорит пас div функция, которая при вызове вернет строку бла. Теперь CoffeeKup знает, что любые возвращаемые ему строки должны отображаться для удобства. Но так как мы не можем вернуть несколько вещей (так как первый возврат существует в блоке), что нам делать?

CoffeeKup обеспечивает text функция, позволяющая нам сделать:

div ->
    text "a"
    text "b"

Который при компиляции выглядит так:

div(function() {
  text("a");
  return text("b");
});

Что именно то, что мы хотим, как text звоните, как div и все другие вызовы элементов не возвращают строку и выводят содержимое напрямую.

В общем, решение состоит в том, чтобы префикс:

@content
@getBlock('scripts').toHTML()

С text звоните, так становится:

text @content
text @getBlock('scripts').toHTML()

Если вы когда-нибудь захотите скрыться от сущностей HTML < в &lt;) тогда вы захотите добавить h называть так же, как и так h "content to be escaped" и в сочетании с text будет выглядеть text h "content to be escaped" - однако это только то, что нужно отметить, а не то, что вам нужно прямо сейчас или здесь.

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