Interfaces
By default, Flute uses the BladeOne templating engine, which is identical to Laravel's Blade, so if you're not familiar with it, I recommend getting acquainted.
How Interfaces Work
Let me explain how interfaces work. Each request renders a single template (home.blade.php
), which provides us with the sidebar
, navbar
, and all meta tags. But how does it do this? It's unlikely that we need to specify all of this in every module.
Yes, each template uses @extends()
of the main template. Essentially, the template does not render content but adds content to another template, which will be rendered.
I understand it might be difficult, so let's get to practice quickly. Let's see the standard layout
template:
@cookie_alert
@lang_alert
<!DOCTYPE html>
<html lang="{{ app()->getLang() }}" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="icon" type="image/x-icon" href="@asset('favicon.ico')">
<title>@yield('title', page()->title)</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="description" content="{{ page()->description }}">
<meta name="keywords" content="{{ page()->keywords }}">
<meta name="robots" content="{{ page()->robots }}">
<meta property="og:title" content="{{ page()->og_title }}">
<meta property="og:description" content="{{ page()->og_description }}">
<meta property="og:image" content="{{ page()->og_image }}">
<link rel='stylesheet' href='@asset('montserrat')' type='text/css'>
<link rel='stylesheet' href='@asset('sfpro')' type='text/css'>
<link rel="stylesheet" href="@asset('animate')" type='text/css'>
<link rel="stylesheet" href="@asset('grid')" type='text/css'>
<link rel="stylesheet" href="@asset('assets/css/libs/driver.css')">
<script src="@asset('phosphor')"></script>
@at(tt('assets/styles/main.scss'))
@stack('header')
</head>
<body>
<main>
@stack('content')
</main>
<footer>
<script src="@asset('jquery')"></script>
<script src="@asset('assets/js/sweetalert.js')"></script>
<script src="@asset('assets/js/driver.js')"></script>
<script src="@asset('assets/js/forms.js')"></script>
<script src="@asset('assets/js/app.js')"></script>
@at(tt('assets/js/modal.js'))
@at(tt('assets/js/template.js'))
@stack('footer')
</footer>
<div class="toast-container">
@stack('toast-container')
</div>
</body>
</html>
Now let's look at an example of the homepage:
@extends(tt('layout.blade.php'))
@section('title')
{{ !empty(page()->title) ? page()->title : __('def.home') }}
@endsection
@push('content')
@navbar
<div class="container">
@navigation
@breadcrumb
@flash
@editor
</div>
@endpush
@if (tip_active('editor'))
@push('footer')
<script>
const IS_EDITING = {{ (int) page()->isEditMode() }};
</script>
@at(tt('assets/js/pages/home.js'))
@endpush
@endif
@footer
Let's break it down step by step.
In the main template, there's a @stack()
serving as a "container" for collecting data from all templates.
@push()
adds data to our "container." Simple, isn't it?
@navbar
, @navigation
, etc. - These are arbitrary functions added by the template itself. More details about this are described in the section on template development.
And at the top, there's the @extends
which includes layout.blade.php
wrapped in the tt()
function.
The tt()
function returns the full path to the current template. For example, Themes/standard/
.
In simple terms, @extends
just calls the main template, which will already have content added to it. Simple as that. In modules, we do the same for creating our pages as we did for the homepage.
As a secret tip, you don't even need to do @extends()
of the main template in module templates. You are not limited in any way. You can create your own layout
or not use it at all. It's all in your hands.
Rendering Interfaces
To render an interface, all we need to do is render our template and return it as a Response
inside the controller:
/** Assuming we have already created routes for this controller */
class ViewController
{
public function index()
{
// We simply return the render of our template as a Response
return view('Modules/Monitoring/Resources/Views/index');
}
}
More About Template Structure
Here's what functions, capabilities, and limitations templates have, described in the template development section.
Extending Standard Templates
If you want to extend a specific block globally in the template, you can do it very simply.
Just render your template on each page!
Wait, what?
Yes, you heard it right. To add a block to every page, you can globally render your template in the ServiceProvider:
template()->render('Modules/Monitoring/Resources/Views/test', [], false);
The template itself would have a structure like this:
@push('container')
I'm added to the container, congratulate me!!!
@endpush
If you only want to insert data on a specific page (e.g., only on the homepage), you can do a check:
if( request()->is('/') ) { // Check if the current page is the homepage
template()->render('Modules/Monitoring/Resources/Views/test', [], false);
}