Меню с выделением текущего раздела

Практически на всех сайтах есть навигация в виде меню. К сожалению, в CakePHP нет хелпера, который бы помогал делать меню автоматически. Это вполне реализуемо, ведь на семантически правильно свёрстаных сайтах меню делается одинаково: <ul><li>...

Мне надоело делать меню вручную и я написал небольшой Element, который делает одноуровневое меню, выделяя текущий раздел.

В шаблоне (например, views/layouts/default.ctp) пишется

PHP:
  1. <?=$this->renderElement('menu', array('items'=>array(
  2.     'Главная' => '/',
  3.     'О компании' => '/pages/company',
  4.     'Услуги' => '/services/',
  5.     'Контакты' => '/feedbacks/add',
  6. )))?>

, где ключи - это названия разделов, а значения - пути к разделам в формате Router (то есть array('controller'=>'feedbacks', 'action'=>'add') будет работать).

Это выведет на главной такой код

PHP:
  1. <div class="menu">
  2.     <ul>
  3.         <li class="current">Главная</li>
  4.         <li><a href="/pages/company">О компании</a></li>
  5.         <li><a href="/services/">Услуги</a></li>
  6.         <li><a href="/feedbacks/add">Контакты</a></li>
  7.     </ul>
  8. </div>

Обёрточный div мне советуют делать наши верстальщики, чтобы было легче оформлять его как угодно с помощью CSS. Текущая страница выделена классом current и не является ссылкой. Если вы привыкли верстать по-другому, то код элемента интуитивно понятен.

/views/elements/menu.ctp

PHP:
  1. <div class="menu">
  2.     <ul>
  3.         <? $here = Router::url(substr($this->here, strlen($this->webroot)-1)) ?>
  4.         <? foreach ($items as $name=>$link): ?>
  5.             <? if (Router::url($link) != $here): ?>
  6.                 <li><?=$html->link($name, $link)?></li>
  7.             <? else: ?>
  8.                 <li class="current"><?=$name?></li>
  9.             <? endif ?>
  10.         <? endforeach ?>
  11.     </ul>
  12. </div>

Для стандартной темы CakePHP я вставляю главное меню в #header после h1 и применяю такой CSS:

CSS:
  1. #header {padding-bottom:27px}
  2. #header h1 {height: auto; float:left}
  3. #header div.menu ul {padding-top:0; float:right}
  4. #header div.menu ul li {float:left; list-style:none; font-weight:bold;}
  5. #header div.menu ul li a {color:#dd9; font-weight:normal}
  6. #header div.menu ul li a.current {color:#fff; text-decoration:none}

Вроде получилось в стиле Cake. Что скажете?


Понравилось?

  1. Подпишись через RSS
  2. Расскажи о http://php.southpark.com.ua друзьям.
    Все способы хороши: ICQ, E-mail, свой блог, комментарий в чужом блоге или сообщение на форуме
  3. Добавь статью на news2.ru, Хабрахабр или в закладки

Огромное спасибо!

И не стесняйтесь комментировать - у меня стоит плагин, который убирает rel="nofollow" у людей, которые написали больше 5 комментариев.

RSS feed | Trackback URI

16 комментариев »

2008-02-01 22:46:58

>> Что скажете?
Скажу, что не вижу смысла в замене фигурных скобок на двоеточия. А в остальном -- вполне в стиле кейка. :smile:

Не понял еще смысл двух галок после этой формы.

2008-02-02 08:42:47

> Скажу, что не вижу смысла в замене фигурных скобок на двоеточия
Тут непонятно. В default.ctp они пишут

PHP:
  1. if ($session->check('Message.flash')):
  2.     $session->flash();
  3. endif;

А в flash.ctp

PHP:
  1. <?php if (Configure::read() == 0) { ?>
  2. <meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
  3. <?php } ?>

Видимо можно писать как удобнее :smile:

А о двух галках после формы не совсем понял.

2008-02-02 23:57:50

После формы для отправки комментария стоят две галки. Одна до кнопки "Добавить комментарий", другая после. Описания галок мало чем отличаются.
Одна "Подписаться на следующие комментарии к этой записи по e-mail", а вторая "Отправлять мне следующие комментарии по e-mail". У них все таки разный смысл или один и тот же?

(Comments wont nest below this level)
2008-02-03 09:09:54

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

 
 
 
 
Comment by Дмитрий Subscribed to comments via email
2008-02-02 01:59:43

Симпатично :)

Я чем-то подобным пользуюсь уже давно (правда не для кейка, а для своей самописной системы). Для универсальности кода могу порекомендовать назначать первому и последнему LI классы "first" и "last" (верстальщики будут рады :)).

2008-02-02 23:53:42

+1
Действительно такое просят. Но так как сейчас мне это не нужно, то будем считать, что код опережает время и рассчитан на CSS3 :cool:

 
 
Comment by Deeper
2008-02-02 16:47:47

подскажите неучу откуда вы получаете массив $items в файле menu.ctp. Бьюсь уже целый день не могу понять..

2008-02-02 23:47:49

тут на помощь придёт Антон Исайкин :wink:
http://cake-php.ru/wiki/Manual11/views#h18760-5

 
 
Comment by SeMeN
2008-02-23 14:45:38

Блин, а для меня это вообще тёмный лес, но у меня диплом по WEB и мне просто необходимо разобраться и забацать свой проект. А тема у меня: "Разработка ПО интернет - библиотеки"

 
Comment by Tazman
2008-02-23 23:08:35

Подскажите, а как бы это переписать для пирожка 1.1. А то не хочется в рабочий проект бэту тыкать :) Просто не совсем понял стиль написания (что за двоеточия - это вместо скорок?)

 
Comment by Tazman
2008-02-23 23:11:27

А как переписать данный Element для пирожка 1.1. Просто не хочется бетой пользоваться (пусть подлатают - тогда пересядем ;) )

2008-02-23 23:32:00

К сожалению, не знаю. Уже месяца 3 как у нас перевёли все проекты на CakePHP 1.2
Там хороший код, можно пользоваться.

 
 
2008-04-01 13:56:38

[...] by implementation of menu element for CakePHP I found that I require multilevel menus. Furthermore if should fit [...]

 
Comment by ring0
2008-09-07 14:54:23

Спасибо, интересный пример. Правда я делал такое не через Routers::url

 
Comment by Hektor Subscribed to comments via email
2008-09-23 20:29:09

Не могу найти как сообразить древовидную навигацию из таблицы типа
CREATE TABLE `productions` (
`id` int(11) NOT NULL auto_increment,
`parent` int(11) default '0',
`title` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251

может гуру покажут?

Comment by Дмитрий Subscribed to comments via email
2008-09-24 23:11:56

А в чем проблема?

Вариантов два:
1. Выгрести одним запросом всю таблицу и скриптом отсортировать.
2. Выгребать поэтапно - сначала все записи с parent=0, потом шерстить результат выборки и вытаскивать дочерние элементы.

 
 
Имя (required)
E-mail (required - never shown publicly)
URL
Текст комментария
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.