Skip to content

Implicit default block for embeds - #419

Merged
dg merged 12 commits into
nette:masterfrom
daun:feat/embed-default-slot
Jun 21, 2026
Merged

Implicit default block for embeds#419
dg merged 12 commits into
nette:masterfrom
daun:feat/embed-default-slot

Conversation

@daun

@daun daun commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

What this does

Provide an implicit default block for embeds and move any "loose" children into that default block.

Mirrors how other templating libraries deal with default/unnamed slots.

{* Pass button label into implicit `default` block *}

{embed button}
  Submit
{/embed}

Current state

Currently, I manually have to define the default block when embedding.

{define button}
  <button>
    {block default}Click{/block}
  </button>
{/define}

{embed button}
  {block default}
    Submit
  {/block}
{/embed}

It's a lot of noise when using many embeds.

<ul>
  <li>{embed button} {block default} Submit {/block} {/embed}</li>
  <li>{embed button} {block default} Reset {/block} {/embed}</li>
  <li>{embed button} {block default} Cancel {/block} {/embed}</li>
</ul>

With this feature

This will move any "loose" children into an implicit default block that the template file can render as necessary.

 {embed button}
-   {block default}
     Submit
-   {/block}
{/embed}
<ul>
  <li>{embed button}Submit{/embed}</li>
  <li>{embed button}Reset{/embed}</li>
  <li>{embed button}Cancel{/embed}</li>
</ul>

Explicit blocks and the implicit default block can live side by side.

{define button}
  <button>
    {block default}Click{/block}
    {block icon}<svg />{/block}
  </button>
{/define}

{embed button}
  Submit
  {block icon}<svg />{/block}
{/embed}

Explicit and implicit default block can never coexist and end up with a new compile error.

{* Throws: "Cannot combine loose content with an explicit {block default} inside {embed}"  *}

{embed button}
  Submit
  {block default}Send{/block}
{/embed}

Tests

Tests are added.

Nonbreaking

No existing tests have been modified.

Templates currently using a default block will keep working.

Also, this does not automatically render the loose content. Loose content is still ignored, just as before. It requires defining a {block default} inside the embedded content.

Alternative implementation

I was thinking of using an unnamed block instead of a default block. Not sure if that would've worked even? Also, I think default reads more intentional and in line with how most templating engines name their default slots.

{define button}
  <button>
    {block}Click{/block}
    {block icon}<svg />{/block}
  </button>
{/define}

@dg

dg commented Jun 21, 2026

Copy link
Copy Markdown
Member

Thanks!

@dg
dg merged commit 072e4fd into nette:master Jun 21, 2026
dg pushed a commit that referenced this pull request Jun 21, 2026
dg pushed a commit that referenced this pull request Jun 21, 2026
dg pushed a commit that referenced this pull request Jun 22, 2026
@daun
daun deleted the feat/embed-default-slot branch June 22, 2026 10:39
@jan-herman

Copy link
Copy Markdown

Great feature! I've been hoping for this for a while!

I've just noticed a small bug though. Using {include parent} results in the error "Cannot include undefined parent block 'content'."

@daun

daun commented Jun 27, 2026

Copy link
Copy Markdown
Contributor Author

@jan-herman Interesting. It's probably best if you open a new issue on the repo, along with the exact latte template that triggers the error for you.

@dg

dg commented Jun 28, 2026

Copy link
Copy Markdown
Member

@jan-herman fixed

dg pushed a commit that referenced this pull request Jun 28, 2026
dg pushed a commit that referenced this pull request Jul 4, 2026
dg pushed a commit that referenced this pull request Jul 19, 2026
dg added a commit that referenced this pull request Jul 19, 2026
A block declared inside a top-level condition or loop of the {embed}
content (single, duplicate or dynamically named) registers according to
the flow of execution: {embed} executes the registration code in
collecting mode before the embedded template renders. Adds the runtime
collecting machinery (collectBlocks/collectBlock); child templates are
not affected yet. Complements the implicit default block for {embed}
(#419).

To be released in 3.1.
dg pushed a commit that referenced this pull request Jul 25, 2026
dg added a commit that referenced this pull request Jul 25, 2026
A block declared inside a top-level condition or loop of the {embed}
content (single, duplicate or dynamically named) registers according to
the flow of execution: {embed} executes the registration code in
collecting mode before the embedded template renders. Adds the runtime
collecting machinery (collectBlocks/collectBlock); child templates are
not affected yet. Complements the implicit default block for {embed}
(#419).

To be released in 3.1.
dg pushed a commit that referenced this pull request Jul 25, 2026
dg added a commit that referenced this pull request Jul 25, 2026
A block declared inside a top-level condition or loop of the {embed}
content (single, duplicate or dynamically named) registers according to
the flow of execution: {embed} executes the registration code in
collecting mode before the embedded template renders. Adds the runtime
collecting machinery (collectBlocks/collectBlock); child templates are
not affected yet. Complements the implicit default block for {embed}
(#419).

To be released in 3.1.
dg added a commit that referenced this pull request Jul 25, 2026
A block declared inside a top-level condition or loop of the {embed}
content (single, duplicate or dynamically named) registers according to
the flow of execution: {embed} executes the registration code in
collecting mode before the embedded template renders. Adds the runtime
collecting machinery (collectBlocks/collectBlock); child templates are
not affected yet. Complements the implicit default block for {embed}
(#419).

To be released in 3.1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

make content of {embed} available

3 participants