активный пункт меню, как? [решено]

Главные вкладки

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 7 мая 2010 в 17:15

Здравствуйте, умные люди.

И снова тема выделения текущих пунктов меню, которые создаются заново и не являются ни примари ни секондери, все еще не решена, или мне так кажется потому что я недостаточно долго рылся на этом форуме)).

так вот, как же всетаки классик прибавить?

даже на этом сайте выделение текущего пункта по-калечному организовано, вроде бы оно есть, но как только на внутреннюю страницу к примеру форума переходишь - классик удаляется...

использую nice menu, необходимо чтобы классик текущего пункта, не важно к ребенку списка, либо к самой ссылке добавлялся, причем чтобы сохранялась логика, т.е. если у пункта есть подпункты, и если подпункт на котором находишься является ребенком к основному пункту, то классик должен добавляться как к родительскому пункту, так и к пункту-ребенку, довольно логично, не находите? (:

решил пройтись по ссылкам примеров сайтов использующих найсменю и ужаснулся, там никто тупо не думает о пользователях и не подсвечивает пункты меню))) это жестяк какой-то.

Уважаемые, неужели это так сложно? нужно много программировать чтобы учесть все возможные варианты, или всетаки есть уже, хоть-какое-то более-менее вменяемое решение этой огромной проблемы?

не взыщите если мои возлияния верстальщика покажутся слишком наивными Wink

Комментарии

Аватар пользователя igorek igorek 7 мая 2010 в 18:42

a class="active" добавляется к активной ссылке по умолчанию, год назад делал, по-моему так... Нужно выделить активную ссылку в данный момент, я правильно понял?

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 7 мая 2010 в 19:19

Извините, igorek, но я специально уточнил, что использую модуль nice menu, и прежде чем задавать вопрос все перепроверил.
Также я прокомментировал свою осведомленность насчет того, что по крайней мере в меню построенном на основе секондери линкс класс, обозначающий активный пункт меню присваивается.
Никакого класса, обозначающего активный пункт меню, в созданном меню на основе модуля nice menu не добавляется ни к ребенку списка этого пункта, ни к ссылке, которая в этом эелементе списка находится.

Да Вы правильно поняли, мне нужно присвоить текущему элементу меню класс (в данном случае текущим я называю элемент меню которому соответствует адрес загруженной в браузере страницы).

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 0:18

спасибо, qwaker, поставил модуль, ничего не изменилось(( настроек у модуля нет, тупо ставишь, активируешь и все... видимо с найсменю он не работает, и нужно что-то другое.. вот гадство, я уже и в темплейт пхп функцию запихнул для добавления к этому меню класса для первого и последнего пункта, все работает, и вот на этих активных пунктах кажется какой-то тупик...

может еще кто-нибудь что-нибудь посоветует?

Аватар пользователя qwaker qwaker 8 мая 2010 в 18:53

<a href="mailto:sikwel@drupal.org">sikwel@drupal.org</a> wrote:
спасибо, qwaker, поставил модуль, ничего не изменилось(( настроек у модуля нет, тупо ставишь, активируешь и все... видимо с найсменю он не работает, и нужно что-то другое.. вот гадство, я уже и в темплейт пхп функцию запихнул для добавления к этому меню класса для первого и последнего пункта, все работает, и вот на этих активных пунктах кажется какой-то тупик...

может еще кто-нибудь что-нибудь посоветует?

ну у меня же работает, и именно nicemenu. класс для активного элемента меню active-trail.

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 0:35

да уж, видимо никто не знает универсального решения) странно, этож почти основы юзабилити, неужели в друпале для этого ничего путного нет?:)

вот гражданин видимо тоже разочаровался (: http://www.drupal.ru/node/32800

Аватар пользователя igorek igorek 8 мая 2010 в 11:13

"<a href="mailto:sikwel@drupal.org">sikwel@drupal.org</a>" wrote:
Да Вы правильно поняли, мне нужно присвоить текущему элементу меню класс (в данном случае текущим я называю элемент меню которому соответствует адрес загруженной в браузере страницы).

"igorek" wrote:
a class="active" добавляется к активной ссылке по умолчанию,

Проверил на 6-ке nice_menus 6.x-1.3
У меня всё работает...

Аватар пользователя Xermit Xermit 8 мая 2010 в 14:58

Если все таки не работает, то вот безумная мысль:

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

1) создать свою theme функцию lala_theme_nice_menu_build(поглядеть оригинальную функцию ), зарегестрировать ее
2) поглядеть функцию menu_get_active_trail (и menu_set_active_trail) и поглядеть функцию menu_get_active_title, которая ее использует, чтобы получить заголовок активной страницы из подсистемы меню drupal, там много чего еще оказывается лежит, в частности href текущей страницы. Написать свою
get_active_path. Не забыть, что в href свойстве может быть и alias вместо оригинального url-а. Обратить внимание, что сама функция возвращает как я понимаю целый набор пунктов от корня меню спускаясь до пункта меню, которому соответствует текущая открытая страница
3) в функции из пункта 1), отловить все пункты от корня до текущего активного пункта и проставить в них свойство active

-) к сожалению своих функций nice_menu_item для установки пользовательских классов модуль nice_item не имеет

X) Возможно active не проставляется из-за alias-ов. Например в меню будет именно alias на страницу, а menu_get_active_trail (у меня покрайне мере) возвращает истинный url, т.е. node/xxx, а не alias, соответственно класс active и не появляется, так как не было найдено соответствия. У меня правда еще хуже, у меня несколько alias-ов висит на один node/xxx, а пункт меню также надо было подсвечивать.

X+1) поглядев на функцию menu_get_active_title, могу еще добавить, что прямо как там делать не надо, так как там еще проверка на тип MENU_IS_LOCAL_TASK. Так как там просто заголовок нужен, а не идентификатор активного пункта меню.

X+2) что касается nice_menu я так понимаю это javascript menu без перезагрузки страницы, оно грузица целиком и потмо вы по нему ходите. Только вот в коде модуля я не нашел чего либо чтобы сразу устанавливало свойство активного пункта меню, проставляются только классы определяющие тип пункта меню, дочерний пункт без детей или с детьми. Вероятно пункт меню для открытой страницы открывается средствами самого javascript+jquery. Поэтому вариантов несколько:
1) отключен javascript
2) глючит код javascript для вашего броузера
3) вариант с alias-ом, т.е. javascript видет только alias страницы, а в пункте меню прописан исключительно истинный адрес node/xxx, соответственно javascript не находит пункта меню для страницы и его подсветки не проивзодится.

Правда кода на javascript подсвечивающего пункт меню открытой страницы я тоже что то не нашел.

Я смотрел код nice_menu версии 6.x-1.3


Модуль сам не подсвечивает пункт меню активной страницы и родительские пункты тоже. Т.е. задачка раздваивается, делать это на javascript, но на сайте без alias-ов или делать свою theme_nice_menu_build функцию, установив соответствующий класс, используя функцию menu_get_active_trail для поиска пункта активной страницы и всех ее родительских пунктов.

Аватар пользователя Xermit Xermit 8 мая 2010 в 15:40

Что касается класса active, добавляется он функцией theme_menu_item_link
которая стандартная для drupal, так как она вызывается из nice_menu_build, чтобы создать ссылку. Точнее она вызывает внутри известную функцию l(), которая внутри как раз тоже анализирует _GET('q') и прописывает тот самый active, если ссылка в _GET('q') текущая страница. Посмотрите function l(
в coomin.inc и станет понятно откуда берется .active у ссылок. Но только надо отметить, что он у ссылки, а в nice_menu класс выставляется для ul элемента. Но если дописать какой нить jquery-css типа:
SelectItems{color:f00;}
$('ul:has(a.active)').addClass{SelectItems};
то будет подсвечиваться любой ul, который внутри имеет ссылку с классом active

В jquery не силен, не бить, но что-то типа этого, так как определить класс тольк через css не выйдет, там нет xml селекторов увы.

Есть вероятность что в вашей теме эта функция кем-то еще перебита, потому и не выставляется active.

Как только active будет выставлен, то можно подумать уже о css или javascript методе подсветки всех необходимых пунктов.

Поглядел до кучи menutrails, для меня код весьма сложным оказался для понимания, снова получают меню, ищут в нем текущий пункт, устанавливают хлебные крошки, что-то с таксономией, и organic groups. При этом еще кажется в теме в шаблоне надо что-то указать, чтобы заработало.

Итотого, уверен, что только под windows nice_menu +menutrails потратит ~500 мс на свою работу, учитывая что оба не используют кэширования и в nice_menu явно указано что блок не кэшируется. Это правда можно поправить самому, если вы точно знаете в каких случаях блок будет одинковым для пользователя.

Плюс там тоже делается сравнение _GET['q'] c href из меню,
только вот, что будет если в _GET['q'] у вас синоним, а в подсистмеме меню истинная ссылка node/xxx, он снова не найдет пункт меню и ничего не подсветит.

Правда это наверное у меня одного куча синонимов на один url Smile

Аватар пользователя Sinkora Sinkora 8 мая 2010 в 19:27

"<a href="mailto:sikwel@drupal.org">sikwel@drupal.org</a>" wrote:
да уж, видимо никто не знает универсального решения) странно, этож почти основы юзабилити, неужели в друпале для этого ничего путного нет?:)

