Skip to content

Commit f44d094

Browse files
committed
Deduce the current attribute on ServiceNavigationNavItemTagHelper
1 parent f04a24a commit f44d094

File tree

6 files changed

+58
-7
lines changed

6 files changed

+58
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ See [the SASS sample](samples/Samples.Sass) for an example of how to use this.
2121
#### `<govuk-service-navigation-nav>` tag helper
2222
A `collapse-navigation-on-mobile` attribute has been added to control whether the service navigation is collapsed on mobile devices.
2323

24+
#### `<govuk-service-navigation-nav-item>` tag helper
25+
If not specified, the `current` attribute will be deduced by comparing the `href` attribute to the current request path.
26+
2427
## 3.1.2
2528

2629
### Fixes

docs/components/service-navigation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ Must be inside a `<govuk-service-navigation-nav>` element.
6767
| Attribute | Type | Description |
6868
| --- | --- | --- |
6969
| `active` | `bool?` | Whether the user is within this group of pages in the navigation hierarchy. |
70-
| `current` | `bool?` | Whether the user is currently on this page. This takes precedence over the `active` attribute. |
70+
| `current` | `bool?` | Whether the user is currently on this page. This takes precedence over the `active` attribute. By default, this is determined by comparing the current URL to this item's generated `href` attribute. |
7171
| (link attributes) | | See [documentation on links](../links.md) for more information. |
7272

7373

src/GovUk.Frontend.AspNetCore.Docs/GovUk.Frontend.AspNetCore.xml

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/GovUk.Frontend.AspNetCore.Docs/TagHelperApiProvider.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using System.ComponentModel;
12
using System.Reflection;
23
using System.Text;
34
using System.Text.RegularExpressions;
45
using System.Xml.Linq;
56
using GovUk.Frontend.AspNetCore.TagHelpers;
7+
using Microsoft.AspNetCore.Mvc.ViewFeatures;
68
using Microsoft.AspNetCore.Razor.TagHelpers;
79

810
namespace GovUk.Frontend.AspNetCore.Docs;
@@ -57,10 +59,26 @@ public TagHelperApi GetTagHelperApi(string tagHelperName)
5759
var memberName = m.Attribute("name")!.Value[(tagHelperClassName.Length + 3)..];
5860
var member = tagHelperType.GetProperty(memberName)!;
5961

62+
if (member.GetCustomAttribute<ViewContextAttribute>() is not null)
63+
{
64+
return null!;
65+
}
66+
67+
if (member.GetCustomAttribute<ObsoleteAttribute>() is not null)
68+
{
69+
return null!;
70+
}
71+
72+
if (member.GetCustomAttribute<EditorBrowsableAttribute>() is { State: EditorBrowsableState.Never })
73+
{
74+
return null!;
75+
}
76+
6077
var typeName = GetNormalizedTypeName(member.PropertyType);
6178

6279
var htmlAttributeName = member.GetCustomAttribute<HtmlAttributeNameAttribute>()!;
6380
var attributeName = htmlAttributeName.Name;
81+
6482
if (attributeName is null)
6583
{
6684
attributeName = htmlAttributeName.DictionaryAttributePrefix + "*";
@@ -76,7 +94,8 @@ public TagHelperApi GetTagHelperApi(string tagHelperName)
7694

7795
return new TagHelperApiAttribute(attributeName, typeName, description);
7896
})
79-
.OrderBy(m => m.Name)
97+
.Where(m => m is not null)
98+
.OrderBy(m => m!.Name)
8099
.ToList();
81100

82101
var canGenerateLinks = _anchorTagHelper.GetCustomAttributes<HtmlTargetElementAttribute>().Any(e => e.Tag == tagName);

src/GovUk.Frontend.AspNetCore/TagHelpers/PaginationItemTagHelper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class PaginationItemTagHelper : TagHelper
2525
/// Whether this item is the current page the user is on.
2626
/// </summary>
2727
/// <remarks>
28-
/// By default this is determined by comparing the current URL to this item's generated <c>href</c> attribute.
28+
/// By default, this is determined by comparing the current URL to this item's generated <c>href</c> attribute.
2929
/// </remarks>
3030
[HtmlAttributeName(CurrentAttributeName)]
3131
public bool? Current { get; set; }
@@ -34,9 +34,10 @@ public class PaginationItemTagHelper : TagHelper
3434
/// Whether this item is the current page the user is on.
3535
/// </summary>
3636
/// <remarks>
37-
/// By default this is determined by comparing the current URL to this item's generated <c>href</c> attribute.
37+
/// By default, this is determined by comparing the current URL to this item's generated <c>href</c> attribute.
3838
/// </remarks>
3939
[EditorBrowsable(EditorBrowsableState.Never)]
40+
[HtmlAttributeName("is-current")]
4041
[Obsolete("Use the 'current' attribute instead.", DiagnosticId = DiagnosticIds.UseCurrentAttributeInstead)]
4142
public bool? IsCurrent
4243
{

src/GovUk.Frontend.AspNetCore/TagHelpers/ServiceNavigationNavItemTagHelper.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using System.Text.Encodings.Web;
13
using GovUk.Frontend.AspNetCore.ComponentGeneration;
4+
using Microsoft.AspNetCore.Http.Extensions;
5+
using Microsoft.AspNetCore.Mvc.Rendering;
6+
using Microsoft.AspNetCore.Mvc.ViewFeatures;
27
using Microsoft.AspNetCore.Razor.TagHelpers;
38

49
namespace GovUk.Frontend.AspNetCore.TagHelpers;
@@ -30,10 +35,19 @@ public class ServiceNavigationNavItemTagHelper : TagHelper
3035
/// </summary>
3136
/// <remarks>
3237
/// This takes precedence over the <c>active</c> attribute.
38+
/// By default, this is determined by comparing the current URL to this item's generated <c>href</c> attribute.
3339
/// </remarks>
3440
[HtmlAttributeName(CurrentAttributeName)]
3541
public bool? Current { get; set; }
3642

43+
/// <summary>
44+
/// Gets the <see cref="ViewContext"/> of the executing view.
45+
/// </summary>
46+
[HtmlAttributeNotBound]
47+
[ViewContext]
48+
[DisallowNull]
49+
public ViewContext? ViewContext { get; set; }
50+
3751
/// <inheritdoc/>
3852
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
3953
{
@@ -55,9 +69,11 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
5569
attributes.Remove("href", out _);
5670
var href = output.GetUrlAttribute("href");
5771

72+
var current = Current ?? ItemIsCurrentPage();
73+
5874
var item = new ServiceNavigationOptionsNavigationItem()
5975
{
60-
Current = Current,
76+
Current = current,
6177
Active = Active,
6278
Html = content.ToTemplateString(),
6379
Text = null,
@@ -73,5 +89,11 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
7389
navContext.Items.Add(item);
7490

7591
output.SuppressOutput();
92+
93+
bool ItemIsCurrentPage()
94+
{
95+
var currentUrl = ViewContext!.HttpContext.Request.GetEncodedPathAndQuery();
96+
return href?.ToHtmlString(HtmlEncoder.Default) == currentUrl;
97+
}
7698
}
7799
}

0 commit comments

Comments
 (0)