Text/XML transformation - how to get current document WithAllData?

Alexey Sidelnikov asked on March 31, 2014 12:48

tl;dr: How can I load custom fields for current data item of the repeater inside Text/XML tranformation in hierarcical viewer? By default it's not loaded and I have to use WithAllData call on ALL CMSContext.Documents for each menu item - which is very inefficient. Looking for better solution.


I'm building a menu using "Text/XML transformation". The reason for that is that I need to have a complex logic (if/else), and the only way to get this working using ASCX transformations as far as I can see was a custom backend logic which returns HTML markup - which I'm not a fan of. For example, as an item template, I need this:

<li><a>MENU TITLE</a>

when current menu item has no children, and this:

<li><span>MENU TITLE</span>
  <ul>
     <li><a>MENU TITLE2</a></li>

when it does have children. Note that <li> is not closed (I'm using separator transformations for that - as per Kentico's "grand menu" example I found somewhere in the internet). That prevents me using <li runat=server visible="<%# some-logic %> trick with ASCX transformation. So I decided to go with "Text/XML" one. Here is how item transformation looks like:

{%
temp = List(Documents[NodeAliasPath]);

if (GetCountChildrenMenuNodes(NodeGUID)>0) {
      temp.ApplyTransformation("cms.menuitem.ItemWithChildren")
} else {
      temp.ApplyTransformation("cms.menuitem.ItemWithoutChildren")
}
#%}

and here is the cms.menuitem.ItemWithChildren one (a bit simplified):

{% 
   menuTitleIfParent = Documents.WithAllData[NodeAliasPath].GetValue("MenuTitleIfParent");
#%}
<li class='parent'>
  <span>{%DocumentName%}</span>
  <ul>
    <li><a>{%menuTitleIfParent%}</a></li>  

Basically, the question (trouble) is that without WithAllData in Documents.WithAllData[NodeAliasPath] expression, my custom field MenuTitleIfParent is not loaded, and GetValue("MenuTitleIfParent") returns nothing. Loading all data for all documents many-many times (while building the menu) seems very inefficient to me. How can I load custom field just for the current item of the repeater for Text/XML tranformation?

Recent Answers


Brenden Kehren answered on March 31, 2014 19:22

Have you followed this example? There should be no need to do any of what you are doing if you follow that example and use hierarchical transformations.

0 votesVote for this answer Mark as a Correct answer

Alexey Sidelnikov answered on April 1, 2014 19:17 (last edited on December 10, 2019 02:30)

Hello Brenden,

i did follow that example actually (and I mentioned it in my post - called it "grand menu" though). The problem with it is that it uses a lot of "quoted" html:

{%MenuItemTeaserImage.ToString()==""?"":"<img src='/getattachment/" + MenuItemTeaserImage + "/" + DocumentName + "?maxsidesize=20' style='margin: 0 5px 0 0; float: left;' />"|(identity)GlobalAdministrator%}

  • which I was trying to avoid by breaking if/else statement into 2 transformations. Otherwise item transformation code would become large and hardly readable... that was my concern - and the reason why I decided to do what I did.

Also - my menu is a bit more complicated than that example - for example, I need to know if there are child elements for each menu item in order to render ">" (open/close) button, etc...

does it make sense? would you agree with me? If so - would you know an answer to the original question I posted? How to avoid the inefficiency with WithAllData call?

Thank you.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on April 3, 2014 16:19

I apologize, I wasn't sure that "grand menu" was the same link I provided. When you say "very inefficient" what test results do you have or have seen? I'd be interested to see/hear them.

As far as a solution, by the looks of your code, I'd be inclined to say if you're navigation or dataset is that complex, then you should be using custom transformation methods. You can make your custom transformation methods/functions so they return a simple boolean value vs. returning or rendering HTML, I've taken this approach as well. Both work well and I've not run into performance issues with either.

0 votesVote for this answer Mark as a Correct answer

Tom F answered on January 6, 2017 00:53 (last edited on January 6, 2017 01:01)

remove me

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.