Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slot content feature for templates and components #629

Merged
merged 11 commits into from
Oct 2, 2022
Merged

Conversation

jaredcwhite
Copy link
Member

@jaredcwhite jaredcwhite commented Sep 26, 2022

A last-minute feature to slot in (see what I did there 😎) to Bridgetown 1.2.

This adds a slot helper to Ruby templates, along with a slot method directly on components. Resources and layouts can assign parts of their content to slots, which can then be rendered higher up the layout chain (or even within another component or partial) using the slotted helper. In addition, Bridgetown components can now have their own slots and render slotted content.

Slots in resource files will be transformed using "slot-supporting converters" — namely Markdown. That way content in Markdown will still get transformed transparently.

An example of resource/layout slots:

Text in an ERB-based resource.

<% slot :hoist_me do %>
  This text won't get rendered into the resource template.
<% end %>

More content…
<!-- later in some layout -->
<%= slotted :hoist_me do %>
  Default content here if no slotted content is available!
<% end %>

And for components:

<%= render Card.new do |card| %>
  <% card.slot :heading do %>
    <h2>I'm a Card</h2>
  <% end %>
  
  I'm the main content body!

  <% card.slot :footer do %>
    <button>Continue</button>
  <% end %>
<% end %> 

Component templates can use slotted to pull in the slotted content supplied within the outside render block, and they can also call helpers.slotted to access slotted content from the main resource/layout rendering pipeline.

Multiple captures using the same slot name will be cumulative — aka the above hoist_me slot could be appended to several times via calling slot :hoist_me. Or if you pass replace: true, then you'll blow away previous slot content. Use with extreme caution!

There's also a pre_render and post_render hook for slots. Builders can register hooks to transform slots in specific ways based on their name or context!

Note: currently slot content is string-based, but I could see a future where that's not a given. Out of scope for this first version though.

Note 2: this resolves a long-standing question of how we could support a content_for sort of notion like in Rails, or content blocks in Nunjucks, etc. Basically capture and defer output of blocks until they're ready to get displayed elsewhere.

  • Tests
  • (including with GeneratedPage)
  • Documentation

@jaredcwhite jaredcwhite added the enhancement New feature or request label Sep 26, 2022
@jaredcwhite jaredcwhite added this to the 1.2 milestone Sep 26, 2022
@render
Copy link

render bot commented Sep 26, 2022

@render
Copy link

render bot commented Sep 26, 2022

@jaredcwhite jaredcwhite changed the title Slot content feature for templates and component Slot content feature for templates and components Sep 26, 2022
@jaredcwhite
Copy link
Member Author

Outstanding question: should slots be supported to/from Liquid rendering contexts?

@jaredcwhite jaredcwhite merged commit 0486550 into main Oct 2, 2022
@jaredcwhite jaredcwhite deleted the slot-content branch October 2, 2022 04:35
@brandondrew
Copy link

Outstanding question: should slots be supported to/from Liquid rendering contexts?

@jaredcwhite
What do you see as the pros and cons?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants