HMVC Матрёшка - пример реализацииМаршруты:
Код:
Route::set('page', '(<slug>(/<subrequest>))', array(
'slug' => '[\w\-]+',
'subrequest' => '\.+',
))
->defaults(array(
'directory' => NULL,
'controller' => 'Page',
'action' => 'item',
'slug' => Kohana::$config->load('page.default.slug'),
'subrequest' => NULL,
))
->filter(
function(Route $route, $params, Request $request)
{
return $request->is_initial() ? $params : FALSE;
}
);
Route::set('default', '(<directory>/<controller>(/<action>(/<id>)))')
->defaults(array(
'directory' => 'Page',
'controller' => 'Home',
'action' => 'index',
));
SQL дамп таблицы со страницами
Код:
CREATE TABLE IF NOT EXISTS `pages` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`slug` varchar(255) NOT NULL,
`content` text NOT NULL,
`layout` varchar(255) NOT NULL,
`controller` varchar(255) NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Контроллер страниц (основной)
Код:
class Controller_Page extends Controller_Template
{
public $template = 'wrapper';
public function action_item()
{
$slug = $this->request->param('slug');
$page = ORM::factory('Page')->where('slug', '=', $slug)->find();
if ( ! $page->loaded())
{
throw HTTP_Exception::factory(404, 'Page :name not found', array(':name' => $slug));
}
View::set_global('PAGE', $page);
View::set_global('PROTOCOL', $this->request->protocol());
$this->template->layout = View::factory('layout/'.$page->layout)->render();
}
} // End Controller_Page
Вид wrapper (обёртка для контента)
Код:
<!DOCTYPE html><?php defined('SYSPATH') OR die('No direct script access.') ?>
<html lang="<?php echo I18n::$lang ?>">
<head>
<base href="<?php echo URL::base($PROTOCOL) ?>">
<title><?php echo $PAGE->title ?></title>
<!--[if lt IE 9]><script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<?php echo $layout ?>
</body>
</html>
Вид layout/home (слой для главной)
Код:
<header><?php echo CMS::snippet('home/header') ?></header>
<main>
<aside id="left_menu"><?php echo CMS::widget('menu/left') ?></aside>
<article><?php echo CMS::snippet('content') ?></article>
</main>
<footer><?php echo CMS::snippet('footer') ?></footer>
Вид layout/default (слой для всех остальных страниц)
Код:
<header><?php echo CMS::snippet('default/header') ?></header>
<main>
<aside id="menu-left"><?php echo CMS::widget('menu/left') ?></aside>
<article><?php echo CMS::snippet('content') ?></article>
<aside id="menu-right"><?php echo CMS::widget('menu/right') ?></aside>
</main>
<footer><?php echo CMS::snippet('footer') ?></footer>
Вид snippet/content (сниппет основного контента)
Код:
<?php if ($PAGE->content): ?>
<div class="header">
<?php echo $PAGE->content ?>
</div>
<?php endif ?>
<?php if ($PAGE->controller): ?>
<div class="footer">
<?php echo CMS::request('page/'.$PAGE->controller.'/'.Request::initial()->param('subrequest')) ?>
</div>
<?php endif ?>
Вспомогательный класс CMS
Код:
abstract class Kohana_CMS
{
/**
* Create identification tag(key) uses the methods attributes.
* Basically used for get or set cache.
*
* @static
* @return string
*/
public static function generate_tag()
{
return I18n::$lang.'_'.sha1(serialize(func_get_args()));
}
/**
* Request bulder
*
*/
public static function request($name, array $data = array(),
$method = NULL, $allow_external = FALSE, Cache $cache = NULL)
{
$options = array();
if ( ! is_null($cache) AND Kohana::$caching)
{
$options['cache'] = HTTP_Cache::factory($cache);
}
$request = Request::factory($name, $options, $allow_external);
if (is_null($method))
{
$method = Request::GET;
}
$request->method($method);
switch ($method)
{
case Request::GET:
$request->query($data);
break;
case Request::POST:
$request->post($data);
break;
}
return $request->execute();
}
public static function snippet($name, array $data = array(), $caching = TRUE)
{
$name = 'snippet'.DIRECTORY_SEPARATOR.str_replace(array(' ', '_', '\\'), DIRECTORY_SEPARATOR, $name);
if ($caching AND Kohana::$caching)
{
$cache = Cache::instance('snippet');
$tag = CMS::generate_tag($name, $data);
if ($snippet = $cache->get($tag))
{
return $snippet;
}
}
$snippet = View::factory($name, $data)->render();
if (isset($cache))
{
$cache->set($tag, $snippet);
}
return $snippet;
}
public static function widget($name, array $data = array(), $caching = TRUE)
{
if ($caching AND Kohana::$caching)
{
return CMS::request('widget/'.$name, $data, NULL, FALSE, Cache::instance('widget'));
}
else
{
return CMS::request('widget/'.$name, $data, NULL, FALSE);
}
}
}