Copied to clipboard

Flag this post as spam?

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


  • trfletch 598 posts 604 karma points
    Dec 13, 2010 @ 18:44
    trfletch
    0

    Finding a property from a node on the same level as parent

    Hi all,

    I have an Umbraco V4.5 instance that contains a few websites with the following structure:

    Website 1
        - Pages
             - Home
             - Page 1
             - Page 2
        - Settings

    Website 2
        - Pages
             - Home
             - Page 1
             - Page 2
        - Settings

    All of the website have the same template therefore I want to create an XSLT that pulls in a property that is set on the settings node of each site. Obviously the settings node is going to have a different property for each site and also it is going to be the same XSLT and template for each site so it is not as if I can specify the Settings node ID. I need some XSLT that is basically going however many levels it needs to until it finds the Settings node for that site then pull out a property from it.

    Can anyone give me any pointers as it if this is possible to start with and if so how I would go about it? Obviously the XSLT cannot search the entire Content node for the Settings node because it would find more than one and would not know which is the correct one for the site.

    Please let me know if you need me to explain this further.

  • Thijs Kuipers 43 posts 66 karma points
    Dec 13, 2010 @ 20:50
    Thijs Kuipers
    0

    When you know at which level the parent node of Settings resides AND the Settings node is always of the same Document Type, you could use something as simple as (where "<" and ">" are placeholders):

    $currentPage/ancestor-or-self::*[@isDoc and @level = <LevelOfParentOfSettings>]/Settings

    The ancestor-or-self XPath "axis" does the hard work for you, it will look from (and including) the current node up until it finds a node that has an "isDoc" property AND is of the required level. Looking at your schema, my best guess is each "Website X" node is at level 1 (one).

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 10:36
    trfletch
    0

    Thank you for the response, I assume your code is using the new XSLT schema which I haven't managed to get my head around yet so I am still using the old schema but hopefully I will be able to write something based on your idea.

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 11:09
    trfletch
    0

    Ok I appear to be struggling to convert what you suggested into the old schema, any help would be appreciated. So far I have got the following but it does not appear to be showing any results, I have tried adjusting the level but that did not help. Any suggestions as to what I'm missing?

     

    <xsl:for-each select="$currentPage/ancestor-or-self [@level=2 and @nodeTypeAlias = 'Settings']">
    <xsl:value-of select="data [@alias = 'testProperty']"/>
    </xsl:for-each>

     

    I did try it with :: after ancestor-or-self similar to yours but that throws an XSLT error

  • Thijs Kuipers 43 posts 66 karma points
    Dec 14, 2010 @ 11:40
    Thijs Kuipers
    0

    After the "axis" ancestor-or-self, you need to specify the node you're looking for, which is just called "node" in the legacy schema, while it can be anything (as in any document type name) in the new schema, hence the "*" in my first reply.

    So it would become something like (for the legacy schema):

     

    <xsl:for-each select="$currentPage/ancestor-or-self::node[@level=2 and @nodeTypeAlias = 'Settings']">
            <xsl:value-of select="data [@alias = 'testProperty']"/>
    </xsl:for-each>

     

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 12:54
    trfletch
    0

    Thank you for the quick response, I tried what you said but it is not displaying any results, as a test I tried the following code and it just displayed "Pages" which suggest to me that it is only search the actual node in the level above the pages and not all the nodes on that level, any ideas what I'm doing wrong? This is the code I used to test:

    <xsl:for-each select="$currentPage/ancestor-or-self::node[@level=2]"> 
           <xsl:value-of select="@nodeName"/>
    </xsl:for-each>

    It's almost like I need something else to tell it to search all the nodes on level 2

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 12:58
    trfletch
    0

    Ok I think I may have cracked it using the following code, not sure if this is best practise of if there is a better way to do this? Please let me know if there is:


    <xsl:for-each select="$currentPage/ancestor-or-self::node[@level=1]/node[@nodeTypeAlias = 'Settings']">
        <xsl:value-of select="data [@alias = 'testProperty']"/>

    </xsl:for-each>
  • Thijs Kuipers 43 posts 66 karma points
    Dec 14, 2010 @ 13:30
    Thijs Kuipers
    0

    The "ancestor-or-self" axis only looks up the chain. The "chain" starts with the "$currentPage" in this case, and goes all the way up, until it finds a "node" that has a attribute "level" that has a value of "1" (or "2" or whatever other value you specify). Level 1 happens to be the "Website" node. It then tries to find all children (of the "Website" node just found) of type "node" that have a property "nodeTypeAlias" that has a value of "Settings". Level "2" didn't work, because that is your "Pages" node (looking up from the $currentPage). So if you would want all level 2 nodes under Website, you will first (in XSLT) go up to Website (level 1 and/or nodeTypeAlias "Website) and next, select all children. If you would want to select all level 2 nodes regardless of their chain you would go up to the root ($currentPage/ancestor::root) and select all nodes on level 2 ($currentPage/ancestor::root//node[@level = 2]), where // just says "any descendant" that matches the selector.

    If you have (remote desktop) access to the server itself, I would advice you to take a look at the umbraco.config file (I think it's in App_data in 4.5). It's the XML file that actually "drives" the XSLT processor. This will give you a good feeling of how the XML nodes are nested and what the difference is between "@attribute" and "data[@alias = 'aliasType']" properties. And I would advice you to use the new schema, since it is much more "human" readable than the old schema.

    As to your question whether this is "good practice" (concerning the Settings node). Is there any reason why you wouldn't want these properties directly on the "Website" node (e.g. neatly grouped on one tab)? It seems like you're just giving yourself a hard time creating some kind of "property bag" (the "Settings" node), while these Settings might as well just live on the Website node itself as properties.

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 15:54
    trfletch
    0

    Hi,

    Thanks for your response, I have took your advice and now have the following structure, the only problem is that now by going to the URL which take you to the /default.aspx page it does not show my home page, I have republished the site to clear the cache but still no joy, the only way I can get to the homepage is by going to /home.aspx. My structure is now as follows:

    Website 1                              (Setting are now defined on this node)
          - Home
          - Page 1
          - Page 2

    Website 2                              (Setting are now defined on this node)
          - Home
          - Page 1
          - Page 2

  • Thijs Kuipers 43 posts 66 karma points
    Dec 14, 2010 @ 16:18
    Thijs Kuipers
    0

    That raises the question why you wouldn't want the "Home" node and the "Website" node to be one and the same? Cause now, the "Website" nodes are just an empty shell. Try to envision the 'friendly URL's you're trying to achieve and implement the site's hierarchy accordingly. I often use the following hierarchy:

    Website 1 (Home)
    - Page 1
    - Page 2
    -- Page 2.1
    - Page 3

    Website 2 (Home)
    - Page 1
    - Page 2
    -- Page 2.1
    - Page 3

    When there are e.g. multiple languages/channels it might become something like:

    Multilingual Website
    - EN (Home)
    -- Page 1
    -- Page 2
    --- Page 2.1
    -- Page 3
    - DE (Home)
    -- Page 1
    -- Page 2
    --- Page 2.1
    -- Page 3
    - NL (Home)
    -- Page 1
    -- Page 2
    --- Page 2.1
    -- Page 3
    - FR (Home)
    -- Page 1
    -- Page 2
    --- Page 2.1
    -- Page 3

    Using URL rewriting, relations between nodes and some IP geolocation and browser language sniffing, you can make a 'best in class' multilingual site.

    I hope I didn't drift off topic too much...

  • trfletch 598 posts 604 karma points
    Dec 14, 2010 @ 16:56
    trfletch
    0

    Hi,

    Thanks for the response, the structure you mentioned is the very thing that I was trying to move away from in the first place because people found it confusing that the pages were underneath the home folder and the fact that settings that apply to the whole site such as a logo etc were being defined on the homepage node when in fact they apply to the whole site. This is the reason I wanted it so that the homepage was on the same level as the other pages and then there was a settings node but as you suggested I can put the settings on the website node.

  • Thijs Kuipers 43 posts 66 karma points
    Dec 14, 2010 @ 17:17
    Thijs Kuipers
    0

    OK, now I understand, it's a usability problem for editors.

    You could put this property umbracoInternalRedirectId on your website node and let it refer to the "Home" node. You would have to do this for every "Website". Refer to the wiki page for more info. I've never used it on a level 1 node, so please test this thoroughly!

Please Sign in or register to post replies

Write your reply to:

Draft