choosing a page/file/link with a data definition and output using macro

Charla's Avatar

Charla

Apr 05, 2012 @ 05:02 PM

This is still part of the nav I've been working on for .....too long. I have a need for the user to be able to use a page choose, a file chooser or a link chooser from the data definition to output to navigation.

I have this statement in my velocity

#set ($firstpage = $_XPathTool.selectSingleNode($item, "first-level-page[path!='/'] | first-level-file[path!='/'] | first-level-link[path!='/']"))label:'#outputItemPath($firstpage)

and this for the macro

#macro (outputItemPath $node)
#set ($itemPath = $node.getChild("link").value)
#set ($itemTitle = $node.getChild("title").value)
#set ($itemTitle = $_EscapeTool.javascript($node.getChild("title").value))
#if ($node.getName() == "system-folder")#set ($itemPath = $itemPath + "/index")
#elseif ($node.getName() == "system-symlink")
#set ($itemPath = $itemPath.replaceAll("&", "&"))
#end<a href="${itemPath}">${itemTitle}</a>#end

It outputs the itemTitle but not the path, it outputs ${itemPath} where the link should be.

In addition, I need to test for these three things, file, link or page at each of my three levels of nav. I'm not sure how to go about it. Should I do three different macros and then and if/else to output that particular macro

