Статьи

Введение в представления и шаблоны в CodeIgniter

Представления являются ключевым компонентом в любом приложении MVC, и приложения CodeIgniter ничем не отличаются. Сегодня мы узнаем, что такое представления, и узнаем, как их можно использовать для создания шаблонного решения для ваших проектов CodeIgniter.

Первая часть этого учебника расскажет начинающим CodeIgniter о том, что такое представление и как его использовать в типичном приложении. Во второй половине будут обсуждаться мотивы поиска шаблонного решения, а также проведено руководство по выполнению необходимых шагов по созданию простой, но эффективной библиотеки шаблонов.

Если вы хотите сделать больше с CodeIgniter, ознакомьтесь с набором плагинов CodeIgniter и сценариев кода на Envato Market.

CodeIgniter plugins and code scripts on Envato Market
Плагины CodeIgniter и скрипты кода на Envato Market

Представления — это специальные файлы, используемые в CodeIgniter для хранения разметки, выводимой приложением, обычно состоящей из HTML и простых тегов PHP.

«Представление — это просто веб-страница или фрагмент страницы, например, верхний колонтитул, нижний колонтитул, боковая панель и т. Д. Фактически, представления могут гибко встраиваться в другие представления (в другие представления и т. Д. И т. Д.), Если вам это необходимо. тип иерархии. »

Представления загружаются из методов контроллера , а содержимое внутри представления впоследствии отображается в браузере.


Чтобы загрузить (и отобразить) представление в CodeIgniter, мы используем встроенную библиотеку Loader .

1
$this->load->view(‘hello_world’, $data, true/false);

Эта единственная строка кода сообщит CodeIgniter о hello_world.php в папке application/views и отображении содержимого файла в браузере.

Обратите внимание, что CodeIgniter позволяет исключить суффикс .php, сохраняя несколько нажатий клавиш при вводе имени файла представления, которое вы хотите загрузить.

Второй параметр, $data , является необязательным и принимает ассоциативный массив или объект. Этот массив / объект используется для передачи данных в файл представления, поэтому его можно использовать или ссылаться в представлении.

Последний необязательный параметр определяет, будет ли содержимое представления отображаться в окне браузера или возвращаться в виде строки. Этот параметр по умолчанию имеет значение false, отображая содержимое в браузере. Позже мы увидим в руководстве, как этот параметр можно использовать при создании шаблонного решения.


Чтобы настроить наше первое представление, создайте новый файл с именем hello_world.php в application/views и напишите следующий простой HTML- hello_world.php :

01
02
03
04
05
06
07
08
09
10
11
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <p>
            Hello world!
        </p>
    </body>
</html>

Теперь, чтобы отобразить это представление в браузере, оно должно быть загружено в методе Controller, используя вышеупомянутый метод.

Итак, давайте создадим новый файл Controller с именем hello_world.php в application/controllers и hello_world.php в него следующий код. Из этого контроллера мы загрузим вновь созданное представление.

1
2
3
4
5
6
7
8
9
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
 
class Hello_world extends CI_Controller {
     
    public function index()
    {
        $this->load->view(‘hello_world’);
    }
}

Указание вашему браузеру на http://your-ci-install.com/index.php/ теперь приведет к application/views/hello_world.php HTML в application/views/hello_world.php в браузере. Вы успешно загрузили просмотр!

Разделение представления на несколько файлов упрощает поддержку вашего веб-сайта и снижает вероятность появления дублирующегося кода.

Отображение одного представления — это хорошо, но вы можете разделить вывод на несколько отдельных файлов, таких как представления заголовка, содержимого и нижнего колонтитула .

Загрузка нескольких представлений достигается простым вызовом метода $this->load->view() несколько раз. Затем CodeIgniter объединяет содержимое представлений вместе перед отображением в браузере.

Создайте новый файл с именем header.php в application/views и hello_world.php и вставляйте первые несколько строк из нашего исходного файла hello_world.php в.

