Меню аккордеон на CMS 2

#16 17 декабря 2014 в 22:40
Вы сдесь пока ла-ла-да-ла-ла… Сел и сделал гармонь-меню за полчаса.
Если интересует как самостоятельно выполнить? Оформлю пост .
PS//Это ла-ла-да-ла-ла образно, Не принимать за личную обиду!
#17 17 декабря 2014 в 22:56
Как сделать аккордеон меню пользователя InstantCms версия 2?
Поскольку есть одна функция menu, к которой обращаемся при выводе ВСЕХ меню ( верхнего, нижнего, меню действий, меню пользователя и так далее). Все меню выводит один шаблон.
То стоит вопрос для использования своих хаков для меню (именно "Персональное меню" — в нашем случае),
нам необходим свой шаблон отличный от системного.
Выполняем хак файла core/template.php. Меняем функцию menu на эту:
  1.  
  2. /**
  3.   * Выводит меню
  4.   */
  5. public function menu($menu_name, $detect_active_id=true, $css_class='menu', $max_items=0, $is_allow_multiple_active=false){
  6.  
  7. $core = cmsCore::getInstance();
  8. $config = cmsConfig::getInstance();
  9.  
  10. if (!isset($this->menus[$menu_name])) {
  11. $menu_model = cmsCore::getModel('menu');
  12. $menu = $menu_model->getMenu($menu_name, 'name');
  13. if (!$menu){ return; }
  14. $items = $menu_model->getMenuItemsTree($menu['id']);
  15. if (!$items){ return; }
  16. $this->addMenuItems($menu_name, $items);
  17. }
  18.  
  19. $active_ids = array();
  20.  
  21. if ($detect_active_id){
  22.  
  23. $current_url = trim($core->uri, '/');
  24.  
  25. if ($menu_name == 'main'){
  26. // dump($this->menus[$menu_name]);
  27. }
  28.  
  29. //перебираем меню в поисках текущего пункта
  30. foreach($this->menus[$menu_name] as $id=>$item){
  31.  
  32. if (!isset($item['url']) && !isset($item['controller'])) { continue; }
  33.  
  34. if (!isset($item['url'])) {
  35. if (!isset($item['action'])) { $item['action'] = ''; }
  36. if (!isset($item['params'])) { $item['params'] = array(); }
  37. $item['url'] = href_to($item['controller'], $item['action'], $item['params']);
  38. $this->menus[$menu_name][$id]['url'] = $item['url'];
  39. $menu[$id] = $item;
  40. }
  41.  
  42. $url = isset($item['url_mask']) ? $item['url_mask'] : $item['url'];
  43. $url = mb_substr($url, mb_strlen($config->root));
  44. $url = trim($url, '/');
  45.  
  46. if (!$url) { continue; }
  47.  
  48. //полное совпадение ссылки и адреса?
  49. if ($current_url == $url){
  50. $active_ids[] = $id;
  51. $is_strict = true;
  52. } else {
  53.  
  54. //частичное совпадение ссылки и адреса (по началу строки)?
  55. $url_first_part = mb_substr($current_url, 0, mb_strlen($url));
  56. if ($url_first_part == $url){
  57. $active_ids[] = $id;
  58. $is_strict = false;
  59. }
  60.  
  61. }
  62.  
  63. }
  64.  
  65. }
  66.  
  67. if (!$is_allow_multiple_active && (count($active_ids)>1)){
  68. $active_ids = array($active_ids[count($active_ids)-1]);
  69. }
  70. if(isset($menu['id'])){
  71. if($menu['id']==2){
  72.  
  73. $this->renderUsrMenu($this->menus[$menu_name], $active_ids, $css_class, $max_items);
  74. }
  75. else{
  76. $this->renderMenu($this->menus[$menu_name], $active_ids, $css_class, $max_items);
  77. }
  78. }
  79. else{
  80. $this->renderMenu($this->menus[$menu_name], $active_ids, $css_class, $max_items);
  81. }
  82.  
  83. }
  84.  
  85.  
Что в ней реализовано?
Если id меню не 2 ( тоесть Меню пользователя) и это меню Действий( id не имеет)- то рендерим обычный шаблон menu.tpl
Если это меню пользователя- то рендерим свой шаблон usr_menu в котором мы и определим нужную нам обработку js script.А также подключим js css файлы.
И создадим свою функцию рендер добавив в файл.core/template.php код функции

  1.  
  2. public function renderUsrMenu($menu, $active_ids=array(), $css_class='menu', $max_items=0){
  3.  
  4. $tpl_file = $this->getTemplateFileName('assets/ui/usr_menu');
  5.  
  6. include($tpl_file);
  7.  
  8. }
  9.  
  10.  
