您的位置:首页 > 运维架构

NopCommerce Web层中的布局页

2013-12-13 10:28 288 查看
一 概况                                                                                                                                            

  nopcommerce其布局页文件分布在Nop.Web/Views/shared当中,主要涉及到五个布局文件:_Root.Head.cshtml、_Root.cshtml、_ColumnsOne.cshtml、_ColumnsTwo.cshtml、_ColumnsThree.cshtml。_ColumnsOne(Two/Three).cshtml三个布局页继承自_Root.cshtml、_Root.cshtml继承自_Root.Head.cshtml。

  所有继承_Root.Head.cshtml的页面将会使用相同的<head>标签内容,<body>体由它的子布局页来进一步细化。

  _Root.cshtml此页面替换掉_Root.Head.cshtml中@RenderBody(),大致结构如下图:

  


  nopcommerc有三个不同的具体布局页:_ColumnsOne(Two/Three).cshtml,三者形式如下:

  1._ColumnsOne.cshtml

  <body>结构与_Root.cshtml一致。

  2._ColumnsTwo.cshtml

      <body>有两种:

  


  


  3._ColumnsThree.cshml Layout

  而到了这里,其结构就有三种:

  


  


  


  

  也就是说_Root.Head主要管<head>中内容设置,以及全局CSS、JS文件引入;_Root.cshtml将网页主体内容<body>设计完成;_ColumnsOne(Two/Three).cshtml对_Root.cshtml变形处理。

二 、细读                                                              

  1._Root.Head.cshtml

  顶层_Root.Head.cshtml内容如下:


_Root.Head.cshtml
  在程序中,已经写了一些注释供大家参考。

  1.1. Html.AppendCssFileParts() 与AppendScriptParts()

   两个方法都是nop为HtmlHelper类定义拓展方法。见名知意,AppendCssFileParts附加CSS文件,AppendScriptParts附加脚本文件:

 



1  // private readonly Dictionary<ResourceLocation, List<string>> _cssParts;
2
3  public virtual void AppendCssFileParts(ResourceLocation location, string part)
4         {
5             if (!_cssParts.ContainsKey(location))
6                 _cssParts.Add(location, new List<string>());
7
8             if (string.IsNullOrEmpty(part))
9                 return;
10
11             _cssParts[location].Insert(0, part);
12         }


 

  _cssParts为字典类型,根据传入的location确定键值,而字符串参数 part是CSS文件的路径。此方法最终就是将传入的CSS文件路径附加到_cssParts Dictionary当中。

与此对应还有一个AddCssFileParts。



1  public virtual void AddCssFileParts(ResourceLocation location, string part)
2         {
3             if (!_cssParts.ContainsKey(location))
4                 _cssParts.Add(location, new List<string>());
5
6             if (string.IsNullOrEmpty(part))
7                 return;
8              //注意这里
9             _cssParts[location].Add(part);
10         }


 

  注意到两者的差别仅仅是给Dictionary<ResourceLocation, List<string>>添加值顺序的不同,Append在Dictionary索引为0处添加,Add在队列末尾添加。因此产生的效果是:AppendCssFileParts()调用越靠后,在界面上显示反而越靠前。大家在_Root.Head.cshtml代码中可以看到 jquery-1.7.1.min.js的引用是在最后,但是通常我们是应该将其引用位置尽量考前。

  AppendScriptParts()与AppendCssFileParts()非常相似,这里就不再贴代码说明。

  1.2 @Html.Partial("LanguageAttributes")

  就是字符串:



