Skip to content

Commit 18f53ac

Browse files
dimodidimodi
authored andcommitted
Polish Menu Templates article
1 parent b3c0ae8 commit 18f53ac

File tree

2 files changed

+157
-85
lines changed

2 files changed

+157
-85
lines changed
-1.18 KB
Binary file not shown.

components/menu/templates.md

Lines changed: 157 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -10,130 +10,220 @@ position: 10
1010

1111
# Menu Templates
1212

13-
The Menu component allows you to define a custom template for its items. This article explains how you can use it.
13+
The Menu component allows you to define a custom template for its items. This article explains how to use it.
1414

15-
The `ItemTemplate` of an item is defined under the `ItemTemplate` tag of the menu.
15+
## ItemTemplate
1616

17-
The template receives the model to which the item is bound as its `context`. You can use it to render the desired content. The menu is a generic component, so you can use a named context variable that will be of the model type without additional casting.
17+
The template of all items is defined in the `ItemTemplate` tag of the Menu.
1818

19-
You can use the template to render arbitrary content according to your application's data and logic. You can use components in it and thus provide rich content instead of plain text. You can also use it to add DOM event handlers like click, doubleclick, mouseover if you need to respond to them.
19+
The template receives the respective Menu data item as its `context`. You can use it to render the desired content. You can also set the `Context` parameter of the `ItemTemplate` tag and use a [named context variable. This is useful in nested template scenarios]().
2020