My loop starts like this

 {#set ($firstpage = $_XPathTool.selectSingleNode($item, "first-level-page"))label:'#outputItemPath($firstpage)',
            #set ($secondLevelItems = $_XPathTool.selectNodes($item, "second-level-nav[second-level-page[path!='/']]")) 
                               #if ( $secondLevelItems.size() >= 1 )
                      children:[                        
                   #foreach ($secondLevelItem in $secondLevelItems)
                    #set($secondLevelPage = $secondLevelItem.getChild("second-level-page"))
                        {
                             label:'#outputItemPath($secondLevelPage)',

I want to choose, at this line,

#set($secondLevelPage = $secondLevelItem.getChild("second-level-page"))

something like

#set($secondLevelPage = $secondLevelItem.getChild("second-level-page | second-level-link | second-level-file"))

Whenever I do that, it outputs the first level page/link/file at the second level.

  1. 1 Posted by Charlie Holder on Apr 05, 2012 @ 05:39 PM

    Charlie Holder's Avatar

    Can you attach the XML you're paring this Format with? It might be easier to help if I can compare it to some actual data.

    Feel free to make the thread private if it has sensitive data.

  2. 2 Posted by Charla on Apr 05, 2012 @ 06:20 PM

    Charla's Avatar

    Not sure if it attached...

  3. 3 Posted by Charlie Holder on Apr 05, 2012 @ 06:22 PM

    Charlie Holder's Avatar

    Will try to take a look this afternoon to offer some assistance. Realistically it might be tomorrow before I can. Will update when I know more.

  4. 4 Posted by Charlie Holder on Apr 09, 2012 @ 03:24 AM

    Charlie Holder's Avatar

    Hey Charla --

    For your first issue, I think your problem is stemming from what you're selecting. You have a .selectSingleNode call with multiple conditions. I'm not 100% on if that is valid. Have you used that with success in other places? Have you tried selecting the parent node of the three choices and then using an if statement to figure out which ones gets passed to the macro? Does this make sense?

    For the second part, my suggestion for the first part may help there as well. I would probably be selecting each of the level nodes and determining which one, file or link or page, should be passed to the macro.

    Also, the getChild does not accept an XPath expression. It only accepts a string that is an XML node name. It does not use the XPath language at all so conditional tests as well as logical ANDs and ORs will not be valid there.

    Hope this helps.

  5. 5 Posted by Charla on Apr 11, 2012 @ 09:59 PM

    Charla's Avatar

    OK, finally got some time to work on this. I did what you said, at least, I think I did what you said and it's working. First level code is below.

    #set ($firstLevelNavs = $_XPathTool.selectNodes($contentRoot, "/system-data-structure/first-level-nav"))
                    #foreach ($firstLevelNav in $firstLevelNavs)
                        {#set ($firstLevelPage = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-page[path!='/']"))
                            #set ($firstLevelFile = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-file[path!='/']"))
                            #set ($firstLevelLink = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-link[path!='/']"))
                            #if ($firstLevelPage)
                                    label:'#outputItemPath($firstLevelPage)',
                                    #elseif ($firstLevelFile)
                                   label:'#outputItemPath($firstLevelFile)',
                                    #elseif ($firstLevelLink)
                                    label:'#outputItemPath($firstLevelLink)',
                            #end
    

    One little problem remains with the symlink and I dont' know what to do about it. I think its with the macro because the symlink has <content> around it and no "link" name. It's not outputting the $itemPath for the symlink. It DOES output the itempath for the other cases, file or page. So, same XML as I posted in my last post and here is the macro:

    #macro (outputItemPath $node)
    #if ($node.getName() == "system-symlink")
    #set ($itemPath = $node.getChild("system-symlink").value)
    #end
    #set ($itemPath = $node.getChild("link").value)
    #set ($itemTitle = $node.getChild("title").value)
    #set ($itemTitle = $_EscapeTool.javascript($node.getChild("title").value))
    #if ($node.getName() == "system-folder")
    #set ($itemPath = $itemPath + "/index")
    #elseif ($node.getName() == "system-symlink")
    #set ($itemPath = $itemPath.replaceAll("&", "&amp;"))
    #end<a href="${itemPath}">${itemTitle}</a>#end
    
  6. 6 Posted by Charla on Apr 12, 2012 @ 03:14 PM

    Charla's Avatar

    OK, I fixed that problem and now I have another problem....seems neverending. When I added a second first level to the data definition, it's not choosing the right pages to display. It's duplicating pages from the first first level to the second first level and the first 2nd level to the second 2nd level. So, something is still not right with the way I'm doing the firstlevelpage, firstlevelfile, firstlevellink etc. SO, back to the drawing board.

  7. 7 Posted by Charla on Apr 12, 2012 @ 03:16 PM

    Charla's Avatar

    Here is the working macro for the symlink, may not be the most elegant solution but it works.

    #macro (outputItemPath $node)
    #set ($itemPath = $node.getChild("link").value)
    #if ($node.getName() == "first-level-link")
    #set ($itemPath = $node.getChild("content").value)
    #elseif ($node.getName() == "second-level-link")
    #set ($itemPath = $node.getChild("content").value)
    #elseif ($node.getName() == "third-level-link")
    #set ($itemPath = $node.getChild("content").value)
    #end
    #set ($itemTitle = $node.getChild("title").value)
    #set ($itemTitle = $_EscapeTool.javascript($node.getChild("title").value))
    #if ($node.getName() == "system-folder")#set ($itemPath = $itemPath + "/index"
    #elseif ($node.getName() == "system-symlink")#set ($itemPath = $itemPath.replaceAll("&", "&amp;"))#end<a href="${itemPath}">${itemTitle}</a>
    #end
    
  8. 8 Posted by Charla on Apr 13, 2012 @ 06:59 PM

    Charla's Avatar

    OK, so now I have the following code:

    #set ($firstLevelNavs = $_XPathTool.selectNodes($contentRoot, "/system-data-structure/first-level-nav[first-level-page[path!='/']] | /system-data-structure/first-level-nav[first-level-file[path!='/']] | /system-data-structure/first-level-nav[first-level-link[path!='/']]"))
                    #foreach ($firstLevelNav in $firstLevelNavs)
                                
                        {#set ($firstLevelPage = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-page[path != '/']"))
    
                            #set ($firstLevelFile = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-file[path != '/']"))
    
                            #set ($firstLevelLink = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-link[path != '/']"))
    
                            #if ($firstLevelPage)
    
                                    label:'#outputItemPath($firstLevelPage)',
    
                                    #elseif ($firstLevelFile)
    
                                   label:'#outputItemPath($firstLevelFile)',
    
                                
                                    #elseif ($firstLevelLink)
    
                                    label:'#outputItemPath($firstLevelLink)',
    
    
                            #end
    

    What I'm trying to do is have the loop go through the 1st firstLevelNav and choose whatever doesn't have a path of "/", whether page, file or link. And then go through the 2nd firstLevelNav and find whatever doesn't have a path of "/" and then the third level.
    Right now, whatever I've selected (say a page) in the 1st firstLevelNav (in the actual data definition) is also linked in the 2nd firstLevelNav, even if I have a link or a file chosen. It does this for every 1st firstLevelNav until I choose a page in one of the firstLevelNavs.
    I think I need the count function or position but I'm not sure how to implement. How can I correct this so it doesn't choose info from the 1st firstLevelNav?

  9. 9 Posted by Charlie Holder on Apr 13, 2012 @ 08:59 PM

    Charlie Holder's Avatar

    Can I see your whole script again? Let's attach it as a text file this time instead of pasting the code in to the comment.

  10. 10 Posted by Charla on Apr 13, 2012 @ 09:07 PM

    Charla's Avatar

    Attached

  11. 11 Posted by Charla on Apr 19, 2012 @ 05:35 PM

    Charla's Avatar

    Charlie...any suggestions on this?

  12. 12 Posted by Charla on Apr 26, 2012 @ 05:51 PM

    Charla's Avatar

    Does anyone have any suggestions on this? I'm really at an impasse.

  13. 13 Posted by Penny on Apr 27, 2012 @ 05:28 PM

    Penny's Avatar

    Hi Charla,

    I believe the following is what you are trying to do. You want to link to a file, page, or link for each nav item. The below code should do it. Your issue before seemed to be that the page was always going to get picked up if the first item had a page bc you do not reset the variable as you loop through. This will check the node before setting the variable.

    #if ($_XPathTool.selectSingleNode($firstLevelNav, "first-level-page[path != '/']"))
        #set ($firstLevelItem = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-page[path != '/']"))
    #elseif ($_XPathTool.selectSingleNode($firstLevelNav, "first-level-file[path != '/']"))
       #set ($firstLevelItem = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-file[path != '/']"))
    #elseif ($_XPathTool.selectSingleNode($firstLevelNav, "first-level-link[path != '/']"))
       #set ($firstLevelItem = $_XPathTool.selectSingleNode($firstLevelNav, "first-level-link[path != '/']"))
    #end
    
     label:'#outputItemPath($firstLevelItem)',
    

    I hope this helps!

  14. 14 Posted by Charla on May 03, 2012 @ 07:02 PM

    Charla's Avatar

    Thanks Penny, works great.

  15. Charla closed this discussion on May 03, 2012 @ 07:02 PM.

  16. Charla re-opened this discussion on May 14, 2012 @ 06:43 PM

  17. 15 Posted by Charla on May 14, 2012 @ 06:53 PM

    Charla's Avatar

    One more issue with this format. In order to save the state for this menu, i need to generate an id for each menu item. something like:

    var data = [
                    { label: '<a href="index-advancement-menu.html">Alumni Affairs</a>', id: 1,
                    children: [
                            { label: 'Get Your Red On 2010 Photos', id: 2 },
                            { label: 'Campus Contest 2011', id: 3 },
                            { label: 'Community Contest 2011', id: 4 }
                                ]
                    },
    

    There is a cookie that this navigation uses to save the state of the menu so that when someone clicks and opens the nav with a drop down and he/she chooses a page, the nav remains open until he/she chooses to close it.

    I'm not sure how to go about doing this because I think each menu would need its own set of numbers, sequential order would be fine. If you are in a particular site, say Current Students, with id numbers for each node being 1-5 and then you click to go to another site, say Faculty/Staff, if the id numbers are the same because the cookie is the same, it would open node 2 if you had node 2 open in Current Students. I'm not entirely sure about this, but it does seem the likely senario.

    Any suggestions about how I should proceed?

  18. 16 Posted by Penny on May 21, 2012 @ 12:44 PM

    Penny's Avatar

    Hi Charla,

    I am not sure that I completely understand the question. Would creating a $count variable help and then just increment it by one in each of your loops?

    #set ($count = 0) Then
    #set ($count = $count + 1) id: ${count}

  19. 17 Posted by Charla on May 22, 2012 @ 04:29 PM

    Charla's Avatar

    I think it may open nodes in other sites that I don't intentionally open because they all share the same format, same ID's. But..it may not, i'll give it a shot.

  20. Ryan Griffith closed this discussion on Nov 25, 2013 @ 02:30 PM.

Discussions are closed to public comments.
If you need help with Cascade CMS please start a new discussion.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac