Help with XSTL extension
Post here questions and problems related to editing and publishing DITA content.
-
- Posts: 19
- Joined: Sat Jun 24, 2023 7:35 pm
Help with XSTL extension
I've spent many hours trying to debug the extension of DITA to WebHelp Responsive that I wrote which comes up with empty results. I want to add Open Graph metadata to each page based on the metadata in that page. I followed this guide to the note, rereading it several times: https://www.oxygenxml.com/doc/versions/ ... mport.html and I am successfully adding the <meta> tags where I want them in the output, but the content is always empty and I cannot figure out why, and I'm getting horribly frustrated. Note: I have no knowledge of XSLT transformations, I'm trying to learn from scratch.
Here's a shortened version of my DITA and .xls files, where I'm trying to get out the title and shortdesc of the current file and put them into og metadata:
(but I want it to work for task/topic as well)
I've tried:
//title
/*/title
/*/*/title
/*/*:title
Nothing works, the resultant meta is always: <meta property="og:title" content=""/>
However, frustrating as it is, when I try:
$toc/title
(as in: https://www.oxygenxml.com/doc/versions/ ... mport.html)
It works, taking the title of the ditamap...
Please, help, and also maybe include an example of using values from the current DITA file instead of $toc in the documentation please?
Thank you in advance.
Here's a shortened version of my DITA and .xls files, where I'm trying to get out the title and shortdesc of the current file and put them into og metadata:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="about">
<title>Title</title>
<shortdesc>Description</shortdesc>
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:whc="http://www.oxygenxml.com/webhelp/components"
exclude-result-prefixes="xs whc"
version="3.0">
<xsl:template match="*:meta[contains(@name, 'viewport')]" mode="copy_template">
<!-- I was trying to find a way to match the head element and put this inside but I could not, so I decided to put the new meta elements after one element that exists in the original template -- and this works correctly -->
<xsl:next-match/>
<xsl:element name="meta" namespace="http://www.w3.org/1999/xhtml">
<!-- I'm adding this because otherwise I had xmlns="" attributes in every meta -->
<xsl:attribute name="property">og:title</xsl:attribute>
<xsl:attribute name="content">
<xsl:value-of select="/*/*:title"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="meta" namespace="http://www.w3.org/1999/xhtml">
<xsl:attribute name="property">og:description</xsl:attribute>
<xsl:attribute name="content">
<xsl:value-of select="/*/*:shortdesc"/>
</xsl:attribute>
</xsl:element>
<!-- there's more but if I can get these 2 to work, I feel I can get anything else to work -->
</xsl:template>
</xsl:stylesheet>
//title
/*/title
/*/*/title
/*/*:title
Nothing works, the resultant meta is always: <meta property="og:title" content=""/>
However, frustrating as it is, when I try:
$toc/title
(as in: https://www.oxygenxml.com/doc/versions/ ... mport.html)
It works, taking the title of the ditamap...
Please, help, and also maybe include an example of using values from the current DITA file instead of $toc in the documentation please?
Thank you in advance.
-
- Posts: 9473
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Help with XSTL extension
Hi,
I will try to give you some more general answers in order to help you help yourself.
A WebHelp publishing customization allows adding XSLT extension points. What extension point ID are you using in your customization. For example:
The extension point ID in this case is "com.oxygenxml.webhelp.xsl.createMainPage", is this the extension point ID you are using?
There are multiple extension points which can be used, depending on what needs to be done:
https://www.oxygenxml.com/doc/versions/ ... uyr_b1y_bx
In your case I would probably use this "com.oxygenxml.webhelp.xsl.dita2webhelp" extension point as I want to influence how HTML content is produced from each DITA XML topic.
Your current XSLT stylesheet has a template like this:
To me it looks like your XSLT template is applied not on a DITA XML topic (which does not contain inside <meta> elements), but on an HTML page.
In such cases I would add an xsl:message inside the xsl:template to see the main file on which the XSLT is applied:
In the Oxygen Preferences->"DITA / Logging" page you can set the "Show console output->Always" flag, the publish and the "DITA OT" console tab view should show all the output coming from the DITA OT process, including the xsl:messages.
So you can use in general xsl:messages to debug your work.
So when using XPath expressions like "/*/*:shortdesc" in general, you need to use xsl:message's first and find out on what /* root element your XSLT stylesheet is applied.
As an example WebHelp customization, I added multiple XSLT customizations for the Oxygen XML Blog:
https://github.com/oxygenxml/blog/blob/ ... mplate.opt
For example:
refers to:
https://github.com/oxygenxml/blog/blob/ ... custom.xsl
which refers to this stylesheet which adds a <script> in the header of each HTML page constructed from a DITA XML topic:
https://github.com/oxygenxml/blog/blob/ ... edData.xsl
Regards,
Radu
I will try to give you some more general answers in order to help you help yourself.
A WebHelp publishing customization allows adding XSLT extension points. What extension point ID are you using in your customization. For example:
Code: Select all
<xslt>
<extension
file="xslt/customMainPage.xsl"
id="com.oxygenxml.webhelp.xsl.createMainPage"/>
There are multiple extension points which can be used, depending on what needs to be done:
https://www.oxygenxml.com/doc/versions/ ... uyr_b1y_bx
In your case I would probably use this "com.oxygenxml.webhelp.xsl.dita2webhelp" extension point as I want to influence how HTML content is produced from each DITA XML topic.
Your current XSLT stylesheet has a template like this:
Code: Select all
<xsl:template match="*:meta[contains(@name, 'viewport')]" mode="copy_template">
In such cases I would add an xsl:message inside the xsl:template to see the main file on which the XSLT is applied:
Code: Select all
<xsl:message>Main file on which XSLT is applied: <xsl:copy-of select="/*"/></xsl:message>
So you can use in general xsl:messages to debug your work.
So when using XPath expressions like "/*/*:shortdesc" in general, you need to use xsl:message's first and find out on what /* root element your XSLT stylesheet is applied.
As an example WebHelp customization, I added multiple XSLT customizations for the Oxygen XML Blog:
https://github.com/oxygenxml/blog/blob/ ... mplate.opt
For example:
Code: Select all
<extension file="xslt/custom.xsl" id="com.oxygenxml.webhelp.xsl.dita2webhelp"/>
https://github.com/oxygenxml/blog/blob/ ... custom.xsl
which refers to this stylesheet which adds a <script> in the header of each HTML page constructed from a DITA XML topic:
https://github.com/oxygenxml/blog/blob/ ... edData.xsl
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
-
- Posts: 19
- Joined: Sat Jun 24, 2023 7:35 pm
Re: Help with XSTL extension
Thank you, Radu, you're always so helpful. Let me elaborate a bit and answer your questions and add more questions of my own.
As said, please bear with me as I'm not an XML/XSLT specialist, far from it, just a simple technical writer (network security)
I'm trying to fasttrack-learn based mostly on examples that I can find and on trial-and-error.
First of all, I am using com.oxygenxml.webhelp.xsl.dita2webhelp indeed, I already figured those extension points out thanks to extensive googling and someone else's example somewhere on the forum
. So the process of actually getting the right extension to work etc. is covered: otherwise I would not be getting new <meta> tags in the output (the ones with empty content).
I was thinking it may be that the problems I'm encountering are due to the fact that the transformation is applied to the HTML template instead of the DITA file, but I was unable to find any information "for noobs" that would help me do it in a different way.
What I did is I simply followed your example here: https://www.oxygenxml.com/doc/versions/ ... mport.html -- I was trying to take this example and modify it for my needs. This example clearly creates new DIV tags in resultant HTML from the source tags in DITA, so I thought that following this example would be a good idea. Now I see that it's probably that the example in your docs is simply incomplete: probably "before the code" that is shown, you would have to define $toc, which would point to the source template (but I don't know how to do that yet...).
Also, when I was trying to create the right <xsl:template match="..."> to put the output of the transformation inside the <head>, I was searching for different existing <meta> tags to simply place my new tags after them, and I discovered that I had to search for a <meta> tag that was actually in the template. So, I don't feel it's possible to e.g. take the Open Graph content from other <meta> tags already added by other transformations (i.e. to place this transformation at the "end of the process" after everything else is added to the HTML, and apply it not to the template file but to the resultant HTML files)...
So, to sum up, my primary and I think only problem in this case is understanding how the XSLT operations are applied to different files: taking information from source DITA files and outputting it in the HTML files...
As said, please bear with me as I'm not an XML/XSLT specialist, far from it, just a simple technical writer (network security)

