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(),大致结构如下图:
![](http://www.nopcommerce.com/images/documentation/design.4.1.jpg)
nopcommerc有三个不同的具体布局页:_ColumnsOne(Two/Three).cshtml,三者形式如下:
1._ColumnsOne.cshtml
<body>结构与_Root.cshtml一致。
2._ColumnsTwo.cshtml
<body>有两种:
![](http://www.nopcommerce.com/images/documentation/design.4.4.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.5.jpg)
3._ColumnsThree.cshml Layout
而到了这里,其结构就有三种:
![](http://www.nopcommerce.com/images/documentation/design.4.6.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.6.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.7.jpg)
也就是说_Root.Head主要管<head>中内容设置,以及全局CSS、JS文件引入;_Root.cshtml将网页主体内容<body>设计完成;_ColumnsOne(Two/Three).cshtml对_Root.cshtml变形处理。
二 、细读
1._Root.Head.cshtml
顶层_Root.Head.cshtml内容如下:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
_Root.Head.cshtml
在程序中,已经写了一些注释供大家参考。
1.1. Html.AppendCssFileParts() 与AppendScriptParts()
两个方法都是nop为HtmlHelper类定义拓展方法。见名知意,AppendCssFileParts附加CSS文件,AppendScriptParts附加脚本文件:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
_cssParts为字典类型,根据传入的location确定键值,而字符串参数 part是CSS文件的路径。此方法最终就是将传入的CSS文件路径附加到_cssParts Dictionary当中。
与此对应还有一个AddCssFileParts。
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
注意到两者的差别仅仅是给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")
就是字符串:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
ShouldUseRtlTheme()方法从当前用户的配置信息中读取其阅读方式是左到右,还是右到左,其实现依托<html>标签 的dir属性。
1.3 @(Html.NopMetaDescription()
NopMetaDescription方法中调用下面关键方法:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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内容如下:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
2.1 @Html.Action("JavaScriptDisabledWarning", "Common")
返回一个PartialView:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
其目的就是检测是否禁用JS,如果禁用就提示。
2.2 @Html.Partial("_Notifications")
弹出提示:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
通知内容通过TempData[nop.notifications.sucess]获取,注意到使用的是TempData,所以nop的通知是跨action的。
2.3 @Html.Partial("Header")
对应第一部分图中header,包含了头部链接、搜索框等内容。
2.4 @Html.Action("Menu", "Common")
菜单,对应第一部分图中的Menu,这个好理解。
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(),大致结构如下图:
![](http://www.nopcommerce.com/images/documentation/design.4.1.jpg)
nopcommerc有三个不同的具体布局页:_ColumnsOne(Two/Three).cshtml,三者形式如下:
1._ColumnsOne.cshtml
<body>结构与_Root.cshtml一致。
2._ColumnsTwo.cshtml
<body>有两种:
![](http://www.nopcommerce.com/images/documentation/design.4.4.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.5.jpg)
3._ColumnsThree.cshml Layout
而到了这里,其结构就有三种:
![](http://www.nopcommerce.com/images/documentation/design.4.6.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.6.jpg)
![](http://www.nopcommerce.com/images/documentation/design.4.7.jpg)
也就是说_Root.Head主要管<head>中内容设置,以及全局CSS、JS文件引入;_Root.cshtml将网页主体内容<body>设计完成;_ColumnsOne(Two/Three).cshtml对_Root.cshtml变形处理。
二 、细读
1._Root.Head.cshtml
顶层_Root.Head.cshtml内容如下:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
_Root.Head.cshtml
在程序中,已经写了一些注释供大家参考。
1.1. Html.AppendCssFileParts() 与AppendScriptParts()
两个方法都是nop为HtmlHelper类定义拓展方法。见名知意,AppendCssFileParts附加CSS文件,AppendScriptParts附加脚本文件:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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。
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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")
就是字符串:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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方法中调用下面关键方法:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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内容如下:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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")
弹出提示:
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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,这个好理解。
相关文章推荐
- Mvc3 Razor 的布局页嵌套
- SharePoint 2013 设置自定义布局页
- java-springmvc4+freemarker-实现layout布局页
- Sharepoint 2010 自定义布局页(转)
- SharePoint 2013 设置自定义布局页
- 下各节已定义,但尚未为布局页“~/Views/Shared/_Layout.cshtml”呈现:“Scripts
- ASP.NET MVC3布局页与分布页调用方式概述
- MOSS系列之五母版页和布局页Featur…
- 以下各节已定义,但尚未为布局页“~/Views/_LayoutHome.cshtml”呈现:“mainContent; jsSrc”。
- Moss 之五母版页 布局页 Features[转贴]
- 母版页和布局页
- MVC视图之【分部视图】【布局页】初了解
- Mvc Razor 的布局页嵌套
- Mvcpager以下各节已定义,但尚未为布局页“~/Views/Shared/_Layout.cshtml”呈现:“Scripts”。
- ASP.Net MVC 布局页、模板页使用方法详细介绍
- ASP.NET MVC 5 学习教程:修改视图和布局页
- Mvcpager以下各节已定义,但尚未为布局页“~/Views/Shared/_Layout.cshtml”呈现:“Scripts”。
- asp.net mvc razor布局页中a标签的href的跳转问题
- 全屏布局页转换jquery+css3
- 以下各节已定义,但尚未为布局页“~/Views/Shared/_Layout.cshtml”呈现:“Scripts”