We just migrated a system from a custom built CMS into EPiServer. If the editor added a link to an unpublished page in the old CMS, it was automatically unlinked for the visitor until the page was published. We tried to find a built in way of doing in this in EPiServer, but could not find one. So instead we created a custom HtmlHelper that did if for us.
The helper method uses Html Agility pack to parse the html code and find links, then we find the content in EPiServer and check if it is published or not. If it’s unpublished we remove the wrapping a-tag.
Bear in mind that the lookup if a page is published or not costs in performance. We’ve added caching on the lookup so it’s only the first lookup on a url that takes time. Another thing to consider in the code below is that we only check pages, and not other content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
public static MvcHtmlString PropertyForHideUnpublished<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) { var val = html.PropertyFor(expression); if (PageEditing.PageIsInEditMode) { return val; } var doc = new HtmlDocument(); doc.LoadHtml(val.ToHtmlString()); var nodes = doc.DocumentNode.SelectNodes("//a[@href]"); if (nodes == null) { return val; } var changed = false; foreach (var node in nodes) { var url = node.Attributes["href"].Value; if (!url.StartsWith("/")) { continue; } var key = "unpublished-check-" + url; var unpublished = false; var cached = CacheManager.Get(key) as bool?; if (cached.HasValue) { unpublished = cached.Value; } else { var content = UrlResolver.Current.Route(new UrlBuilder(url)); var page = content as PageData; if (page != null && !page.CheckPublishedStatus(PagePublishedStatus.Published)) { unpublished = true; } CacheManager.Insert(key, unpublished); } if (unpublished) { var newNode = HtmlNode.CreateNode(node.InnerText); node.ParentNode.ReplaceChild(newNode, node); changed = true; } } return changed ? new MvcHtmlString(doc.DocumentNode.OuterHtml) : val; } |