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

时间:2021-08-19 14:14:08

     个性化的主题是一个完善的Blog系统中所必备的,同时也是一个亮点。在这篇文章里我将给大家展示一下BlogEngine.Net的第三个开发特性,那就是自定义的Theme。本文的重点放在BlogEngine.Net的开发规范和实现原理上。如果您对BlogEngine.Net的架构很了解的话,那么开发一个自己的Theme是一件很简单的事情,如果您不是很了解,那么你也可以按照本文讲述的规范开发出一个自定义的Theme来。

     BlogEngine.Net中的Theme

     在BlogEngine.Net的源代码中默认存储了三个Theme(Standard默认,Mobile移动版,Indigo),更多的Theme您可以到它的官方站点下载。同样这些Theme支持热插拔,我们只要把下载的Theme放在themes目录下就可以实现它的安装。相信这种Theme会给用户带来更多的使用上的感受。由于BlogEngine.Net开放源代码,所以对于Theme的开发也完全由用户自己控制。如果大家想知道这个Theme到底有多厉害,看看BlogEngine.Net的官方站点就知道了,估计那就是使用BlogEngine.Net,然后换了一个Theme做的。

     规范与原理

     对于用户来说到底使用哪个Theme是存储在BlogSetting中的,在设置页面中我们可以看到一个下拉列表来选择主题,这个下拉列表的数据是通过读取themes目录下的子文件夹名称获得的,这就要求我们在开发Theme时要以Theme的名称作为这个文件夹的名称。需要注意的一个问题就是在BlogEngine.Net的Web站点的根目录下的所有.aspx的Codebehind都是继承自BlogBasePage,这个类又继承自Page类,也就是说BlogBasePage将一些页面*有的操作进行了统一的处理,对于这个类我会在接下来的一篇文章中进行分析。

     在BlogBasePage中有这么一段代码:

private string _Theme = BlogSettings.Instance.Theme;
/// <summary>
/// Assignes the selected theme to the pages.
/// </summary>
protected override void OnPreInit(EventArgs e)
{            
    
if (Request.QueryString["theme"!= null)
        _Theme 
= Request.QueryString["theme"];

    MasterPageFile 
= Utils.RelativeWebRoot + "themes/" + _Theme + "/site.master";

    
base.OnPreInit(e);

    
//....

}

 

这段代码就是在页面预初始化时(注意一定要放在这个处理器中)将Page的MasterPageFiles设置为BlogSetting中所设置主题名称的目录中的site.master,这就要求我们在开发自己的Theme时需要创建页面的主文件site.master。

     此外就是在研究了PostViewBase和CommentViewBase(这两个类也会在下一篇文章中做详细的说明)的实现以后对于Post和Comment的显示也是到BlogSetting中所设置主题名称的目录中去查找PostView.ascx(直接继承自PostViewBase)和CommentView.ascx(直接继承自CommentViewBase),这就需要我们在开发自己的Theme中需要创建文章的显示界面PostView.ascx和评论的显示界面CommentView.ascx。

     以上几个文件是开发BlogEngine.Net的Theme所必须的,实际上也就形成了一个完整的前台页面了。当然你也可以定义自己的布局,css,图片等。这些文件到底应该如何定义,以Standard为例,先让我们看一下它的实现。

     site.master中依次是资源的引入,header部分,顶部的一些链接,主题部分,版权部分,WidgetZone。请注意:

< blog:SearchOnSearch  runat ="server"  MaxResults ="3"  Headline ="You searched for"  Text ="Here are some results for the search term on this website"   />
< asp:ContentPlaceHolder  ID ="cphBody"  runat ="server"   />

SearchOnSearch是一个控件,主要完成根据搜索引擎的参数在本站中进行再次搜索。<asp:ContentPlaceHolder ID="cphBody" runat="server" />在site.master中必须存在的,因为Page中已经存在对它的引用。

     PostView.ascx中依次是标题,作者,创建时间,主体,标签,分类,一些链接和管理菜单。其中<asp:PlaceHolder ID="BodyContent" runat="server" />同样也是必须存在的,因为在PostViewBase中就是将Post的内容输出到BodyContent控件中(请参照PostViewBase的Page_Load方法)。

     CommentView.ascx中依次是评论的作者,时间,Gravatar图片显示,内容,管理连接等。这里似乎没有什么是必须的。

     只要遵守这些规范我们就可以开发Theme了,除此之外对于Widget的引入我们也不必使用WidgetZone,只要将这些Widget的控件类直接放在site.master中就行了,其实这已经不能算作一个Widget,只能说是一种类似Widget的控件。对于BlogBasePage,PostViewBase,CommentViewBase以及各个页面之间的继承关系,我会在下一篇文章中做详细的介绍,希望大家继续关注。

     总结

     这篇文章涉及到的内容比较少,并且和下一篇文章有很多联系。实际上,Theme的实现应该是基于BlogBasePage,PostViewBase,CommentViewBase等的,它主要应用了Asp.Net的site.master布局页面,通过动态设置实现。这样操作损失了一个IDE的重要特性——智能感知,开发起来可能会有些不便,但是这样的架构还是不错的。

     看来Asp.Net的site.master的确很有用

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

     下一篇:BlogEngine.Net架构与源代码分析系列part12:页面共同的基类——BlogBasePage

 

     返回到目录