6

发布具有多个动态模板的组件通常会导致将所有可能的动态组件表示发布到代理。

当您创建具有将项目放置在页面上的选项的 DCT 时,内容编辑器可能不想直接发布组件,而只是依靠页面发布来做正确的事情。我们可以考虑三种可能的期望发布场景:

  1. 发布页面应该只导致呈现静态组件演示文稿,(加上显示动态组件所需的任何 CD 代码)
  2. 除了静态 CP 之外,还应发布任何动态 CP。未发布同一组件的其他可能的动态渲染。
  3. 如果发布了动态 CP,则遵循通常的组件发布语义,所有动态渲染都会到 broker。

Tridion 的默认行为似乎是场景 2),而我的经验是,您通常想要的是场景 3),为您提供 CD 端任何给定组件的完整且一致的视图。

实施方案 3(包括取消发布以正常工作)的最佳方法是什么?

4

2 回答 2

8

在我看来,您问题的最佳答案是实现一个自定义解析器,其中包含所需的动态组件演示。我会在取消发布时对做任何事情持谨慎态度,因为有时您可能希望在取消发布给定页面后保留 DCP(对于“最新消息”类型的功能或任何其他类型的动态查询),但下面的代码示例会做到这一点如果您需要取消发布所有 DCP,您可以轻松适应。

警告:以下代码未经生产测试。

using Tridion.ContentManager;
using Tridion.ContentManager.CommunicationManagement;
using Tridion.ContentManager.ContentManagement;
using Tridion.ContentManager.Publishing;
using Tridion.ContentManager.Publishing.Resolving;

public class IncludeDynamicComponentPresentations : IResolver
{
    public void Resolve(
            IdentifiableObject item, 
            ResolveInstruction instruction,
            PublishContext context, 
            Tridion.Collections.ISet<ResolvedItem> resolvedItems)
    {

        if (!(instruction.Purpose == ResolvePurpose.Publish ||
            instruction.Purpose == ResolvePurpose.RePublish))
        {
            // Do nothing more when unpublishing
            return;
        }

        Session session = item.Session;
        foreach (ResolvedItem resolvedItem in resolvedItems)
        {
            // Only do something if we're dealing with a page
            if (!(resolvedItem.Item is Page)) continue;
            Page page = (Page)resolvedItem.Item;
            if (page.ComponentPresentations.Count > 0)
            {
                UsingItemsFilter filter = new UsingItemsFilter(session);
                filter.InRepository = page.ContextRepository;
                filter.ItemTypes = new[] { ItemType.ComponentTemplate };

                foreach (ComponentPresentation cp in page.ComponentPresentations)
                {
                    // Find all component templates linked to this component's schema
                    Schema schema = cp.Component.Schema;
                    foreach (ComponentTemplate ct in schema.GetUsingItems(filter))
                    {
                        if (!ct.Id.Equals(cp.ComponentTemplate.Id))
                        {
                            if (ct.IsRepositoryPublishable)
                            {
                                resolvedItems.Add(new ResolvedItem(cp.Component, ct));
                            }
                        }
                    }
                }
            }
        }
    }
}

您现在需要将此添加到 GAC 并修改 [Tridion]\Config\Tridion.ContentManager.Config 以便在每次解析操作后调用此解析器(在每个项目类型的解析/映射下)。

于 2012-02-18T13:57:40.017 回答
3

也许自定义解析器会在这种情况下有所帮助?这将使您可以访问发布操作的结果的所有项目,从而允许您更改默认行为。

SDL Tridion 文档门户中有一个很好的示例,但它基本上允许您在 .net 中创建自定义解析器类,您可以在其中实现自定义逻辑。

于 2012-02-18T13:56:56.070 回答