Xpoint
   [напомнить пароль]

Способы разработки сайтов

Метки: [без меток]
2005-10-18 19:23:27 [обр] Михаил Харитонов[досье]

Здравствуйте.
Поделитесь, пожалуйста, знаниями в технологии разработки сайтов.
Мне интересна техническая сторона. Как Вы отделяете код от дизайна и от контента.
Сам я хочу в ближайшем будущем использовать технологию XSLT (php скрипт будет выдавать xml контент, который, наложением на него xsl шаблона будет в html преобразовываться. А если контент статический (т.е. который не выдаётся скриптом, например, текст о фирме в соответствующем разделе), то он будет храниться в отдельно xml файле, для того, что бы, например, можно было сделать другую версию страницы (версия для печати, например), просто написав ещё один xsl шаблон. Тогда не будет необходимости текст в нескольких местах менять.)
Но пока, на изучение XSLT нет времени, так что обхожусь шаблонизатором Smarty.
В основном делаю в основном так:
для каждой страницы есть свой php скрипт, к которому и обращается пользователь.
Т.е. вроде следующего:
index.php
about.php
contacts.php
PHP скрипт вызывает основной шаблон и передаёт различные переменные и название другого (второстепенного) шаблона для конкретной страницы, который загружается в основной шаблон. Т.е. вроде того (contacts.php):

<?php
require('includes/smarty.php');
$smarty = new Smarty_Site;
//
//
require('includes/top_menu.php'); //Добавляется $smarty->assign('menu', $menu);
require('includes/sub_menu.php'); //Добавляется $smarty->assign('sub_menu', $sub_menu);
$smarty->assign('page', 'contacts'); //Или можно просто название страницы передавать ($_SERVER['PHP_SELF'])
$smarty->assign('page_title', 'Контакты » Контактная информация');
$smarty->assign('page_head', 'Контактная информация');
//
//
$smarty->display('index_template.tpl');
?>

