BlogEngine.Net架构与源代码分析系列part10:开发扩展(中)——Widget小工具

 上篇文章我向大家介绍了BlogEngine.Net中开发扩展的重要一部分——Extension。在本文中我将向大家展示它的另外一种扩展特性,那就是Widget小工具,主要是Widget的开发标准和工作原理等。

     什么是Widget与为什么要使用Widget

     Widget实际上就是一种带有界面的小工具,主要应用在桌面领域,例如:Yahoo!Widget,还有Vista自带的边栏等。在BlogEngine.Net中它就是页面左侧或右侧的那种小的分区,例如Category list,Calendar,Tag cloud等,这种东西实际上在很多Blog系统中都存在,在BlogEngine.Net中我们就叫它Widget。

     Widget可以将Blog系统中很多的功能提供给用户一个统一的界面访问接口。如果有一些功能需要加到页面上,我们首先考虑的就是可否作成一个Widget来实现,因为这种Widget具有统一的开发标准,可以很方便的达到我们的目的。

     WidgetBase和WidgetEditBase

     在BlogEngine.Net中,作为一个有界面的Widget我们只需要继承WidgetBase类就行了。WidgetBase直接继承了UserControl,重写了Render用来生成统一的Widget界面,至于具体Widget中显示什么,则由自定义Widget类本身来完成,WidgetBase中有一个抽象方法LoadWidget用来完成Widget对象的初始化工作,IsEditable用于说明Widget是否可以编辑,如果可以编辑在Render时就会输出编辑按钮,那么这个Widget也必须提供一个编辑界面(继承了WidgetEditBase)。此外还需要注意WidgetBase中GetSettings会根据WidgetID从DataStore(前文讲述过)中获得相应的配置信息(也就是内容信息)并存储在Cache中。Cache在这部分的DataStore的处理中运用很多,希望大家留意。

     如果某个Widget可以编辑,那么它还需要一个实现WidgetEditBase的类,这个类主要是给用户提供一个对于Widget配置信息(具体内容)修改的界面,它提供了一个抽象的Save方法用于将修改的信息保存到DataStore中,还有一个Saved事件用于外部监听以便进行扩展。

     所有已经实现的Widget必须放在widgets目录下,并以Widget的名称给相应的文件夹命名,如果只是浏览我们加入一个widget.ascx就行了,如果需要修改还需要加入一个edit.ascx,以TextBox(可以设置一些关于作者的描述信息)的实现为例:

在widgets\TextBox中有widget.ascx和edit.ascx两个文件(加上Codebehind一共四个),在widget.ascx.cs的LoadWidget(重写父类的方法)获得DataStore信息并加入到Widget内容中。

ContractedBlock.gif ExpandedBlockStart.gif Code
 1ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
 2/// This method works as a substitute for Page_Load. You should use this method for
 3/// data binding etc. instead of Page_Load.
 4/// </summary>

 5public override void LoadWidget()
 6ExpandedBlockStart.gifContractedBlock.gif{
 7    StringDictionary settings = GetSettings();
 8    if (settings.ContainsKey("content"))
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    {
10        LiteralControl text = new LiteralControl(settings["content"]);
11        this.Controls.Add(text);
12    }

13}

14
15ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
16/// Gets the name. It must be exactly the same as the folder that contains the widget.
17/// </summary>
18/// <value></value>

19public override string Name
20ExpandedBlockStart.gifContractedBlock.gif{
21ExpandedSubBlockStart.gifContractedSubBlock.gif    get return "TextBox"; }
22}

23
24ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
25/// Gets wether or not the widget can be edited.
26/// <remarks>
27/// The only way a widget can be editable is by adding a edit.ascx file to the widget folder.
28/// </remarks>
29/// </summary>
30/// <value></value>

31public override bool IsEditable
32ExpandedBlockStart.gifContractedBlock.gif{
33ExpandedSubBlockStart.gifContractedSubBlock.gif    get return true; }
34}

35

同样对于edit.ascx.cs中重写了父类的Save方法将内容又保存回DataStore中。

     Widget的增,删,改,排序等是如何处理的

     在admin目录下存在WidgetEditor.aspx用来对Widget的操作进行处理。它实际上是一个通用的模板,也是一个操作的路由,根据请求的参数进行相应的操作。

