Наследование HTML файлов в xslt-стиле

Проблема Однажды, в ходе переписывания большого проекта, возникла необходимость улучшить механизм кастомизации html шаблонов под разные версии нашего web-приложения. В старой версии кастомизация выглядела подобным образом: {{if app.version==versions.main}} {{else if app.version==versions.custom1}} {{else if app.version==versions.custom2}} {{endif}} И подобной лапшой был пронизан весь проект. Такой код сложно поддерживать и изменять, при активном использовании шаблоны превращаются в непонятную кашу, где бизнес логика отображения отдельных блоков переплетается с кастомизацией под разные версии.Привыкнув к удобным методам управления версиями приложения с помощью инъекции зависимостей, когда в зависимости от версии используются разные реализации интерфейсов, я решил изобрести свой велосипед для XSLT-подобного управления версиями html файлов: grunt-html-inheritance. Он позволяет подменять кусочки базового html-файла с помощью маленьких патчей.При переписывании проекта в качестве фреймворка был выбран AngularJS, поэтому вёрстка в приложении хранится в виде множества html файлов, подгружаемых при необходимости, что позволило легко внедрить систему сборки этих файлов с кастомизацией под разные версии приложения.

Пример Давайте представим, что у нас имеется следующий кусок вёрстки в HTML файле «myfile.html»:

Blah blah blah
Main version
И, как часто бывает в разных версиях приложения, нам понадобилось, чтобы в версии «myversion» вместо одного текста «Main version» отображался другой: «My version». Чтобы сделать это с помощью html-inheritance, нужно сделать 2 простых шага:

1. Добавить к кастомизируемому тегу аттрибут, начинающийся на «bl-»:

Blah blah blah
Main version
2. Создать файл «myfile.myversion.html» с патчем к родительскому файлу:
Custom version
Всё! При билде проекта все html файлы будут аккуратно сложены в указанную папку с разбивкой по версиям:

dist | main/ myfile.html myversion/ myfile.html Теперь достаточно указать вашему приложению, откуда грузить html файлы в зависимости от версии, и всё будет работать само по себе! Установка Чтобы добавить grunt-html-inheritance в ваш проект, нужно установить npm модуль командой npm install grunt-html-inheritance --save-dev или добавить зависимость в package.json, загрузить задачу в Gruntfile.js командой grunt.loadNpmTasks ('grunt-html-inheritance'); и настроить задачу следующим образом: grunt.initConfig ({ html_inheritance: { main: { files: { src:»**.html» //селектор для файлов }, options: { modules: [«version1», «version2»], //список модулей dstDir:»…/dist», //папка, в которую будут складываться скомпиленные файлы }, }, }, }); В AngularJS приложении важным условием легкого переключения между версиями HTML файлов является использование хелпера для построения путей к файлам шаблонов вместо жёсткого прописывания этих путей в директивах и роутингах.Преимущества Самое интересное преимущество такой системы кастомизации — основную версию проекта можно использовать без компиляции html файлов, так как bl-аттрибуты не мешают браузеру отображать исходный файл. Так же для использования такого метода не нужно изучать новый синтаксис какого-либо шаблонизатора, вся логика реализуется с помощью обычных html-аттрибутов, знакомых каждому разработчику.Использование Кроме замены базового тега в патче, описанного в примере выше, так же доступны следующие режимы: Удаление — удаление в патче родительского элемента Вставка — вставка в патче элемента, тогда как в основной версии элемента не будет Модификация аттрибутов — удаление и добавление аттрибутов к родительскому элементу, удаление и добавление классов. Полная документация доступна на странице пакета или в репозитории на github. Модуль покрыт тестами и нуждается в дальнейшем совершенстовании. Приглашаю сообщество помочь в развитии, присылайте pull-реквесты!

© Habrahabr.ru