orchard创建一个地图内容部件Content part

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

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

打开命令行窗口,输入:

orchard> codegen module Maps /IncludeInSolution:true
Creating module Maps
Module Maps created successfully

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

VS2010会提示重新加载解决方案文件

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

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,

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 Retrieve(r => r.Latitude); }
            set { Store(r => r.Latitude, value); }
        }

        [Required]
        public double Longitude
        {
            get { return Retrieve(r => r.Longitude); }
            set { Store(r => r.Longitude, value); }
        }
    }
}

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

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提示重新加载解决方案,新的数据迁移类出现在项目中。

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>

Views/Parts/Map.cshtml :

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

Parts_Map shape

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

Content Types

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

Parts列表

现在在"管理内容"中编辑内容项。地图部分将纬度和经度的字段添加到此内容中。键入一些有效的坐标并重新发布该内容。

地图部分将纬度和经度的字段添加到此内容中

现在在网站前台就可以看到如下图所示:

10.png

本实例源码下载:

Orchard.Module.Maps.1.0.0.zip


Add a Comment