Ответ 1
Я рекомендую вам использовать другой подход. Вместо того, чтобы изменять сами ссылки, вы можете добавить код в HttpRequestPipeline, чтобы разрешить "Данные/Главная/Продукты/Продукт А" как "клон/Главная/Продукты/Продукт". Аналогичный подход описан в Повторное использование и совместное использование данных:
Пользователь CMS может использовать Редактор Rich Text Editor, свойства рендеринга или другие функции для ссылки на элемент на основе шаблона данных выбора элемента. Учтите эти условия в своем коде. Ты можешь настроить обработчик конвейера httpRequestBegin для обработки запросов HTTP для элементов [...]
Чтобы применить этот подход к вашему сценарию, добавьте пользовательскую реализацию HttpRequestProcessor после <processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel"/>
в конвейере HttpRequestBegin в web.config.
Здесь логика для реализации:
- Используйте
HttpContext.Current.Request.UrlReferrer
для определения ссылочного сайта. - Убедитесь, что ссылочный сайт находится в вашем списке клонированных сайтов.
- Проверьте, находится ли
Sitecore.Context.Item
на исходном сайте. - Создайте строку с новым путем и убедитесь, что этот элемент существует с помощью
Database.GetItem()
. - Измените Sitecore.Context.Item на новый элемент.
Преимущество такого подхода заключается в том, что вам не нужно перехватывать множество способов создания ссылки, и вы сохраняете свою логику перезаписи пути в одном месте. По сути, вы будете создавать псевдоним из "Data/Products/ProductA" для "clone/Home/ProductA", который будет действовать, только если ваш сайт находится в вашем списке клонов.
Обновление: Я проверил этот подход в Office Core. Я создал второй сайт, AlternalteSite, с дочерним node 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;
}
}
Update2: Как отмечает Джеймс Уолфорд в комментариях, этот подход работает только в том случае, если клоны не переименованы. Насколько мне известно, Sitecore предоставляет способ перехода от исходного элемента к его клонам в веб-базе данных. В мастере вы можете использовать базу данных ссылок, чтобы перейти от элемента к его клонов (см. этот пост форума от John Запад), но после публикации клоны становятся обычными элементами, поэтому, по-видимому, они не будут включены в базу данных ссылок.
Один из подходов заключался бы в том, чтобы добавить мультилиста ссылок к клонам в стандартный шаблон и добавить логику, чтобы заполнить это как часть конвейера uiCloneItems
, и использовать эти данные в коде HttpRequestProcessor. Это сохранит связь базы данных ссылок, но будет накладывать дополнительные накладные расходы как на процесс клонирования, так и на процесс разрешения запроса Http, так как вашему коду нужно будет перебирать все клоны, чтобы определить, какой из них живет на запрашивающем веб-сайте.