A slot is a placeholder or container that allows you to insert content into a designated area of a template or component. Slots provide a way to define a portion of a template/component that can be filled with custom content from the parent component or template. Owl is a component system built on templates. The owl must therefore be able to create generic components.
Slots provide a way to pass content from a parent component to a child component, allowing for greater flexibility and reusability. When you define a component, you can include slots within its template. Slots act as placeholders for content that will be provided by the parent component when the component is used. Here’s a basic example:
Parent Component
<div>
<ChildComponent>
<p>This content will be placed in the default slot</p>
</ChildComponent>
</div>
<div class="content">
<t t-slot="default"/>
</div>
Named Slot
<div>
<t t-set-slot="header_slot"/>
<p>Parent Template Content</p>
<t t-set-slot="footer_slot">
<p>Fallback Footer Content</p>
</t>
</div>
<div>
<t t-call="parent_template">
<t t-slot="header_slot">
<h1>Child Template Header</h1>
</t>
<t t-slot="footer_slot">
<p>Child Template Footer</p>
</t>
</t>
</div>
Default content
<div t-name="Parent">
<Child/>
</div>
<span t-name="Child">
<t t-slot="default">default content</t>
</span>
Dynamic Slots
<t t-slot="{{current}}" />
Slots and props
{ slotName_1: slotInfo_1, ..., slotName_m: slotInfo_m }
So, a component can pass its slots to a subcomponent like this:
<Child slots="props.slots"/>
Slot Params
class Notebook extends Component {
static template = xml`
<div class="notebook">
<div class="tabs">
<t t-foreach="tabNames" t-as="tab" t-key="tab_index">
<span t-att-class="{active:tab_index === activeTab}" t-on-click="() => state.activeTab=tab_index">
<t t-esc="props.slots[tab].title"/>
</span>
</t>
</div>
<div class="page">
<t t-slot="{{currentSlot}}"/>
</div>
</div>`;
setup() {
this.state = useState({ activeTab: 0 });
this.tabNames = Object.keys(this.props.slots);
}
get currentSlot() {
return this.tabNames[this.state.activeTab];
}
}
<Notebook>
<t t-set-slot="page1" title="'Page 1'">
<div>this is in the page 1</div>
</t>
<t t-set-slot="page2" title="'Page 2'" hidden="somevalue">
<div>this is in the page 2</div>
</t>
</Notebook>
Slot Scopes
<MyComponent>
<t t-set-slot="foo" t-slot-scope="scope">
content
<t t-esc="scope.bool"/>
<t t-esc="scope.num"/>
</t>
</MyComponent>
<t t-slot="foo" bool="other_var" num="5">
<t t-slot="foo" t-props="someObject">
<MyComponent t-slot-scope="scope">
content
<t t-esc="scope.bool"/>
<t t-esc="scope.num"/>
</MyComponent>