/// <summary> /// The actual implementation of GenerateToCFragment. This is factored out to be able to re-use the fragment HTML product logic for the root index element /// which would otherwise be skipped as it's an index element. /// </summary> /// <param name="navigatedPath">The navigated path.</param> /// <param name="relativePathToRoot">The relative path to root.</param> /// <returns></returns> public string PerformGenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot) { // we can't navigate deeper from here. If we are the element being navigated to, we are the current and will have to emit any additional relative URLs too. bool isCurrent = navigatedPath.Contains(this); var fragments = new List <string>(); var liClass = "tocentry"; var aClass = string.Empty; if (isCurrent) { liClass = "tocentry current"; aClass = "current"; } fragments.Add(string.Format("<li{0}><a{1} href=\"{2}{3}\">{4}</a>", string.IsNullOrWhiteSpace(liClass) ? string.Empty : string.Format(" class=\"{0}\"", liClass), string.IsNullOrWhiteSpace(aClass) ? string.Empty : string.Format(" class=\"{0}\"", aClass), relativePathToRoot, HttpUtility.UrlPathEncode(this.TargetURL), this.Name)); if (isCurrent && _relativeH2LinksOnPage.Any()) { // generate relative links fragments.Add(string.Format("<ul class=\"{0}\">", this.ParentContainer.IsRoot ? "currentrelativeroot" : "currentrelative")); foreach (var p in _relativeH2LinksOnPage) { fragments.Add(string.Format("<li class=\"tocentry\"><a href=\"#{0}\">{1}</a></li>", p.Item1, p.Item2)); } fragments.Add("</ul>"); } else { fragments.Add("</li>"); } return(string.Join(Environment.NewLine, fragments.ToArray())); }
/// <summary> /// Generates the ToC fragment for this element, which can either be a simple line or a full expanded menu. /// </summary> /// <param name="navigatedPath">The navigated path to the current element, which doesn't necessarily have to be this element.</param> /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> /// <returns></returns> public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot) { var fragments = new List <string>(); if (!this.IsRoot) { fragments.Add("<li class=\"tocentry\">"); } if (navigatedPath.Contains(this)) { // we're expanded. If we're not root and on the top of the navigated path stack, our index page is the page we're currently generating the ToC for, so // we have to mark the entry as 'current' if (navigatedPath.Peek() == this && !this.IsRoot) { fragments.Add("<ul class=\"current\">"); } else { fragments.Add("<ul>"); } // first render the level header, which is the index element, if present or a label. The root always has an __index element otherwise we'd have stopped at load. var elementStartTag = "<li><span class=\"navigationgroup\"><i class=\"fa fa-caret-down\"></i> "; var indexElement = this.IndexElement; if (indexElement == null) { fragments.Add(string.Format("{0}{1}</span></li>", elementStartTag, this.Name)); } else { if (this.IsRoot) { fragments.Add(indexElement.PerformGenerateToCFragment(navigatedPath, relativePathToRoot)); } else { fragments.Add(string.Format("{0}<a href=\"{1}{2}\">{3}</a></span></li>", elementStartTag, relativePathToRoot, HttpUtility.UrlPathEncode(indexElement.TargetURL), this.Name)); } } // then the elements in the container. Index elements are skipped here. foreach (var element in this.Value) { fragments.Add(element.GenerateToCFragment(navigatedPath, relativePathToRoot)); } fragments.Add("</ul>"); } else { // just a link fragments.Add(string.Format("<span class=\"navigationgroup\"><i class=\"fa fa-caret-right\"></i> <a href=\"{0}{1}\">{2}</a></span>", relativePathToRoot, HttpUtility.UrlPathEncode(this.TargetURL), this.Name)); } if (!this.IsRoot) { fragments.Add("</li>"); } return(string.Join(Environment.NewLine, fragments.ToArray())); }
/// <summary> /// The actual implementation of GenerateToCFragment. This is factored out to be able to re-use the fragment HTML product logic for the root index element /// which would otherwise be skipped as it's an index element. /// </summary> /// <param name="navigatedPath">The navigated path.</param> /// <param name="relativePathToRoot">The relative path to root.</param> /// <param name="navigationContext">The navigation context.</param> /// <returns></returns> public string PerformGenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, NavigationContext navigationContext) { // we can't navigate deeper from here. If we are the element being navigated to, we are the current and will have to emit any additional relative URLs too. bool isCurrent = navigatedPath.Contains(this); var fragments = new List <string>(); var liClass = "tocentry"; var aClass = string.Empty; if (isCurrent) { liClass = "tocentry current"; aClass = "current"; } fragments.Add(string.Format("<li{0}><a{1} href=\"{2}{3}\">{4}</a>", string.IsNullOrWhiteSpace(liClass) ? string.Empty : string.Format(" class=\"{0}\"", liClass), string.IsNullOrWhiteSpace(aClass) ? string.Empty : string.Format(" class=\"{0}\"", aClass), relativePathToRoot, this.GetFinalTargetUrl(navigationContext), this.Name)); if (isCurrent && _relativeLinksOnPage.Count > 0) { bool renderHeadings = _relativeLinksOnPage.SelectMany(x => x.Children).Any(x => x.Level > 1); if (!renderHeadings) { // check if there are headings of a higher level than 1 present. If so, continue and render as usual renderHeadings = _relativeLinksOnPage.Any(x => x.Level > 1); } if (renderHeadings) { // generate relative links fragments.Add("<ul class=\"currentrelative\">"); foreach (var heading in _relativeLinksOnPage) { var content = GenerateToCFragmentForHeading(heading, navigationContext); if (!string.IsNullOrWhiteSpace(content)) { fragments.Add(content); } } fragments.Add("</ul>"); } } else { fragments.Add("</li>"); } return(string.Join(Environment.NewLine, fragments.ToArray())); }