The first thing I wanted for my BlogEngine powered site was to write a widget.
Since I haven´t dived very deep into the BE.NET code I´ll start with a simple widget that displays some profile information and a small image, like an avatar.
Basically, a classic "About Me" widget that will replace the TextBox widget that comes along with the source.
The basics
A widget consists of two elements; a widget control (ordinary user control) containing the UI and logic, and an edit control which both must inherit from WidgetBase and WidgetEditBase. They has to be placed in the widgets folder in the BlogEngine.Net project for it to work. BE.NET then uses reflection to dynamically load new widgets upon compile time. Every widget also has it´s own "storage" for storing widget-related data. Just call WidgetBase.GetSettings() to retrieve a StringDictionary and WidgetEditBase.SaveSettings(StringDictionary d) to save. The widget framework will take care of all the serialization and deserialization for you.
Step 1
Start with creating a new folder - lets call it AboutMe - in the widgets folder.

Then add 2 usercontrols; widget & edit and make them inherit from WidgetBase and WidgetEditBase
public partial class widgets_AboutMe_Widget : WidgetBase
{
}
public partial class widgets_AboutMe_edit : WidgetEditBase
{
}
Now we have to override some properties/functions in the widget control:
public override string Name
{
get { return "AboutMe"; }
}
public override bool IsEditable
{
get { return true; }
}
public override void LoadWidget()
{
//Nothing to do
}
The Name property decides the name for the property and it _must_ be the same as the folder name.
The IsEditable property tells the widget engine whether or not the widget is editable.
The LoadWidget() function is a widgets equivalent to Page_Load.
If you compile it now you should be able to add your new widget to the sidebar.
Dont forget to add the WidgetZone in your master page.
<blog:WidgetZone ID="WidgetZone1" runat="server" ZoneName="be_WIDGET_ZONE" />
Step 2 - Add some logic
Ok, so now we have widget - it doesn´t do very much but at least it´s there.
Lets add some containers for an image and some description in the widget.asmx file.
1: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Widget.ascx.cs"
Inherits="widgets_AboutMe_Widget" %>
2:
3: <asp:PlaceHolder runat="Server" ID="widgetAboutMe" />
4:
5: <asp:Image runat="server" ID="imageurl2" ImageUrl="" />
6:
7: <br />
8:
9: <%= Description %>
Now - to the code behind file.
We will start by adding two properties; ImageUrl and Description... Yeay, the one´s we used in the asmx file.
We´ll then add some logic to the Page_Load function which does the following:
- Retrieve the currently displayed profile (the name)
- Retrieve the AboutMe text for that particular profile (set in the profiles tab in the control panel)
- Retrieve the image url
By currently displayed profile, I mean a profile selected using the edit functionality - we will get to that part later. Dont get confused over the GetSettings() call, it´s a function from the base class that returns a dictionary with values for this particular widget.
Here is what the code behind file looks like:
1: using System;
2: using System.Collections.Generic;
3: using System.Web;
4: using System.Web.UI;
5: using System.Web.UI.WebControls;
6: using System.Collections.Specialized;
7: using BlogEngine.Core;
8:
9: public partial class widgets_AboutMe_Widget : WidgetBase
10: {
11: public string Description;
12: public string ImageURL;
13:
14: protected void Page_Load(object sender, EventArgs e)
15: {
16: StringDictionary settings = GetSettings();
17: if (!string.IsNullOrEmpty(settings["activeprofile"]))
18: {
19: foreach (AuthorProfile profile in AuthorProfile.Profiles)
20: if (profile.UserName.Equals(settings["activeprofile"]))
21: {
22: Description = profile.AboutMe;
23: break;
24: }
25: }
26: else //if no profile is previously selected
27: {
28: foreach (AuthorProfile profile in AuthorProfile.Profiles)
29: { //pick the first one, but not the admin profile
30: if (profile.UserName != "admin" && !string.IsNullOrEmpty(profile.AboutMe))
31: {
32: Description = profile.AboutMe;
33: break;
34: }
35: }
36: }
37:
38: if (!string.IsNullOrEmpty(settings["imageurl"]))
39: ImageURL = settings["imageurl"];
40: else //set default url
41: ImageURL = "themes/terrafirma/noavatar.jpg";
42: imageurl2.ImageUrl = ImageURL;
43: //StringDictionary settings = GetSettings();
44:
45: }
46:
47: public override string Name
48: {
49: get { return "AboutMe"; }
50: }
51:
52: public override bool IsEditable
53: {
54: get { return true; }
55: }
56:
57: public override void LoadWidget()
58: {
59: //Nothing to do
60: }
61: }
Since we don´t have an edit yet, the first profile (part from admin) with an AboutMe text defined will the displayed by the widget.
Now - lets dive into the edit functionality...
Part 3 - Edit
Adding edit functionality is just as straight forward as the widget control itself. Basically, you only read and write to/from the settings dictionary, and populate the controls in the asmx file when loaded. Since we have two properties; ImageUrl and Description, we are going to add these two to the edit page.
Begin by adding an input control for our image url and radioButtonList which are going to be our list with available profiles.
The BE engine will wire up events for displaying the edit control when you press edit link.
1: <%@ Control Language="C#" AutoEventWireup="true" CodeFile="edit.ascx.cs"
2: Inherits="widgets_AboutMe_edit" %>
3:
4: <div>
5: <h3>Select profile</h3>
6:
7: Image URL:
8: <input type="text" id="imageurl" runat="server"
9: value="~/themes/terrafirma/noavatar.jpg" />
10:
11: <asp:RadioButtonList ID="profiles" runat="server"
12: DataTextField="UserName" DataValueField="UserName">
13: </asp:RadioButtonList>
14:
15: <br />
16:
17:
18: </div>
Now - the take a look at the code behind file:
1: using System;
2: using System.Collections.Generic;
3: using System.Collections.Specialized;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
7: using BlogEngine.Core;
8:
9: public partial class widgets_AboutMe_edit : WidgetEditBase
10: {
11: protected void Page_Load(object sender, EventArgs e)
12: {
13: if (!IsPostBack)
14: {
15: string ActiveProfile = null;
16:
17: //Get widget settings
18: StringDictionary settings = GetSettings();
19: ActiveProfile = settings["activeprofile"];
20:
21: //Fill the dropdown with the available profiles
22: profiles.DataSource = AuthorProfile.Profiles;
23: profiles.DataBind();
24:
25: imageurl.Value = settings["imageurl"];
26:
27: if (!string.IsNullOrEmpty(ActiveProfile))
28: profiles.SelectedValue = ActiveProfile;
29: }
30:
31:
32: }
33:
34: public override void Save()
35: {
36: StringDictionary settings = GetSettings();
37: settings["activeprofile"] = profiles.SelectedValue;
38: settings["imageurl"] = imageurl.Value;
39: SaveSettings(settings);
40: }
41: }
That´s not so bad huh, lets go through it.
First we start off by setting ActiveProfile to the value from our settings, and then we go ahead and set our RadioButtonList using databinding.
Least but not last we retrieve the image url and populate the textbox with it.
Thats all there is to it - now you have a working widget - in less than 1 hour 
Step 4 - Summary
All we have to do is:
- Create a folder for your widget in the widgets folder
- Add two user controls; widget and edit
- Make them inherit from WidgetBase and WidgetEditBase
- Override the Name and IsEditable properties and the LoadWidget() function
- Don't forget: The Name propert must return the exact name of your widget folder (AboutMe in this example)
- Override the Save() function in the edit control, save all your stuff her
Happy coding!
525fc701-634e-4f08-9d16-c101e53991d7|2|4.5