Sitecore 6.4 中克隆项目之间的链接和引用

发布于 2024-11-07 03:27:45 字数 1000 浏览 4 评论 0原文

我正在构建一个数据存储库站点,然后将其整体克隆以提供多个克隆站点,从而实现全球内容的本地化。

我需要做的是确保存储库站点中的项目之间的所有引用(富文本字段中的链接、拉入“相关项目”点的项目引用等)都被覆盖以引用相关的克隆而不是存储库中的原始项目。

这可能涉及例如自定义 LinkManager 以及可能使用一些附加逻辑的 GetItem(itemID) 来查找正确的克隆。

我需要知道的是我需要担心 API 的哪些部分?我是否可以进行单个修改,该修改将继承 .Net 组件中富文本字段中的链接渲染、从下拉列表馈送到子布局的项目引用、通过 XSLT 的渲染等?在克隆站点的上下文中,我需要一个项目 ID 来作为其克隆的别名。当处于克隆站点上下文中时,Context.Database.GetItem(ID) 需要返回一个克隆。

我基本上正在寻找一种机制,无论何时何地在克隆站点的上下文中使用它,都可以将“Data/Home/Products/Product A”转换为“clone/Home/Products/ProductA”。

我需要在哪里实现这个逻辑,有多少个地方?

交叉发布到 SDN http://sdn.sitecore.net/SDN5/ Forum/ShowPost.aspx?PostID=35598

这与之前的问题相关处理 Sitecore 6.4 克隆网站中的内部链接 ,但包含更多内容细节并且更加具体。

编辑:虽然理想的解决方案会将此功能置于 Sitecore 深处,但重要的是这仅适用于在实际网站上查看的内容,即它不得干扰 Sitecore 管道,例如创建、克隆和删除项目。

I'm building a data repository site that I will then clone in its entirety to provide multiple clone sites, enabling localistaion of global content.

What I need to do is to ensure that all references between items in the repository site (links in rich text fields, item references to pull in "related items" spots etc) are overridden to refer to the relevant clones instead of the original items in the repository.

This will likely involve e.g. customising the LinkManager and maybe GetItem(itemID) with some additional logic to find the correct clone.

What I need to know is which bits of the API do I need to worry about? Is there a single modification I can make which will inherit to link rendering in a rich text field in .Net components, item references fed to a sublayout from drop list, renderings through XSLT etc? I need an item ID to work as an alias for its clone when in the context of the clone site. Context.Database.GetItem(ID) needs to return a clone when in the clone site context.

I'm basically looking for a mechanism that will translate "Data/Home/Products/Product A" to "clone/Home/Products/ProductA" whenever and however I use it in the context of a clone site.

Where do I need to implement this logic, how many places?

Cross posted to SDN http://sdn.sitecore.net/SDN5/Forum/ShowPost.aspx?PostID=35598

This is related to an earlier question Handling internal links in Sitecore 6.4 cloned sites , but contains more detail and is more specific.

EDIT: though the ideal solution would place this functionality deep within Sitecore it is important that this only applies to content as viewed on the actual website, i.e. it must not interfere with Sitecore pipelines for e.g. creating, cloning and deleting items.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清眉祭 2024-11-14 03:27:45

我建议您采取不同的方法。您可以向 HttpRequestPipeline 添加代码以将“Data/Home/Products/Product A”解析为“clone/Home/Products/ProductA”,而不是更改链接本身。 重用和共享数据中描述了类似的方法:

CMS 用户可以使用富文本编辑器、呈现属性或其他功能来链接到项目
基于项目选择数据模板。在代码中考虑这些条件。你可以
配置 httpRequestBegin 管道处理器来处理项目的 HTTP 请求 [...]

要将此方法应用到您的场景,请在

以下是要实现的逻辑:

  1. 使用 HttpContext.Current.Request.UrlReferrer 确定引用站点。
  2. 验证引用站点是否在您的克隆站点列表中。
  3. 检查 Sitecore.Context.Item 是否位于源站点中。
  4. 使用新路径创建一个字符串,并使用 Database.GetItem() 验证此项是否存在。
  5. 将 Sitecore.Context.Item 修改为新项目。

这种方法的优点是您不需要拦截创建链接的多种方法,并且可以将路径重写逻辑保留在一个位置。实际上,您将创建从“Data/Products/ProductA”到“clone/Home/ProductA”的别名,该别名仅在您的站点位于克隆列表中时才会生效。

