Челендж на 2026

Александр Воробьев
На сайте с 03.02.2020
Offline
67
#581
Вообще модуль шаблонизатора получился самым насыщенным по количеству опробованных "версий": варианта три парсера, несколько вариантов синтаксисов, в общем у каждой мелочи было по несколько вариантов. :)
S3
На сайте с 29.03.2012
Offline
395
#582
Александр Воробьев #:
Это удобно решил. Предположим ставим компонент через композер и мне как его пользователю должно быть пофиг что там со стилями. Возможно мне о них даже знать не надо вовсе. Либо, стили подключаются в зависимости от некоей логики в компоненте. 

это все решается грамотной иерархией без необходимости лишнего рендеринга пхп в хтмл. Вот смотри:
есть базовый шаблон с структурой

Здесь я описываю блоки страницы, а потом просто создаю шаблон для раздела

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

В итоге абсолютно поняитная структура, которая легко подстраивается под требования

Александр Воробьев #:
Да. Над этим вопросом долго думал. И был даже изначально именно с end , но потом все же пришел к слешу.
Александр Воробьев #:
вообще у меня есть идея по расширению функционала директив и там вертикальной черте была роль отведена.

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

Александр Воробьев #:
Это удобно решил. Предположим ставим компонент через композер и мне как его пользователю должно быть пофиг что там со стилями. Возможно мне о них даже знать не надо вовсе. Либо, стили подключаются в зависимости от некоей логики в компоненте. 

Вместо того чтобы просто использовать блок со стилями тебе в итоге нужно каждый раз их подключать - излишний код.
Мы через такое проходили. KISS/DRY/Solid  в помощь 😀

Понятно, что моя критика - как человека который перебрал массу вариантов. Нсли кто-то начнет разработку с твоего фреймворка - он будет прекрасно использовать его без моих заморочек. Вполне понятный синтаксис, мне, как уже 10 лет не работавшему с пхп - все понятно.
В отличие от XML  мешанины твоего конкурента

ArbNet
На сайте с 27.10.2019
Offline
154
#583
Александр Воробьев #:
Вообще модуль шаблонизатора получился самым насыщенным по количеству опробованных "версий": варианта три парсера, несколько вариантов синтаксисов, в общем у каждой мелочи было по несколько вариантов. :)
Поверь это ещё не предел. Если всё же не бросишь разработку своего этого инструмента, то не раз ещё его будешь переделывать. Особенно когда начнёшь на нём что-то создавать, тот же форум, наткнешься на разные неудобства, которые придётся решать костылями или всё же если по хорошему, то переделывать основу своего ядра, шаблонизатора и тд.

ЗЫ. Я через это всё проходил неоднократно. Поэтому и долго всё разрабатываю.
Александр Воробьев
На сайте с 03.02.2020
Offline
67
#584
Sly32 #:
Вместо того чтобы просто использовать блок со стилями тебе в итоге нужно каждый раз их подключать - излишний код

Зачем каждый раз? не совсем понял. Компонент подключает - пользователь об этом не знает. (По крайней мере до тех пор если не понадобиться переопределить). Но в этом случае он просто размещает нужный файл  в нужном подкаталоге (условно: templates/my-new-year-site-template/component/vasoft/greeting/main/style.css ,  (т.е. когда мой новогодний шаблон сайта и компонент подключен с шаблоном main) штатный css файл замещается указанным. Пользователю так же ни чего не надо "подключать" отдельно.

Александр Воробьев
На сайте с 03.02.2020
Offline
67
#585
ArbNet #:
ЗЫ. Я через это всё проходил неоднократно. Поэтому и долго всё разрабатываю.
У меня есть опыт проектов выполненных с использованием разных инструментов и без, так что мне, в этом плане, несколько легче и позволяет пропускать лишние итерации.
ArbNet
На сайте с 27.10.2019
Offline
154
#586
Александр Воробьев #:
У меня есть опыт проектов выполненных с использованием разных инструментов и без, так что мне, в этом плане, несколько легче и позволяет пропускать лишние итерации.

Ну да, ты же не изобретаешь велосипед, а делаешь как другие просто.

ЗЫ. А вот если бы реально что-то разрабатывал с ноля, то ты бы прошёл через то, что и я.

S3
На сайте с 29.03.2012
Offline
395
#587
Александр Воробьев #:
Компонент подключает - пользователь об этом не знает.

Это все понятно. Но я вижу избыточное решение, которое ничего не дает в плане функционала. Да, так можно, но зачем? Зачем мне отдельно прописывать компонент, который и так отлично работает в хтмл и в шаблоны подключается обычным тегом, без дополнительного класса-прослойки? шаблонизатор - понимаю, наследования, директивы-фильтры - тут все супер. Стили - переусложнение, имхо.

Я почти уверен что ты и сам к этому придешь

Александр Воробьев
На сайте с 03.02.2020
Offline
67
#588
Sly32 #:

Это все понятно. Но я вижу избыточное решение, которое ничего не дает в плане функционала. Да, так можно, но зачем? Зачем мне отдельно прописывать компонент, который и так отлично работает в хтмл и в шаблоны подключается обычным тегом, без дополнительного класса-прослойки? шаблонизатор - понимаю, наследования, директивы-фильтры - тут все супер. Стили - переусложнение, имхо.

Я почти уверен что ты и сам к этому придешь

Пожалуй мы говорим о разном :) не совсем тогда понимаю о чем ты.

Компонент это в первую очередь функционал. Т.е. я вывел {% component  vasoft:catalog %} (который установил композером) и вот у меня полноценное отображение каталга товаров (а это не только тупое отображение списка, но и выборка, учет все возможных скидок, акций и т.п) Что значит его подключить обычным тегом? Т.е. у компонента вывод html важная но не обязательная часть. Может быть это просто подключение кода счетчика на страницу (при чем ИД из конфига, и вывод по условию какомуто).....

Если ты про директиву include. То на первом этапе ее фишка это то, что стили будут подключены один раз даже если по каким то причинам (например использование в разных компонентах и лейаутах), далее это точка для "расширения": склеивать файлы стилей в один/"ограниченное несколько",  или "переключать" на CDN. Так же сейчас дополняется солью, чтобы при изменениях кеш не мешал.

S3
На сайте с 29.03.2012
Offline
395
#589
Александр Воробьев #:
Пожалуй мы говорим о разном :) не совсем тогда понимаю о чем ты.
Возможно. Попробую на пальцах обьсянить свое видение шаблонизатора.
1. У меня есть базовый шаблон, каркас. В jinja2  это выглядит так.
base.html
<!DOCTYPE html>
<html lang="ru">
  <head>
    {% include "head.html" %}
  </head>
  <body>
    {% include "navbar-main.html" %}

    <main class="container-fluid py-4">
      {% block content %}{% endblock %}
    </main>
все
    {% include "footer.html" %}
    {% include "cookie-consent.html" %}

    <div class="theme-toggle dropdown dropup">
      <button
       class="btn btn-primary dropdown-toggle d-flex align-items-center"
       id="theme-toggle-button"
       type="button"
       data-bs-toggle="dropdown"
       aria-expanded="false"
       aria-label="Toggle theme"
      >

        <i class="bi bi-circle-half"></i>
      </button>
      <ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="theme-toggle-button">
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="light">
            <i class="bi bi-sun-fill"></i>
            Светлая
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="dark">
            <i class="bi bi-moon-stars-fill"></i>
            Темная
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="auto">
            <i class="bi bi-circle-half"></i>
            Авто
          </button>
        </li>
      </ul>
    </div>
    
    <script>
      (function () {
        const csrfToken = "{{ csrf_token | default('') }}";
        if (!csrfToken) return;
        const forms = document.querySelectorAll("form");
        forms.forEach((form) => {
          if (form.querySelector('input[name="csrf_token"]')) return;
          const input = document.createElement("input");
          input.type = "hidden";
          input.name = "csrf_token";
          input.value = csrfToken;
          form.appendChild(input);
        });
      })();
    
</script>
    <script src="/static/js/cookie-consent.js"></script>
    <script src="/static/js/theme-toggle.js?v={{ release_version }}"></script>
    {% block scripts %}{% endblock %}
  </body>
</html>

тут есть только то, что будет на любой странице - мне не нужно каждый раз это переподключать - стили, скрипты, тот же бутстрап...
Дальше я создаю, например страницу для статей, блог. Аналог твоего RSS.

{% extends "base.html" %}

{% block head %}
  {{ super() }}
  <!-- Schema.org JSON-LD разметка для SEO -->
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "SoftwareApplication",
    "name": "LearnService - Платформа для обучения",
    "description": "Платформа для эффективного обучения с расписанием занятий, интерактивными тестами и поддержкой ИИ-наставника",
    "applicationCategory": "EducationalApplication",
    "offers": {
      "@type": "Offer",
      "price": "0",
      "priceCurrency": "RUB"
    },
    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": "4.8",
      "ratingCount": "100"
    }
  }
  
</script>
{% endblock %}

{% block content %}
  <section class="page-hero pb-1">

Ты это уже реализовал примерно также. Для кастомной страницы я наследуюсь от  базового шаблона и просто меняю нужные мне блоки - header, content,  в которых и происходит вся магия - так же как у тебя.
Но для того чтобы подключить блок стилей или скриптов мне не нужно регистриовать компонент - у меня уже есть хедер или футер. Я или заменяю его или наследуюсь и расширяя.
то есть просто создаю новый шаблон head.html,  в котором подключаю стили.

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ page_title or "Главная" }}</title>
<script src="/static/js/theme-init.js?v={{ release_version }}"></script>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico" />
<link rel="alternate icon" type="image/svg+xml" href="/static/favicon.svg" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFebRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" />
<link rel="stylesheet" href="/static/css/web.css?v={{ release_version }}" />
<link rel="stylesheet" href="/static/css/theme-toggle.css?v={{ release_version }}" />
<link rel="stylesheet" href="/static/css/cookie-consent.css?v={{ release_version }}" />
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-P"></script>
<script src="/static/js/analytics.js?v={{ release_version }}"></script>
<script src="/static/js/switch-language.js?v={{ release_version }}"></script>

