Portal Engine Questions on portal engine and web parts.
Version 6.x > Portal Engine > CMSListMenu and Classes View modes: 
User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 7/25/2012 1:24:14 PM
   
CMSListMenu and Classes
I've got two things I need asssitance with:

1.) I have a pretty simple navigation structure although I need to have specific classes rendered to it, how can I go about getting this to work right and how can I get it to work with HTML5?

Here is my basic navigation structure:

I need to render the <nav> and role="navigation" somehow
<div id="sidebar">
<div id="sidebar inner">
<nav class="nav">
<ul role="navigation">
<li><a href="#"><b>Link1</b><span>caption for link1</span>
<ul class="sub">
<li><a href="#">link1 subpage1</a></li>
<li><a href="#">link1 subpage2</a></li>
<li><a href="#">link1 subpage3</a></li>
</ul>
</li>
<li><a href="#"><b>Link2</b><span>caption for link2</span>
<ul class="sub">
<li><a href="#">link2 subpage1</a></li>
<li><a href="#">link2 subpage2</a></li>
<li><a href="#">link2 subpage3</a></li>
</ul>
</li>
</ul>
</nav>
</div>
</div>

2.) The navigation structure is a vertical layout and the <a href="#"><b>Link2</b><span>caption for link2</span> code should render the "Link2" text and the "caption for link2" would show directly underneath the "Link2" text. Here is an example of what I'm talking about:

User image

How can I accomplish this?

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 7/25/2012 2:20:05 PM
   
RE:CMSListMenu and Classes
You will have to write your own menu control.
You could use .net reflector to get the source code of CMSListMenu and copy it then modify the output it produces and save it as a custom class to use. That's what I had to do.

Shame on Kentico for not providing a menu that is more customizable or with some nice events to subscribe to or methods to override that make rendering the the menu captions the way we want to more easy to do.

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 7/25/2012 4:21:12 PM
   
RE:CMSListMenu and Classes
That's what I was thinking I had to do. I've already created a menu control that renders a <span> tag inside the <a> tag which allows me to do some custom CSS work but was hoping to not have to do another. Yes, I agree, would be nice if the CMSListMenu was more flexible in regards to custom layout. Would make it a bit simpler to get complex navigation structure in place.

Thanks again.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 7/25/2012 2:32:15 PM
   
RE:CMSListMenu and Classes
You could use macros in your MenuCaption fields except that the menu control HtmlEncodes the output, which means your HTML markup would just come out as plain text.

Even if it didn't HTMLEncode the output, you would then have to train your client to write the macros themselves when they create new top level pages.

User avatar
Kentico Support
Kentico Support
kentico_janh - 7/26/2012 2:50:39 AM
   
RE:CMSListMenu and Classes
Hello,

It shouldn't be that difficult to render it by using the Universal Viewer and the Hierarchical transformation. If there is a problem with implementation, please let me know and I will try to help with.

Best regards,
Jan Hermann

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 7/26/2012 8:56:06 AM
   
RE:CMSListMenu and Classes
So Jan you're suggesting using the Universal Viewer in place of the CMSListMenu or with it? I've attempted the hierarchial transformations before and have been less than successful. Any suggestions for implementation would be welcomed!

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 7/26/2012 10:54:23 AM
   
RE:CMSListMenu and Classes
FroggEye wrote: So Jan you're suggesting using the Universal Viewer in place of the CMSListMenu or with it? I've attempted the hierarchial transformations before and have been less than successful. Any suggestions for implementation would be welcomed!

And on top of that, how would I apply my different css classes to the menu items when one was selected, not selected, etc? Does the Universal Viewer have those abilities?

User avatar
Kentico Support
Kentico Support
kentico_janh - 7/27/2012 2:07:01 AM
   
RE:CMSListMenu and Classes
Hello,