Эта функция аналогична штатной только отрисовывает другой шаблон.
Собственно и все.
Файл шаблона

  1.  
  2. <?php
  3. $this->addJS('templates/default/js/jquery.cookie.js');
  4. $this->addJS('templates/default/js/jquery.hoverIntent.minified.js');
  5. $this->addJS('templates/default/js/jquery.dcjqaccordion.2.7.min.js');
  6. $this->addCSS('templates/default/css/skins/blue.css');
  7. //$this->addCSS('templates/default/css/skins/graphite.css');
  8. //$this->addCSS('templates/default/css/skins/grey.css');
  9. ?>
  10. <script type="text/javascript">
  11. $(document).ready(function($){
  12. $('#accordion-1').dcAccordion({
  13. eventType: 'click',
  14. autoClose: true,
  15. saveState: true,
  16. disableLink: true,
  17. speed: 'slow',
  18. showCount: true,
  19. autoExpand: true,
  20. cookie : 'dcjq-accordion-1',
  21. classExpand : 'dcjq-current-parent'
  22. });
  23. $('#accordion-2').dcAccordion({
  24. eventType: 'click',
  25. autoClose: false,
  26. saveState: true,
  27. disableLink: true,
  28. speed: 'fast',
  29. classActive: 'test',
  30. showCount: true
  31. });
  32. $('#accordion-3').dcAccordion({
  33. eventType: 'click',
  34. autoClose: false,
  35. saveState: false,
  36. disableLink: false,
  37. showCount: false,
  38. speed: 'slow'
  39. });
  40. $('#accordion-4').dcAccordion({
  41. eventType: 'hover',
  42. autoClose: true,
  43. saveState: true,
  44. disableLink: true,
  45. menuClose: false,
  46. speed: 'slow',
  47. showCount: true
  48. });
  49. $('#accordion-5').dcAccordion({
  50. eventType: 'hover',
  51. autoClose: false,
  52. saveState: true,
  53. disableLink: true,
  54. menuClose: true,
  55. speed: 'fast',
  56. showCount: true
  57. });
  58. $('#accordion-6').dcAccordion({
  59. eventType: 'hover',
  60. autoClose: false,
  61. saveState: false,
  62. disableLink: false,
  63. showCount: false,
  64. menuClose: true,
  65. speed: 'slow'
  66. });
  67. });
  68. </script>
  69. <div class="blue">
  70. <ul class="accordion" id="accordion-3">
  71.  
  72. <?php if ($max_items){
  73.  
  74. //
  75. // Считаем количество пунктов первого уровня
  76. //
  77. $first_level_count = 0;
  78. $first_level_limit = 0;
  79. $index = 0;
  80. foreach($menu as $item){
  81. if ($item['level']==1){ $first_level_count++; }
  82. if ($first_level_count > $max_items && !$first_level_limit){ $first_level_limit = $index; }
  83. $index++;
  84. }
  85.  
#18 17 декабря 2014 в 23:04
Файл шаблона usr_menu разместить в templates/default/assets/ui/user_menu.tpl.php
Файлы js /templates/default/js/
Файлы css /templates/default/css/
Выбирайте сами тип меню их 6, Просто ид блока указав accordion-1 или accordion-3 или accordion-6
ну и стили уж как нибудь под свои нужды сами.

Не претендую на красоту решения. Другого пути пока не вижу!
#19 17 декабря 2014 в 23:44

Другого пути пока не вижу!

Геннадий Иванович
Нет необходимости делать хаки системных файлов. Свой шаблон меню тоже не нужен (ну или я не увидел в вашем описании почему без него нельзя обойтись).

Ваш шаблон ведь в плане верстки по сути идентичен системному (да и глобально, вообще, практически любому меню на любом сайте) — он генерирует ul-li список. А привязать JS и CSS можно в основном шаблоне сайта (main.tpl.php), который может быть уникальным и для этого не требуется вмешательство в ядро. Выбирать нужное меню в JS можно по css-классу виджета.

Вы сдесь пока ла-ла-да-ла-ла… Сел и сделал гармонь-меню за полчаса.

Геннадий Иванович
Вот за это — уважение.
#20 18 декабря 2014 в 00:02

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

r2
Уважаемым R2! Мне спорить не к лицу.
Сделаю робкое обьяснение.
Для использования всех этих гармоней… необходим и класс и селектор id блока. Вот именно для одного меню,
Стандартный шаблон имеет
  1. <ul class="<?php echo $css_class; ?>">
только класс.menu для всех меню. И изменить класс или добавить id нет возможности.
Тоесть если я добавлю
  1. <ul class="accordion" id="accordion-3">
в штатный шаблон, я получу все меню аккордеон что неправильно.
#21 18 декабря 2014 в 00:07

Ваш шаблон ведь в плане верстки по сути идентичен системному (да и глобально, вообще, практически любому меню на любом сайте) — он генерирует ul-li список. А привязать JS и CSS можно в основном шаблоне сайта (main.tpl.php), который может быть уникальным и для этого не требуется вмешательство в ядро. Выбирать нужное меню в JS можно по css-классу виджета.

r2
Что много писать, Лучше практически реализацию увидеть.
#22 18 декабря 2014 в 00:22
r2, есть просьба прислушаиться — каждый виджет снабдить выбором шаблона (и про контент очень желательно не забыть).
Fuze, ещё раз спасибо, что это уже есть в первой ветке!
Геннадий Иванович, я там и пытался освоить создание возможности выбора шаблона для виджета (аккордион просто для примера)
#23 18 декабря 2014 в 00:50
Геннадий Иванович, меню выводятся виджетами. Виджету можно добавить класс через админку.
Найти элемент ведь можно не только по id. Есть масса способов как составить селектор

Если не считать виджеты, то можно, например, присвоить класс любому корневому пункту в нужном меню, через админку.
Например, класс accordion-1. Тогда найти само меню можно будет так:
  1. $('li.accordion-1').parent('.menu')
#24 18 декабря 2014 в 01:00

r2, есть просьба прислушаиться — каждый виджет снабдить выбором шаблона (и про контент очень желательно не забыть).

Олег Васильевич я
Будет со временем.

Fuze, ещё раз спасибо, что это уже есть в первой ветке!

Олег Васильевич я
В первой ветке это делал я )

Мне спорить не к лицу.

Геннадий Иванович
Я же не ради спора, а для консультации. Править системные файлы плохо, по понятным причинам. Поэтому я и подсказываю как можно обойтись без них.
#25 18 декабря 2014 в 07:12
r2, Хотелось бы увидит возможность, установки CSS класса в меню, не к пунктам меню а в самом меню, типа Персональное меню, Главное меню, Верхнее меню и т.д.
Сейчас там можно изменить только название меню, хотелось бы туда еще поле класс добавить и передать в файл \templates\default\assets\ui\menu.tpl.php
Там ведь первая строчка кода, от куда то получает css класс 'menu' — только не знаю от куда.
  1. <ul class="<?php echo $css_class; ?>">
#26 18 декабря 2014 в 09:00

В первой ветке это делал я )

r2
Извините, — думал что вы ведёте двойку а единичку — Fuze. shock
Спасибо!
#27 18 декабря 2014 в 13:55

r2, Хотелось бы увидит возможность, установки CSS класса в меню, не к пунктам меню а в самом меню

Evanescence
Да, я уже об этом думаю

Извините, — думал что вы ведёте двойку а единичку — Fuze.

Олег Васильевич я
Сейчас уже так оно и есть.
#28 18 декабря 2014 в 18:27

Там ведь первая строчка кода, от куда то получает css класс 'menu' — только не знаю от куда.
Код PHP:

<ul class="<?php echo $css_class; ?>">

Evanescence
Evanescence, этот класс получается отсюда \templates\default\widgets\menu\menu.tpl.php
#29 18 декабря 2014 в 18:50

Собственно и все.

Геннадий Иванович
Попробовал я Ваш способ. В итоге в левом верхнем углу остались иконка пользователя и никнейм из шапки меню пользователя и больше ничего:)
Если в
  1. if($menu['id']==2){
поменять 2 на любое другое значение, то возвращается в исходное положение весь сайт. В чем проблема?
#30 18 декабря 2014 в 18:53

Evanescence, этот класс получается отсюда \templates\default\widgets\menu\menu.tpl.php

Atid — Gorec
В шаблоне уже идет представление класса а определение идет в функции menu.
Этот класс принудительно указан в функции public function menu class cmsTemplate
  1.  
  2. public function menu($menu_name, $detect_active_id=true, $css_class='menu',
  3.  
И изменить $css_class='menu' пока невозможно.
Я удаляю описание класса в шаблоне меню у элемента ul. и получаю развязанные руки в стилях для всех меню.
Есть предложение для использования личных шаблонов и классов для меню
Сейчас оформляю.
Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.