Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Поиск по форуму вроде работает - https://laravel.ru/forum/viewtopic.php?id=826
Пока склоняюсь к http://johnny.github.io/jquery-sortable/ с возможностью сериализации при перемещении.
Может есть еще предложения для сортировки дерева?
Почему-то для древовидной структуры очень мало скриптов
А в базе created_at отличается?
Спасибо
Понятно, а для коментов тоже такую структуру брать за основу?
Какую структуру выбрать для категорий, вроде как есть:
Adjacency List, Matherialized Path, Nested Set и Closure Table.
Количество категорий будет не очень большим, поэтому думаю остановиться на Adjacency List. Возьмем простейший пример - блог, где у постов будет cat_id - id категории. Для категорий тогда будет такая структура:
id,
parent_id,
cat_title,
cat_url,
order
Категорий думаю будет около 100, ну максимум 200. Разумно ли использовать Adjacency List или выбрать другую структуру? Также интересует, что выбрать в дальнейшем для комментариев?
Для Laravel нашел etrepat/baum - для Nested Sets, franzose/ClosureTable - для ClosureTable. Есть ли какой-нибудь пакет для Adjacency List?
Попробуй так:
public function lastcomments(){
return $this->hasMany('App\Comment','blogitem_id')->with('userprofile')->latest('created_at')->limit(3)->get();
}
Спасибо, попробую.
Как реализовать удобную сортировку (порядок) вывода меню, например перетаскиванием?
В БД поле order я добавил, но каждый раз лесть в конкретный пункт и править там позицию неудобно, может поделитесь своим вариантом или скриптом, с помощью которого можно это сделать?
Добавил в таблицу 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' или любой другой странице, которая является главной.
Переместил в app/helpers.
А как сделать, чтобы страница, url которой main или index, выводилась в корне сайта, т.е. по адресу sitename.ru, а не по адресу sitename.ru/main или sitename.ru/pages/main, и при этом ссылка была бы с классом active?
Точно такой вариант работает, только там больше маршрутов:
Route::get( 'register', 'Auth\AuthController@getRegister');
Route::post('register', 'Auth\AuthController@postRegister');
Route::get('login', 'Auth\AuthController@getLogin');
Route::post('login', 'Auth\AuthController@postLogin');
Route::get( 'logout', 'Auth\AuthController@getLogout');
Как сделать, чтобы url основного меню были сразу после слеша
в routes.php прописано:
Route::get('/', 'HomeController@index');
Route::resource('pages', 'PagesController');
Route::resource('users', 'UserController');
Route::get('/{url}', [ 'as' => 'url', 'uses' => 'HomeController@show' ]);
Route::controllers([
'password' => 'Auth\PasswordController',
'' => 'Auth\AuthController'
]);
Все маршруты срабатывают нормально, кроме контроллера авторизации, т.к. вместо
'auth' => 'Auth\AuthController'
стоит
'' => 'Auth\AuthController'
Сделано для упрощения входа, чтобы адрес был сразу sitename/login
Если прописать
Route::get('/{url}', [ 'as' => 'url', 'uses' => 'HomeController@show' ]);
после маршрута контроллеров, то он не работает.
Спасибо, действительно, через хелпер удобнее. Добавил в папку 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.: Пагинацию забыл убрать, т.к. тестовый вариант, там ее вообще не будет.
Сделал так:
Для вывода меню используется таблица 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
Теперь можно инклудить наше меню куда угодно.
Подскажите пожалуйста, как реализовать меню с отображением активного пункта?
Оказывается надо было так:
$user = $user->create($request->all());
$insertedId = $user->id;
dd($insertedId);
В методе store
$user->create($request->all());
$insertedId = $user->id;
dd($insertedId);
возвращает null
Как мне получить id добавленного пользователя?
Наверно через атрибуты не получиться так сделать, т.к. атрибуты должны совпадать с полем в БД, а поля role_select там нет, пришлось сделать через контроллер, в методе create добавил:
$role_select = Role::where('name', '=', 'user')->firstOrFail()->id;
return view('users.create', compact('roles', 'role_select'));
А в методе edit:
$role_select = null;
return view('users.edit', compact('user','roles','role_select'));
Во вьюхе
<div class="row form-group">
<div class="col-md-2"> {!! Form::label('role', 'Роль пользователя:') !!} </div>
<div class="col-md-2"> {!! Form::select('role', $roles, $role_select, ['class' => 'form-control']) !!} </div>
</div>
У меня используется одна форма для добавления и редактирования пользователей, поэтому приходится передавать $role_select в оба метода create и edit.
Можно еще в самой вьюхе определить $role_select, что лучше не знаю, может есть еще какой способ?
Есть список с ролями пользователей
В модели User.php
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function getRoleAttribute()
{
return $this->roles()->lists('id');
}
В контроллере UserController.php
public function create()
{
$roles = Role::lists('display_name', 'id');
return view('users.create', compact('roles'));
}
Во вьюхе
<div class="row form-group">
<div class="col-md-2"> {!! Form::label('role', 'Роль пользователя:') !!} </div>
<div class="col-md-2"> {!! Form::select('role', $roles, null, ['class' => 'form-control']) !!} </div>
</div>
Все работает замечательно, т.е. появляется список где выбираем роль по названию, запись же по id.
При редактировании пользователя прекрасно подставляется его собственная роль.
Вопрос только как при создании пользователя подставить значение по умолчанию?
Пробовал в модели User.php добавить функцию
public function getRoleSelectAttribute(){
return $this->roles()->where('name', '=', 'user')->firstOrFail();
}
После чего во вьюхе вместо значения по умолчанию null подставить переменную $role_select
<div class="row form-group">
<div class="col-md-2"> {!! Form::label('role', 'Роль пользователя:') !!} </div>
<div class="col-md-2"> {!! Form::select('role', $roles, $role_select, ['class' => 'form-control']) !!} </div>
</div>
Но появляется ошибка Undefined variable: role_select, также пробовал добавить в контроллере переменную $role_select
public function create()
{
$roles = Role::lists('display_name', 'id');
$role_select = 'user';
return view('users.create', compact('roles', 'role_select'));
}
Тогда переписал User.php
public function getRoleSelectAttribute($name){
return $this->roles()->where('name', '=', $name)->firstOrFail()->id;
}
Но обработки $role_select из 'user' в id не происходит. Есть ли какой-нибудь короткий способ передать значение по умолчанию, желательно через атрибуты в модели, что у меня не получилось?
У меня все работает и без этих 4-х пунктов, но в форму надо добавить поле
{!! Form::token() !!}
Оказывается пока не умеет чистить кеш, у них в документации написано, но обещают в будущем поправить
Спасибо, а как Glide чистит кеш?
Такое ощущение, что он постоянно накапливается?
Теперь возникает другой вопрос, как при загрузке файлов сразу конвертировать изображение с определенными размерами?
В laravel-Glide есть функция:
GlideImage::load('kayaks.jpg')
->modify(['w'=> 50, 'filt'=>'greyscale'])
->save($pathToWhereToSaveTheImage);
Но у меня так и не получилось в контроллере ее использовать.