Putting a "Return to Top" link only on select paragraphs
The Requirements
Wanting a return to top link per paragraph
The Challenge
First before anything else, you have to make a modification to the page template to include an anchor. Since Page.asp contains conditions, you have to make them match the ones set for the "Page content with header/footer" and the "Page content with no header/footer." and change it so it would look like the following:
<a wwpage:condition="header-footer-exists" name="topcontent">Top of the page</a> <blockquote wwpage:condition="header-footer-exists" wwpage:content="content"> Page content with header/footer. </blockquote> <a wwpage:condition="header-footer-not-exists" name="topcontent">Top of the page</a> <div wwpage:condition="header-footer-not-exists" wwpage:replace="content"> Page content with no header/footer. </div>
For more information on page template modifications and appropriate conditions, you can refer to the following: http://wiki.webworks.com/DevCenter/Documentation/PageTemplates#defining-conditions-and-replacements
After this has been set, you could, if you have no tables or bullets (highly unlikely) simply add a modification to the content.xsl file located in Formats\[your format]\Transforms and put
<html:a href="#returntop">Return to top</html:a>
Underneath the
<!-- End paragraph emit -->
comment
However, this returns less than favorable results. When trying this, the link would appear under every item in the content that contained a carriage return. Epublisher treats every Paragraph style (Headings, bullets, and even table cells) as its own break. This is great for styling, not so great for semantics (treating multi-line text rather than just single lines of text as a paragraph) Mad props to JesseWiles, though to at least pointing me in the right direction to get started with looking at the </xsl:element> tag to put in my code.
The Code
Requirements are to put a link under Body paragraphs and having some sort of logic to control the XSL to only recognize certain paragraph style. In lieu of having this style hardcoded in the XSL, we would want a switch that the user can control in the UI. Mad shouts to BenAllums too, because he suggested creating an FTI setting that will let the user switch on or off if a given Paragraph style will get this return to top link.
For more information on FTI settings, refer to the following page: http://wiki.webworks.com/DevCenter/Documentation/FTI
Content.xsl
We heart content.xsl, because it is like totally our BFF:
So, we have to create a boolean <xsl:if> statement in order to get this FTI setting to appear as "true" but we need to grab this from user input from the FTI (discussed next) So we don't have to reinvent the wheel, Ben suggested looking to the "Use character style" options around line 817
<xsl:variable name="VarUseCharacterStylesOption" select="$ParamOverrideRule/wwproject:Options/wwproject:Option[@Name = 'use-character-styles']/@Value" /> <xsl:variable name="VarUseCharacterStyles" select="(string-length($VarUseCharacterStylesOption) = 0) or ($VarUseCharacterStylesOption = 'true')" />
So based on this code, I modified it slightly to look like this
<xsl:variable name="VarEmitReturnToTopLinkOption" select="$ParamOverrideRule/wwproject:Options/wwproject:Option[@Name = 'emit-return-to-top-link']/@Value " /> <xsl:variable name="VarEmitReturnToTopLink" select="$VarEmitReturnToTopLinkOption = 'true'" /> <xsl:if test="$VarEmitReturnToTopLink"> <a href="#topcontent">Return to top...</a>
Basically, we are taking the value of the attributes in the heirarchy of the Options and the Option in the pages.fti (will make more since when you open it up) and the "emit-return-to-top-link" attribute and testing to see if they are true based on the user input. If you want to learn more about the ins and outs of XSL and how it relates to ePublisher, I would suggest taking a look at the following: http://wiki.webworks.com/DevCenter/Documentation/Engine
Pages.fti
We have to make the modification to the Pages.fti in order for us to actually see the switch:In the same directory as the content.xsl file, you will have the FTI file (copied from your favorite format and pasted in your project directory)
<Option name="emit-return-to-top-link" group="options" default="false"> <OptionClass name="boolean" /> </Option>
Page.asp
Returning to page conditions, you modify the page template as was mentioned earlier:
<a wwpage:condition="header-footer-exists" name="topcontent">Top of the page</a> <blockquote wwpage:condition="header-footer-exists" wwpage:content="content"> Page content with header/footer. </blockquote> <a wwpage:condition="header-footer-not-exists" name="topcontent">Top of the page</a> <div wwpage:condition="header-footer-not-exists" wwpage:replace="content"> Page content with no header/footer. </div>
Generate, generate, generate
Save these files, save your project, reopen ePublisher, and voila you have your switch and then you can regenerate with the "Back to Top" links
If you look at the content.xsl code above and are familiar with XSL, you will recognize the paths that we used to get this modification and why they were like that. If not, well you can trust me.
Support Goddess Notes
- Your variables, elements, attributes and existence must have case sensitivity, otherwise this will not work.
Tested in CHM and WebWorks Help 5.0 formats.
- Best advice if working with multiple Formats: start from scratch each time.
- Don't try to copy and paste between multiple versions of content.xsl
- Very messy and you might get an error like this:
[Error] Error occurred while reading tranform 'wwformat:Transforms\popups.xsl' from file 'C:\Program Files\WebWorks\ePublisher\2009.4\Formats\Microsoft HTML Help 1.x\Transforms\popups.xsl'. [Error] An 'xsl:call-template' element cannot have text node children.
Yuck! So, just take your time, have a few cups of espresso and enjoy the world of XSL modifications.
2013-04-02: Can This Be Done with Reverb?
I’m trying to find a good way to implement return to top links and I would like to add this code to my Reverb stationery project, but I’m having some problems.
I added the VarEmitReturnToTopLinkOption code indicated above to Content.xsl following the end of the code for the VarUseCharacterStylesOption.
I added the emit-return-to-top-link code indicated above to Pages.fti as a child of the <RuleTraits category=”Paragraph”> <Options>.
I added the conditions code indicated above to Page.asp as a child of the <div wwpage:replace=”content”>Page content.</div> (Should I put that code outside of this <div> code?)
I created a paragraph format in the FrameMaker file called emit-return-to-top-link and used it where I want return to top links in the output. (Do I need to create a new custom marker or use a different name for the format?)
When I tried to generate the output in ePublisher Express using the new stationery, I got these errors:
[Error] Error occurred while reading tranform 'wwformat:Transforms\wrappers.xsl' from file 'J:\Reverb_Stationery_Back_To_Top_Test\Reverb_Output\Reverb_TEB_Admin_Test\Formats\WebWorks Reverb.base\Transforms\wrappers.xsl'. [Error] XSLT compile error. [Error] The 'xsl:if' start tag on line 825 does not match the end tag of 'xsl:template'. Line 1056, position 4.
I don’t have any overrides in the wrappers.xsl file. Do I need to add something there due to the other overrides?
So you can see what I've done, I have uploaded a zip file containing the project folder with the master design project wep file and format overrides, the source FrameMaker file with the paragraph formats used, and a text error log file: Reverb-Return-To-Top-Files.zip.
2013-04-23: Some Progress in Reverb
I tried a different approach that works, but I can’t quite get it to work as well as I’d like it to. I got a Back to Top link that works to go to the breadcrumbs just under the toolbar, but I’d like it to go all the way to the top of the page. I’ve also been able to get a Back to Top link that goes to the top of the page, but that one does not work consistently.
For the one that consistently works to go back to the breadcrumbs, first I added this code just above the <header> in Page.asp:
<div id="page-top"> </div>
Next I added this to skin.css:
/* Toplink */ #cr_toplink { Text-align: left; font-family: Arial, sans-serif; font-size: 90%; }
Then I added the PassThrough marker type to my FrameMaker file with this code in the Marker Text:
<div id="cr_toplink"> <p> <a href="#page-top" id="cr_toplink">Back to top</a> </p> </div>
I would like the Back to Top link to take the reader all the way to the top of the page, so they see the toolbar at the top of the screen as well as the breadcrumbs. So, I tried changing the PassThrough marker code to link to div ids in Connect.asp instead of the <div id=”page-top”> I put in Page.asp. I’ve tried using #Page-top, #layout_div, and #presentation_div (not at the same time). All three of these links worked to take the reader to the top of the page, but only the second time the page is loaded in the browser. So, when opening a page with the Back to Top links for the first time, the links do not work at all. When opening the next page, then going back to the first page opened with the Back to Top links, the links work.
I also tried removing the <div id=”page-top”> from Page.asp and putting it in Connect.asp directly above <div id=”layout_div”…> and then linking to it in the PassThrough marker, but this did not work. It seems that the PassThrough marker links only work consistently when I’m linking to something in Page.asp.
Can anyone suggest an improvement that can get the Back to top links to take the reader to the very top of the page?
2013-05-22: This Works in Reverb!
Ignore the entry above about the PassThrough marker. LaurenLever helped me get this working in my Reverb output with the paragraph tags in the FrameMaker source files. It involves a little more coding than the PassThrough marker, but the paragrah tag option is much easier to work with in the source files than the PassThrough marker.
Content.xsl
For Lauren's Content.xsl code above, she noticed I needed to add a line at the end with </xsl:if>. I also added some <div>, <p>, and <id> code for my own skin.css requirements (see below). So, now it looks like this:
<xsl:variable name="VarEmitReturnToTopLinkOption" select="$ParamOverrideRule/wwproject:Options/wwproject:Option[@Name = 'emit-return-to-top-link']/@Value " /> <xsl:variable name="VarEmitReturnToTopLink" select="$VarEmitReturnToTopLinkOption = 'true'" /> <xsl:if test="$VarEmitReturnToTopLink"> <div id="cr_toplink"> <p> <a href="#topcontent" id="cr_toplink">Return to top...</a> </p> </div> </xsl:if>
I put that code after the code starting with <!-- Use character styles? --> and ending with ($VarUseCharacterStylesOption = 'true')" />
Pages.fti
For the Pages.fti code above, I added it in the <RuleTraits category="Paragraph"> before the final closing </Options>. So, at the end of that <RuleTraitsSet> it looks like this (with the </Options>):
<Option name="emit-return-to-top-link" group="options" default="false"> <OptionClass name="boolean" /> </Option> </Options>
Page.asp
For Page.asp, I could not get it to work with Lauren's page conditions code. Lauren suggested that I instead use a simple anchor around line 69 of Page.asp: <a name="topcontent">Top of the page</a> right before the:
<div wwpage:replace="content"> Page content. </div>
I didn't like that "Top of the page" was showing in the output and I wanted the Return to Top links to take the reader all the way to the top of the page instead of below the breadcrumbs. So instead, I added this directly above the <header>:
<div id="topcontent"> </div>
With this code above the <header>, the Return to Top links take the reader to the breadcrumbs on any page starting with a Head1 paragraph tag and all the way to the Company Info section at the very top of the page for any page starting with a Head2 or smaller heading paragraph tag.
skin.css
This method requires an addition to skin.css to format the Return to Top links in the output. For my project, I added this code at the end of skin.css:
/* Toplink */ #cr_toplink { text-align: left; font-family: Arial, sans-serif; font-size: 90%; }
FrameMaker Source File
In the FrameMaker source files, I added a new paragraph tag named BackToTopLink.
Stationery Project
The last piece of the puzzle, I'm embarassed to say I missed before Lauren helped me, was to open my stationery project in WebWorks Designer. For the BackToTopLink paragraph style, I set emit-return-to-top-link to Enabled in the Options.
This is working consistently with my Reverb output. If someone knows of a better way to consistently get the reader to the very top of the page from the Return to Top links, I'd love to know about it.
Many thanks to Lauren for the code and troubleshooting in Reverb! Hail, Support Goddess!