Холивар кодера - шаблонизатор для пхп

KillDead

Хранитель порядка
Регистрация
11 Авг 2006
Сообщения
894
Реакции
579
Когда то человека задавшегося таким вопросом я бы кинул чемнибуть тяжёлым, но вот сейчас сам задаюсь проблемами шаблонизатора для своей цмс для скрипта, который возможно в будущем будут юрзать и другие. Шаблонизатор - один из вечных холиваров.
Итак, мой мнение, как среднего кодера не много стоит, почему? потому что обычно мнение отдельного индивидуума ограничено его мировосприятием, а особенно такого *****того как я. Я не вижу ничего сложного в конструкциях аля
Код:
core::$readRouter('mail:controller', new Profiler('core'))->getAction()->runApp()->endApp()
многие вещи которые вызывают страх у обычных людей мне кажутся очень красивым решением где всё разложено по полочкам, пусть и порой длинно.
Но, сейчас поставил задачу - сделать максимум простую и понятную цмс скрипт.
Меня интересует в первую очередь мнение верстальщиков, дизайнеров, людей которые больше делают верстку и дизайн, нежели программируют либо вообще ничего не знают. Так что примерно такие вопросы :
1. Если бы вам предложили сделать шаблонизатор специально для вас, чтобы вы максимально удобно и быстро верстали, какое бы вы дали ТЗ.
2. Что вас неимоверно бесит когда вы работаете с шаблонизватором Х и чужим кодом.
3... У меня есть некая квалификация и ещё более узкие вопросы, возможно задам их позже, чтобы не ограничивать ответы (если они будут :) ).
 
Самый читаемый вариант:
Код:
return template('user', form=form, hello='Здравствуйте, {0} {1}'.format(form.firstName.data,  form.lastName.data))
Код:
return template('название шаблона', ['user': 'Вася', 'Дата регистрации': '09.09.2012'])

Обязательно нужно if/endif, for in/endfor, возможно поддержка в шаблоне вызов метода переменной. В идеале чтобы что-то подобное можно было сделать:
Код:
{{ form.firstName.label }}: {{ form.firstName(size=30, value=form.firstName.data if form.firstName.errors and form.firstName.data) }}
Ну и без наследования (подключаем шаблон, который подключает еще один шаблон, который подключает еще один шаблон) сейчас уже никуда, иначе много дублирующего кода в шаблонах. Экранирование тоже нужно:
Код:
{{ user.name|safe }}
Ну и еще все это должно компилироваться в оптимальный PHP код для кеширования.


Работу с формами уже сделал?
 
У меня вообще идеи немного старомодны- максимально отделить шаблон от скрипта, логику и представление, в вакууме и идеале, чтобы скрипт вообще ничего не знал о шаблоне, а шаблон ничего не знал о сервере (ни какая система использована, ни переменные окружения, ни даже языка). Всё хорошо пока мы занимается простыми вещами, перебором и ифами. Но стоит нам на переферию, где логика и шаблон связаны неразрывно либо взаимоисключаемы и тут начинается поиск альтернативы, причём бескомпромиссной. Пример – активное меню. Верстальщик хочет его отметить и создаёт переменную в шаблоне построенной на логике, возможно которая не будет работать нигде кроме как на страницах с page. { @var = @config[‘pages’][‘cpage’]; if@get[‘page’] = @var} Либо кодер должен залезть в вьювер и определить эту логику. А вдруг он сделает её очень ограниченной для верстальщика, к примеру определит только в массиве с меню .


Чтобы вызывать методу у переменной - это конечно хорошо, но я вообще разделяю шаблонизаторы на
1. Скриптовые - смарти и нативный пхп .
+ Можно реализовать всё и просто. Нужна зебра особенная- легко. Прост в понимании и использовании.
- Мешанина логики и кода. Это далеко не лучший вариант особенно когда видишь в коде
{ $allPages = $page->getPages(); foreach( $allPages->getActive() as $p) { if( $p !== $config['page']){ .... } } }