If you are talking about the pseudo-classes like:
a:link {color:#FF0000;} /* unvisited link */
a:visited {color:#00FF00;} /* visited link */
a:hover {color:#FF00FF;} /* mouse over link */
a:active {color:#0000FF;} /* selected link */

then it doesn't matter if it is a standard menu web part or another rendered HTML code.

If you mean you want to add a class to a current document to style it with different styles, you can check in the Item transformation if the current document is that rendered one and you can add a CSS class into it. Do you know how to do that?

Best regards,
Jan Hermann

User avatar
Kentico Support
Kentico Support
kentico_janh - 7/27/2012 1:56:06 AM
   
RE:CMSListMenu and Classes
Hello,

Ok, let's have following document structure:
User image

1) Create a hierarchical transformation and add first level transformations into it:

(Type) (Document types) (Level)
Header transformation All 0
<div id="sidebar">
<div id="sidebar inner">
<nav class="nav">
<ul role="navigation">
<li>


Footer transformation All 0
        </li>
</ul>
</nav>
</div>
</div>

Separator transformation All 0
</li>
<li>

Item transformation CMS.MenuItem 0
<a href="#"><b><%# Eval("DocumentName") %></b></a><span><%# Eval("DocumentName") %></span>

2) Now you need to specify, how documents are rendered in a sub menu:

Header transformation All 1
<ul class="sub">

Footer transformation All 1
</ul>


Separator transformation All 1 (needs to be empty to brake transformation inheritance)

Item transformation CMS.MenuItem 1
<li><a href="#"><%# Eval("DocumentName") %></a></li>

As you can see below, if you use this hierarchical transformation in the Universal Viewer web part, the rendered HTML code is very similar to your requested one:
<div id="sidebar">
<div id="sidebar inner">
<nav class="nav">
<ul role="navigation">
<li>
<a href="#"><b>computer</b></a><span>computer</span>
<ul class="sub">
<li>
<a href="#">hard drivers</a>
</li>
<li>
<a href="#">software</a>
</li>
</ul>
</li>
<li>
<a href="#"><b>web design</b></a><span>web design</span>
<ul class="sub">
<li>
<a href="#">domain names</a>
</li>
<li>
<a href="#">hosting</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>

Best regards,
Jan Hermann

User avatar
Kentico Support
Kentico Support
kentico_janh - 7/30/2012 5:56:19 AM
   
RE:CMSListMenu and Classes
You can also put the content of the first header and footer transformation into the Content before and after property of the Universal Viewer web part.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 7/30/2012 3:54:00 PM
   
RE:CMSListMenu and Classes
It's not really the building of the ul>li structure that's the problem, It's all the other stuff you have to take into consideration that the CMSListMenu already does. Like setting classes for the current node and using the MenuCaption instead of the document name and stuff like that.

We should be able to specify a menu item transformation or something. Even if we had to do it in code, there is no exposed event to hook in to so we can get the text of the menu items to have the markup we want in them.

We don't want to rewrite a navigation control, we want to just tweak it. Kentico doesn't come with a navigation control that lets us do this very easily, which I think is strange since every client I've ever had wants to have some snazzy menu that can't be done with Kentico out of the box.

User avatar
Kentico Support
Kentico Support
kentico_janh - 7/31/2012 2:06:14 AM
   
RE:CMSListMenu and Classes
Hello,

You want to generate your own menu structure and Kentico allows you to do that by 12 lines of transformation code. It sounds pretty simple to me and you have full control of rendered HTML output. And it is also not that hard to add your mentioned functionality. I have changed the Item transformation for you, so now it highlights current selected menu item and if there is a menu caption filled, it renders it instead of the document name (the transformation type is changed to the Text one):
<li class='menuItem{% DocumentID==CurrentDocument.DocumentID?"Highlighted":"" %}</a></li>

Best regards,
Jan Hermann

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/9/2012 11:00:20 AM
   
RE:CMSListMenu and Classes
I see what you're saying Jan, and I really do appreciate your help with this.

I just think that we should be able to at least specify a transformation for just the text part of the menu. Sometimes we just need an extra span around the Menu Caption to make it work with a nice CSS/javascript menu plugin like SuperFish.

It should be simple enough to at least add support for a non-ascx and non/xslt transformation.


User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 8/9/2012 11:53:45 AM
   
RE:CMSListMenu and Classes
Agree with you 100% Jiveabillion! I had to create a new CMSListMenu and parse through all the CMSListMenu.RenderedHTML just to add a <span> tag between the <a> tags. It only ended up being about 15 lines of code but it wasn't what I had expected I would need to do in order to make this particular menu work.

I've now got another issue which I'm going to have to write some special transformations for because the default CMSListMenu won't work again. I my hierarchical transformation I use the DocumentName as the main text and the DocumentMenuCaption as the sub text wrapped in a <span> tag. When I go to use the BreadCrumbs webpart now, the DocumentMenuCaption is used there and not the DocumentName. Seems DocumentMenuCaption ALWAYS overrides the DocumentName in any of the navigation webparts. Would be ideal to be able to select one or the other.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/9/2012 2:05:37 PM
   
RE:CMSListMenu and Classes
I just finished writing a web part that lets you specify transformations for the top level and sub level items. You can download it here:

http://www.mediafire.com/?t9tc9dc84pgcgih

In the zip file there is a .cs file that you need to put in your app_code folder and a web part export that you should be able to just import into your project.

Let me know if it works.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/9/2012 2:07:30 PM
   
RE:CMSListMenu and Classes
Read the description of the web part for some additional information. In short, you can use the macro parameter {%OriginalMenuItemText%} to output the text that the menu control would have output by default (The menucaption, documentname, or resolved macro expression).

User avatar
Member
Member
jmoughon-tamu - 8/23/2012 3:44:16 PM
   
RE:CMSListMenu and Classes
Could you provide a little more clarification here? I am having trouble applying transformations. Nothing is seeming to change the output of the menu.

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 8/23/2012 4:57:15 PM
   
RE:CMSListMenu and Classes
What have you done already?

User avatar
Member
Member
jmoughon - 8/23/2012 5:28:21 PM
   
RE:CMSListMenu and Classes
I used his custom webpart and tried to apply transformations, but I am not sure what I am doing or what I needed to do.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/24/2012 9:39:18 AM
   
RE:CMSListMenu and Classes
The transformations only affect the content inside of the anchor tag (or span tag if you have it set to render current page as a span). This allows you to add extra content or markup around the text of a menu, which is generally where you need to change something to get it to look the way you want.

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/24/2012 9:42:14 AM
   
RE:CMSListMenu and Classes
You also are required to use Text/XML or HTML or JQuery template types. It does not currently work with ASCX transformations and I have no plans to make it so.

Here is an example of a transformation:
<span class="itemText">{%OriginalMenuItemText%}</span><span class="itemSubText">{%MenuItemSubtitle%}</span>

User avatar
Member
Member
jmoughon - 8/24/2012 9:48:30 AM
   
RE:CMSListMenu and Classes
Got it. Thanks. I am trying to rewrite the classes on the UL and LI. I guess I need a different method

User avatar
Certified Developer 8
Certified Developer 8
Jiveabillion - 8/24/2012 10:18:15 AM
   
RE:CMSListMenu and Classes
you can change the class prefix in the settings and change your CSS to use the classes it outputs. It's a much better way than doing it the other way around.

User avatar
Member
Member
lwhittemore-emh - 8/29/2013 3:06:54 PM
   
RE:CMSListMenu and Classes
kentico_janh wrote: Hello,

You want to generate your own menu structure and Kentico allows you to do that by 12 lines of transformation code. It sounds pretty simple to me and you have full control of rendered HTML output. And it is also not that hard to add your mentioned functionality. I have changed the Item transformation for you, so now it highlights current selected menu item and if there is a menu caption filled, it renders it instead of the document name (the transformation type is changed to the Text one):
<li class='menuItem{% DocumentID==CurrentDocument.DocumentID?"Highlighted":"" %}</a></li>

Best regards,
Jan Hermann


This code does not seem to work. At least the macro to get the highlighted item does not.


User avatar
Kentico Support
Kentico Support
kentico_janh - 9/10/2013 1:22:01 AM
   
RE:CMSListMenu and Classes
Hello,

If you want to highlight a currently selected item in the menu, you can use the following code in your Item transformation:

ASCX transformation (same as above):
<%# IfCompare(Eval("NodeAliasPath"), CMS.CMSHelper.CMSContext.CurrentDocument.NodeAliasPath.ToString(), "regular", "selected") %>

so for example, the class property of a LI element would look like this:
<li class='<%# IfCompare(Eval("NodeAliasPath"), CMS.CMSHelper.CMSContext.CurrentDocument.NodeAliasPath.ToString(), "regular", "selected") %>'>

Text/XML or HTML transformations:
<li class='{% if (NodeAliasPath == CurrentDocument.NodeAliasPath) {return "selected"} else {return "regular") #% }'>

If you want to highlight all items in the path, you can use following code in your Item transformation:

ASCX transformation (same as in article):
<%# IfCompare(CMS.CMSHelper.CMSContext.CurrentDocument.NodeAliasPath.StartsWith(Eval("NodeAliasPath").ToString()).ToString(), "True", "regular", "selected") %>

so for example for the class property it would look like this:
<li class='<%# IfCompare(CMS.CMSHelper.CMSContext.CurrentDocument.NodeAliasPath.StartsWith(Eval("NodeAliasPath").ToString()).ToString(), "True", "regular", "selected") %>'>

Text/XML or HTML transformations:
<li class='{% if (CurrentDocument.NodeAliasPath.StartsWith(NodeAliasPath)) {return "selected"} else {return "regular") %}'>

Best regards,
Jan Hermann

1 2 3