From: Lady Date: Sat, 24 Dec 2022 01:23:42 +0000 (-0800) Subject: Support more slots, including custom slotting X-Git-Tag: 0.3.1~1 X-Git-Url: https://git.ladys.computer/Shrine-XSLT/commitdiff_plain/b165654fb546b6262512b33a590b2dacf00eb92c Support more slots, including custom slotting --- diff --git a/README.markdown b/README.markdown index 0abeeb6..00dd2b5 100644 --- a/README.markdown +++ b/README.markdown @@ -100,10 +100,21 @@ There’s an example `feed.atom` provided so you can see what this (``) 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 `` of the template by setting - `@slot="shrine-head"` on the appropriate elements. For example, one - might customize the title of a page like - `My Title | My Cool Shrine`. +- 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 `` of + the resulting document. This is especially useful for ``, + `<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 diff --git a/transform.xslt b/transform.xslt index 20fe4c2..e8ecb3d 100644 --- a/transform.xslt +++ b/transform.xslt @@ -1,6 +1,6 @@ <!-- -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, @@ -124,7 +124,7 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h <!-- Process template text; just make a copy. --> - <xslt:template match="text()" mode="content"> + <xslt:template match="text()" mode="template"> <xslt:copy/> </xslt:template> @@ -169,32 +169,61 @@ If a copy of the MPL was not distributed with this file, You can obtain one at h </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> <!--