aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2014-10-12 12:57:01 +0200
committerAdrian Kummerlaender2014-10-12 12:57:01 +0200
commit22ed1ee6e63a496f1e56d8bd905542035d88ca2b (patch)
tree64f8eed3d7a80d9a69eacd08a7f9c9821d411934
parentd9784669ec613d42d453c907921a9983a36518fb (diff)
downloadblog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar.gz
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar.bz2
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar.lz
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar.xz
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.tar.zst
blog.kummerlaender.eu-22ed1ee6e63a496f1e56d8bd905542035d88ca2b.zip
Extracted generation framework into StaticXSLT module
* i.e. the `detail` transformations were moved into a BuildXSLT module * modified XML Makefile accordingly * removed framework documentation from `README.md` and added usage documentation * this was done to make it easier to use the basic static site generation framework in other projects ** the detail transformations were developed to enable the implementation of this blog but are generic enough to be used in other contexts
-rw-r--r--README.md20
-rw-r--r--detail/list.xsl49
-rw-r--r--detail/plan.xsl99
-rw-r--r--detail/process.xsl250
-rw-r--r--detail/summarize.xsl75
-rw-r--r--make.xml9
6 files changed, 8 insertions, 494 deletions
diff --git a/README.md b/README.md
index 236ade5..8f83558 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,14 @@
# blog.kummerlaender.eu
-This repository contains a implementation of my existing [Symphony CMS based blog](https://github.com/KnairdA/symphony_blog) using static site generation in XSLT enabled by [InputXSLT](https://github.com/KnairdA/InputXSLT) and [BuildXSLT](https://github.com/KnairdA/BuildXSLT).
+This repository contains a implementation of my existing [Symphony CMS based blog](https://github.com/KnairdA/symphony_blog) using static site generation in XSLT enabled by [InputXSLT](https://github.com/KnairdA/InputXSLT) and [BuildXSLT](https://github.com/KnairdA/BuildXSLT) using the [StaticXSLT](https://github.com/KnairdA/StaticXSLT) module.
-## Overview:
+## Usage:
-The `detail` directory contains a chain of transformations which are processed by the build system as specified in `make.xml`.
+The `make.xml` file contains the build instructions to be processed by [BuildXSLT](https://github.com/KnairdA/BuildXSLT) which may be executed as follows:
-The first of these transformations `list.xsl` traverses and lists the `source` directory as a base for all further processing. This `source` directory contains four so called _levels_ which depict the different stages of the static generation process.
-
-Based on the results of the `list.xsl` transformation the next transformation `plan.xsl` schedules a number of different tasks to be processed by `process.xsl`. Examples for these tasks are cleaning the `target` directory, linking files and folders and of course generating transformation stylesheets contained within the various levels of the `source` tree.
-
-After the various tasks are processed by `process.xsl` the results of all tasks are summarized by `summarize.xsl` to provide the user with a easy to read plain-text output.
+```
+ixslt --input make.xml --transformation ../BuildXSLT/build.xsl --include ../StaticXSLT
+```
## Levels:
@@ -21,9 +19,3 @@ The second level `01_data` reads the contents of the `00_content` level and gene
The third level `02_meta` further augments and groups these data sources. For example articles are grouped by year, tags and categories are resolved and augmented with article data provided by the previous level and articles are paginated in preparation for generating the primary article stream.
Last but not least the fourth level `99_content` takes all the data sources generated in lower levels and generates the actual website pages.
-
-## Data Source and target resolution:
-
-Every transformation contained in one of the levels contains a `meta` variable defining the required data sources and target paths. This information is read during task processing by the `process.xsl` transformation and used to provide each transformation with the data sources it requires and write the output to the path it desires. This definition of requirements and targets directly inside each transformation is an essential part of how this static site generation concept works.
-
-The system currently provides a couple of different data source reading modes such as `full` for reading a complete XML file as input, `iterate` for iterating the second-level elements of a given XML source and `expression` for evaluating a arbitrary XPath expression against a given XML file. Target modes include `plain` for writing a the result into a given file at the appropriate target level and `xpath` for evaluating a XPath expression to generate the target path. This XPath evaluation functionality in combination with the `iterate` data source mode is especially helpful in situations where one wants to generate multiple output files from a single transformation such as when generating article pages or the pages of the article stream.
diff --git a/detail/list.xsl b/detail/list.xsl
deleted file mode 100644
index c70a6bf..0000000
--- a/detail/list.xsl
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet
- version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:InputXSLT="function.inputxslt.application"
- exclude-result-prefixes="InputXSLT"
->
-
-<xsl:output
- method="xml"
- omit-xml-declaration="yes"
- encoding="UTF-8"
- indent="no"
-/>
-
-<xsl:include href="../utility/datasource.xsl"/>
-
-<xsl:template name="list">
- <xsl:param name="base"/>
-
- <xsl:for-each select="InputXSLT:read-directory($base)/entry">
- <xsl:choose>
- <xsl:when test="@type = 'directory'">
- <directory name="{./name}">
- <xsl:call-template name="list">
- <xsl:with-param name="base" select="./full"/>
- </xsl:call-template>
- </directory>
- </xsl:when>
- <xsl:otherwise>
- <file name="{./name}" extension="{./extension}">
- <xsl:copy-of select="full"/>
- </file>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-</xsl:template>
-
-<xsl:template match="datasource">
- <xsl:copy-of select="meta"/>
-
- <source>
- <xsl:call-template name="list">
- <xsl:with-param name="base" select="meta/source"/>
- </xsl:call-template>
- </source>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/detail/plan.xsl b/detail/plan.xsl
deleted file mode 100644
index 653a9ca..0000000
--- a/detail/plan.xsl
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet
- version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:dyn="http://exslt.org/dynamic"
- xmlns:xalan="http://xml.apache.org/xalan"
- xmlns:InputXSLT="function.inputxslt.application"
- exclude-result-prefixes="dyn xalan InputXSLT"
->
-
-<xsl:output
- method="xml"
- omit-xml-declaration="yes"
- encoding="UTF-8"
- indent="no"
-/>
-
-<xsl:include href="../utility/datasource.xsl"/>
-
-<xsl:template name="traverse">
- <xsl:param name="source"/>
- <xsl:param name="target"/>
- <xsl:param name="path"/>
- <xsl:param name="node"/>
-
- <xsl:for-each select="$node/directory">
- <xsl:choose>
- <xsl:when test=".//file/@extension = '.xsl'">
- <xsl:call-template name="traverse">
- <xsl:with-param name="source" select="$source"/>
- <xsl:with-param name="target" select="$target"/>
- <xsl:with-param name="path" select="concat($path, '/', @name)"/>
- <xsl:with-param name="node" select="."/>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <task type="link">
- <from>
- <xsl:value-of select="concat($target, '/', $path, '/', @name)"/>
- </from>
- <to>
- <xsl:value-of select="concat($source, '/', $path, '/', @name)"/>
- </to>
- </task>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-
- <xsl:for-each select="$node/file">
- <xsl:choose>
- <xsl:when test="@extension = '.xsl'">
- <task type="generate">
- <meta>
- <datasource_prefix>
- <xsl:value-of select="$target"/>
- </datasource_prefix>
- </meta>
- <source>
- <xsl:value-of select="concat($source, '/', $path, '/', @name, @extension)"/>
- </source>
- <target>
- <xsl:value-of select="concat($target, '/', $path)"/>
- </target>
- </task>
- </xsl:when>
- <xsl:when test="@extension = '.css'">
- <task type="link">
- <from>
- <xsl:value-of select="concat($target, '/', $path, '/', @name, @extension)"/>
- </from>
- <to>
- <xsl:value-of select="concat($source, '/', $path, '/', @name, @extension)"/>
- </to>
- </task>
- </xsl:when>
- </xsl:choose>
- </xsl:for-each>
-</xsl:template>
-
-<xsl:template match="datasource">
- <xsl:copy-of select="source"/>
- <xsl:copy-of select="meta"/>
-
- <tasks>
- <task type="clean">
- <path>
- <xsl:value-of select="meta/target"/>
- </path>
- </task>
-
- <xsl:call-template name="traverse">
- <xsl:with-param name="source" select="$root/meta/source"/>
- <xsl:with-param name="target" select="$root/meta/target"/>
- <xsl:with-param name="node" select="source"/>
- </xsl:call-template>
- </tasks>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/detail/process.xsl b/detail/process.xsl
deleted file mode 100644
index 7b596b6..0000000
--- a/detail/process.xsl
+++ /dev/null
@@ -1,250 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet
- version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:dyn="http://exslt.org/dynamic"
- xmlns:xalan="http://xml.apache.org/xalan"
- xmlns:InputXSLT="function.inputxslt.application"
- exclude-result-prefixes="dyn xalan InputXSLT"
->
-
-<xsl:output
- method="xml"
- omit-xml-declaration="yes"
- encoding="UTF-8"
- indent="no"
-/>
-
-<xsl:include href="../utility/datasource.xsl"/>
-
-<xsl:variable name="source_tree" select="$root/source"/>
-
-<xsl:template name="create_link">
- <xsl:param name="from"/>
- <xsl:param name="to"/>
-
- <xsl:value-of select="InputXSLT:external-command(
- concat('ln -sr ./', $to, ' ./', $from)
- )/self::command/@result"/>
-</xsl:template>
-
-<xsl:template name="clean">
- <xsl:param name="path"/>
-
- <xsl:value-of select="InputXSLT:external-command(
- concat('rm -r ./', $path, '; mkdir ./', $path)
- )/self::command/@result"/>
-</xsl:template>
-
-<xsl:template name="generate">
- <xsl:param name="input"/>
- <xsl:param name="transformation"/>
- <xsl:param name="target"/>
-
- <xsl:variable name="generation_result" select="InputXSLT:generate(
- $input,
- $transformation,
- $target
- )/self::generation"/>
-
- <subtask>
- <xsl:attribute name="result">
- <xsl:value-of select="$generation_result/@result"/>
- </xsl:attribute>
- <xsl:if test="$generation_result/@result = 'error'">
- <log>
- <xsl:copy-of select="$generation_result/error"/>
- </log>
- </xsl:if>
-
- <target>
- <xsl:value-of select="$target"/>
- </target>
- </subtask>
-</xsl:template>
-
-<xsl:template name="merge_datasource">
- <xsl:param name="main"/>
- <xsl:param name="support"/>
-
- <datasource>
- <xsl:copy-of select="$main"/>
- <xsl:copy-of select="$support"/>
- </datasource>
-</xsl:template>
-
-<xsl:template name="resolve_target">
- <xsl:param name="prefix"/>
- <xsl:param name="target"/>
- <xsl:param name="datasource"/>
-
- <xsl:choose>
- <xsl:when test="$target/@mode = 'plain'">
- <xsl:value-of select="concat($prefix, '/', $target/@value)"/>
- </xsl:when>
- <xsl:when test="$target/@mode = 'xpath'">
- <xsl:value-of select="concat($prefix, '/', dyn:evaluate($target/@value))"/>
- </xsl:when>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template name="resolve_datasource">
- <xsl:param name="prefix"/>
- <xsl:param name="datasource"/>
-
- <xsl:for-each select="$datasource">
- <xsl:element name="{@target}">
- <xsl:choose>
- <xsl:when test="@mode = 'full'">
- <xsl:copy-of select="InputXSLT:read-file(
- concat($prefix, '/', @source)
- )/self::file/*/*"/>
- </xsl:when>
- <xsl:when test="@mode = 'expression'">
- <xsl:copy-of select="dyn:evaluate(@source)"/>
- </xsl:when>
- </xsl:choose>
- </xsl:element>
- </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="compile">
- <xsl:param name="main"/>
- <xsl:param name="support"/>
- <xsl:param name="transformation"/>
- <xsl:param name="datasource_prefix"/>
- <xsl:param name="target_prefix"/>
- <xsl:param name="target"/>
-
- <xsl:variable name="datasource">
- <xsl:call-template name="merge_datasource">
- <xsl:with-param name="main" select="$main"/>
- <xsl:with-param name="support">
- <xsl:call-template name="resolve_datasource">
- <xsl:with-param name="prefix" select="$datasource_prefix"/>
- <xsl:with-param name="datasource" select="$support"/>
- </xsl:call-template>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="resolved_target">
- <xsl:call-template name="resolve_target">
- <xsl:with-param name="prefix" select="$target_prefix"/>
- <xsl:with-param name="target" select="$target"/>
- <xsl:with-param name="datasource" select="xalan:nodeset($datasource)/*[1]"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:call-template name="generate">
- <xsl:with-param name="input" select="$datasource"/>
- <xsl:with-param name="transformation" select="$transformation"/>
- <xsl:with-param name="target" select="$resolved_target"/>
- </xsl:call-template>
-</xsl:template>
-
-<xsl:template name="process">
- <xsl:param name="task"/>
-
- <xsl:variable name="transformation" select="InputXSLT:read-file($task/source)/self::file/node()"/>
- <xsl:variable name="meta" select="$transformation/self::*[name() = 'xsl:stylesheet']/*[name() = 'xsl:variable' and @name = 'meta']"/>
- <xsl:variable name="main_source" select="$meta/datasource[@type = 'main']"/>
- <xsl:variable name="support_source" select="$meta/datasource[@type = 'support']"/>
-
- <xsl:choose>
- <xsl:when test="$main_source/@mode = 'iterate'">
- <xsl:for-each select="InputXSLT:read-file(
- concat($task/meta/datasource_prefix, '/', $main_source/@source)
- )/self::file/*/entry">
- <xsl:call-template name="compile">
- <xsl:with-param name="main">
- <xsl:element name="{$main_source/@target}">
- <xsl:copy-of select="."/>
- </xsl:element>
- </xsl:with-param>
- <xsl:with-param name="support" select="$support_source"/>
- <xsl:with-param name="transformation" select="$transformation"/>
- <xsl:with-param name="datasource_prefix" select="$task/meta/datasource_prefix"/>
- <xsl:with-param name="target_prefix" select="$task/target"/>
- <xsl:with-param name="target" select="$meta/target"/>
- </xsl:call-template>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="compile">
- <xsl:with-param name="main">
- <xsl:choose>
- <xsl:when test="$main_source/@mode = 'full'">
- <xsl:element name="{$main_source/@target}">
- <xsl:copy-of select="InputXSLT:read-file(
- concat($task/meta/datasource_prefix, '/', $main_source/@source)
- )/self::file/*/*"/>
- </xsl:element>
- </xsl:when>
- <xsl:when test="$main_source/@mode = 'expression'">
- <xsl:element name="{$main_source/@target}">
- <xsl:copy-of select="dyn:evaluate($main_source/@source)"/>
- </xsl:element>
- </xsl:when>
- </xsl:choose>
- </xsl:with-param>
- <xsl:with-param name="support" select="$support_source"/>
- <xsl:with-param name="transformation" select="$transformation"/>
- <xsl:with-param name="datasource_prefix" select="$task/meta/datasource_prefix"/>
- <xsl:with-param name="target_prefix" select="$task/target"/>
- <xsl:with-param name="target" select="$meta/target"/>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="task[@type = 'clean']">
- <xsl:copy>
- <xsl:attribute name="result">
- <xsl:call-template name="clean">
- <xsl:with-param name="path" select="path"/>
- </xsl:call-template>
- </xsl:attribute>
- <xsl:copy-of select="@* | node()"/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="task[@type = 'generate']">
- <xsl:variable name="results">
- <xsl:call-template name="process">
- <xsl:with-param name="task" select="."/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="total_count" select="count(xalan:nodeset($results)/subtask)"/>
- <xsl:variable name="success_count" select="count(xalan:nodeset($results)/subtask[@result = 'success'])"/>
-
- <xsl:copy>
- <xsl:attribute name="result">
- <xsl:choose>
- <xsl:when test="$success_count = $total_count">
- <xsl:text>success</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>error</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:attribute>
- <xsl:copy-of select="@* | source"/>
- <xsl:copy-of select="$results"/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="task[@type = 'link']">
- <xsl:copy>
- <xsl:attribute name="result">
- <xsl:call-template name="create_link">
- <xsl:with-param name="from" select="from"/>
- <xsl:with-param name="to" select="to"/>
- </xsl:call-template>
- </xsl:attribute>
- <xsl:copy-of select="@* | node()"/>
- </xsl:copy>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/detail/summarize.xsl b/detail/summarize.xsl
deleted file mode 100644
index 0399507..0000000
--- a/detail/summarize.xsl
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet
- version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
->
-
-<xsl:output
- method="text"
- omit-xml-declaration="yes"
- encoding="UTF-8"
- indent="no"
-/>
-
-<xsl:template match="task[@result = 'error']">
- <xsl:text>&#xa;Error #</xsl:text>
- <xsl:value-of select="position()"/>
- <xsl:text>: </xsl:text>
-
- <xsl:choose>
- <xsl:when test="@type = 'generate'">
- <xsl:for-each select="subtask[@result = 'error']">
- <xsl:text>Generation of "</xsl:text>
- <xsl:value-of select="target"/>
- <xsl:text>" failed.</xsl:text>
-
- <xsl:for-each select="log/error">
- <xsl:text>&#xa;</xsl:text>
- <xsl:value-of select="."/>
- </xsl:for-each>
- </xsl:for-each>
- </xsl:when>
- <xsl:when test="@type = 'link'">
- <xsl:text>Link from "</xsl:text>
- <xsl:value-of select="from"/>
- <xsl:text>" to "</xsl:text>
- <xsl:value-of select="to"/>
- <xsl:text>" failed.</xsl:text>
- </xsl:when>
- <xsl:when test="@type = 'clean'">
- <xsl:text>Cleaning of "</xsl:text>
- <xsl:value-of select="path"/>
- <xsl:text>" failed.</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:copy-of select="."/>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template match="datasource">
- <xsl:variable name="total_count" select="count(task)"/>
- <xsl:variable name="success_count" select="count(task[@result = 'success'])"/>
-
- <xsl:text>Tasks processed: </xsl:text>
- <xsl:value-of select="$total_count"/>
- <xsl:text>&#xa;</xsl:text>
- <xsl:text>Tasks successful: </xsl:text>
- <xsl:value-of select="$success_count"/>
- <xsl:text>&#xa;</xsl:text>
-
- <xsl:text>▶ Generation </xsl:text>
- <xsl:choose>
- <xsl:when test="$total_count = $success_count">
- <xsl:text>successful</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>failed</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:text>.&#xa;</xsl:text>
-
- <xsl:apply-templates select="task[@result = 'error']"/>
-</xsl:template>
-
-</xsl:stylesheet>
diff --git a/make.xml b/make.xml
index 177189b..89637dc 100644
--- a/make.xml
+++ b/make.xml
@@ -1,4 +1,4 @@
-<task type="generate">
+<task type="module">
<input mode="embedded">
<datasource>
<meta>
@@ -7,10 +7,5 @@
</meta>
</datasource>
</input>
- <transformation mode="chain">
- <link>detail/list.xsl</link>
- <link>detail/plan.xsl</link>
- <link>detail/process.xsl</link>
- <link>detail/summarize.xsl</link>
- </transformation>
+ <definition mode="file">[StaticXSLT.xml]</definition>
</task>