(`<html>`) element of the template, as will `@lang` and `@xml:lang`.
You can use this to help configure page‐specific styling.
-- You can insert content into the `<head>` of the template by setting
- `@slot="shrine-head"` on the appropriate elements. For example, one
- might customize the title of a page like
- `<title slot="shrine-head">My Title | My Cool Shrine</title>`.
+- You can use the `@slot` attribute with a few special values to insert
+ content in various places :—
+
+ - `@slot="shrine-head"` will place the content into the `<head>` of
+ the resulting document. This is especially useful for `<title>`,
+ `<meta>`, and `<style>` elements.
+
+ - For `shrine-header` and `shrine-footer`, there are `-before` and
+ `-after` slot names which will place content into the beginning or
+ ending of the shrine header or footer, respectively.
+
+ - You can define your own slots with `<slot>` in templates, headers,
+ and footers; this will enable a corresponding `@slot` name
+ beginning with `shrine-template-slot-`, `shrine-header-slot-` or
+ `shrine-footer-slot`, respectively.
- If you delete files from `sources/`, the corresponding files in
`public/` will **not** be deleted and will need to be manually
<!--
-This is an extremely simple XSLT transform which simply reads in a
-`template.xml` and :—
+This is a⸠n extremely simple⸡ progressively‐less‐simple X·S·L·T
+transform which simply reads in a `template.xml` and :—
• Replaces the `<html:shrine-content>` element with the content of the document it is being applied to,
<!--
Process template text; just make a copy.
-->
- <xslt:template match="text()" mode="content">
+ <xslt:template match="text()" mode="template">
<xslt:copy/>
</xslt:template>
</xslt:template>
<!--
- Process the template header.
- Read the `@data-header` attribute of the root element, append `"-header.xml"` to the end of it, and process the resulting document.
- If no `@data-header` attribute is provided, no header is rendered.
+ Process the template header and footer.
+ Read the corresponding `@data-header` or `@data-footer` attribute of the root element, append `"-header.xml"` or `"-footer.xml"` to the end of it, and process the resulting document.
+ If no `@data-header` or `@data-footer` attribute is provided, nothing is rendered.
-->
- <xslt:template match="html:shrine-header" mode="template">
- <xslt:for-each select="$source/*/@data-shrine-header">
- <xslt:apply-templates select="document(concat('./', ., '-header.xml'), $template)/*" mode="content"/>
- </xslt:for-each>
+ <xslt:template match="html:shrine-header|html:shrine-footer" mode="template">
+ <xslt:param name="context" select="'shrine-template'"/>
+ <xslt:variable name="kind" select="substring-after(local-name(), 'shrine-')"/>
+ <xslt:choose>
+ <xslt:when test="$context='shrine-template'">
+ <xslt:for-each select="$source/*/@*[name()=concat('data-shrine-', $kind)]">
+ <xslt:for-each select="document(concat('./', ., '-', $kind, '.xml'), $template)/*">
+ <xslt:element name="{local-name()}">
+ <xslt:for-each select="@*">
+ <xslt:copy/>
+ </xslt:for-each>
+ <xslt:for-each select="$source//*[@slot=concat('shrine-', $kind, '-before')]">
+ <xslt:apply-templates select="." mode="content"/>
+ </xslt:for-each>
+ <xslt:apply-templates mode="template">
+ <xslt:with-param name="context" select="concat('shrine-', $kind)"/>
+ </xslt:apply-templates>
+ <xslt:for-each select="$source//*[@slot=concat('shrine-', $kind, '-after')]">
+ <xslt:apply-templates select="." mode="content"/>
+ </xslt:for-each>
+ </xslt:element>
+ </xslt:for-each>
+ </xslt:for-each>
+ </xslt:when>
+ <xslt:otherwise>
+ <xslt:element name="{local-name()}">
+ <xslt:for-each select="@*">
+ <xslt:copy/>
+ </xslt:for-each>
+ <xslt:apply-templates mode="template"/>
+ </xslt:element>
+ </xslt:otherwise>
+ </xslt:choose>
</xslt:template>
<!--
- Process the template footer.
- Read the `@data-footer` attribute of the root element, append `"-footer.xml"` to the end of it, and process the resulting document.
- If no `@data-footer` attribute is provided, no footer is rendered.
+ Process the content.
-->
- <xslt:template match="html:shrine-footer" mode="template">
- <xslt:for-each select="$source/*/@data-shrine-footer">
- <xslt:apply-templates select="document(concat('./', ., '-footer.xml'), $template)/*" mode="content"/>
- </xslt:for-each>
+ <xslt:template match="html:shrine-content" mode="template">
+ <xslt:apply-templates select="$source/*" mode="content"/>
</xslt:template>
<!--
- Process the content.
+ Process miscellaneous template slots.
-->
- <xslt:template match="html:shrine-content" mode="template">
- <xslt:apply-templates select="$source/*" mode="content"/>
+ <xslt:template match="html:slot[not(ancestor::html:template)]" mode="template">
+ <xslt:param name="context" select="'shrine-template'"/>
+ <xslt:variable name="name" select="string(@name)"/>
+ <xslt:for-each select="$source//*[@slot=concat($context, '-slot-', $name)]">
+ <xslt:apply-templates select="." mode="content"/>
+ </xslt:for-each>
</xslt:template>
<!--