Templating - sgml/signature GitHub Wiki

Minilanguages

Instruction Set Variant GitHub Repository URL Last README.md Update
RISC-V riscv/sail-riscv March 26, 2024
AluVM AluVM/aluvm-spec February 17, 2024
XSLT w3c/qtspecs March 22, 2024
AWK onetrueawk/awk June 5, 2024
M4 autotools-mirror/m4 January 12, 2024
SED onetrueawk/sed April 15, 2024
Tcl/Expect aeruder/expect August 16, 2022

PItarget

MSBuild Processing Instructions Metadata Details

The following tables outline metadata keys supported by the two custom processing instructions in MSBuild (<?job ...?> and <?assembly ...?>) along with descriptions and examples of their acceptable values.


Processing Instruction: <?job ...?>

Metadata Key Description Possible Values
id Unique identifier for the build job Any non-empty string (e.g., "job-001", "build-123")
target Specifies the build target to execute e.g., "Build", "Clean", "Rebuild"
configuration Build configuration setting e.g., "Debug", "Release", "CustomConfig"
platform Target platform specification (CPU architecture) e.g., "AnyCPU", "x86", "x64"
priority Execution priority level of the job e.g., "High", "Normal", "Low" or numeric values (e.g., "1", "2", "3")

Subtables for <?job ...?> Metadata Keys

For Key id

Key Example Value
id "job-001"

For Key target

Key Example Value
target "Build"

For Key configuration

Key Example Value
configuration "Release"

For Key platform

Key Example Value
platform "x64"

For Key priority

Key Example Value
priority "High"

Processing Instruction: <?assembly ...?>

Metadata Key Description Possible Values
path File path to the assembly being referenced Valid file path strings (e.g., "libs/MyAssembly.dll", "./bin/Release/MyLib.dll")
version Version of the referenced assembly Versions formatted as "major.minor.build.revision" (e.g., "1.0.0.0")
culture Culture information for the assembly e.g., "neutral", "en-US", "fr-FR"
publicKeyToken Public key token used to strongly name the assembly Hexadecimal string (e.g., "b77a5c561934e089")

Subtables for <?assembly ...?> Metadata Keys

For Key path

Key Example Value
path "libs/MyAssembly.dll"

For Key version

Key Example Value
version "1.0.0.0"

For Key culture

Key Example Value
culture "neutral"

For Key publicKeyToken

Key Example Value
publicKeyToken "b77a5c561934e089"

Markup

The W3 Word Processor Filters page should answer most of these questions. For more details, here some resources on the evolution of separating content from presentation:

Markup and typesetting languages are the earliest examples of templating. Here is the Wikipedia definition:

A markup language is a modern system for annotating a document in a way that is syntactically distinguishable from the text. The idea and terminology evolved from the "marking up" of manuscripts, i.e., the revision instructions by editors, traditionally written with a blue pencil on authors' manuscripts. Examples are typesetting instructions such as those found in troff and LaTeX, or structural markers such as XML tags.

Here is a diagram:

                        RUNOFF                      "Generic Coding"                 "Editorial Structure Tags"
                   (Jerome Saltzer, 1964)         (William Tunnicliffe, 1967)          (Stanley Rice, pre-1970)
                            |                               |                                     |
                            |                               |                                     |
        TeX          roff - nroff - troff                   |-------------------------------------|
 (Don Knuth, 1977)   (Josef Osanna, 1973)                   |
                                                           GML
                                                    (Charles Goldfarb, 1969)
                                                            |                       SCRIBE
                                                            |                   (Brian Reid, 1980)
                                                            |                          |
                                                            |--------------------------|
                                                          SGML
                                                      (Standard, 1980)
                                                     |                |
                                                     |                |
                                                   HTML              XML
                                            (Berners-Lee, 1990)    (Standard, 1998)

As far as web site templating, SSI is the mother of them all.

From a security standpoint, JSP scriptlets have vulnerabilities:

There are a handful of objects made available in JSPs which are susceptible to security flaws. Their corresponding Java class functions are used as is in scriptlets. All the same security rules should apply.

For example, one session variable:

 <%=session.getAttribute(name)%>

can taint another:

<% 
String name = request.getParameter("username");
session.setAttribute("taintedAttribute", name);
%>

and unescaped strings can be dangerous as well:

<style>
<%
  String parm = request.getParameter("foobar");
  String cssEscaped = Escape.cssString(parm);
%>

