SDL Tridion Docs – HTML output customization - create DITA-OT plugin

Objective

Need to customize HTML output when we publish a publication from Tridion Docs.

How to Do it

We need to create DITA-OT plugin which extends html5 plugin

Let’s do it

 

What we need is Tridion Docs installed on serverWink

And we should be able to publish content on HTML5

Status should be ‘Release Candidate’ or ‘Draft’ after publish a publication

And you will see html output once click on download as below

For Map

For Topic

Let’s do some stuff with this HTML output

  • What we are going to do
  • We’ll apply some CSS on output and also add SDL logo as well.

 

We are going to need custom output format where we’ll publish this publication.

  • Let’s name it like ‘Exercise-html5output

What we are going to learn

  • Create output format with style processor on Tridion Docs
  • Customize DITA-OT html output

 

Here are steps to create new output format

  • Go to Tridion docs installation folder
  • %TRIDION_DOCS%\Web\Author\ASP\ClientConfig
  • Take backup of MetadataConfig.xml
  • Openxml and Search for DitaOTTransactionTypeField
    • Add following xml tag on enumlist tag to add transtype on Tridion Docs
               <item>

                      <value>exercise-html5</value>

                      <label resourceref="FDITAOTTRANSTYPE.ValueList.exercise-html5.Text">exercise-html5</label>

               </item>
  • Search for StyleProcessorField on xml
    • Add following xml tag to add style processor on Tridion Docs
              <item>

                      <value>DITA-OT\Exercise</value>

                      <label resourceref="FSTYLEPROCESSOR.ValueList.Exercise.Text">Exercise</label>

               </item>
    • Save MetadataConfig.xml
  • To Create Style-processor on Tridion Docs folder
    • Go to %TRIDION_DOCS%\App\Utilities\DITA-OT
    • Copy Infoshare and paste it and rename new folder to Exercise
  • Now Open Tridion Docs webclient
    • Go to Settings -> Output Format
    • Click on new button
    • Add following information on output format window and click ok
    • Now Update publish plug-in setting as this transformtype is not configured on Publish setting
      Open Publish Plug-in setting add “exercise-html5” transformation type and save it

Restart service “Trisoft InfoShare BackgroundTask One

  • This allows publication to publish on exercise-html5 output format.

 

