diff --git a/doc/reference/slots.md b/doc/reference/slots.md
index ccc0d01a..f687d4d7 100644
--- a/doc/reference/slots.md
+++ b/doc/reference/slots.md
@@ -3,68 +3,89 @@
## Content
- [Overview](#overview)
-- [Example](#example)
-- [Reference](#reference)
+- [Named slots](#named-slots)
+- [Rendering Context](#rendering-context)
+- [Default Slot](#default-slot)
+- [Default Content](#default-content)
+- [Dynamic slots](#dynamic-slots)
+- [Slots and props](#slots-and-props)
+- [Slot params](#slot-params)
+- [Slot scopes](#slot-scopes)
## Overview
Owl is a template based component system. There is therefore a need to be able
-to make generic components. For example, imagine a generic `Dialog`
-component, which is able to display some arbitrary content.
-
-Obviously, we want to use this component everywhere in our application, to
-display various different content. The `Dialog` component is technically the
-owner of its content, but is only a container. The user of the `Dialog` is
-the component that want to _inject_ something inside the `Dialog`. This is
-exactly what slots are for.
-
-## Example
-
-To make generic components, it is useful to be able for a parent component to _inject_
-some sub template, but still be the owner. For example, a generic dialog component
-will need to render some content, some footer, but with the parent as the
-rendering context.
-
-Slots are inserted with the `t-slot` directive:
+to make generic components. For example, imagine a generic `Navbar`
+component, which displays a navbar, but with some customizable content. Since
+the specific content is only known to the user of the `Navbar`, it would be nice
+to specify it in the template where `Navbar` is used:
```xml
-
-
-
+
+
+ Hello Owl
+
+
+```
+
+This is exactly the way slots work! In the example above, the user of the `Navbar`
+component specify some content (here, in the default slot). The `Navbar`
+component can insert that content in its own template at the appropriate location.
+An important information to notice is that the content of the slot is rendered in
+the parent context, not in the navbar. As such, it can access values and methods
+from the parent component.
+
+Here is how the `Navbar` component could be defined, with the `t-slot` directive:
+
+```xml
+
+
+
+
+
+
+```
+
+## Named slots
+
+Default slots are very useful, but sometimes, we may need more than one slot.
+This is what named slots are for! For example, suppose we implement a component
+`InfoBox` that display a title and some specific content. Its template could look
+like this:
+
+```xml
+
+
+
+ X
+
+
-
```
-Slots are defined by the caller, with the `t-set-slot` directive:
+And one could use it with the `t-set-slot` directive:
```xml
-
-
some component
-
-
+
+
+ Specific Title. It could be html also.
+
+
+
+
+
```
-In this example, the component `Dialog` will render the slots `content` and `footer`
-with its parent as rendering context. This means that clicking on the button
-will execute the `doSomething` method on the parent, not on the dialog.
+## Rendering context
-Note: Owl previously used the `t-set` directive to define the content of a slot.
-This is deprecated and should no longer be used in new code.
+The content of the slots is actually rendered with the rendering context corresponding
+to where it was defined, not where it is positioned. This allows the user to define
+event handlers that will be bound to the correct component (usually, the
+grandparent of the slot content).
-## Reference
-
-### Default Slot
+## Default Slot
The first element inside the component which is not a named slot will
be considered the `default` slot. For example:
@@ -81,7 +102,19 @@ be considered the `default` slot. For example:
```
-### Default content
+One can mix default slot and named slots:
+
+```xml
+
+
+ default content
+
+ content for footer slot here
+
+
+```
+
+## Default content
Slots can define a default content, in case the parent did not define them:
@@ -96,12 +129,7 @@ Slots can define a default content, in case the parent did not define them:
```
-Rendering context: the content of the slots is actually rendered with the
-rendering context corresponding to where it was defined, not where it is
-positioned. This allows the user to define event handlers that will be bound
-to the correct component (usually, the grandparent of the slot content).
-
-### Dynamic Slots
+## Dynamic Slots
The `t-slot` directive is actually able to use any expressions, using string
interplolation:
@@ -109,3 +137,102 @@ interplolation:
```xml
```
+
+This will evaluate the `current` expression, and insert the corresponding slot
+at the place of the `t-slot` directive.
+
+## Slots and props
+
+In a sense, slots are almost the same as a prop: they define some information
+to pass to the child component. To make it possible to use it, and to pass it
+down to sub component, Owl actually define a special prop `slots` that contains
+all slot information given to the component. It looks like this:
+
+```js
+{ slotName_1: slotInfo_1, ..., slotName_m: slotInfo_m }
+```
+
+So, a component can pass its slots to a subcomponent like this:
+
+```xml
+
+```
+
+## Slot params
+
+For advanced usecases, it may be necessary to pass additional information to a
+slot. This can be done by providing extra key/value pairs to the `t-set-slot`
+directive. Then, the generic component can read them in its prop `slots`.
+
+For example, here is how a Notebook component could be implemented (a component
+with multiple page, and a tab bar, which only render the current active page,
+and each page has a title).
+
+```js
+class Notebook extends Component {
+ static template = xml`
+
+
+
+
+
+
+
+
+
+
+
+
`;
+
+ setup() {
+ this.state = useState({ activeTab: 0 });
+ this.tabNames = Object.keys(this.props.slots);
+ }
+
+ get currentSlot() {
+ return this.tabNames[this.state.activeTab];
+ }
+}
+```
+
+Notice how one can read the `title` value for each slots. Here is how one could
+use this `Notebook` component:
+
+```xml
+
+
+
this is in the page 1
+
+
+
this is in the page 2
+
+
+```
+
+## Slot scopes
+
+For other kind of advanced use cases, the content of a slot may depends on some
+specific information specific to the generic component. This is the opposite
+of the slot params.
+
+To solve this kind of problems, one can use the `t-set-scope` directive along
+with the `t-set-slot`. This defines the name of a variable that can access
+everything given by the child component:
+
+```xml
+
+
+ content
+
+
+
+
+```
+
+And the child component that includes the slot can provide values like this:
+
+```xml
+
+
+
+```
diff --git a/doc/reference/templates.md b/doc/reference/templates.md
index 4c0d8b49..181432c9 100644
--- a/doc/reference/templates.md
+++ b/doc/reference/templates.md
@@ -69,16 +69,16 @@ For reference, here is a list of all standard QWeb directives:
The component system in Owl requires additional directives, to express various
needs. Here is a list of all Owl specific directives:
-| Name | Description |
-| ------------------------ | --------------------------------------------------------------- |
-| `t-component`, `t-props` | [Defining a sub component](component.md#sub-components) |
-| `t-ref` | [Setting a reference to a dom node or a sub component](refs.md) |
-| `t-key` | [Defining a key (to help virtual dom reconciliation)](#loops) |
-| `t-on-*` | [Event handling](event_handling.md) |
-| `t-portal` | [Portal](portal.md) |
-| `t-slot` | [Rendering a slot](slots.md) |
-| `t-model` | [Form input bindings](input_bindings.md) |
-| `t-tag` | [Rendering nodes with dynamic tag name](#dynamic-tag-names) |
+| Name | Description |
+| -------------------------------------- | --------------------------------------------------------------- |
+| `t-component`, `t-props` | [Defining a sub component](component.md#sub-components) |
+| `t-ref` | [Setting a reference to a dom node or a sub component](refs.md) |
+| `t-key` | [Defining a key (to help virtual dom reconciliation)](#loops) |
+| `t-on-*` | [Event handling](event_handling.md) |
+| `t-portal` | [Portal](portal.md) |
+| `t-slot`, `t-set-slot`, `t-slot-scope` | [Rendering a slot](slots.md) |
+| `t-model` | [Form input bindings](input_bindings.md) |
+| `t-tag` | [Rendering nodes with dynamic tag name](#dynamic-tag-names) |
## QWeb Template Reference