代码改变世界

BlogEngine中的widget机制

2011-03-19 20:45  MichaelYin  阅读(429)  评论(0编辑  收藏  举报

BlogEngine中的widget机制支持在页面可添加一些小的widget,这个功能当时还是特别吸引我的,现在简单的说下实现的原理。

所有的widget都在一个WidgetZone的容器内,这个容器继承自PlaceHolder,而这个容器是在自定义theme中的模板页中用到的,当这个控件加载的时候,它从数据库中找到关于widget的配置信息。这个配置信息也是DataStore的方式提取和存储的。

<?xml version="1.0" encoding="utf-16"?>
<WidgetData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Settings>&lt;widgets&gt;&lt;widget
  id="b7d72394-7556-4a5b-87ed-c63cbdc915fb" title="Administration"
  showTitle="True"&gt;Administration&lt;/widget&gt;&lt;widget
  id="f8dffe75-8e8c-4732-a3ff-77df966f7220" title="Calendar"
  showTitle="True"&gt;Calendar&lt;/widget&gt;&lt;widget
  id="292c7de9-8d1c-444e-bb66-1c23c28c7c7b" title="Month List"
  showTitle="True"&gt;Month List&lt;/widget&gt;&lt;widget
  id="2b7bef82-7cf2-4e76-88e8-61ec0436a73a" title="Tag cloud"
  showTitle="True"&gt;Tag cloud&lt;/widget&gt;&lt;widget
  id="c7830f7c-2ef5-4c16-85d2-bcbca25d0c6f" title="Search"
  showTitle="True"&gt;Search&lt;/widget&gt;&lt;/widgets&gt;</Settings>
</WidgetData>

读取了配置信息后,根据所能够取到的wieget的信息动态的读取widget

所有的widget放在widgets文件夹下,widget.ascx负责显示widget,edit.ascx负责对widget进行配置,负责显示的widget继承自WidgetBase,它提供了widget所必须的一些信息,比如title,name和widgetId等等.

下面是动态读取widget的代码

	XmlNodeList zone = XML_DOCUMENT.SelectNodes("//widget");
			foreach (XmlNode widget in zone)
			{
				string fileName = Utils.RelativeWebRoot + "widgets/" + widget.InnerText + "/widget.ascx";
				try
				{
					WidgetBase control = (WidgetBase)Page.LoadControl(fileName);
					control.WidgetID = new Guid(widget.Attributes["id"].InnerText);
					control.ID = control.WidgetID.ToString().Replace("-", string.Empty);
					control.Title = widget.Attributes["title"].InnerText;
                                        control.Zone = _ZoneName;
					
					if (control.IsEditable)
						control.ShowTitle = bool.Parse(widget.Attributes["showTitle"].InnerText);
					else
						control.ShowTitle = control.DisplayHeader;

					control.LoadWidget();
					this.Controls.Add(control);
				}
				catch (Exception ex)
				{
					Literal lit = new Literal();
					lit.Text = "<p style=\"color:red\">Widget " + widget.InnerText + " not found.<p>";
					lit.Text += ex.Message;
                    lit.Text += "<a class=\"delete\" href=\"javascript:void(0)\" onclick=\"BlogEngine.widgetAdmin.removeWidget('" + widget.Attributes["id"].InnerText + "');return false\" title=\"" + Resources.labels.delete + " widget\">X</a>";

					this.Controls.Add(lit);
				}
			}

Widget的编辑功能则是通过js脚本访问Admin下WidgetEditor.aspx页面,然后通过该页面来进行修改配置。

Widget的添加则是通过脚本将添加的Widget的type通过ajax的形式返回到WidgetEditor页面,然后进行处理返回控件的html代码,完成widget的添加,实现过程不是很复杂,主要是理解它的整套机制。