组件链接作为元数据 在出版物级别,找到使用相应组件的页面

本文关键字:组件 链接 元数据 出版物 | 更新日期: 2023-09-27 18:37:04

在TBB中,我试图使用条件和查询来查找页面,该页面使用具有特定TcmUri的组件。

我在sdllive上搜索了一个示例,但没有找到。

有人可以给我一个例子来说明我该怎么做吗?

完整的场景是这样的:

我有一个组件链接设置为出版物上的元数据字段。此组件链接是一个登录组件。使用组件的页面提供了网站的登录功能。现在,我在发布网站管理员时从发布中读取元数据,获取用作组件链接的组件的 tcmId(我已经这样做了)并找到正在使用组件的页面(登录页面),以便获取此登录页面的路径并将其写入 web.config。

组件链接作为元数据 在出版物级别,找到使用相应组件的页面

如果组件作为组件演示文稿在页面中,那么为什么不直接使用组件链接来查找它呢?将组件的 URI 存储在 Web.Config 中,如果这对您来说最简单,请使用如下所示的内容:

const string currentPageId = "tcm:6-123-64";
TcmUri itemUri = new TcmUri(ConfigurationManager.AppSettings["MyLoginComponent"]);
ComponentLink componentLink = new ComponentLink(itemUri.PublicationId);
string loginUrl =
    componentLink.GetLink(currentPageId, itemUri.ToString(), "tcm:0-0-0", "", "",
                          false, false).Url;

如果您希望在发布时使用 TBB 查找此信息:

RepositoryLocalObject context = null;
if (package.GetByName(Package.ComponentName) == null)
    context = (RepositoryLocalObject)engine.GetObject(
               package.GetByName(Package.ComponentName));
else
    context = (RepositoryLocalObject)engine.GetObject(
               package.GetByName(Package.ComponentName));
Repository contextPublication = context.ContextRepository;
if (contextPublication.Metadata == null) return;
ItemFields metadata = 
     new ItemFields(contextPublication.Metadata, contextPublication.MetadataSchema);
if (!metadata.Contains("MyLoginComponentField")) return;
ComponentLinkField myLoginComponentField = (ComponentLinkField)metadata["MyLoginComponentField"];
Component loginTarget = myLoginComponentField.Value;
UsingItemsFilter filter = new UsingItemsFilter(engine.GetSession())
                                {
                                    InRepository = contextPublication, 
                                    ItemTypes = new[] {ItemType.Page}
                                };
foreach (Page page in component.GetUsingItems(filter))
{
    string url = page.PublishLocationUrl;
}

如果该组件在多个页面中使用,那么这将包含列表中最后一个页面的 URL - 确保不是这种情况......我本可以在代码中正确处理它,但我认为我不应该做你所有的功课。

Nuno 是对的 - Tridion 的动态组件链接功能将完全满足您的需求。Nuno 的示例使用应用程序配置数据,但您可以像问题中建议的那样轻松地使用发布数据来引用登录组件。

有时,您在页面上没有要链接到的明显组件。例如,主页或子网站主页通常实际上没有内容。如果是这样,那么您也可以通过在作为链接目标的页面上放置一个虚拟组件,并使用不呈现任何额外输出的模板来呈现它。

我设法通过实现此方法过滤版本:

public static bool IsPageLastVersion(Page page)
    {
        bool isLastVersion = false;
        if (page != null)
        {
            List<VersionedItem> pageVersions = page.GetVersions().ToList();
            pageVersions.Sort((v1, v2) => v1.Version.CompareTo(v2.Version));
            int lastVersion = pageVersions.Last().Version;
            isLastVersion = lastVersion == page.Version;
        }
        return isLastVersion;
    }

我采用了 Nuno 建议的方法,我现在拥有的是以下内容:

        StringBuilder url = new StringBuilder();
        RepositoryLocalObject context = null;
        if (package.GetByName(Package.ComponentName) == null)
            context = (RepositoryLocalObject)engine.GetObject(
                       package.GetByName(Package.PageName));
        else
            context = (RepositoryLocalObject)engine.GetObject(
                       package.GetByName(Package.ComponentName));
        Repository contextPublication = context.ContextRepository;
        _log.Debug("Starting checking the metadata");
        if (contextPublication.Metadata != null)
        {
            ItemFields metadata =
             new ItemFields(contextPublication.Metadata, contextPublication.MetadataSchema);
            if (metadata.Contains("LoginPage"))
            {
                _log.Debug("LoginPage metadata field found in " + metadata.ToXml().OuterXml);
                ComponentLinkField myLoginComponentField = (ComponentLinkField)metadata["LoginPage"];
                Component loginTarget = myLoginComponentField.Value;
                UsingItemsFilter filter = new UsingItemsFilter(engine.GetSession())
                {
                   // InRepository = contextPublication,
                    ItemTypes = new[] { ItemType.Page }
                };
                foreach (comm.Page page in loginTarget.GetUsingItems(filter))
                {
                    if(PublishEngine.IsPublished(page))
                    {
                        url.Append(" url: ").Append(page.PublishLocationUrl);
                    }
                }
            }
        }
        return url.ToString();

现在,我只是将所有页面路径读取为单个字符串。