pasaran / yate

Yet Another Template Engine
MIT License
214 stars 28 forks source link

Препроцессинг HTML в yate-шаблонах #162

Open kizu opened 11 years ago

kizu commented 11 years ago

Я долго-долго думал о том, как лучше объединить возможноти, предоставляемые языками вроде Haml, SIML и Jade, и возможности, предоставляемые Yate.

В итоге решил примерно так: всё, что мне нужно от вышеупомянутых препроцессоров HTML — непосредственно препроцессинг + несколько мелких, связанных с этим делом фич.

Что я хочу: возможность предкомпилировать HTML из определённой конструкции. Примерно такой:

%div.class#id {
    …
}

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

Всё, что идёт после этого символа и до начала блока в фигурных скобках парсится и из этого генерируется html-блок. Синтаксис простейший, почти zen-html. В идеале хотелось бы там использовать более сложные селекторы, чуть ли не зен-кодинговые, но для начала точно хватило бы того, что я выше описал — имя тега, класс и айди. Остальные атрибуты можно задавать и потом в Yate.

Следуя традициям упомянутых выше языков имя тега должно быть опциональным — %.class, множественные классы хочется записывать аналогично — %.foo.bar и т.д.

Это первая часть :)


Вторая часть — то, чего мне жутко не хватало в HAML и что я долго проталкивал в Jade, пускай и не в совсем том виде, что хотелось бы.

Это «кастомные теги», или «миксины».

Синтаксис может быть примерно такой:

mixin %foo {
    …
}

Ну, ключевое слово mixin + имя тега (можно, наверное, не включая знак процента, но для единообразия можно и включить).

При использовании такого кастомного тега он бы генерировал хтмл, описанный в определении этого миксина.

Важный момент — нужно уметь пробрасывать внутрь переданные классы/айди, т.е. при вызове такого миксина: %foo.class#id этот класс и этот айди, по сути, будут переданы как аргументы (class и id, соответственно).

Кроме того, можно, в общем-то, добавить возможность передавать дополнительные аргументы, как если бы это был просто вызов функции: %foo.class(arg1,arg2) — в определении миксина можно было бы использовать тогда эти аргументы.

Внутри определения миксина нужно уметь писать какую-то специальную конструкцию, которая, собственно, будет применять то, что может быть передано в миксин.

Всё это может выглядеть как-то вот так:

mixin %link(href) {
    %a.link {
        @href = href
        @class += class
        %span.link__inner {
            yield()
        }
    }
}

%link.lol("#foo") {
    "Hello world"
}

Такой код бы был бы аналогичен вот такому Yate:

<a class="link">
    @href = "#foo"
    @class += " lol"
    <span class="link__inner">
        "Hello world"
    </span>
</a>

Над синтаксисом применения классов можно ещё подумать, но в целом выглядит это примерно вот так.

Мне кажется, что добавление такого дополнительного синтаксиса для написания HTML могло бы очень многие вещи упростить — было бы очень просто определять «вёрсточные» шаблоны, реиспользовать их и т.д. — и т.к. такие конструкции можно «разворачивать в Yate» перед компиляцией, на производительность это влиять уже не будет, разве что может чуть увеличиться время сборки, но вроде синтаксис получается не особо страшным, так что, кажется, можно реализовать это быстро.

Как-то так.

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

С подобными возможностями (особенно, если потом ещё и дать возможность по-разному обрабатывать переданные классы, как я это сделал в bemto) интерфейсная часть может стать очень простой — будет очень легко выделять всякие блоки в отдельные сущности и реиспользовать их, добавляя классы и/или атрибуты по необходимости.


Всё это обдумано в метро, потому наверняка где-то можно к чему-то придраться, есть что дополнить и с чем поспорить. Но, если честно, я не смог придумать каких-либо аргументов почему бы не реализовать подобную штуку в Yate. Если я что-то упускаю — всегда буду готов выслушать аргументы.

И ещё раз, на всякий случай, — это не замена HTML, а возможность писать его иначе.

Для начала мне бы хватило и первой части — шортката над html-тегами, но вся мощь подобного сокращения раскрывается именно в сочетании с принципов «кастомных тегов».

pasaran commented 11 years ago

Вкуриваю )