Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML шаблонизатор #46

Closed
maxsite opened this issue Apr 15, 2015 · 14 comments
Closed

HTML шаблонизатор #46

maxsite opened this issue Apr 15, 2015 · 14 comments

Comments

@maxsite
Copy link
Owner

maxsite commented Apr 15, 2015

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

<p class="comment-info">
    <span class="comment-num">№ <?= $comment_num ?></span> | 
    <span class="url"><?= $comments_url ?> | <?= $comusers_url ?></span>
    <?= $comment_edit ?>
    <?= $comment_approved ?> 
    <span class="date"><a href="#comment-<?= $comments_id ?>" id="comment-<?= $comments_id ?>"><?= $comments_date ?></a></span>
</p>

То есть стандартные короткие php-конструкции, которые не загромождают верстку.

Однако возникают сложности, если требуется использовать при верстке if-условия. Для затравки посмотрите файл shared/type/page/units/page-comment-form.php
https://github.com/maxsite/cms/blob/dev/application/maxsite/shared/type/page/units/page-comment-form.php

Здес такая куча и такое переплетение условий, что не так и просто разобраться.

Поэтому моё предоложение: подумать о каком-то простом шаблонизаторе, который упростит синтаксис php-кода и сделает верстку проще.

Чтобы было понятно, приведу пример готового кода для шаблонизатора:

<div class="comments-textarea">

    {% if (is_login()) : %}
        <input type="hidden" name="comments_user_id" value="{{ getinfo('users_id') }}">
        <div class="comments-user">
            {{ tf('Привет') }}, 
            {{ getinfo('users_nik') }}! 
            <a href="{{ getinfo('siteurl') }}logout">{{ tf('Выйти') }}</a>
        </div>
    {% endif %}

    {% if ($comuser = is_login_comuser()) : %}

        <input type="hidden" name="comments_email" value="{{ $comuser['comusers_email'] }}">
        <input type="hidden" name="comments_password" value="{{ $comuser['comusers_password'] }}">
        <input type="hidden" name="comments_password_md" value="1">
        <input type="hidden" name="comments_reg" value="reg">

        <div class="comments-user comments-comuser">

            {% if (!$comuser['comusers_nik']) : %} 
                    {{ tf('Привет!') }}
            {% else %}
                    {{ tf('Привет,') }} <a href="{{ getinfo('siteurl') }}users/{{ $comuser['comusers_id'] }}">{{ $comuser['comusers_nik'] }}</a>!
            {% endif %}

            <a href="{{ getinfo('siteurl') }}logout">{{ tf('Выйти') }}</a>

        </div>

    {% endif %}

Здесь всё очень просто. Есть две управляющие конструкции {{ }} и {% %}

Первая эквивалент
Вторая:

Всё остальное — обычный php-синтаксис. При этом в шаблоне можно использовать и его обычные конструкции.

Прошу высказаться по этому вопросу.

@maxsite
Copy link
Owner Author

maxsite commented Apr 15, 2015

Первый пример с шаблонизатором.

<p class="comment-info">
    <span class="comment-num">№ {{ $comment_num }}</span> | 
    <span class="url">{{ $comments_url }} | {{ $comusers_url }}</span>
    {{ $comment_edit }}
    {{ $comment_approved }}
    <span class="date"><a href="#comment-{{ $comments_id }}" id="comment-{{ $comments_id }}">{{ $comments_date }}</a></span>
</p>

Читабельность кода выше за счет отказа от < и > в php-коде. Угловые скобки это только html.

@leonovmax
Copy link

а не будет ли проще в шаблонизаторе реализовать что-то типа:

$tpl->set('{comment_num}', $comment_num);

а оформление уже будет выглядеть:

<span class="comment-num">№ {comment_num}</span>

итд...

@leonovmax
Copy link

а для блока использовать что-то типа:

$tpl->block( "[is_login](.*?)[/is_login]", is_login() );

оформлять блок как:

[is_login]
тут отображать то, что для is_login()
[/is_login]

@cuprum
Copy link

cuprum commented Apr 15, 2015

@maxsite А вот <? ?> и <?php ?> это полные эквиваленты? Тогда можно везде использовать один вариант - {{ }} (или какой нибудь другой).

@leonovmax А если нужно написать условие посложнее? Геморройно 😿.

@maxsite
Copy link
Owner Author

maxsite commented Apr 15, 2015

Основная проблема смеси php и html — это единые угловые скобки. Именно поэтому в шаблонизаторах исключают php-скобки.

