Место для вас

Cоздание многоуровнего меню для Yii 2

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

В Yii за формирование меню отвечает готовый виджет. И чтоб сделать многоуровневое меню нужно просто рассписать все пункты руками. Это хорошо когда заранее известна структура меню и вы уверенны, что она изменяться уже не будет.

Но что делать если этого не известно??? Либо пытаться изобретать велосипед и самому создавать виджет. Лиюо качать готовые расширения для Yii и потом их править под свои нужды. Или воспользоваться моим протым решением, которое получает меню из БД и вставляем в готовый виджет меню от Yii.

Я не буду описывать, как добавить сам виджет для отображения меню. Тут кто как хочет так и делает.

Сделаю помарку: покажу пример для Yii 2

Сперва мы выводим меню:


use yii\widgets\Menu;
use app\models\TopMenu;
echo Menu::widget([
	'options' => ['class' => 'clearfix', 'id'=>'main-menu'],
	'encodeLabels'=>false,
	'activateParents'=>true,
	'activeCssClass'=>'current-menu-item',
	// подключаем модель и  вызываем метод,  который строит всю логику формирования меню
	'items' => app\models\TopMenu::viewMenuItems(),
]);

А вот сами  методы, которые делают всю работу и логику:


/***************START generate my top menu****************/
private static function getMenuItems()
{
	$items = array();
	$resultAll = TopMenu::find()->orderBy('position')->all();

	foreach($resultAll as $result)
	{
		if(empty($items[$result->parentid]))
		{
		$items[$result->parentid] = array();
		}
		$items[$result->parentid][] = $result->attributes;
	}
	return $items;
}

public static function viewMenuItems($parentId=0) { $arrItems = TopMenu::getMenuItems(); if(empty($arrItems[$parentId])) {return;} for($i = 0; $i<count($arrItems[$parentId]); $i++) { $result[] = [ 'label' => $arrItems[$parentId][$i]['name'], 'url' => [$arrItems[$parentId][$i]['seolink']], 'linkOptions'=> ['title'=>$arrItems[$parentId][$i]['name']], 'items' => TopMenu::viewMenuItems($arrItems[$parentId][$i]['id']), 'options' => ['class'=>$arrItems[$parentId][$i]['classa']], ]; } return $result; } /***************END generate my top menu****************/

Вот и все. за деталями обращайтесь в коментах =)

Как видно,  создание автоматического многоуровнего меню не так уж и сложно.


Место для вас

Коментарии

добавить коментарий

  1. Александр Булатов - 03 августа, 2017 в 08:39:39

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

    Уже все способы перепробовал всю документацию наверно облазил, а Ваш способ отлично сделал свою работу!

    Ещё раз спасибо!

  2. Александр Булатов - 03 августа, 2017 в 08:39:36

    Только не могли бы Вы пояснить, почему срабатывает передача параметра $parentId = 0, ведь при итерации в цикле for он не увеличивается, а остаётся не изменным?

    • adminer - 03 августа, 2017 в 08:39:54

      Александр Булатов, спасибо. смотрите. в методе viewItems у мемя есть рекурсия. $parentId=0 указывает на супер главного родителя

    • Александр Булатов - 04 августа, 2017 в 14:08:32

      adminer, понял.


      А ещё один вопрос, если не возражаете, есть у Вас идеи, как в данном коде передать параметра, который бы ещё определял меню, которое нужно выводить?

      Я вот такой код добавил в метод getMenuItems




      $code = 'top-menu';


      $query_menu = MenuModel::find() ->andWhere(['code' => $code, 'status' => 1]) ->one();



      А выборку потом делаю с добавлением




      andWhere(['id' => $query_menu->id])



      Но выдаёт ошибку при передаче get-параметра.

    • adminer - 11 августа, 2017 в 13:17:59

      Александр Булатов, что за ошибка у вас?

  3. Александр Булатов - 15 октября, 2017 в 13:36:19

    Прошу прощения, что только сейчас написал.
    У меня получается следующим образом (названия функций и некоторые переменные я изменил):

    В отображении у меня сейчас так

    'items' => Choice_Menu::viewMenuItemsTop( 0, 'bottom-menu'),

     

    В методе viewMenuItemsTop

    public static function viewMenuItemsTop($parentId, $nameMenu)
    ,

    $array = self::getMenuItemsTop($nameMenu);


    А в методе

    private static function getMenuItemsTop($nameMenu)


    $code = $nameMenu;

            

            $query_menu = MenuModel::find()

                            ->andWhere(['code' => $code, 'status' => 1])

                            ->one();



    И в браузере такое сообщение

    issing argument 2 for app\modules\manager\models\Choice_Menu::viewMenuItemsTop(), called in C:\OpenServer\domains\yii2-cms-basic.loc\modules\manager\models\Choice_Menu.php on line 62 and defined

    И чтобы я не делал он всё равно говорит, что нехватает второго аргумента.

    • админер - 15 октября, 2017 в 13:38:25

      Александр Булатов, а можно в студию строку 62 ?

  4. Александр Булатов - 15 октября, 2017 в 16:21:30

    Строка 62 это строчка 

    'items' => self::viewMenuItemsTop($array[$parentId][$i]['id'])

    И чтобы был понятен контекст то полный код метода, где эта строчка

    public static function viewMenuItemsTop($parentId, $nameMenu)

        {        

            $array = self::getMenuItemsTop($nameMenu);

            

            if ( empty($array[$parentId]) ) { return; }

            

            for ( $i = 0; $i < count($array[$parentId]); $i++ )

            {

                $result[] = [

                    'label' => $array[$parentId][$i]['name'],

                    'url' => [$array[$parentId][$i]['url_item'].'/index'],

                    'items' => self::viewMenuItemsTop($array[$parentId][$i]['id'])

                ];

            }

            

            return $result;

        }

  5. Александр Булатов - 15 октября, 2017 в 16:21:32

    ))))
    Ну это я конечно выкинул)))
    Когда Вам написал, то увидел, где абсолютно глупая ошибка)

    Нужно вот так оформить 62 строчку:


    'items' => self::viewMenuItemsTop($array[$parentId][$i]['id'], $nameMenu)

    • админер - 15 октября, 2017 в 16:21:35

      Александр Булатов, ага. все верно. не хватало. успехов. будут вопросы, то обращайтесь

  6. Ярослав - 05 января, 2018 в 15:00:56

    Недоработанное меню. Подучить надо PHP, а потом выкладывать

    • adminer - 05 января, 2018 в 15:04:32

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

Добавить коментарий

Что за сайт

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

Будь в курсе

Интересненько

Вверх