Copied to clipboard

Flag this post as spam?

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


  • Chris Davis 56 posts 74 karma points
    Jul 10, 2009 @ 02:07
    Chris Davis
    1

    Redirect to first child node in xslt

    What is the best practice to redirect from a parent node to the first child node in xslt?

    Instead of using 'umbracoRedirect' to redirect to a specific page, I would like to create a document type of type 'True/False', and if set to true, redirect from that page to the first child node/page. I am hoping to implement this feature in xslt into a sidebar navigation menu.

    Thanks.

     

  • Petr Snobelt 923 posts 1535 karma points
    Jul 10, 2009 @ 07:58
    Petr Snobelt
    0

    You can do that in xslt, simply check your properti and redirect, but you need some redirect xslt extension. In umbraco library this function isn't.

     

    Petr

  • Jesper Hauge 298 posts 487 karma points c-trib
    Jul 10, 2009 @ 09:04
    Jesper Hauge
    0

    Do you really want to redirect ie. send the user from the requested url, to another, or would you rather make the root node in a page hierarchy display the content of the first child node instead of its own content?

    If you want to redirect, you could use a urlRewriter rule, I frequently do this in sites where i know the first child node is not going to change. With UrlRewriter you can even let the user keep the original url in their browser, and just make Umbraco show the output from another url like the url of the first child.

    If the first chilnode is subject to change it's url, eg. if you will frequently put another node as the first child of the root node, you're probably better of making a special template for the root node, and make this template show the contents of the first child using an xslt.

    Regards
    .Hauge

  • Ove Andersen 435 posts 1541 karma points c-trib
    Jul 10, 2009 @ 14:30
    Ove Andersen
    1

    You can also use a RenderTemplate xslt that renders a subnode inside the parent.

    Then you need to create a master template with only the RenderTemplate macro inside it.
    But be aware that you then will get two pages with the same content, and it might affect your site SEO-wise.

    Code:

    <xsl:param name="renderFirstSubnode" select="/macro/renderFirstSubnode"/>

    <xsl:variable name="PageId">
    <xsl:choose>
    <xsl:when test="$renderFirstSubnode='true'">
    <xsl:value-of select="$currentPage/node/@id"/>
    </xsl:when>
    <xsl:when test="$currentPage/data [@alias = 'RenderTemplate']!=''">
    <xsl:value-of select="$currentPage/data [@alias = 'RenderTemplate']"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="/macro/pageId"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:variable>
    <xsl:variable name="TemplateId">
    <xsl:choose>
    <xsl:when test="/macro/templateId != ''">
    <xsl:value-of select="/macro/templateId"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="umbraco.library:GetXmlNodeById($PageId)/./@template"/>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:variable>

    <xsl:template match="/">
    <xsl:choose>
    <xsl:when test="string($PageId)!='' and string($TemplateId)!=''">
    <xsl:value-of select="umbraco.library:RenderTemplate($PageId, $TemplateId)" disable-output-escaping="yes"/>
    </xsl:when>
    <xsl:otherwise>
    <xsl:text>An error has occured.</xsl:text><br />
    <xsl:text>Please contact 3D Design Media to resolve this error.</xsl:text>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    Template:

    <%@ Master Language="C#" MasterPageFile="/umbraco/masterpages/default.master" AutoEventWireup="true" %>

    <asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server">
        <umbraco:Macro pageId="" templateId="" renderFirstSubnode="true" Alias="RenderTemplate" runat="server"></umbraco:Macro>
    </asp:Content>
  • Chris Davis 56 posts 74 karma points
    Jul 10, 2009 @ 16:23
    Chris Davis
    0

    Thanks guys.

    The first child node is subject to change, so I need a way to always grab the first child node. Let's say my content tree looks like this:

    -About Us
    -Projects
    ----Project 1
    --------Item 1
    --------Item2
    ----Project 2
    -Services

    If the user clicks on 'Project 1' (nav menu), it will automatically take them to the 'Item 1' page (the first child node). Is there a simple way to do this in xslt? Examples will be helpful.

    Thanks!


  • Vladimir Dobrov 45 posts 167 karma points
    Jul 10, 2009 @ 16:38
    Vladimir Dobrov
    0

    You can use xslt function position() to get the first child item. The example below read the 1st child item of the current page.

    <xsl:value-of select="$currentPage/node [position()=1]"/>

    Hope this will help

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Jul 10, 2009 @ 16:47
    Douglas Robar
    3

    The way I would probably handle this is by updating your navigation menu's xslt to link the 'Project 1' menuitem to the 'Item 1' page. No need for a redirect at all.

    I don't know what you've got for nav menu code but this should outline the idea at least.

    1. Add another property to the docType(s) that should link a child node (the docType for 'Project 1' in your example).

    2. Give the new property the following details:
        Name = Link to first subpage?
        Alias = linkToSubpage
        Type = true/false

    3. On the 'Project 1' page, select the Link to first subpage field and publish the page

    4. Update the Navigation menu's xslt to look for the value of the linkToSubpage property and link to the first subnode if appropriate. See below.

    The xslt for navigation normally looks something like this:

    <ul id="topnavigation">
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

    I would change it to something like this instead:

    <ul id="topnavigation">
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a>
                <xsl:attribute name="href">
                     <xsl:choose>
                        <xsl:when test="count(./node) &gt; 1 and string(data[@alias='linkToSubpage']) = '1'">
                            <xsl:value-of select="umbraco.library:NiceUrl(./node/@id)" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="umbraco.library:NiceUrl(@id)" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:attribute>
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

     

     

    cheers,
    doug.

     

  • Warren Buckley 2106 posts 4836 karma points MVP 7x admin c-trib
    Jul 10, 2009 @ 17:00
    Warren Buckley
    0

    Nice solution Doug, not sure if you know but the preformatted option from the dropdown does the code highlighting :)

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Jul 10, 2009 @ 17:05
    Douglas Robar
    4

    [HERE'S A RE-POST, USING CODE HIGHLIGHTING... THANKS, WARREN!]

     

    The way I would probably handle this is by updating your navigation menu's xslt to link the 'Project 1' menuitem to the 'Item 1' page. No need for a redirect at all.

    I don't know what you've got for nav menu code but this should outline the idea at least.

    1. Add another property to the docType(s) that should link a child node (the docType for 'Project 1' in your example).

    2. Give the new property the following details:
        Name = Link to first subpage?
        Alias = linkToSubpage
        Type = true/false

    3. On the 'Project 1' page, select the Link to first subpage field and publish the page

    4. Update the Navigation menu's xslt to look for the value of the linkToSubpage property and link to the first subnode if appropriate. See below.

    The xslt for navigation normally looks something like this:

    <ul id="topnavigation">
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

    I would change it to something like this instead:

    <ul id="topnavigation">
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <li>
            <a>
                <xsl:attribute name="href">
                     <xsl:choose>
                        <xsl:when test="count(./node) &gt; 1 and string(data[@alias='linkToSubpage']) = '1'">
                            <xsl:value-of select="umbraco.library:NiceUrl(./node/@id)" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="umbraco.library:NiceUrl(@id)" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:attribute>
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

     

    cheers,
    doug.

  • Chris Davis 56 posts 74 karma points
    Jul 10, 2009 @ 17:28
    Chris Davis
    0

    Awesome.

    Doug, your solution is exactly what I was looking for. Thanks everyone.

     

    Chris

  • Nico Lubbers 151 posts 175 karma points
    Oct 25, 2009 @ 17:30
    Nico Lubbers
    0

    Nice solution. Just what I needed after 2 hours of trying to make something similar :-)

     

  • BarneyHall 141 posts 210 karma points
    Aug 25, 2010 @ 18:08
    BarneyHall
    0

    Hi Doug (or anyone else for that matter),

    I was trying to get this working with the new XML schema, but can't figure why this isn't working?

                <a>
                    <xsl:attribute name="href">
                        <xsl:choose>
                            <xsl:when test="count(./*[@isDoc]) &gt; 1 and string(linkToSubpage) = 1">
                                <xsl:value-of select="umbraco.library:NiceUrl(./*[@isDoc]/@id)" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="umbraco.library:NiceUrl(@id)" />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:attribute>
                    <xsl:value-of select="@nodeName"/>
                </a>

    Even with the linkToSubpage DocType having a true value, it ignores the child nodes URL and just uses it's current URL.

    Any ideas where I'm going wrong?

    Many thanks,
    Barney

  • Gerben 41 posts 136 karma points
    Aug 25, 2010 @ 18:21
    Gerben
    0

     

    Try the following 

    Replace: 

    xsl:when test="count(./*[@isDoc]) &gt; 1 and string(linkToSubpage) = 1">

    With:

      <xsl:when test="count(./*[@isDoc]) &gt; 1 and string(linkToSubpage) = '1'">

    (note the single Quote's around the last 1)

  • BarneyHall 141 posts 210 karma points
    Aug 25, 2010 @ 18:25
    BarneyHall
    0

    Hey Gerben, cheers for chipping in but unfortunately I'm getting the same result.

  • Gerben 41 posts 136 karma points
    Aug 25, 2010 @ 18:31
    Gerben
    0

    Mmm try the code below.  (note the check for greater than 0 instead of greater than 1).

    Not sure what you want to achive, but this one checks for ANY child node (instead of more than 1 child node)

     <xsl:when test="count(./*[@isDoc]) &gt; 0 and string(linkToSubpage) = '1'">

     

    Otherwise you might post the source XML snippet so we can have a look at that?

  • BarneyHall 141 posts 210 karma points
    Aug 25, 2010 @ 18:37
    BarneyHall
    0

    Oh my giddy, that worked! Thanks Gerben!

  • KoosMos 19 posts 41 karma points
    Nov 17, 2010 @ 11:01
    KoosMos
    0

    Hi,

    I am new in umbraco world and I try to use this code but it doesn't work.

    My content tree looks like this:

    - News

        - News 1

        - News 2

    - Products

       - Product 1

       - Product 2

    When I click on News or Product, actually the url is http://localhost/news.aspx but I need to go on this url http://localhost/news/news1.aspx

    My code :

    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::* [@level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
        <li>
            <a>
                <xsl:attribute name="href">
                     <xsl:choose>
                        <xsl:when test="count(./*[@isDoc]) > 0">
                            <xsl:value-of select="umbraco.library:NiceUrl(./*[@isDoc]/@id)" />
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="umbraco.library:NiceUrl(@id)" />
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:attribute>
                <xsl:value-of select="@nodeName"/>
            </a>
        </li>
    </xsl:for-each>
    </ul>

    In this code count(./*[@isDoc]) always return 0.

     

    Thanks

     

Please Sign in or register to post replies

Write your reply to:

Draft