Dynamically resolving Sitefinity links when using HtmlField

Dynamically resolving Sitefinity links when using HtmlField

Posted on February 15, 2013 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

This is a solution to dynamically resolving links for sites running version of Sitefinity lower than 5.4 sites. Sitefinity 5.4 provides this out of the box.

When using HtmlField in user control or by adding custom fields of type LongText to Sitefinity modules and selecting pages, images, documents or videos using the built in selectors for those the link to the selected content or page Sitefinity will generate:

<a href="/page" SFREF="[F669D9A7-009D-4D83-DDAA-000000000002]BDC53495-7357-4B44-82D9-572C1A71374E">Page</a>
 the link indicates the selected page url is ~/page and the other attribute added to the link "SFREF" is used to resolve the proper link to the page selected if its moved to another url.

For example if the page is moved under another page its url will be ~/parent/page

When selecting pages or media content in Sitefinity built in ContentBlock widget which used HtmlField the link is resolved automatically if the page or image has been moved to new location or their url was changed.

 If you use HtmlField or LongText field in user control or as custom field in module you will not get the automatic link resolution.

To fix this when rendering the html entered in the HtmlField use use Sitefinity LinkParser class

//get the html from HtmlField and convert it in format usable for ResolveLinks method
var fixedHtml = LinkParser.UnresolveLinks(Name);
 
//resolve the links if there has been a change in the url
            NameLiteral.Text = LinkParser.ResolveLinks(fixedHtml, DynamicLinksParser.GetContentUrl, null, false);

 Attached is a user control utilizing html and implementing the use of LinkParser.

 

When using LongText field as custom field to modules the selected media or pages links also will not resolve and to overcome this, create a custom htmlField (the long text field is htmlfield control), which inherits from the default one and override GetStringValue method to use LinkParser

public class HtmlFieldCustom : HtmlField
  
{
  
    protected override string ScriptDescriptorType
  
    {
        get
        {
            return typeof(HtmlField).FullName;
        }
  
    }
  
    public override string GetStringValue(object value)
    {
        var val = base.GetStringValue(value);
  
        var fixedHtml = LinkParser.UnresolveLinks(val);
  
        val = LinkParser.ResolveLinks(fixedHtml, DynamicLinksParser.GetContentUrl, null, false);
  
        return val;
    }
}
 If you have added the field to News module (for other modules the approach is the same) edit the module widget template and in the template register the namespace of the class created above and use the class to render the LongText field.

<%@ Control Language="C#" %>
  <%@ Register TagPrefix="sf" Namespace="SitefinityWebApp" Assembly="SitefinityWebApp" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit" Assembly="Telerik.Sitefinity" %>
  
<telerik:RadListView id="listsControl" runat="server"
                     ItemPlaceholderId="ListContainer"
                     EnableEmbeddedSkins="false"
                     EnableEmbeddedBaseStylesheet="false">
  
    <LayoutTemplate>
        <div class="sfexpandableListWrp">
            <div class="sflistExpandAllLnkWrp">
                <asp:LinkButton ID="listExpandAllLnk" runat="server" class="sflistExpandAllLnk" Text="<%$ Resources:Labels, ExpandAll %>" OnClientClick="return false;" />
                <asp:LinkButton ID="listCollapseAllLnk" runat="server" class="sflistCollapseAllLnk" style="display: none;" Text="<%$ Resources:Labels, CollapseAll %>" OnClientClick="return false;" />
            </div>
            <asp:PlaceHolder id="ListContainer" runat="server" />
  
        </div>
    </LayoutTemplate>
    <ItemTemplate>
  
            <h2 class="sflistTitle">
  
                <asp:Literal runat="server" Text='<%# Eval("Title") %>' />
  
            </h2>
  
            <telerik:RadListView ID="listItemsControl" runat="server"
  
                    ItemPlaceholderID="ItemsContainer"
   
                    EnableEmbeddedSkins="false"
  
                    EnableEmbeddedBaseStylesheet="false">
  
                <LayoutTemplate>
  
                    <ul class="sflistList">
  
                        <asp:PlaceHolder ID="ItemsContainer" runat="server" />
  
                    </ul>
  
                </LayoutTemplate>
  
                <ItemTemplate>
  
                    <li class="sflistListItem">
  
                        <h3 class="sflistItemTitle">
  
                            <asp:LinkButton runat="server" ID="listItemToggleLnk" class="sflistItemToggleLnk" Text='<%# Eval("Title") %>' OnClientClick="return false;" />
  
                        </h3>
  
                        <div runat="server" ID="listItemContent" class="sflistItemContent" style="display: none;">
  
                            <asp:Literal runat="server" Text='<%# Eval("Content") %>' />
                          <sf:HtmlFieldCustom runat="server" DisplayMode="Read" Value='<%# Eval("TestField")%>' />
                        </div>
 
progress-logo

The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation