Включить данные шаблона jekyll / liquid в переменную YAML?

Я использую заголовок YAML файла уценки, чтобы добавить переменную excerpt в сообщения блога, которые я могу использовать в другом месте. В одном из этих отрывков я ссылаюсь на более раннее сообщение в блоге с помощью разметки ссылки на уценку, и я использую переменную данных жидкого шаблона {{ site.url }} вместо базового URL-адреса сайта.

Так что у меня есть что-то вроде (немного подрезал)

--- 
title: "Decluttering ordination plots in vegan part 2: orditorp()"
status: publish
layout: post
published: true
tags: 
- tag1
- tag2
excerpt: In the [earlier post in this series]({{ site.url }}/2013/01/12/
decluttering-ordination-plots-in-vegan-part-1-ordilabel/ "Decluttering ordination
plots in vegan part 1: ordilabel()") I looked at the `ordilabel()` function
----

Однако jekyll и парсер Maruku md это не нравится, что заставляет меня подозревать, что вы не можете использовать жидкую разметку в заголовке YAML.

Можно ли использовать жидкую разметку в заголовке YAML страниц, обрабатываемых jekyll?

  1. Если это так, что я делаю не так в показанном примере?
  2. Если это запрещено, кто еще я могу достичь того, что задумал? В настоящее время я разрабатываю свой сайт на своем ноутбуке и не хочу жестко кодировать базовый URL-адрес, поскольку он должен измениться, когда я буду готов к развертыванию.

Ошибки, которые я получаю от Maruku:

| Maruku tells you:
+---------------------------------------------------------------------------
| Must quote title
| ---------------------------------------------------------------------------
|  the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-o
| --------------------------------------|-------------------------------------
|                                       +--- Byte 40

а также

| Maruku tells you:
+---------------------------------------------------------------------------
| Unclosed link
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
|                                       +--- Byte 41

а также

| Maruku tells you:
+---------------------------------------------------------------------------
| No closing ): I will not create the link for ["earlier post in this series"]
| ---------------------------------------------------------------------------
| the [earlier post in this series]({{ site.url }}/2013/01/12/decluttering-or
| --------------------------------------|-------------------------------------
|                                       +--- Byte 41

person Gavin Simpson    schedule 23.01.2013    source источник
comment
Одна из проблем может заключаться в том, что ваше значение excerpt содержит двоеточие (:). Если значение содержит двоеточие, значение должно быть заключено в кавычки в YAML.   -  person mipadi    schedule 23.01.2013
comment
@mipadi Спасибо за это. Даже если я процитирую, что проблема не устранена   -  person Gavin Simpson    schedule 23.01.2013


Ответы (3)


Я не верю, что можно вкладывать жидкие переменные в YAML. По крайней мере, я не понял, как это сделать.

Один из подходов, который будет работать, - использовать фильтр замены Liquid. В частности, определите строку, которую вы хотите использовать для замены переменной (например, !SITE_URL!). Затем используйте фильтр замены, чтобы переключить его на желаемую переменную Jekyll (например, site.url) во время вывода. Вот урезанный файл .md, который ведет себя должным образом при установке jekyll 0.11:

---
layout: post

excerpt: In the [earlier post in this series](!SITE_URL!/2013/01/12/)

---

{{ page.excerpt | replace: '!SITE_URL!', site.url }}

Проверяю, что на моем компьютере URL-адрес вставляется правильно, а затем преобразуется из разметки в HTML-ссылку, как и ожидалось. Если у вас есть более одного элемента для замены, вы можете объединить несколько вызовов замены вместе.

---
layout: post

my_name: Alan W. Smith
multi_replace_test: 'Name: !PAGE_MY_NAME! - Site: [!SITE_URL!](!SITE_URL!)'

---

{{ page.multi_replace_test | replace: '!SITE_URL!', site.url | replace: '!PAGE_MY_NAME!', page.my_name }}

Важное примечание: необходимо явно указать значение site.url. С Джекилом вы не получите этого бесплатно. Вы можете установить его в своем _config.yml файле с помощью:

url: http://alanwsmith.com

Или определите его при вызове jekyll:

jekyll --url http://alanwsmith.com
person Alan W. Smith    schedule 01.02.2013
comment
+1 Спасибо Алану за обстоятельный и хорошо иллюстрированный ответ. (У меня site.url установлен в моем _config.yml, и я должен был упомянуть об этом.) Я подожду еще немного, чтобы узнать, есть ли у кого-нибудь другие идеи / предложения, но если нет, я приму это. Ваше здоровье. - person Gavin Simpson; 01.02.2013

Сегодня столкнулся с похожей проблемой. В качестве решения я создал следующий простой плагин-фильтр Jekyll, который позволяет расширять вложенные жидкие шаблоны (например, жидкие переменные в начальной части YAML):

module Jekyll
  module LiquifyFilter
    def liquify(input)
      Liquid::Template.parse(input).render(@context)
    end
  end
end

Liquid::Template.register_filter(Jekyll::LiquifyFilter)

Фильтры можно добавить на сайт Jekyll, поместив их в подкаталог _plugins корневого каталога сайта. Приведенный выше код можно просто вставить в файл yoursite / _plugins / liquify_filter.rb.

После этого шаблон вроде ...

---
layout: default
first_name: Harry
last_name: Potter
greetings: Greetings {{ page.first_name }} {{ page.last_name }}!
---
{{ page.greetings | liquify }}

... должен отобразить что-то вроде «Привет, Гарри Поттер!». Расширение работает также для более глубоких вложенных структур - при условии, что фильтр сжижения также указан на внутренних блоках вывода жидкости. Что-то вроде {{site.url}}, конечно, тоже работает.

Обновление - похоже, теперь он доступен как гем Ruby: https://github.com/gemfarmer/jekyll-liquify.

person blueling    schedule 11.06.2013
comment
Хотя это лучший ответ, который я слышал до сих пор, это также означает, что я должен помнить об использовании фильтра liquify каждый раз, когда я хочу использовать переменную, и если я забуду, я молча получаю {{ }} на своей странице, что заставляет меня хочу поставить его на КАЖДОЕ расширение переменной на всякий случай ... :( - person KFunk; 03.07.2016
comment
Это идеально, именно то, что я искал. Этот плагин должен полностью входить в состав ядра jekyll. - person alxrb; 10.11.2016
comment
Очень элегантное решение. Спасибо! - person Dan Ancona; 12.01.2017
comment
есть ли способ использовать это на страницах github? - person cregox; 13.03.2017
comment
@cregox GitHub Pages не позволяет создавать с помощью плагинов. В документации Jekyll есть информационная подсказка о плагинах, GitHub Pages работает на Jekyll. Однако все сайты Pages создаются с использованием параметра --safe для отключения настраиваемых подключаемых модулей по соображениям безопасности. К сожалению, это означает, что ваши плагины не будут работать при развертывании на GitHub Pages. Вы по-прежнему можете использовать GitHub Pages для публикации своего сайта, но вам нужно будет локально преобразовать сайт и отправить сгенерированные статические файлы в репозиторий GitHub вместо исходных файлов Jekyll. источник: jekyllrb.com/docs/plugins - person Brian Zelip; 01.04.2017
comment
@BrianZ он говорит о пользовательских плагинах, так как мы можем сделать что-то вроде этого нестандартного, официального или чего-то еще? :) - person cregox; 01.04.2017
comment
Пользовательские плагины @cregox - это то же самое, что и плагины - ресурс, недоступный в ядре jekyll, то есть ресурс, созданный извне для jekyll. Вам нужно будет либо включить плагин в ядро ​​jekyll, либо стать боссом GitHub, чтобы изменить их политику :). Просто используйте плагин для локальной разработки, а затем отправьте статическую сборку в репозиторий GH, как упоминается в последней части приведенной выше цитаты. Ваше здоровье - person Brian Zelip; 01.04.2017
comment
@cregox Или используйте Netlify вместе с GitHub, netlify.com. - person Brian Zelip; 01.04.2017
comment
@BrianZ спасибо за подсказку netlify! Я видел это в прошлом и даже создал там учетную запись, но по какой-то причине отказался от нее посередине ... если кому-то еще может быть интересно, они предлагают бесплатный профессиональный план для некоммерческих программ с открытым исходным кодом и довольно просто интегрируются с jekyll netlify. com / blog / 2015/10/28 / - попробую настроить сегодня. :) - person cregox; 06.04.2017
comment
@cregox GitLab также является вариантом для настраиваемых плагинов (например, посмотрите репозиторий моего блога: gitlab. com / ohadschn / ohadschn.gitlab.io). - person Ohad Schneider; 10.09.2017