И подобные тучные конструкции из какой то логики. Причём порой наблюдаем в шаблоне всякие mysql_query что вообще выбивает из колеи.

2. xslt вида.
Это уже не шаблонизатор - это язык шаблонов. Т.е пишем шаблон как скрипт.
+ хорошо структурирован. Нет мешанины, допустили ошибку в верстке- ничего не заработает.
- Особо сложен в понимании.

3. Макросные. xtemplates
Тут минимум функции в шаблоне. Нельзя ничего. Есть всего пара функций, (xtepl даже иф не поддерживает) все переменные текстовые либо массив с текстом .
+ Логика шаблона только в шаблоне.
- Логика шаблона уже в скрипте. Нам обязательно надо знать как верстальщик сделал шаблон и если он чтото поменяет, нам надо будет переделывать скрипт.

Тут и делема- всё или ничего не включать в шаблон. Нужна очень жёстная структура либо достаточно простых макросов.


----------

Формы.
Раньше я бы сказал что только аля зендФорм – тут мы просто боги- и автоматом генерим валидный и верный html, включаем js и серверную валидацию, можем даже тестировать формы автоматом. Но сейчас понимаю – мы залезаем в шаблон. Представьте- верстальщик, мы хотим красивую форму с картинками и бордюрами, вы хотите увидеть структуру? Гуглите, форма генерируется на лету. Хотите изменить порядок форм? Лезте в пхп и меняйте массив с неипической вложенностью и правилами…
У меня сейчас 2 решения:
1. Всё таки сделать реализацию зендФорм, но так чтобы она не была очень сильно связана с шаблоном. Т.е можем сделать и генерацию макросом {zendform_login}, либо пишем сами. Тут сложность в магии – мы генерируем чтото, неизвестно нужна ли jsпроверка, да и если мы будем сами формы в шаблоне писать, зачем нам изгаляться и писать их в пхп?
2. Сейчас просто остановился на правилах. Т.е есть у нас екшен с именем reg, создаём правило с таким же именем и пишем там правила валидации
Код:
    public function reg() {
        $this->login->notSimpleStr('Недопустимые символы в логине')->notLen(8, 25, 'Логин лишком длинный либо слишком короткий')->chekF(function ($login) {
                    return core::$user->loginExists($login);
                }, 'Увы, этот логин уже зарегистрирован в системе');
        $this->pass->notSimpleStr('Недопустимые символы в пароле')->notLen(8, 25, 'Пароль лишком длинный либо слишком короткий');
        $this->email->notEmail('Неверное мыло')->chekNotBadEmail('Выберите другой домен для мыла');
    }

Мы не можем построить настоящую форму, хотя простые – да. Даже с jsвалидацией. Не говоря уж и о серверной. Мне кажется красиво и понятно всё названо – notНАЗВАНИЕ_УСЛОВИЯ(САМО УСЛОВИЕ, МЕССАЖ)
+ пара ещё доработок для удобства.
 
KillDead, ты не понял суть form.firstName(size=30). Эта конструкция превращается в <input size=30 />, т.е. это всего лишь генератор View.
{ @var = @config[‘pages’][‘cpage’]; if@get[‘page’] = @var}
Код в шаблоне? WTF? Максимум должна быть возможность определить переменную с помощью шаблонизатора.
Код:
{% set active_page = "index" %}
У меня сейчас 2 решения:
Есть и третье решение:
Код:
<form method="post" action="/form">
    {{ form.firstName.label }}: {{ form.firstName(size=30, value=form.firstName.data if form.firstName.errors and form.firstName.data) }}

    {{ form.submit(value="Нажми меня!") }}
    {{ form.csrf_token }}
</form>
Что превращается в:
HTML:
<form method="post" action="/form">
    <label for="firstName">Имя</label>: <input id="firstName" name="firstName" size="30" type="text" value="">

    <input id="submit" name="submit" type="submit" value="Нажми меня!">
    <input id="csrf_token" name="csrf_token" type="hidden" value="20120909135858##2f7b450f33ac21ec0cfae5a0da36020cb892a639">
