Copied to clipboard

Flag this post as spam?

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


  • FarmFreshCode 225 posts 422 karma points
    Jan 30, 2013 @ 20:19
    FarmFreshCode
    0

    Dynamic File Path - Causing Script Error

    Using Umbraco v4.8.1

    Ok so I have this XSLT file which is currently calling a hard coded file path.. but what I need to do is have it call the path dynamically because I am using it in multiple sections of my website... Here's the current code:

    <?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:tagsLib="urn:tagsLib" xmlns:BlogLibrary="urn:BlogLibrary" xmlns:PS.XSLTsearch="urn:PS.XSLTsearch"
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib BlogLibrary PS.XSLTsearch ">

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

    <xsl:param name="currentPage"/>

    <xsl:template match="/">

    <xsl:choose>
    <xsl:when test="$currentPage/ancestor-or-self::*[@isDoc]/hideQuickFacts != '1'">

    <div id="cohpa-3column-column1-statusnav-title"><h4><span class="color-darkGold">Quick</span> Facts</h4></div>
    <div id="cohpa-quickfact">
    <ul>
    <xsl:for-each select="umbraco.library:GetXmlNodeById(4705)/NewQuickFact">

    <li><span class="cohpa-quickfact-number"><xsl:value-of select="quickFactNumber"/></span> - <xsl:value-of select="quickFactInfo"/></li>
    </xsl:for-each>
    </ul>
    </div>

    </xsl:when>
    <xsl:otherwise>

    <div id="cohpa-3column-column1-statusnav-title" style="display:none;"><h4><span class="color-darkGold">Quick</span> Facts</h4></div>
    <div id="cohpa-quickfact" style="display:none;">
    <ul>
    <xsl:for-each select="umbraco.library:GetXmlNodeById(4705)/NewQuickFact">

    <li><span class="cohpa-quickfact-number"><xsl:value-of select="quickFactNumber"/></span> - <xsl:value-of select="quickFactInfo"/></li>
    </xsl:for-each>
    </ul>
    </div>

    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

     

     

    You can see that I am calling:

    <xsl:for-each select="umbraco.library:GetXmlNodeById(4705)/NewQuickFact">

    but what I need is for it to be:

    <xsl:for-each select="$currentPage/ExtraLists/QuickFacts/NewQuickFact">

    I've included a picture of my file tree to give you a visual reference:

    You can see here at the bottom the file path:  Lists > Quick Facts > Idividual Items

    Everytime that I update the code to what I think should be the correct dynamic file path, it sets off some kind of script error when I preview the page. Saying that the script is taking too long to load.

    I don't know what I'm missing here. If anyone has an idea, I would greatly appreciate it!

    Thanks!

     

  • Brendan Rice 538 posts 1102 karma points
    Feb 01, 2013 @ 17:14
    Brendan Rice
    0

    Can you not have a content picker on the doctype to select the relevant quick fact?

    Or use uComponents Multi Node Tree Picker - which would allow you to select oe or many - http://ucomponents.codeplex.com/wikipage?title=MultiNodeTreePicker&referringTitle=Documentation

  • FarmFreshCode 225 posts 422 karma points
    Feb 04, 2013 @ 17:01
    FarmFreshCode
    0

    Thanks for replying, but I'm trying to call a series of nodes realtive to my current location in the website... So currently I have

    <xsl:for-eachselect="umbraco.library:GetXmlNodeById(4705)/NewQuickFact">

    which is set to call a specific node and all the nodes under it which the doctype of "NewQuickFact"... However if I go to a different "department" of my website I want to access their own "NewQuickFacts". That being said, I need something like this..

    <xsl:for-eachselect="$currentPage/ExtraLists/QuickFacts/NewQuickFact">

    However this seems to be giving me errors, even though I've used something like this before to call realtive information based on the current location of a user on my site.

  • Brendan Rice 538 posts 1102 karma points
    Feb 04, 2013 @ 17:06
    Brendan Rice
    0

    You could go up the xpath axis until you hit the doctype you need then down the apath axis to the relevant child item

    More information can be found below about the xpath axis:

    http://our.umbraco.org/wiki/reference/xslt/xpath-axes-and-their-shortcuts

    $currentPage/ancestor-or-self::*[@isDoc and name()="doctype"]/descendant::*[@isDoc and name()="QuickFacts"]

    ^ that will be pretty close to what you need, you should be able to iterate over the NewQuickFacts with that

     

  • FarmFreshCode 225 posts 422 karma points
    Feb 04, 2013 @ 18:52
    FarmFreshCode
    0

    It seems that no matter what I write I get an error warning popping up on the page when I refresh...

    "A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete." with a reference to my script --> /scripts/jquery-latest.js:... which is just the standard jquery script that isn't causing any other problems.

    jQuery JavaScript Library v1.5.2


    When I return the script to a direct node path everything works fine. According to the file tree I showed here is the list of doctype names:

    • ExtraLists
      • QuickFacts
        • NewQuickFact    

    So @Brendan Rice given that information... If a user was on the "CAREERS" page.. in your senerio, my xslt should be written:

    select="$currentPage/ancestor-or-self::*[@isDoc and name()='QuickFacts']/descendant::*[@isDoc and name()='NewQuickFact']">

    correct?

     

    I feel like there should be a ton of ways to get the nodes I'm trying to.. even something like:

    <xsl:for-each select="$currentPage/ExtraLists/QuickFacts/*[@isDoc]"> 

    Since all child nodes of QuickFacts will be "NewQuickFact"

  • Brendan Rice 538 posts 1102 karma points
    Feb 04, 2013 @ 19:06
    Brendan Rice
    0

    You file tree doesn;t match what you want to do

    CAREERS
    |---ExtraLists
            |---QuickFacts
                    |---*

    Matches the query below, but not the image you originally posted. If that makes sense? 

     

    "$currentPage/ExtraLists/QuickFacts/*[@isDoc]

     

  • FarmFreshCode 225 posts 422 karma points
    Feb 04, 2013 @ 19:22
    FarmFreshCode
    0

    Hmmm.... well lets assume that "alpha" is a department in my website... and I have others at that level (2) like "beta"... so if I am checking out the alpha department.. I want to see their quickfacts in the sidebar area... but if a switch over to the beta department... i want to see their quickfacts listed in the side bar of the website.. Thats what I'm trying to accomplish.. the file tree image shows the layout that currents exists.

    Does that help?

  • FarmFreshCode 225 posts 422 karma points
    Mar 13, 2013 @ 17:57
    FarmFreshCode
    1

    Hey guys... I still haven't been able to solve this issue.. I thought I would include a more graphic representation of my situation in hopes of making it more clear. I would really really really appreciate your help and a solution. THANKS!!!

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Mar 14, 2013 @ 10:11
    Douglas Robar
    104

    The way to solve these kind of traversing problems is to go UP the content tree to a known location, and then go DOWN the content tree from that known source. 

    Typically I end up going to the home page because I always know where that is and how to get where I'm going from there. As an example, imagine this site structure:

    CONTENT
    - Home
    - - News Area
    - - - News Item 1
    - - - :
    - - - News Item 55
    - - Another page 

    Let's suppose I want to make a news list macro on the News Area page. I would loop over each News Item below the current page:

    <xsl:for-each select="$currentPage/NewsItem"> 

    But what if I wanted to make the same macro work on any page of the site (perhaps as a sidebar module on the home page or on the 'another page'). I would want to update the xpath to go up to the Home page, which is the parent of everything I'll ever want, and then back down the tree to the news area and then the news items:

    <xsl:for-each select="$currentPage/ancestor-or-self::*[@isDoc and name()='Home']/NewsArea/NewsItem">

    Because we know the content tree hierarchy (it's the 'Structure' tab useful for simplifying things in macros?) I can be sure I know how to get where I want to go no matter where I start from.

     

    You don't have to always go to the home page though. In your case it might be enough to go up to whatever document type is associated with the 'Alpha' and 'Bravo' nodes in the content tree. I'll assume these have a document type of 'department' but change that in the xpath shown below: 

    <xsl:for-each select="$currentPage/ancestor-or-self::*[@isDoc and name()='Department']/ExtraLists/QuickFacts/NewQuickFact">

    The same idea as discussed above... go UP to a known location, and then go DOWN to where you need to get to. It'll work anywhere within the current department. 

     

     

    As for why your jquery is timing out... disable it for the time being until you get the output from your macro and xpath working properly. It's not related to the xpath problem per se and is only confusing things. Once you have the macro working properly, re-enable the jquery and if it errors you can debug the jquery separately, knowing your macro is at least producing the correct output.

     

    cheers,
    doug. 

  • FarmFreshCode 225 posts 422 karma points
    Mar 14, 2013 @ 13:02
    FarmFreshCode
    1

    Hello Doug!

    THANK YOU  SOOO MUCH! What an informative answer! I really appreciate the time you spent here to answer my question. The solution for me was ultimately:

    <xsl:for-eachselect="$currentPage/ancestor-or-self::*[@isDoc and name()='Departments']/ExtraLists/QuickFacts/NewQuickFact">

    I had tried using the ancestor-or-self method before... but never specifically referenced the alias for the "Department" doctype. Which of course in hindsight makes complete sense. As soon as I plugged this into my code it worked perfectly and didn't even throw a jquery error.

    Thank you again so much for assisting new guys with their problems... and helping to educate them as well!

  • Dan Okkels Brendstrup 101 posts 197 karma points
    Mar 14, 2013 @ 13:16
    Dan Okkels Brendstrup
    3

    And for bonus brevity points, this will do the same thing:

    <xsl:for-each select="$currentPage/ancestor-or-self::Departments/ExtraLists/QuickFacts/NewQuickFact"></xsl:for-each>
  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Mar 14, 2013 @ 13:18
    Douglas Robar
    2

    Quite right, Dan.

    I should also mention that this idea of going up to a known location and then down to a specific area is equally applicable in Razor code. The concept is universal.

    cheers,
    doug. 

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 14, 2013 @ 13:35
    Chriztian Steinmeier
    3

    Hi all,

    - One thing I do in ALL of my Umbraco XSLT macros is to add a siteRoot variable after the currentPage param:

    <xsl:param name="currentPage"/>
    <xsl:variable name="siteRoot" select="ancestor-or-self::Website" />
    
    "Website" is the document type alias for my "Home" node - if you prefer something a little more generic you can use the level attribute:
    <xsl:param name="currentPage"/>
    <xsl:variable name="siteRoot" select="ancestor-or-self::*[@level = 1]" />
    

    This makes all the following XPaths even more readable because they don't include the overhead of understanding to go up and then down again (as Doug explained so elegantly), e.g.:

    <xsl:for-each select="$siteRoot/Clients/Client">
        <!-- Do something -->
    </xsl:for-each>

    VS:

    <xsl:for-each select="$currentPage/ancestor-or-self::*[@level = 1]/Clients/Client">
        <!-- Do something -->
    </xsl:for-each>

     

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft