Copied to clipboard

Flag this post as spam?

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


  • PedroM. 28 posts 87 karma points
    Sep 17, 2013 @ 18:10
    PedroM.
    0

    Help with Menu on a multilanguage site

    Hi, I search and try some examples to change my menu xslt file to support multilingual site but unsuccessfully. I have a structure like

    en
    - Company news
       - Page1
       - Page2
     - Company Blog
       - Page3
       - Page4
     - PageAbout
    
    pt
     - Company news
       - Page1
       - Page2
     - Company Blog
       - Page3
       - Page4
     - PageAbout
    

    My code always shows all the items from both languages on the menu. Someone could help me to understand where I can change my code to support this?

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [
      <!ENTITY nbsp " ">
    ]>
    <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"
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
    
      <xsl:output method="xml" omit-xml-declaration="yes" />
      <xsl:param name="currentPage"/>
      <xsl:param name="level" select="1"/>
      <xsl:template match="/">
        <xsl:call-template name="menu">
          <xsl:with-param name="level" select="$level"/>
        </xsl:call-template>
      </xsl:template>
    
      <xsl:template name="menu">
        <xsl:param name="level"/>
        <ul class="menu">
          <!--parent Node-->
          <li>
            <xsl:if test="$currentPage/@id = $currentPage/ancestor-or-self::* [@level=$level]/@id">
              <xsl:attribute name="class">sel</xsl:attribute>
            </xsl:if>
            <a href="/">
              <!--set the innerText for the a element-->
              <xsl:if test="string($currentPage/ancestor-or-self::*[@isDoc][@level=1]/text()) = ''">
                <xsl:value-of select="$currentPage/ancestor-or-self::*[@isDoc][@level=1]/@nodeName"/>
              </xsl:if>
            </a>
          </li>
    
          <xsl:if test="count($currentPage/ancestor::root/* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']) > '0'">
            <xsl:for-each select="$currentPage/ancestor::root/* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
              <li>
                <xsl:if test="$currentPage/@id = current()/@id">
                  <xsl:attribute name="class">sel</xsl:attribute>
                </xsl:if>
                <!--umbracoNaviInactive-->
                <xsl:choose>
                  <xsl:when test="string(umbracoNaviInactive) != '1'">
                    <a href="{umbraco.library:NiceUrl(@id)}">
                      <xsl:value-of select="@nodeName"/>
                    </a>
                  </xsl:when>
                  <xsl:otherwise>
                    <span>
                      <xsl:value-of select="@nodeName"/>
                    </span>
                  </xsl:otherwise>
                </xsl:choose>
    
    
                <xsl:if test="count(current()/* [@isDoc and string(umbracoNaviHide) != '1']) > '0'">
                  <xsl:call-template name="submenu">
                    <xsl:with-param name="level" select="$level+1"/>
                  </xsl:call-template>
                </xsl:if>
              </li>
            </xsl:for-each>
          </xsl:if>
        </ul>
      </xsl:template>
    
      <xsl:template name="submenu">
        <xsl:param name="level"/>
        <ul>
          <xsl:for-each select="current()/* [@isDoc and string(umbracoNaviHide) != '1']">
            <li>
              <xsl:if test="$currentPage/@id = current()/@id">
                <xsl:attribute name="class">sel</xsl:attribute>
              </xsl:if>
              <!--umbracoNaviInactive-->
              <xsl:choose>
                <xsl:when test="string(umbracoNaviInactive) != '1'">
                  <a href="{umbraco.library:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName"/>
                  </a>
                </xsl:when>
                <xsl:otherwise>
                  <span>
                    <xsl:value-of select="@nodeName"/>
                  </span>
                </xsl:otherwise>
              </xsl:choose>
              <xsl:if test="count(current()/* [@isDoc and string(umbracoNaviHide) != '1']) > '0'">
                <xsl:call-template name="submenu">
                  <xsl:with-param name="level" select="$level+1"/>
                </xsl:call-template>
              </xsl:if>
            </li>
          </xsl:for-each>
        </ul>
      </xsl:template>
    
    </xsl:stylesheet>
    
  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Sep 17, 2013 @ 19:06
    Chriztian Steinmeier
    100

    Hi Pedro,

    Check this approach out - it uses the more idiomatic style XSLT was built for, which consist of separate templates for handling specific elements - you get very little duplication and you don't have recursively call a template - it's all built-in:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umbraco.library="urn:umbraco.library"
        exclude-result-prefixes="umbraco.library"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
    
        <!-- Specify level of the top node for a language (usually 1) -->
        <xsl:variable name="level" select="1" />
    
        <!-- Grab the top node -->
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = $level]" />
    
        <xsl:template match="/">
            <ul class="menu">
                <!-- Create the Home link -->
                <li>
                    <xsl:if test="$currentPage/@id = $siteRoot/@id">
                        <xsl:attribute name="class">sel</xsl:attribute>
                    </xsl:if>
                    <a href="/">
                        <xsl:value-of select="$siteRoot/@nodeName" />
                    </a>
                </li>
                <!-- Process all children of $siteRoot (if any) -->
                <xsl:apply-templates select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
            </ul>
        </xsl:template>
    
        <!-- Generic template for all nav links -->
        <xsl:template match="*[@isDoc]">
            <li>
                <xsl:if test="@id = $currentPage/@id">
                    <xsl:attribute name="class">sel</xsl:attribute>
                </xsl:if>
                <a href="{umbraco.library:NiceUrl(@id)}">
                    <xsl:value-of select="@nodeName" />
                </a>
                <!-- Render sub menu if necessary -->
                <xsl:call-template name="submenu" />
            </li>
        </xsl:template>
    
        <!-- Template for Inactive links -->
        <xsl:template match="*[@isDoc][umbracoNaviInactive = 1]">
            <li>
                <xsl:if test="@id = $currentPage/@id">
                    <xsl:attribute name="class">sel</xsl:attribute>
                </xsl:if>
                <span>
                    <xsl:value-of select="@nodeName" />
                </span>
                <!-- Submenu? -->
                <xsl:call-template name="submenu" />
            </li>
        </xsl:template>
    
        <!-- Template checking for, and processing any submenu -->
        <xsl:template name="submenu">
            <xsl:variable name="subPages" select="*[@isDoc][not(umbracoNaviHide = 1)]" />
            <xsl:if test="$subPages">
                <ul>
                    <xsl:apply-templates select="$subPages" />
                </ul>
            </xsl:if>
        </xsl:template>
    
    </xsl:stylesheet>
    

    I've added some comments to explain what's going on, but feel free to ask about it - the only thing you may need to change is the $level variable if your "Home" nodes (i.e. the 'en' and 'pt' nodes) are not at level 1.

    /Chriztian

  • PedroM. 28 posts 87 karma points
    Sep 17, 2013 @ 19:27
    PedroM.
    0

    Thank you for your answer. I tested you code and I have a doubt.

    So when I change the language of the site, how he knows what node to show? Like changing "en" to "pt"? I need to change the level?

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Sep 17, 2013 @ 21:13
    Chriztian Steinmeier
    0

    Hi Pedro,

    The trick lies solely in getting the $level variable right — because the XSLT goes up from $currentPage and stops at the level specified to find the root of the site. So if the level matches the level of the en or pt nodes, the navigation will always only show nodes within the current language/site.

    If your Content tree looks like this:

    Content
        en
        pt
    

    — it should work as it is.

    If you have another node before the languages, like this:

    Content
        Sites
            en
            pt
    

    — you need to set the level to 2 instead.

    You should not need to do anything else - you can (and should) use the exact same macro for all languages.

    /Chriztian

  • PedroM. 28 posts 87 karma points
    Sep 18, 2013 @ 12:40
    PedroM.
    0

    Great, thank you so much.

  • PedroM. 28 posts 87 karma points
    Sep 23, 2013 @ 11:29
    PedroM.
    0

    Hi again Chriztian
    Can you help me with one more thing?
    The Menu is working but now the issue is the Link to the homepage.
    If I change the language from en to pt
    When click at homepage link on pt language it change to the default en language, the first language.
    How can I control the link on the homepage link?
    What I miss to see?

    Example

    www.mysite.com when in pt should be www.mysite.com/pt/ but when click homepage returns always to www.mysite.com

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Sep 23, 2013 @ 11:39
    Chriztian Steinmeier
    0

    Hi Pedro,

    Oh yes - of course.

    You just need to call the NiceUrl() extension with the $siteRoot variable:

    <a href="{umbraco.library:NiceUrl($siteRoot/@id)}">
        <xsl:value-of select="$siteRoot/@nodeName" />
    </a>
    

    (Instead of the hardcoded "/" ...)

    /Chriztian

  • PedroM. 28 posts 87 karma points
    Sep 23, 2013 @ 12:00
    PedroM.
    0

    Thank you again :)

  • PedroM. 28 posts 87 karma points
    Jan 08, 2014 @ 11:41
    PedroM.
    0

    Hi again,

    I'm trying also to hide from the menu a specific document type (News Item) from the submenu

    I try to use from XSLT Examples

    [not(self::NewsItem)]

    but I inserted on all matches but is all showing the news items on the menu.

    How can I use this?

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jan 08, 2014 @ 11:47
    Chriztian Steinmeier
    0

    Hi Pedro,

    There can be lots of reasons for them to be rendered anyway - can you post some more code so we can help you better?

    /Chriztian

  • PedroM. 28 posts 87 karma points
    Jan 08, 2014 @ 11:54
    PedroM.
    0

    I'm using the code that you posted on September 17 to render the menu and using the Business Starter site pack

    and tried this

        <!-- Template checking for, and processing any submenu -->
       
    <xsl:templatename="submenu">
           
    <xsl:variablename="subPages"select="*[@isDoc][not(umbracoNaviHide = 1)]
    [not(self::NewsItem)]"/>
           
    <xsl:iftest="$subPages">
               
    <ul>
                   
    <xsl:apply-templatesselect="$subPages"/>
               
    </ul>
           
    </xsl:if>
       
    </xsl:template>
  • PedroM. 28 posts 87 karma points
    Jan 08, 2014 @ 12:02
    PedroM.
    0

    I think i figure this out

    use it like this

    <xsl:variable name="subPages" select="*[@isDoc][not(umbracoNaviHide = 1)][not(self::umbNewsArticle)]"/>
Please Sign in or register to post replies

Write your reply to:

Draft