Чем страница с текстом новости отличается от "обычной" страницы сайта? Нужна ли для неё отдельная таблица в БД? Нужна ли отдельная таблица для разделов (рубрик) Каталога? Откуда веб-приложение узнаёт, что на этой странице надо показывать список новостей с анонсами, а на той - список товаров из рубрики "Конденсаторы"? Где хранится эта информация и кто её пользователь?

Информационные сущности или инфоблоки

"А как вы оформляете текстовые сущности?" – возник вопрос на одном из форумов. (Например, новость. Или рубрика каталога. Или страница "О компании"). Ну, как, как... Набираем текст в Xara Extreme, добавляем красивую рамочку, сохраняем в гиф – и на ФТП. А как ещё можно ответить на такой вопрос? И из ответа становится ясно, что вопрос не о "текстовых" сущностях, а, скорее, об "информационных" (картинка тоже содержит информацию). И правильнее было бы сказать не "оформляете", а "храните". То есть нужны ли для сущностей Статья и Новость разные таблицы в БД? Нужны ли разные классы для извлечения и оформления данных? Ответ может быть только для конкретного сайта; ясно, что "вообще" можно хранить данные как угодно, в зависимости от задач.

Основа нормального (нормализованного!:-) сайта – sitemap, список УРЛ, ведущих на разные страницы. В норме этот список хранится в отдельной таблице pages (или artiles). На каждой странице должно быть какое-то важное для пользователя содержание, то есть причина, по которой эта страница вообще существует. Достаточно очевидным кажется хранить содержание (текст) страницы в той же таблице, что и УРЛ. То есть таблица pages должна содержать поля: url, title, text.

Новости

Новость по своей сути – та же страница, запись в таблице pages. Ну, у новости обычно бывают даты, значит, надо добавить в таблицу поле date. Но как нам увидеть список всех новостей? Так же, как и мы видим ссылки на Главную, О компании, Контакты – через меню.

Меню – это список всех УРЛ из таблицы pages (если список большой, на текущей странице отображается фрагмент списка). Извлечённое из такой таблицы pages, как сейчас, меню будет выглядеть достаточно стрёмно:

  • Главная
  • Контакты
  • Новости
  • Новость1
  • Новость2
  • Новость3
  • ...

Здесь возникает неоднородность (список новостей – другой уровень, более низкий, чем Главная-Контакты), а значит, в таблицу надо добавить ещё одно управляющее поле – Раздел (parent). У страниц самого верхнего уровня можно оставить поле parent пустым, а конкретным страницам с новостями назначить раздел Новости:

Теперь мы легко можем построить для меню дерево (или многомерный массив) и выводить иерархическое (многоуровневое) меню:

  • Главная
  • Контакты
  • Новости
    1. Новость1
    2. Новость2
    3. Новость3
  • ...

Но появляется новый вопрос: каково собственное содержание страницы Новости? Что там должно быть написано в поле text? Очевидно, что в общем случае – ничего. Так на---> она тогда нужна? А там обычно выводится список всех новостей (ну, 8 самых последних, например), ещё и с анонсами. Такой список несложно получить из той же таблицы pages, выбрав строки, в поле parent у которых стоит значение news.htm, и отлущив от текстов страниц по 300 первых символов (для анонсов).

Но в шаблоне у нас написано просто "вывести title", "вывести text" – для всех страниц одинаково. Почему бы вдруг шаблон начал запрашивать какой-то непонятный список для какой-то отдельной страницы? Как шаблон узнает, что эта страница какая-то особенная? Особенность спрятана в таблице, значит, из таблицы и должен поступать сигнал (хотя можно составить и отдельный список особенностей для разных УРЛ). Добавим в таблицу ещё одно поле – Шаблон (tpl); у всех "обычных" страниц пусть будет шаблон как шаблон – page, а у страницы Новости будет особый шаблон – anonce_child:

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

Каталог товаров

Рубрика каталога – страница, очень похожая на страницу Новости. Похожа отсутствием "собственного" содержания: она должна получать содержание (список элементов каталога) откуда-то из другого места, в норме, совсем уже из другой таблицы. Почему, кстати, из другой? Потому что у элемента каталога есть принципиальное (предметное) отличие от страницы: они обычно выводятся списком, их суть – показать пользователю именно набор значений, из которого можно сделать выбор. Поэтому элементы каталога не обязаны иметь собственных "обслуживающих" меток типа parent, title, tpl; им нужна только привязка к своей рубрике (с помощью соответствующей метки, поля rubrika).

Каталожная часть нашего сайта могла бы выглядеть примерно так:

Весь каталог автоматически появляется в иерархическом меню в подпункте Каталог. И – вот досада! – что мы увидим при щелчке по ссылке catalog.htm? Правильно, пустую страницу, не имеющую собственного содержания. Потому что в таблице catalog есть, конечно, поле rubrika, связывающее элементы каталога с основной таблицей, – но в этом поле ведь записаны "конечные" рубрики (Автомобили, Дачи), и там не указываются "родительские" рубрики Недвижимость, Транспорт (и уж тем более сам Каталог). То есть при открытии "промежуточной" рубрики Недвижимость мы тоже увидим пустую страницу.

Это так раздражает – щёлкать много раз по пустым ссылкам, добираясь до "реального" содержания... Может быть несколько вариантов для решения этой проблемы. Один из самых простых – не делать ссылками пункты меню, которые ведут на пустые страницы. Допустим, у нас для Каталога вертикальное растягивающееся меню, и мы на Главной в числе прочих видим только пункт Каталог (всё, что внутри, скрыто). Этот пункт НЕ является ссылкой, при щелчке по нему просто раскрывается следующий уровень, и мы видим Недвижимость и Транспорт, которые тоже не являются ссылками! Всё просто. А при щелчке по Транспорту появляются уже долгожданные ссылки, ведущие на страницы с реальными элементами каталога.

А если (кстати!) для рубрики Автомобили в таблице catalog нет записей, пункт Автомобили в меню тоже не должен быть ссылкой! Такая вот бэст практис. Кто думает, что это реализовать невозможно, смотрит стр. http://monjus.ru/ – там невозможно по ссылкам меню Каталога попасть на пустую страницу. Для реализации (и чтоб быстро работало!) пришлось добавить в таблицу page ещё одно поле – elements, которое может принимать значение 1 или 0. Поле изменяется при любом изменении таблицы элементов каталога. Глобально. Чем-то вроде такого запроса:

Возникает коллизия: если при генерации меню подозревать каждую страницу в том, что она – рубрика Каталога (и должна содержать элементы Каталога), то не будут создаваться ссылки для таких страниц, как Контакты. Поэтому при вызове меню пришлось добавить параметр check_empty_ (то есть явно указывать, надо ли делать ссылки на пустые с точки зрения Каталога страницы). Если вызывается генератор для "обычного" меню (например, верхнего), мы пишем: Menu::out($check_empty_pages = false), а если это меню Каталога (справа), то Menu::out($check_empty_pages = true).

Встречаются "недоделанные" образцы сокрытия ссылок на промежуточные рубрики Каталога. Пример – на стр. http://gemshunter.ru/ . Там при щелчке по ссылке Хромдиопсид в левом меню страница не открывается, а раскрывается список нижележащих рубрик. Недоделанность в том, что промежуточные ссылки всё-так являются ссылками, просто щелчок по ним перехватывается обработчиком javascript и не даёт открывать новую страницу. Это легко проверить, щёлкнув по ссылке правой кнопкой мыши и выбрав "Открыть в новом окне".

"Ну и что?!" – скажете вы. Всё ведь работает! А вот ни х--->! Яндекс видит ссылку и индексирует промежуточную страницу! А оптимизатор при знакомстве с сайтом наивно полагает, что, как видно на экране, так и будет работать. А потом в Яндекс.Вебмастере он с удивлением видит кучу проиндексированных страниц, на которые на сайте вроде бы нет ссылок. И вынужден лезть в движок, чтобы понять, откуда ноги растут. Потому что не предусмотренная протоколом страница – опасность, она может оказаться более релевантной, чем продвигаемая. Ну, короче, разный вид сайта для ПС и для пользователя – это всегда говнокод (за исключением, конечно, классических примеров страниц с формами и ещё некоторых "законных" случаев, когда сам Яндекс не рекомендует индексировать страницу).

/*********************************************/

Таким образом, страница "О компании", страница "Лучшая новость" и страница "Рубрика каталога" вполне могут лежать себе рядышком в одной общей таблице pages (и не мешать друг другу).

Дилетант

Комментарии

Дилетант 29.11.2012 20:26:10

А, э!.. на стр. http://gemshunter.ru/ уже всё доделано, ссылок на пустые страницы нет. Сайт перенесён на CMS Бикубик, которая, в частности, использует обсуждаемые в этой статье идеи.