Let’s Customize HTML format now

  • As we created Style-processor on one previous step, we will create exercise-html5 plugin
  • What is StyleProcessor in Tridion Docs
    • StyleProcessor is DITA-OT for Tridion docs, which process input DITA and render different output based on given transformation type to processor
    • In our case we’ll use transformation type exercise-html5.
  • To Create plugin Go to directory %TRIDION_DOCS%\App\Utilities\DITA-OT\Exercise\plugins
  • Right click create New folder give some name to folder which will denote your custom plugin.
    • In my case I’ll give name sdl.exercise-html5

 

  • Go to sdl.exercise-html5 directory do following steps to develop plugin
    • Create xml as DITA-OT tool will look for plugin.xml and perform operations based on that
    • Require tag on above xml allows plugin to extend “org.dita.html5” plugin which comes with dita-ot.
    • Let’s add some feature to plugin
      • Add <feature extension="dita.conductor.target.relative" file="integrator.xml"/> after transtype tag and we’ll create integrator.xml and write some xml instructions on it.
    • Please visit https://www.dita-ot.org/3.5/topics/html-customization.html to understand xml tags mentioned above.
    • Now we need to provide
      • exercise-html5.xsl
      • map2html5-cover.xsl
      • css
      • images directory
    • this would look like



    • Let’s look at each file
      • exercise.css
        /*Exercise CSS*/

         

        .topichead h2,.topictitle1 {

                       border-bottom: 1px solid #dbdbdb;

                       font-size: 36px;

            color: #b0b0b0;

            line-height: 80px;

        }

        .map, .topichead ul{

                       list-style: none;

        }

         

        .topichead ul:first-child{

                       /*padding-left: 0px;*/

                       border-bottom: 1px solid #dbdbdb;

        }

         

        .li{

                       font-size: 20px;

                       color: #757575;

            line-height: 46px;

                       margin-top: 0;

            display: block;

                       text-decoration: none;

        }

         

         a{

                       font-size: 20px;

                       /*color: #212121;*/

                       color: #757575;

            line-height: 46px;

                       margin-top: 0;

            cursor: pointer;

            /*display: block;*/

                       text-decoration: none;

        }

         

         a:hover{

                       color: #ff6700;

        }
      • exercise-html5.xsl
        <?xml version="1.0" encoding="UTF-8"?><!-- This file is part of the DITA Open Toolkit project.

             See the accompanying license.txt file for applicable licenses. --><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot" version="2.0" exclude-result-prefixes="xs dita-ot">

         

          <xsl:import href="plugin:org.dita.html5:xsl/dita2html5.xsl"/>

         

          <xsl:template match="*" mode="chapterBody">

            <body>

              <xsl:apply-templates select="." mode="addAttributesToHtmlBodyElement"/>

              <xsl:call-template name="setaname"/>  <!-- For HTML4 compatibility, if needed -->

              <xsl:value-of select="$newline"/>

              <xsl:apply-templates select="." mode="addHeaderToHtmlBodyElement"/>

         

              <!-- Include a user's XSL call here to generate a toc based on what's a child of topic -->

              <xsl:call-template name="gen-user-sidetoc"/>

         

                         <nav><div class="milogo-wrapper"><a href="index.html"><img src="images/SDL_Logo.png"/></a></div></nav>

              <xsl:apply-templates select="." mode="addContentToHtmlBodyElement"/>

              <xsl:apply-templates select="." mode="addFooterToHtmlBodyElement"/>

            </body>

            <xsl:value-of select="$newline"/>

          </xsl:template>

         

        <xsl:template match="*[contains(@class, ' topic/image ')]/@height">

          <xsl:variable name="height-in-pixel">

            <xsl:call-template name="length-to-pixels">

              <xsl:with-param name="dimen" select="."/>

            </xsl:call-template>

          </xsl:variable>

          <xsl:if test="not($height-in-pixel = '100%')">

            <xsl:attribute name="height">

              <!--xsl:choose>

                <xsl:when test="../@scale and string(number(../@scale))!='NaN'">         

                  <xsl:value-of select="number($height-in-pixel) * number(../@scale)"/>

                </xsl:when>

                <xsl:otherwise-->

                  <xsl:value-of select="number($height-in-pixel)*2"/>

                <!--/xsl:otherwise>

              </xsl:choose-->

            </xsl:attribute>

          </xsl:if> 

        </xsl:template>

         

        <xsl:template match="*[contains(@class, ' topic/image ')]/@width">

          <xsl:variable name="width-in-pixel">

            <xsl:call-template name="length-to-pixels">

              <xsl:with-param name="dimen" select="."/>

            </xsl:call-template>

          </xsl:variable>

          <xsl:if test="not($width-in-pixel = '100%')">

            <xsl:attribute name="width">

              <!--xsl:choose>

                <xsl:when test="../@scale and string(number(../@scale))!='NaN'">         

                  <xsl:value-of select="number($width-in-pixel) * number(../@scale)"/>

                </xsl:when>

                <xsl:otherwise-->

                  <xsl:value-of select="number($width-in-pixel)*2"/>

                <!--/xsl:otherwise>

              </xsl:choose-->

            </xsl:attribute>

          </xsl:if> 

        </xsl:template>

           

                      

                                     

          <xsl:output xmlns:dita="http://dita-ot.sourceforge.net" method="html" encoding="UTF-8" indent="no" doctype-system="about:legacy-compat" omit-xml-declaration="yes"/>

         

        </xsl:stylesheet>
      • map2html5-cover.xsl
         <?xml version="1.0" encoding="UTF-8"?>

        <!-- This file is part of the DITA Open Toolkit project.

             See the accompanying license.txt file for applicable licenses. -->

        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

         

          <xsl:import href="plugin:org.dita.html5:xsl/dita2html5.xsl"/>

          <xsl:import href="plugin:org.dita.xhtml:xsl/map2html-coverImpl.xsl"/>

          <xsl:import href="plugin:com.sdl.exercise-html5:xsl/exercise-nav.xsl"/>

         

         

         

          <xsl:output xmlns:dita="http://dita-ot.sourceforge.net" method="html" encoding="UTF-8" doctype-system="about:legacy-compat" omit-xml-declaration="yes"/>

         

        </xsl:stylesheet>
      • exercise-nav.xsl
        <?xml version="1.0" encoding="UTF-8"?><!-- This file is part of the DITA Open Toolkit project.

             See the accompanying license.txt file for applicable licenses. --><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot" version="2.0" exclude-result-prefixes="xs dita-ot">

         

         

          <xsl:import href="plugin:org.dita.xhtml:xsl/map2html-coverImpl.xsl"/>

         

          <xsl:template match="*[contains(@class, ' map/map ')]" mode="toc" priority="10">

            <xsl:param name="pathFromMaplist"/>

            <xsl:if test="descendant::*[contains(@class, ' map/topicref ')]                                [not(@toc = 'no')]                                [not(@processing-role = 'resource-only')]">

              <nav>

                         <div class="milogo-wrapper"><a href="index.html"><img src="images/SDL_Logo.png"/></a>test</div>

                <ul>

                  <xsl:call-template name="commonattributes"/>

                  <xsl:apply-templates select="*[contains(@class, ' map/topicref ')]" mode="toc">

                    <xsl:with-param name="pathFromMaplist" select="$pathFromMaplist"/>

                  </xsl:apply-templates>

                </ul>

              </nav>

            </xsl:if>

          </xsl:template>

         

         

          <xsl:template match="*[contains(@class, ' map/topicref ')]                         [not(@toc = 'no')]                         [not(@processing-role = 'resource-only')]" mode="toc">

            <xsl:param name="pathFromMaplist"/>

            <xsl:variable name="title">

              <xsl:apply-templates select="." mode="get-navtitle"/>

            </xsl:variable>

            <xsl:choose>

              <xsl:when test="normalize-space($title)">

                <li>

                  <xsl:call-template name="commonattributes"/>

                  <xsl:choose>

                    <!-- If there is a reference to a DITA or HTML file, and it is not external: -->

                    <xsl:when test="normalize-space(@href)">

                      <a>

                        <xsl:attribute name="href">

                          <xsl:choose>

                            <xsl:when test="@copy-to and not(contains(@chunk, 'to-content')) and                                      (not(@format) or @format = 'dita' or @format = 'ditamap') ">

                              <xsl:if test="not(@scope = 'external')">

                                <xsl:value-of select="$pathFromMaplist"/>

                              </xsl:if>

                              <xsl:call-template name="replace-extension">

                                <xsl:with-param name="filename" select="@copy-to"/>

                                <xsl:with-param name="extension" select="$OUTEXT"/>

                              </xsl:call-template>

                              <xsl:if test="not(contains(@copy-to, '#')) and contains(@href, '#')">

                                <xsl:value-of select="concat('#', substring-after(@href, '#'))"/>

                              </xsl:if>

                            </xsl:when>

                            <xsl:when test="not(@scope = 'external') and (not(@format) or @format = 'dita' or @format = 'ditamap')">

                              <xsl:if test="not(@scope = 'external')">

                                <xsl:value-of select="$pathFromMaplist"/>

                              </xsl:if>

                              <xsl:call-template name="replace-extension">

                                <xsl:with-param name="filename" select="@href"/>

                                <xsl:with-param name="extension" select="$OUTEXT"/>

                              </xsl:call-template>

                            </xsl:when>

                            <xsl:otherwise><!-- If non-DITA, keep the href as-is -->

                              <xsl:if test="not(@scope = 'external')">

                                <xsl:value-of select="$pathFromMaplist"/>

                              </xsl:if>

                              <xsl:value-of select="@href"/>

                            </xsl:otherwise>

                          </xsl:choose>

                        </xsl:attribute>

                        <xsl:if test="@scope = 'external' or not(not(@format) or @format = 'dita' or @format = 'ditamap')">

                          <xsl:attribute name="target">_blank</xsl:attribute>

                        </xsl:if>

                        <xsl:value-of select="$title"/>

                      </a>

                    </xsl:when>

                    <xsl:otherwise>

                                                                    <xsl:choose>

                                                                     <xsl:when test="$title and $title != ''">

                                                                       <h2><xsl:value-of select="$title"/></h2>

                                                                     </xsl:when>

                                                                     <xsl:otherwise>

                                                                      <xsl:value-of select="$title"/>

                                                                     </xsl:otherwise>

                                                                    </xsl:choose>

                    </xsl:otherwise>

                  </xsl:choose>

                  <!-- If there are any children that should be in the TOC, process them -->

                  <xsl:if test="descendant::*[contains(@class, ' map/topicref ')]                                      [not(@toc = 'no')]                                      [not(@processing-role = 'resource-only')]">

                    <ul>

                      <xsl:apply-templates select="*[contains(@class, ' map/topicref ')]" mode="toc">

                        <xsl:with-param name="pathFromMaplist" select="$pathFromMaplist"/>

                      </xsl:apply-templates>

                    </ul>

                  </xsl:if>

                </li>

              </xsl:when>

              <xsl:otherwise><!-- if it is an empty topicref -->

                <xsl:apply-templates select="*[contains(@class, ' map/topicref ')]" mode="toc">

                  <xsl:with-param name="pathFromMaplist" select="$pathFromMaplist"/>

                </xsl:apply-templates>

              </xsl:otherwise>

            </xsl:choose>

          </xsl:template>

         

                      

                                     

          <xsl:output xmlns:dita="http://dita-ot.sourceforge.net" method="html" encoding="UTF-8" indent="no" doctype-system="about:legacy-compat" omit-xml-declaration="yes"/>

         

        </xsl:stylesheet>
      • this will customize your html output.
    • Let’s create new output format for publication and select exercise-html5 from dropdown
    • Click next select language and click create.
    • Now select output format and click publish
    • index.html would look like
    • And topic page would look like