Creating the “Hello World” Widget

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:

Step 1: Copy, paste, and rename HelloWorld.ascx and HelloWorld.ascx.jpg

Step 1: Copy, Paste, and Rename HelloWorld.ascx and HelloWorld.ascx.jpg

  1. Open your Web site in Visual Studio.
  2. In the Visual Studio Solution Explorer, open the widgets folder.

  3. Within that folder, scroll down to and select HelloWorld.ascx.

  4. Right click the mouse and choose Copy.
  5. Scroll up to the widgets folder.
  6. Right click the mouse and choose Paste.

  7. Scroll down until you see Copy of HelloWorld.ascx.
  8. Right click and choose Rename.

  9. Rename the file new_widget.ascx. Visual Studio automatically renames the code-behind file to new_widget.ascx.cs.
  10. Copy, paste, then rename the 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.
Step 2: Update the class names in the new files

Step 2: Update the Class Names in the New Files

  1. Double click on new_widget.ascx to open it.
  2. On the first line of that file, replace the reference to HelloWorld (circled below) with new_widget.

  3. Double click on the code-behind file, new_widget.ascx.cs.
  4. Replace the class HelloWorld with new_widget.

  5. Save new_widget.ascx and new_widget.ascx.cs.
  6. Check for errors by choosing Build > Build Page for each file. Correct any errors before proceeding.
Step 3: Add widget in Ektron Workarea

Step 3: Add Widget in Ektron Workarea

  1. Open the Ektron Workarea.
  2. Choose Settings > Configuration > Personalizations > Widgets.
  3. Click Synchronize. The new user control file, new_widget.ascx, appears in the list.
  4. Choose Settings > Configuration > Template Configuration.
  5. Find the template that you created in Building Pages, PageLayout.aspx. Or, any wireframe template that you are using to create a PageBuilder page.

  6. Click Update Template. On the Update Template screen, scroll down until you see the new widget.

  7. Click Select All (circled in the figure).
  8. Click Update Template. For directions on creating a PageBuilder page, see Building Pages.
  9. Go to Content and select a folder that has a PageBuilder page.
    1. Choose Content > Folders > PageBuilder and click on PageLayout.
    2. Click Edit Page Layout.
  10. Open the Widget menu. Make sure your new widget appears on the menu.

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.

Understanding the user control (.ascx) file

Understanding the User Control (.ascx) File

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.

  • The asp:MultiView element declares that the control has 2 possible modes: View and Edit.
    <asp:MultiView ID="ViewSet" runat="server" ActiveViewIndex="0">
  • in view mode, the marketing team can see the control but not change it.
  • in edit mode, the developers can change the control’s content and properties.
  • Between the 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>
  • Also between the 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" />
Understanding the code-behind (.ascx.cs) file

Understanding the Code-behind (.ascx.cs) File

Review the code-behind file,new_widget.ascx.cs.

  • A series of 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;
  • Next, note a widget host class, which inherits the 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.

  • In the next line, notice the widget’s properties: a string for the text field, and a boolean for the check box. You define the variables and their type here. Possible types are string, integer, long and date.
    #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
  • The following is a widget host declaration.
    private IWidgetHost _host;
  • The following is the widget’s 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

Comments about the page_init code

  • The gethost method returns a reference to the container widgethost for this widget. This is the case in both Personalization and PageBuilder.
  • The 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.
  • The events below 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.
  • For 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.
  • The final line sets the view to display mode.
  • The following is the declaration of the widget’s 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

Comments about the edit code

WARNING! You must register JavaScript and cascading style sheet (css) instructions in an external file.

  • The Edit event is triggered by the widgethost, and if you subscribed to it already, it will call the delegate here.
  • Use sitepath to ensure that the correct path for included files is used across installations.
  • Ensure that it works inside update panels by calling the scriptmanager to include the script. Alternatively, you can use Ektron.Cms.Api.Js.RegisterJSInclude ScriptManager.RegisterOnSubmitStatement(this.Page, this.GetType(), "gadgetescapehtml", "GadgetEscapeHTML('" + HelloTextBox.ClientID + "');");
  • The onsubmitstatement is JavaScript that is run when the widget is submitted. It calls escape html, which cleans the submitted text to avoid any XSS.
  • Notice the editing fields, so users can see the existing data.

    HelloTextBox.Text = HelloString;

    MyCheckBox.Checked = CheckBoxBool;

    ViewSet.SetActiveView(Edit);

  • The following code is the widget’s save events.
    protected void SaveButton_Click(object sender, EventArgs e)
        {
            HelloString = ReplaceEncodeBrackets(HelloTextBox.Text);
            CheckBoxBool = MyCheckBox.Checked;
            _host.SaveWidgetDataMembers();
            ViewSet.SetActiveView(View);
        }
  • The following code is the widget’s SetOutput events.
    protected void SetOutput()
        {
            HelloTextLabel.Text = HelloString;  
            // client javascript remove brackets, server side adds back
            CheckBoxLabel.Text = CheckBoxBool.ToString();
        }
  • The following code is the widget’s Cancel events.
    protected void CancelButton_Click(object sender, EventArgs e)
        {
            ViewSet.SetActiveView(View);
        }
  • The following code is for greater than and less than signs.
    protected string ReplaceEncodeBrackets(string encodetext)
        {
            encodetext = Regex.Replace(encodetext, "&lt;", "<");
            encodetext = Regex.Replace(encodetext, "&gt;", ">");
            return encodetext;
        }