<c-portal> sends markup from one place in the page to another. The destination renders a placeholder, sources add to it, and the outermost template fills it in once the page has rendered.
<head>
<c-portal name="head" />
</head>
<head>
{% cotton:portal name="head" %}
</head>
<span {{ attrs }}>{{ slot }}</span>
<c-portal to="head">
<script src="{% static 'tooltip.js' %}"></script>
</c-portal>
<span {{ attrs }}>{{ slot }}</span>
{% cotton:portal to="head" %}
<script src="{% static 'tooltip.js' %}"></script>
{% endcotton:portal %}
nameMarks a destination. Self-closing, or an empty pair. A destination nobody pushes to renders nothing.
toMarks a source. The content between the tags is rendered with the current context and sent to the destination of that name.
multipleSends the block on every render instead of once, in render order:
<c-portal to="breadcrumbs" multiple>
<li>{{ article.title }}</li>
</c-portal>
{% cotton:portal to="breadcrumbs" multiple %}
<li>{{ article.title }}</li>
{% endcotton:portal %}
Destinations and sources can be in components or in ordinary templates, including a child template pushing into a layout it extends. Resolution happens when the outermost template finishes, so it works for full pages, render_to_string, render_component and isolated components alike. Nothing to configure.
{% cotton:portal name="head" %}
{% cotton:portal to="head" %}...{% endcotton:portal %}
{% cotton:portal to="breadcrumbs" multiple %}...{% endcotton:portal %}
See the Component Assets tutorial for the pattern this is built for.
View this page as markdown, handy as context for your AI tools. Full index at /llms.txt. Spotted a mistake? Edit this page on GitHub.