增加Widget:我们将自己的按照上文的标准开发的Widget放在widgets的目录以后就已经完成了Widget的安装。通过添加列表(这是WidgetZone生成的一个列表,实际上就是搜索widgets目录下的文件而获得的所有已安装的Widget列表)就可以转向WidgetEditor.aspx,之后将这个Widget添加进来,而WidgetEditor.aspx是通过AddWidget方法完成的。

删除Widget:这里的删除不是卸载,而只是从WidgetZone中移出Widget,同时删除DataStore信息。当我们点击Widget中的删除时会使用WidgetEditor.aspx来处理,而WidgetEditor.aspx又是通过RemoveWidget完成的。

修改Widget:当我们点击Widget的修改时会转向WidgetEditor.aspx,而WidgetEditor.aspx使用InitEditor读取了DataStore中的信息并加载了相应Widget中的edit.ascx,实际上对于Widget的修改一部分(总体的描述信息)是通过WidgetEditor.aspx直接修改完成的,而另一部分(Widget的配置信息)则是由WidgetEditor.aspx委托edit.ascx来完成的,这样做的好处显而易见,可以实现修改界面的个性化处理,这也是继承带来的好处。

ContractedBlock.gif ExpandedBlockStart.gif Code
 1private void btnSave_Click(object sender, EventArgs e)
 2ExpandedBlockStart.gifContractedBlock.gif{
 3    WidgetEditBase widget = (WidgetEditBase)FindControl("widget");
 4    if (widget != null)
 5        widget.Save();
 6
 7    XmlDocument doc = GetXmlDocument();
 8    XmlNode node = doc.SelectSingleNode("//widget[@id=\"" + Request.QueryString["id"] + "\"]");
 9    bool isChanged = false;
10
11    if (node.Attributes["title"].InnerText != txtTitle.Text.Trim())
12ExpandedSubBlockStart.gifContractedSubBlock.gif    {
13        node.Attributes["title"].InnerText = txtTitle.Text.Trim();
14        isChanged = true;
15    }

16
17    if (node.Attributes["showTitle"].InnerText != cbShowTitle.Checked.ToString())
18ExpandedSubBlockStart.gifContractedSubBlock.gif    {
19        node.Attributes["showTitle"].InnerText = cbShowTitle.Checked.ToString();
20        isChanged = true;
21    }

22
23    if (isChanged)
24        SaveXmlDocument(doc);
25
26    WidgetEditBase.OnSaved();
27    Cache.Remove("widget_" + Request.QueryString["id"]);
28
29    string script = "top.location.reload(false);";
30    Page.ClientScript.RegisterStartupScript(this.GetType(), "closeWindow", script, true);
31}

 

排序Widget:当我们在拖动某个Widget时它会进行新的排序,这个排序是持久性的。最初见到BlogEngine.Net时这个功能就很吸引我。那么它是如何实现的呢?

ContractedBlock.gif ExpandedBlockStart.gif Code
 1ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
 2/// Moves the widgets as specified while dragging and dropping.
 3/// </summary>
 4/// <param name="move">The move string.</param>

 5private void MoveWidgets(string move)
 6ExpandedBlockStart.gifContractedBlock.gif{
 7    XmlDocument doc = GetXmlDocument();
 8    string[] ids = move.Split(';');
 9
10    for (int i = 0; i < ids.Length; i++)
11ExpandedSubBlockStart.gifContractedSubBlock.gif    {
12        string id = ids[i];
13        XmlNode node = doc.SelectSingleNode("//widget[@id=\"" + id + "\"]");
14        XmlNode parent = node.ParentNode;
15
16        parent.RemoveChild(node);
17        parent.AppendChild(node);
18    }

19
20    SaveXmlDocument(doc);
21    WidgetEditBase.OnSaved();
22}

