Copied to clipboard

Flag this post as spam?

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


  • curlybub 133 posts 107 karma points
    Jul 25, 2010 @ 15:18
    curlybub
    0

    Go to first node of a folder

    Hi again Umbraco People,

    I have this kind of structure:

    Home
      MODEL Line Up
    ---------Cars
              -------Car1
                        ----Features
                        ----Specifications
                        ----Gallery
              -------Car2
              -------Car3
    ---------SUV
              -------SUV1
              -------SUV2
              -------SUV3

    What I want to happen is that when I click on the link for Car1, I want to go directly to the first node under it instead of going to car1.aspx. 

    How can I achieve this? Sorry, I dont know if such a function exists.

    Thank you.

    Regards,

    Harry

  • Dimitris Tsoukakis 33 posts 59 karma points
    Jul 25, 2010 @ 16:08
    Dimitris Tsoukakis
    1

    You can create a "redirectTo" property of type "Content Picker" on the Car1 document type. When you render the menu you can check the value of the redirectTo property and accordingly render the appopriate url. It's a quite manual process but gives you freedom to point any page on your content tree (not just the first child) and only when you need it. For example if you don't have enough information for Car2 you don't have to create any sub pages. All the information will be on the Car2 page.

    <xsl:choose>
        <xsl:when test="data[@alias='redirectTo']!=''">
            <a href="{umbraco.library:NiceUrl(data[@alias='redirectTo'])}">
              <xsl:value-of select="@nodeName" />
            </a>
        </xsl:when>
        <xsl:otherwise>
            <a href="{umbraco.library:NiceUrl(@id)}">
              <xsl:value-of select="@nodeName" />
            </a>
        </xsl:otherwise>
    </xsl:choose>                    

    You can also create an xslt macro that you will include in the corresponding template that will redirect any request at the Car1 page. This is useful if there are somewhere (in your site or at google results) direct links to the car1 page.

    <?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:msxsl="urn:schemas-microsoft-com:xslt"
        xmlns:tsouki="urn:tsouki"
        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 msxsl tsouki umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
    
        <msxsl:script language="C#" implements-prefix="tsouki">
        <msxml:assembly name="System.Web" />
        <msxml:using namespace="System.Web" />
            <![CDATA[
            public String Redirect(String url){
                 System.Web.HttpContext.Current.Response.Status = "301 Moved Permanently";
                 System.Web.HttpContext.Current.Response.AddHeader("Location", url);
                 return "";
            }
            ]]>
      </msxsl:script>
    
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    
    <xsl:param name="currentPage"/>
    
    <xsl:template match="/">
    
        <xsl:if test="$currentPage/data[@alias='redirectTo']!=''">        
            <xsl:value-of select="tsouki:Redirect(umbraco.library:NiceUrl($currentPage/data[@alias='redirectTo']))"/>
        </xsl:if>
    
    </xsl:template>
    
    </xsl:stylesheet>

     

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Jul 25, 2010 @ 16:10
    Lee Kelleher
    2

    Hi Harry,

    You could use one of the special reserved property aliases - either umbracoRedirect or umbracoInternalRedirectId to set a redirect from the Car 1 node to the Features node.

    The main problem with this is that you have to manually select the node to redirect to.  Guess that depends on how much content you are going to have.

    Another way would be to set a template on the Car 1 node that does a Response.Redirect to the first child node?

    Cheers, Lee.

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jul 25, 2010 @ 22:10
    Matt Brailsford
    2

    I usualy use a .NET user control macro. I can either drop it in a template, or allow the user to drop it into a rich text area. I don't have a package for it, but my codebehind (which contains everything) is as follows:

    using System;
    using System.Web;
    using umbraco.presentation.nodeFactory;

    namespace UserControls
    {
    public partial class RedirectControl : System.Web.UI.UserControl
    {
    public bool RedirectToUrl { get; set; }
    public string RedirectUrl { get; set; }
    public bool RedirectToPage { get; set; }
    public int RedirectPage { get; set; }
    public bool RedirectToFirstChild { get; set; }
    public bool IsPermanent { get; set; }

    protected void Page_Init(object sender, EventArgs e)
    {
    if (RedirectToUrl)
    DoRedirect(RedirectUrl);

    if(RedirectToPage)
    DoRedirect(FullyQualifiedApplicationPath + umbraco.library.NiceUrl(RedirectPage).TrimStart('/'));

    if(RedirectToFirstChild)
    {
    var currentNode = Node.GetCurrent();
    if (currentNode.Children != null && currentNode.Children.Count > 0)
    DoRedirect(FullyQualifiedApplicationPath + umbraco.library.NiceUrl(currentNode.Children[0].Id).TrimStart('/'));
    }
    }

    protected void DoRedirect(string url)
    {
    if (!IsPermanent)
    {
    Response.Redirect(url, true); // 302 Found
    }
    else
    {
    Response.Clear();
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", url);
    Response.End();
    }
    }

    protected string FullyQualifiedApplicationPath
    {
    get
    {
    var appPath = "";

    var context = HttpContext.Current;
    if (context != null)
    {
    appPath = string.Format("{0}://{1}{2}{3}",
    context.Request.Url.Scheme,
    context.Request.Url.Host,
    (context.Request.Url.Port == 80) ? string.Empty : ":" + context.Request.Url.Port,
    context.Request.ApplicationPath);
    }

    if (!appPath.EndsWith("/"))
    appPath += "/";

    return appPath;
    }
    }
    }
    }

    Allows you to redirect to a url, specific page id, or the first child. Additionaly you can decide whether the redirect is perminant or not.

    Matt

  • curlybub 133 posts 107 karma points
    Jul 26, 2010 @ 04:44
    curlybub
    0

    Hi Guys,

    Thanks for your replies. The only downside of this is I have to manually pick the document to where I need to be redirected, theres no automated way?

    Regards,

    Harry

  • Matt Brailsford 4124 posts 22215 karma points MVP 9x c-trib
    Jul 26, 2010 @ 08:18
    Matt Brailsford
    0

    Hey Harry

    My macro control has the option to redirect to first child. This is worked out dynamicly, so if you reorder the children, it will automatically update.

    Matt

  • Dimitris Tsoukakis 33 posts 59 karma points
    Jul 26, 2010 @ 08:39
    Dimitris Tsoukakis
    0

    Hi Matt,

    even if your control does the job in the eyes of the end user I believe that it's not right to send Redirect headers again and again. Your control is perfect to be used in conjunction with another macro (xslt or user control) that will render the correct Urls in the menus.

    Even with the umbracoInternalRedirectId that Lee proposed there will be a problem. This is because /Car1.aspx and Car1/Features.aspx will render the same content. This means that you will get a duplicate content warning from Google web-master tools.

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Jul 26, 2010 @ 09:03
    Lee Kelleher
    0

    @Dimitris: IMO, sending redirect headers isn't that much of an overhead.  The duplicate content (for Google) isn't a problem either... Harry could include a canonical link in the meta data. (ref)

    @Harry: There can be an automated way, but you'd need to hook into one of the Publish events in the API - to set the value of "umbracoInternalRedirectId" (or "umbracoRedirect") for the car type (hopefully you've got a separate doc-type for those pages?)

    If you don't want to get your hands dirty with the API code, then Matt's redirect macro is the way to go.  Add it to the template for the car type (or create a new one for them), include the redirect macro ... and set that template as the default for the car type doc-type, (again that is if you have a separate doc-type for those pages?)

    Edit: One last thing, about Dimitris's solution. Its recommend that you do not use inline .NET scripts in your XSLT files. It's bad practice, apart from that it wont work in Medium Trust and other security reasons - it will also create a new temporary compiled class for each and every page-load/request.  These will be stored in the "Temporary ASP.NET Files" folder (default location: "%SystemRoot%\Microsoft.NET\Framework\versionNumber\Temporary ASP.NET Files")

    Unless you regularly clean-out that folder, depending on your traffic - your hard-disk space can soon fill-up.  I'm not scaremongering, just letting you know your options.

    Cheers, Lee.

     

  • curlybub 133 posts 107 karma points
    Jul 27, 2010 @ 09:18
    curlybub
    0

    Hi Lee,

    The first several post works fine. I don't want to get my hands dirty with the umbraco API. I'll go to that place in the near future. 

    Again guys, thank you so much!

     

    Regards,
    Harry

Please Sign in or register to post replies

Write your reply to:

Draft