0

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

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

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

完整的场景是这样的:

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

4

4 回答 4

2

如果组件在页面中作为组件表示,那么为什么不直接使用组件链接来查找它呢?将组件的 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 - 确保不是这种情况......我可以在代码中正确处理,但我认为我应该不要做所有的功课。

于 2012-06-13T11:11:30.810 回答
0

我采用了 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();

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

于 2012-06-15T08:39:03.757 回答
0

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

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

于 2012-06-14T22:00:22.000 回答
0

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

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;
    }
于 2012-06-18T09:51:31.423 回答