了解内容处理程序-Understanding Content Handlers
This topic has been updated for the Orchard 1.9.1 release.
本主题已针对Orchard 1.9.1发行版进行了更新。
A content handler defines what happens with a content part in response to specific events, such as when the part is activated. The content handler enables you to perform actions at particular moments in the lifecycle of the content item. It also enables you to set up data repositories and manipulate the data model prior to rendering the content item.
内容处理程序定义内容部分响应特定事件时发生的情况,例如激活部件时。内容处理程序使您可以在内容项的生命周期中的特定时刻执行操作。它还使您能够在呈现内容项之前设置数据存储库并操纵数据模型。
Typically, you define a handler for a content part by creating a class that inherits from ContentHandler
. The ContentHandler
class is a base class that provides the methods and properties you will commonly need when defining your own content handler. Alternately, you can also create your own content handler by creating a class that implements IContentHandler
.
通常,您可以通过创建继承自“ContentHandler”的类来为内容部件定义处理程序。 ContentHandler
类是一个基类,它提供了在定义自己的内容处理程序时通常需要的方法和属性。或者,您也可以通过创建实现IContentHandler
的类来创建自己的内容处理程序。
Defining Data Repository and Adding Filters
定义数据存储库和添加过滤器
When working with a content part that persists data, add a constructor for the handler that accepts an IRepository
parameter for objects of the type you defined for records in the part. The following code shows a basic implementation of a content handler. MapRecord
is a class defined in a separate file.
使用持久化数据的内容部件时,为处理程序添加构造函数,该构造函数接受为您为部件中的记录定义的类型的对象的“IRepository”参数。以下代码显示了内容处理程序的基本实现。 MapRecord
是在单独的文件中定义的类。
using Map.Models;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
namespace Map.Handlers {
public class MapHandler : ContentHandler {
public MapHandler(IRepository<MapRecord> repository) {
Filters.Add(StorageFilter.For(repository));
}
}
}
You can add other types of filters to the content handler. For example, you can add an ActivatingFilter
to the Filters
collection to define how the part is added to a type.
您可以向内容处理程序添加其他类型的过滤器。例如,您可以将ActivatingFilter
添加到Filters
集合中,以定义如何将零件添加到类型中。
Built-in filter types
内置过滤器类型
-
StorageFilter
class - Takes care of persisting the data fromrepository
object to the database. Its usage is shown in the example above. -
StorageFilter
类 - 负责将来自repository
对象的数据持久保存到数据库中。其用法如上例所示。 * -
ActivatingFilter
class - Attaches a part to a content type from code. As opposed to attaching parts via migrations, parts attached using this filter will neither be displayed in the Dashboard, nor users will be able to remove them from types. It's a legitimate way of attaching parts that should always exist on a given content type. -
ActivatingFilter
类 - 从代码中将一部分附加到内容类型。与通过迁移附加零件相反,使用此过滤器附加的零件既不会显示在仪表板中,也不会将用户从类型中删除。这是一种合法的方式来附加应该始终存在于给定内容类型上的部分。
Lifecycle Events
生命周期事件
In addition to defining the repository, you can add code for handling events. You use the following methods to add the code that is executed for the event:
除了定义存储库之外,您还可以添加用于处理事件的代码。您使用以下方法添加为事件执行的代码:
-
OnActivated
-
OnActivated
* -
OnCreated
-
OnCreated
* -
OnCreating
-
OnCreating
* -
OnDestroyed
-
OnDestroyed
* -
OnDestroying
-
OnDestroying
* -
OnGetContentItemMetadata
-
OnGetContentItemMetadata
* -
OnGetDisplayShape
-
OnGetDisplayShape
* -
OnGetEditorShape
-
OnGetEditorShape
* -
OnIndexed
-
OnIndexed
* -
OnIndexing
-
OnIndexing
* -
OnInitialized
-
OnInitialized
* -
OnInitializing
-
OnInitializing
* -
OnLoaded
-
OnLoaded
* -
OnLoading
-
OnLoading
* -
OnPublished
-
OnPublished
* -
OnPublishing
-
OnPublishing
* -
OnRemoved
-
OnRemoved
* -
OnRemoving
-
OnRemoving
* -
OnUpdated
-
OnUpdated
* -
OnUpdateEditorShape
-
OnUpdateEditorShape
* -
OnUpdating
-
OnUpdating
* -
OnUnpublished
-
OnUnpublished
* -
OnUnpublishing
-
OnUnpublishing
* -
OnVersioned
-
OnVersioned
* -
OnVersioning
-
OnVersioning
*
For example, the TagPartHandler
class contains code to take action for the Removed
and Indexing
events, as shown in the following example:
例如,TagPartHandler
类包含对Removed
和Indexing
事件采取操作的代码,如以下示例所示:
public class TagsPartHandler : ContentHandler {
public TagsPartHandler(IRepository<TagsPartRecord> repository, ITagService tagService) {
Filters.Add(StorageFilter.For(repository));
OnRemoved<TagsPart>((context, tags) =>
tagService.RemoveTagsForContentItem(context.ContentItem));
OnIndexing<TagsPart>((context, tagsPart) =>
context.DocumentIndex.Add("tags", String.Join(", ", tagsPart.CurrentTags.Select(t => t.TagName))).Analyze());
}
}
Data Manipulation
数据操作
You can override the following methods to perform actions related to the state of the data:
您可以覆盖以下方法以执行与数据状态相关的操作:
-
GetItemMetadata
-
GetItemMetadata
* -
BuildDisplayShape
-
BuildDisplayShape
* -
BuildEditorShape
-
BuildEditorShape
* -
UpdateEditorShape
-
UpdateEditorShape
*
For example, the BlogPostPartHandler
class overrides the GetItemMetadata
method to add route values using code like the following:
例如,BlogPostPartHandler
类重写了GetItemMetadata
方法,使用如下代码添加路由值:
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
var blogPost = context.ContentItem.As<BlogPostPart>();
if (blogPost == null)
return;
context.Metadata.CreateRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
{"Controller", "BlogPostAdmin"},
{"Action", "Create"},
{"blogId", blogPost.BlogPart.Id}
};
context.Metadata.EditorRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
{"Controller", "BlogPostAdmin"},
{"Action", "Edit"},
{"postId", context.ContentItem.Id},
{"blogId", blogPost.BlogPart.Id}
};
context.Metadata.RemoveRouteValues = new RouteValueDictionary {
{"Area", "Orchard.Blogs"},
{"Controller", "BlogPostAdmin"},
{"Action", "Delete"},
{"postId", context.ContentItem.Id},
{"blogSlug", blogPost.BlogPart.As<RoutePart>().Slug}
};
}