Сам шаблонизатор должен быть очень простым. Если делать какой-то более сложный вариант со своим синтаксисом, то это сильно усложнит и его разработку. Плюс привыкать к новому синтаксису. Если мы берем php, то будут доступны все его возможности.

Вариант {{ }} удобен для набора и годится для самой часто используемой конструкции . Вариант {% %} будет встречаться гораздо реже и тоже визуально выделяется.

@vimruler
Copy link

@maxsite, предложение по такому шаблонизатору выглядит разумно и вполне юзабельно. Но проблема обычно не в технологии, а в ленивых людях :) Я правильно понимаю, что без использования шаблонизатора кастомизировать указанные фрагменты шаблона будет нельзя (точнее можно, но в очень ограниченном варианте)?

@maxsite
Copy link
Owner Author

maxsite commented Apr 16, 2015

Можно. Задача разделить логику от представления. Но в представлении (верстка) всё равно будет встречаться какая-то логика. Например вывод комментария. Там есть аноним, комюзер, юзер. У комюзера может быть указан еще и сайт. Таким образом вывод будет меняться от A до SPAN, причем может одбавляться дополнительное поле-ссылка САЙТ. В во всех этих элементах будет свой css-класс. Задавать где-то отдельно класс, а html-код ещё где-то просто не удобно. Здесь же всё будет в одном месте.

Идея этого шаблонизатора в том, чтобы просто заменить php-скобки. Сам код остается с php-синтаксисом. И это означает что в файле-шаблоне можно будет использовать привычный php.

<?php
любой php
?>

<a href="{{ $URL }}">{{ $SITE }}</a>

Верстальщик кидает в свой шаблон файл для кастомизации и сам уже решает что ему удобней: чистый php или html-шаблонизатор.

@maxsite
Copy link
Owner Author

maxsite commented Apr 16, 2015

Добавлю. Шаблонизатор — не глобальная вещь. Он будет использоваться только в предопределенных подключаемых файлах. То есть это точечное использование.

@maxsite
Copy link
Owner Author

maxsite commented Apr 19, 2015

Покажу готовый код вывода коментария.

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); ?>

<article class="{{ $a_class }} clearfix">

    <img src="{{ $avatar }}" alt="" class="gravatar right">

    <p class="comment-info">
        <span class="comment-num">№ {{ $comment_num }}</span> | 

        <span class="url">{{ $comments_url }}

        {% if ($comusers_url) : %}
            | <a href="{{ $comusers_url }}" rel="nofollow" class="comuser-url">{{ tf('Сайт') }}</a>
        {% endif %}

        </span>

        {% if ($edit_link) : %}
            | <a href="{{ $edit_link . $comments_id }}" class="comment-edit">edit</a>
        {% endif %}

        {% if (!$comments_approved) : %}
            | <span class="comment-approved">{{ tf('Ожидает модерации') }}</span>
        {% endif %}

        | <span class="comment-date"><a href="#comment-{{ $comments_id }}" id="comment-{{ $comments_id }}">{{ mso_date_convert('d-m-Y H:i', $comments_date) }}</a></span>
    </p>

    <div class="comments_content">{{ $comments_content }}</div>

</article>
<hr>

Алгоритм работы шаблонизатора очень простой. На примере вывода тех же комментариев.

// проверили наличие файла и передали его в mso_get_tmpl()
if ($fn = mso_find_ts_file('type/page/units/page-comments-article-tmpl.php')) 
        $template = mso_get_tmpl($fn);

// теперь в $template готовый php-код для eval()

foreach()
{
    // готовим все php-переменные, которые используются в шаблоне

    // выполняем код шаблона
    eval($template);
}

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

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

@vimruler
Copy link

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

Код выглядит нормально. Надо пробовать на реальных задачах чтобы что-то более конкретное сказать.

@leonovmax
Copy link

Да, выглядит отлично. Чем-то напоминает Twig ) Или это он и есть?

@maxsite
Copy link
Owner Author

maxsite commented Apr 20, 2015

Нет, не Twig. У нас круче. :-)

@Tiahin
Copy link

Tiahin commented May 4, 2015

Поэтому моё предоложение: подумать о каком-то простом шаблонизаторе, который упростит синтаксис php-кода и сделает верстку проще.

Мое предложение - Fenom
Статья о нем на Хабре

@maxsite
Copy link
Owner Author

maxsite commented May 5, 2015

Наш получился круче. :-)

@maxsite maxsite closed this as completed May 8, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants