Skip to content

Layout and pages

@extends('lte3::layouts.app')
@section('content')
@include('lte3::parts.content-header', [
'page_title' => 'Posts',
'url_create' => route('admin.posts.create'),
'breadcrumbs' => [
['title' => 'Home', 'url' => url('admin')],
['title' => 'Posts'],
],
])
<section class="content">
<div class="card">
<div class="card-body">
...
</div>
</div>
</section>
@endsection

After lte3:install the layouts are copied into the project, use @extends('<slug>.layouts.app') there.

lte3::layouts.app is built from parts in layouts/inc/:

ViewContent
begin<head>: meta, CSRF token, AdminLTE and plugin styles, main.css, @stack('styles'); applies the color theme before the page is painted
navbartop bar: sidebar toggle, server time tooltip, theme switcher, demo dropdowns, user menu or logout
sidebarbrand (logo, link to dashboard_slug), user panel (view.sidebar.auth), search (view.sidebar.search), menu layouts/inc/sidebar-menu/example
footerfooter and the control sidebar
preloadershown when view.preloader is true
endjQuery, Bootstrap, plugins, AdminLTE, main.js, mb-blocks.js, @stack('scripts'), then options
optionshidden action form, modals #modal-sm, #modal-lg, #modal-xl, @stack('modals'), editor and picker initialization

The navbar and the sidebar menu are demo content. Publish the layouts and replace them with your own:

Terminal window
php artisan vendor:publish --tag=lte3-view-layouts

Published views in resources/views/vendor/lte3/layouts override the package ones, so lte3::layouts.app keeps working. See Views and publishing.

Stacks for page-specific code:

@push('styles')
<link rel="stylesheet" href="/css/admin-posts.css">
@endpush
@push('scripts')
<script>
$(function () { /* ... */ });
</script>
@endpush
@push('modals')
<div class="modal fade" id="modal-import">...</div>
@endpush

lte3::layouts.app-print is a bare page for printing: it has @yield('content'), @stack('styles'), @stack('scripts'), opens the print dialog on load and closes the window after printing.

The active menu item is set by JS: the js-activeable class on the menu <ul> makes main.js mark the link that matches the current URL as active and open its parent tree. Keep the class in your menu:

<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column js-activeable" data-widget="treeview" role="menu">
<li class="nav-item">
<a href="{{ route('admin.posts.index') }}" class="nav-link">
<i class="nav-icon fas fa-newspaper"></i>
<p>Posts</p>
</a>
</li>
</ul>
</nav>

Details of the matching: JavaScript API.

view.theme sets the initial theme: light, dark or system. The switcher in the navbar (lte3ToggleTheme()) cycles through the three and keeps the choice in localStorage under lte3-theme; a stored choice overrides the config. The dark theme is AdminLTE’s dark-mode class on <body>.

view.compact (default true) makes the navbar, the brand and the sidebar menu smaller.

lte3::parts.content-header renders the page title, buttons and breadcrumbs, then includes callouts and alerts. All variables are optional:

VariableDescription
page_titleTitle (HTML allowed)
small_page_titleSmaller text after the title
url_backShows a “back” button before the title
url_createShows a “Create” button after the title
btn_searchtrue — a search input that submits q to the current URL with GET
btn_filtertrue — a button that toggles #collapseFilter (filters). An array [['url' => ..., 'title' => ...], ...] adds a dropdown of saved filters and a “Clear” link
breadcrumbs[['title' => ..., 'url' => ...], ...]; the last item and items without url are plain text, empty items are skipped

Extra buttons on the right — the btn-content-header section:

@section('btn-content-header')
<a href="{{ route('admin.posts.export') }}" class="btn btn-flat btn-default mb-1"><i class="fas fa-download"></i></a>
@endsection

url_back pairs well with Lte3::backUrl() — the last visited URL of the index page with its filters and page number, see Back URL, modals and options:

@include('lte3::parts.content-header', [
'page_title' => 'Edit post',
'url_back' => Lte3::backUrl('admin.posts.index') ?: route('admin.posts.index'),
])

Two wrappers turn @section('body') into a GET form to the current URL with “Reset” and “Submit” buttons. A hidden _f=1 marks that the filter was applied; the block is expanded while _f is in the query (pass collapsed to override).

  • lte3::parts.filter-wrap — an AdminLTE card with a collapse button
  • lte3::parts.filter-wrap2 — a Bootstrap collapse #collapseFilter, toggled by btn_filter of the content header. When the page has a q parameter, matches of it in .content are highlighted
@include('lte3::parts.content-header', ['page_title' => 'Orders', 'btn_filter' => true, 'btn_search' => true])
@section('body')
<div class="row">
<div class="col-md-3">{!! Lte3::select2('status', null, $statuses, ['empty_value' => '']) !!}</div>
<div class="col-md-3">{!! Lte3::datepicker('date_from', null, ['default' => '']) !!}</div>
</div>
@endsection
@include('lte3::parts.filter-wrap2')

Fields of a GET form take their values from the query string, so the filter keeps its state after submit. “Reset” leads to the URL without the query, see btnReset.

Flash messages with the keys success, info, warning, error and validation errors are shown by lte3::parts.alerts, which the content header includes. view.alerts selects how:

ValueOutput
toastrtoast notifications (default)
sweetalertSweetAlert2 dialogs
bootstrapdismissible Bootstrap alerts at the top of the content
return back()->with('success', 'Saved');

lte3::parts.alerts.bootstrap can also be included on its own, e.g. only errors and warnings above a form:

@include('lte3::parts.alerts.bootstrap', ['types' => ['warning', 'error'], 'class' => ''])

types — which messages to show (default all four; error also covers the danger key and validation errors), class — the wrapper class (default container-fluid p-2).

Callouts — larger AdminLTE blocks — are shown for the flash keys callout.success, callout.info, callout.warning, callout.error:

session()->flash('callout.warning', 'The import is still running.');

From JavaScript: lteAlert(status, message), see JavaScript API.

{!! Lte3::pagination($posts) !!}

Works with paginate(), simplePaginate() and cursorPaginate() results; keeps the current query string except page. Views: view.pagination.view and view.pagination.simple_view (Bootstrap 5 views of Laravel by default). Anything else logs an error and renders an empty string.

Row numbers counting down from the total: pagination_row_number($posts, $loop->index), see Helpers.

lte3::auth.login, register, forgot-password and reset-password extend lte3::auth.app and post to /login, url('register'), route('password.email') and route('password.update') — the routes of Laravel Breeze / Fortify. Use them as views of your auth routes, or publish (lte3-view-auth) and adapt.

Lte3::user() returns the authenticated user or null, Lte3::user('name') — one attribute. The navbar uses it for the user menu.