Topic Specialization Step 4-4 (continued): Implement Specialization-Specific XSLT Processing
Having reworked the markup design to provide a short answer and answer details, pop back up to step 4-4 and continue implementing the XSLT processing.
<faq-answer>
to match on
"faq-answer-details" instead of "faq-answer":
<xsl:template match="*[contains(@class, ' faq-question/faq-answer-details ')]">
- Delete all the comments between the call-template to "start-revtag" and the apply-templates for "topic/abstract."
- Because we have removed
<abstract>
from the content model for<faq-question>
, you can delete the apply-templates instruction that matches on "topic/abstract." Having the instruction there wouldn't hurt anything (there will never be an abstract to match on), but it might confuse somebody who knows the content model for<faq-question>
. However, since somebody who knows the content model for topic might expect there to be a match on<abstract>
, it's probably a good idea to provide a comment to the effect that<faq-question>
doesn't allow<abstract>
. - Put a
<div>
with a@class
attribute value of "faq-answer-details" around the last "apply-templates" call:<div class="faq-answer-details"> <xsl:apply-templates/> </div>
This
<div>
clearly separates the answer details from the short answer and the@class
value provides a hook that can be used in CSS styles or JavaScript to add additional formatting or behavior to the answer details.
<xsl:template match="*[contains(@class, ' faq-question/faq-answer-details ')]"> <xsl:variable name="flagrules"> <xsl:call-template name="getrules"/> </xsl:variable> <div> <xsl:call-template name="commonattributes"/> <xsl:call-template name="gen-style"> <xsl:with-param name="flagrules" select="$flagrules"></xsl:with-param> </xsl:call-template> <xsl:call-template name="setidaname"/> <xsl:call-template name="start-flagit"> <xsl:with-param name="flagrules" select="$flagrules"></xsl:with-param> </xsl:call-template> <xsl:call-template name="start-revflag"> <xsl:with-param name="flagrules" select="$flagrules"/> </xsl:call-template> <!-- Abstract not allowed in faq-question topic type --> <!-- get the shortdesc para --> <xsl:apply-templates select="preceding-sibling::*[contains(@class,' topic/shortdesc ')]" mode="outofline"/> <!-- Insert pre-req links - after shortdesc - unless there is a prereq section about --> <xsl:apply-templates select="following-sibling::*[contains(@class,' topic/related-links ')]" mode="prereqs"/> <div class="faq-answer-details"> <xsl:apply-templates/> </div> <xsl:call-template name="end-revflag"> <xsl:with-param name="flagrules" select="$flagrules"/> </xsl:call-template> <xsl:call-template name="end-flagit"> <xsl:with-param name="flagrules" select="$flagrules"></xsl:with-param> </xsl:call-template> </div><xsl:value-of select="$newline"/> </xsl:template>
Without having tested it yet, the template now looks like it should be right: it's
not getting the
abstract, it is processing the short description (our new <faq-short-answer>
) and the
rest of the processing should be appropriate.
Redeploy the Toolkit plugin and run the transform against your sample FAQ question. You should get the same output you got before since all we really did was change the template match value and cut away stuff we didn't need.
The next step in the implementation is to handle the <faq-short-answer>
element.
The formatting specification says to output "A. " followed by the answer text. To do
this we need a template that matches on " faq-question/faq-short-answer ". Note
that even though <faq-short-answer>
is specialized from
<shortdesc>
, it would not make sense to simply override the
processing for <shortdesc>
, as that would change the formatting for all
other topic types.
<xsl:template match="*[contains(@class, ' faq-question/faq-short-answer ')]" mode="outofline"> <div class="faq-short-answer"> <span class="faq-short-answer-a">A. </span> <xsl:apply-templates/> </div> </xsl:template>
@mode
attribute with the value "outofline." This is necessary
because the short description is being processed out of its normal source order, that
is
from within the processing for the topic body (to which <shortdesc>
is
a sibling) rather than from with the processing of <topic>
(of which it
is a child). The base DITA stylesheets provide a generic way to handle this using
the
mode "outofline" for all templates that handle elements processed out of their
normal document order. You can see that the mode is used on the apply templates in
the
template for <faq-question>
:
<xsl:template match="*[contains(@class, ' faq-question/faq-answer-details ')]" priority="10"> <div> ... <!-- get the shortdesc para --> <xsl:apply-templates select="preceding-sibling::*[contains(@class,' topic/shortdesc ')]" mode="outofline"/> ... </div> <xsl:value-of select="$newline"/> </xsl:template>
If you didn't specify the corresponding mode on the match template for
<faq-short-answer>
, you would get the answer text twice, once from
base outofline mode template that matches on " topic/shortdesc " and once for the
default mode template that matches on " faq-question/faq-short-answer ".
This template will put out "A. " before the short description. The
@class
values are there to support styling the result using CSS.
Redeploy the Toolkit plugin, run the sample FAQ answer through the Toolkit, and inspect the results. You should now see the "A. " before the short answer text (the first paragraph of the result). This means that the XSLT is done. The next step is to create or update the applicable CSS stylesheet to add the appropriate styling to the HTML pages.