Я знаю, как все это делается. Это знают и все нормальные разработчики. И объяснять вам никто не будет, потому что вы ничего не поймете, судя по вашему объему знаний. И дело здесь не в Друпале, а в ваших ручках. Не умеете разрабатывать вебприложения - нанимайте специалистов.

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 17:52

да уж, спасибо всем, теперь я понял, что с активными пунктами меню одному мне - верстальщику не справится без программиста-друпаллера. Разделение труда дает о себе знать) будешь начинать разбираться еще и с программированием помимо верстки - потеряешь профессионализм. Оказывается такая простая и необходимая на каждом сайте функция меню не так то просто дается даже программистами...

Аватар пользователя Xermit Xermit 8 мая 2010 в 20:54

1) убедитесь через firebug или другим способом, что у нужной ссылки стоит class active, как я уже сказал, nice_menu дергает нужную функцию и он там должен быть класс
2) найти в вашей теме css и проглядеть все стили для .active
я вот к примеру для гарланд нашел такой кусочек:

ul.primary-links li a:hover, ul.primary-links li a.active {
color: #fff;
background: transparent url(images/bg-navigation-item-hover.png) no-repeat 50% 0;
}

этот класс написано для тэга a, который в составе ссылки, вам же надо как я понял разукрасить, не только a, но и li

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

