惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
Webroot Blog
Webroot Blog
T
Troy Hunt's Blog
S
Secure Thoughts
S
Security @ Cisco Blogs
S
Security Affairs
Forbes - Security
Forbes - Security
W
WeLiveSecurity
H
Hacker News: Front Page
T
Threatpost
Google Online Security Blog
Google Online Security Blog
S
Schneier on Security
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - Franky
腾讯CDC
IT之家
IT之家
博客园 - 聂微东
L
LINUX DO - 最新话题
罗磊的独立博客
Hacker News - Newest:
Hacker News - Newest: "LLM"
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)
Hacker News: Ask HN
Hacker News: Ask HN
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Know Your Adversary
Know Your Adversary
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cisco Talos Blog
Cisco Talos Blog
S
SegmentFault 最新的问题
酷 壳 – CoolShell
酷 壳 – CoolShell
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
美团技术团队
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
AI
AI
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Jina AI
Jina AI
Help Net Security
Help Net Security
N
News | PayPal Newsroom
月光博客
月光博客
Spread Privacy
Spread Privacy
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
N
News and Events Feed by Topic

博客园 - 飞翔的天空

sp.net core部署到iis中出现 HTTP Error 502.5 - Process Failure 的解决办法 aspnet zero Swagger 不出现Authorize按钮的解决办法 Js获取当前日期时间及其它操作 js阿拉伯数字转中文大写 php学习点滴 excel合并单元格内容 EXCEL公式以指定分隔符从右往左截取字符 drupal学习FAQ drupal模块简介 js中三目运算及readonly的解决办法 Zxing中文乱码的简单解决办法 easyUI MVC3一些注意的东东(4) orchard模块编写的错误及其解决办法 orchard文档之-orchard工作原理 orchard文档之-搜索和索引 orchard文档之-更新站点到新的orchard版本 orchard文档之-创建自定义表单 准备把orchard的自己认为重要的文档翻译一遍 orchard文档之-理解数据访问
orchard文档之-理解内容处理器
飞翔的天空 · 2013-05-31 · via 博客园 - 飞翔的天空

理解内容处理器

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.

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.

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.

Built-in filter types

  • StorageFilter class - Takes care of persisting the data from repository object to the database. Its usage is shown in the example above.
  • 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.

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
  • OnCreated
  • OnCreating
  • OnIndexed
  • OnIndexing
  • OnInitializing
  • OnLoaded
  • OnLoading
  • OnPublished
  • OnPublishing
  • OnRemoved
  • OnRemoving
  • OnUnpublished
  • OnUnpublishing
  • OnVersioned
  • OnVersioning

For example, the TagPartHandler class contains code to take action for the Removed and Indexing events, as shown in the following example:

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
  • BuildDisplayShape
  • BuildEditorShape
  • UpdateEditorShape

For example, the BlogPostPartHandler class overrides the GetItemMetadata method to add route values using code like the following:

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