Русскоязычный форум, посвященный фреймворку Kohana

Все о фреймворке Kohana. Обсуждение уроков, документации.
Текущее время: 20 апр 2024, 02:52

Часовой пояс: UTC + 4 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 9 ] 
Автор Сообщение
 Заголовок сообщения: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 22:14 
Не в сети
Супермодератор
Аватара пользователя

Зарегистрирован: 13 фев 2012, 22:24
Сообщения: 65
Откуда: оттуда
Добрый день всем. Озадачился я намедни написанием небольшой цмс-ки и вот возник затык с роутами, как лучше сделать.
Поскольку изначально неизвестно, какие адреса у нас будут, написание роута под каждый случай отметается.
Как вариант, все сплавлять на один контроллер (нашел в тырнете):
Код:
Route::set('node', '(<path>)', array('path' => '.+'))
    ->defaults(array(
    'controller' => 'route',
    'action'     => 'index',
    'path'       => NULL,
));


Далее там по path ищем в базе, есть ли такой адрес. Вот тут не знаю, каким образом это сделать. К каждой статье приписывать uri, по которому ее можно найти и к каждой категории тоже. Искать сначала по статьям, если есть - обрабатывать контроллером статей, если нету - искать по категориям. Как это все туповато.

Вот на хабре накопал статью:
http://habrahabr.ru/post/47941/
и как назло на самом нужном месте она обрывается
Цитата:
А теперь создайте файл routes.php и пропишите в нем


Пытался на глиз разобраться, как работает, но не особо понял.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 22:47 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 24 июл 2012, 18:00
Сообщения: 701
Откуда: Murom, Russia
Маршрутизация:
Код:
  Route::set('static', '(<controller>(/<page>(/<action>)))', array('page' => '.+'))
    ->defaults(array(
      'controller'  => 'page',
      'action'      => 'view'
  ));


Контролёр:
Код:
class Controller_Page extends Controller_Common {

  public function before()
  {
    $name = $this->request->param('page', FALSE);

    if (! $name)
      $this->request->action('welcome');
    parent::before();
  }

  public function action_welcome()
  {
    $content = View::factory('/template/welcome');
    $this->template->content = $content;
  }

  public function action_view()
  {
    $name = $this->request->param('page', FALSE);
    $page = ORM::factory('page', array('name' => $name));
    $view = '/pages/static';

    if (!$page OR !$page->loaded())
    {
      Kohana::$log->add(Log::ERROR, 'Attempt to access non-existent page ' . $name);
      throw new HTTP_Exception_404('Page not found!');
    }

    $this->template->title = $page->title;
    $content = View::factory($view)
             ->bind('page', $page);
    $this->template->content = $content;
  }
}


Вид:
Код:
  <div id="page_content">
    <h2><?php echo $page->title ?></h2>
    <div id="page_body"><?php echo $page->body ?></div>
  </div>


Модель:
Код:
class Model_Page extends ORM {

  /**
   * Stores the table name.
   *
   * @var string
   * @access protected
   */
  protected $_table_name = 'pages';

  /**
   * Stores table columns
   *
   * @var array
   * @access protected
   */
  protected $_table_columns = array(
    'id'      => array('type' => 'int'),
    'author'  => array('type' => 'int'),
    'type'    => array('type' => 'string'),
    'name'    => array('type' => 'string'),
    'created' => array('type' => 'int'),
    'modified'=> array('type' => 'int'),
    'title'   => array('type' => 'string'),
    'body'    => array('type' => 'string'),
    'status'  => array('type' => 'string'),
  );
}


SQL:
Код:
--
-- Definition of table `pages`
--
DROP TABLE IF EXISTS `pages`;
CREATE TABLE `pages` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `author` SMALLINT(8) UNSIGNED NOT NULL,
  `type` VARCHAR(20) NOT NULL DEFAULT 'page',
  `name` VARCHAR(200) NOT NULL,
  `created` INT(11) NOT NULL DEFAULT '0',
  `modified` INT(11) NOT NULL DEFAULT '0',
  `title` VARCHAR(56) NOT NULL,
  `body` LONGTEXT NOT NULL,
  `status` VARCHAR(20) NOT NULL DEFAULT 'pending',
  PRIMARY KEY (`id`),
  KEY `page_type` (`type`),
  KEY `page_type_id` (`type`, `id`),
  KEY `type_status_date` (`type`,`status`,`created`,`id`),
  KEY `page_author` (`author`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 23:13 
Не в сети
Супермодератор
Аватара пользователя

Зарегистрирован: 13 фев 2012, 22:24
Сообщения: 65
Откуда: оттуда
Да это все понятно. Мне не это надо.
Допустим
site.ru/cars
выдает список машин, а
site.ru/cars/daewoo-matiz выдает уже конкретную машину.
Поэтому я и говорю, что в базе забивать для daewoo-matiz адрес cars/daewoo-matiz.
И потом что-то вроде
Код:
        $path = $this->request->param('path');
        $node = ORM::factory('article')->where('url_path', '=', trim($path, '/'))->find();

        if($node->loaded())
            $this->response->body(Request::factory('article/'. $node->id)->execute());


Для категорий аналогично, только ищем в другой таблице и контроллер другой. Оно как бы и работает, но как-то не то.

PS В вашем роуте '(<controller>(/<page>(/<action>)))'
action не нужен. В него все равно ничего не попадет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 23:35 
Не в сети
Супермодератор
Аватара пользователя

Зарегистрирован: 13 фев 2012, 22:24
Сообщения: 65
Откуда: оттуда
Еще как вариант - написать регулярку, которая будет получать последнюю часть uri (т.е. то, что находится после последнего слеша) и по нему уже тогда можно искать в базе alt_name (обычно транслитное название статьи или категории). Тогда отдельное поле не понадобится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 23:35 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 24 июл 2012, 18:00
Сообщения: 701
Откуда: Murom, Russia
eBasher писал(а):
Да это все понятно. Мне не это надо.
Допустим
site.ru/cars
выдает список машин, а
site.ru/cars/daewoo-matiz выдает уже конкретную машину.


Не изобретайте велосипед.
cars в данном случае контролёр, который будет работать с моделью cars
в в action_index проверяйте $name (который в данном примере будет daewoo-matiz) и выбирайте из бд
Роут будет примерно такой: '(<controller>(/<name>))'

eBasher писал(а):
PS В вашем роуте '(<controller>(/<page>(/<action>)))'
action не нужен. В него все равно ничего не попадет.


Ну это всего лишь заготовка


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 12 авг 2012, 23:42 
Не в сети
Супермодератор
Аватара пользователя

Зарегистрирован: 13 фев 2012, 22:24
Сообщения: 65
Откуда: оттуда
Мне не нужно, чтобы cars был контроллером. Мне нужно, чтобы все статьи обрабатывал контроллер articles, а все категории обрабатывал контроллер categories.
Взглянул сейчас на дле и вордпресс. Можно из дле содрать. Все, что оканчивается на .html - считать статьей. Остальное -это категории (с постраничкой и без, причем постраничка определяется по куску /page/). Соответственно пишем два роута и все.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 13 авг 2012, 00:40 
Не в сети
Бывалый
Аватара пользователя

Зарегистрирован: 05 июн 2012, 03:08
Сообщения: 213
Я в одном контроллере content делал 3 экшена
Код:
Route::set('content', '(<action>/)<slug>(/page-<page>)', array('action' => 'category|page', 'slug' => '[-a-z0-9_]+'))
    ->defaults(array(
    'directory'  => 'frontend',
    'controller' => 'content',
    'action'     => 'static',
));
 

Т.е. если просто <slug>, то работает экшн static http://mysite/about, http://mysite/help - статические страницы
Если есть экшн (category или page)
http://mysite/category/category-name - категория (тут можно показывать статьи этой категории или подкатегории или и то и то)
http://mysite/page/article-name - статья из категории
Т.е. <slug> обязательный в любом случае, а к чему относится определяется экшеном.
Если изменили название категории (slug изменился), то на url статьи это не влияет, не нужно в базе лопатить и менять ссылки
Код:
public function action_category()
{
    // Ссылка категории
    $slug = $this->request->param('slug');

    // Получаем категорию
    $o_category = ORM::factory('content_category')
        ->where('slug', '=', $slug)
        ->find();

    // Получаем статьи текущей категории
    $o_articles = $o_category->articles;
        
    
//бла-бла-бла....
}

/**
 * Вывод статических страниц
 */
public function action_static()
{
    $this->_get_page('content_static');
}

/**
 * Вывод статьи
 */
public function action_page()
{
    $this->_get_page('content_article');
}


/**
 * Получение статической страницы или статьи
 *
 * @param $model
 */
private function _get_page($model)
{
    $slug = $this->request->param('slug');

    $o_page = ORM::factory($model)
        ->where('slug', '=', $slug)
        ->find();

    //бла-бла-бла....
}
 

Может вам подойдет
Примерно такая структура url в maxsite cms сделана

_________________
http://de-en.info (работает на Kohana 3.3)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 13 авг 2012, 18:32 
Не в сети
Бывалый

Зарегистрирован: 06 авг 2012, 22:39
Сообщения: 91
ну экшн у вас по прежнему один - static, остальные параметры. параметров может быть несметное количество.
в данном случае если контроллер один (!), надо в роуте просто опустить его название

Код:
route::set('xxx', '(/<param1>(/<param2>(...)))
->defaults(array(
    'controller' => 'articles',
    'action'     => 'view',
));

допустим парам1- категория, парам2 - уже статья
если в строке набрать просто site.ru - вызовется контроллер articles и выведется к примеру список категорий или статьи
добавить парам1 - статьи категории
парам2 - статья.
в экшене лишь необходима проверка парамсов. только стоит позаботится о резервации таких урлов как /login, /register и т.д. можно добавить следующим роут с указанием допустимых значений, он перезапишет этот и все.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Универсальный роутинг
СообщениеДобавлено: 13 авг 2012, 19:54 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 24 июл 2012, 18:00
Сообщения: 701
Откуда: Murom, Russia
Да конечно. Говорю же, велосипед изобретает :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 9 ] 

Часовой пояс: UTC + 4 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Все о фреймворке Kohana  | 
Powered by phpBB® Forum Software © phpBB Group