zoukankan      html  css  js  c++  java
  • Orchard: Razor介绍

        Orchard 使用模板来显示shapes,模板类似ASP.MVC的partial views概念。Shapes 是一个包含模型数据的动态对象,模板可以包括HTML标记代码片段、CSS样式、JavaScript等。视图引擎负责解析模板并且把shape显示在web页面。Orchard的默认视图引擎是Razor,本文介绍一下Razor。

        Razor语法是一个服务器端web页面标记语言,代码在服务器端运行生产HTML或者其他格式,然后发送到浏览器端。Razor支持C#和VB语言,文件扩展名为.cshtml.vbhtml。服务器能够识别这些后缀名,运行这些代码展现shape

        如果你想体验一下Razor 语法,我们推荐你使用WebMatrix。WebMatrix 是一个使用Razor语法生成ASP.NET Web页面的免费开发环境。它包括IIS Express (一个开发下的a development web server)、ASP.NET和SQL Server Compact (一个嵌入式)。

        WebMatrix 支持Razor 语法高亮,Microsoft也会在VS2010 Pack上加上这个功能。下载链接:WebMatrix download page

    代码块和内置表达式

    使用@添加代码,大括号 ({ }) 用来放置代码块。例如下面把"Hello World" 设为myMessage变量:

    @{ var myMessage = "Hello World"; }

    下面是一个稍微复杂一点的代码块:

    @{
    var greeting
    = "Welcome to our site!";
    var weekDay
    = DateTime.Now.DayOfWeek;
    var greetingMessage
    = greeting + " Today is: " + weekDay;
    }
    <p>The greeting is: @greetingMessage</p>

    注意: 不鼓励使用内置样式,尽量使用CSS。

    当代码块包含一个简单的表达式,例如for,你可以在关键字之前加上@表示这是代码,而不需要添加大括号。例如下面:

    for(var i = 10; i < 21; i++)
    {
    <p style="font-size: @(i + "pt")">My font size is now: @i</p>
    }

    几个提示

    1. 使用@添加代码
    2. 使用大括号{}写代码块
    3. 在代码块中,每个代码都是分号;结束
    4. 使用变量保存值
    5. 使用双引号加入字符串
    6. 代码区分大小写
    7. 代码经常会使用一些对象,例如Request

    更多内容可以参考: Introduction to ASP.NET Web Programming Using the Razor Syntax

    Razor解析器

    参考:http://tech.ddvip.com/2010-08/1282202894159226.html

    它实际上分为三个独立的组件:

    1. 理解基础HTML语法的标记解析器;
    2. 理解基础C#或者VB语法的代码解析器;
    3. 理解标记和代码如何混合的中央控制器

    Razor解析器有三个参与者:代码解析器,标记解析器,代码解析器。三个组件相互配合,协同工作完成对Razor文档的解析。Razor解析器有三种状态,分别是:解析标记文档、解析标记块,解析代码块,任何情况下解析器都处在以上三种状态中的一种状态上。前两种状态由标记解析器来处理,最后一种状态由代码解析器处理。

     文件内容如下:

    <ul>   
        @foreach(var p 
    in Model.Products) {   
        
    <li>@p.Name ($@p.Price)</li>   
        }   
    </ul> 
      我们从最上面开始解析过程。当第一次调用核心解析器的时候,它会调用标记解析器来解析标记文档。此时,解析器处在解析标记文档状态,在这种状态下,它会一 直向前扫描,直到找到下一个"@"字符,除此之外它不关心任何标记或者其它HTML相关的内容。当遇到一个"@"字符的时候,它会通过查看"@"字符前后 的内容,并据此判断是切换到代码状态呢还是这仅仅是一个email地址。这是默认的处理方式,但是有些特殊情况会强制解析器切换到代码解析状态。本例中, 当解析到"@"字符的时候,会发现该字符的前面是空格,据此判定这并不是一个合法的email地址,所以切换到代码解析状态。

      标记解析器接着调用代码解析器,让其来解析代码块。在Razor中块为单独的一段代码或者是有明确开始结束字符序列的标记,因而此处的"foreach" 声明是代码块,它以字符"f"开始,以字符"}"结束。代码解析器非常清楚C#语法,他会跟踪C#指令,当遇到"<li>"字符序列的时候, 它知道此处应该是C#指令的开始,但C#并不支持这样的指令,因而代码解析器会再次调用标记解析器来解析接下来的HTML代码块。这样在代码和标记解析器 之间创建一种从标记解析开始,进入代码解析,然后再进入标记解析….的递归过程。

      我们可以从中看出ASPX和Razor的区别:在ASPX文件中,代码和标记可以看作是两个并行的流,我们写一些标记然后跳过去写一些代码,再跳回来写标记,如此进行;而Razor文件更像是一棵树,我们写一些标记,然后在标记里面写一些代码,再在代码中嵌入标记….。

    到目前为止,解析器内的调用栈应该类似于以下结构(省略了一些帮助方法):

    HtmlMarkupParser.ParseDocument() 
    CSharpCodeParser.ParseBlock() 
    HtmlMarkupParser.ParseBlock() 
    我们可以从中看出ASPX和Razor的区别:在ASPX文件中,代码和标记可以看作是两个并行的流,我们写一些标记然后跳过去写一些代码,再跳回来写 标记,如此进行;而Razor文件更像是一棵树,我们写一些标记,然后在标记里面写一些代码,再在代码中嵌入标记….。

      所以我们仅需要调用标记解析器去解析"<li>"和"</li>"之间的标记块,在没有到达"</li>"之前解析器认为标记块还没结束,哪怕在标记之间有"}"字符都不会打断"foreach"声明。

      当解析"<li>"的时候,标记解析器发现了"@"字符,因而代码解析器会被调用,此时栈结构变成:

    HtmlMarkupParser.ParseDocument() 
    CSharpCodeParser.ParseBlock() 
    HtmlMarkupParser.ParseBlock() 
    CSharpCodeParser.ParseBlock() 
    对于这些代码块如何终止的具体信息以后再做介绍,但是最终我们会完成这些代码块的解析并且回到"<li>"块中, 在"</li>"之后又回到了"foreach"块中,最后"}"字符结束了"foreach"块,重新回到栈的顶端:标记文档。之后因为没 发现新的"@"字符,文档解析器将一直解析到文件的结尾。

    启动代码

    在View每次渲染前,都会执行_ViewStart.cshtml的代码:

    Layout

    参考:http://www.cnblogs.com/lengleng3898/archive/2010/07/21/Introduce_Razor.html

    先说RenderBody。当我们在母版页中的某个位置写了@RenderBody()后,接下来在使用母版页时,只需在页面的顶部写入:

    @{ LayoutPage = "MasterPageLocation"; }
    这样,接下来的内容会自动填充到母版页RenderBody()对应的位置:

    MasterPage:

     

    Page:

     

    使用RenderSection时需要指定Section片断的名字, 我们可以在母版页中的相关位置上写上@RenderSection("name"),然后在使用母版页的页面中声明类似的Section,即:@section header {/*HTML or other*/},具体如下:

    MasterPage:

     

    Page:

     

    内联模板

    我们可以使用内联模板来创建自己的模板帮助类。

    • Repeat实现代码
    View Code
    @using System.Text;

    @functions {

    public static IHtmlString Repeat(int times, Func<int, object> template) {

    StringBuilder builder
    = new StringBuilder();

    for(int i = 0; i < times; i++) {

    builder.Append(template(i));

    }

    return new HtmlString(builder.ToString());

    }

    }
    • 模板

    View Code
    <!DOCTYPE html>   
    <html>   
         
    <head>   
             
    <title>Repeat Helper Demo</title>   
         
    </head>   
         
    <body>   
             
    <p>Repeat Helper</p>   
             
    <ul>   
                 @Repeat(
    10, @<li>List Item #@item</li>);    
             
    </ul>   
         
    </body>   
    </html>  

    • 显示结果 

    配置

    参考:http://www.cnblogs.com/n-pei/archive/2011/01/23/1942711.html

    关于Razor的配置,你可以看到它会在Web.Config中有一个单独的section来存放Razor的configuration:

    如果你在其它例如web form中使用Razor,记得添加这部分配置。

    生成Shape模板

    Orchard:使用VS2010来生成一个地图Content Part

    <img alt="Location" border="1" src="http://maps.google.com/maps/api/staticmap?
    &zoom=14
    &size=256x256
    &maptype=satellite&markers=color:blue|@Model.Latitude,@Model.Longitude
    &sensor=false" />
    @model Maps.Models.MapPart

    <fieldset>
    <legend>Map Fields</legend>

    <div class="editor-label">
    @Html.LabelFor(model
    => model.Longitude)
    </div>
    <div class="editor-field">
    @Html.TextBoxFor(model
    => model.Latitude)
    @Html.ValidationMessageFor(model
    => model.Latitude)
    </div>

    <div class="editor-label">
    @Html.LabelFor(model
    => model.Longitude)
    </div>
    <div class="editor-field">
    @Html.TextBoxFor(model
    => model.Longitude)
    @Html.ValidationMessageFor(model
    => model.Longitude)
    </div>

    </fieldset>

    Layout 和Document模板

      layout 和 document 模板是定义一个Web页面结构的特定模板,这些特定模板通常使用在主题中进行页面布局。每个页面都有一个Layout shape 与它关联。这个Layout shape 定义了一些可以容纳web页面内容的zones。layout 和document 模板决定如何摆放zones。
      layout 模板(Layout.cshtml)摆放zones在页面上,文档模板(Document.cshtml)摆放在Web剩余地方。缺省情况下,Layout shape 为文档模板定义了三个zones(Head, Body, Tail)和一个layout模板(Content)的shape。在文档模板中,Head zone 用来定义Web页面的header,Body zone用来插入layout 模板,Tail zone用来放置页面脚注。

    下面为一个典型的文档模板:

    @using Orchard.Mvc.Html;
    @using Orchard.UI.Resources;
    @{
    RegisterLink(
    new LinkEntry {Type = "image/x-icon", Rel = "shortcut icon",
    Href
    = Url.Content("~/modules/orchard.themes/Content/orchard.ico")});
    Script.Include(
    "html5.js").AtLocation(ResourceLocation.Head);

    var title
    = (Request.Path != Request.ApplicationPath && !string.IsNullOrWhiteSpace((string)Model.Title)
    ? Model.Title + WorkContext.CurrentSite.PageTitleSeparator
    :
    "") +
    WorkContext.CurrentSite.SiteName;
    }
    <!DOCTYPE html>
    <html lang="en" class="static @Html.ClassForPage()">
    <head>
    <meta charset="utf-8" />
    <title>@title</title>
    @Display(Model.Head)
    < script>(function(d){d.className="dyn"+d.className.substring(6,d.className.length);})(document.documentElement);</script>
    </head>
    <body>
    @
    * Layout (template) is in the Body zone at the default position *@
    @Display(Model.Body)
    @Display(Model.Tail)
    </body>
    </html>


    下面示例显示了一个典型的布局模板。

    @* Html.RegisterStyle("site.css"); *@
    @{
    Model.Header.Add(Display.Header(),
    "5");
    Model.Header.Add(Display.User(),
    "10");
    Model.Header.Add(Model.Navigation,
    "15");
    }
    <div id="page">
    <header>
    @Display(Model.Header)
    </header>
    <div id="main">
    <div id="messages">
    @Display(Model.Messages)
    </div>
    <div id="content-wrapper">
    <div id="content">
    @Display(Model.Content)
    </div>
    </div>
    <div id="sidebar-wrapper">
    <div id="sidebar">
    @Display(Model.Sidebar)
    </div>
    </div>
    </div>
    <div id="footer-wrapper">
    <footer>
    @Display(Model.Footer)
    </footer>
    </div>
    </div>

    为了能够显示这些zones,必须引用zones到主题 Theme.txt 文件中,示例如下:
    Name: SimpleTheme
    Author:
    Description: Simple example theme.
    Version:
    1.0
    Tags: Simple
    Website: http:
    //www.orchardproject.net
    Zones: Header, User, Navigation, Messages, Content, Sidebar, Footer

    推荐:你可能需要的在线电子书   

    我的新浪围脖: http://t.sina.com.cn/openexpressapp   敏捷个人sina围裙:http://q.t.sina.com.cn/135484  

    欢迎转载,转载请注明:转载自周金根 [ http://zhoujg.cnblogs.com/ ]

  • 相关阅读:
    CodeForces 659F Polycarp and Hay
    CodeForces 713C Sonya and Problem Wihtout a Legend
    CodeForces 712D Memory and Scores
    CodeForces 689E Mike and Geometry Problem
    CodeForces 675D Tree Construction
    CodeForces 671A Recycling Bottles
    CodeForces 667C Reberland Linguistics
    CodeForces 672D Robin Hood
    CodeForces 675E Trains and Statistic
    CodeForces 676D Theseus and labyrinth
  • 原文地址:https://www.cnblogs.com/zhoujg/p/1973324.html
Copyright © 2011-2022 走看看