Closed ebrehault closed 9 years ago
In https://github.com/lrowe/diazo/tree/after-before-content-tests I've added a test that is current failing ontop of your commit, rebased on top of a python 3 fix for the test class so that test failures display errors better.
This is the failure:
--- /Users/lrowe/scratch/diazo/lib/diazo/tests/v1-before-replace-after-content/output.html
+++ now
@@ -1,10 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <h1>Title</h1>
- <span>before</span>
- <span>replace</span>
- <span>after</span>
- </body>
+<body><h1>Title</h1><p id="one" class="after">one</p><span>after</span></body>
</html>
Which from looking at the compiled xsl you can see is due to the template including only known before-content/replace-content/after-content modes. All of these modes always have to be included so that different ways of selecting the same content node work:
$ .tox/py34/bin/diazocompiler -r lib/diazo/tests/v1-before-replace-after-content/rules.xml
...
<xsl:template match="//*[@id = 'one']">
<xsl:apply-templates select="." mode="before-content"/>
<xsl:apply-templates select="." mode="replace-content"/>
</xsl:template>
<xsl:template match="//*[@id = 'one']" mode="before-content">
<span xmlns:diazo="http://namespaces.plone.org/diazo">before</span>
</xsl:template>
<xsl:template match="//*[@id = 'one']" mode="replace-content">
<span xmlns:diazo="http://namespaces.plone.org/diazo">replace</span>
</xsl:template>
<xsl:template match="//*[@class and contains(concat(' ', normalize-space(@class), ' '), ' after ')]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:apply-templates select="." mode="after-content"/>
</xsl:template>
<xsl:template match="//*[@class and contains(concat(' ', normalize-space(@class), ' '), ' after ')]" mode="after-content">
<span xmlns:diazo="http://namespaces.plone.org/diazo">after</span>
</xsl:template>
...
Added another test for before content-children showing it being applied multiple times.
--- /Users/lrowe/scratch/diazo/lib/diazo/tests/v1-before-content-content-children/output.html
+++ now
@@ -1,12 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <h1>Title</h1>
- <p id="one">
- <span>before</span>
- <span>one</span>
- <span>1</span>
- </p>
- </body>
+<body><h1>Title</h1><p id="one"><span>before</span><span>one</span><span>before</span><span>1</span></p></body>
</html>
This is because content-children has to compile differently in content rules:
$ .tox/py34/bin/diazocompiler -r lib/diazo/tests/v1-before-content-content-children/rules.xml
...
<xsl:template match="//*[@id = 'one']/node()">
<xsl:apply-templates select="." mode="before-content"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*[@id = 'one']/node()" mode="before-content">
<span xmlns:diazo="http://namespaces.plone.org/diazo">before</span>
</xsl:template>
...
for instance in replace content-children:
$ .tox/py34/bin/diazocompiler -r lib/diazo/tests/v1-replace-content-content-children/rules.xml
...
<!--RULE: <diazo:replace css:content-children="#you-are-here" xml:id="r1" content-children="//*[@id = 'you-are-here']"/>-->
<xsl:template match="//*[@id = 'you-are-here']"><xsl:copy><xsl:apply-templates select="@*"/>Location:</xsl:copy></xsl:template>
...
Otherwise I think its looking good. Thanks for working on this!
@lrowe it was actually very tricky (each time I fixed the code for a given test, another one was failing), but it was fun too! I have succeeded in managing the content children rules in a quite good way, the only downside is we cannot modify a content children and also use the same content children selector in a regular theme rule. For instance:
<before css:content-children="#one">
<span>Uno</span>
</before>
<before
css:theme="#alpha"
css:content-children="#one"
/>
would not work (the first rule would be ignored). But:
<before css:content-children="#one">
<span>Uno</span>
</before>
<before
css:theme="#alpha"
css:content="#one"
/>
would work. That's just for children rules, so I do not think it is too bad.
Note: the Python 3 compliancy broke the tests with Python 2.7, but I guess you are already aware of that, right?
Great! I will take a close look before I merge which may not be until I am at PLOG next week.
Sure, no problem. Meanwhile I will work on the 2nd PR mentioned in our #42 discussion:
<include css:content="h2" href="extra.html"/>
as a simpler syntax for:
<xsl:apply-templates select="document('extra.html', '/')//h2" mode="raw"/>
@lrowe, do you think you will have some time to review this PR (and the #44 too) ? thanks
Principle
This PR proposes to use
after
andbefore
rules to modify the content on the fly just like thereplace
rule allows to do it. Example:Implementation
It has been implemented as discussed with @lrowe in https://github.com/plone/diazo/pull/42. The resulting XSLT code is a little bit more complex than the example mentioned in this discussion (mainly to apply the rules conditions properly), but the most important thing is we do not add an extra pass over the processed document.