How to customize a general link button to create a dynamic link with an internal link and a data source in Sitecore
I needed to generate a dynamic link with an internal link and data source item. For example, I wanted to create a link like the one below.
https://local.com/faq#heading-4f8d1f56-54af-4f2b-9f9b-0dcc6bcdec0b
/faq- Sitecore page item
4f8d1f56-54af-4f2b-9f9b-0dcc6bcdec0b - data source item
Let's dive deeper into the process.
- Switch to the core database in the CMS.
- Navigate to the folder path:
/sitecore/system/Field types/Link Types/General Link/Menu - Create a new item for the custom link button and provide a display name for the message.
**Message:** This is similar to the command action name.
Use: `contentlink:accordionlink(id=$Target)` - Expand the Link Field to include the custom button action. Use `"control:AccordionLink"` to find the AccordionLink control and open the dialog box.
- Create an XML file for a custom link to open a dialog box with an internal link and data source item.
- Extend a LinkForm field to develop a new custom submit action for a link button.
- Go to any General Link field, and you’ll find the new link button has been added.
- Now, click the link, and there you go!
- The `OnLoad` method provides the initial data to the dialog box, while the `OnOK` method handles the actual action that submits the form.
<?xml version="1.0" encoding="utf-8" ?>
<control xmlns:def="Definition" xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense">
<AccordionLink>
<FormDialog Icon="Network/32x32/link.png" Header="Insert a link" Text="Select both page link and datasource item. When done click the Link button." OKButton="Link">
<CodeBeside Type="Unity.Project.Unity.sitecore.shell.Applications.Dialogs.InsertLinkForm, Unity.Project.Unity"/>
<DataContext ID="InternalLinkDataContext"/>
<DataContext ID="DataSourceContext" Root="{E686F6D8-5EC7-4E3D-A3EC-E6789A874F34}"/>
<GridPanel Class="scFormTable" CellPadding="2" Columns="2" Width="100%">
<Label For="Text" GridPanel.NoWrap="true">
<Literal Text="Link Text:"/>
</Label>
<Edit ID="Text" Width="100%" GridPanel.Width="100%"/>
</GridPanel>
<div class="scStretch">
<div class="col2">
<Label For="InternalLinkTreeview" GridPanel.NoWrap="true">
<Literal Text="Page Link:"/>
</Label>
<Scrollbox Border="1px solid #CFCFCF">
<TreeviewEx ID="InternalLinkTreeview" DataContext="InternalLinkDataContext" Root="true" Style="padding-top: 10px" ContextMenu='Treeview.GetContextMenu("contextmenu")' />
</Scrollbox>
</div>
<div class="col2">
<Label For="DataSourceview" GridPanel.NoWrap="true">
<Literal Text="Datasource Item:"/>
</Label>
<Scrollbox Border="1px solid #CFCFCF">
<TreeviewEx ID="DataSourceview" DataContext="DataSourceContext" Style="padding-top: 10px" ContextMenu='Treeview.GetContextMenu("contextmenu")' />
</Scrollbox>
</div>
</div>
</FormDialog>
</AccordionLink>
</control>
Please find the CS file code. public class InsertLinkForm : LinkForm
{
protected DataContext InternalLinkDataContext;
protected TreeviewEx InternalLinkTreeview;
protected DataContext DataSourceContext;
protected TreeviewEx DataSourceview;
protected Edit Text;
protected override void OnLoad(EventArgs e)
{
Assert.ArgumentNotNull((object)e, nameof(e));
base.OnLoad(e);
if (Context.ClientPage.IsEvent)
return;
this.InternalLinkDataContext.GetFromQueryString();
this.DataSourceContext.GetFromQueryString();
string queryString = WebUtil.GetQueryString("ro");
string linkAttribute1 = this.LinkAttributes["url"];
//string linkAttribute2 = this.LinkAttributes["target"];
this.Text.Value = this.LinkAttributes["text"];
//string Anchor = this.LinkAttributes["anchor"];
string linkAttribute3 = this.LinkAttributes["id"];
if (string.IsNullOrEmpty(linkAttribute3) || !ID.IsID(linkAttribute3))
{
this.SetFolderFromUrl(linkAttribute1);
}
else
{
ID id = new ID(linkAttribute3);
if (Sitecore.Client.ContentDatabase.GetItem(id, this.InternalLinkDataContext.Language) == null && !string.IsNullOrWhiteSpace(linkAttribute1))
this.SetFolderFromUrl(linkAttribute1);
else
this.InternalLinkDataContext.SetFolder(new ItemUri(id, this.InternalLinkDataContext.Language, Sitecore.Client.ContentDatabase));
}
if (queryString.Length <= 0)
return;
this.InternalLinkDataContext.Root = queryString;
}
/// Handles a click on the OK button.
///
///
/// When the user clicks OK, the dialog is closed by calling
/// the CloseWindow method.
protected override void OnOK(object sender, EventArgs args)
{
Assert.ArgumentNotNull(sender, nameof(sender));
Assert.ArgumentNotNull((object)args, nameof(args));
Item selectionItem = this.InternalLinkTreeview.GetSelectionItem();
Item DataSourceItem = this.DataSourceview.GetSelectionItem();
if (selectionItem == null || DataSourceItem == null)
{
Context.ClientPage.ClientResponse.Alert("Select page and datasource item.");
}
else
{
string str = "heading-" + DataSourceItem.ID.Guid.ToString("D").ToLower();
Packet packet = new Packet("link", Array.Empty());
LinkForm.SetAttribute(packet, "text", (Control)this.Text);
LinkForm.SetAttribute(packet, "linktype", "internal");
LinkForm.SetAttribute(packet, "anchor", str);
LinkForm.SetAttribute(packet, "id", selectionItem.ID.ToString());
Assert.IsTrue(!string.IsNullOrEmpty(selectionItem.ID.ToString()) && ID.IsID(selectionItem.ID.ToString()), "ID doesn't exist.");
Context.ClientPage.ClientResponse.SetDialogValue(packet.OuterXml);
base.OnOK(sender, args);
}
}
private void SetFolderFromUrl(string url)
{
Assert.ArgumentNotNull((object)url, nameof(url));
if (this.LinkType != "internal")
url = "/sitecore/content" + Settings.DefaultItem;
if (url.Length == 0)
url = "/sitecore/content";
if (!url.StartsWith("/sitecore", StringComparison.InvariantCulture))
url = "/sitecore/content" + url;
this.InternalLinkDataContext.Folder = url;
}
}
Comments
Post a Comment