五、扩展Orchard(五) Writing a Content Part

Content part 是一块要可重用的的功能或UI,能加到Orchard中的任何类型中。

本文将建立一个自定义Map part,能用经纬度进行配置,为content item显示地图图片。

打开命令行窗口,输入:

orchard> codegen module Maps /IncludeInSolution:true

执行这个命令后,VS2010会提示重新加载解决方案文件

Maps 模块项目出现在解决方案中,

 

编辑Module.txt文件:

Name: Maps
AntiForgery: enabled
Author: The Orchard Team
Website: http://orchardproject.net
Version: 1.0.0
OrchardVersion: 1.0.0
Description:  Adds a map image to content items, based on longitude and latitude.
Features:
    Maps:
        Description: Adds a map image to content items, based on longitude and latitude.
        Category: Geolocation

 

现在我们开始写Map part,我们需要为part包含数据的类,在Models文件夹中添加Data classes,

Orchard中,content part数据用Record class表示,表示的fields存储到数据库表,一个content part类使用Record存储。添加MapRecord(ContentPartRecord)和MapPart(ContentPart)类:

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

namespace Maps.Models {
    public class MapRecord : ContentPartRecord {
        public virtual double Latitude { get; set; }
        public virtual double Longitude { get; set; }
    }

    public class MapPart : ContentPart<MapRecord> {
        [Required]
        public double Latitude
        {
            get { return Record.Latitude; }
            set { Record.Latitude = value; }
        }

        [Required]
        public double Longitude
        {
            get { return Record.Longitude; }
            set { Record.Longitude = value; }
        }
    }
}

现在build Maps项目,确保Record类成功编译。

下面,我们将为我们的Maps模块创建数据迁移。我们为什么需要一个数据迁移类?原因是,定义Record和Part类存储数据任何方式都不影响数据库。数据迁移告诉Orchard当Maps功能启用时(迁移在功能启用时运行)如何更新数据库架构,迁移同样能升级数据库架构从前面的版本到新版本。.

能使用Code Generation功能创建新数据迁移类,在命令行输入:

orchard> codegen datamigration Maps
Creating Data Migration for Maps
Data migration created successfully in Module Maps

VS提示重新加载解决方案,新的数据迁移类出现在项目中。

Migration类包含一个Create()方法,基于Record类定义一个数据库表结构。因为我们只有一个有经纬度属性的MapRecord类,Migration很简单,在功能启用时将调用Create方法,因此数据库将更新。

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

namespace Maps.DataMigrations {
    public class Migrations : DataMigrationImpl {

        public int Create() {
            // Creating table MapRecord
            SchemaBuilder.CreateTable("MapRecord", table => table
                .ContentPartRecord()
                .Column("Latitude", DbType.Double)
                .Column("Longitude", DbType.Double)
            );

            ContentDefinitionManager.AlterPartDefinition(
                typeof(MapPart).Name, cfg => cfg.Attachable());

            return 1;
        }
    }
}

为了使part能附加到任何内容类型在Migration中添加AlterPartDefinition 行,在文件顶部添加using Maps.Models;

现在为Map part添加handler,Map part很简单,在这种情况下,我们的处理程序类将只能指定MapRecord的IRepository 应作为存储使用。

Add the following Handlers\MapHandler.cs

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

namespace Maps.Handlers {
    public class MapHandler : ContentHandler {
        public MapHandler(IRepository<MapRecord> repository) {
            Filters.Add(StorageFilter.For(repository));
        }
    }
}

 

我们也为Map part添加一个driver,我们将保持这个part的简单,且仅使用Map作为shape的名称,为显示和编辑上下文而使用。添加MapDriver类:

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);
        }
    }
}

 

我们能在VS中添加display和editor视图,首先添加parts和EditorTemplates/Parts文件夹到Views下面,然后在 Views/EditorTemplate/Parts和Views/Parts 添加Map.cshtml文件:

@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>



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

 

这两个模板将做为大的、组合页面进行渲染,因为系统需要知道他们在组合页面中的顺序和位置,我们需要添加placement.info文件到模块的根目录中:

<Placement>
    <Place Parts_Map="Content:10"/>
    <Place Parts_Map_Edit="Content:7.5"/>
</Placement>

这是说Parts_Map shape(被渲染的Views/Parts/Maps.cshtml除非被当前主题覆盖)应该在”Content”zone中被渲染(如果可用),第10个位置,它也在第二个位置中的"Primary"zone中放置editor shape/template。

你可以尝试将Map part附加到任何内容类型上,使用Orchard管理面板的”Content Types.让我们添加到”Event”内容类型上。在”Manage Content Types" 面板上点击”edit”,

Map Part显示在可以Parts列表中,选上它并保存.

 

ow go the "Manage Content" and edit an event content item. Notice that the Map part adds Latitude and Longitude fields to this item. Type some valid coordinates and re-publish the content item.

On the front-end of your site, you can see the effect of the Map part rendering on the event content item.

posted @ 2012-03-21 19:16  commanderss  阅读(685)  评论(0编辑  收藏  举报