Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template inheritance and sections without Blade syntax

How to structure view hierarchy without using blade? What are the pure php counterparts of blade directives (i,e @section, @extend , etc)?

Perhaps, something similar to <?php extend('foo') ?>

In Phalcon framework, while it has its own template engine (Volt) all of its template engine is also available in pure PHP syntax.

like image 705
Handsome Nerd Avatar asked Aug 30 '15 10:08

Handsome Nerd


People also ask

What is Template inheritance in Laravel blade?

Template InheritanceThe @section directive, as the name implies, defines a section of content, while the @yield directive is used to display the contents of a given section. Now that we have defined a layout for our application, let's define a child page that inherits the layout.

What is Template inheritance?

Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override. Sounds complicated but is very basic. It's easiest to understand it by starting with an example.

Why does Laravel use the blade template engine?

Laravel Blade template engine enables the developer to produce HTML based sleek designs and themes. All views in Laravel are usually built in the blade template. Blade engine is fast in rendering views because it caches the view until they are modified. All the files in resources/views have the extension .


2 Answers

Since Blade directives just compile to normal PHP, it is technically possible to use the view structuring features without actually using Blade. I don't think it's very pretty though, and I personally would think twice about this decision.

You can find all the PHP code, Blade is compiled to, in this class:

Illuminate\View\Compilers\BladeCompiler

Here are some of them:

@section('content')

<?php $__env->startSection('content'); ?>

@endsection

<?php $__env->stopSection(); ?>

@extends('layout')

This is a bit a tricky one. Usually Blade compiles it and then adds it to a footer variable which is printed at the bottom. So instead of putting it at the top (like you would with @extends) you have to place this at the end of your view:

<?php echo $__env->make('layout', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>

@yield('content')

<?php echo $__env->yieldContent('content'); ?>
like image 58
lukasgeiter Avatar answered Nov 15 '22 11:11

lukasgeiter


To put this in a pure PHP way you'll have to check out the storage/framework/cache/views and see what's happening there. Basically, is what Blade compiles to PHP code (instead of using @ and with proper function calls).

One way I can think is:

In your template where you use yield:

<!-- template.php -->
<div class="container">
    <!-- instead of using yield('container') -->
    <?php echo "_yield:container"; ?>
</div>

In your file, instead of using section and stop

<!-- view.php -->
<!-- instead of using extend('template') -->
<?php $templatePath = 'template.php'; ?>
<?php $sections = []; ?>
<!-- instead of using section('container') -->
<?php $currentSectionName = 'container'; ob_start(); ?>
    <p>This will be in my container div</p>
<!-- instead of using stop -->
<?php
    // get the current html
    $sections["_yield:".$currentSectionName] = ob_get_contents();
    ob_end_clean();
    ob_start();
    require($templateName);
    $template = ob_get_contents();
    ob_end_clean();
    echo str_replace($template,array_keys($sections),array_values($sections));
?>

Of course, this approach is simplistic at best. The code provided is not intended as a copy & paste solution, more like the concept.

Everything else is simple:

@foreach($arr as $k=>$v)
    ...
@endforeach

translates to

<?php foreach($arr as $k=>$v) : ?>
    ...
<?php endforeach; ?>

That's how it's exactly done by the BladeCompiler. The same is with if and while.

like image 45
Alex Avatar answered Nov 15 '22 13:11

Alex