HTML разметка в стиле цепочки - PullRequest
2 голосов
/ 10 июня 2011

Мотивация и проблема

Есть несколько библиотек для генерации строк разметки html с использованием ruby ​​(erb, haml, builder, markaby, tagz, ...), но я не удовлетворенс любым из них.Причина в том, что, за исключением erb, они используют стиль вложенности, а не стиль цепочки.И erb - это способ встроить ruby ​​в html, а не генерировать html с помощью ruby.

Насколько я понимаю, одна прелесть ruby ​​заключается в поощрении использования стиля цепочки:

receiver.method1(args1).method2(args2). ... method_n(args_n)

выполнения стиля вложения:

method_n(...method2(method1(receiver, args1), args2), ... args_n)

Но библиотеки, упомянутые выше (кроме erb), используют стиль вложения (иногда с помощью аргументов блока).

Моя идея

Для своих собственных целей я написал метод dom, чтобы я мог выполнять разметку html в стиле цепочки.Применительно к строке этот пример

"This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html)

сгенерирует:

<html><body><a href="http://stackoverflow.com";>This is a link to SO</a></body></html>

При применении к массиву это:

[
  ["a".dom(:td), "b".dom(:td)].dom(:tr),
  ["c".dom(:td), "d".dom(:td)].dom(:tr)
].dom(:table, border: 1)

сгенерирует

<table border="1";>
  <tr>
    <td>"a"</td>
    <td>"b"</td>
  </tr>
  <tr>
    <td>"c"</td>
    <td>"d"</td>
  </tr>
<table>

И, при применении без явного получателя (вне области строк и массивов),

dom(:img, src: "picture.jpg", width: 48, height: 48)

будет генерировать

<img src="picture.jpg";width="48";height="48";/>

Обратите внимание, что всесделано только одним методом dom.Это намного проще, чем использование других библиотек.Он также гибок в том смысле, что на него не влияет изменение инвентаря HTML-тегов;Вы просто указываете это с помощью аргумента символа.В других библиотеках есть классы и / или методы для каждого тега.Кроме того, в отличие от эрба, это чистый рубин.Это не DSL, который необходимо преобразовать.

Моя реализация

Реализация выглядит следующим образом:

class Hash
    def attribute
        map{|k, v| %Q{#{k}#{
            case v
            when TrueClass; ''
            when Hash;       %Q{="#{v.subattribute}"}
            else             %Q{="#{v}"}
            end
        ;}}}.join
    end
    def subattribute
        map{|k, v| %Q{#{k}:#{v};}}.join
    end
end

class Array
    def dom type, hash = {}
        "<#{type} #{hash.attribute}>\n#{join("\n").gsub(/^/, "  ")}\n</#{type}>"
    end
end

class String
    def dom type, hash = {}
        "<#{type} #{hash.attribute}>#{self}</#{type}>"
    end
end

class Object
    def dom type, hash = {}
        "<#{type} #{hash.attribute}/>"
    end
end

Вопросы

  • Есть ли уже стабильные библиотеки, которые делают подобное?
  • Каковы потенциальные проблемы этого подхода (особенно моей реализации или использования цепного подхода))?
  • Некоторые атрибуты принимают логические значения, которые часто рекомендуется опускать.Например, <input type="text";readonly> вместо <input type="text";readonly="true">.В моей нынешней реализации я могу сделать это, передав true (который не будет использоваться в конце) в качестве значения для такого атрибута, как dom(:input, type: "text", readonly: true), но это кажется избыточным и также является частью причины, по которой я case оператор в коде, что делает его медленнее.Есть ли лучший способ сделать это?
  • Есть ли возможные улучшения в реализации?

1 Ответ

1 голос
/ 10 июня 2011

Основная причина хамла и большинства других вложенных вещей заключается в том, что в принципе легко посмотреть, как вложен ваш HTML. Я предполагаю это, но вы на самом деле код HTML или вы делаете больше бэкэнда? Причина в том, что во вложенном стиле вы увидите, как вложены ваши элементы (что важно для вас, если вы также пишете стили)

Хотя писать довольно просто

 .dom(:body).dom(:html)

дизайнеру сложно увидеть, как HTML движется без отображения и пытается его визуализировать в своей голове, тогда как:

 %html
   %body

делает это уже одним взглядом.

Не бери более длинный пример:

 "This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html)

Будет ли вам легче, если, скажем, клиенту или вам нужно добавить кликабельное изображение в ссылку? Как бы вы это сделали? В хамле это просто как:

 %html
   %body
     %a{:href => "blah"}
       = image_tag("image.png")

Кроме того, ИМХО, написание dom(:) для каждого тега html так же утомительно, как и написание для него закрывающего тега (который HAML и другие исправили)

Опять же, это всего лишь мое мнение программиста XHTML / CSS (в отличие от точки зрения программиста ruby)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...