Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 02.04.2015 12:39:07

Меню

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

Не в сети

#2 02.04.2015 14:46:10

Re: Меню

Сделал так:
Для вывода меню используется таблица Page
Создаем свой провайдер ViewComposerServiceProvider, в него помещаем:

<?php namespace App\Providers;

use Html;
use Illuminate\Support\Facades\Request;
use App\Page;
use Illuminate\Support\ServiceProvider;

class ViewComposerServiceProvider extends ServiceProvider {

	public function boot()
	{
        $this->composerNavigation();
        $this->isActive();
    }

	public function register()
	{
        //
	}

    //Главное меню
    private function composerNavigation()
    {
        view()->composer('partials.mainmenu', function ($view) {
            $view->with('pages', Page::latest('published_at')->published()->paginate(5));
        });
    }

    //Проверка на активный путь меню
    private function isActive()
    {
        HTML::macro('isActive', function ($url) {
            $segments = explode('/', Request::path());
            foreach ($segments as $segment) {
                if ($url == $segment) return 'active';
            }
            return '';
        });
    }

}

Здесь мы выводим наше меню через view()->composer и создаем макрос для проверки URL.
Добавляем наш провайдер в config\app.php

'App\Providers\ViewComposerServiceProvider',

Далее создаем вьюху mainmenu, в которую помещаем следующий код:

@if ($pages->count())
<nav class="mainmenu">
    <ul>
@foreach($pages as $page)
        <li>{!! link_to_action('PagesController@show', $page->title, [$page->url], ['class' => HTML::isActive($page->url)]) !!}</li>
@endforeach
    </ul>
</nav>
@endif

Теперь можно инклудить наше меню куда угодно.

Изменено Johnson (02.04.2015 14:47:39)

Не в сети

#3 02.04.2015 14:55:24

Re: Меню

что-то как-то сложно. без HTML наверное меньше кода бы было — фактически мы же просто проверяем на совпадение url. я бы написал простой хелпер, положил его в helpers.php и было бы xml<a href="{{ $page->url }}" class="{{ is_current($page->url) ? 'active' : '' }}">

и ещё в композере зря вызываешь paginate. если там нет постранички, достаточно просто ->take(5)->get(). создание пагинатора тут наверное избыточно.

Не в сети

#4 02.04.2015 15:25:27

Re: Меню

Спасибо, действительно, через хелпер удобнее. Добавил в папку resources файл helpers.php

<?php
function is_current($url)
{
    $segments = explode('/', Request::path());
    foreach ($segments as $segment) {
        if ($url == $segment) return 'active';
    }
    return '';
}
?>

Далее добавляем его в композер:

        "files": [
            "resources/helpers.php"
        ]

Выполняем php composer dump-autoload
Убираем из ViewComposerServiceProvider метод isActive, а также HTML и Request в директиве use
В mainmenu ссылка будет выглядить так

<li>{!! link_to_action('PagesController@show', $page->title, [$page->url], ['class' => is_current($page->url)]) !!}</li>

P.S.: Пагинацию забыл убрать, т.к. тестовый вариант, там ее вообще не будет.

Не в сети

#5 02.04.2015 16:52:43

Re: Меню

почти. по-моему в resources иметь php-код — это не очень, ресурсы — это то что рендерится в браузер уже. я бы положил в app или app/services. или сделал app/helpers.

Не в сети

#6 03.04.2015 09:39:30

Re: Меню

Переместил в app/helpers.
А как сделать, чтобы страница, url которой main или index, выводилась в корне сайта, т.е. по адресу sitename.ru, а не по адресу sitename.ru/main или sitename.ru/pages/main, и при этом ссылка была бы с классом active?

Изменено Johnson (03.04.2015 09:39:46)

Не в сети

#7 03.04.2015 11:38:33

Re: Меню

Добавил в таблицу pages поле main типа boolean, переписал mainmenu так:

<nav class="mainmenu">
    <ul>
@foreach($pages as $page)
        <li>{!! link_to_action('HomeController@show', $page->title, [$page->url], ['class' => is_current($page->url, $page->main)]) !!}</li>
@endforeach
    </ul>
</nav>

Теперь передается два параметра is_current($page->url, $page->main)
В helpers.php

<?php
function is_current($url, $main)
{
    if (Request::path() == '/' && $main) return 'active';
    $segments = explode('/', Request::path());
    foreach ($segments as $segment) {
        if ($url == $segment) return 'active';
    }
    return '';
}
?>

И еще при назначении странице параметра главная меняем его url на '/', иначе придется добавлять еще условие, чтобы в mainmenu ссылка для главной была '/' вместо 'main' или 'index' или любой другой странице, которая является главной.

Не в сети

#8 14.03.2016 09:36:56

Re: Меню

{{ (Request::is('companies') ? 'class=active' : '') }}

Где companies - ваш route

Не в сети

#9 03.02.2017 20:04:18

Re: Меню

На ларакасте сегодня подсмотрел:
В appserviceprovider в методе boot регистрируем новую директиву для блейд

Blade::directive('active', function ($expression) {
            list($pattern, $class) = explode(',', str_replace(['(',')', ' ', "'"], '', $expression));
            return "<?= request()->is('$pattern') ? '$class' : ''; ?>";
        });

В коде меню используем:

<li class="@active('templates/*', 'active')"><a href="/templates"><i class="glyphicon glyphicon-list-alt"></i> Шаблоны</a></li>

Не в сети

#10 04.02.2017 00:03:25

Re: Меню

Я использовал просто виджет для вывода меню, и там одно условие

Не в сети

Подвал раздела