Создание пользовательских тегов в Jekyll, с реальным примером

Shields.io — это «сервис для создания лаконичных, последовательных и разборчивых бейджей в формате SVG и растровом формате, которые можно легко включить в ридми GitHub или любую другую веб-страницу».

shields.io

Их сервис принимает параметры запроса к конечной точке API для создания бейджа / щита. Например:

https://img.shields.io/static/v1?label=Find%20me%20on&message=GitHub&color=181717&style=flat&logo=github
Войти в полноэкранный режим Выйти из полноэкранного режима

становится:

Я планировал использовать это в своем личном блоге, но понял одну проблему: это сложно поддерживать.
Хотя содержимое этих щитов можно редко менять, было бы неплохо иметь поддерживаемый способ размещения щита в моем блоге.

Поскольку я использую Jekyll, я могу определить пользовательский «жидкий тег». Точно так же, как мы можем встраивать материалы из совместимых сервисов с помощью тегов liquid здесь, на DEV.to, например, {% github repo %} и {% embed website %}, мы можем сделать пользовательский тег, скажем, {% shields_io payload %}, для отображения щита.

Как работает тег Liquid на Jekyll?

Тег Liquid на Jekyll имеет следующий формат:

{% tag_name [tag_argument] %}
Войти в полноэкранный режим Выйти из полноэкранного режима

Он имеет имя тега и один необязательный аргумент.

Видите, в чем проблема? В качестве аргумента принимается не более одного значения. Shields.io принимает гораздо больше, и размещение здесь параметра запроса ничего не решает.

Однако надежда еще есть; давайте посмотрим на код, который мы будем писать.

module Jekyll
  class CustomTag < Liquid::Tag
    def initialize(tag_name, arg, parse_context)
      super
      # @type [String]
      @arg = arg
    end
    def render(_context)
      "The argument is #{@arg}" # return the render result here
    end
  end
end
Вход в полноэкранный режим Выйти из полноэкранного режима

Аргумент arg — это аргумент, передаваемый из тега. Это строка. Таким образом, мы можем что-то сделать с вводом.

Если вернуться к исходной задаче, то мы пытаемся передать набор пар ключ-значение в конечную точку API.

Поэтому я решил передать сюда полезную нагрузку в формате JSON; ее можно приукрасить для наших целей, а Ruby поддерживает десериализацию JSON из коробки.

Как превратить его в URL

Поскольку Ruby может превратить входной JSON в хэш, мы можем выполнить итерации по этому хэшу и построить параметр запроса.

Идея заключается в том, чтобы десериализовать JSON и сохранить его в переменной:

    def initialize(tag_name, input, parse_context)
      super
      # @type [Hash]
      @config = JSON.load(input.strip)
    end
Войти в полноэкранный режим Выход из полноэкранного режима

И сконструировать параметр запроса. Я также решил включить href и alt для других целей в полезную нагрузку JSON, но они не имеют отношения к запросу. Поэтому я извлекаю их значения и удаляю из входного хэша, прежде чем превратить остаток в параметр запроса.

def render(_context)
  href = @config[:href]
  alt = @config[:alt]
  @config.delete(:href)
  @config.delete(:alt)
  shield_tag = <<HTML
  <img src="https://img.shields.io/static/v1?#{hash_to_query}"
HTML
  if alt != nil
    shield_tag += " alt="#{alt}" />"
  else
    shield_tag += " />"
  end
  if href != nil
    <<HTML
<a href="#{href}">
#{shield_tag}
</a>
HTML
  else
    shield_tag
  end
end

private
def hash_to_query
  @config.to_a.map { |k, v|
    "#{k}=#{v}"
  }.join '&'
end
Вход в полноэкранный режим Выйти из полноэкранного режима

Результат

Вот мое творение — скопируйте последние два файла и запустите локальный сервер!

Оцените статью
devanswers.ru
Добавить комментарий