Get “linked” product url

Imagine a scenario where you have a main catalog containing all your products and several “sub” catalogs with products linked from the main catalog.
When you do a search for a product in the sub catalog and you would want to get the link to a product, you would get the link to the product within the main catalog, as the main product is the only one in the index.

With the help of a reference to the catalog you are currently in, you can construct the correct link to the linked product in the sub catalog like this:

public void GetProductUrl(ProductContent product, ContentReference catalogLink, out string path)
{
	path = product.RouteSegment;

	ContentReference parentLink = product.ParentLink;

	if (catalogLink.CompareToIgnoreWorkID(contentReference: parentLink))
	{
		return;
	}

	ContentReference contentLink = product.ContentLink;
	int objectId = this.referenceConverter.GetObjectId(contentLink: catalogLink);

	NodeContent content;
	while (this.contentLoader.TryGet(contentLink: parentLink, content: out content))
	{
		if (content.CatalogId != objectId)
		{
			NodeContent linkedParentNode = this.GetLinkedParentNode(
				contentLink: contentLink,
				catalogLink: catalogLink);
				
			if (linkedParentNode == null)
			{
				return;
			}

			content = linkedParentNode;
			contentLink = linkedParentNode.ContentLink;
		}

		path = content.RouteSegment + "/" + path;
		parentLink = content.ParentLink;

		if (this.referenceConverter.GetContentType(contentLink: parentLink) == CatalogContentType.Catalog)
		{
			break;
		}
	}
}

private NodeContent GetLinkedParentNode(ContentReference contentLink, ContentReference catalogLink)
{
	List<ContentReference> source = this.relationRepository.GetParents<NodeRelation>(childLink: contentLink)
		.Where(r => r.TargetCatalog.CompareToIgnoreWorkID(contentReference: catalogLink)).Select(r => r.Parent)
		.ToList();

	if (!source.Any())
	{
		return null;
	}

	LoaderOptions settings =
		new LoaderOptions { new LanguageLoaderOption { Language = ContentLanguage.PreferredCulture } };

	return this.contentLoader.GetItems(contentLinks: source, settings: settings).OfType<NodeContent>()
		.FirstOrDefault();
}

It’s just a small “trick”, but can be useful in certain scenarios. You can also find the code in a gist

Leave a comment