Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jimmy Dan Mortensen 77 posts 197 karma points
    Jan 09, 2013 @ 08:58
    Jimmy Dan Mortensen
    0

    Hierachy in Sitemap

    First of all I'd like to state that I'm still a newbie to the world of Umbraco - so treat me kindly ;-)

    I have a problem with my sitemap. The first 2 levels on each "main-node" should not be a link, as I only use it as way to "structure" my website.

    You can see the sitemap here: http://www.hessel.dk/sitemap.aspx

    The problem is that the first 2 levels isn't clickable, and the 3nd level is the first that actually links to something usefull. Those 2 levels shouldn't be indexed if I understand the way a sitemap should work. And then i should have Hessel.dk on the top.

    I haven't really used XSLT before, as I jumped directly into Razor, so it's kind of rubbish for me :-(

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:PS.XSLTsearch="urn:PS.XSLTsearch"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets PS.XSLTsearch ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="6"/>

    <xsl:template match="/">
    <div id="sitemap">
    <xsl:call-template name="drawNodes">  
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>  
    </xsl:call-template>
    </div>
    </xsl:template>

    <xsl:template name="drawNodes">
    <xsl:param name="parent"/>
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <ul><xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]">
    <li>  
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/></a>  
    <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
    <xsl:call-template name="drawNodes">    
    <xsl:with-param name="parent" select="."/>    
    </xsl:call-template>  
    </xsl:if>
    </li>
    </xsl:for-each>
    </ul>
    </xsl:if>
    </xsl:template>
    </xsl:stylesheet>
  • Charles Afford 1163 posts 1709 karma points
    Jan 10, 2013 @ 23:05
    Charles Afford
    0
  • Charles Afford 1163 posts 1709 karma points
    Jan 10, 2013 @ 23:06
    Charles Afford
    100

    Hello, So am i right in saying that you want a site map for all level of your site and that the first two level are no clickable, thus will not have a <a href="url"></a>?.

    can you post what umbracoNaviHide is (value and type) and also what $maxLevelForSitemap is (value and type).  Some of the code above need refactoring.

    You need to use a a <xsl choose><xsl:when select=""> statement.  At the moment you are placing the xml with an <a></a> whatever it is and you only want to do this if is greate than level 2 in your structure.

    so you will end up with something like:

    <ul>

     

    <xsl:for-eachselect="$parent/* @level &lt;= $maxLevelForSitemap]">
    <xsl:choose>
    <xsl:whentest="level of the node is less than 2 &lt; '2'">
    render the map but dont use an <a>
    </xsl:when>
    <xsl:whentest="level of the node is greater than 2 &gt; '2'">
    render the map an douse an <a> tag
    </xsl:when>
    </xsl:choose>
    If you need some code post back and i will knock some up for you :)

    </ul>

  • Jimmy Dan Mortensen 77 posts 197 karma points
    Jan 14, 2013 @ 10:55
    Jimmy Dan Mortensen
    0

    After two days of heartbreak i figured it out :-) You gave me some insight to how XSLT works. Thanks for that :-)

  • Charles Afford 1163 posts 1709 karma points
    Jan 14, 2013 @ 14:54
    Charles Afford
    0

    No problem :) glad i could help.  What was the solution in the end?  Thanks :) Charles.

  • Jimmy Dan Mortensen 77 posts 197 karma points
    Jan 14, 2013 @ 14:56
    Jimmy Dan Mortensen
    0

    Here is my end code :-)

    Had to change some of the levels as I wasn't thinking clearly when i asked the question :-)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:PS.XSLTsearch="urn:PS.XSLTsearch"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets PS.XSLTsearch ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="8"/>

    <xsl:template match="/">
    <div id="sitemap">
      <xsl:call-template name="topNode">  
      </xsl:call-template>
    <xsl:call-template name="drawNodes">  
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>  
    </xsl:call-template>
    </div>
    </xsl:template>

        <xsl:template name="topNode">
    <ul>
      <li>
        <a href="/">Home</a>
      </li>
    </ul>
        </xsl:template>
    <xsl:template name="drawNodes">
    <xsl:param name="parent"/>
      <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <ul>
      <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]">
        <xsl:choose>
          <xsl:when test="@level &lt; 4">
            <li>  
              <xsl:value-of select="@nodeName"/>
              <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
                <xsl:call-template name="drawNodes">    
                  <xsl:with-param name="parent" select="."/>    
                </xsl:call-template>  
              </xsl:if>
            </li>
          </xsl:when>
          <xsl:when test="@level &gt;=4">
            <li>
              <a href="{umbraco.library:NiceUrl(@id)}">
              <xsl:value-of select="@nodeName"/></a>  
              <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
                <xsl:call-template name="drawNodes">    
                  <xsl:with-param name="parent" select="."/>    
                </xsl:call-template>  
              </xsl:if>
            </li>
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
        </ul>
        </xsl:if>

    </xsl:template>
    </xsl:stylesheet>
     
  • Charles Afford 1163 posts 1709 karma points
    Jan 15, 2013 @ 00:08
    Charles Afford
    0

    Brilliant :) well hope i helped a bit :D.  Charles

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jan 15, 2013 @ 01:14
    Chriztian Steinmeier
    0

    Hi Jimmy & Charles,

    Just for reference, here's my "match templates" approach to something like this (note that it's a quite different way of thinking):

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umb="urn:umbraco.library"
        exclude-result-prefixes="umb"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
        <xsl:variable name="maxLevelForSiteMap" select="8" />
        <xsl:variable name="isLoggedOn" select="umb:IsLoggedOn()" />
    
        <xsl:template match="/">
            <div id="sitemap">
                <xsl:call-template name="topNode" />
                <xsl:apply-templates select="$siteRoot" />
            </div>
        </xsl:template>
    
        <xsl:template match="*[@isDoc]">
            <xsl:variable name="isProtected" select="umb:IsProtected(@id, @path)" />
            <xsl:if test="not($isProtected) or ($isProtected and $isLoggedOn)">
                <ul>
                    <xsl:apply-templates select="*[@isDoc][@level &lt;= $maxLevelForSiteMap][not(umbracoNaviHide = 1)]" mode="link" />
                </ul>
            </xsl:if>
        </xsl:template>
    
        <!-- General template for links -->
        <xsl:template match="*[@isDoc]" mode="link">
            <xsl:variable name="subNodes" select="*[@isDoc][@level &lt;= $maxLevelForSiteMap][not(umbracoNaviHide = 1)]" />
            <li>
                <a href="{umb:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName" />
                </a>
                <xsl:apply-templates select="*[@isDoc][@level &lt;= $maxLevelForSiteMap][not(umbracoNaviHide = 1)]" />
            </li>
        </xsl:template>
    
        <!-- Exclude link for levels 1 through 3 -->
        <xsl:template match="*[@isDoc][@level &lt; 4]" mode="link">
            <li>
                <xsl:value-of select="@nodeName" />
                <xsl:apply-templates select="*[@isDoc][@level &lt;= $maxLevelForSiteMap][not(umbracoNaviHide = 1)]" />
            </li>
        </xsl:template>
    
        <!-- Special template to render Home node -->
        <xsl:template name="topNode">
            <ul>
                <li><a href="/">Home</a></li>
            </ul>
        </xsl:template>
    
    </xsl:stylesheet>

    /Chriztian

  • Charles Afford 1163 posts 1709 karma points
    Jan 15, 2013 @ 21:56
    Charles Afford
    0

    Thanks Chriztian :).  Out of intrest why have you got a a template topNode just to put a <ul> <li></li></ul> in or i am missing something?  Thanks.  Charlie.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jan 15, 2013 @ 22:03
    Chriztian Steinmeier
    0

    Hi Charlie,

    Mostly because it makes it more obvious that it's actually getting a special treatment (URL is almost never the NiceUrl() result, nor is its name "Home" - in my solutions :-)

    For the record, in my own solutions the "Home" node is always a document type called Website, and I just have a match template for that instead.

    /Chriztian 

  • Charles Afford 1163 posts 1709 karma points
    Jan 15, 2013 @ 22:44
    Charles Afford
    0

    ahhhh ok :)  just looking at that code i find it really hard to quicky see what its doing becuase its so seperated.  ok :)  we always have document types of HTML and then Default and then put all of the header information in the HTML template.

    How come you dont use NiceUrl()?

     

    Charlie.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jan 15, 2013 @ 22:55
    Chriztian Steinmeier
    0

    The overview thing is because you're still "thinking" in C# (or other "regular" programming language) terms — XSLT really works much more like CSS in many ways, but, unfortunately, xsl:for-each and xsl:choose tricks a lot of developers into thinking it's just another programming language :-)

    I *do* use NiceUrl() - but not on the Home node, because I want the link to say href="/" - NiceUrl() will give me something like href="/ikea-dk" or similar.

    /Chriztian

  • Charles Afford 1163 posts 1709 karma points
    Jan 16, 2013 @ 09:54
    Charles Afford
    0

    What is the 'overview' thing?  In any language you need people looking at the code to quickly understand whats going on, it just appears to add complexity.  Thanks for the tip of not using the NiceUrl() in the home node, will bear that in mind :).  Thanks.  Charles.

  • Charles Afford 1163 posts 1709 karma points
    Jan 16, 2013 @ 09:55
    Charles Afford
    0
Please Sign in or register to post replies

Write your reply to:

Draft