Universal “Soldier” in PHP
Templating: Twig vs Blade
After controllers, DI, and Request handling, the next key layer is view rendering.
In PHP frameworks, this usually means templating engines:
- Symfony/Drupal: Twig
- Laravel: Blade
Even though the syntax differs, the concept is the same: the controller prepares data, passes it to a template, and the template renders HTML.
1. Symfony / Drupal — Twig
Controller Example (Symfony)
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HelloController extends AbstractController
{
#[Route('/hello', name: 'hello')]
public function index(): Response
{
$name = 'Alice';
return $this->render('hello/index.html.twig', [
'name' => $name,
]);
}
}
Twig Template (templates/hello/index.html.twig)
<!DOCTYPE html>
<html>
<head>
<title>Hello Twig</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
Drupal Example
In a Drupal controller, you return a render array:
public function hello(): array {
return [
'#theme' => 'hello_template',
'#name' => 'Alice',
];
}
Twig template (hello-template.html.twig):
<h1>Hello, {{ name }}!</h1>
📌 Key points:
- Twig is logic-light — only simple filters, loops, and conditionals
- Templates receive variables from the controller
- Safe by default (auto-escaping)
2. Laravel — Blade
Controller Example
use App\Http\Controllers\Controller;
class HelloController extends Controller
{
public function index()
{
$name = 'Alice';
return view('hello.index', compact('name'));
}
}
Blade Template (resources/views/hello/index.blade.php)
<!DOCTYPE html>
<html>
<head>
<title>Hello Blade</title>
</head>
<body>
<h1>Hello, {{ $name }}!</h1>
</body>
</html>
Blade Features
- Similar to Twig: loops (
@foreach), conditionals (@if), includes (@include) - Variables prefixed with
$ - Auto-escaping by default
Comparison Table
| Feature | Twig (Symfony/Drupal) | Blade (Laravel) |
|---|---|---|
| Variable syntax | {{ name }} | {{ $name }} |
| Loops | {% for user in users %} | @foreach ($users as $user) |
| Conditionals | {% if condition %} | @if ($condition) |
| Includes | {% include 'partial.html.twig' %} | @include('partial') |
| Auto-escaping | Yes | Yes |
| Controller data | Passed as array | Passed via view() |
Universal Pattern
No matter the engine:
- Controller collects data
- Passes data to template
- Template renders HTML safely
This matches our “Universal Soldier” principle:
Controllers are the soldier, templates are the battlefield — same logic, different syntax.
Comments