Если вам нужно заменить значения в data/yml из другого data/yml файла, я написал плагин. Это не так изящно, но работает:

Я сделал некоторые улучшения кода. Теперь он ловит все вхождения в одну строку и работает с вложенными значениями.

module LiquidReplacer
  class Generator < Jekyll::Generator
    REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/
  
    def replace_str(str)
      out = str
      str.to_s.to_enum(:scan, REGEX).map { 
        m = Regexp.last_match.to_s
        val = m.gsub('!', '').split('.')
        vv = $site_data[val[0]]
        val.delete_at(0)
        val.length.times.with_index do |i|
          if val.nil? || val[i].nil? || vv.nil? ||vv[val[i]].nil?
            puts "ERROR IN BUILDING YAML WITH KEY:\n#{m}"
          else
            vv = vv[val[i]]
          end
        end
        out = out.gsub(m, vv)
      }
      out
    end

    def deeper(in_hash)
      if in_hash.class == Hash || in_hash.class == Array
        _in_hash = in_hash.to_a
        _out_hash = {}
        _in_hash.each do |dd|
          case dd
          when Hash
            _dd = dd.to_a
            _out_hash[_dd[0]] = deeper(_dd[1])
          when Array
            _out_hash[dd[0]] = deeper(dd[1])
          else
            _out_hash = replace_str(dd)
          end
        end
      else
        _out_hash = replace_str(in_hash)
      end
      return _out_hash
    end

    def generate(site)
        $site_data = site.data
        site.data.each do |data|
            site.data[data[0]] = deeper(data[1])
        end
    end
  end
end

поместите этот код в site/_plugins/liquid_replacer.rb

в yml файле используйте !something.someval! как site.data.something.someval, но без части site.data.

пример :

_data/one.yml

foo: foo

_data/two.yml

bar: "!one.foo!bar"

вызов {{ site.data.two.bar }} даст foobar

======= СТАРЫЙ КОД ======

module LiquidReplacer
  class Generator < Jekyll::Generator
    REGEX = /\!([A-Za-z0-9]|_|\.){1,}\!/

    def generate(site)
      site.data.each do |d|
        d[1].each_pair do |k,v|
          v.to_s.match(REGEX) do |m|
            val = m[0].gsub('!', '').split('.')
            vv = site.data[val[0]]
            val.delete_at(0)
            val.length.times.with_index do |i|
              vv = vv[val[i]]
            end
            d[1][k] = d[1][k].gsub(m[0], vv)
          end
        end
      end
    end
  end
end
person dude    schedule 05.02.2021