Создание каталога довольно сложная задача. Обычно для него делают отдельную таблицу БД и, соответственно, програмирование выносится в отдельный модуль. Сегодня я расскажу, как можно сделать несложный каталог средствами MaxSite CMS.
Начало статьи было положено участниками форума поддержки.
У нас будет несколько основ.
1. Страницы каталога будут обычными страницами. Для того, чтобы вывести их из общей ленты, сделаем для них свой тип (Настройки - Основные - Типы страниц). Я сделал тип «catalog».
2. У страниц каталога, помимо стандартных рубрик, меток и т.п. будет своя рубрификация. Сделаем мы её с помощью мета-полей, которые задаются в шаблонном meta.ini.
3. Посколько рубрики каталога могут меняться, то сделаем так, чтобы мета-поля можно было настраивать с помощью отдельной PHP-функции, которая в свою очередь может настраиваться из опций, ушки и т.д.
4. Навигация по разделам каталога будет сделана с помощью виджета «Избранное». Сделал я это с целью немного упростить эту статью. Для тех, кто захочет автоматизировать этот процесс нет большой сложности придумать свою PHP-функцию, которую вывести с помощью текстового виджета.
5. Так же сделаем ссылку на раздел каталога на странице каталога. Отображать страницы каталога будем как обычно списком.
Итак, тип страниц мы сделали. Теперь нам нужно задать meta.ini. Я исходил из того, что у одной страницы может быть только один раздел каталога. Поэтому мы будем использовать тип select.
[Каталог] options_key = catalog type = select values = PHP_START catalog_values PHP_END description = "Выберите нужный раздел" default = 00
PHP_START и PHP_END - специальная конструкция, которая позволяет выводить в ini-файлах какой-то динамический текст. Функция, которая должна отдать его, заключена между ними. В нашем случае это catalog_values.
Саму функцию мы зададим в файле functions-catalog.php.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); function catalog_values() { return ' 00 || Нет # 01 || Первый раздел # 01-01 || --- Подраздел 1 # 01-01-01 || ------ Подподраздел 1 # 01-01-02 || ------ Подподраздел 2 # 01-01-03 || ------ Подподраздел 3 # 01-01-04 || ------ Подподраздел 4 # 01-02 || --- Подраздел 2 # 01-03 || --- Подраздел 3 # 01-04 || --- Подраздел 4 # 01-05 || --- Подраздел 5 # 02 || Второй раздел # 02-01 || --- Подраздел 1 # 02-02 || --- Подраздел 2 # 02-03 || --- Подраздел 3 # 02-04 || --- Подраздел 4 # 02-05 || --- Подраздел 5 '; } ?>
То есть наша функция возвращает строку, которая окажется в ini-секции values. Символ «#» - разделитель опций, «||» используется для разделения ключ/описание. Как видите я задал для рубрик каталога еще и подразделы. Ключи (00, 01 и т.п.) будут являться ссылкой (slug) на страницу этого раздела.
Наверное вы уже поняли, что catalog_values() может отдавать не только жестко прописанный текст, но и текст ушки или опции. Таким образом, когда вы будете делать свой каталог вы можете задавать список разделов из админ-панели. Вот пример использования ушки:
function catalog_values() { if (function_exists('ushka')) return ushka('каталог', '', '00 || Нет'); else return '00 || Нет'; }
Здесь мы берем значения из ушки «каталог».
Теперь давайте определимся, где мы будем подключать functions-catalog.php. Возможно, когда вы будете делать каталог и вам потребуется дополнительная функциональность, то наверное удобней будет сделать отдельный плагин. Тогда можно будет выводить на отдельной странице разные опции. Но в нашем случае пока этого не требуется, поэтому мы подключим файл в шаблонном functions.php.
require_once('functions-catalog.php');
Файл functions.php имеет особую роль в MaxSite CMS. Он подключается не только при «отработке» самого шаблона, но и в админ-панели. Это сделано с той целью, чтобы админ-панель «знала» особенности шаблона. Например, количество и названия сайдбаров. У нас, поскольку мы динамически формируем значения для meta.ini, админ-панель должна «видеть» функцию catalog_values().
На этом приготовления для админ-панели будут завершены. Теперь можно создать новую страницу, выставить у неё тип «catalog» и выбрать нужный раздел.
Определимся по какому адресу будем выводить каталог. Самый простой способ - задать определить сегмент в type-каталоге.
Если у нас будет адрес «http://site.com/catalog/...», то будет автоматически подключен type-файл catalog.php.
Мы решили, что по этому адресу будет выводиться лента записей этого раздела.
За основу возьмем type-файл tag.php из дефолтного шаблона. Скопируем, переименуем.
Теперь один важный технический момент. Все операции с meta.ini, по сути своей являются операциями с таблицей meta. То есть, когда мы добавили секцию «Каталог» с «options_key = catalog», то мы фактически внесли в таблицу meta эти данные. Я объясняю этот момент, потому что MaxSite CMS предоставляет API, который значительно упрощает работу с мета-полями и все происходит автоматически. Но, если вы будете делать более сложную версию каталога, то понимание этих основ позволит вам сделать это быстрей и проще.
Теперь, когда мы хотим получить страницы с определенным ключом, нужно сделать выборку из БД. Лучше всего для этих целей подойдут метки, поскольку они также хранятся в таблице meta.
SQL-запросы нам писать не придется, вместо этого укажем нужные параметры для mso_get_pages().
$par = array( 'limit' => mso_get_option('limit_post', 'templates', '7'), 'cut' => mso_get_option('more', 'templates', t('Читать полностью »')), 'type'=>false, 'custom_type'=>'tag', 'meta_key'=>'catalog', );
- 'type'=>false - будем выводить все типы страниц. Как вы помните, мы задали свой тип «catalog». Если мы его укажем здесь, то будет выводиться строго этот тип. Если же задать «false», то тип страниц не учитывается, что является более универсальным решением.
- 'custom_type'=>'tag' - означает, что данные мы будем получать как метки.
- 'meta_key'=>'catalog' - ключ, по которому нужно получить выборку.
Если вы планируете использовать для вывода служную структуру URL, то вам потребуется указывать еще и «slug», который будет использоваться как meta_value. Мы его не указываем, потому что система автоматически анализирует второй сегмент URL и если он есть, сама подставляет это условие (в нашем случае это выводд подразделов). Если у вас будет более 2-х сегментов, то вам нужно явно указывать параметр «slug».
Теперь, когда мы указали нужные параметры, мы можем обратиться по адресу каталога и посмотреть список страниц.
Правда у нас есть небольшая проблема: данные о разделе хранятся в мета-полях, но мы получаем только значение поля (slug), но не его текстовое описание. Оно у нас задается через «||» в meta.ini. Таким образом нам придется подключить этот файл и сформировать массив названий всех значений.
... if ($pages) // есть страницы { // если указан meta.ini if (file_exists(getinfo('template_dir') . 'meta.ini')) { // функции для работы с ini-файлом require_once( getinfo('common_dir') . 'inifile.php' ); // получаем все опции $meta_all = mso_get_ini_file( getinfo('template_dir') . 'meta.ini' ); // находим нужный ключ $my_meta = mso_find_options_key($meta_all, 'catalog'); // преобразуем values в массив $all_values = mso_parse_ini_values($my_meta['catalog']['values']); } ...
То есть нам нужен будет массив $all_values.
Вывод названия раздела делается практически стандартно, за исключением того, что нам нужно использовать $all_values для получения этого самого названия:
echo '<div class="info">'; ... // указан в meta раздел? if ($rasz = mso_page_meta('catalog', $page_meta, '', '', '', false)) { // заменим '-' на '' $link = str_replace('-', '', $all_values[$rasz]); // формируем ссылку $link = '<a href="' . getinfo('siteurl') . 'catalog/' . $rasz . '">' . $link . '</a>'; // выводим echo '<span>Каталог:</span> ' . $link ; } ... echo '</div>';
Вначале смотрим есть ли мета-поле «catalog». Если есть, то получаем значение - $all_values[$rasz]. Тут же удаляем «-»: они у нас используются для визуального отделения подразделов. Дальше формируем ссылку и выводим её.
Я не стал дальше развивать код на вывод текста и прочей информации, которая обычно характерна для каталогов. Просто она очень специфична. Например мы хотим сделать каталог фильмов. Разделы - это жанры. Дополнительные разделы - страна, режисcер, код выпуска и т.д. - делаются абсолютно аналогично, как описано выше. Только указываете свой ключ и значения в meta.ini. Описание фильма можно задать прямо в тексте. Если указывается скриншот, то его адрес указываем в отдельном мета-поле. То есть подход к работе с мета-полями везде будет один и тот же. Ну а сам вывод вы делает по своей задумке.
Теперь разберемся с боковой навигацией. Я предлагаю её вручную задать в стандартном виджете «Избранное». Этот виджет позволяет указывать ссылки в коротком виде:
catalog/01 | Первый раздел catalog/01-01 | Подраздел 1 catalog/01-01-01 | Подподраздел 1 catalog/01-01-02 | Подподраздел 2 catalog/01-01-03 | Подподраздел 3 catalog/01-01-04 | Подподраздел 4
Может будет удобней размесить несколько виджетов для разных разделов. Тогда они визуально будут разделены. В сайдбаре указываем:
favorites_widget Каталог_01 favorites_widget Каталог_02 favorites_widget Каталог_03
Дальше настраиваем виджеты как обычно.
Если же нужно вывести ссылки на записи (страницы) каталога, то можно воспользоваться виджетом «Последние записи». В нем мы указываем тип страниц «catalog» (мы его заранее задали). Заголовок что-то вроде «Последние добавления».
Если вы решили выводить одиночные страницы каталога, то заметили, что вывод осуществляется как обычная страница, где не указывается подраздел каталога. Чтобы исправить этот недочет, воспользуемся автоматически подключаемым файлом type_foreach. Скопируйте из дефолтного шаблона type_foreach/_page.php в свой шаблон как type_foreach/page.php.
В этом файле перед «extract($page);» добавим знакомый нам код «// если указан meta.ini ... », а после «mso_page_meta('music' ... », код «// указан в meta раздел?».
Если же вы хотите отключить вывод прочей информации, вроде рубрик, меток и т.д., то сделайте их отображение по условию «если нет $rasz = mso_page_meta('catalog'...». В общем самые обычные php-условия.
Комментариев: 7 RSS
1Аноним15-12-2009 11:11
Максим, хочется сказать огромное спасибо за такую систему. Сам был в шоке от ВП, когда прогнал его (2.8) под профайлером и сравнил с джумлой 1.5. 16000 вызовов только одного метода класса для вывода страницы без плагинов - это преступление. Похоже что ребята подавились популярностью и архитектура им стала по барабану. Как программиста, меня это просто бесит )).
Слава Богу, что нашелся _думающий_ человек, который изначально принял правильное направление. Думаю, что даже через несколько лет и номеров версий Ваша ЦМС останется на порядок легче и продуманнее "железобетонных паровозов". А функционал - дело наживное.
В моем лице Вы приобрели своего отчаянного сторонника, а может, если буду что-то городить в ближ. будущем, то и соратника. 5+!
2jogurt18-06-2010 16:03
Максим, а как быть, если у одной страницы несколько разделов может быть в каталоге? В meta.ini ведь нет такой опции, чтобы можно было выбрать не что-то одно, а несколько значений. Скажем, чекбокс предполагает только "да" или "нет", селект предлагает выбрать один вариант из нескольких, так же и радио.
Как реализовать возможность отметить несколько рубрик каталога? И, кстати, заметили в системе такую ошибку: если мы указываем для страницы несколько рубрик, то число комментариев на главной (home) для этой страницы увеличивается.
3Аноним18-06-2010 16:36
На вскидку приходит только вариант, аналогичный меткам, где нужно указать разделы через запятую. Всё-таки мета-поля это несколько другое, нежели рубрики. Ну а если нужны рубрики, то есть специальный хук admin_page_form_add_block_1, который позволяет вывести свой блок при редактировании записи.
Не могу воспроизвести эту ошибку.
4jogurt18-06-2010 17:18
Весьма интересно.
Как это реализовать? На форуме предлагают разные варианты, но мне бы простенький примерчик для размышления...
И тут тоже мне не хватает простенького примера. Хук я вижу, как к нему прицепить, допустим, список чекбоксов?
Понимаю, что в этой области у меня пробелы, но не нашел ничего по этим вопросам, к сожалению.
Значит, ошибка каким-то образом завязана на настройки хостинга, по-видимому...
5Аноним18-06-2010 18:12
Если через запятую, то два варианта.
Первый - это оставить meta.ini без изменений, а сам вывод сделать на уровне type/catalog.php. То есть в mso_get_pages дописываем в параметре function_add_custom_sql свою функцию, которая будет вычленять из мета нужное вхождение. Что-то вроде поиска с использованием LIKE.
Второй - это прицепиться к хукам new_page и edit_page, взять полученные мета и разбить их с помощью mso_explode на одиночные значения и с помощью своего sql-запроса добавить в базу.
Что касается admin_page_form_add_block_1, то этот хук выводит самые обычные input, radio и т.п. То есть формируем нужные поля формы, потом цепляемся на хуки new_page и edit_page и обрабатываем по ним как обычно POST.
6Аноним29-01-2013 10:22
Подскажите плз, за три года эта идея как-то получила развитие в виде плагинов или встроенных функций системы ? Наверное не я один столкнулся с задачей создание своей базы данных на данном движке (Каталог книг например - это уже база данных).
7Юрий04-04-2015 19:27
Прошло ещё пара лет :)
Натолкнулся на MaxSite CMS, это нечто! Поставил на этом движке свой блог - не могу нарадоваться. И вот столкнулся с необходимостью создания подобного каталога для софта на сайте. FTP для посетителей не лучший вариант, в идеале хотелось бы иметь плагин похожий на этот:
http://help.siteedit.ru/modul-katalog-faylov/