Layouts
Table of contents
1. Overview Table of Contents
The layouts feature supports the ability to present a consistent user experience across views in the framework. We natively support Bootstrap 5 for the styling.
Layouts are supported by layout files that are located at resources/views/layouts
, menus that can be found at resources/views/components
, and menu_acl json files within the app
directory.
2. Layouts Table of Contents
Let’s look at the default layout.
<?php
use Core\Session;
use Core\FormHelper;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title><?=$this->siteTitle()?></title>
<link rel="icon" href="<?=Env::get('APP_DOMAIN', '/')?>public/noun-mvc-5340614.png">
<?php if (Env::get('APP_ENV', 'production')): ?>
<script type="module" src="http://localhost:5173/@vite/client"></script>
<script type="module" src="<?= vite('resources/js/app.js') ?>"></script>
<?php else: ?>
<!-- Production: Include compiled assets -->
<link rel="stylesheet" href="<?= vite('resources/css/app.css') ?>">
<script type="module" src="<?= vite('resources/js/app.js') ?>"></script>
<?php endif; ?>
<link rel="stylesheet" href="<?=Env::get('APP_DOMAIN', '/')?>node_modules/bootstrap/dist/css/bootstrap.min.css" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="<?=Env::get('APP_DOMAIN', '/')?>resources/css/alerts/alertMsg.min.css?v=<?=Env::get('VERSION')?>" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="<?=Env::get('APP_DOMAIN', '/')?>resources/css/font-awesome-4.7.0/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
<script src="<?=Env::get('APP_DOMAIN', '/')?>resources/js/jQuery-3.7.1/jQuery-3.7.1.min.js"></script>
<script src="<?=Env::get('APP_DOMAIN', '/')?>node_modules/@popperjs/core/dist/umd/popper.min.js"></script>
<script src="<?=Env::get('APP_DOMAIN', '/')?>node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="<?=Env::get('APP_DOMAIN', '/')?>resources/js/alerts/alertMsg.min.js?v=<?=Env::get('VERSION')?>"></script>
<?= $this->content('head'); ?>
</head>
<body class="d-flex flex-column min-vh-100">
<?php $this->component('main_menu') ?>
<div class="container-fluid" style="min-height:calc(100% - 125px);">
<?= Session::displayMessage() ?>
<?= $this->content('body'); ?>
</div>
<?php //$this->component(footer.php'); ?>
</body>
</html>
Within the head
element the first thing after the required meta tags you will see a call to the siteTitle() function. This sets the title of the current page on a browser tab.
The if statement that is in this section is where Vite is used for asset bundling. During development, when you save a view file, any changes are automatically presented to the user without have to refresh the page.
The last function call, $this->content('head)
is where additional information for head
element is injected into your view. More information about the content
function can be found in the View page.
The body
element contains a call to the component
function for rendering menus. For the admin layout we use the admin_menu
instead and the framework is smart enough to display this menu for pages that uses the admin layout.
The next function call displays session or sometimes called flash messages depending on the framework. Finally, we have a call to the content function for displaying body
content.
3. Building Your Own Layout Table of Contents
User have the ability to create their own layout. You can either create just a layout. We will create a layout called Foo.
php console make:layout Foo
This tells the framework to create a new layout using the default main_menu The make:layout
also accepts --menu
and -menu-acl
as arguments for generating the menu file and the menu_acl json file. Using these arguments will create new menu and menu_acl files. More about this in the next two sections.
4. Menus Table of Contents
You can create custom menus to be used with your layouts. There are two ways to accomplish this task. You can create a menu using the following command:
php console make:menu Foo
This will create a new menu called foo that you can customize. You can also create a menu using the make:layout
commands as shown below:
php console make:layout Foo --menu
This will create a new layout where the menu name is set when the component function as called. Note, this operation will fail if you type anything after --menu
such as --menu=afafaf
. This is demonstrated below:
$this->component('foo_menu')
No matter what method you use the same menu will be created as shown below:
use Core\Router;
use Core\Helper;
$profileImage = Helper::getProfileImage();
$menu = Router::getMenu('foo_menu_acl');
$userMenu = Router::getMenu('user_menu');
?>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top mb-5">
<!-- Brand and toggle get grouped for better mobile display -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#main_menu" aria-controls="main_menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="<?=Env::get('APP_DOMAIN', '/')?>home"><?=Env::get('MENU_BRAND', 'My Brand')?></a>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="main_menu">
<ul class="navbar-nav me-auto">
<?= Helper::buildMenuListItems($menu); ?>
</ul>
<ul class="navbar-nav me-2 align-items-center"> <!-- Align items vertically -->
<?= Helper::buildMenuListItems($userMenu, "dropdown-menu-end"); ?>
<li class="nav-item">
<a class="nav-link p-0" href="<?=Env::get('APP_DOMAIN', '/')?>profile">
<?php if ($profileImage != null): ?>
<img class="rounded-circle profile-img ms-2"
style="width: 40px; height: 40px; object-fit: cover; border: 2px solid #ddd; transition: opacity 0.3s;"
src="<?=Env::get('APP_DOMAIN', '/') . $profileImage->url?>"
alt="Profile Picture">
<?php endif; ?>
</a>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</nav>
Notice that the parameter near the top for the getMenu
function call is set to foo_menu_acl
. That is the name of the menu_acl file that is used to configure your menu. You can also edit other parts of the menu. If you inspect the admin_menu you will notice there are slight differences from the main_menu file.
5. Menu ACLs Table of Contents
The menu_acl json file is tied to the menu file created above. The menu_acl json file is used to configure the contents of the navigation bar. With this file you can define links and menus. Let’s take a look at the admin_menu_acl.json
file.
{
"Home" : "home",
"Admin" : {
"Admin Dashboard" : "admindashboard/index",
"Manage ACLS" : "admindashboard/manageACLs"
}
}
Anything on the left side of a colon is the label for your link or menu. Home is simple. The right side text, home
, is the name of the controller. The admin section is a little more complicated. Admin
is the name of the menu and anything inside this json object are link labels, just like Home, along with the name of the view directory and the name of the action after the forward slash. If you write home/index
the same result will occur when clicking on the link since index actions are always the default action. To summarize, the right side looks the text in the call to the render function inside your controller.c
You have two options for creating menu_acl json files. The first is by using the following command:
php console make:acl admin
This is the command we used to generate the admin_menu_acl.json
file shown above. You can also use the make:layout
command as well which is shown below:
php console make:layout Admin --menu-acl
Running the command above will create the Admin layout along with your acl file.