First of all, I am using com.oxygenxml.webhelp.xsl.dita2webhelp indeed, I already figured those extension points out thanks to extensive googling and someone else's example somewhere on the forum

I was thinking it may be that the problems I'm encountering are due to the fact that the transformation is applied to the HTML template instead of the DITA file, but I was unable to find any information "for noobs" that would help me do it in a different way.
What I did is I simply followed your example here: https://www.oxygenxml.com/doc/versions/ ... mport.html -- I was trying to take this example and modify it for my needs. This example clearly creates new DIV tags in resultant HTML from the source tags in DITA, so I thought that following this example would be a good idea. Now I see that it's probably that the example in your docs is simply incomplete: probably "before the code" that is shown, you would have to define $toc, which would point to the source template (but I don't know how to do that yet...).
Also, when I was trying to create the right <xsl:template match="..."> to put the output of the transformation inside the <head>, I was searching for different existing <meta> tags to simply place my new tags after them, and I discovered that I had to search for a <meta> tag that was actually in the template. So, I don't feel it's possible to e.g. take the Open Graph content from other <meta> tags already added by other transformations (i.e. to place this transformation at the "end of the process" after everything else is added to the HTML, and apply it not to the template file but to the resultant HTML files)...
So, to sum up, my primary and I think only problem in this case is understanding how the XSLT operations are applied to different files: taking information from source DITA files and outputting it in the HTML files...
-
- Posts: 19
- Joined: Sat Jun 24, 2023 7:35 pm
Re: Help with XSTL extension
I'm attempting a different approach now. Could I just pretty please ask for a working solution and then I will try and backtrack why it works, instead of trying to give me general information? I learn much better on working examples than on theories...
This is my example .xsl file now based on more googling and trying to understand your examples from the blog:
And this is in my publishing template at its end:
Unfortunately, it's not working either because is it's applying the transformation to the raw template, and not to the resultant HTML files, and I cannot find any information how to apply it to the resultant HTML files just before they would be ready to be published, at the very end of the process... I confirmed this with the test message inside a template that matches "head", the file it applies to begins with:
Thank you so much in advance.
EDIT: Spent 10 more hours trying every single possible approach, trying to get ChatGPT to help, without actual working code I will not be able to do this with the hints provided.
This is my example .xsl file now based on more googling and trying to understand your examples from the blog:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="meta[contains(@name, 'wh-out-relpath')]">
<!-- I'm trying to find the wh-out-relpath meta, which is the last <meta> element added by the Oxygen transformation, and trying to add my OG meta after it, but nothing is added at all, as if the wh-out-relpath is not found, probably due to the fact that what is being processed is the template file, not the final html file -->
<xsl:copy-of select="."/>
<xsl:element name="meta" namespace="http://www.w3.org/1999/xhtml">
<xsl:attribute name="property">og:title</xsl:attribute>
<xsl:attribute name="content">
<xsl:value-of select="//title"/>
</xsl:attribute>
</xsl:element>
<xsl:element name="meta" namespace="http://www.w3.org/1999/xhtml">
<xsl:attribute name="property">og:description</xsl:attribute>
<xsl:attribute name="content">
<xsl:value-of select="//meta[@name='description']/@content"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Code: Select all
<xslt>
<extension file="xsl/metadata.xsl" id="com.oxygenxml.webhelp.xsl.dita2webhelp"/>
</xslt>
Code: Select all
[pipeline] <html xmlns="http://www.w3.org/1999/xhtml"
[pipeline] xmlns:whc="http://www.oxygenxml.com/webhelp/components"
[pipeline] whc:version="26.1">
[pipeline] <head>
[pipeline] <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
[pipeline] <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
[pipeline] <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
[pipeline] <whc:page_libraries page="topic"/>
[pipeline] <whc:webhelp_skin_resources/>
EDIT: Spent 10 more hours trying every single possible approach, trying to get ChatGPT to help, without actual working code I will not be able to do this with the hints provided.
-
- Posts: 19
- Joined: Sat Jun 24, 2023 7:35 pm
Re: Help with XSTL extension
To be perhaps more direct and for this to be more useful in the future, I'm looking for code that will let me:
1. Take the following element values from the DITA topic/task/concept:
- title
- shortdesc
- prolog/author
- prolog/copyright/copyryear
(etc.)
2. Put these values in the following HTML tags anywhere in the <head> element of the WebHelp Responsive transformation:
<meta property="og:title" content="value_of_title"/>
<meta property="og:description" content="value_of_shortdesc"/>
(etc.)
1. Take the following element values from the DITA topic/task/concept:
- title
- shortdesc
- prolog/author
- prolog/copyright/copyryear
(etc.)
2. Put these values in the following HTML tags anywhere in the <head> element of the WebHelp Responsive transformation:
<meta property="og:title" content="value_of_title"/>
<meta property="og:description" content="value_of_shortdesc"/>
(etc.)
-
- Posts: 19
- Joined: Sat Jun 24, 2023 7:35 pm
Re: Help with XSTL extension
Finally, after around 20 hours in total, I figured it out by examining the DITA-OT files and finding the gen-metadata mode...
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="*[contains(@class, ' topic/title ')]" mode="gen-metadata">
<xsl:variable name="titlemeta">
<xsl:apply-templates select="* | text()" mode="text-only"/>
</xsl:variable>
<meta property="og:title">
<xsl:attribute name="content">
<xsl:value-of select="normalize-space($titlemeta)"/>
</xsl:attribute>
</meta>
<meta property="og:url">
<xsl:attribute name="content">
<xsl:value-of select="concat('https://docs.portnox.com/topic/', ../@id)"/>
</xsl:attribute>
</meta>
</xsl:template>
<xsl:template match="*[contains(@class, ' topic/shortdesc ')]" mode="gen-metadata">
<xsl:variable name="shortmeta">
<xsl:apply-templates select="* | text()" mode="text-only"/>
</xsl:variable>
<meta property="og:description">
<xsl:attribute name="content">
<xsl:value-of select="normalize-space($shortmeta)"/>
</xsl:attribute>
</meta>
</xsl:template>
<xsl:template match="*[contains(@class, ' topic/author ')]" mode="gen-metadata">
<xsl:variable name="authormeta">
<xsl:apply-templates select="* | text()" mode="text-only"/>
</xsl:variable>
<meta name="author">
<xsl:attribute name="content">
<xsl:value-of select="normalize-space($authormeta)"/>
</xsl:attribute>
</meta>
</xsl:template>
</xsl:stylesheet>
-
- Posts: 9473
- Joined: Fri Jul 09, 2004 5:18 pm
Re: Help with XSTL extension
Hi,
Thanks for posting the solution.
The stylesheet "DITA-OT/plugins/org.dita.html5/xsl/topic.xsl" has a template which generates the <head>
and in the XSLT stylesheet "DITA-OT/plugins/org.dita.html5/xsl/get-meta.xsl" there are lots of templates in the "getMeta" mode which can be overwritten from someone's XSLT customization.
Regards,
Radu
Thanks for posting the solution.
The stylesheet "DITA-OT/plugins/org.dita.html5/xsl/topic.xsl" has a template which generates the <head>
Code: Select all
<xsl:template match="*" mode="chapterHead">
<head>
<!-- initial meta information -->
<xsl:call-template name="generateCharset"/> <!-- Set the character set to UTF-8 -->
<xsl:apply-templates select="." mode="generateDefaultCopyright"/> <!-- Generate a default copyright, if needed -->
<xsl:call-template name="generateDefaultMeta"/> <!-- Standard meta for security, robots, etc -->
<xsl:apply-templates select="." mode="getMeta"/> <!-- Process metadata from topic prolog -->
<xsl:call-template name="copyright"/> <!-- Generate copyright, if specified manually -->
<xsl:call-template name="generateChapterTitle"/> <!-- Generate the <title> element -->
<xsl:call-template name="gen-user-head" /> <!-- include user's XSL HEAD processing here -->
<xsl:call-template name="gen-user-scripts" /> <!-- include user's XSL javascripts here -->
<xsl:call-template name="gen-user-styles" /> <!-- include user's XSL style element and content here -->
<xsl:call-template name="processHDF"/> <!-- Add user HDF file, if specified -->
<xsl:call-template name="generateCssLinks"/> <!-- Generate links to CSS files -->
</head>
</xsl:template>
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
<oXygen/> XML Editor
http://www.oxygenxml.com
Return to “DITA (Editing and Publishing DITA Content)”
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ Artificial Intelligence (AI Positron Assistant add-on)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service