从这里可以看出move是一个使用";"分隔的WidgetID序列来表示顺序,这个序列是JavaScript生成的。服务器接收到这个序列以后使用MoveWidgets并对于DataStore中的Widget列表进行重新的排序。对于JavaScript的实现已经超出本文的范围,这里不做讨论。感兴趣的朋友可以研究一下admin/widget.js,Widget这部分的所有JavaScript都在此,写的也是不错的。

     由此可见WidgetEditor.aspx是Widget管理的一个核心。

     WidgetZone是一个Widget的容器

     WidgetZone上文已经涉及到,它就是一个Widget的容器。WidgetZone继承自PlaceHolder,在OnLoad时会根据DataStore将已经添加的Widget加载到PlaceHolder中,在Render的时候还会去查找安装在widgets目录下的Widget列表。这个WidgetZone在BlogEngine.Net中并不是一个必须的类,你可以将Widget直接放在主界面的某个位置上就可以使用。但是,如果不使用它来管理而直接显示Widget会失去Widget的管理特性,在下一篇制作Theme的文章中我会对其进行详细的说明。

     总结

     Widget的实现无非是BlogEngine.Net中的经典。BlogEngine.Net对这些界面上的小工具进行了统一的抽象,尤其是继承的使用带来了很大的扩展空间。WidgetEditor.aspx的统一管理也是非常经典的,尤其是排序和修改部分更值得大家仔细研究。此外,Widget的XCopy安装也是很不错的,实际上BlogEngine.Net的一个重要特性就是在Web上实现了很多这种热插拔(Plug'n play),包括Extension,Widget等。

     继承的正确使用给我们带来的好处实在太多

     上一篇:BlogEngine.Net架构与源代码分析系列part9:开发扩展(上)——Extension与管理上的实现

     下一篇:BlogEngine.Net架构与源代码分析系列part11:开发扩展(下)——自定义Theme

 

     返回到目录

【作者】: GUO Xingwang
【来源】: http://thriving-country.cnblogs.com/ 
     本文版权归作者和博客园共同所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

 

转载于:https://www.cnblogs.com/l1b2q31/articles/1720999.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
博易产品说明文档 博易是一款功能强大、设计新颖、方便易用的博客程序。原名为 BlogEngine.NET,是由 BlogYi.net 从英文官方 www.dotnetblogengine.net 获得项目并对其本地化修改而完成的。 【英文官方】 由 www.dotnetblogengine.net 开发的一个完全基于.net Framework 2.0 技术的,功能强大、高性能、可伸缩的多用户博客程序。 【文官方】 http://www.BlogYi.net 自英文官方发布 BlogEngine.NET 1.3 以来不断追踪官方新版的改进与修改,并通过本地化工作来使之更符合国网民使用习惯,提供更多的文支持。 【版权声明】 本博客遵守国际开源协议,您可以自由使用本博客,但必须保留 dotnetblogengine.net 标识和 BlogYi.net 标识,否则 dotnetblogengine.net 标识和 BlogYi.net 保留追究其法律权力。 如果您想使用本论坛,并不愿意看到我们的版权标识,请联系我们购买授权版本,并享受更多支持与服务。 【开源精神】 博易遵循“完全开放源码”的精神,向任何 asp.net 程序员和其他所有的程序员提供最全面的博客系统。您可以通过 http://www.BlogYi.net 获取完整的源代码。 【应用实例】 http://www.blogyi.net 【博易的功能特性】 新一代的博客 博易集众多博客的新功能于一体,是一款名副其实的新一代博客的典型范例!无刷新的日历、评论、回访功能无不体现了AJAX在博客的娴熟运用! 成熟的系统架构 专业的团队用专业的框架开发出的产品。基于微软的.Net 2.0,作者对OOP具有着深入的理解,并对.Net特性有着透彻的研究。博易的系统架构和编码风格不能不说是OOP的设计典范! 方便的内容导入导出 博易后台提供了内容的导入和导出功能,生成一个XML文件。便利地解决了博客搬家的麻烦! 先进的评论体系 评论是博客极为重要的组成部分,博易用AJAX技术提供了一组先进的评论体系!该评论体系支持国别选择、发表评论支持实时预览、个性头像、聚合式评论……所有的这些都可以由管理员在后台做便捷的编辑调整! 无须数据库且支持多种数据库 默认采用基于 XML 的数据存储方式,此种方式提供几乎与静态网页相当的访问效率(避免了数据库并发查询的瓶颈)。同时也可以扩展支持SQL Server、Access等多种数据库存储方式。 独立页面发布功能 除了标准的博客日志,博易还支持在线发布静态页面!这些页面是独立的,对发布各种信息尤为有用! 多用户支持 博易对多用户共同创作、维护博客提供了全面的支持,博易允许多个用户维护同一个博客。访问者可以订阅任意一个博客用户的RSS feed、仅关注他们感兴趣的某个博客用户的日志! 多语言支持 博易支持多语言,您可以在全球任意地区的服务器上运行博易,而不用担心服务器时间和本地时间存在时差的问题。 Trackback 和 Pingback 特性 博易可以对所有链出的链接进行Track回溯和Ping回溯,您的博客链接将自动出现在您引用的博客的评论列表之!提高您博客的链入指数、在无形之推广了您的博客!每当创建一个新的日志,博易就会自动完成PingTechnorati、Feedburner、Ping-o-Matic等操作! 灵活易用的插件机制 博易采用了灵活强大的C#开发架构十分先进成熟,她的插件机制也是如此。系统开放了事件定义,利用订阅事件能够使所开发的插件强大得如同系统程序本身一样! 酷炫主题支持 博易为快速开发主题(模板、风格)提供了支持,用户只需要稍稍懂得HTML和CSS便可进行主题的制作!博易的模板机制是基于.Net2.0的MasterPage的,这样,开发一套新的主题模板只需要修改3~5个文件即可完成!与此同时,博易有专业的设计师为您免费提供更多的个性主题!此外,博易还支持识别移动设备(如手机等)。能分别制定在用这些设备访问和用PC机访问时所用的主题模板! 符合 XHTML 博易所用的控件全部符合XHTML 1.0标准。所有的日志都会在您发表时自动转换成符合标准的格式! 遵循GPL协议 软件完全开源,任何人都可以免费获得博易的源代码,在保证不去掉BlogYi.NETBlogEngine.NET标识的前提下修改和发布。 【更多技术参数】 当前版本 BlogYi v1.6.5 同步版本 BlogEngine v1.4.5 费用 免费 开源 服务器配置要求 ASP.NET 2.0 or Mono Mono 框架支持 Yes 多语言支持 Yes, 支持 31 种语言 复合语言支持 No 多用户支持 Yes 静态页面 Yes. 你可以创建独立于博客的静态页面 导航功能 主题基于站点地图制作 更换首页 Yes. 所有的页面均可作为您博客的首页 每个用户拥有独立的 feed Yes 全新的评论通知机制 Yes. 通过 RSS, ATOM 或者 e-mail 数据支持 支持基于 XML 或者 SQL Server 2000/2005/2008. 日志评级 Yes. 访问者可以对每一篇日志进行评级 个性头像支持 Yes Tag 标签集 Yes 日志日历 Yes. AJAX 无刷新支持 日志检索 Yes. 这可能是迄今最强大的博客搜索功能了 评论检索 Yes. 检索范围可以包含评论内容 用户自定义控件挂接 Yes. 任何用户控件 (.ascx) 都可以挂接到日志 联系作者 Yes 评论开关 Yes. 管理员可以设定开启或者关闭评论功能 禁止评论延时 Yes. 您甚至可以设定在日志发表后的一段时间之后自动禁止评论 E-mail 发送附件 Yes. 联系作者支持发送带有附件的电子邮件 日志排序 按照发表时间降序排列 分类支持 多分类 子分类支持 No Tag 标签支持 Yes 在线编辑器 TinyMCE 以及其他编辑器,可扩展 稿件模式 Yes 自动保存 Yes 格式支持 xFolk, Rel-Tag, VoteLinks, XFN, XOXO, rel-home, rel-directory, rel-enclosure 开放式检索 Yes Google 网站地图 Yes HTTP 压缩 Yes (可选) 发表评论实时预览 Yes 日志 API 支持 MetaWeblog (支持 newMediaObject 方法) 日志开关 No 聚合 feeds 支持 RSS 2.0 and ATOM 1.0 Feedburner 支持 Yes OPML 支持 Yes Windows Live Writer Yes, 扩展到支持发表日志和发布独立页面 Ping services Yes. 各种 Ping 的添加更容易 评论支持 Yes Comment 广告 对 CAPTCHA and AJAX 不可见 Comment 聚合 Yes, 同 RSS 和 ATOM AJAX 评论 Yes 主题风格 Yes (母板页和 ascx 文件) User 安全 用户权限级别自定义 Trackback Yes, 收发 Pingback Yes, 收发 RSS 输出 动态的博客聚合 论坛支持 No 展厅支持 No 插件/扩展扩展模式 移动设备支持 Yes, 可独立设定移动设备的主题风格 引用日志记录 Yes 导入/导出 BlogML and RSS 静态 URL 重写 Yes 交叉发表 No 拼写检查 Yes (ieSpell) XFN 编辑支持 Yes 密码保护模式发表 No 通过 Email 维护博客 Not yet API MetaWeblog, javascript API 以及全部的 SOAP web service API Tracking scripts 管理员可以更改 tracking script. 可运行于所有的主题风格 HTML 首部标签 管理员可以在后台添加自定义的首部 程序文件扩展名 默认 .aspx, 可在 web.config 更改该配置 开发模式 KISS 且无第三方程序集. 精巧、简练的架构 代码高亮显示 Yes. 支持 C#, Java, VB.NET, HTML, Javascript, T-SQL
【博易的功能特性】 新一代的博客 博易集众多博客的新功能于一体,是一款名副其实的新一代博客的典型范例!无刷新的日历、评论、回访功能无不体现了AJAX在博客的娴熟运用! 成熟的系统架构 专业的团队用专业的框架开发出的产品。基于微软的.Net 2.0,作者对OOP具有着深入的理解,并对.Net特性有着透彻的研究。博易的系统架构和编码风格不能不说是OOP的设计典范! 方便的内容导入导出 博易后台提供了内容的导入和导出功能,生成一个XML文件。便利地解决了博客搬家的麻烦! 先进的评论体系 评论是博客极为重要的组成部分,博易用AJAX技术提供了一组先进的评论体系!该评论体系支持国别选择、发表评论支持实时预览、个性头像、聚合式评论……所有的这些都可以由管理员在后台做便捷的编辑调整! 无须数据库且支持多种数据库 默认采用基于 XML 的数据存储方式,此种方式提供几乎与静态网页相当的访问效率(避免了数据库并发查询的瓶颈)。同时也可以扩展支持SQL Server、Access等多种数据库存储方式。 独立页面发布功能 除了标准的博客日志,博易还支持在线发布静态页面!这些页面是独立的,对发布各种信息尤为有用! 多用户支持 博易对多用户共同创作、维护博客提供了全面的支持,博易允许多个用户维护同一个博客。访问者可以订阅任意一个博客用户的RSS feed、仅关注他们感兴趣的某个博客用户的日志! 多语言支持 博易支持多语言,您可以在全球任意地区的服务器上运行博易,而不用担心服务器时间和本地时间存在时差的问题。 Trackback 和 Pingback 特性 博易可以对所有链出的链接进行Track回溯和Ping回溯,您的博客链接将自动出现在您引用的博客的评论列表之!提高您博客的链入指数、在无形之推广了您的博客!每当创建一个新的日志,博易就会自动完成PingTechnorati、Feedburner、Ping-o-Matic等操作! 灵活易用的插件机制 博易采用了灵活强大的C#开发架构十分先进成熟,她的插件机制也是如此。系统开放了事件定义,利用订阅事件能够使所开发的插件强大得如同系统程序本身一样! 酷炫主题支持 博易为快速开发主题(模板、风格)提供了支持,用户只需要稍稍懂得HTML和CSS便可进行主题的制作!博易的模板机制是基于.Net2.0的MasterPage的,这样,开发一套新的主题模板只需要修改3~5个文件即可完成!与此同时,博易有专业的设计师为您免费提供更多的个性主题!此外,博易还支持识别移动设备(如手机等)。能分别制定在用这些设备访问和用PC机访问时所用的主题模板! 符合 XHTML 博易所用的控件全部符合XHTML 1.0标准。所有的日志都会在您发表时自动转换成符合标准的格式! 遵循GPL协议 软件完全开源,任何人都可以免费获得博易的源代码,在保证不去掉BlogYi.NETBlogEngine.NET标识的前提下修改和发布。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值