</form>
 
Код в шаблоне? WTF? Максимум должно быть возможность определить переменную с помощью шаблонизатора.
дада, это и есть недостаток скриптовых шаблонов- вначале у нас логика может быть хоть и простая, типо определяем из конфига активную страницу, а затем это преращается в то, что мы чють ли не считаем подоходный налог подключая curl и парсим банк, и всё в шаблоне...


Есть и третье решение:
а, я понял, ты предлагаешь аналог типа 2- язык шаблонов, когда html элементы формируется всякими наборами. Но насчёт форм - тут же обычный шаблонизатор, только выводим форму. Или идея аналогична зендформ но форма описывается именно в шаблоне?
 
дада, это и есть недостаток скриптовых шаблонов- вначале у нас логика может быть хоть и простая, типо определяем из конфига активную страницу, а затем это преращается в то, что мы чють ли не считаем подоходный налог подключая curl и парсим банк, и всё в шаблоне...
В других скриптовых языках либо пиши на шаблонном языке, либо выведется "как есть". Так что вопрос лишь в руках. Или в языке, если руки не из того места. Хотя я именно про это и говорил: PHP сам по себе шаблонизатор.
а, я понял, ты предлагаешь аналог типа 2- язык шаблонов, когда html элементы формируется всякими наборами. Но насчёт форм - тут же обычный шаблонизатор, только выводим форму. Или идея аналогична зендформ но форма описывается именно в шаблоне?
Там обычный метод, который возвращает html (с id и class, если в параметрах указать). Сама форма и её тип (text, password) описываются в контроллере.
Насчет зендформы я хз. Но идея проста: всякие input-ы с помощью методов создаем (возвращающие html, в параметрах можно указать id, class и специфичные для данного типа size, value и т.п.), остальное руками. Быстро и гибко.
 
Там обычный метод, который возвращает html (с id и class, если в параметрах указать). Сама форма и её тип (text, password) описываются в контроллере.
Насчет зендформы я хз. Но идея проста: всякие input-ы с помощью методов создаем (возвращающие html, в параметрах можно указать id, class и специфичные для данного типа size, value и т.п.), остальное руками. Быстро и гибко.
А ну это же работа с формами никак не отличается с работой с дивами и прочим html. Я просто имелл виду что формы можно вывести отдельно в пхп коды. Получается обеспечение целостности, гибкости, контроля и тп.

Мне больше всего нравится смарти без всего - аля Для просмотра ссылки Войди или Зарегистрируйся или аналог xlst, вернее питоновских штучек Для просмотра ссылки Войди или Зарегистрируйся
 
А ну это же работа с формами никак не отличается с работой с дивами и прочим html. Я просто имелл виду что формы можно вывести отдельно в пхп коды. Получается обеспечение целостности, гибкости, контроля и тп.

Мне больше всего нравится смарти без всего - аля Для просмотра ссылки Войди или Зарегистрируйся или аналог xlst, вернее питоновских штучек Для просмотра ссылки Войди или Зарегистрируйся
Сами формы имеют вид:
Код:
class MyForm(SessionSecureForm):
    SECRET_KEY = b'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym'

    firstName = TextField('Имя', validators=[validators.Length(max=6, message='Не больше 6!')])
    lastName = TextField('Фамилия')
    birthday = DateField('Дата рождения')
    password = PasswordField('Пароль', validators=[validators.Required(message='Введите пароль!')])
    submit = SubmitField()
Формы (создание, валидация и т.п.) пусть будут на PHP, но View для них нужно делать в шаблонизаторе (с помощью метода-генератора или еще как-то), т.к. я уже натрахался с drupal-ом, который гененировал View форм прямо в контроллере, у него костыли типа:
Код:
'prefix' => '<div id='123'>',
'suffix' => '</div>'
 
Назад
Сверху