все! никакой код писать ненадо пользователю, просто меняю путь к стилям, как ты говоришь, если хочу  прикрутить новогодний.
Просто и понятно даже новичку - 15 минут прочитать про шаблонизатор и начать его использовать. Гибкость - абсолютная. от кода - полная изоляция.

Но на самом деле это спор так, чисто  убить свободное время. Если проект получит развитие, я в 99% просто уйду на фронте на Реакт. Поэтому я всегда больше делаю упор на API.

Но как практика - снимаю шляпу, ты молодец. Мне вот лень так глубоко лезть и тратить время на свой шаблонизатор

Александр Воробьев
На сайте с 03.02.2020
Offline
67
#590

не. тут история другая. Начнем с начала. 

1. все что ВНЕ body не надо пользователю писать непосредственно. Это все формируется HtmlResponse из фреймворка даже а не шаблонизатора. Туда можно добавлять и скрипты и css и все что необходимо прочее. Т.е. шаблонизатор это только про body (учитывая что из него можно регистрировать для хеадера все что нужнл, устанавливать title или метатеги.)   Т.е. это как раз "фишка" фреймворка что есть HTmlRespons - который гарантирует отдачу валидной HTML страницы в целом (т.е без боди все остальное формирует он)

2. В контроллере делаем $response->show('/pages/some.php'). Этот файл может быть таким (из твоего примера):


{%layout base%}
    <div class="theme-toggle dropdown dropup">
      <button
       class="btn btn-primary dropdown-toggle d-flex align-items-center"
       id="theme-toggle-button"
       type="button"
       data-bs-toggle="dropdown"
       aria-expanded="false"
       aria-label="Toggle theme"
      >

        <i class="bi bi-circle-half"></i>
      </button>
      <ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="theme-toggle-button">
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="light">
            <i class="bi bi-sun-fill"></i>
            Светлая
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="dark">
            <i class="bi bi-moon-stars-fill"></i>
            Темная
          </button>
        </li>
        <li>
          <button type="button" class="dropdown-item d-flex align-items-center gap-2" data-bs-theme-value="auto">
            <i class="bi bi-circle-half"></i>
            Авто
          </button>
        </li>
      </ul>
    </div>
{%/layout%}

далее имеем /templates/default/layouts/base.php

<!-- здесь подключение навбара -->
    {%raw __layout.content%}
    {%include css __layout.css%}
    {%include js __layout.js%}
<!-- здесь подключение футера -->

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

Стили и js в данном случае. Это "не каждому пользователю", это создается разработчиком конкретного каркаса. Эти файлы размещаются рядом. т.е. в данном примере будут   

/templates/default/layouts/base.php, /templates/default/layouts/base.js и /templates/default/layouts/base.css. Это отголоски однофайлового компонента Vue  :)  только там все в одном файле.  Но эти подключения не обязательны.  По  сути может быть ведь каркас кнопки. И, с одной стороны, нет необходимости подключать всегда и/или на всякий случай стили кнопки, с другой не надо подключать файлы по количеству кнопок на странице.

т.е. если

// pages/index.php
{%layout button%}
<button>First</button>
{%/layout%}
{%layout button%} <button>Second</button> {%/layout%}
// ... layouts/button.php
{%include css __layout.css%}
{%include js __layout.js%}
<div class="buttons-place">
<div class="buttons-notice"></div>
{%raw __layout.content%}
</div>

То пользователь этого каркаса вообще не будет знать о подключении стилей у него просто все заработает - и стили и скрипты. Подключаемые файлы подключатся единожды. Если здесь ставить HTML-подключение файлов - оно будет около каждой кнопки подключаться. 

Sly32 #:
Но для того чтобы подключить блок стилей или скриптов мне не нужно регистриовать компонент

Для простого подключения стилей/скриптов компонент не нужен. Для этого есть include. Компонент нужен - когда необходима логика. Т.е там может быть все что угодно, с кеширвоанием  и без, с внешними интеграциями и прочим,  при этом на странице может в итоге отобразиться только фраза дня :)

Sly32 #:
Но на самом деле это спор так, чисто  убить свободное время. Если проект получит развитие, я в 99% просто уйду на фронте на Реакт. Поэтому я всегда больше делаю упор на API.

Ну я не воспринимаю как спор. Наоборот это полезно. ( и уж точно полезнее чем в 100500 раз слушать о "с ноля / не с ноля" :) ). Я ж вполне понимаю, что могу быть и не прав, и из обсуждений как раз таки и рождаются полезные мысли. Как пример из твоего  примера пометил себе что не хватает что то типа include но уже строки (<script>....</script>)чтоб гарантировать отсутствия дублирования и закидывать этот кусок либо в head либо вниз страницы (третий параметр include есть сейчас такой)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий