Показаны сообщения с ярлыком cakephp. Показать все сообщения
Показаны сообщения с ярлыком cakephp. Показать все сообщения

четверг, 17 сентября 2009 г.

Простое решение красивых URL

Если Вы просматриваете какую-то запись/пост на Cake-сайте, то скорее всего адрес выглядит так:
/posts/view/5, где posts - модель, а 5 - номер id записи.
Чтобы сгенерировать такую ссылку надо порписать что-то вроде:$html->link('CakePHP Tips', array('controller' => 'Post','action' => 'view',5));
Но вы не будете писать id вручную, скорее всего это будет что-то вроде:
$html->link($post['Post']['title'], array('controller' => 'Post','action' => 'view',$post['Post']['id']));

А сейчас самое интересное:
Вы можете написать дополнительный параметр, и он будет перенаправлен туда же.
То есть /posts/views/5/Cakephp-tips, ведет туда же, куда и /posts/views/5

Все! Нам больше нигде не нужно хранить Slug. Достаточно прописать его в ссылке

$html->link($post['Post']['title'], array('controller' => 'Post', 'action'=>'view', $post['Post']['id'], Inflector::slug($post['Post']['title'], '-')));
Это даст нам что-то вроде: /posts/view/5/cakephp_tips

среда, 16 сентября 2009 г.

Cakephp TreeBehavior и отдельная ветка

Сегодня расскажу о замечательном свойстве TreeBehavior-a для Cakephp generatetreelist()
Как правило, он выдает большое дерево с подкатегориями и тому подобное.

чтобы использовать tree behavior, в вашей таблице должны быть хотя бы эти 3 поля:
parent_id, lft, rght

$this->Category->generatetreelist();
и все наше дерево готово!

Оказывается не все! а если я хочу не всю ветку, а начиная с id=5?
сразу скажу что варианты типа
$this->Category->generatetreelist(array('id'=>5));
Не прокатит. т.к. в этом случае он вернет только 'id'=5. а нам нужна ветка.

Ну что ж, пойдем дальше...
заменим $this->Category->generatetreelist(); на $this->Category->find('threaded');
этим мы ничего не изменили, а всего лишь вывели все поля, а не только key=>value

а для чего спросите Вы, здесь lft, rgth? странно. я сам долго не мог понять, а чем им id не понравился для сортировки?

как выяснилось, они вовсе не для сортировки.
пока у строк parent_id=0, т.е все они нулевого уровня, lft+1=rght
до того как Вы для какого нибудь элемента добавите дочерний.

Что же тут происходит? lft и rght продолжают нумерацию дальше, как ни в чем ни бывало, не смотря на то что это уже дочерние элементы.
А вот у родительского lft тот же самый, но вот rght = "последний дочерний rght"+1

и так приступим:
$prn = $this->Category->find('first',
array('conditions'=>array('id'=>5))
);
$out = $this->Category->find('threaded', array('conditions'=>array('Category.lft BETWEEN ? AND ?'=> array($prn['Category']['lft'], $prn['Category']['rght'])), 'order'=>'lft');

удачного приготовления :-)

суббота, 12 сентября 2009 г.

Прикручиваем resuestAction к Cache-у

В документации Cakephp 1.2 говорится о том что если requestAction используется без кеширования, то то может уменьшить производительность.
If used without caching requestAction can lead to poor performance. It is rarely appropriate to use in a controller or model.
И правда, сами подумайте, каждый раз при просмотре сайта, кроме основнфх запросов к базе, делается куча мелких, с помощью requestAction-ов...
И как истинные политики, они говорят что может произойти, при этом не говоря КАК это избежать.
Привожу пример того, как с этим разбираюсь я. Это не догмат. Потому буду признателен чужим мнениям, тем более, что Вы, дорогие читатели, не чужие!

Коротко, о том как работает requestAction:
requestAction обычно используется вo view-файле (папка views). из view-файла, вы делаете запрос на другую страницу, и получаете значение.
синтаксис requestAction-а таков: $this->requestAction('/articles/home');
который говорит Cakephp что надо сделать запрос по адресу http://адрес.сайта/articles/home
в самом контроллере к которому обращается requestAction надо прописать return;
function home(){
   $out = $this->Article->find('all');
   Cache::write('articleHome', $out);
   return $out;
}

теперь мы можем смело дописать к $this->requestAction('/articles/home'); следующие строки
$out = Cache::read('articlesHome');
if(empty($out)){
   $out = $this->requestAction('/articles/home');
}

и теперь при каждом обновлении этого списка, если мы что-то добавили/изменили не забываем перезаписывать: Cache::write('articleHome', $out);