class_blocka_menu ul li a.active{color:#fff}

class_blocka_menu - вот это очень хитро генерируется в nice_menu, лично я понял, что если пользователь авторизован, то
class_blocka_menu будет совпадать с именем пользователя, если нет, то по умолчанию 'Nice Menu номер_меню_если_их_несколько (Nice Menu)' или тому, что вы указали в настроках nice_menu в поле 'Menu Name', убил бы, они даже не транслитилировали насколько я понимаю его, а потом используют в качестве класса к блоку.

Лучший вариант

кроме того обычно все блоки, по крайне мере если поглядеть block.tpl.php в теме garland, выводится в div с классом

module .'-'. $block->delta; ?>" class="clear-block block block-<?php print $block->module ?>">

т.е. я так понимаю можно просто прописать такой css
block-nice_menus ul li a.active{color:#fff}

А чтобы изменить свойства ul, нужно использовать jquery как я указал выше, так как нельзя выделить ul элемент, который родительский по отношению к a.active.

Но это подсветит только одну ссылку, но не родительcкие ссылки, чтобы подсветить родительcкие тоже придется делать через jquery.

Но сначала убедиться что у ссылки все же выставлен класс .active, сама подсветка может и не работать при этом, но класс должен быть, его не может не быть. Точнее его может не быть если url в заголовке страницы не совпадает с тем url-ом, который вы выбираете в меню.

И еще, без анализа кода php вам не разобраться. Так как если что-то не работает, то придется разбираться почему, а причины все кроются во внутренностях.

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 22:02

Господи боже мой, qwaker.
Как же это у вас может работать а у меня нет?
Может я что-то не так делаю?

Зашел в админку, создал свое меню, потом вывел блок nice menu и указал ему источник - мое только что созданное меню.

первому пункту своего меню, задал ссылку на корень сайта. т.е. при переходе на главную страницу сайта, первому пункту по вашим словам должен присваиваться класс active-trail, но ничего не присваивается, как с включеным модулем Menu Trails, так и без него...
вот что у меня в адресной строке браузера:http://drupal/
а вот как на этой странице выглядит html код меню:

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 22:15

уважаемый, Xermit, я верстальщик, не нужно мне объяснять как верстать, я эту тему открыл, потому что класс как таковой php на сервере не генерируется и не вставляется в html. или это я что-то не так делаю, но вроде бы ссылки то совпадают, та что в меню и реальная...

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

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

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 8 мая 2010 в 22:21

"qwaker" wrote:
Вы скорее всего сюды не заходили, или не выставили чаго? /admin/build/menu/trails
заходил, в списке Menutrails Menu: выбрано именно мое созданное меню.

Аватар пользователя Sinkora Sinkora 8 мая 2010 в 22:35

"<a href="mailto:sikwel@drupal.org">sikwel@drupal.org</a>" wrote:
но если я делаю свое меню не на их основе, то к активному пункту никакого класса не добавляется.

Расскажите, на основе чего делаете свое меню, прежде чем задавать вопросы. "Подсвечивание" ссылок - это задача, которая не должна быть универсальной, у каждого своя структура разделов на сайте. Добавлять атрибут типа "active" для активных ссылок, а также для всех родительских, можно в php-скриптах на уровне темизации или через джаваскрипт. Но если на вашем сайте запутанная логика, то в коде нужно учитывать все возможные варианты.

Кстати, возможны ситуации, когда для того чтобы построить "ветвь активных ссылок от дочерних до родительских", нужно делать лишнее обращение к БД, чтобы определить, к какому типу, к какому термину, к какому разделу и т.д. принадлежит текущая страница. Поэтому, если вы на этом сайте находитесь на странице топика, то не совсем целесообразно подсвечивать ссылку "Форум" в главном меню, в противном случае нужно было бы делать дополнительную проверку в коде (а оно сильно надо?).

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 0:22

Меню я создаю через админпанель друпала, отдельно каждый пункт, для каждого пункта задаю ссылку, иерархия меню простая: несколько пунктов первого уровня и некоторые пункты являются родительскими с подпунктами. дальше подпунктов родительских пунктов детализации нет. все пункты ссылаются на ноды, кроме пункта главной, в которой просто прописан адрес сайта.

кастомизирую я свое меню с помощью модуля nice menus 6.x-1.3

Аватар пользователя Xermit Xermit 9 мая 2010 в 1:07

Вот в этой теме
http://drupal.org/node/465738
на которую qwaker указал патч содержит код который как раз похож на то о чем я говорил в первых постах,
там в патче сначала собираются все пункты которые должны стать menutrails, а потом прописывает им этот класс.

так как в обычном nice_menu-6.x-1.3 этого нету.

но, я что хотел сказать, в функции nice_menu_build, чтобы создать ссылку вызывается стандартная theme_menu_item от друпала, а она в свою очередь зовет l(), код функции l():

function l($text, $path, $options = array()) {
  global $language;

  // Merge in defaults.
  $options += array(
      'attributes' => array(),
      'html' => FALSE,
    );

  // Append active class.
  if (($path == $_GET['q'] || ($path == '<front>' && drupal_is_front_page())) &&
      (empty($options['language']) || $options['language']->language == $language->language)) {
    if (isset($options['attributes']['class'])) {
      $options['attributes']['class'] .= ' active';
    }
    else {
      $options['attributes']['class'] = 'active';
    }
  }

Но у вас класс active так и не появился почему то.
Смею предположить что в _GET['q'] для корня сайта ничего не находится, так как там должна быть пустота, а в path для пункта меню не содержится <front>, так как вы явно указали http://drupal ? А надо было для такого пункта меню передать <front> или вы как раз так и сделали?

Для более корректного теста, сделайте пустую страницу с своим адресом, а потом посмотрите пункт меню для этой странице находясь на этой странице он по идее должен быть уже с классом .active.

а самое лучшее распечатать _GET['q'] и $path, который передается в theme('menu_item_link')...) в функции nice_menu_build, там кажется всего два таких места.

Аватар пользователя qwaker qwaker 9 мая 2010 в 11:21

sikwel@drupal.org, специально сейчас попробовал патч, указанный здесь http://drupal.org/node/465738. Всё замечательно работает

Если не лады с английским:
1. Качаете патч с 11-го коммента приведенной выше страницы
2. пропатчиваете модуль nicemenu (о том, как это делать, еси не в курсе - указано здесь
3. После этого вы работаете с классом active-trail и темизируете как надо:
3.1. для дочерних меню класс active-trail
3.2. для родительских menuparent active-trail.

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 17:10

"qwaker" wrote:
sikwel@drupal.org, специально сейчас попробовал патч, указанный здесь http://drupal.org/node/465738. Всё замечательно работает

у меня наверное друпал заколдованный)) проделал все как вы сказали - никакого класса не появилось))
я уже и ноду повесил на пункт меню чтобы убедиться, нифига, перехожу на эту ноду и никакого класса не добавляется...

