Организуем циклы статей на MaxSite CMS

Организуем циклы статей на MaxSite CMS

10 января 2012 г. Sadovnik Просмотров: 395 RSS
MaxSite CMS практика

Циклы статей – один из способов дополнительной навигации для сайта. Статьи могут быть из разных рубрик, иметь разные метки, да и вообще – быть разного типа. И эти разношерстные статьи можно объединить в цикл статей.

Цикл статей подразумевает, что в каждой статье из цикла будет ссылка на предыдущую и следующую (по времени публикации) статьи.

Кроме того, будет заголовок цикла и ссылка на содержание цикла статей.

На мой взгляд, идеально для объединения статей в цикл будет связь дочерние-родительская страницы.

Все статьи цикла будут объединяться общей родительской статьей. Родительская статья будет заголовком цикла, и содержать аннотацию цикла и содержание.

Рекомендую придумать свой тип страниц для статей – заголовков циклов (например, navi).

Исключение статей с отложенной публикацией.

Для получения статей рекомендуется использовате функцию mso_get_pages.

Но здесь будем получать статьи из БД своими SQL запросами.

В этом случае нам необходимо самостоятельно позаботиться о том, что лежит на плечах mso_get_pages.

Например, исключить статьи с отложенной публикацией. Кто не знает - это статьи с датами публикации большими, чем текущая дата.

Рассмотрим получение ID отложенных статей (если отложенная публикация не используется – этот код можно удалить).

Разберемся со временем.

  1.  // смещение времени
  2.  $time_zone = getinfo('time_zone');
  3.  if ($time_zone < 10 and $time_zone > 0) $time_zone = '0' . $time_zone;
  4.  elseif ($time_zone > -10 and $time_zone < 0)
  5.  {
  6.   $time_zone = '0' . $time_zone;
  7.   $time_zone = str_replace('0-', '-0', $time_zone);
  8.  }
  9.  else $time_zone = '00.00';
  10.  $time_zone = str_replace('.', ':', $time_zone);

Получим массив ID отложенных статей.

  1.  //получаем неопубликованные записи
  2.  $CI = & get_instance();
  3.  $CI->db->select('SQL_BUFFER_RESULT `page_id`', false);
  4.  if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
  5.  $query = $CI->db->get('page');
  6.  if ($query and $query->num_rows() > 0)
  7.  {
  8.   $result = $query->result_array();
  9.   $page_id_date_now = array();
  10.   foreach ($result as $key=>$val)
  11.   {
  12.   $page_id_date_now[] = $val['page_id'];
  13.   }
  14.  }
  15.  else $page_id_date_now = false; // нет отложенных записей

Получение ссылок на статьи цикла: родительскую, предыдущую и последующую.

Получим родительскую страницу и сформируем на нее ссылку.

  1.  $CI->db->select('page_id, page_title, page_slug');
  2.  $CI->db->where('page_id', $page_id_parent);
  3.  $CI->db->where('page_status', 'publish');
  4.  if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
  5.  $query = $CI->db->get('page');
  6.  $result = $query->result_array(); // здесь родительская страница
  7.  
  8.  if ($result)
  9.   foreach ($result as $key=>$row)
  10.   {
  11.   $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
  12.   $parent_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
  13.   }

Получим все страницы цикла (сестры текущей).

  1.  // получим все страницы цикла
  2.  $CI->db->select('page_id, page_id_parent, page_title, page_slug');
  3.  $CI->db->where('page_id_parent', $pages[0]['page_id_parent']);
  4.  $CI->db->where('page_status', 'publish');
  5.  if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now); // исключим отложенные
  6.  $CI->db->order_by('page_date_publish');
  7.  $query = $CI->db->get('page');
  8.  $result = $query->result_array(); // здесь все дочерние страницы

Выберем из статей цикла предыдущую и следующую для текущей.

  1.  if ($result) // имеются страницы - сестры
  2.  {
  3.   // ищем текущую
  4.   reset($result);
  5.   while (each($result))
  6.   {
  7.   $key = key($result);
  8.   if ($page_id == $result[$key]['page_id']) break;
  9.   }
  10.  
  11.   // берем предыдущую
  12.   if ( ($key-1)>=0 ) // если есть предыдущая
  13.   {
  14.   $url = getinfo('siteurl') . 'page/' . $result[$key-1]['page_slug'];
  15.   $prev_page_link = '<a href="' . $url . '" title="' . mso_strip($result[$key-1]['page_title']) . '">' . mso_strip($result[$key-1]['page_title']) . '</a>';
  16.   }
  17.  
  18.  // берем следующую
  19.   if (isset($result[$key+1]))
  20.   {
  21.   $url = getinfo('siteurl') . 'page/' . $result[$key+1]['page_slug'];
  22.   $next_page_link = '<a href="' . $url . '" title="' . mso_strip($result[$key+1]['page_title']) . '">' . mso_strip($result[$key+1]['page_title']) . '</a>';
  23.   }
  24.   } // if ($result)
  25.   } // if ($page_id_parent)

Выведем полученное.

Можно организовать примерно такой вывод:

  1.  $out = '';
  2.  if ($parent_page_link) $out .= 'Статья из цикла статей: "' . $parent_page_link . '".' . '</br>';
  3.  if ($prev_page_link) $out .= 'Предыдущая: ' . $prev_page_link . '</br>';
  4.  if ($next_page_link) $out .= 'Следующая: ' . $next_page_link . '</br>';
  5.  echo $out;

Или такой:

  1.  // выводим теперь полученное
  2.  $out = '<div class="navi">';
  3.  $out .= $parent_page_link;
  4.  $out .= '<table><tr>';
  5.  $out .= '<td width="50%"><span class="left"><<</span>' . $prev_page_link . '</td>';
  6.  $out .= '<td width="50%">' . $next_page_link . '<span class="right">>></span></td>';
  7.  $out .= '</tr></table></div>';
  8.   echo $out;

Вывод навигации «Циклы статей», даже если статья не в цикле.

Если у статьи есть родительская и есть сестры, то будет выведена дополнительная навигация, которую реализовали выше.

А что если текущая статья не состоит в цикле (не имеет родительской) или не можем получить предыдущую и последующую статьи по другой причине?

Как альтернатива "ничего не выводить" можно вывести ссылку на предыдущую и следующую статью глобально по сайту.

Более того, вместо ссылки на главную страницу цикла можно вывести ссылку на ленту статей (home), а именно - на страницу пагинации n (siteurl/home/next/n), содержащую текущую статью.

Получение предыдущей (по времени публикации на блоге) статьи.

  1.  // получем предыдущую статью
  2.  $CI->db->select('page_id, page_title, page_slug');
  3.  $CI->db->where('page_status', 'publish');
  4.  $CI->db->where('page_date_publish <', $pages[0]['page_date_publish']);
  5.  $CI->db->limit(1);
  6.  $CI->db->order_by('page_date_publish', 'desc');
  7.  $query = $CI->db->get('page');
  8.  if ($query->num_rows() > 0)
  9.  {
  10.   $row = $query->row_array(1);
  11.   $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
  12.   $prev_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
  13.  }

Получение следующей (по времени публикации на блоге) статьи.

  1.  // получем следующую статью
  2.  $CI->db->select('page_id, page_title, page_slug');
  3.  $CI->db->where('page_status', 'publish');
  4.  $CI->db->where('page_date_publish >', $pages[0]['page_date_publish']);
  5.  if ($page_id_date_now) $CI->db->where_not_in('page_id', $page_id_date_now);
  6.  $CI->db->order_by('page_date_publish');
  7.  $CI->db->limit(1);
  8.  $query = $CI->db->get('page');
  9.  if ($query->num_rows() > 0)
  10.  {
  11.   $row = $query->row_array(1);
  12.   $url = getinfo('siteurl') . 'page/' . $row['page_slug'];
  13.   $next_page_link = '<a href="' . $url . '" title="' . mso_strip($row['page_title']) . '">' . mso_strip($row['page_title']) . '</a>';
  14.  }

Получение ссылки "Назад к списку статей".

  1.  // получим ссылку на страницу пагинации home/next/n, на которой текущая страница
  2.  // для этого получим номер текущей по порядку сортровки по дате
  3.  
  4.  // кол-во на главной
  5.  $home_limit = mso_get_option('home_limit_post', 'templates', '7');
  6.  
  7.  // получим все страницы только ID
  8.  $CI->db->select('page_id');
  9.  $CI->db->where('page_status', 'publish');
  10.  $CI->db->where('page_date_publish <', date('Y-m-d H:i:s'));
  11.  $CI->db->order_by('page_date_publish', 'desc');
  12.  $query = $CI->db->get('page');
  13.  $result = $query->result_array(); // здесь номера всех страниц
  14.  
  15.  if ($result) // имеются страницы
  16.  {
  17.   // найдем страницу, на которой текущая
  18.   $i = 1; // счетчик
  19.   $found = 0; // найденный номер
  20.   foreach ($result as $cur_page)
  21.   {
  22.   if ($cur_page['page_id'] == $pages[0]['page_id'])
  23.   {
  24.   // если нашли нашу
  25.   $no = (int) ($i/$home_limit); // номер страницы
  26.   $no = $no+1; // т к первая - нулевая
  27.   if ($no>0) $url = getinfo('siteurl') . 'home/next/' . $no;
  28.   else $url = getinfo('siteurl') . 'home';
  29.   $parent_page_link = '<a href="' . $url . '" title="' . $info_text['home'] . '">' . $info_text['return'] . '</a>';
  30.   break;
  31.   }
  32.   $i++;
  33.   }
  34.  }

Как организовать вывод всего этого в своем шаблоне?

Проще всего интегрировать описанный функционал в свой шаблон при помощи type_foreach файлов.

Вывод навигации: главная, предыдущая, следующая можно реализовать в файле type_foreach/page-do.php.

Пример можете наблюдать в этом блоге.

Вот готовый файл, который нужно разместить в type_foreach шаблона.

Скачать файл: page_do.zip

Дополнение: Как получить следующую и предыдущую только из рубрик текущей.

Часто, может возникнуть дополнительная задача - чтобы следующая и предыдущая статья были из той же рубрики/рубрик, что и текущая. Речь, понятно, идет не о случае с циклом статей, а о глобально по сайту следующей и предыдущей.

Тогда к запросу получения нужно добавить такие строчки:

  1.  $CI->db->join('cat2obj', 'cat2obj.page_id = page.page_id', 'left');
  2.  $CI->db->join('category', 'cat2obj.category_id = category.category_id');
  3.  $CI->db->where_in('category.category_id', $pages[0]['page_categories']);
  4.  $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.

Похожие страницы
Комментариев: 5
  1. Cuprum (профиль) 17 января 2012 в 20:36:44 (ссылка)

    Что-то какие-то проблемы с архивом, не скачивается...

    Вот еще какой вопрос - а можно ли как-то ограничить выборку страниц только текущей рубрикой и подрубриками данной рубрики?

  2. dignityinside (профиль) 17 января 2012 в 21:16:19 (ссылка)

    Да, ссылка на архив не работает.

  3. Sadovnik 18 января 2012 в 17:14:16 (ссылка)

    Теперь работает (попутал "-" "_")

  4. Cuprum (профиль) 19 января 2012 в 22:50:48 (ссылка)

    Вот, так гораздо лучше wink

  5. Sadovnik 28 января 2012 в 20:59:17 (ссылка)
    Еще одна проблема

    - page_do подключается до проверки

    if ($pages)

    Поэтому если обратиться к несуществующей странице - засыпет ошибками.

    Нужно проверки добавить.

Оставьте комментарий!

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

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий email. При регистрации на указанный адрес придет письмо с кодом активации и ссылкой на ваш персональный аккаунт, где вы сможете изменить свои данные, включая адрес сайта, ник, описание, контакты и т.д., а также подписку на новые комментарии.

Авторизация: Авторизация MaxSite CMS. Facebook.

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

(обязательно)