1 @if (this.ShouldUseRtlTheme())
2 {
3     <text>dir="rtl"</text>
4     //<text>dir="rtl" xml:lang="he" lang="he"</text>
5 }


 

  ShouldUseRtlTheme()方法从当前用户的配置信息中读取其阅读方式是左到右,还是右到左,其实现依托<html>标签 的dir属性。

  1.3 @(Html.NopMetaDescription()

  NopMetaDescription方法中调用下面关键方法:


GenerateMetaDescription
 

  DefaultMetaDescription是属性,从数据库中查取。

  1.4 @Html.Action("RssHeaderLink", "News")、@Html.Action("RssHeaderLink", "Blog")

  返回形如这样的字符串:<link href="xx" rel="alternate" ……>,用于RSS。

  1.5 @Html.Action("Favicon", "Common")

   返回的字符串形式这样: <link rel="shortcut icon" href="XX" />,href属性默认寻找Nop.Web根目录下名字为favicon.ico文件。

  2._Root.cshtml 

  _Root.cshtml内容如下:



1 @{
2     Layout = "~/Views/Shared/_Root.Head.cshtml";
3 }
4 @Html.Widget("body_start_html_tag_after")
5 @Html.Partial("_Notifications")
6 @Html.Action("AdminHeaderLinks", "Common")
7 <div class="master-wrapper-page">
8     @Html.Action("JavaScriptDisabledWarning", "Common")
9     <div class="master-wrapper-content">
10         <script type="text/javascript">
11             AjaxCart.init(false, '.header-links .cart-qty', '.header-links .wishlist-qty', '#flyout-cart');
12         </script>
13         @Html.Partial("Header")
14         <div class="header-menu">
15             @Html.Action("Menu", "Common")
16         </div>
17         @Html.Widget("content_before")
18         @*ajax loading window*@
19         <div class="ajax-loading-block-window" style="display: none">
20             <div class="loading-image">
21             </div>
22         </div>
23         <div class="master-wrapper-main">
24             @RenderBody()
25         </div>
26         @Html.Widget("content_after")
27        @* Eu Cookie Law 欧盟cookie新法:http://www.theeucookielaw.com/ 在用户机器上替换cookie前必须先通知客户*@
28         @Html.Action("EuCookieLaw", "Common")
29     </div>
30     @Html.Action("Footer", "Common")
31 </div>
32 @Html.Widget("body_end_html_tag_before")


 

  2.1  @Html.Action("JavaScriptDisabledWarning", "Common")

  返回一个PartialView:

  



1 @model dynamic
2 @*此标签详情:http://www.w3school.com.cn/tags/tag_noscript.asp*@
3 <noscript>
4     <div class="noscript">
5         <p>
6             <strong>JavaScript seem to be disabled in your browser.</strong></p>
7         <p>
8             You must have JavaScript enabled in your browser to utilize the functionality of
9             this website.</p>
10     </div>
11 </noscript>


 

  其目的就是检测是否禁用JS,如果禁用就提示。

  2.2 @Html.Partial("_Notifications")

  弹出提示: 



1 @{
2     //success messages
3     var successMessages = new List<string>();
4     if (TempData[string.Format("nop.notifications.{0}", NotifyType.Success)] != null)
5     {
6         successMessages.AddRange(TempData[string.Format("nop.notifications.{0}", NotifyType.Success)] as IList<string>);
7     }
8     if (ViewData[string.Format("nop.notifications.{0}", NotifyType.Success)] != null)
9     {
10         successMessages.AddRange(ViewData[string.Format("nop.notifications.{0}", NotifyType.Success)] as IList<string>);
11     }
12
13
14     //error messages
15     var errorMessages = new List<string>();
16     if (TempData[string.Format("nop.notifications.{0}", NotifyType.Error)] != null)
17     {
18         errorMessages.AddRange(TempData[string.Format("nop.notifications.{0}", NotifyType.Error)] as IList<string>);
19     }
20     if (ViewData[string.Format("nop.notifications.{0}", NotifyType.Error)] != null)
21     {
22         errorMessages.AddRange(ViewData[string.Format("nop.notifications.{0}", NotifyType.Error)] as IList<string>);
23     }
24 }
25 @*TODO use "displayPopupNotification" java-script function*@
26 @if (successMessages.Count > 0)
27 {
28     <script type="text/javascript">
29         $(document).ready(function () {
30             $("#dialog-notifications-success").dialog({ modal: true });
31         });
32     </script>
33 }
34 @if (errorMessages.Count > 0)
35 {
36     <script type="text/javascript">
37         $(document).ready(function () {
38             $("#dialog-notifications-error").dialog({ modal: true });
39         });
40     </script>
41 }
42 <div id="dialog-notifications-success" title="@T("Common.Notification")" style="display:none;">
43     @foreach (var message in successMessages)
44     {
45         <p>@message</p>
46     }
47 </div>
48 <div id="dialog-notifications-error" title="@T("Common.Error")" style="display:none;">
49     @foreach (var message in errorMessages)
50     {
51         <p>@message</p>
52     }
53 </div>
54 <div id="bar-notification" class="bar-notification">
55     <img src="@Url.Content("~/Content/Images/ico-close-notification-bar.png")" class="close" alt="Close" title="Close" />
56 </div>
57 @Html.Widget("notifications")


 

  通知内容通过TempData[nop.notifications.sucess]获取,注意到使用的是TempData,所以nop的通知是跨action的。

  2.3  @Html.Partial("Header")

  对应第一部分图中header,包含了头部链接、搜索框等内容。

  2.4  @Html.Action("Menu", "Common")

  菜单,对应第一部分图中的Menu,这个好理解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息