потратил даже пару часов чтобы разобраться как патчить через patch под винду))
потом еще и руками все перерпроверил, файл пропатчился все замечательно, но ничего не работает))

Аватар пользователя Xermit Xermit 9 мая 2010 в 17:17

Все кэширующее и оптимизирующее выключено? Начни с простого, в nice_menu_build впиши ручками куда нибудь print('AAAA'), просто, чтобы убедится, что твои изменения в этом файле отражаются на выводе друпала, если нет, то ты не тот файл возможно редактируешь.

надеюсь у тебя не включен APC и eAccelerator в php c флагом mktime='0', иначе даже после рестарта апача кэшириующий оптимизатор не поймет что php код давно обновился и по прежнему будет загружать старый закэшированный код.

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 17:32

"Xermit" wrote:
Начни с простого, в nice_menu_build впиши ручками
хм, а можно поподробнее куда именно? в функцию под этим именем?

да вроде никакого сверхъестественного кеширования у меня не включено, к примеру изменяю файл темплейт пхп (переопределяю функцию темизации найс меню для вывода классов для первого и последнего пунктов) и все тут же изменяется. (эту функцию темизации на время попыток отобразить класс активного меню я убрал от греха подальше)

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 17:35

кстати, когда я перехожу на ноду, в цепочке навигации она ведь должна отображаться? у меня почему-то там как была домашняя страница(Home › ) , так и осталась...

Аватар пользователя qwaker qwaker 9 мая 2010 в 17:42

"<a href="mailto:sikwel@drupal.org">sikwel@drupal.org</a>" wrote:
потом еще и руками все перерпроверил, файл пропатчился все замечательно, но ничего не работает))

Ну смотрите: если пропатчился, значит по любому есть класс active-trail. Тут даже ведь и ошибиться негде.
Возьмите firebug, и посмотрите, какой класс присваивается активным пунктам меню -родительскому и дочернему?

Аватар пользователя Xermit Xermit 9 мая 2010 в 18:04

в любом месте той функции nice_menu_build, она в nice_menu.module

впишите print('AAA'), если в начале страницы вы увидите AAA
то значит все норм и ваш патч наложился и все должно работать,
только я думаю может у вас кэшируется это и в результате выполняется либо старый код от nice_menu
либо вы не в том месте файл пропатчили

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 20:47

создал простое меню на основе секондери линкс в блоке, вывел туда ноду, все прекрасно работает, модуль меню трейл добавляет класс активного пункта (элемента списка li), также класс по-умолчанию для секондери добавляется к ссылкe. В моем меню по-прежнему к этому пункту ничегоне добавляется... значит не работает в моих условиях этот патч(

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 21:05

Провел еще один эксперимент, применил модуль найсменю к этому меню которое на секондери линкс, как известно у секондери линкс активный класс добавляется по-умолчанию без каких бы то нибыло модулей к тегу ссылки, просто active. Я вывел этом меню через блок модуля найсменю, который был пропатчен и вуаля, у элемента li активного пункта, добавлися класс active-trail.
Беру и заменяю пропатченный файл найсменю на родной, который без изменений. перегружаю страницу и вижу - класс active-trail благополучно исчез, остался только по-умолчанию который у ссылки...

вот такие вот дела... патч и модуль работают.. значит дело в созданном мною меню... а создавал я его правильно..

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 21:29

ИТС ЭЛАЙВ!!!))) Мытарства окончены))) дело было опять в мелочи и моих кривых руках))

я в пункте меню на главную и на ноду ставил полный путь, т.е. http://drupal/node/6, а если так задавать, то ничего не работает)

поставил на ноду: node/6
на главную: <front>

и все прекрасно заработало, класс добавляется))

спасибо всем огромное за ответы и терпение (;

Аватар пользователя sikwel@drupal.org sikwel@drupal.org 9 мая 2010 в 21:33

"Xermit" wrote:
эх, а ведь говорил проверьте соответствие, что в _GET['q'] и что в меню указываете.
видимо Вы слишком мудрено об этом говорили и мой неокрепший мозг верстальщика не воспринял эту суровую информацию:)

Аватар пользователя CITY_beta CITY_beta 15 декабря 2017 в 13:27

Скачиваешь "Menu position" и выбираешь свои меню, создаешь их и ставишь галочку на "Mark the rule's parent menu item as being "active"."ВсеЮ проблема решена, работает.