Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Подскажите пожалуйста, как реализовать меню с отображением активного пункта?
Не в сети
Сделал так:
Для вывода меню используется таблица 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)
Не в сети
что-то как-то сложно. без HTML наверное меньше кода бы было — фактически мы же просто проверяем на совпадение url. я бы написал простой хелпер, положил его в helpers.php и было бы
xml<a href="{{ $page->url }}" class="{{ is_current($page->url) ? 'active' : '' }}">
и ещё в композере зря вызываешь paginate. если там нет постранички, достаточно просто ->take(5)->get(). создание пагинатора тут наверное избыточно.
Не в сети
Спасибо, действительно, через хелпер удобнее. Добавил в папку 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.: Пагинацию забыл убрать, т.к. тестовый вариант, там ее вообще не будет.
Не в сети
Не в сети
Переместил в app/helpers.
А как сделать, чтобы страница, url которой main или index, выводилась в корне сайта, т.е. по адресу sitename.ru, а не по адресу sitename.ru/main или sitename.ru/pages/main, и при этом ссылка была бы с классом active?
Изменено Johnson (03.04.2015 09:39:46)
Не в сети
Добавил в таблицу 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' или любой другой странице, которая является главной.
Не в сети
{{ (Request::is('companies') ? 'class=active' : '') }}
Где companies - ваш route
Не в сети
На ларакасте сегодня подсмотрел:
В 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>
Не в сети
Я использовал просто виджет для вывода меню, и там одно условие
Не в сети
Страницы 1