a[href *= "<%= cssEscaped %>"] {
   background-color: pink!important;
}
</style>

XSLT

Canonical Example

  • Repeat args, do not redefine vars
  • Comment judiciously to avoid write-only code
  • Use unconditional output to map input to output
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <!-- Template to handle the default case when there's no 'data' element -->
    <xsl:template match="/">
        <results>
            <xsl:call-template name="myfunc">
                <xsl:with-param name="results" select="/results"/>
            </xsl:call-template>
        </results>
    </xsl:template>

    <!-- Template to simulate the 'myfunc' function -->
    <xsl:template name="myfunc">
        <xsl:param name="results"/>
        <xsl:variable name="foo">
            <xsl:choose>
                <xsl:when test="$results/data">
                    <xsl:copy-of select="$results/data"/>
                </xsl:when>
                <xsl:otherwise>
                    <?echo 'Failed to get results for: '; ?>
                    <?echo $results; ?>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <foo>
            <xsl:choose>
                <xsl:when test="$foo">
                    <xsl:copy-of select="$foo"/>
                </xsl:when>
                <xsl:otherwise>
                    <?echo 'false' ?>
                </xsl:otherwise>
            </xsl:choose>
        </foo>
    </xsl:template>
</xsl:stylesheet>

Processing Model

XSLT uses a hierarchy to allow parameters to be redefined:

  • the with-param value has the highest precedence
  • the param value has the second highest precedence
  • the value-of value has the third highest precedence

For example:

<xsl:template match="/">
    <xsl:call-template name="blob">
        <xsl:with-param name="par" select="'some-value'"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="blob">
    <xsl:param name="par" select="'default-value'"/>
    <xsl:value-of select="$param"/>
</xsl:template>

Modes in XSLT allow us to invoke templates based on matching XPath selectors, which is a form of delegation:

<xsl:template match="/">
    <!-- Apply templateA -->
    <xsl:apply-templates mode="templateA"/>
</xsl:template>

<xsl:template match="someElement" mode="templateA">
    <!-- Your templateA logic here -->
</xsl:template>