1
2
3
4
5
6
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>

Точно так же создайте другой файл с именем footer.php в application/views и переместите последние две строки hello_world.php в.

1
2
</body>
</html>

Это оставляет hello_world.php представления hello_world.php содержащий только содержимое нашей страницы.

1
2
3
<p>
    Hello world!
</p>

Теперь, чтобы снова отобразить страницу, мы должны загрузить все три представления (header.php, hello_world.php, footer.php) по порядку в нашем контроллере.

Снова откройте application/controllers/hello_world.php и добавьте новые вызовы $this->load->view() выше и ниже существующего.

01
02
03
04
05
06
07
08
09
10
11
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
 
class Hello_world extends CI_Controller {
     
    public function index()
    {
        $this->load->view(‘header’);
        $this->load->view(‘hello_world’);
        $this->load->view(‘footer’);
    }
}

Поскольку представления верхнего и hello_world колонтитула теперь отделены от представления hello_world , это означает, что они могут использоваться в сочетании с любыми другими представлениями на веб-сайте. Это означает, что код в файлах верхнего и нижнего колонтитула не нужно копировать в другие представления проекта, для которых требуется этот код.

Очевидно, что это огромное преимущество, так как любые изменения HTML или содержимого в представлениях, например, добавление новой таблицы стилей в заголовок, могут быть внесены только в один файл, а не в каждый файл!


Теперь мы рассмотрим передачу данных из контроллеров, чтобы их можно было использовать или выводить внутри представления.

Для этого мы передадим ассоциативный массив $data в качестве второго параметра в вызове $this->load->view() .

Значения этого массива будут доступны в загруженном представлении как переменные, названные их соответствующими ключами .

1
2
3
4
5
6
7
8
9
$data = array(
 
    ‘title’ => ‘Hello World!’,
    ‘content’ => ‘This is the content’,
    ‘posts’ => array(‘Post 1’, ‘Post 2’, ‘Post 3’)
 
);
 
$this->load->view(‘hello_world’, $data);

Приведенный выше код даст переменной $ title значение ‘Hello World!’ в представлении hello_world .

Как только мы передадим наши данные в файлы представлений, переменные можно использовать обычным способом.

Как правило, файл представления будет использовать переданные данные для:

  • Показать значение переменной
  • Цикл по массивам или свойствам объекта
  • Используйте условные операторы, чтобы показать или скрыть разметку

Я бегу через быстрые примеры того, как сделать каждый.

Чтобы отобразить содержимое переменной, используйте простой и знакомый оператор echo :

1
<h1><?php echo $title;

Циклический просмотр массива или объекта является обычной задачей в файлах представления и может быть достигнут с помощью цикла foreach :

1
2
3
4
5
6
7
<ul>
<?php foreach($posts as $post) { ?>
     
    <li><?php echo $post;
     
<?php } ?>
</ul>

Простые условные операторы могут использоваться в файлах представления для небольшого изменения вывода в зависимости от переданных данных.

В общем, вы хотите свести к минимуму использование условных операторов в представлениях, так как чрезмерное использование может привести к сложным файлам представления, содержащим «бизнес-логику». Разделение представления на разные файлы и решение, которое должно отображаться в контроллере, гораздо предпочтительнее.

1
2
3
4
5
6
7
8
9
<?php if ( $logged_in ) { ?>
 
    <p><?php echo ‘Welcome ‘.$user_name;
     
<?php } else { ?>
 
    <p>Please login</p>
     
<?php } ?>

В приведенном выше примере будет отображаться сообщение «Welcome» или запрос на вход пользователя в зависимости от значения $logged_in (true / false).


Мы видели, как разбиение представлений на отдельные файлы меньшего размера может помочь организовать и уменьшить количество файлов в ваших проектах CodeIgniter, но теперь необходимо выполнять несколько вызовов представления загрузки для каждого экземпляра страницы.