21-
>caption Use templates to implement navigation between views without the UrlField feature
21+
The Menu item template can contain arbitrary content according such as HTML markup and other components. You can also use standard event handlers like `@onclick` or `@onmouseover`.
22+
23+
## Examples
24+
25+
### Use ItemTemplate for Navigation
26+
27+
The following example shows how to render `<NavLink>` tags inside the Menu and use them for navigation instead of the [built-in Menu navigation mechanism]({%slug menu-navigation%}). This approach requires the URL property name to be different from `Url`. In addition to rendering customization, `<NavLink>` also supports the `target="_blank"` attribute.
28+
29+
>caption Use Menu item template for navigation
2230
2331
````CSHTML
24-
Use your own NavLink elements for navigation instead of the built-in feature of the menu
32+
<h3>Menu with ItemTemplate</h3>
2533
26-
<TelerikMenu Data="@MenuItems"
27-
ItemsField="@nameof(MenuItem.SubSectionList)">
34+
<TelerikMenu Data="@MenuItems">
2835
<ItemTemplate Context="item">
2936
@{
30-
var shouldNavigate = !string.IsNullOrEmpty(item.Page);
37+
@*
38+
k-menu-link-text will make the NavLink similar to built-in Menu items.
39+
You also need to reset the underline and text color.
40+
Do not render an SvgIcon component if item.Icon is null.
41+
*@
42+
43+
var shouldNavigate = !string.IsNullOrEmpty(item.Href);
44+
3145
if (shouldNavigate)
3246
{
33-
@*k-menu-link-text will expand the NavLink to match default Menu styling*@
34-
<NavLink href="@item.Page" class="k-menu-link-text">@item.Section</NavLink>
47+
<TelerikSvgIcon Icon="@item.Icon" />
48+
<NavLink href="@item.Href" class="k-menu-link-text color-underline">@item.Text</NavLink>
3549
}
3650
else
3751
{
38-
@*k-menu-link-text will expand the span to match default Menu styling*@
39-
<span style="font-weight: bold;" class="k-menu-link-text">
40-
See more about our @item.Section.ToLowerInvariant()</span>
52+
<TelerikSvgIcon Icon="@item.Icon" />
53+
<span class="k-menu-link-text">@item.Text</span>
4154
}
4255
}
4356
</ItemTemplate>
4457
</TelerikMenu>
4558
46-
@code {
47-
public List<MenuItem> MenuItems { get; set; }
48-
49-
public class MenuItem
50-
{
51-
public string Section { get; set; }
52-
public string Page { get; set; }
53-
public List<MenuItem> SubSectionList { get; set; }
59+
<style>
60+
/* Reset NavLink styles for consistent look. */
61+
a.color-underline {
62+
color: inherit;
63+
text-decoration: none;
5464
}
65+
</style>
66+
67+
<h3>Default Menu</h3>
68+
69+
<TelerikMenu Data="@MenuItems" />
70+
71+
@code {
72+
public List<MenuItem> MenuItems { get; set; } = new();
5573
5674
protected override void OnInitialized()
5775
{
5876
MenuItems = new List<MenuItem>()
5977
{
6078
new MenuItem()
6179
{
62-
Section = "Company",
63-
SubSectionList = new List<MenuItem>()
80+
Text = "Company",
81+
Icon = SvgIcon.Globe,
82+
Items = new List<MenuItem>()
6483
{
6584
new MenuItem()
6685
{
67-
Section = "Overview",
68-
Page = "company/overview"
86+
Text = "Overview",
87+
Href = "company/overview",
88+
Icon = SvgIcon.InfoCircle
6989
},
7090
new MenuItem()
7191
{
72-
Section = "Events",
73-
Page = "company/events"
92+
Text = "Events",
93+
Href = "company/events",
94+
Icon = SvgIcon.Calendar,
95+
Items = new List<MenuItem>()
96+
{
97+
new MenuItem()
98+
{
99+
Text = "Boston",
100+
Href = "company/events/boston",
101+
Icon = SvgIcon.Calendar
102+
},
103+
new MenuItem()
104+
{
105+
Text = "Sofia",
106+
Href = "company/events/sofia",
107+
Icon = SvgIcon.Calendar
108+
}
109+
}
74110
},
75111
new MenuItem()
76112
{
77-
Section = "Careers",
78-
Page = "company/careers"
113+
Text = "Careers",
114+
Href = "company/careers",
115+
Icon = SvgIcon.User
79116
}
80117
}
81118
},
82119
new MenuItem()
83120
{
84-
Section = "Services",
85-
SubSectionList = new List<MenuItem>()
121+
Text = "Services",
122+
Icon = SvgIcon.Sparkles,
123+
Items = new List<MenuItem>()
86124
{
87125
new MenuItem()
88126
{
89-
Section = "Consulting",
90-
Page = "consultingservices"
127+
Text = "Consulting",
128+
Href = "consulting",
129+
Icon = SvgIcon.Graph
91130
},
92131
new MenuItem()
93132
{
94-
Section = "Education",
95-
Page = "education"
133+
Text = "Education",
134+
Href = "education",
135+
Icon = SvgIcon.Book
96136
}
97137
}
98138
}
99139
};
100140
101141
base.OnInitialized();
102142
}
143+
144+
public class MenuItem
145+
{
146+
public string Text { get; set; } = string.Empty;
147+
public string Href { get; set; } = string.Empty;
148+
public ISvgIcon? Icon { get; set; }
149+
public List<MenuItem>? Items { get; set; }
150+
}
103151
}
104152
````
105153

106-
>caption Use templates to visually distinguish the current page as an item that is styled differently, and to open external links in new tabs
154+
### Use ItemTemplate for Styling and target="_blank"
155+
156+
The example below shows a Menu configuration that is suitable for use in `MainLayout.razor`.
157+
158+
>caption Use Menu item template to distinguish the current page and open external links in new browser windows
159+
160+
<div class="skip-repl"></div>
107161

108162
````CSHTML
109-
@inject NavigationManager navigationManager
163+
@inject NavigationManager NavManager
110164
111165
<TelerikMenu Data="@MenuItems" OnClick="@((MenuItem item) => OnClick(item))">
112166
<ItemTemplate Context="item">
113167
@{
168+
@*
169+
k-menu-link-text will make the NavLink or span similar to built-in Menu items.
170+
You also need to reset the underline and text color.
171+
Do not render an SvgIcon component if item.Icon is null.
172+
*@
173+
114174
if (EqualityComparer<MenuItem>.Default.Equals(item, SelectedMenuItem))
115175
{
116-
@*k-menu-link-text will expand the span to match default Menu styling*@
117-
<span style="color: black; font-weight: bold" class="k-menu-link-text">@item.Text</span>
176+
<TelerikSvgIcon Icon="@item.Icon" />
177+
<span style="color: black; font-weight: bold;" class="k-menu-link-text">@item.Text</span>
118178
}
119179
else
120180
{
121-
string target = "";
122-
if (!IsInternalPage(item.Url))
181+
string target = string.Empty;
182+
if (!IsInternalPage(item.Href))
123183
{
124184
target = "_blank";
125185
}
126-
@*k-menu-link-text will expand the NavLink to match default Menu styling*@
127-
<NavLink target="@target" href="@item.Url" class="k-menu-link-text">@item.Text</NavLink>
186+
<TelerikSvgIcon Icon="@item.Icon" />
187+
<NavLink target="@target" href="@item.Href" class="k-menu-link-text color-underline">@item.Text</NavLink>
128188
}
129189
}
130190
</ItemTemplate>
131191
</TelerikMenu>
132192
193+
<style>
194+
/* Reset NavLink styles for consistent look. */
195+
a.color-underline {
196+
color: inherit;
197+
text-decoration: none;
198+
}
199+
</style>
200+
133201
@code {
134-
public List<MenuItem> MenuItems { get; set; }
202+
private List<MenuItem> MenuItems { get; set; } = new();
203+
204+
private MenuItem? SelectedMenuItem { get; set; }
205+
206+
private void OnClick(MenuItem item)
207+
{
208+
if (IsInternalPage(item.Href))
209+
{
210+
SelectedMenuItem = item;
211+
}
212+
}
135213
136-
public MenuItem SelectedMenuItem { get; set; }
214+
private bool CompareCurrentPageUrl(string urlToCompare)
215+
{
216+
return NavManager.Uri.Substring(NavManager.BaseUri.Length - 1).Equals(urlToCompare);
217+
}
218+
219+
private bool IsInternalPage(string url)
220+
{
221+
if (string.IsNullOrEmpty(url))
222+
{
223+
return false;
224+
}
225+
return !(url.StartsWith("https://") || url.StartsWith("http://"));
226+
}
137227
138228
protected override void OnInitialized()
139229
{
@@ -142,77 +232,59 @@ Use your own NavLink elements for navigation instead of the built-in feature of
142232
new MenuItem()
143233
{
144234
Text = "Home",
145-
Url = "/",
235+
Href = "/",
236+
Icon = SvgIcon.Home
146237
},
147238
new MenuItem()
148239
{
149-
Text = "Fetch Data",
150-
Url = "/fetchdata"
240+
Text = "Counter",
241+
Href = "/counter",
242+
Icon = SvgIcon.Calculator
151243
},
152244
new MenuItem()
153245
{
154-
Text = "Counter",
155-
Url = "/counter"
246+
Text = "Weather",
247+
Href = "/weather",
248+
Icon = SvgIcon.Globe
156249
},
157250
new MenuItem()
158251
{
159-
Text = "Telerik UI for Blazor",
252+
Text = "Telerik",
253+
Href = "https://www.telerik.com",
254+
Icon = SvgIcon.Star,
160255
Items = new List<MenuItem>()
161256
{
162257
new MenuItem()
163258
{
164259
Text = "Documentation",
165-
Url = "https://docs.telerik.com/blazor-ui/introduction"
260+
Href = "https://docs.telerik.com/blazor-ui/introduction",
261+
Icon = SvgIcon.Star
166262
},
167263
new MenuItem()
168264
{
169-
Text = "Live Demos",
170-
Url = "https://demos.telerik.com/blazor-ui"
265+
Text = "Demos",
266+
Href = "https://demos.telerik.com/blazor-ui",
267+
Icon = SvgIcon.Star
171268
}
172269
}
173270
}
174271
};
175272
176-
SelectedMenuItem = MenuItems.Find(item => CompareCurrentPageUrl(item.Url));
273+
SelectedMenuItem = MenuItems.Find(item => CompareCurrentPageUrl(item.Href));
177274
178275
base.OnInitialized();
179276
}
180277
181-
private void OnClick(MenuItem item)
182-
{
183-
if (IsInternalPage(item.Url))
184-
{
185-
SelectedMenuItem = item;
186-
}
187-
}
188-
189-
private bool CompareCurrentPageUrl(string urlToCopmare)
190-
{
191-
return navigationManager.Uri.Substring(navigationManager.BaseUri.Length - 1).Equals(urlToCopmare);
192-
}
193-
194-
private bool IsInternalPage(string url)
195-
{
196-
if (string.IsNullOrEmpty(url))
197-
{
198-
return false;
199-
}
200-
return !(url.StartsWith("https://") || url.StartsWith("http://"));
201-
}
202-
203278
public class MenuItem
204279
{
205-
public string Text { get; set; }
206-
public string Url { get; set; }
207-
public List<MenuItem> Items { get; set; }
280+
public string Text { get; set; } = string.Empty;
281+
public string Href { get; set; } = string.Empty;
282+
public ISvgIcon? Icon { get; set; }
283+
public List<MenuItem>? Items { get; set; }
208284
}
209285
}
210286
````
211287

212-
>caption The result from the snippet above, assuming the current page URL is `/counter`
213-
214-
![Blazor Menu Template Distinguish Item](images/menu-template-distinguish-item.png)
215-
216288
## See Also
217289

218290
* [Data Binding a Menu]({%slug components/menu/data-binding/overview%})

0 commit comments

Comments
 (0)