Как бы вы структурировали следующую страницу в Codeigniter?
Я думал о создании отдельных контроллеров для каждого раздела
Исключая раздел содержимого (поскольку это изменяется в зависимости от ссылки на левом навигационном и контентном навигаторе, используемом как своеобразное подменю). Все остальные разделы остаются примерно одинаковыми
Я думал об этом:
Class User_Profile extends Controller { function index() { $this->load_controller('Left_Nav'); $this->load_controller('Content_Nav'); $this->load_controller('Login_Name'); $this->load_controller('Leaderboard', 'Board'); $this->Left_Nav->index(array('highlight_selected_page' => 'blah')); $this->load('User'); $content_data = $this->User->get_profile_details(); $this->view->load('content', $content_data); $this->Login_Name->index(); $this->Board->index(); } }
Очевидно, что этот load_controller
не существует, но эта функция была бы полезна. Контроллер для каждого раздела получает данные, требуемые от модели, а затем загружает страницу через $this->view->load()
Это может быть головная боль, чтобы иметь этот код во всех левых навигационных ссылках, таких как «Новости», «Пользователи», «О нас» и т. Д. Но опять же не у каждой навигационной ссылки есть все эти разделы, поэтому мне нужна гибкость в том, что разделы являются «частичными Посмотреть"
Может ли кто-нибудь предложить лучший способ сделать это?
Я не могу ручаться, что это лучший подход, но я создаю базовый контроллер следующим образом:
class MY_Controller extends CI_Controller { public $title = ''; // The template will use this to include default.css by default public $styles = array('default'); function _output($content) { // Load the base template with output content available as $content $data['content'] = &$content; $this->load->view('base', $data); } }
Представление, называемое «базой», является шаблоном (представление, которое включает в себя другие виды):
<?php echo doctype(); ?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <?php $this->load->view('meta'); ?> </head> <body> <div id="wrapper"> <?php $this->load->view('header'); ?> <div id="content"> <?php echo $content; ?> </div> <?php $this->load->view('footer'); ?> </div> </body> </html>
Это достигается тем, что каждый контроллер обертывает свой результат в базовом шаблоне, и эти представления имеют действительный HTML вместо того, чтобы открывать теги в одном представлении и закрываться другим. Если бы я хотел, чтобы конкретный контроллер использовал другой шаблон или без него, я мог бы просто переопределить метод _output()
.
Фактический контроллер будет выглядеть так:
class Home extends MY_Controller { // Override the title public $title = 'Home'; function __construct() { // Append a stylesheet (home.css) to the defaults $this->styles[] = 'home'; } function index() { // The output of this view will be wrapped in the base template $this->load->view('home'); } }
Тогда я мог бы использовать его свойства в своих представлениях, подобных этому (это представление «мета», которое заполняет элемент <head>
):
echo "<title>{$this->title}</title>"; foreach ($this->styles as $url) echo link_tag("styles/$url.css");
Мне нравится мой подход, потому что он уважает принцип DRY, а верхний и нижний колонтитулы и другие элементы включаются только один раз в код.
Ответ @Reinis, вероятно, правильно попал на место для более ранних версий CI менее 2.0, но с тех пор он сильно изменился, поэтому я решил ответить на этот вопрос с помощью современного метода того, что я сделал.
Большинство из них аналогично методу @Reinis, а также описано здесь: http://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_Controller
Однако здесь сделаны обновления:
Шаг 1. Создайте файл MY_Controller.php и сохраните его в / application / core
Шаг 2. В вашем файле MY_Controller.php добавьте следующее содержимое:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class MY_Controller extends CI_Controller { function __construct() { parent::__construct(); } function _output($content) { // Load the base template with output content available as $content $data['content'] = &$content; echo($this->load->view('base', $data, true)); } }
Шаг 3: Создайте образец контроллера, чтобы сфокусироваться на MY_Controller.php, в этом случае я создам контроллер welcome.php внутри приложения / контроллеров / со следующим содержимым:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Welcome extends MY_Controller { function __construct() { parent::__construct(); } public function index() { $this->load->view('welcome_message'); } }
После установки этих контроллеров выполните следующие действия:
Шаг 4. Создайте базовый вид внутри / application / views и назовите файл base.php, содержимое файла должно быть похоже на это:
<!DOCTYPE html> <!--[if IE 7 ]><html lang="en" class="ie7"><![endif]--> <!--[if IE 8 ]><html lang="en" class="ie8"><![endif]--> <!--[if gt IE 8]><!--><html lang="en"><!--<![endif]--> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <title></title> <link rel="stylesheet" href="<?php echo base_url(); ?>stylesheets/reset.css" media="screen" /> </head> <body> <div id="section_main"> <div id="content"> <?php echo $content; ?> </div> </div> <?php $this->load->view('shared/scripts.php'); ?> </div> </body> </html>
Шаг 5: Создайте еще один вид в / application / views и назовите это представление welcome_message.php, содержимое этого файла будет:
<h1>Welcome</h1>
Как только все это будет завершено, вы увидите следующий результат:
<!DOCTYPE html> <!--[if IE 7 ]><html lang="en" class="ie7"><![endif]--> <!--[if IE 8 ]><html lang="en" class="ie8"><![endif]--> <!--[if gt IE 8]><!--><html lang="en"><!--<![endif]--> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <title></title> <link rel="stylesheet" href="http://somedomain.local/stylesheets/reset.css" media="screen" /> </head> <body> <!-- BEGIN: section_main --> <div id="section_main"> <div id="content"> <h1>Welcome</h1> </div> </div> <!-- END: section_main --> <script src="/path/to/js.js"></script> </div> </body> </html>
Как вы видите, <h1>Welcome</h1>
было помещено в базовый шаблон.
Ресурсы:
Надеюсь, это поможет кому-то еще прибегнуть к этой технике.
Моя библиотека шаблонов может справиться со всем этим. Вы создаете один (или несколько) файл макета, который содержит частичные и теги, для которых будет распространяться содержимое основного тела.
Синтаксис прост как:
// Set the layout: defaults to "layout" in application/views/layout.php $this->template->set_layout('whatever') // Load application/views/partials/viewname as a partial $this->template->set_partial('partialname', 'partials/viewname'); // Call the main view: application/views/bodyviewname $this->template->build('bodyviewname', $data);
от// Set the layout: defaults to "layout" in application/views/layout.php $this->template->set_layout('whatever') // Load application/views/partials/viewname as a partial $this->template->set_partial('partialname', 'partials/viewname'); // Call the main view: application/views/bodyviewname $this->template->build('bodyviewname', $data);
Симплирует правильно?
Поместите часть этого в MY_Controller и еще проще.
вы считали шаблоны? Есть много достойных, доступных с небольшим поиском – проверьте CI wiki.
шаблоны делают более или менее то, что вам нужно. Вы определяете один главный шаблон и «разделы», и они загружаются для вас каждый раз
не хотите подключаться слишком сильно, чтобы вы могли начать работу – библиотеки шаблонов в CI
Я бы сделал MY_Controller, чтобы позаботиться обо всем этом. Вы можете разместить его с помощью макета (шаблона) / навигационной библиотеки для создания всех макетов, навигации, отображения / выделения выделенного пункта меню, загрузки представлений и т. Д.
Я бы сказал, что это неправильный способ сделать это, если вы используете контроллер для каждого раздела. Вы можете использовать представления и вложенные представления для этого.
Мне нравится то, что Фил Стерджон упомянул. Хотя это считается очень сложной, мне очень понравилась структура шаблонов, которая имеет magento.
Вдохновленный таким способом структурирования, я сделал свою логику (что не очень хорошо, но это просто, как может быть, и, возможно, возможно, я мог бы переопределить -> просмотр загрузчика и заставить его принять какой-то объект в качестве имени шаблона и чем загружать структуру по мере необходимости)
во-первых : этот подход должен использоваться очень ответственно (вы собираете данные в контроллере / методе, который требуется вашим шаблонам!
second : Шаблон должен быть подготовлен и структурирован должным образом.
Вот что я делаю:
в каждом контроллере у меня есть атрибут типа Array, что-то вроде этого:
class Main extends CI_Controller { public $view = Array( 'theend' => 'frontend', 'layout' => '1column', 'mainbar' => array('content','next template file loaded under'), 'sidebar' => array('generic','next template file loaded under'), 'content' => '', );
В каждом методе, для которого я хочу использовать предыдущую структуру, и если я хочу немного изменить его, напишу его так:
public function index() { $data['view'] = $this->view; // i take/load global class's attribute $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it // i add/load data that i need in all those templates that are needed $data['view'] also my using same Array $data['my_required_data_that_i_use_in_template_files'] = 1; $this->load->view('main',$data); // }
Третья папка In / application / view у меня есть структура вроде
/view/main.php <-- which basically just determines which side's wrapper of web to load (frontend or backend or some other) /view/frontend/wrapper.php /view/backend/wrapper.php /view/mobile/wrapper.php <-- this wrappers are again another level of structuring for ex: /view/backend/layouts/ <-- inside i have templates different layouts like 1column.php 2columns-left (have left side is narrow one),2columns-right,3columns... etc... /view/backend/mainbar/ <-- inside i have templates for mainbar in pages /view/backend/mainbar/.../ <-- in the same way it's possible to add folders for easily grouping templates for example for posts so you add for example /view/backend/mainbar/posts/ <-- all templates for creating, editing etc posts... /view/backend/sidebar/ <-- inside i have templates for sidebar in pages /view/backend/...other special cases.... like dashboard.php
Четвертый файл в /app/view/main.php выглядит примерно так:
if ($view['theend'] == "frontend") { $this->load->view('/frontend/wrapper'); } elseif ($view['theend'] == "backend") { $this->load->view('/backend/wrapper'); }
пятая оболочка проста в php в структурированном HTML, где у вас есть заголовок (загрузка заголовков html, заголовок и т. д.) заголовок / заголовки (загрузка в заголовках, если в переданной переменной $ data ['view'] ['headers'] / array) (загружает в файл макета, который просто имеет новый html-структурированный файл со следующим уровнем загрузки файлов) нижние колонтитулы (загрузка нижних колонтитулов, если в переданной переменной $ data ['view'] ['footers'] есть какая-либо информация) скриптов (загрузка скриптов, таких как analytics / facebook, скрипты перед тегом)
шестой. Таким же образом, макет также будет загружаться в контент mainbar / sidebar, указанный в public $ view = Array (….)
Если мне нужен какой-то метод, я просто переопределяю часть публичного атрибута $ view = Array (…), и я переопределяю только часть, которая отличается.
это делается примерно так:
public function index() { $data['view'] = $this->view; // i take/load global class's attribute $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it // i add/load data that i need in all those templates that are needed $data['view'] also my using same Array $data['my_required_data_that_i_use_in_template_files'] = 1; $this->load->view('main',$data); // }
НАКОНЕЧНЯ Загрузка выглядит следующим образом:
$ This-> load-> Вид ( 'главный', $ данных); <- Loads /app/view/main.php и передает $ data $ data имеет узел 'view' ($ data ['view']), и в нем у него есть узлы, которые определяют другие важные вещи, такие как: какой конец , какой макет, какие заголовки, какие нижние колонтитулы и т. д. …
Используя определенные данные в $ data ['view'] ['theend'], он загружает соответствующую оболочку
Это о нем …
ps Мне очень жаль, что не использовал числа, но система stackoverflow настолько странная, что вместо показа 3. она показывает мне 1 .. как вы видите, у меня были некоторые вложенные списки …
То, что я сделал (в Kohana 2), имеет 1 шаблон со всеми подразделами (например, левое меню, верхний заголовок) и один контроллер, который заполняет переменные, которые будут заменены в шаблоне.
Затем переменные для каждого подсектора могут быть сгенерированы функциями, называемыми самим контроллером. Вы также можете использовать эти функции в отдельном конструкторе класса контроллера, причем каждый ваш контроллер расширяет его, чтобы они автоматически запускались и устанавливались как переменные класса для легкого доступа.
Для немного более приятных шаблонов вы можете иметь подразделы в отдельных файлах, а большой шаблон включает их:
<?php include 'leftMenu.php'; ?>