五、扩展Orchard(四) Creating a module

Generating Code for the Module

打开命令行工具,输入下面命令:

codegen module SimpleCommerce

然后到新建的目录中编辑module.txt文件:

Name: SimpleCommerce
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 0.5.0
OrchardVersion: 0.5.0
Description: A simple commerce module
Features:
    SimpleCommerce:
        Name: Simple Commerce
        Description: A simple product part.
        Category: Commerce

 

Creating the Model for the Part

下面将创建一个数据模型,用于显示存储在数据库中的内容。

在Models目录中创建Product.cs文件:

using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;

namespace SimpleCommerce.Models {
  public class ProductPartRecord : ContentPartRecord {
    public virtual string Sku { get; set; }
    public virtual float Price { get; set; }
  }

  public class ProductPart : ContentPart<ProductPartRecord> {
    [Required]
    public string Sku {
      get { return Record.Sku; }
      set { Record.Sku = value; }
    }

    [Required]
    public float Price {
      get { return Record.Price; }
      set { Record.Price = value; }
    }
  }
}

 

这段代码有两个属性,Sku和Price,这是虚拟的,以便启用动态代理的创建将透明地处理持久化。

代码同样定义了一个content part从ContentPart&lt;ProductPartRecord&gt;并暴露了记录的Sku和Price,这两个属性有特性用于验证测试在UI中浮出。

需要将这个文件加入到模块的项目文件中,打开SimpleCommerce.csproj,查找"assemblyinfo.cs",添加下面信息

<Compile Include="Models\Product.cs" />

保存文件。在浏览器打开网站,确保启用了动态编译功能,启用SimpleCommerce功能。

 

reating the Initial Data Migration File

数据迁移是一个模式,使应该程序或组件在不丢失数据前提下完美的升级到新版本。主要思想是保持对当前版本安装的跟踪和每个数据迁移的变化,从一个版本到下一个版本。如果系统检测到有一个新版本安装当前的数据是之前版本的,将提示网站管理员进行升级。系统之前版本的数据和代码同步了,然后运行所有必要的迁移方法。

开始创建新的模块的初始迁移,仅仅创建需要的数据表,在命令行窗口输入下面命令:

codegen datamigration SimpleCommerce

这将创建下面的Migrations.cs文件:

using System;
using System.Collections.Generic;
using System.Data;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;

namespace SimpleCommerce.DataMigrations {
    public class Migrations : DataMigrationImpl {

        public int Create() {
            // Creating table ProductPartRecord
            SchemaBuilder.CreateTable("ProductPartRecord", table => table
                .ContentPartRecord()
                .Column("Sku", DbType.String)
                .Column("Price", DbType.Single)
            );



            return 1;
        }
    }
}

Create方法为初始数据迁移约定,它调用SchemaBuilder.CreateTable方法创建一个ProductPartRecord数据表的Sku和Price列,除了基本的ContentPartRecord表。

注意这个方法返回1,迁移的版本号。

为了说明如何能修改架构和类型的元数据加入另一个迁移步骤,你将以此为契机,添加一个功能,这将使部分被附加到任何内容类型。数据迁移类添加以下方法

public int UpdateFrom1() {
  ContentDefinitionManager.AlterPartDefinition("ProductPart",
    builder => builder.Attachable());
  return 2;
}

这个新的迁移被命名为UpdateFrom1,这是该公约从版本1升级。

下个迁移应该叫UpdateFrom2、UpdateFrom3,依此类推。

确保.csproj文件中有下面一行:

<Compile Include="Migrations.cs" />

导航到Features面板,将看到警告升级,点击 update ,迁移将运行,模块也升级了。

 

Adding a Handler

Orchard中的handler与ASP.NET MVC的filter相似,它是特定事件发生时运行的一段代码,但不具体到一个给定的内容类型。例如:你可以创建一个统计模块,为了记录使用统计监听Loaded事件。

创建Handlers文件夹,添加ProductHandler.cs文件:

using Orchard.ContentManagement.Handlers;
using SimpleCommerce.Models;
using Orchard.Data;

namespace SimpleCommerce.Handlers {
  public class ProductHandler : ContentHandler {
    public ProductHandler(IRepository<ProductPartRecord> repository) {
      Filters.Add(StorageFilter.For(repository));
    }
  }
}

 

.csproj文件中加入动态编译

<Compile Include="Handlers\ProductHandler.cs" />

 

