As you develop your second web site and look to start sharing custom controls there is no doubt you will want to find a way to do so with ease. Sitefinity employs modules as their next step in the evolution of customization. While working to package up a few controls I put together a bare bones module to demonstrate how to use a module, explore the new SimpleControl class which has a brief mention in the documentation-by-blog, and an easy way to deploy the module.
When creating a module you derive from the Telerik.WebModule class. Once you have done so there is very little you need to implement. For the sake of our sample class we will override Name, Title, Description, and Controls properties:
public class HelloWorldModule : Telerik.WebModule
{
#region Properties
public override IList Controls
{
get
{
return new List(new ToolboxItem[] {
new HelloWorldToolboxItem()
});
}
}
public override string Description
{
get
{
return "Control library demonstration";
}
}
public override string Name
{
get
{
return "Hello World Controls";
}
}
public override string Title
{
get
{
return "Hello World Controls";
}
}
#endregion
}
The Controls property returns a list of class instances derived from the Telerik.Web.ToolboxItem class. This is used by Sitefinity to populate the page editor’s toolbox without having to explicitly define each control the web site’s web.config. The Toolbox Item is not much more than a DisplayName and Description of the item for use in the page editor view:
public class HelloWorldToolboxItem : Telerik.Web.ToolboxItem
{
#region Constructors
public HelloWorldToolboxItem()
: this(typeof(HelloWorld)) { }
public HelloWorldToolboxItem(Type type)
: base(typeof(HelloWorld))
{
base.DisplayName = "Hello World!";
base.Description = "Simple Control sample";
}
#endregion
}
The sample control is derived from SimpleControl which provides localization and embedded template support. We have included an embedded user control in the project which creates a label control and exposes that through our control interface:
[ToolboxItem(typeof(HelloWorldToolboxItem)),
ToolboxData("<{0}:HelloWorld runat=\"server\" />")]
public class HelloWorld : Telerik.Cms.Web.UI.SimpleControl
{
#region Properties
[Bindable(true), Category("Text"), DefaultValue("Hello world!"),
Description("Gets or sets the Label text."),]
public string LabelText { get; set; }
public override string LayoutTemplateName
{
get
{
return "SampleControlLibrary.HelloWorld.ascx";
}
}
protected ITextControl Label1
{
get
{
return base.Container.GetControl("Label1", true);
}
}
#endregion
#region Constructor
public HelloWorld()
{
LabelText = "Hello world!";
}
#endregion
#region Methods
protected override void CreateChildControls()
{
base.CreateChildControls();
Label1.Text = LabelText;
}
#endregion
}
To make deployment easy I used the often forgotten System.Configuration.Install.Installer class which is called by the installer utility, InstallUtil.exe. The challenge with using this class is that there is very little guidance or examples of how to use it. I referred to an article on Windows Installer installation phases, which this class is loosely based upon, to guide my implementation. Below is a snippet of the Install method. In addition I have implemented Commit, Rollback, and Uninstall.
...
public override void Install(IDictionary stateSaver)
{
if (!File.Exists(WebConfigPath))
{
throw new FileNotFoundException("Unable to locate web.config. Ensure that this assembly located in the web application's bin folder.", WebConfigPath);
}
base.Context.LogMessage(string.Format("Using web.config located at '{0}'", WebConfigPath));
string backupConfigFile = String.Format("{0}.bak", WebConfigPath);
File.Copy(WebConfigPath, backupConfigFile, true);
stateSaver.Add(WebConfigPath, backupConfigFile);
XDocument configDoc = XDocument.Load(WebConfigPath);
base.Context.LogMessage(string.Format("Assembly contains {0} modules to register", this.AssemblyWebModules.Count));
if (this.AssemblyWebModules.Count > 0)
{
XElement modulesEntry = configDoc.XPathSelectElement(".//telerik/framework/modules");
List moduleList = modulesEntry.Descendants().ToList();
foreach (Type module in this.AssemblyWebModules)
{
Regex moduleType = new Regex(string.Format("^{0}, {{0,}}{1}$", module.FullName, AssemblyName), RegexOptions.IgnoreCase);
if (!moduleList.Exists(x => moduleType.IsMatch(x.Attribute("type").Value)))
{
base.Context.LogMessage(string.Format("Registering '{0}'", module.Name));
XElement addElement = new XElement("add");
addElement.SetAttributeValue("type", string.Format("{0}, {1}", module.FullName, AssemblyName));
modulesEntry.Add(addElement);
}
}
configDoc.Save(WebConfigPath);
}
base.Install(stateSaver);
}
...
That about wraps it up. Download the project source code and use it to build your own control libraries.