Codeigniter

Создание движка на CodeIgniter 3 + HMVC. Часть 3. Пишем модуль page

Судя по отзывам к предыдущей статье - начало создания всем понравилось. Не буду скрывать мне тоже нравится такой подход к программированию и рендера шаблона;) Вместо старомодных include('./header.php') include('./footer.php') мы сделали один шаблон и будем выводить контент в шаблоне в одну строку и любые настройки в переменных со своими именами заданными в настройках сайта в базе данных.

Итак, подошло время увеличивать сложность и делать level up в программировании на codeigniter ;) Будеv делать сердце фронт-енда нашего движка - вывод страниц. Что мы получим в конце работы с нашим движком в этой статье?

  • Сформированную и продуманную таблицу в бд для страниц сайта
  • Рендинг данных самой страницы в отдельном шаблоне
  • Проверку на существование страницы
  • Формирование мета данных, для сео продвижения и передачу данных общему шаблону
  • Вывод страницы по адресу http://website.name/page/meta_url_page
  • Настройка роутинга codeigniter для обработки модуля

Модуль page. Создание базы данных для всех страниц сайта

Создадим таблицу pages

CREATE TABLE IF NOT EXISTS `pages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(300) NOT NULL,
  `cat_id` int(11) DEFAULT NULL,
  `image` varchar(255) DEFAULT NULL,
  `content` text,
  `meta_title` varchar(300) DEFAULT NULL,
  `meta_h1` varchar(300) DEFAULT NULL,
  `meta_description` text,
  `meta_keywords` text,
  `meta_url` varchar(130) DEFAULT NULL,
  `template` varchar(50) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `edited` datetime DEFAULT NULL,
  `post_status` tinyint(1) DEFAULT NULL,
  `short_content` text,
  `author` varchar(255) DEFAULT NULL,
  `post_viewed` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `cat_id` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Теперь разберем по полочкам:

  • id - идентификатор каждой страницы, ключевое поле
  • name - имя страницы, при отсутствии заголовка H1 или мета тегов - будет выводится именно это имя на сайте
  • cat_id - идентификатор категории к которой принадлежит данная страница, пригодится позже при написании модуля категории
  • image - изображение страницы(для раздела категории или вывода изображения внутри статьи)
  • content - текст, полное содержание страницы
  • meta_title, meta_h1, meta_keywords, meta_description - мета данные для каждой страницы
  • meta_url - хоть URL страницы не является мета данными )), мы будем использовать данное название для поля во всех наших модулях, что бы проверять существование той или иной страницы в одной системной функции
  • template - очень важное поле, с его помощью можно будет для любой страницы задать свой шаблон. По умолчанию данные будут рендерится в общем шаблоне page_full.tpl
  • created и edited - дата создания и редактирования страницы, пригодится для вывода новостей или блога
  • post_status - отображать или не отображать, вот в чем вопрос
  • short_content - краткое содержание, можно использовать для вывода анонса в разделах, либо дополнительных данных
  • author - автор статьи
  • post_viewed - счетчик просмотра страницы
image description

Конечно же вы можете добавить любые другие поля, например post_from, post_to - что бы сделать отложенную публикацию, а ля joomla и wordpress. Или date_hidden - что бы отображать или не отображать дату публикации. Все это вы оставите для изобретения индивидуальных проектов;-)

Создание шаблона page_full.tpl для вывода данных страницы и подготовка index.tpl

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

Выводим meta_title, meta_description, meta_keywords. Шапку сайта, футер и content - вывод генерированного шаблона страницы нашим модулем page.

Теперь нужно подготовить содержание шаблона страницы. Создадим файл в папке /themes/site/page_full.tpl. Код:

Отлично! В новом шаблоне кратким условным оператором выводим название страницы либо заданный meta_h1. В описании - дату создания статьи и имя автора с ссылкой. Если задали изображения для страницы выводим и его перед основным текстом. Правый сайдбар оставим, позже заполниться полезной информацией.

Модель - Вид - Контроллер модуля page на Codeigniter 3

Пришла пора заняться программированием. Создаем папку page в modules. В папке с модулем, в controllers создадим файл page.php и модель page_model.php в папке models

image description

Не буду ходить во круг да около и сразу выложу рабочий код контроллера. пояснения ниже.

Вот оно сердце нашего произведения ^-) по порядку:

  • В конструкторе подключаем общую библиотеку main_lib - мы уже использовали ее в предыдущем уроке
  • Подключаем модель page_model - пока в ней будет только один запрос, но позже модель будет расширятся
  • Метод view, контроллера page - принимает передаваемый параметр $url
  • С помощью функции check_isset_page библиотеки main_lib - проверяем существует ли данная страницы. Передаем функции имя url и название таблицы в котором проверять, существует ли такая страница или вывести страницу 404. Вот код функции для нашей общей библиотеки:
    function check_isset_page($url, $table){
            $this->CI->db->where('meta_url', $url)
                     ->from($table);
            if($this->CI->db->count_all_results() < 1){
                show_404();
            }
        }
    
  • Далее, еще одна общая для большинства будущих модулей функция get_meta_data
    	function get_meta_data($url, $table){
            $result =  $this->CI->db->select('meta_title, meta_description, meta_keywords, name')->where('meta_url', $url)->get($table)->row_array();
            $result['meta_title'] != "" ? $result['meta_title'] = $result['meta_title'] : $result['meta_title'] = $result['name'];
    
            //добавляем суффикс к title если не пустой
            $title_suffix = Modules::run('settings/get_one_setting', 'title_suffix');
            if(!empty($title_suffix)) $result['meta_title'] .= $title_suffix;  
    
            return $result;
        }
    
    Выбираем значения всех нужных полей. И если мы не задавали meta_title для нашей страницы - то будем выводить ее имя. Так же c помощью модуля настройки - смотрим нужно ли добавлять суффикс к заголовку страницы, если в базе есть данные - объединяем значения. Эта же функция - создает многомерный ассоциативный массив $data - в который помещаются все наши основные данные для рендера общего шаблона.
  • Функция модели page_model - get_page($url) - выбирает и помещает в наш массив под индексом content - данные из базы.
  • Если значение поля post_status равно 0, то выводим страницу 404
  • Если страница расположена в категории, то также выбираем все данные категории и помещаем в массив $data под индексом category
  • Увеличиваем счетчик просмотра на 1 с помощью функции модели - update_page_viewed
  • Проверяем - следует ли нам загружать конкретный файл отображения или использовать стандартный page_full.tpl
  • Вызываем функцию загрузки отображения следующим образом: в первом параметре - указываем шаблон, во втором параметре из контроллера в отображение передаем массив $result с данными, третий параметр позволяет нам возвратить данные строкой а НЕ отправлять их сразу в браузер - мы же будем выводить все в общем шаблоне.
  • возвращаем все данные основному методу view и рендерим функцией библиотеки main_lib наш шаблон с данными страницы.

В добавок - не достающий код модели page_model.php

class Page_model extends CI_Model {

    function __construct()
    {
        parent::__construct();
    }

    //функция возвращает все данные страницы page
    function get_page($url){
        $result = $this->db->where('meta_url', $url)->get('pages')->row_array();
        return $result;
    }

    //функция возвращает все данные категории страницы
    function get_category_data($cat_id){
        $result = $this->db->where('id', $cat_id)->get('category')->row_array();
        return $result;
    }

    //функция увеличивает число просмотров страницы
    function update_page_viewed($url){
        $this->db->where('meta_url', $url)->set('post_viewed', '`post_viewed`+ 1', FALSE)->update('pages');
    }
}

Создание и вывод главной страницы движка homepage с помощью нового модуля

Давайте создадим в нашей таблице page первую и обязательную, и главную страницу homepage. Именно она будет открываться как индексная главная страница в нашем движке. Мы сделаем это в роутере codeigniter.

INSERT INTO `pages` (`id`, `name`, `cat_id`, `image`, `content`, `meta_title`, `meta_h1`, `meta_description`, `meta_keywords`, `meta_url`, `template`, `created`, `edited`, `post_status`, `short_content`, `author`, `post_viewed`) VALUES
(1, 'Главная', 0, NULL, '

Содержание главной страницы

', NULL, 'Заголовок главной страницы', 'Главная', 'Главная', 'homepage', NULL, '2015-11-06 21:58:10', '2015-11-06 21:58:15', 1, NULL, 'Евгений Поляков', '22');

Отлично! Проверяем - заходим на наш сайт http://ci3.ru/page/view/homepage - и о чудо! Модуль работает =).

image description

Но и это еще не все. Ни по фен-шую выводить пользователю такой адрес страницы. Установим собственную маршрутизацию. открываем файл /application/config/routes.php и добавим следующие строки

$route['default_controller'] = "page";

Теперь создадим собственный файл роутинга для нашего модуля в папке config/routes.php

$route['page'] = 'page';
$route['page/(:any)'] = 'page/view/$1';

B создадим метод вызываемый контроллером модуля по умолчанию

function index(){
        $this->view('homepage');
    }

В предыдущей, 2й версии codeigniter. Всего выше описанного можно было и не делать. Достаточно было дописать две строки в основном файле роутинга:
$route['page/(:any)'] = "page/view/$1";
$route['default_controller'] = "page/view/homepage";
Но в третьей версии и расширении HMVC данный подход почему то не сработал, приходится импровизировать, пока не будет такой возможности в расширения HMVC для новой версии codeigniter делать так же. Кстати 2 дня назад на репозитории выложили новую свежую версию расширения HMVC. В исходниках она уже установлена;)

Как всегда исходный код с дампом базы в архиве.
А я жду ваших отзывов! И не забывайте что продолжение следует...

4312 Просмотров Комментариев: 11

Євген

Ответить

Майже завжди не коментую, але не той випадок :) Клас! Дуже дякую за статті, саме те що шукав. Кожен день заходжу подивитись чи щось не пропустив.

Поляков Евгений

Ответить

Всегда пожалуйста. Это только начало цикла статей. Заходите ;)

Павел

Ответить

Набиваю код по вашим примерам, помогает для "переваривания" материала.. Спасибо.. Ждем-с ))

hipm

Ответить

Евгений подскажите, что может быть. У меня локально стоит wamp - Денвер. И если я ввожу http://localhost/ci3.ru/page/view/homepage то у меня происходит переход на http://localhost/denwer. В чем причина? Смотреть htaccess?

HIPM

Ответить

Евгений, я разобрался.... В вашем примере htaccess RewriteRule ^(.*)$ /index.php/$1 [L,QSA] я убрал слэш "/" перед index.php и все заработало.

Поляков Е.

Ответить

Да, HIPM! Все верно. Для оптимизации, убрал дубли страниц редиректом, localhost - считается отдельным доменом и пути соответственно нужно статические указывать! И советую снести denwer и поставить openserver - в сто раз меньше хлопот;)

HIPM

Ответить

Спасибо за совет! Огромное спасибо за Ваш труд - отличные уроки и профессиональный подход к материалу!

Алексей Кулагин

Ответить

Евгений! Курс ЗАМЕЧАТЕЛЬНЫЙ, но сырой... Без обид. Как отправная точка для экспериментов да, ты КРАСАВЧЕГ!!! Хочу ещё! 1. Пиши, пожалуйста, имена классов с большой буквы, windows not linux :) 2. Разберись с путями (это к предыдущим урокам). Точка входа в CI одна - index.php. Например, APPPATH . '../modules/' От точки входа мы идем в application, потом возвращаемся обратно наверх. Мелочь, но глаз царапает. Идеологически верно: ./modules/, т.к. этот каталог лежит на одном уровне с точкой входа на сайт. 3. По этому уроку: не нравится костыль с роутами. Я вообще не понимаю вот этого: $route['page/(:any)'] = 'page/view/$1'; В правой части 'page/view/$1' page это контроллер в котором есть функция view(), предопределенная кстати, или это модуль page в котором нужно найти контроллер view(), и обратиться к его функции, переданной в (:any)?

Алексей Кулагин

Ответить

Евгений! Курс ЗАМЕЧАТЕЛЬНЫЙ, но сырой... Без обид. Как отправная точка для экспериментов да, ты КРАСАВЧЕГ!!! Хочу ещё! 1. Пиши, пожалуйста, имена классов с большой буквы, windows not linux :) 2. Разберись с путями (это к предыдущим урокам). Точка входа в CI одна - index.php. Например, APPPATH . '../modules/' От точки входа мы идем в application, потом возвращаемся обратно наверх. Мелочь, но глаз царапает. Идеологически верно: ./modules/, т.к. этот каталог лежит на одном уровне с точкой входа на сайт. 3. По этому уроку: не нравится костыль с роутами. Я вообще не понимаю вот этого: $route['page/(:any)'] = 'page/view/$1'; В правой части 'page/view/$1' page это контроллер в котором есть функция view(), предопределенная кстати, или это модуль page в котором нужно найти контроллер view(), и обратиться к его функции, переданной в (:any)?

Алексей Кулагин

Ответить

Продолжаю, букофф много Вот мой тестовый листинг в application/routes.php 1 $route['default_controller'] = 'home'; 2 $route['test_home'] = 'home/test_home'; 1 строка: home это модуль, внутри которого есть контроллер с именем модуля - home.php. По запросу http://my_site отдается этот контроллер функция index() По запросу http://my_site/my_func тоже отдается этот контроллер функция my_func() Причем у меня в роуте нет $route[home/(:any)] = 'home/$1' 2 строка: по запросу http://my_site/test_home отдается контроллер test_home, который лежит в модуле home. Во второй строке home - это модуль!!! В первой строке home - это контроллер, имя которого совпадает с модулем!!! Также у меня есть тестовый модуль home_1 с контроллером home_1.php Он отдается без записи в application/routes.php Возможно всё так просто потому, что у меня более свежие версии CI и HMVS. Всё может быть. Но, я все равно не понимаю $route['page/(:any)'] = 'page/view/$1'; А вообще здорово! Спасибо огромное!

Владимир

Ответить

Спасибо за серию уроков. Очень полезно.

« Предыдущая статьяСоздание движка на CodeIgniter 3 + HMVC. Часть 2 - пишем модули settings и common. Следующая статья »Создание движка на Codeigniter 3 + HMVC. Часть 4. Создание модуля category