]> Lady’s Gitweb - Shrine-XSLT/commitdiff
Support more slots, including custom slotting
authorLady <redacted>
Sat, 24 Dec 2022 01:23:42 +0000 (17:23 -0800)
committerLady <redacted>
Sat, 29 Apr 2023 03:05:19 +0000 (20:05 -0700)
README.markdown
transform.xslt

index 0abeeb6d910fc95e24a168e43692b2b94b20ee3e..00dd2b59aa4d6f1cf7d192870d6b1367a9ebb5d3 100644 (file)
@@ -100,10 +100,21 @@ There’s an example `feed.atom` provided so you can see what this
   (`<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
index 20fe4c29b354fa5166cba66c9a17e9c3647f2829..e8ecb3d55fe1ec7047b7c20eb7319673d2a49aca 100644 (file)
@@ -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>
 
        <!--
This page took 0.027393 seconds and 4 git commands to generate.