Организуем циклы статей на MaxSite CMS
Организуем циклы статей на MaxSite CMS
Циклы статей – один из способов дополнительной навигации для сайта. Статьи могут быть из разных рубрик, иметь разные метки, да и вообще – быть разного типа. И эти разношерстные статьи можно объединить в цикл статей.
Цикл статей подразумевает, что в каждой статье из цикла будет ссылка на предыдущую и следующую (по времени публикации) статьи.
Кроме того, будет заголовок цикла и ссылка на содержание цикла статей.
На мой взгляд, идеально для объединения статей в цикл будет связь дочерние-родительская страницы.
Все статьи цикла будут объединяться общей родительской статьей. Родительская статья будет заголовком цикла, и содержать аннотацию цикла и содержание.
Рекомендую придумать свой тип страниц для статей – заголовков циклов (например, navi).
Исключение статей с отложенной публикацией.
Для получения статей рекомендуется использовате функцию mso_get_pages.
Но здесь будем получать статьи из БД своими SQL запросами.
В этом случае нам необходимо самостоятельно позаботиться о том, что лежит на плечах mso_get_pages.
Например, исключить статьи с отложенной публикацией. Кто не знает - это статьи с датами публикации большими, чем текущая дата.
Рассмотрим получение ID отложенных статей (если отложенная публикация не используется – этот код можно удалить).
Разберемся со временем.
- // смещение времени
- $time_zone = getinfo('time_zone');
- if ($time_zone < 10 and $time_zone > 0) $time_zone = '0' . $time_zone;
- elseif ($time_zone > -10 and $time_zone < 0)
- {
- $time_zone = '0' . $time_zone;
- $time_zone = str_replace('0-', '-0', $time_zone);
- }
- else $time_zone = '00.00';
- $time_zone = str_replace('.', ':', $time_zone);
Получим массив ID отложенных статей.
- //получаем неопубликованные записи
- $CI = & get_instance();
- $CI->db->select('SQL_BUFFER_RESULT `page_id`', false);
- if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
- $query = $CI->db->get('page');
- if ($query and $query->num_rows() > 0)
- {
- $result = $query->result_array();
- $page_id_date_now = array();
- foreach ($result as $key=>$val)
- {
- $page_id_date_now[] = $val['page_id'];
- }
- }
- else $page_id_date_now = false; // нет отложенных записей
Получение ссылок на статьи цикла: родительскую, предыдущую и последующую.
Получим родительскую страницу и сформируем на нее ссылку.
- $CI->db->select('page_id, page_title, page_slug');
- $CI->db->where('page_id', $page_id_parent);
- $CI->db->where('page_status', 'publish');
- if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
- $query = $CI->db->get('page');
- $result = $query->result_array(); // здесь родительская страница
- if ($result)
- foreach ($result as $key=>$row)
- {
- $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
- $parent_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
- }
Получим все страницы цикла (сестры текущей).
- // получим все страницы цикла
- $CI->db->select('page_id, page_id_parent, page_title, page_slug');
- $CI->db->where('page_id_parent', $pages[0]['page_id_parent']);
- $CI->db->where('page_status', 'publish');
- if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now); // исключим отложенные
- $CI->db->order_by('page_date_publish');
- $query = $CI->db->get('page');
- $result = $query->result_array(); // здесь все дочерние страницы
Выберем из статей цикла предыдущую и следующую для текущей.
- if ($result) // имеются страницы - сестры
- {
- // ищем текущую
- reset($result);
- while (each($result))
- {
- $key = key($result);
- if ($page_id == $result[$key]['page_id']) break;
- }
- // берем предыдущую
- if ( ($key-1)>=0 ) // если есть предыдущая
- {
- $url = getinfo('siteurl') . 'page/' . $result[$key-1]['page_slug'];
- $prev_page_link = '<a href="' . $url . '" title="' . mso_strip($result[$key-1]['page_title']) . '">' . mso_strip($result[$key-1]['page_title']) . '</a>';
- }
- // берем следующую
- if (isset($result[$key+1]))
- {
- $url = getinfo('siteurl') . 'page/' . $result[$key+1]['page_slug'];
- $next_page_link = '<a href="' . $url . '" title="' . mso_strip($result[$key+1]['page_title']) . '">' . mso_strip($result[$key+1]['page_title']) . '</a>';
- }
- } // if ($result)
- } // if ($page_id_parent)
Выведем полученное.
Можно организовать примерно такой вывод:
- $out = '';
- if ($parent_page_link) $out .= 'Статья из цикла статей: "' . $parent_page_link . '".' . '</br>';
- if ($prev_page_link) $out .= 'Предыдущая: ' . $prev_page_link . '</br>';
- if ($next_page_link) $out .= 'Следующая: ' . $next_page_link . '</br>';
- echo $out;
Или такой:
- // выводим теперь полученное
- $out = '<div class="navi">';
- $out .= $parent_page_link;
- $out .= '<table><tr>';
- $out .= '<td width="50%"><span class="left"><<</span>' . $prev_page_link . '</td>';
- $out .= '<td width="50%">' . $next_page_link . '<span class="right">>></span></td>';
- $out .= '</tr></table></div>';
- echo $out;
Вывод навигации «Циклы статей», даже если статья не в цикле.
Если у статьи есть родительская и есть сестры, то будет выведена дополнительная навигация, которую реализовали выше.
А что если текущая статья не состоит в цикле (не имеет родительской) или не можем получить предыдущую и последующую статьи по другой причине?
Как альтернатива "ничего не выводить" можно вывести ссылку на предыдущую и следующую статью глобально по сайту.
Более того, вместо ссылки на главную страницу цикла можно вывести ссылку на ленту статей (home), а именно - на страницу пагинации n (siteurl/home/next/n), содержащую текущую статью.
Получение предыдущей (по времени публикации на блоге) статьи.
- // получем предыдущую статью
- $CI->db->select('page_id, page_title, page_slug');
- $CI->db->where('page_status', 'publish');
- $CI->db->where('page_date_publish <', $pages[0]['page_date_publish']);
- $CI->db->limit(1);
- $CI->db->order_by('page_date_publish', 'desc');
- $query = $CI->db->get('page');
- if ($query->num_rows() > 0)
- {
- $row = $query->row_array(1);
- $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
- $prev_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
- }
Получение следующей (по времени публикации на блоге) статьи.
- // получем следующую статью
- $CI->db->select('page_id, page_title, page_slug');
- $CI->db->where('page_status', 'publish');
- $CI->db->where('page_date_publish >', $pages[0]['page_date_publish']);
- if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
- $CI->db->order_by('page_date_publish');
- $CI->db->limit(1);
- $query = $CI->db->get('page');
- if ($query->num_rows() > 0)
- {
- $row = $query->row_array(1);
- $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
- $next_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
- }
Получение ссылки "Назад к списку статей".
- // получим ссылку на страницу пагинации home/next/n, на которой текущая страница
- // для этого получим номер текущей по порядку сортровки по дате
- // кол-во на главной
- $home_limit = mso_get_option('home_limit_post', 'templates', '7');
- // получим все страницы только ID
- $CI->db->select('page_id');
- $CI->db->where('page_status', 'publish');
- $CI->db->where('page_date_publish <', date('Y-m-d H:i:s'));
- $CI->db->order_by('page_date_publish', 'desc');
- $query = $CI->db->get('page');
- $result = $query->result_array(); // здесь номера всех страниц
- if ($result) // имеются страницы
- {
- // найдем страницу, на которой текущая
- $i = 1; // счетчик
- $found = 0; // найденный номер
- foreach ($result as $cur_page)
- {
- if ($cur_page['page_id'] == $pages[0]['page_id'])
- {
- // если нашли нашу
- $no = (int) ($i/$home_limit); // номер страницы
- $no = $no+1; // т к первая - нулевая
- if ($no>0) $url = getinfo('siteurl') . 'home/next/' . $no;
- else $url = getinfo('siteurl') . 'home';
- $parent_page_link = '<a href="' . $url . '" title="' . $info_text['home'] . '">' . $info_text['return'] . '</a>';
- break;
- }
- $i++;
- }
- }
Как организовать вывод всего этого в своем шаблоне?
Проще всего интегрировать описанный функционал в свой шаблон при помощи type_foreach файлов.
Вывод навигации: главная, предыдущая, следующая можно реализовать в файле type_foreach/page-do.php.
Пример можете наблюдать в этом блоге.
Вот готовый файл, который нужно разместить в type_foreach шаблона.
Дополнение: Как получить следующую и предыдущую только из рубрик текущей.
Часто, может возникнуть дополнительная задача - чтобы следующая и предыдущая статья были из той же рубрики/рубрик, что и текущая. Речь, понятно, идет не о случае с циклом статей, а о глобально по сайту следующей и предыдущей.
Тогда к запросу получения нужно добавить такие строчки:
- $CI->db->join('cat2obj', 'cat2obj.page_id = page.page_id', 'left');
- $CI->db->join('category', 'cat2obj.category_id = category.category_id');
- $CI->db->where_in('category.category_id', $pages[0]['page_categories']);
- $CI->db->group_by('page_id');
Ну и, конечно, заменить в $CI->db->select() 'page_id' на 'page.page_id' во избежание ошибки: Error Number: 1052 Column 'page_id' in field list is ambiguous.
Классификация пользоательских метаполей и способов их вывода для MaxSite CMS.
MaxSite CMS позволяет к существующим полям страницы добавлять произвольные ...
Вывод всех меток в виде дерева для сайта на MaxSite CMS
В предыдущей статье на эту тему Вывод меток сайта деревом я пытался ...
Добавление полей Сайт и Ник в форму комментирования для комюзеров в MaxSite CMS
В статье пойдет речь о том, как и зачем добавить в форму комментирования ...
mso_get_pages и типы данных в MaxSite CMS: что это и как эти штуки связанны.
Вопрос, который можно считать классическим: Я хочу, чтобы статьи в обратном ...
Страница-форма регистрации для MaxSite CMS
В MaxSite CMS есть два вида пользователей: users и comusers, информация о которых ...











Что-то какие-то проблемы с архивом, не скачивается...
Вот еще какой вопрос - а можно ли как-то ограничить выборку страниц только текущей рубрикой и подрубриками данной рубрики?
Да, ссылка на архив не работает.
Теперь работает (попутал "-" "_")
Вот, так гораздо лучше
- page_do подключается до проверки
Поэтому если обратиться к несуществующей странице - засыпет ошибками.
Нужно проверки добавить.