好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Orchard: Shape展现介绍

Orchard: Shape展现介绍

一个 shape 是一个动态数据模型,shape的目的是用来代替ASP.NET MVC中静态的视图模型,Orchard使用的模型可以在运行时更新。本文将介绍shape的概念以及如何使用它。如果你还不知道module的基本概念和开发可以看我之前写的文章,这里就不再重复,如果不知道.Net的动态对象的可以看看 Creating and Using Dynamic Objects 。

介绍Shapes

    Shapes是一个动态数据模型,它使用shape templates来展现UI,Shape templates是一个标记片段。Shapes的示例包括menus, menu items, content items, documents, and messages。Shape是一个派生自 Orchard.DisplayManagement.Shapes.Shape  类的数据模型对象。 Shape  类不会实例化,而是在运行时通过shape工厂来生成。缺省的shape工厂是 Orchard.DisplayManagement.Implementation.DefaultShapeFactory 。shape工厂生成的shape是一个动态对象。

注意:  Dynamic objects是.NET 4.0才有的功能。作为一个动态对象,shape在运行时暴露它的成员,而不是在编译期。而在ASP.NET MVC中模型对象是一个在编译器定义的静态对象。

    Shape信息由shape的 ShapeMetadata 属性来描述,这些信息包括shape的type、display type、position、prefix、wrappers、alternates、child content和一个 WasExecuted  布尔值。我们可以通过以下代码来获取shape的元信息:

 

var shapeType = shapeName.Metadata.Type;

    当shape对象生成之后,我们如何展现它呢?shape template是一个HEML代码片段,它负责显示shape。我们还可以不使用shape template而直接通过使用shape attribute ( Orchard.DisplayManagement.ShapeAttribute ) 来写代码显示shape。

Creating Shapes

    对于模块开发人员来说,需要知道我们是在driver中把数据转化成模板来显示的。Driver派生自 Orchard.ContentManagement.Drivers.ContentPartDriver ,一般都会重载类的 Display  和 Editor  方法。 Display  和 Editor  方法返回一个 ContentShapeResult 对象,这个对象与ASP.NET MVC中的 ActionResult 类似。

     ContentShape  方法生成一个shape并且把它返回在一个 ContentShapeResult  对象中。 ContentShape 是overloaded的方法,最常用的是传入两个参数(shape 类型和定义shape的动态函数表达式)。动态函数表达式定义这个shape,shape类型命名这个shape并且绑定这个shape到展现模板上。(Shape类型命名规约在本文后面会介绍)

    以下是一个driver的 Display 方法示例,这个方法用来显示一个 Map  part:

 

protected override DriverResult Display(

    MapPart part, string displayType, dynamic shapeHelper)

{

  return ContentShape("Parts_Map",

       () => shapeHelper.Parts_Map(

           Longitude: part.Longitude,

           Latitude: part.Latitude));

} 

这个表达式使用一个动态对象 shapeHelper 来定义一个Parts_Map shape 和它的属性。表达式在shape上添加了一个 Longitude  属性,并且与part的 Longitude  属性绑定起来;同样增加了一个 Latitude  属性。 Display 返回 ContentShape 方法生成的对象。

    下面的示例演示了一个关于 Map  part的完整的driver 类, Display  方法用来显示地图, Editor  方法标记了"GET",用来编辑地图信息,标记了"POST"的 Editor 方法用来重新显示用户提供值的编辑视图。

 

using Maps.Models;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;

namespace Maps.Drivers
{
    public class MapDriver : ContentPartDriver<MapPart>
    {
        protected override DriverResult Display(
            MapPart part, string displayType, dynamic shapeHelper)
        {

            return ContentShape("Parts_Map", () => shapeHelper.Parts_Map(
                Longitude: part.Longitude,
                Latitude: part.Latitude));
        }

        //GET
        protected override DriverResult Editor(
            MapPart part, dynamic shapeHelper)
        {

            return ContentShape("Parts_Map_Edit",
                () => shapeHelper.EditorTemplate(
                    TemplateName: "Parts/Map",
                    Model: part,
                    Prefix: Prefix));
        }
        //POST
        protected override DriverResult Editor(
            MapPart part, IUpdateModel updater, dynamic shapeHelper)
        {

            updater.TryUpdateModel(part, Prefix, null, null);
            return Editor(part, shapeHelper);
        }
    }
}


标记"GET"的 Editor 方法使用 ContentShape 方法来生成一个编辑模板代表的shape对象。在这个例子当中,类型名是Parts_Map_Edit,shapeHelper 对象生成一个 EditorTemplate  shape。这是一个有一个 TemplateName  属性和 Model  属性的shape。 TemplateName  属性表示模板的部分路径,"Parts/Map" 会告诉Orchard去"Views/EditorTemplates/Parts/Map.cshtml"中查找模板。

这里的 Model  属性代表part的不带文件扩展名的模型文件名。

Shapes and Templates命名约定

    命名约定是很多架构现在采用的一种方式,它可以减少一些复杂性,只要保证遵守一定的约定即可。假使我们要生成一个显示地图的Map part,它又精度和纬度两个属性。对shape type的命名可能就是Parts_Map。如果shape命名为Parts_Map,那么Orchard 会在views/parts/Map.cshtml中查找模板