The for-each loop control of XSLT uses the position() method to capture the index, and the current()` method to capture its value. Enumerate these items:

<items>
    <item>Apple</item>
    <item>Banana</item>
    <item>Cherry</item>
</items>

Using a template:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <enumerated-items>
            <xsl:for-each select="items/item">
                <enumerated-item>
                    <xsl:number value="position()" />
                    <xsl:value-of select="current()" />
                </enumerated-item>
            </xsl:for-each>
        </enumerated-items>
    </xsl:template>
</xsl:stylesheet>

XSLT will transform it to:

<enumerated-items>
    <enumerated-item>1 Apple</enumerated-item>
    <enumerated-item>2 Banana</enumerated-item>
    <enumerated-item>3 Cherry</enumerated-item>
</enumerated-items>

And now the data is annotated with the index and you can see the total count at a glance.

UIML

UIML is an abstraction which can be used to generate XSLT, JSX, or any other tag based language easily using XSLT. Here is 'Hello World':

<uiml>
  <part class="HelloWorld">
    <content>
      <data>
        <![CDATA[Hello, World!]]>
      </data>
    </content>
  </part>
</uiml>

XSLT Processor Interop

RFC 6570

Transclusion

Slots in web components vs XSLT transclusion

Slots in Web Components

 <my-component>
   <p slot="mySlot">Content to be transcluded</p>
 </my-component>

 <script>
   this.shadowRoot.addEventListener('slotchange', (event) => {
     const slotContent = event.target.assignedNodes();
     // Handle the slot content as needed
   });
</script>

XSLT

 <!-- doc1.xml -->
 <chapter>
   <title>doc1.xml</title>
   <p>First paragraph</p>
   <transclusion src="doc2.xml"/>
   <p>Last paragraph</p>
 </chapter>

 <!-- XSLT stylesheet -->
 <xsl:template match="transclusion">
   <xsl:copy-of select="document(@src)"/>
 </xsl:template>

MediaWiki

Declarative Markup

<h2 id="page-one">foo</h2>
<!-- content block -->
<h2 class="footer">bar</h2>
<h2 id="page-two" class="page-break">baz</h2>
<!-- content block -->
<h2 class="footer">bop</h2>
<h2 id="page-three" class="page-break">buzz</h2>
<!-- content block -->
<h2 class="footer">blip</h2>
<h2 id="page-four" class="page-break">bloop</h2>
<!-- content block -->
<h2 class="footer">blarg</h2>
<h2 id="page-five" class="page-break">blech</h2>


@media print {
    #page1, #page2, #page3, #page4, #page5 {
        page-break-after: always;
    }
    #page5 {
        page-break-after: auto; /* No page break after the last page */
    }
}

Semantic Markup

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Social Network Timeline</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css"
      rel="stylesheet"
    />
  </head>
  <body class="bg-gray-100 p-6">
    <div class="max-w-4xl mx-auto">
      <h1 class="text-3xl font-bold mb-6">
        Timeline of Social Network Domain Launches
      </h1>
      <div class="space-y-4">
        <div class="flex items-center">
          <span class="w-40">Friendster (2002)</span>
          <meter
            value="2002"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">LinkedIn (2003)</span>
          <meter
            value="2003"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">MySpace (2003)</span>
          <meter
            value="2003"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">Facebook (2004)</span>
          <meter
            value="2004"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">Twitter (2006)</span>
          <meter
            value="2006"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">Instagram (2010)</span>
          <meter
            value="2010"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">Pinterest (2010)</span>
          <meter
            value="2010"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">Snapchat (2011)</span>
          <meter
            value="2011"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
        <div class="flex items-center">
          <span class="w-40">TikTok (2016)</span>
          <meter
            value="2016"
            min="2000"
            max="2022"
            class="w-full h-6 bg-gray-200 border-2 border-gray-300 rounded"
          ></meter>
        </div>
      </div>
    </div>
  </body>
</html>

Comparison

templating_engines:
  - name: "Jinja"
    primary_use: "Templating engine for Python"
    language: "Python"
    syntax: "{% %} for control flow, {{ }} for variables"
    customization: "Highly customizable with extensions"
    performance: "Fast rendering"
    learning_curve: "Moderate, especially for Python devs"
    community_support: "Active community"
    use_cases: "Web applications, data visualization"
  
  - name: "Django Template Language (DTL)"
    primary_use: "Templating engine for Django"
    language: "Python"
    syntax: "{% %} for control flow, {{ }} for variables"
    customization: "Built-in tags and filters"
    performance: "Moderate rendering"
    learning_curve: "Moderate, especially for Django devs"
    community_support: "Large community"
    use_cases: "Web applications"
  
  - name: "Server Side Includes (SSI)"
    primary_use: "Adding dynamic content to HTML pages"
    language: "HTML"
    syntax: "<!--# --> for directives"
    customization: "Limited to basic directives"
    performance: "Fast for small dynamic content"
    learning_curve: "Easy for HTML developers"
    community_support: "Limited community"
    use_cases: "Static websites with dynamic content"
  
  - name: "XSLT"
    primary_use: "Transforming XML documents"
    language: "XSL (a subset of XML)"
    syntax: "<xsl: > for control flow"
    customization: "Extensive transformation capabilities"
    performance: "Can be slow for large documents"
    learning_curve: "Steep, requires understanding of XML"
    community_support: "Active community"
    use_cases: "Data transformation, XML processing"

References

Property Accessors

XBL

CSS

Static Site Generators

PHP

Python

Ruby

Perl

Golang

Node.js

OCaml

Erlang

Wordpress Gutenberg

Editing the Block Editor via Source Code

Editing the block editor via source code involves working with the Gutenberg project on GitHub. Here's a high-level overview of how you can do this:

Portable Templating

  • Data URIs - URI Templates allow for parameterization. This can be used to generate Data URIs with different embedded data based on the provided parameters
  • XSLT - normalized processing instructions can be parameterized to create dynamic strings in XSLT
  1. Clone the Gutenberg Repository: You can start by cloning the Gutenberg repository from GitHub. This will give you access to the entire codebase.
  2. Set Up Your Development Environment: Make sure you have Node.js, npm, and a code editor like Visual Studio Code installed.
  3. Install Dependencies: Navigate to the cloned repository and run npm install to install all the necessary dependencies.
  4. Create Custom Blocks: You can create custom blocks by adding new JavaScript files in the packages/blocks directory. Each block should have an edit function that defines how the block is rendered and a save function that defines how the block's content is saved.
  5. Register Blocks: Use the registerBlockType function to register your custom blocks with WordPress.
  6. Test Your Blocks: You can test your custom blocks by running a local WordPress instance and adding the blocks to posts and pages.

For a more detailed guide, you can refer to the Block Editor Handbook on the WordPress Developer site.

⚠️ **GitHub.com Fallback** ⚠️