Таким образом дизайн меняется только в одном шаблоне ("index_template.tpl"), в который подгружаются шаблоны других страниц.
Но мне интересны другие подходы. Может есть лучший способ. В случае с шаблонизатором, интересует как Вы организуете структуру файлов (шаблонов в частности).
Недавно прочитал 16 наблу Д. Котерова "Код и шаблон страницы" (http://dklab.ru/chicken/nablas/16.html) и мне очень понравилась описанная там модель ведомых контроллеров. Может кто её использует? Интересует, какие проблемы встречаются при этом (если встречаются конечно)?

Понравился способ с ведомым контроллером в основном тем, что удобнее работать со структурой сайта (и шаблоны и изображение и стили - всё в одном месте) - т.е. структура как у статического html сайта. Но в этом случае не удобно будет отделять основной шаблон (с дизайном страницы) от шаблонов страниц. Максимум что можно сделать получается - это вынести шапку и подвал в отдельные файлы, а что бы сделать такой, например, шаблон http://iqb.ru/services/website-creation.html - простого выносы шапки и подвала думаю не достаточно. Может например понадобится изменение правой части...

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

P.S.: я прочитал многие темы на разных форумах, но они уже староваты...

спустя 6 минут [обр] Михаил Харитонов[досье]
Недавно прочитал 16 наблу Д. Котерова "Код и шаблон страницы" (http://dklab.ru/chicken/nablas/16.html) и мне очень понравилась описанная там модель ведомых контроллеров. Может кто её использует? Интересует, какие проблемы встречаются при этом (если встречаются конечно)?
P.S.: в статье этот способ (ведомый контроллер) описывается в четвертом и пятом способе и называется модель1 (от Sun)... просто ведомым контроллером этот способ Д.Котеров ещё где-то называл.
спустя 4 часа 39 минут [обр] Андрей Брайнин(0/127)[досье]

не буду теоритезировать, просто поделюсь личным опытом:

  1. выбираем инструменты исходя из поставленной задачи.

1.1 если нужен сугубо статичный сайт с максимальной производительностью, то SSI вполне достаточно

1.2 XML+XSLT - тяжелая связка (и с точки зрения используемых ресурсов и с точки зрения разработки XSLT-шаблонов). ее стоит применять, когда вы уверены, что в вашем сайте непременно будет несколько видов на одну модель (версия для печати, wap и пр.). при этом чтобы реализовать интерактивность, придется Model (XML) и View (XSLT) озаботиться реализацией Controler`а, который будет обрабатывать пользовательский ввод.
использовать эту схему во всех задачах просто ради мифического "концепта" (или "торчащих пальцев"), на мой взгляд, глупо. из пушки по воробьям.

1.3 наиболее распространенная ситуация - динамический сайт в одном дизайне (может быть версия для печати и различные скины). используем "шаблонизатор" + CSS (для реализациии версиии для печати и скинов). конкретно мы используем активный шаблонизатор, т.е. совмещающий функции View и Controler. но возможен и ваш вариант (который мне кажется менее удобным, но тем не менее имеющим право на существование) - когда контролером выступает отдельный скрипт, а шаблонизатор используется исключительно для наложения вида на модель.

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

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

спустя 1 час 46 минут [обр] Михаил Харитонов[досье]

Андрей Брайнин[досье]

конкретно мы используем активный шаблонизатор, т.е. совмещающий функции View и Controler.

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

<HTML><BODY>

<!-- Блок новостей -->
<h2>Последние новости:</h2>
<DATASRC src="News">
<FOREACH src=News>
    <li>$i-я новость: $news
</FOREACH>
<hr>

<!-- Блок погоды -->
<DATASRC src="Weather">
По сообщениям синоптиков, дождь, объявленный 
на сегодня, переносится на завтра на те же часы. 
Также завтра ожидается: $weather

</BODY></HTML>

Так?
Если я не правильно понял, то привидите пожалуйста небольшой пример кода.

спустя 2 минуты [обр] Eugene Efremov(0/68)[досье]

Михаил Харитонов[досье] писал:

Сам я хочу в ближайшем будущем использовать технологию XSLT (php скрипт будет выдавать xml контент, который, наложением на него xsl шаблона будет в html преобразовываться.

Ну, я, например, как раз что-то в этом роде пишу. Именно шаблонизатор в том смысле, который имеет в виду Дмитрий Котеров[досье], и именно на php + xslt.
Лежит здесь: http://xtpl.info-esta.ru/, исходники — на sourceforge, представляют собой почти точную копию означенного сайта.

А если контент статический (т.е. который не выдаётся скриптом, например, текст о фирме в соответствующем разделе), то он будет храниться в отдельно xml файле

Что касается содержимого статических страниц — то у меня оно может храниться хоть в xml, хоть в обычном html, хоть вообще в чем угодно, благо libxml может читать html и конвертить его в xml.
Но если статического содержимого мало, а тем более, если оно требует хитрых изменений шаблона страницы, то обычно оно хранится непосредсвенно в xstl.

А версию для печати можно будет сделать, воздействовав на то, что подгружается через xsl:import. (Впрочем, пока у меня это не реализовано)...

Интересует, какие проблемы встречаются при этом (если встречаются конечно)?

Естественно, встречаются. С самим шаблонизатором-то все относительно прозрачно, Дмитрий Котеров[досье] в своей книге все детально расписал. А вот с XSLT... Вот с чем, примерно, мне пришлось столкнуться. Перечисляю в хронологическом порядке:

  1. Не работала XsltProcessor::registerPhpFunctions -- при ее использовании совместно с xsl:key php висел намертво.

Отправил багрепорт. Исправили, но только для php 5.1. На нем сейчас и сижу. Пока нормального 5.1 не было — изобретал хитрую двухуровенвую систему парсинга, чтобы сперва генерился весь динамический xml, а уже потом оно единым куском запихивалось в xslt. По этой схеме оно сейчас и работает. Буду обратно переделывать.

  1. Не обрабатывались entity из dtd.

Написал препроцессор, dtd прибил.

  1. Возникла проблема перехвата всяческих import и document() для предварительной обработки всех xml. Параллельно возникла проблема с обеспечением правильных путей, по которым оно должно их искать

Это вообще отдльная песня. Именно этот глюк заставил меня зарегистрироваться на xpoint. Скажу сразу — здесь мне никто приемливого решения не предложил. И тему вообще быстро удалили. Так что в текущей версии (0.2.1 pre-alpha) это делается очень кривым способом. Через повторный запрос на сервер.

Правильное решение — надо юзать stream_wrapper_register. И это у меня в TODO-лист значится первым пунктом.

  1. Когда libxml порождало кучу error'ов и warning'ов в одном вызове, начинал глючить механизм перевода ошибок в исключения

Сейчас решается через очень кривой хак: несколько вложенных вызовов ф-ций, вложенных try-catch и т.п. В следующей версии попробую заюзать libxml — это расширение для пхп 5.1, обрабатывающее ошибки одноименной библиотеки. Правда не знаю, будет ли оно обрабатывать также и ошибки libxslt, с которыми наблюдается та же история. Это я еще буду проверять.

  1. Про утечки (дескрипторов файлов в первую очередь) вообще молчу. Впрочем, libxml от файловой системы я так и так скоро отважу, и как следствие, большенство моего кода, который мудрил с файлами, тоже отпадет.

В общем, мораль такая: шаблонизатор на php+xslt написать можно и без помощи сверхнавороченой XML-DB, хоть сам Дмитрий Котеров[досье] и утвeрждал обратное.

Впрочем, то, что у меня готово сейчас, стоит юзать только в плане ознакомления/тестирования. То что у меня самого на нем более-менее сносно работают два сайта — еще ничего не значит :-) Вот как у меня будет, хотя бы, версия 0.3 (которая, надеюсь, уже будет просто alpha, без "pre") — тогда желающие могут рискнуть...

Собственно, всё. Не знаю, наколько внятно ответил на поставленый вопрос, но, по крайней мере для себя я эту задачу в общих чертах решил...

спустя 8 часов [обр] Андрей Брайнин(0/127)[досье]

Михаил Харитонов[досье] все переменные могут задаваться как внутри шаблона, так и вне его (передаваться непосредственно шаблонизатору в виде параметров - этот подход используем для отправки писем).
под активностью шаблона я подразумевал, что щаблон может самостоятельно обращаться к модели для получения данных, а также может выполнять вызовы активных методов (например регистрации пользователя по данным полученным из формы ввода).

простейший пример вывода новостей news.xhtml:

<html><body>
<use class="POEM::Container">
<for each="Item" from="POEM::Container->new('site::news')->list()">
<b>#[Item.date|DATE(%d.%m.%Y)] #[Item.title]</b><br>
#[Item.body]<br>
</for>
</body></html>
спустя 4 часа 57 минут [обр] Михаил Харитонов[досье]

Андрей Брайнин[досье]
Т.е. активный шаблон - это тот, который включает в себя элементы программирования...
Но меня немного другое интересует. А именно структура файлов. Т.е. как я понял у Вас происходит примерно так:
Есть страницы (шаблоны) news.html, about.html и т.д. Так же есть файлы (либо одноимённые классы) includes/news.php, includes/about.php и т.д.
Пользователь обращается к странице news.html (т.е. набрав адрес http://example.com/news.html/). А в news.html лежит шаблон, в котором подключается файл news.php из которого берутся переменные для шаблона:

<html><body>
{include_php file="includes/news.php"}
<h1>Новости</h1>
{$news_arr} //тут выводим массив новостей, полученный из файла news.php.
</body></html>

Так?
Если да, то в этом случае можно будет вынести только отдельные общие части шаблона (например: шапку, подвал, левую часть). Т.е. шаблон бутет примерно такой:

<html><body>
{include file="header.tpl"}


{include_php file="includes/news.php"}
<h1>Новости</h1>
{$news_arr} //тут выводим массив новостей, полученный из файла news.php.


{include file="footer.tpl"}
</body></html>

Для простой разбивки это подходит, а если разбивка будет посложней? Например, вот эта или ещё сложней: http://iqb.ru/services/website-creation.html, где простого выноса шапки может быть недостаточно.
Я щас делаю так: выношу главный шаблон (с разметкой) и в отмеченные в нём части (в центр, в левую часть и т.д.) подключаю второстепенные шаблоны, в зависимости от выбранной страницы. Т.е. пользователь обращается к news.php (к контроллеру, а не к шаблону), а этот скрипт передаёт данные в основной шаблон, в который подключается вротостепенные шаблоны для news.php и всё выводится. (то, что я в первом посте описывал)
Ваше решение мне больше нравится (я в начале писал об этом вначале, называя этот способ "ведомым контроллером"), но так же мне нравится выносить всю разметку с дизайном (а не отдельные её части, такие как шапка) в отдельшый главный шаблон, что не получается сделать в Вашем способе.

спустя 3 минуты [обр] Михаил Харитонов[досье]

Eugene Efremov[досье]

С самим шаблонизатором-то все относительно прозрачно, Дмитрий Котеров[досье] в своей книге все детально расписал.

Давно хочу это книжку купить (думаю она мне многое прояснит), но щас другую читаю и бросать не хочется на середине. )

спустя 1 час 39 минут [обр] Алексей Севрюков(2/1280)[досье]

Михаил Харитонов[досье]

{$news_arr} //тут выводим массив новостей, полученный из файла news.php.

Неконцептуально, визуальное оформление и разметка генерится скриптом. В то время как у Андрея Брайнина[досье] разметка находится в самом шаблоне.

спустя 1 час 26 минут [обр] melfar(0/-1)[досье]

Алексей Севрюков[досье]

{$news_arr} //тут выводим массив новостей, полученный из файла news.php.

Я все же понял так, что в целях экономии места автор не стал приводить здесь детали оформления и разметки.

спустя 1 час 10 минут [обр] Андрей Брайнин(0/127)[досье]

Михаил Харитонов[досье] вы не совсем точно домыслили "мой" способ.
немного раскрою подход:

  1. нет никаких отдельных файлов из которых берутся переменные для шаблона. переменные шаблон формирует (объявляет) сам и заполняет их сам, обращаясь за необходимыми данными к модели. обращение к ней быть осуществлено в любом месте любого шаблона.

никаких отдельных news.php, about.php и пр.
в примере с новостями модель - это POEM::Container->new('site::news') - объект инкапсулирующий список сущностей (для простоты понимания - модель таблицы)
у этого объекта есть метод list, возвращающий список всех сущностей контейнера (для простоты - записей таблицы) (в данном примере всех новостей). вот на этом модель заканчивается.

шаблон (вид) умеет этот список перебирать (конструкция for) и отображать свойства сущности (конструкция #[Item.title] и подобные ). на этом заканчивается вид.
т.е. тут вроде все понятно - модель не содержит разметки, шаблон не содержит кода, формирующего данные (шаблон лишь обращается за данными к модели).

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

наши технологии позволяют реализовать обе описанные вами схемы:
как шапка-контент-подвал (1), так и центральный склелет + контексто-зависимые блоки (2).
c (1), я думаю, все понятно.
(2) могу пояснить на примере:
нужен сайт, имеющий единый скелет следующего вида: сверху шапка (общаяя для всех разделов) - слева блок "меню раздела" - в центре блок контент раздела - справа блок "смотри также" (содержание трех последних блоков зависит от отображаемого раздела). скелет настолько сложный, что его стоит реализовать в виде одного шаблона, к которому в зависимости от раздела подключатся блоки с соответствующим содержимым.
реализация:
/index.xhtml (центральная страница)

                 ШАПКА
МЕНЮ:
<include src="menu.xhtml">
здесь, ясен пень, куча всякой сложной разметки, чтобы все смотрелось достойно.
КОНТЕНТ:
<include src="content.xhtml">
здесь тоже разметка
<include src="related-links.xhtml">

/menu.xhtml

А вот новости
А вот каталог товаров

/content.xhtml

Добро пожаловать! бла-бла-бла

/related-links.xhtml

xpoint.ru
borland.com

раздел каталог товаров
/catalog/
опаньки, index.xhtml здесь нет.
и тут самое интересное! идея всплытия (с) (предложена мне для реализации Новиковым)
зато есть /catalog/content.xhtml и /catalog/menu.xhtml
1.клиент запрашивает /catalog/index.xhtml

  1. процессор шаблонов, видит что в папке /catalog/ такого файла нет и ищет его в папке выше (пока не дойдет до корня, в этом случае - 404)
  2. находит /index.xhtml но все инклуды внутри него отсчитывает от /catalog (и если не находит подключаемый файл, то ищет его выше)

в итоге при обращении к /catalog/index.xhtml мы видим:
ОБЩАЯ ШАПКА
меню каталога
контент каталога
и "смотри также", взятое с уровня выше (т.к. в /catalog/ нет файла related-links.xhtml)
xpoint.ru
borland.com


вуа-ля. на наш взгляд, очень удобно.

спустя 47 минут [обр] Михаил Харитонов[досье]

melfar[досье]

Я все же понял так, что в целях экономии места автор не стал приводить здесь детали оформления и разметки.

Так и есть. :)

спустя 1 час 33 минуты [обр] Михаил Харитонов[досье]

Андрей Брайнин[досье]

  1. как организовать шаблоны, чтобы не дублировать одни и те же куски в нескольких местах - это совершенно отдельный и вопрос, с кучей вариаций.
центральный склелет + контексто-зависимые блоки (2).

Вот как это реализовать мне и не было понятно. Теперь, благодаря Вам, понял. Это то, что я искал.
Только пару вопросов возникло:

1.клиент запрашивает /catalog/index.xhtml
  1. процессор шаблонов, видит что в папке /catalog/ такого файла нет и ищет его в папке выше (пока не дойдет до корня, в этом случае - 404)

Тут, как я понял, происходит переадресация или подмена URL через mod_rewriter, например? Т.е. клиент обращается к http://example.com/catalog/index.xhtml, а на самом деле, например к http://example.com/index.xhtml?page=catalog? Так? Ведь иначе, если пользователь запросит http://example.com/catalog/index.xhtml, а такого файла не будет - то 404. Или я опять не догнал идею?

И второй вопрос, Вы используете самописный шаблонизатор или нет?

спустя 11 часов [обр] Андрей Брайнин(0/127)[досье]

Михаил Харитонов[досье]
мы используем механизм апачи-хэндлера, натравленного на расширение .xhtml

    AddHandler text/x-poem-template .xhtml
    Action text/x-poem-template /cgi-bin/view.cgi

view.cgi - и есть тот самый процессор шаблонов, о котором я говорил ранее (правильней назвать его контроллером, но об этом чуть ниже).
независмо от того, существует ли файл на диске или нет, этот контроллер получает переменную окружения PATH_INFO, в которой содержится '/catalog/index.xhtml'. идея в этом. остальное - дело техники.

да, мы используем самописный "шаблонизатор" (дюже непонятное мне слово).
у нас есть объект "Шаблон", который содержит всю логику работы с текстом шаблона.
пример работы с шаблоном (кусок из view.cgi):

my $template = POEM::Template->new($file, $ENV{DOCUMENT_ROOT}, $ENV{PATH_INFO});
$template->do({ 'ENV' => \%ENV, 'Request' => $Request, 'Response' => $Response });
$Response->out($template->getOutput());

в этом примере шаблону передаются начальные переменные, с которыми он сможет работать
(но это не мешает шаблону формировать свои переменные внутри себя).

соответсвенно view.cgi - всего лишь обработчик URL, который находит соответсвующий запросу шаблон (вид) и передает управление ему.
вот почему его правильней называть контроллером. процессором же является сам объект "Шаблон".

сделано все это на Perl


можно использовать и описанную вами схему с mod_rewrite

спустя 9 часов [обр] Михаил Харитонов[досье]

Андрей Брайнин[досье]
Спасибо, теперь полностью разобрался, как работает Ваша схема.

P.S.: пытался найти готовое решение шаблонизатора с такими функциями, что бы не писать самому (т.к. нормальный я врядли напишу). Пока нашёл Templier (от Д.Котерова) - http://forum.dklab.ru/php/book......hLanguageOfPatternsSmarty.html

Powered by POEM™ Engine Copyright © 2002-2005