Kentico Xperience 13.0 ASP.NET Core Tag Helpers that generates links to pages from NodeGUID values
This package is compatible with ASP.NET Core 3.1+ applications or libraries integrated with Kentico Xperience 13.0.
-
Install the NuGet package in your ASP.NET Core project (or class library)
dotnet add package XperienceCommunity.PageLinkTagHelpers
-
Create an implementation of
ILinkablePage
:public class LinkablePage : ILinkablePage { public static LinkablePage Home { get; } = new LinkablePage(new Guid("...")); public static LinkablePage Store { get; } = new LinkablePage(new Guid("...")); public static LinkablePage ContactUs { get; } = new LinkablePage(new Guid("...")); public static LinkablePage TermsOfUse { get; } = new LinkablePage(new Guid("...")); public Guid NodeGUID { get; } protected LinkablePage(Guid nodeGUID) => NodeGUID = nodeGUID; public static IReadOnlyList<LinkablePage> All { get; } = new List<LinkablePage> { Home, Store, ContactUs, TermsOfUse }; }
-
Add the correct
@addTagHelper
directive to your_ViewImports.cshtml
file:(optional) Add your
LinkablePage
class's namespace to your_ViewImports.cshtml
file (ex: Sandbox.Pages).@using Sandbox.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Kentico.Content.Web.Mvc @addTagHelper *, Kentico.Web.Mvc @addTagHelper *, DancingGoatCore @addTagHelper *, XperienceCommunity.PageLinkTagHelpers
-
Register the library with ASP.NET Core DI:
public void ConfigureServices(IServiceCollection services) { // Use default implementations services.AddXperienceCommunityPageLinks(); // or use a custom implementation of ILinkablePageLinkRetriever services.AddXperienceCommunityPageLinks<MyCustomLinkablePageLinkRetriever>(); }
-
Use the
xp-page-link
tag helper on an<a>
element in a Razor View:<a href="" xp-page-link="LinkablePage.Home"> <img src="/getmedia/10d5e094-d9aa-4edf-940d-098ca69b5f77/logo.png" alt="..." /> </a>
-
(recommended) Create a global event handler to protect the Pages referenced by your
ILinkablePage
implementation:using System; using System.Linq; using CMS; using CMS.Core; using CMS.DataEngine; using CMS.DocumentEngine; [assembly: RegisterModule(typeof(LinkablePageProtectionModule))] namespace Sandbox { /// <summary> /// Protects <see cref="LinkablePage"/> instances that represent Pages in the content tree with hard coded <see cref="TreeNode.NodeGUID"/> values. /// </summary> public class LinkablePageProtectionModule : Module { public LinkablePageProtectionModule() : base(nameof(LinkablePageProtectionModule)) { } protected override void OnInit() { base.OnInit(); DocumentEvents.Delete.Before += Delete_Before; } private void Delete_Before(object sender, DocumentEventArgs e) { if (LinkablePage.All.Any(p => p.NodeGuid == e.Node.NodeGUID)) { e.Cancel(); var log = Service.Resolve<IEventLogService>(); log.LogError( nameof(LinkablePageProtectionModule), "DELETE_PAGE", $"Cannot delete Linkable Page [{e.Node.NodeAliasPath}], as it might be in use. Please first remove the Linkable Page in the application code and re-deploy the application."); } } } }
-
Use Kentico Xperience's Content Staging to keep your
LinkablePage
s valid between different environments.
Razor (assuming the ContactUs Page has a DocumentName
of "Contact Us"):
<a href="" xp-page-link="LinkablePage.ContactUs"></a>
Generated HTML will set the child content, href
and title
attributes:
<a href="/contact-us" title="Contact Us">Contact Us</a>
Razor (assuming the ContactUs Page has a DocumentName
of "Contact Us"):
<a href="" title="Please contact us" xp-page-link="LinkablePage.ContactUs">
<img src="..." />
</a>
Generated HTML will keep the child content and only set the href
and title
attributes:
<a href="/contact-us" title="Please contact us">
<img src="..." />
</a>
Razor:
<a href="" title="" xp-page-link="LinkablePage.ContactUs">
No title necessary!
</a>
Generated HTML will not populate the title
attribute, assuming the child content provides some text:
<a href="/contact-us" title=""> No title necessary! </a>
Razor (assuming the ContactUs Page has a DocumentName
of "Contact Us"):
<a href="" title="" xp-page-link="LinkablePage.ContactUs"> </a>
Generated HTML will populate the title
for accessibility:
<a href="/contact-us" title="Contact Us"> Contact Us </a>
Razor:
<a
href=""
xp-page-link="LinkablePage.ContactUs"
title="Please contact us"
xp-page-link-query-params="@(new NameValueCollection { { "a": "b" } })">
Contact us for help!
</a>
Generated HTML will include query string parameters in the href
, and set the title
attribute/child content as appropriate:
<a href="/contact-us?a=b" title="Please contact us">Contact us for help!</a>
If you discover a problem, please open an issue.
If you would like contribute to the code or documentation, please open a pull request.