Предположим, у вас есть отдельные представления верхнего и нижнего колонтитула, которые используются для формирования шаблона. Каждый экземпляр в проекте, где вы хотите загрузить и отобразить страницу, используя этот шаблон, должны быть вызваны три вида загрузки. Это не только может загромождать ваши контроллеры, но и приводит к большому количеству повторяющегося кода — именно того, от чего мы хотели избавиться, разбив файлы на части.

Если вы хотите добавить дополнительную разметку к этому шаблону сейчас, например, боковое меню. Он может идти в представлении заголовка, но он больше подходит для отдельного представления. Добавление этого нового представления к существующему шаблону означает прохождение каждого экземпляра представления и добавление еще одного. Это может быстро запутаться.

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

Следующие шаги помогут вам создать простую библиотеку CodeIgniter, которая отвечает этим требованиям, а также:

  • Обеспечение предсказуемой и поддерживаемой структуры каталогов для ваших представлений
  • Возможность использования нескольких различных шаблонов
  • Сокращение загрузки просмотра страницы до одной строки кода

Как только библиотека будет написана и в нашем поясе инструментов CodeIgniter, мы сможем отобразить шаблонную страницу следующим образом:

1
$this->template->load(‘template_name’, ‘body_view’);

Намного приятнее!

Наше шаблонное решение будет использовать файлы представлений, которые содержат полную разметку шаблона, с заполнителем для другого файла представления (с содержимым страницы), который будет встроен в него.

Заполнитель будет просто переменной с именем $body . При загрузке шаблонного представления в нашу библиотеку содержимое соответствующего файла представления тела будет назначено этому $body , встраивая представление в шаблон.


Мы хотим обеспечить разумную и предсказуемую систему каталогов для наших файлов представлений, чтобы наши представления были такими:

  • Легко найти
  • Легко определить, к какой области приложения они относятся
  • Простота в обслуживании

Наша система каталогов также позволит библиотеке умно определять, где искать файлы представлений, сокращая объем кода, необходимый для загрузки шаблонного представления.

Создайте новую папку в каталоге application/views и назовите ее templates . Эта папка будет содержать различные виды шаблонов.


Библиотеки в CodeIgniter — это просто классы PHP и загружаются в контроллеры так же, как и представления.

1
$this->load->library(‘class_name’);

Пользовательские библиотеки, которые вы используете в своих проектах CodeIgniter, хранятся в папке application/libraries . Чтобы начать писать нашу библиотеку шаблонов, создайте в этой папке новый файл с именем Template.php и поместите в него следующий код:

01
02
03
04
05
06
07
08
09
10
11
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
 
   class Template
   {
       var $ci;
        
       function __construct()
       {
           $this->ci =& get_instance();
       }
   }

Приведенный выше код определяет новый класс или библиотеку с именем Template и методом __construct() внутри.

Этот метод назначает суперобъект CodeIgniter переменной класса $ci , позволяя использовать все ресурсы CodeIgniter, заменив $this на $this->ci в обычных вызовах методов.

Когда библиотека загружается в платформу CodeIgniter, автоматически вызывается метод __construct() .

Теперь мы напишем метод для фактической загрузки представления шаблона. Мы хотим передать до трех параметров этой функции:

  • Название шаблона
  • Имя вида тела (необязательно)
  • Данные для передачи в представления (необязательно)

Результатом вызова этого метода будет представление шаблона, отображаемое в браузере, с представлением тела, встроенным в него, если оно есть.

Под методом __construct() поместите следующий код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function load($tpl_view, $body_view = null, $data = null)
{
    if ( ! is_null( $body_view ) )
    {
        if ( file_exists( APPPATH.’views/’.$tpl_view.’/’.$body_view ) )
        {
            $body_view_path = $tpl_view.’/’.$body_view;
        }
        else if ( file_exists( APPPATH.’views/’.$tpl_view.’/’.$body_view.’.php’ ) )
        {
            $body_view_path = $tpl_view.’/’.$body_view.’.php’;
        }
        else if ( file_exists( APPPATH.’views/’.$body_view ) )
        {
            $body_view_path = $body_view;
        }
        else if ( file_exists( APPPATH.’views/’.$body_view.’.php’ ) )
        {
            $body_view_path = $body_view.’.php’;
        }
        else
        {
            show_error(‘Unable to load the requested file: ‘ . $tpl_name.’/’.$view_name.’.php’);
        }
         
        $body = $this->ci->load->view($body_view_path, $data, TRUE);
         
        if ( is_null($data) )
        {
            $data = array(‘body’ => $body);
        }
        else if ( is_array($data) )
        {
            $data[‘body’] = $body;
        }
        else if ( is_object($data) )
        {
            $data->body = $body;
        }
    }
     
    $this->ci->load->view(‘templates/’.$tpl_view, $data);
}

Приведенный выше код начинается с проверки, был ли $body_view параметр $body_view для метода. Эта переменная будет содержать имя представления, которое будет использоваться в качестве тела в представлении шаблона.

1
if ( ! is_null( $body_view ) )

Если параметр указан, выполняется серия проверок file_exists , чтобы попытаться найти файл представления в нашей системе каталогов.

1
2
3
4
5
6
7
8
if ( file_exists( APPPATH.’views/’.$tpl_view.’/’.$body_view ) )
{
    $body_view_path = $tpl_view.’/’.$body_view;
}
else if ( file_exists( APPPATH.’views/’.$tpl_view.’/’.$body_view.’.php’ ) )
{
    $body_view_path = $tpl_view.’/’.$body_view.’.php’;
}

Сначала код пытается найти файл представления внутри папки с тем же именем, что и шаблон в папке application/views .

Это полезно, если разделы вашего проекта кардинально отличаются от других и используют разные шаблоны. В этих обстоятельствах имеет смысл сгруппировать эти файлы представлений вместе.

Например, многие веб-сайты отображают разные шаблоны для отдельных разделов, например блогов. В нашей системе файлы просмотра блога можно поместить в папку application/views/blog , отделив их от основных просмотров сайта.

Если файл представления не может быть расположен в этой папке, .php добавляется в конец имени файла, и проверка выполняется снова. Это просто так, что .php может быть исключен как нативный вызов $this->load->view() .

Если файл все еще не может быть найден, дальнейшие проверки его местоположения сделаны.

01
02
03
04
05
06
07
08
09
10
11
12
else if ( file_exists( APPPATH.’views/’.$body_view ) )
{
    $body_view_path = $body_view;
}
else if ( file_exists( APPPATH.’views/’.$body_view.’.php’ ) )
{
    $body_view_path = $body_view.’.php’;
}
else
{
    show_error(‘Unable to load the requested file: ‘ . $tpl_name.’/’.$view_name.’.php’);
}

На этот раз код проверяет, находится ли файл представления в папке application/views , и еще раз, если он не может быть найден, добавляет .php и проверяет еще раз.

Если файл находится в одном из этих мест, путь присваивается $body_view_path , в противном случае $body_view_path сообщение об ошибке с помощью встроенной в CodeIgniter функции show_error() , и сценарий завершается.

Если файл представления тела был успешно найден, его содержимое присваивается переменной $body .

1
$body = $this->ci->load->view($body_view_path, $data, TRUE);

Мы передаем параметр $data (null, если не указан) в вызов загрузки представления и устанавливаем для третьего параметра значение true, чтобы возвращать вывод представления в виде строки.

Теперь мы добавим эту переменную $body в список данных в $data чтобы она могла быть встроена в представление шаблона при загрузке.

01
02
03
04
05
06
07
08
09
10
11
12
if ( is_null($data) )
{
    $data = array(‘body’ => $body);
}
else if ( is_array($data) )
{
    $data[‘body’] = $body;
}
else if ( is_object($data) )
{
    $data->body = $body;
}

Если $data не был предоставлен вызову load() , $data присваивается массиву, содержащему $body под телом ключа. Если параметр был указан, $body добавляется в список путем присвоения ему ключа массива или свойства объекта, оба также именуются body .

Переменная $body теперь может использоваться в файлах представления шаблона в качестве заполнителя для встроенных представлений .

Последняя строка нашего метода загружает файл application/views/templates папки application/views/templates и передает переменную $data во второй параметр.

1
$this->ci->load->view(‘templates/’.$tpl_name, $data);

Вот и все! Теперь библиотеку можно использовать.


Чтобы начать использовать нашу библиотеку, давайте создадим представление шаблона с именем default.php в application/views/templates и поместим в него следующий HTML / PHP:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
 
    <head>
        <title><?php echo $title;
    </head>
 
    <body>
     
        <h1>Default template</h1>
         
        <div class=»wrapper»>
             
            <?php echo $body;
             
        </div>
         
    </body>
     
</html>

В этом шаблоне мы ссылаемся на две переменные, $title и $body .

Напомним, что в наших файлах шаблонов $body служит заполнителем для встроенного представления.

Теперь мы сделаем другое представление, которое будет встроено в этот шаблон. Создайте новый файл с именем content.php в application/views/ и поместите этот простой HTML внутри:

1
2
3
<p>
    Hello world!
</p>

Теперь мы готовы загрузить шаблонное представление страницы из контроллера.

Внутри любого метода контроллера поместите следующий код для отображения представления content в шаблоне по default .

1
2
3
4
5
6
7
8
$data = array(
 
    ‘title’ => ‘Title goes here’,
     
);
 
$this->load->library(‘template’);
$this->template->load(‘default’, ‘content’, $data);

Примечание: библиотека должна быть загружена до того, как вы сможете вызвать метод load . Чтобы сэкономить на загрузке библиотеки каждый раз, когда необходимо отобразить шаблон,
автоматически загрузить класс, добавив его в массив библиотек в application/config/autoload.php .

Если вместо файла представления вы хотите, чтобы строка была встроена в шаблон, просто присвойте строку массиву $data используя body ключа, и передайте null в качестве второго параметра в вызове загрузки.

1
2
3
4
5
6
7
8
$data = array(
 
    ‘title’ => ‘Title goes here’,
    ‘body’ => ‘The string to be embedded here!’
     
);
 
$this->template->load(‘default’, null, $data);

Я обнаружил, что группировка файлов представлений в папках по контроллеру и даже способ, к которому они принадлежат, действительно помогает упорядочить и легко найти мои представления.

Таким образом, организация ваших представлений приводит к структуре каталогов, точно соответствующей схеме URL controller/method .

Например, скажем, в вашем проекте есть контроллер с именем Members , содержащий list методов.

Подходящее место для файла представления list будет в application/views/members или application/views/members/list , если этот метод загружает несколько представлений.

Затем это представление может быть встроено в шаблон с использованием нашей библиотеки со следующим кодом:

1
$this->template->load(‘template_name’, ‘members/list’);

Решение для шаблонов, обсуждаемое в этом руководстве, является лишь одним из множества способов достижения шаблонов в CodeIgniter.

Надеемся, что теперь вы должны знать, что такое представления и как эффективно их использовать — в своих проектах CodeIgniter.

Решение для шаблонов, обсуждаемое в этом руководстве, является лишь одним из множества способов достижения шаблонов в CodeIgniter. Существует несколько различных подходов, и я призываю вас, читатель, изучить другие методы и определить, какие из них лучше всего подходят для ваших проектов.

Если у вас есть какие-либо комментарии или вопросы по поводу учебника, или какие-либо идеи о различных шаблонных решениях, пожалуйста, оставьте комментарий ниже! Спасибо за прочтение.