This document describes a radical approach to web development where the system that serves the website is also the system that documents, tests, and modifies itself. Built on XSL transformations and an XML database, it eliminates the traditional boundaries between code, content, documentation, and development tools.
Instead of having separate systems for:
- Serving web pages
- Editing content
- Writing code
- Running tests
- Viewing documentation
We have one unified system where everything is:
- Data (XML in the database)
- Transformations (XSL stylesheets)
- Editable (through XPath-based mutations)
XSL stylesheets are XML documents. This means:
- XSL can transform XSL
- XSL can document itself
- XSL can edit itself
- The system serving your website can also serve its own source code as documentation
Every request generates a <reaction>
document that can contain:
<reaction>
<response> <!-- HTML/XML to return -->
<tx> <!-- Database changes to apply -->
<changes> <!-- XPath-based mutations -->
</tx>
<redirect path=""/> <!-- Post-redirect-get pattern -->
<rerender path=""/> <!-- Re-render for HTMX -->
</reaction>
Any node in the XML database can be edited by:
- Generating its XPath (finding the nearest ancestor with an @id)
- Creating an edit affordance (link/button with the XPath)
- Showing an edit form when that XPath is in the query string
- Generating a
<changes>
element to modify that exact node
<!-- This pattern makes ANY content editable -->
<xsl:variable name="xpath">
<xsl:call-template name="generate-xpath">
<xsl:with-param name="node" select="."/>
</xsl:call-template>
</xsl:variable>
<!-- Now use $xpath to create edit links, forms, and mutations -->
Stylesheets are registered in the XML database:
<stylesheets route-en="/xsl/">
<stylesheet route-en="routing" src="src/base/routing.xsl" title="Routing System"/>
<stylesheet route-en="index" src="src/xsl/index.xsl" title="Main Entry"/>
</stylesheets>
Then rendered by loading themselves as XML:
<xsl:template match="stylesheet">
<xsl:variable name="xsl-doc" select="document(concat('../../', @src))"/>
<xsl:apply-templates select="$xsl-doc"/>
</xsl:template>
Tests are XML documents with embedded documentation:
<nt:suite name="Admin Editing">
<doc:why>
We need clean inline editing without PHP handlers
</doc:why>
<nt:test name="Edit title">
<doc:thinking>
Click edit, change value, verify it persists
</doc:thinking>
<nt:request method="GET" path="/?edit=title"/>
<nt:assertions>
<nt:assert xpath="//form[@action='?save=1']"/>
</nt:assertions>
</nt:test>
</nt:suite>
These same test files can be:
- Executed (to verify behavior)
- Rendered (as documentation)
- Edited (through the web interface)
Changes made through the web interface are immediately live. Edit an XSL template, save it, and the next request uses the updated code.
The production system includes its own development environment. You can:
- Browse to
/xsl/routing
to see how routing works - Click edit on any template to modify it
- Browse to
/tests/
to see and run test suites - Add new features without leaving the browser
The documentation isn't separate from the code - it IS the code, rendered in a human-readable way. When you're reading the docs, you're reading the actual running system.
Using XPath generation, literally any content becomes editable:
- Page content (obviously)
- XSL templates (the code itself)
- Test cases (the specifications)
- Database schema (the data structure)
- Even this documentation (if stored as XML)
Users with admin access can:
- See exactly how any page is generated
- Trace through the transformation pipeline
- Understand the data structure
- Modify anything they understand
-
User reports a bug: "The film title is too small"
-
Developer browses to
/xsl/film
to see the film template -
Finds the title rendering, clicks edit icon
-
Modifies the class attribute to use larger text
-
Saves the change - it's immediately live
-
Browses to
/tests/film-display
-
Adds a test for the title size
-
Runs the test to verify it passes
All of this happens in the browser, on the live system, with no deployment step.
This approach challenges fundamental assumptions:
- Code/Content Division: Everything is content in the XML database
- Development/Production: The same system serves both purposes
- Documentation/Implementation: They're the same thing viewed differently
- Static/Dynamic: Code can modify itself at runtime
With great power comes great responsibility:
- Admin access must be carefully controlled
- Changes should be logged in the transaction system
- Backups are critical
- Consider read-only modes for stability
This paradigm represents a return to the original vision of the web as a read/write medium, but applied to the entire stack. It's not just about editing content - it's about having a living system that can examine, document, test, and modify itself.
The boundary between using software and programming software dissolves. The system becomes a living document that carries its own blueprint, can explain how it works, and can evolve through its own interface.
This is what happens when you take the principles of XML/XSL to their logical conclusion: everything is data, everything is transformable, everything is editable.