Adding a Driver

Orchard中的driver与ASP.NET MVC中的控制器相似,但在web CMS中很好的适应必要的组成方面。它是为专为指定content part,并可指定知名的行为像在前端显示一条或在管理界面中编辑它。

一个driver通常重写display和editor行为,对于product part,创建一个新Drivers文件夹, 创建ProductDriver.cs文件:

using SimpleCommerce.Models;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement;

namespace SimpleCommerce.Drivers {
  public class ProductDriver : ContentPartDriver<ProductPart> {
    protected override DriverResult Display(
        ProductPart part, string displayType, dynamic shapeHelper)
    {
      return ContentShape("Parts_Product",
          () => shapeHelper.Parts_Product(
              Sku: part.Sku,
              Price: part.Price));
    }

    //GET
    protected override DriverResult Editor(ProductPart part, dynamic shapeHelper)
    {
      return ContentShape("Parts_Product_Edit",
          () => shapeHelper.EditorTemplate(
              TemplateName: "Parts/Product",
              Model: part,
              Prefix: Prefix));
    }

    //POST
    protected override DriverResult Editor(
        ProductPart part, IUpdateModel updater, dynamic shapeHelper)
    {
      updater.TryUpdateModel(part, Prefix, null, null);
      return Editor(part, shapeHelper);
    }
  }
}

在Display代码中创建一个shape当在前端渲染时使用。

这个shape有Sku和Price属性从part复制。

更新.csproj文件:

<Compile Include="Drivers\ProductDriver.cs" />

Editor方法也创建一个shape叫EditorTemplate,这个shape有TemplateName属性指示Orchard到哪里寻找这个渲染模板。访代码还指定该模板模型的一部分,而不是shape(这是默认的)。在较大的前端或仪表盘中的这个parts的placement必须指定使用placement.info文件,位于模块的根目录。这个文件,像一个视图,从一个主题重写,用下面内容创建placement.info文件:

<Placement>
    <Place Parts_Product_Edit="Content:3"/>
    <Place Parts_Product="Content:3"/>
</Placement>

修改.csproj文件:

<Content Include="placement.info" />

 

Building the Templates

为了新content part能工作要做的最后事情是写两个模板(前端和后端),在driver中配置。

首先,创建前端模板,在Views文件夹下创建Parts文件夹并添加Product.cshtml文件:

<br/>
@T("Price"): <b>$@Model.Price</b><br />
@Model.Sku<br/>

这是shape的一个非常清晰的渲染,注意这里使用了localization的T方法。

然后,在Views文件夹下创建EditorTemplates文件夹,并在Parts文件夹添加Product.cshtml文件:

@model SimpleCommerce.Models.ProductPart
<fieldset>
    <label class="sub" for="Sku">@T("Sku")</label><br />
    @Html.TextBoxFor(m => m.Sku, new { @class = "text" })<br />
    <label class="sub" for="Price">@T("Price")</label><br />
    @Html.TextBoxFor(m => m.Price, new { @class = "text" })
</fieldset>

将上面两个模板加入.csproj文件:

<Content Include="Views\Parts\Product.cshtml" />
<Content Include="Views\EditorTemplates\Parts\Product.cshtml" />

 

Putting it All Together into a Content Type

将建立一个新Product 内容类型,包含Product part和一些Orchard中的part,到目前为止,你一直关注特定的领域,下面将改变,你将开始整合到Orchard中。

为一个新迁移建立内容类型,打开Migrations.cs文件,添加下面的类:

public int UpdateFrom2() {
  ContentDefinitionManager.AlterTypeDefinition("Product", cfg => cfg
    .WithPart("CommonPart")
    .WithPart("RoutePart")
    .WithPart("BodyPart")
    .WithPart("ProductPart")
    .WithPart("CommentsPart")
    .WithPart("TagsPart")
    .WithPart("LocalizationPart")
    .Creatable()
    .Indexed());
  return 3;
}

你正在做的是创建(或更新)一个Product内容类型,添加自己的URL和Title(RoutePart),有一个描述(BodyPart),对产品可以评论(CommentsPart),能标记(TagsPart),本地化(LocalizationPart),

它也可以被创建,这将添加一个创建产品菜单项,它也将进入搜索索引(Indexed)。

启用新模块,

添加一个新Product 内容类型,点击Content,

posted @ 2012-03-21 17:36  commanderss  阅读(713)  评论(0编辑  收藏  举报