Комментарии 9
Вы бы хоть какой-нибудь пример типа бложека сделали, а то одинокий hello world и больше никаких намёков на то, на что же будет похож итоговый код.
+1
В качестве учебного пособия есть гостевая книга: github.com/nyan-cat/easybook, ее логика такая: регистрации нет, автор сообщения может редактировать или удалять сообщения. Автор определяется по правилу: если IP тот же, и если сообщение не старше 10 минут (конечно же это просто для примера, в жизни так не делают). Или вы ее и назвали hello world-ом? Реальный сайт будет примерно так и выглядеть, только будет больше файликов в каждой папке. Объемы файликов будут такие же, или чуть больше. Разве что последние фичи, описанные в этом посте, там еще не используются. Easybook должна дать полное понимание того, как делается сайт на Easyweb. В репе лежит easybook.sql — его надо импортнуть в базу, создать MySQL-юзера, прописать его логин-пароль в datasource.xml, и все — сайт заработает. Если же примера Easybook вам недостаточно, то напишите, что именно вы хотели бы увидеть, и я буду дорабатывать этот пример.
P.S. Хабротипограф — фи. Тире нужно отбивать неразрывным пробелом, а не обычным.
P.S. Хабротипограф — фи. Тире нужно отбивать неразрывным пробелом, а не обычным.
0
делаю нечто похожее, так что небольшой обмен опытом)
1. для парсера нужно уметь указывать baseURI относительно которого будут вычисляться relativeURI. использовать везде абсолютные ссылки — не предлагать)
2. get — слишком абстрактный интерфейс, лучше его конкретизировать: getDOMNode, getSimpleXML и тп. у меня у каждого узла просто есть свойства DOMNode и DOMDocument.
3. www:paginate — опять же префикс слишком абстрактен, лучше использовать конктретный типа easyweb:paginate. и использовать его не только в имени функции, но и в имени режимов (easyweb:previous,easyweb:next,...). основная цель пространств имён — не указать предназначение, а избежать конфликтов и недопониманий. впрочем, там действительно нужна эта функция? сдаётся мне всё это реализуемо не слишком сложными шаблонами. к тому же, почему нельзя указать откуда брать данные? или предполагается для каждого блока на странице вручную прогонять по xslt преобразованию? не слишком практичное решение.
4. инвалидация по времени — зло. неужели так сложно сделать инвалидацию по событиям? да и вообще, что там кешировать? xslt преобразования и так реактивны. а если уж совсем жалко процессорного времени фронтенда, то можно вообще переложить его на плечи клиента. для примера сайт: hyoo.ru/?article=XStyle;author=Nin+Jin — статейку тоже почитайте, может заинтересует)
5. «В репе лежит easybook.sql — его надо импортнуть в базу, создать MySQL-юзера, прописать его логин-пароль в datasource.xml, и все — сайт заработает.» — фу как сложно) вы же наверняка используете какой-нибудь pdo, так что какая проблема по умолчанию автоматом создавать sqlite базу с нужной структурой?
6. почему нету checked_children, кидающего исключение в случае отсутствия детей, а также checked_alone_children проверяющего, что он такой один?) я это к чему — ошибка в данных не является настолько исключительной ситуацией, чтобы раскручивать стек. и все такие ошибки должны быть обработаны и зачастую могут быть заменены дефолтными значениями или другими источниками получения. а если нужна логика «либо всё верно и работаем, либо не верно и падаем», то лучше применить какую-нибудь схему валидации с более совершенными механизмами чем проверка «в элементе есть хотябы один узел»)
1. для парсера нужно уметь указывать baseURI относительно которого будут вычисляться relativeURI. использовать везде абсолютные ссылки — не предлагать)
2. get — слишком абстрактный интерфейс, лучше его конкретизировать: getDOMNode, getSimpleXML и тп. у меня у каждого узла просто есть свойства DOMNode и DOMDocument.
3. www:paginate — опять же префикс слишком абстрактен, лучше использовать конктретный типа easyweb:paginate. и использовать его не только в имени функции, но и в имени режимов (easyweb:previous,easyweb:next,...). основная цель пространств имён — не указать предназначение, а избежать конфликтов и недопониманий. впрочем, там действительно нужна эта функция? сдаётся мне всё это реализуемо не слишком сложными шаблонами. к тому же, почему нельзя указать откуда брать данные? или предполагается для каждого блока на странице вручную прогонять по xslt преобразованию? не слишком практичное решение.
4. инвалидация по времени — зло. неужели так сложно сделать инвалидацию по событиям? да и вообще, что там кешировать? xslt преобразования и так реактивны. а если уж совсем жалко процессорного времени фронтенда, то можно вообще переложить его на плечи клиента. для примера сайт: hyoo.ru/?article=XStyle;author=Nin+Jin — статейку тоже почитайте, может заинтересует)
5. «В репе лежит easybook.sql — его надо импортнуть в базу, создать MySQL-юзера, прописать его логин-пароль в datasource.xml, и все — сайт заработает.» — фу как сложно) вы же наверняка используете какой-нибудь pdo, так что какая проблема по умолчанию автоматом создавать sqlite базу с нужной структурой?
6. почему нету checked_children, кидающего исключение в случае отсутствия детей, а также checked_alone_children проверяющего, что он такой один?) я это к чему — ошибка в данных не является настолько исключительной ситуацией, чтобы раскручивать стек. и все такие ошибки должны быть обработаны и зачастую могут быть заменены дефолтными значениями или другими источниками получения. а если нужна логика «либо всё верно и работаем, либо не верно и падаем», то лучше применить какую-нибудь схему валидации с более совершенными механизмами чем проверка «в элементе есть хотябы один узел»)
0
Ох, сколько всего. Отвечу на каждый пункт отдельно, чтобы было удобнее обсуждать.
1. В PHP-конфиге сайта указывается константа website_root — все пути внутри сайта (за исключением пары особых ситуаций) считаются относительно этого пути: github.com/nyan-cat/easybook/blob/master/php/config.php
1. В PHP-конфиге сайта указывается константа website_root — все пути внутри сайта (за исключением пары особых ситуаций) считаются относительно этого пути: github.com/nyan-cat/easybook/blob/master/php/config.php
0
2. Вопрос именования сущностей — это тема отдельного курса лекций, обосновать свою позицию в несколько предложений не так просто. Но я все же попробую :) Имена сущностей должны нести минимум информации, которой, в свою очередь, должно быть достаточно для того, чтобы понять, как этой сущностью пользоваться, и не более. Имена не должны сообщать «как это устроено», только — «как этим пользоваться». Например, в Boost-е аналогичная функция назвается native_handle, и у сокетов, и у файлов, и у тредов. Я надеюсь, вы доверяете коммьюнити буста в вопросе имен? native_handle не говорит, что именно вы получите. Об этом можно догадаться по имени агрегирующего класса, и убедиться наверняка из документации. Именно поэтому в C++ шаблоны, конкретизированные параметрами, берут в typedef. Пользователю нужно знать, как этим пользоваться, а не как оно устроено. В 90% ситуаций пользователю достаточно знать про контейнер лишь то, что это контейнер, и его можно проитерировать через range-based for-loop. То есть, сосредоточиться стоит на том, «для чего мне это», а не «как это устроено». Я вижу всего один случай, когда действительно нужно называть функции getDOMNode / getSimpleXML — это когда фасилити умеют выдавать сразу несколько встроенных типов ресурсов.
0
3. Пространства имен XML — это не просто способ разрешения коллизии имен. Подразумевается, что за пространством имен стоит какая-то библиотека, или часть очень большой библиотеки (как в случае EXSLT). Функция введена просто для удобства, т.к. отрисовка пагинатора — задача каждого второго сайта. Все XPath-расширения, предоставляемые движком: github.com/nyan-cat/easyweb/wiki/XPath-extensions
Что же касается самого имени пространства имен «www» — предполагается, что XSL- и XPath-расширения Easyweb реализуют всю необходимую сайтостроительную функциональность и должны покрыть 95% всех вебмастеропотребностей, поэтому мне кажется совершенно логичным выбрать имя, претендующее на дефолтность.
Что же касается самого имени пространства имен «www» — предполагается, что XSL- и XPath-расширения Easyweb реализуют всю необходимую сайтостроительную функциональность и должны покрыть 95% всех вебмастеропотребностей, поэтому мне кажется совершенно логичным выбрать имя, претендующее на дефолтность.
0
4. Это например по каким событиям? Можете привести пару примеров? Теперь что касается кеширования. Необходимость решения возникла как раз в реальном проекте. Суть такова: на каждой странице сайта есть ссылка «Выбрать город». По нажатию появляется окно со списком городов. Всего городов порядка ~1500, а их XSL-отверстывание выполняется с группировкой по первой букве названия. По ТЗ нужнто было чтобы этот блок был именно в HTML, а не подгружался аяксом, и был на каждой странице сайта. При этом Google Bot ходит на сайт ~50 раз в секунду. Речь именно про страницы сайта, а не про скрипты или там favicon. Такой интенсивности оказалось достаточно, чтобы достаточно сильно напрячь деда на предпоследней линейке Intel Xeon. Введение кеша снизило общую нагрузку в разы. Вот вам и пример из реальной жизни ;-)
0
5. Easyweb — это не CMS. В ней нет ничего по умолчанию: нет готовых баз, готовых шаблонов, или чего-то еще готового. Голый сайт на Easyweb — это голый сайт впринципе, в котором нет вообще ничего. Считайте так: Easyweb — это XSLT-верстка + специальная шина данных. То есть, вы устанавливаете сторонние хранилища данных (MySQL, PostgreSQL, Apache Solr, GeoIP, и т.д.), конфигурите их как хотите, дизайните их внутренние контейнеры данных (базы, таблицы, индексы, и т.д.) так, как хотите, без каких-либо ограничений, и уже после этого конфигурите Easyweb так, чтобы он умел брать нужные данные из нужных мест. Далее вам остается только верстать на XSL, а Easyweb уже сам разберется, куда пойти, и что откуда взять.
0
6. Рекомендую еще раз посмотреть на Boost. Функции по работе с некоторыми типами системных ресурсов (например — файлы или сокеты) представлены в двух экземплярах — одна в случае ошибки кидает исключение, другая — возвращает ошибку через параметр-ссылку. Поскольку в PHP нет перегрузки функций, я решил сделать префикс checked_. Смысл в том, что одной и той же функцией можно воспользоваться с разными ожиданиями. В одном случае логика программы может сразу же предполагать, что файла может и не быть. То есть — это не является ошибкой, а является одним из валидных кейсов. В таком случае пользовател пишет что-то вроде:
Но может быть ситуация, когда файл обязан быть, и его отсутствие означает невалидность каких-либо дальнейших действий. В таком случае пользователь пишет:
и получает гарантию, что «либо все, либо ничего».
checked_children не нужен, т.к. в случая отсутствия детей функция вернет пустой range, из-за которого foreach не сломается, а просто будет выполнено ноль итераций. checked_ функций не так много: это fs::checked_read, nodeset::checked_first и nodeset::checked_last. Кажется — все. Это просто редкие ситуации, когда одна и та же функция в разных ситуациях может вызываться с разными ожиданиями.
if($file = fs::read('...'))
{
# ...
}
Но может быть ситуация, когда файл обязан быть, и его отсутствие означает невалидность каких-либо дальнейших действий. В таком случае пользователь пишет:
$file = fs::checked_read('...');
# ...
и получает гарантию, что «либо все, либо ничего».
checked_children не нужен, т.к. в случая отсутствия детей функция вернет пустой range, из-за которого foreach не сломается, а просто будет выполнено ноль итераций. checked_ функций не так много: это fs::checked_read, nodeset::checked_first и nodeset::checked_last. Кажется — все. Это просто редкие ситуации, когда одна и та же функция в разных ситуациях может вызываться с разными ожиданиями.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Easyweb: Новогоднее обновление