NOTE: For more information on creating widgets, see http://www.ektron.com/eGandalf-Blog/Break-it-down-widget-development-how-to-pt1/.
To learn how to create a widget, create a simple widget in the siteroot/widgets
folder. This widget is based on the Hello World widget that is installed with the sample site with the following files:
HelloWorld.ascx
—user control fileHelloWorld.ascx.cs
—user control code-behind fileHelloWorld.ascx.jpg
—image that represents this control on the widget menuwidgets
folder.HelloWorld.ascx
.widgets
folder.Copy of HelloWorld.ascx
.new_widget.ascx
. Visual Studio automatically renames the code-behind file to new_widget.ascx.cs.
helloworld.ascx.jpg
file to new_widget.ascx.jpg.
The image file is 48 x 48 pixels and 72 dpi. Ektron administrators and content authors drag a widget’s image onto the page.new_widget.ascx
to open it.HelloWorld
(circled below) with new_widget
.new_widget.ascx.cs
. HelloWorld
with new_widget
.new_widget.ascx
and new_widget.ascx.cs.
new_widget.ascx
, appears in the list.PageLayout.aspx
. Or, any wireframe template that you are using to create a PageBuilder page.After you create a new widget and enable it in the Ektron Workarea, you can begin to customize it. For more information about customizing widgets, see Customizing Widgets.
Here is the new_widget.ascx
file that is the basis of the widget.
<%@ Control Language=”C#” AutoEventWireup=”true” CodeFile=”new_widget.ascx.cs” Inherits=”widgets_new_widget” %> <%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TagPrefix="asp" %> <asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0"> <asp:View ID="View" runat="server"> <!-- You Need To Do .............................. --> <asp:Label ID="TextLabel" runat="server"></asp:Label><br /> <asp:Label ID="CheckBoxLabel" runat="server"></asp:Label> <!-- End To Do .............................. --> </asp:View> <asp:View ID="Edit" runat="server"> <div id="<%=ClientID%>_edit"> <!-- You Need To Do .............................. --> <asp:TextBox ID="TextTextBox" runat="server" Style="width: 95%"> </asp:TextBox><br /> <asp:CheckBox ID="MyCheckBox" runat="server" Checked="false" /> <br /> <!-- End You Need To Do .............................. --> <asp:Button ID="CancelButton" runat="server" Text="Cancel" OnClick="CancelButton_Click" /> <asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" /> </div> </asp:View> </asp:MultiView>
Notice the following elements of the file.
asp:MultiView
element declares that the control has 2 possible modes: View and Edit.<asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0">
multiview
tags is information about the control in view mode. It has 2 fields: one is a text field, and the other is a check box.<asp:View ID="View" runat="server">
<asp:Label ID="HelloTextLabel" runat="server"></asp:Label><br />
<asp:Label ID="CheckBoxLabel" runat="server"></asp:Label>
</asp:View>
multiview
tags is information about the control in edit mode. In edit mode, a text box, a check box, and a Save button appear. The text box and check box collect end-user input, and the Save button saves that input to the database.<asp:View ID="Edit" runat="server">
<div id="<%=ClientID%>_edit">
<!-- You Need To Do .............................. -->
<asp:TextBox ID="HelloTextBox" runat="server" Style="width: 95%"> </asp:TextBox><br />
<asp:CheckBox ID="MyCheckBox" runat="server" Checked="false" /> <br />
<!-- End You Need To Do .............................. -->
<asp:Button ID="CancelButton" runat="server" Text="Cancel" OnClick="CancelButton_Click" />
<asp:Button ID="SaveButton" runat="server" Text="Save" OnClick="SaveButton_Click" />
Review the code-behind file,new_widget.ascx.cs
.
using
statements are at the top of the file. Notice the Ektron ones in particular:using Ektron.Cms.Widget; using Ektron.Cms;Marketing team using Ektron.Cms.API; using Ektron.Cms.Common; using Ektron.Cms.PageBuilder; using System.Text.RegularExpressions;
system.Web.UI.UserControl
and IWidget
classes.public partial class widgets_new_widget: System.Web.UI.UserControl, IWidget
The following figure summarizes the remaining elements of the code-behind file.
#region properties private string _HelloString; private bool _CheckBoxBool; [WidgetDataMember(true)] public bool CheckBoxBool { get { return _CheckBoxBool; } set { _CheckBoxBool = value; } } [WidgetDataMember("Hello Wolrd")] public string HelloString { get { return _HelloString; } set { _HelloString = value; } } #endregion
private IWidgetHost _host;
page_init
events.protected void Page_Init(object sender, EventArgs e) { _host = Ektron.Cms.Widget.WidgetHost.GetHost(this); _host.Title = "Hello World Widget"; _host.Edit += new EditDelegate(EditEvent); _host.Maximize += new MaximizeDelegate(delegate() { Visible = true; }); _host.Minimize += new MinimizeDelegate(delegate() { Visible = false; }); _host.Create += new CreateDelegate(delegate() { EditEvent(""); }); PreRender += new EventHandler(delegate(object PreRenderSender, EventArgs Evt) { SetOutput(); }); ViewSet.SetActiveView(View); }
Comments about the page_init code
gethost
method returns a reference to the container widgethost for this widget. This is the case in both Personalization and PageBuilder.Title
property is the title of this widget. By setting it in page_init
for the widget, we inform the host what text to put in the title bar above the widget. This works in both PageBuilder and Personalization.host.Title
are raised by the widgethost. It’s up to the widget to subscribe to them. In all cases, if we don’t subscribe to them, the icons don’t show up. This is a method of attaching widget code to button clicks and other events that occur outside the widget.PreRender
: Ektron renders the contents of this widget on pre-render, thus ensuring a single render event. Another option is to call SetOutput
on the Load event, but you can only do that if the widget is not in edit mode currently.edit
events.void EditEvent(string settings) { string sitepath = new CommonApi().SitePath; ScriptManager.RegisterClientScriptInclude(this, this.GetType(), "widgetjavascript", sitepath + "widgets/widgets.js"); ScriptManager.RegisterOnSubmitStatement(this.Page, this.GetType(), "gadgetescapehtml", "GadgetEscapeHTML('" + HelloTextBox.ClientID + "');"); HelloTextBox.Text = HelloString; MyCheckBox.Checked = CheckBoxBool; ViewSet.SetActiveView(Edit); }
Comments about the edit code
WARNING! You must register JavaScript and cascading style sheet (css) instructions in an external file.
sitepath
to ensure that the correct path for included files is used across installations.scriptmanager
to include the script. Alternatively, you can use Ektron.Cms.Api.Js.RegisterJSInclude ScriptManager.RegisterOnSubmitStatement(this.Page, this.GetType(), "gadgetescapehtml", "GadgetEscapeHTML('" + HelloTextBox.ClientID + "');");
onsubmitstatement
is JavaScript that is run when the widget is submitted. It calls escape html, which cleans the submitted text to avoid any XSS.HelloTextBox.Text = HelloString;
MyCheckBox.Checked = CheckBoxBool;
ViewSet.SetActiveView(Edit);
save
events.protected void SaveButton_Click(object sender, EventArgs e) { HelloString = ReplaceEncodeBrackets(HelloTextBox.Text); CheckBoxBool = MyCheckBox.Checked; _host.SaveWidgetDataMembers(); ViewSet.SetActiveView(View); }
SetOutput
events.protected void SetOutput() { HelloTextLabel.Text = HelloString; // client javascript remove brackets, server side adds back CheckBoxLabel.Text = CheckBoxBool.ToString(); }
Cancel
events.protected void CancelButton_Click(object sender, EventArgs e) { ViewSet.SetActiveView(View); }
protected string ReplaceEncodeBrackets(string encodetext) { encodetext = Regex.Replace(encodetext, "<", "<"); encodetext = Regex.Replace(encodetext, ">", ">"); return encodetext; }