Задать вопрос
Lumore
@Lumore
Front-end developer

Как задать метод POST ссылке в классе Menu yii2?

Взял класс Menu.php с официальных доков yii2, и при написании ссылок меню столкнулся с такой проблемой:
При переходе по адресу /site/logout, выходит такая ошибка: Method Not Allowed (#405).
Окей, полез в гугл, понял в чем проблема но не смог ее исправить.

Пытался сделать так:
['label' => 'Logout', 'url' => ['site/logout'], 'visible' => !Yii::$app->user->isGuest, 'linkOptions' => ['data-method' => 'post']]

но не получилось.
Можно кончено залезть в конфиг и перенаправить на GET, но мне это не нравится. Кто сталкивался, помогите.
  • Вопрос задан
  • 4039 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@AKtor
Я считаю, что лучше будет следующий вариант, так как не заменяет, а дополняет метод renderItem() родителя и рендерит аттрибуты с помощью Html::renderTagAttributes(), так как это делает виджет Nav:

<?php

namespace app\components\widgets;

use yii\helpers\ArrayHelper;
use yii\helpers\Html;

class Menu extends \yii\widgets\Menu
{
    public $linkTemplate = '<a href="{url}"{attr}>{label}</a>';

    protected function renderItem($item)
    {
        $template = parent::renderItem($item);

        if (isset($item['url'])) {
            $template = strtr($template, [
                '{attr}' => Html::renderTagAttributes(ArrayHelper::getValue($item, 'linkOptions', [])),
            ]);
        }

        return $template;
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@homsterius
Столкнулся с такой же проблемой и так как в классе \yii\widgets\Menu необходимый функционал не нашёл, решил просто дописать :)
Может кому пригодится
<?php

namespace app\widgets;

use yii\helpers\ArrayHelper;
use yii\helpers\Html;

class Menu extends \yii\widgets\Menu
{
    public $linkTemplate = '<a href="{url}"{attr}>{label}</a>';

    public $linkOptions = [];

    protected function renderItem($item)
    {
        if (isset($item['linkOptions'])) {
            $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);

            $linkOptionsStr = ' ';
            foreach ($linkOptions as $key => $value) {
                $linkOptionsStr .= $key.'='.$value.' ';
            }

            $this->linkTemplate = strtr($this->linkTemplate, [
                '{attr}' => Html::encode($linkOptionsStr)
            ]);
        } else {
            $this->linkTemplate = strtr($this->linkTemplate, [
                '{attr}' => ''
            ]);
        }
        return parent::renderItem($item);
    }
}
Ответ написан
Snorway
@Snorway
Можно сделать так, не идеально, но без дописывания функционала:
['label' => 'Logout', 'url' => ['site/logout'], 'template' => '<a href="{url}" data-method="post">{label}</a>'],
Ответ написан
Комментировать
@sehav
Код неправильный
После первой замены атрибутов, все остальные ссылки пойдут с этим атрибутом

Мое решение
<?php

namespace app\widgets;

use yii\helpers\ArrayHelper;
use yii\helpers\Html;

class Menu extends \yii\widgets\Menu
{
    public $linkTemplate = '<a href="{url}"{attr}>{label}</a>';

    public $linkOptions = [];

    protected function renderItem($item)
    {
        $template = ArrayHelper::getValue($item, 'template', $this->linkTemplate);
        $replace=[
            '{label}' => $item['label'],
            '{attr}'=>'',
            '{url}'=>''
        ];

        if (isset($item['url'])) {
            $replace['{url}']=Html::encode(Url::to($item['url']));
        }

        if (isset($item['linkOptions'])) {
            $replace['{attr}']=$item['linkOptions'];
        }

        return strtr($template, $replace);
    }
}


Есть возможность добавить еще какие-либо атрибуты, классы например
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы