[Reprint] dottext source code reading (6)-template skin

Source: Internet
Author: User
From: orders Program File. The author of dottext uses urlrewrite to implement the template and skin replacement. After analyzing its principles, we can identify how to add new templates to the blog to personalize the site blog. Speaking of personalization, it is the root of web! Take my blog as an example to explain: Suppose we access the http://blog.csdn.net/shanhe, HTTP requests will pass through IIS to Asp.net process (through pipeline interaction data), and blog.csdn.net is an application, Web. config takes effect. Its request is composed < Add Verb = "*" Path = "*" Type = "Dottext. Common. urlmanager. urlrewritehandlerfactory, dottext. Common" /> However Urlrewritehandlerfactory Take over. In the factory processing routine, the URL of the current request is retrieved: String Appstr = dottext. Framework. util. globals. removeappfrompath (context. Request. Path, context. Request. applicationpath ); The Context. Request. Path is/shanhe, and request. applicationpath is "/". After replacement, appstr is "/shanhe", which is the same < Httphandler Pattern = "^ (? : \/(\ W | \ s | \.(?! Aspx) + (\/Default \. aspx )? | (\/?))?) $"   Controls = "Homepage. ascx"/> The specified pattern matches. In this case, the handlertype is page and is executed Case Handlertype. Page:// The default value is page. ReturnProccesshandlertypepage (items [I], context, requesttype, URL ); Let's go Proccesshandlertypepage PrivateIhttphandler proccesshandlertypepage (httphandler item, httpcontext context,StringRequesttype,StringURL) {StringPagepath = item. fullpagelocation; If(Pagepath =Null) { Pagepath = handlerconfiguration. instance (). fullpagelocation; } Handlerconfiguration. setcontrols (context, item. blogcontrols ); Ihttphandler myhandler = pageparser. getcompiledpageinstance (URL, pagepath, context ); ReturnMyhandler; } Item is the matched handler's Fullpagelocation: You can view the attributes by reading the handler object class: Private String_ Fullpagelocation; Public StringFullpagelocation { Get {If(This. _ Fullpagelocation =Null& Pagelocation! =Null) { This. _ Fullpagelocation = httpcontext. Current. server. mappath ("~ /"+ Pagelocation ); } Return This. _ Fullpagelocation; } } Fullpagelocation is not specified here. It is null and then executed Pagepath = handlerconfiguration. instance (). fullpagelocation; Here there is deserialization, which will enter the static function instance of handlerconfiguration: Public StaticHandlerconfiguration instance () { Return(Handlerconfiguration) configurationsettings. getconfig ("handlerconfiguration ")); } In this case, pagepath obtainsDefaultpagelocation= "Default. aspx ",Because This . _ Fullpagelocation = httpcontext. Current. server. mappath ("~ /"+ Pagelocation ); The default file will be located in the actual application path of the blog site and deafault. aspx in the directory, which may be like: "X: \ cnblogsdottext \ dottextweb \ default. aspx", Asp.net will execute this file through pageparser. getcompiledpageinstance (URL, pagepath, context. From this point on, it enters the skin execution stage. Default. aspx is simple and contains only several nested container controls. <Body> <Form ID = "form1" method = "Post" runat = "server"> <DT: masterpage id = "mpcontainer" runat = "server"> <DT: contentregion id = "mpmain" runat = "server"> <Asp: placeholder id = "centerbodycontrol" runat = "server"> </ASP: placeholder> </Dt: contentregion> </Dt: masterpage> </form> </Body> MasterpageSource code(No UI part) under dottextweb \ UI \ webcontrols \, you need to read the properties of the control. Public StringTemplatefile { Get { If(This. Templatefile =Null) { Blogconfig Config = config. currentblog (context );// Read the blog configuration, according If(Config! =Null) { This. Templatefile = config. Skin. teamplatefilepath; } } Return This. Templatefile; } Set{This. Templatefile =Value;} } Use blogconfig Config = config. currentblog (context );Read the blog configuration, which involves the DTO part. refer to the previous section. All the configuration information of the blog to be accessed is retrieved, and the skin name is obtained.   At this point, we will start to analyze the page lifecycle: After the Page Object is instantiated, it enters the initialization stage (initialize). It calls the page_onint event and correspondingly enters the oninit method of each surface control, and Recursion to the oninit of the child control. The main control of default. aspx is masterpage. The oninit of this control is as follows: Protected Override VoidOninit (eventargs e ){ This. Buildmasterpage (); This. Buildcontents (); Base. Oninit (E ); } Execute the process of loading the sub-control (buildmasterpage) and generate the sub-control instance (buildcontents) respectively: Private VoidBuildmasterpage (){ If(This. Templatefile =Null|This. Templatefile =String. Empty)// Obtain the Template Name. If the Template Name does not exist or is not specified, an exception is thrown. { Throw NewApplicationexception ("templatefile property for masterpage must be defined "); } This. Template =This. Page. loadcontrol (This. Templatefile ); This. Template. ID =This. ID + "_ template "; IntCount =This. Template. Controls. count; For(IntIndex = 0; index <count; index ++ ){// Pay attention to the collection traversal and deletion generation? Control control =This. Template. controls [0]; This. Template. Controls. Remove (control ); If(Control. Visible ){ This. Controls. Add (control ); } } This. Controls. addat (0,This. Template ); } 'AnalysisClassSkinconfig is not hard to getThis. Page. loadcontrol (This. Templatefile) is the pagetemplate. ascx that points to a subdirectory in the skin directory. This is actually a mode-like "stage ". Pagetemplate actually contains most of the controls in the controls directory of its subdirectory.This. Template. ID =This. ID + "_ template "; After naming, dottext uses a loop to load all the child controls contained in pagetemplate one by one (of course, it must be visible ). Buildmasterpage is actually imitating the internal details of the pages where Asp.net is loaded with sub-controls. Subsequent buildcontents Set From buildmasterpage to all Sub-controls are loaded Used Contentregion control (this is a container control ): Private VoidBuildcontents (){ Foreach(Contentregion contentIn This. Contents ){ Control Region =This. Findcontrol (content. ID ); If(Region =Null|! (RegionIsContentregion )){ Throw NewException ("contentregion with id'" + content. ID + "'must be defined "); } Region. Controls. Clear (); IntCount = content. Controls. count; For(IntIndex = 0; index <count; index ++ ){ Control control = content. controls [0]; Content. Controls. Remove (control ); Region. Controls. Add (control ); } } } The conditions are as follows: Contentregion instances are within the actual scope (the "stage" just mentioned "). Why? This . Page. loadcontrol (This. Templatefile); this sentence is to load a user control, and the user control itself is actually a page, so in order to complete the name integrity of the page finally browsed to the user, you need to rename all controls according to the container rules to avoid conflicts. In fact, the execution process of the main template is in this page. loadcontrol (This. templatefile), it will load the template user control under the specific template when you apply for a blog, look at config. skin. teamplatefilepath; the original teamplatefilepath attribute defines the user control to be loaded "pagetemplate. ascx ", but the selected template is different, the specific template path is different, pagetemplate. ascx is different, so it achieves a "skin change ". Pagetemplate. ascx consists of several user controls under the sub-Directory Controls in the directory where pagetemplate. ascx is located to implement the user UI. These UI controls. We know that a user control is similar to a page which consists of two files. One is responsible for the UI and consists of various HTML files. The other is a CS file, which executes the logic of the user control. In general, they are in the same directory. However, in the template implementation, dottext places the UI file (. ascx) under different templates, whileCodeAll files point to the UI \ controls \ *. CS under the dottext web directory. In this way, the same logic (. CS file) corresponds to N sets of UI ascx files. As long as we set different skin template names, we can switch the template freely to achieve the goal of "skin replacement. Now that we know this principle, we can achieve two development directions in Template Development: 1, Add new functions on the blog for the current template, such as counters (not available in the current version ). A) First, add the implemented logic function CS file to the UI \ controls under the web directory. B) Add an ascx file that implements UI elements to each skin directory C) Add a counter to pagetemplate. ascx or a specific control. 2, Add a new template. This requires us: A) Copy one of the skin and change it to the name we need (the dottext Template Name doesn't know why, I always think it's cool) B) Modify the user controls, but do not modify them. Inherits = "dottext. Web. UI. Controls. xxxxxx" Statement (xxxxxx is the name of a control ). This will map the UI to the logic. C) Add the skin name to the management background configuration options of the blog for your choice. The above analysis of the implementation principle of the template can help us modify the template, expand new interface elements based on the current dottext design, and fully implement personalization. Personalization is very important for a blog that is one of the main services of Web2.0.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.