下表汇总了shape type和模板的命名约定:

应用到

Template命名约定

Template示例

Shape Type 示例

Zone

Zone-(zone name)

Zone-AsideSecond.cshtml

Zone__AsideSecond

Menu

Menu-(menu name)

Menu-main.cshtml

Menu__main

MenuItem

MenuItem-(menu name)

MenuItem-main.cshtml

MenuItem__main

Content

Content-(content type)

Content-BlogPost.cshtml

Content__BlogPost

Content

Content-(content id)

Content-42.cshtml

Content__42

Content

Content.(display type)

Content.Summary.cshtml

Content_Summary__Page

Content

Content-(content type).(display type)

Content-Page.Summary.cshtml

Content_Summary__Page

Content.Edit

Content-(content type).Edit

Content-Page.Edit.cshtml

Content_Edit__Page

Widget

Widget-(content type)

Widget-HtmlWidget.cshtml

Widget__HtmlWidget

Widget

Widget-(zone name)

Widget-AsideSecond.cshtml

Widget__AsideSecond

Fields/Common.Text

Fields/Common.Text-(text field name)

Fields/Common.Text-Location.cshtml 
(if the field's Name property equals "Location")

Fields_Common_Text__Location

模板在项目中的位置应该遵守以下规则:

Content item shape 模板放在views/items 目录 Parts_ shape 模板放在views/parts 目录 Fields_ shape 模板放在views/fields 目录下 EditorTemplate shape 模板放在views/EditorTemplates/ template name  目录。例如,模板名是"Parts/Routable.RoutePart" 的EditorTemplate放在views/EditorTemplates/Parts/Routable.RoutePart.cshtml 其他shape模板放在views 目录下

注意: 模板扩展名可以是任意支持的视图引擎支持的扩展名,例如.cshtml, .vbhtml, .ascx.

模板文件名到shape名的映射

    以下规则表示从一个模板文件名到对应shape名的映射规则:

(.) 和 (\) 变成 (_):例如在foo目录下的bar.cshtml 对应的是foo_bar (-) 变成两个下划线 (__):例如Views/Hello.World.cshtml对应的shape名称为Hello_World,Views/Hello.World-85.cshtml 对应的是Hello_World__85

使用模板显示Shapes

    Shape template是显示shape的一个代码片段,在Orchard中缺省的视图引擎是Razor,在后面文章中我会单独介绍Razor语法。下面示例把一个Map part显示为图片:

<img alt="Location" border="1" src="http://maps.google测试数据/maps/api/staticmap?

&zoom=14

&size=256x256

&maptype=satellite&markers=color:blue|@Model.Latitude,@Model.Longitude

&sensor=false" /> 


这个示例显示一个 img  元素,并设定好带参数的 src  属性,在query字符串中, @Model代表传入到模板中的shape。因此, @Model.Latitude 代表shape的 Latitude  属性, @Model.Longitude 代表shape的 Longitude 属性。


下面我们再显示一个编辑模板,这个模板可以输入经度和纬度值:

@model Maps.Models.MapPart

<fieldset>
  <legend>Map Fields</legend>
            
  <div class="editor-label">
    @Html.LabelFor(model => model.Latitude)
  </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>


@Html.LabelFor 表达式生成一个shape属性的label, @Html.TextBoxFor 生成输入shape属性的文本框, @Html.ValidationMessageFor 生成非法提示信息框。

生成一个shape的方法

    另一种生成并展现shape的方法时生成一个同时定义和展现shape的方法。这个方法必须标记 Shape  属性( Orchard.DisplayManagement.ShapeAttribute )。这个方法不适用模板,而是直接返回一个 IHtmlString  对象,这个对象包括展现shape的标记。

    下面示例是 DateTimeRelative  shape,这个shape 输入之前的日期,返回与现在日期的差隔时间:

public class DateTimeShapes : IDependency
{

    private readonly IClock _clock;


    public DateTimeShapes(IClock clock)
    {

        _clock = clock;

        T = NullLocalizer.Instance;

    }


    public Localizer T { get; set; }


    [Shape]

    public IHtmlString DateTimeRelative(HtmlHelper Html, DateTime dateTimeUtc)
    {

        var time = _clock.UtcNow - dateTimeUtc;


        if (time.TotalDays > 7)

            return Html.DateTime(dateTimeUtc, T("'on' MMM d yyyy 'at' h:mm tt"));

        if (time.TotalHours > 24)

            return T.Plural("1 day ago", "{0} days ago", time.Days);

        if (time.TotalMinutes > 60)

            return T.Plural("1 hour ago", "{0} hours ago", time.Hours);

        if (time.TotalSeconds > 60)

            return T.Plural("1 minute ago", "{0} minutes ago", time.Minutes);

        if (time.TotalSeconds > 10)

            return T.Plural("1 second ago", "{0} seconds ago", time.Seconds);


        return T("a moment ago");

    }

} 


作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Orchard: Shape展现介绍的详细内容...

  阅读:50次

上一篇: net2.0事务学习

下一篇:在线支付平台