Skip to content

feat: add #blank, #solo, #inject, and #slot directives to Odo templat…#231

Merged
techmahedy merged 1 commit intodoppar:3.xfrom
techmahedy:techmahedy-3.x
Mar 15, 2026
Merged

feat: add #blank, #solo, #inject, and #slot directives to Odo templat…#231
techmahedy merged 1 commit intodoppar:3.xfrom
techmahedy:techmahedy-3.x

Conversation

@techmahedy
Copy link
Member

This PR introduces four new built-in directives to the Odo template engine — #blank/#endblank, #notblank/#endnotblank, #solo/#endsolo, and #inject/#slot. These directives cover common template patterns that previously required raw PHP or verbose #if workarounds.

#blank / #endblank

#blank($posts)
    <div class="alert alert-info">No posts found.</div>
#endblank

#notblank($posts)
    <p>[[ count($posts) ]] posts found.</p>
#endnotblank

#solo / #endsolo

Renders its content block only once per request, even if the surrounding template or partial is included or looped multiple times. This is critical for preventing duplicate <script> and tags when including partials inside loops.

#foreach ($posts as $post)
    #solo
        <script src="/js/editor.js"></script>
        <link rel="stylesheet" href="/css/editor.css">
    #endsolo

    <div class="post">[[ $post->title ]]</div>
#endforeach

Even if the loop runs 100 times, the <script> and tags are rendered exactly once. Without this directive, developers had to manage their own deduplication flags in raw PHP.

#inject / #endinject and #slot

Introduces a named content stack system. Views and partials can push content into named stacks using #inject, and layouts can output the accumulated content anywhere using #slot. Multiple #inject calls into the same stack are rendered in the order they were pushed.

Define slot placeholders in your layout:

[[-- resources/views/layouts/app.odo.php --]]
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/css/app.css">
    #slot('styles')
</head>
<body>
    #yield('content')

    <script src="/js/app.js"></script>
    #slot('scripts')
</body>
</html>

Push content from any view or partial:

[[-- resources/views/dashboard.odo.php --]]
#extends('layouts.app')

#inject('styles')
    <link rel="stylesheet" href="/css/dashboard.css">
#endinject

#section('content')
    <h1>Dashboard</h1>
    #include('partials.chart')
#endsection

#inject('scripts')
    <script src="/js/dashboard.js"></script>
#endinject

@techmahedy techmahedy merged commit 8dd5396 into doppar:3.x Mar 15, 2026
27 checks passed
@techmahedy techmahedy added the feat new feature label Mar 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant