Copied to clipboard

Flag this post as spam?

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


  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 01:24
    Gregg Duncan
    0

    Can I get parent node properties using Umbraco:Item and xslt

    I have a side bar in my news room with various images and links. These are accomplished by 3 properties in the "News Library" data type. The News Library data type has children of type "News Page". I'm wanting this side bar on the "News Library" page to appear on all it's children's "News Page" type pages. I'm trying to figure out the xslt to pull the data from the parent's properties.

    The side bar of my "News Library" template looks like this:

    <div class="sideinfo-top">
          <umbraco:Item field="sideBarTop" runat="server"></umbraco:Item>
        </div>
        <div class="sideinfo-header">
          <h2><umbraco:Item field="sideBarHeader" runat="server"></umbraco:Item></h2>
        </div>
        <div class="sideinfobox">
          <umbraco:Item field="sideBarContent" runat="server"></umbraco:Item>
        </div>

    In the "News Page" template I added the xslt to the umbraco item trying to get the parent node properties but It's not working:

    
    <div class="sideinfo-top">
          <umbraco:Item field="sideBarTop" runat="server" xslt="$currentPage/parent::node/data [@alias='{0}']"></umbraco:Item>
        </div>
        <div class="sideinfo-header">
          <h2><umbraco:Item field="sideBarHeader" runat="server" xslt="$currentPage/parent::node/data [@alias='{0}']"></umbraco:Item></h2>
        </div>
        <div class="sideinfobox">
          <umbraco:Item field="sideBarContent" runat="server" xslt="$currentPage/parent::node/data [@alias='{0}']"></umbraco:Item>
        </div>

    I'm a C# developer. I know next to nothing about xslt. I could do this with a user control and macro but I really thought the xslt would be an easier way for something like this. 

    Can someone point me in the right direction?

    Thanks,

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 04:13
    Tom Fulton
    1

    Hi Gregg,

    The reason your inline XSLT isn't working is inline XSLT doesn't support $currentPage.  You could hack something like this:

     <umbraco:Item field="pageID" runat="server" xslt="umbraco.library:GetXmlNodeById({0})/ancestor-or-self::NewsLibrary/sideBarTop"></umbraco:Item>

    ... but it would probably be best to just use an XSLT macro.  The code should be simple:

    <xsl:variable name="newsLibrary" select="$currentPage/ancestor-or-self::NewsLibrary"/> <!-- change NewsLibrary to whatever the Alias of the News Library doctype is -->
    <div class="sideinfo-top">
      <xsl:value-of select="$newsLibrary/sideBarTop"/>
    </div>
    <div class="sideinfo-header">
      <h2><xsl:value-of select="$newsLibrary/sideBarHeader" /></h2>
    </div>
    <div class="sideinfobox">
     <xsl:value-of select="$newsLibrary/sideBarContent" />
    </div>

    All you need to do is paste this code in a new XSLT macro (inside the <xsl:template> tags) and use the Insert Macro button to add it on your template.

    Also, since you are a C# developer, you might find Razor easier to use.  You can also use it inline without having to create a file if that's what you're after..something like:

    <umbraco:Macro runat="server" language="cshtml">
    @{
    var newsLibrary = Model.AncestorOrSelf("NewsLibrary")
    <div class="sideinfo-top">
      @newsLibrary.sideBarTop
    </div>
    <div class="sideinfo-header">
      <h2>@newsLibrary.sideBarHeader</h2>
    </div>
    <div class="sideinfobox">
      @newsLibrary.sideBarContent
    </div>
    }
    </umbraco:Macro>

    or you could stick that in a .cshtml file (created in Developers -> Scripting Files) and reference it like so:

    <umbraco:Macro runat="server" language="cshtml" FileLocation="~/macroScripts/yourFile.cshtml"/>

    .. but XSLT isn't bad at all once you get to know it :)

    Hope this helps,
    Tom

     

  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 16:54
    Gregg Duncan
    0

    Hi Tom, 

    Thanks for the reply. That got me a lot closer. I've tried both your macro and your inline xslt. They both work. The problem is the three properties that I'm trying to copy to the child pages are "Rich Text Editor" properties. so the output from both the macro and the inline xslt is the html code being displayed on the page. How can you output the content of a Rich Text Editor to the page? There is an HTML Encode function but I don't find an HTML Decode function. 

    Thanks,

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 16:55
    Tom Fulton
    0

    Hi Gregg,

    Yes, just add disable-output-escaping="yes" to the value-of on any RTE fields:

     <xsl:value-ofselect="$newsLibrary/sideBarTop"disable-output-escaping="yes"/>

    Note I'm not sure you can do that with the umbraco:Item tag combined with inline XSLT.  But the macro is a better route anyway.

    -Tom

  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 17:43
    Gregg Duncan
    0

    Hey Tom,

    I really appreciate your help. You've almost got me where I wanted to go. That's working great except I have a user control based macro embedded in the "rich text editor" field. The html is showing up fine but the output from the macro isn't showing up at all.

    I tried pulling the text into a variable and outputing using RenderMacroContent ( see below ) but that only renders the html on the asmx page. The code behind is never run. Do you have any idea how to get around this?

    <xsl:variable name="top" select="$currentPage/ancestor-or-self::AgentNewsLibrary/sideBarTop" />
    <xsl:variable name="header" select="$currentPage/ancestor-or-self::AgentNewsLibrary/sideBarHeader" />
    <xsl:variable name="content" select="$currentPage/ancestor-or-self::AgentNewsLibrary/sideBarContent" />
    <div class="sideinfo-top">
      <xsl:value-of select="umbraco.library:RenderMacroContent($top, $currentPage/@parentID)" disable-output-escaping="yes"/>
    </div>
    <div class="sideinfo-header">
      <h2><xsl:value-of select="umbraco.library:RenderMacroContent($header, $currentPage/@parentID)" disable-output-escaping="yes" /></h2>
    </div>
    <div class="sideinfobox">
      <xsl:value-of select="umbraco.library:RenderMacroContent($content, $currentPage/@parentID)" disable-output-escaping="yes" />
    </div>
    

     Thanks,

     

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 17:49
    Tom Fulton
    0

    Hi,

    You're correct in using RenderMacroContent, but I'm pretty sure it's not possible to render a .NET Macro from an XSLT Macro...so I think you may need to find an alternative, such as embedding the .NET macro in the template instead.

    You can try making sure your template has <form runat="server"> wrapped around the area where the macro is...but I still don't think that will work

    -Tom

  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 18:23
    Gregg Duncan
    0

    If I convert my .NET macro to an XSLT macro, will it then display correctly using the RenderMacroContent method?

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 18:28
    Tom Fulton
    0

    Yes, the problem is rendering .NET macros from XSLT - there is no issue with rendering XSLT macros from XSLT.

    -Tom

  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 18:36
    Gregg Duncan
    0

    Thanks for all your help, Tom. I've marked your answer as a solution and High Fived you. 

    I guess I'm going to have to start going through the xslt tutorials that I can find. Any suggestions on resources for learning XSLT, especially as it relates to umbraco?

     

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 18:48
    Tom Fulton
    1

    I don't know of a good definitive tutorial, but...

    - Check out the XSLT Wiki, check the links on the right for a lot of info and examples. 

    - Check out pimpmyxslt.com - there is an axes visualizer that can help you understand the XPath axes, and especially check out this article - it described a different approach than most of the Umbraco examples but it really makes a lot of sense.

    - There are also some examples built into Umbraco when you create a new XSLT file.

    - Here is also a page describing the XML schema change in case you find some older examples.  You can also check out your XML by opening /App_Data/umbraco.config - seeing this might help make things clearer.

    Other than that, just check out all the examples you can and try it out.  You can post any problems you have here and someone will surely help you out.

    On a side note, remember that XSLT support is not planned for Umbraco 5, so maybe your efforts are better spent learning Razor.  Though I hate to deter anyone away from XSLT - it really is awesome ;)

    On another side note, I generally try to avoid using macros in the WYSIWYG, not sure if in your case you can re-think it to include the macro in your template instead...sounds like you already have though.

    -Tom

  • Dennis Aaen 4500 posts 18255 karma points admin hq c-trib
    Jan 11, 2012 @ 18:53
    Dennis Aaen
    1

    Hi, Gregg,

    Maybe it could help you to learn XSLT, by looking at Umbraco.tv.

    There are a few free videos about XSLT. It is certainly a good start to learn XSLT in Umbraco. That's how I got understanding XSLT in Umbraco.

    http://umbraco.com/help-and-support/video-tutorials/introduction-to-umbraco.aspx?

    There is a video about XSLT on about 10 minutes, I hope this can get you started understanding working with XSLT in Umbraco.


    /Dennis


  • Gregg Duncan 48 posts 70 karma points
    Jan 11, 2012 @ 19:11
    Gregg Duncan
    0

    It's amazing how sometimes you can make something so difficult when the right way is so easy. 

    I figured out how to get the properties from my parent "News Library" page to appear on each of the "News Page" pages. Including getting the embedded .NET macro to work. I simply had to add "recursive='true'" to my Umbraco:Item tags.

    In my "News Library" template (Parent document) my side bar looks like this:

    <div class="sideinfo-top">
          <umbraco:Item field="sideBarTop" runat="server"></umbraco:Item>
        </div>
        <div class="sideinfo-header">
          <h2><umbraco:Item field="sideBarHeader" runat="server"></umbraco:Item></h2>
        </div>
        <div class="sideinfobox">
          <umbraco:Item field="sideBarContent" runat="server"></umbraco:Item>     </div> 

     so to output the same content in the side bar of the child pages. Including running the .NET macro imbedded in the RTE fields. I set up my "News Page" template (Child document) side bar to look like this:

    <div class="sideinfo-top">
          <umbraco:Item field="sideBarTop" runat="server" recursive="true"></umbraco:Item>
        </div>
        <div class="sideinfo-header">
          <h2><umbraco:Item field="sideBarHeader" runat="server" recursive="true"></umbraco:Item></h2>
        </div>
        <div class="sideinfobox">
          <umbraco:Item field="sideBarContent" runat="server" recursive="true"></umbraco:Item>
        </div>

     Wow I made this a lot harder than it had to be. But I learned some about XSLT in the process, so it's not all bad. 

    Thanks everyone for all your help.

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jan 11, 2012 @ 19:33
    Tom Fulton
    0

    Doh, not sure how I missed that, I think I got sidetracked by your inline XSLT comments :)  That's definately the way to go if it's all you need to do.

    Also FYI, you can use the same block of code from your News Page as your News Library - recursive will try to take the value from the current page, and if it's not available move up in the tree.  So recursive="true" on the Library page would still show the same data.

    -Tom

Please Sign in or register to post replies

Write your reply to:

Draft