更新:我在 Office Core 中对此方法进行了测试。我创建了第二个站点 AlternalteSite,其中包含一个子节点 Our-Process。 AlternateSite 主页有一个指向 /home/Our-Process 的链接。当以下代码添加到 HttpRequestBegin 管道时,链接将定向到 /AlternateSite/Our-Process 项。

public class SiteChanger : HttpRequestProcessor
 {
   // Some definitions removed...
    public override void Process(HttpRequestArgs args)
    {

        if (ReferringSiteIsTarget())
        {
            Item targetItem = GetTargetItem();
            if (targetItem != null)
            {
                Sitecore.Context.Item = targetItem;
            }
        }
    }

    private Item GetTargetItem()
    {
        string currentItemPath = Sitecore.Context.Item.Paths.FullPath;
        string newPath;

        if (currentItemPath.Contains(SourcePath))
        {
            newPath = currentItemPath.Replace(SourcePath, TargetPath);
            return Sitecore.Context.Database.GetItem(newPath);
        }
        return null;
    }
}

更新2:正如 James Walford 在评论中指出的那样,这种方法仅在克隆未重命名时才有效。据我所知,Sitecore 并未提供从源项目遍历到 Web 数据库中其克隆的方法。在 master 中,您可以使用链接数据库从项目获取其克隆(请参阅 此论坛帖子,作者:John West),但在发布后,克隆就成为正常项目,因此大概不会包含在链接数据库中。

一种方法是将克隆链接的多重列表添加到标准模板,并添加逻辑以将其填充为 uiCloneItems 管道的一部分,并在 HttpRequestProcessor 代码中使用此数据。这将保留链接数据库关系,但会增加克隆过程和 Http 请求解析过程的开销,因为您的代码需要迭代所有克隆以确定哪个克隆位于请求网站中。

I recommend you take a different approach. Rather than changing the links themselves, you can add code to the HttpRequestPipeline to resolve "Data/Home/Products/Product A" as "clone/Home/Products/ProductA". A similar approach is described in Reusing and Sharing Data:

A CMS user could use the Rich Text Editor, rendering properties, or other features to link to an item
based on an item selection data template. Account for these conditions in your code. You can
configure an httpRequestBegin pipeline processor to handle HTTP requests for items [...]

To apply this approach to your scenario, add the custom implementation of HttpRequestProcessor after <processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel"/> in the HttpRequestBegin pipeline in web.config.

Here's the logic to implement:

  1. Use HttpContext.Current.Request.UrlReferrer to determine the referring site.
  2. Verify that the referring site is in your list of cloned sites.
  3. Check if Sitecore.Context.Item is in the source site.
  4. Create a string with the new path, and verify that this item exists using Database.GetItem().
  5. Modify Sitecore.Context.Item to the new item.

The advantage of this approach is that you do not need to intercept the many ways that a link can be created, and you keep your path rewriting logic in one place. In effect, you will be creating an alias from "Data/Products/ProductA" to "clone/Home/ProductA" that will only take effect if your site is in your list of clones.

Update: I did a test of this approach in Office Core. I created a second site, AlternalteSite, with a child node Our-Process. The AlternateSite home page has a link to /home/Our-Process. When the code below is added to the HttpRequestBegin pipeline, the link directs to the /AlternateSite/Our-Process item.

public class SiteChanger : HttpRequestProcessor
 {
   // Some definitions removed...
    public override void Process(HttpRequestArgs args)
    {

        if (ReferringSiteIsTarget())
        {
            Item targetItem = GetTargetItem();
            if (targetItem != null)
            {
                Sitecore.Context.Item = targetItem;
            }
        }
    }

    private Item GetTargetItem()
    {
        string currentItemPath = Sitecore.Context.Item.Paths.FullPath;
        string newPath;

        if (currentItemPath.Contains(SourcePath))
        {
            newPath = currentItemPath.Replace(SourcePath, TargetPath);
            return Sitecore.Context.Database.GetItem(newPath);
        }
        return null;
    }
}

Update2: As James Walford points out in the comments, this approach only works if the clones are not renamed. Sitecore does not, to my knowledge, provide a way of traversing from a source item to its clones in the web database. In master, you can use the Link Database to get from an item to its clones (see this forum post by John West), but after publication, clones become normal items, so presumably will not be included in the Link Database.

One approach would be to add a multilist of links to clones to the standard template, and add logic to populate this as part of the uiCloneItems pipeline, and to use this data in the HttpRequestProcessor code. This will preserve the Link Database relationship, but will put overhead on both the cloning process and the Http Request resolution process, as your code would need to iterate through all the clones to determine which one lived in the requesting website.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文