I want to share content between multiple sites. So I set up a root node with no host name that will host the global lists. Then the sites that will show these lists are defined with their own root node. Like this:
Global lists
-News
+ News item 1
+ News item 2
-Calendar
+ Calendar item 1
Site 1 (site1.com)
-Some page with a list of news items embedded
-Another page
-A sub page with a list of news items embedded
Site 2 (site2.com)
-Some page with a list of news items embedded
I have managed to get the list and display the news items embedded in the pages I want and as expected the urls to the items are a relative url that does not exist in the site where the news items are embedded. As an example, url site1.com/news/news-item-1 is created but the page does not exist in site1.com. How can I do to accomplish that this link actually works in site1.com as well as in site2.com?
Is there a better solution to have many different common lists of data shared between sites which should render in the local site and not a link to another site?
I am not the most experienced when it comes to this setup but I see two ways that you could accomplish this.
Option 1 Custom Application Page
Create a page with no data for the News/Calendar in each site. Make the template pull in the contents using C# and Umbraco page queries. Sub pages would be accomplished by interrogating the URLs.
Option 2 Microsoft ARR
You might be able to tie the global lists section to a domain/port say localhost:8081 and use URL Rewrite + ARR to rewrite the site1.com/News to go to localhost:8081/news.
No one would be able to get directly to localhost except for on the server. Microsoft ARR would just reverse proxy traffic there. It is not a hard setup and does not require an IIS reboot. You just install, turn on the proxy and update the web.config.
ARR sounds complicated, but it isn't. Especially if you already understand the fundamentals of web.config and URL rewrite. It just allows you to URL rewrite outside of your app.
I thought of something like option 1 but I would prefer if I didn't have to create a page in each site for each list since what list is needed in each site will be chosen by the end user.
Option 2 was interesting, but then I loose the ability to render the content in the different sites layout since all would be rendered by the same site (global list site) and I want them to be rendered locally
For anyone else who finds this thread, I worked out a solution for this scenario which seems to work quite nicely.
Create an IContentFinder:
public class SharedContentFinder : IContentFinder
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
public SharedContentFinder(IUmbracoContextAccessor umbracoContextAccessor)
{
_umbracoContextAccessor = umbracoContextAccessor;
}
public Task<bool> TryFindContent(IPublishedRequestBuilder contentRequest)
{
var path = contentRequest.Uri.GetAbsolutePathDecoded();
if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext))
{
return Task.FromResult(false);
}
var sharedContent = umbracoContext.Content.GetByRoute(path);
if (sharedContent is null)
{
// If not found, let another IContentFinder in the collection try.
return Task.FromResult(false);
}
// If content is found, then render that node
contentRequest.SetPublishedContent(sharedContent);
return Task.FromResult(true);
}
}
Create an extension method for adding it to the builder:
public static class SharedContentBuilderExtensions
{
public static IUmbracoBuilder AddSharedContentFinder(this IUmbracoBuilder builder)
{
builder.ContentFinders().Append<SharedContentFinder>();
return builder;
}
}
Anywhere your views access the root node using something like this you will get errors as the chosen node is not a direct descendent of your root node:
HomePage rootNode = (Model.Root() as HomePage);
.. so you'll instead need to use something like this:
var domain = DomainService.GetByName(Context.Request.Host.Value);
HomePage rootNode = (Umbraco.Content(domain.RootContentId) as HomePage);
Urls for shared content in multi site setup
I want to share content between multiple sites. So I set up a root node with no host name that will host the global lists. Then the sites that will show these lists are defined with their own root node. Like this:
I have managed to get the list and display the news items embedded in the pages I want and as expected the urls to the items are a relative url that does not exist in the site where the news items are embedded. As an example, url site1.com/news/news-item-1 is created but the page does not exist in site1.com. How can I do to accomplish that this link actually works in site1.com as well as in site2.com?
Is there a better solution to have many different common lists of data shared between sites which should render in the local site and not a link to another site?
TIA
I am not the most experienced when it comes to this setup but I see two ways that you could accomplish this.
Option 1 Custom Application Page
Create a page with no data for the News/Calendar in each site. Make the template pull in the contents using C# and Umbraco page queries. Sub pages would be accomplished by interrogating the URLs.
Option 2 Microsoft ARR
You might be able to tie the global lists section to a domain/port say localhost:8081 and use URL Rewrite + ARR to rewrite the site1.com/News to go to localhost:8081/news.
No one would be able to get directly to localhost except for on the server. Microsoft ARR would just reverse proxy traffic there. It is not a hard setup and does not require an IIS reboot. You just install, turn on the proxy and update the web.config.
ARR sounds complicated, but it isn't. Especially if you already understand the fundamentals of web.config and URL rewrite. It just allows you to URL rewrite outside of your app.
Microsoft ARR documentation
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing
Thanks for your input E
I thought of something like option 1 but I would prefer if I didn't have to create a page in each site for each list since what list is needed in each site will be chosen by the end user.
Option 2 was interesting, but then I loose the ability to render the content in the different sites layout since all would be rendered by the same site (global list site) and I want them to be rendered locally
For anyone else who finds this thread, I worked out a solution for this scenario which seems to work quite nicely.
Create an IContentFinder:
Create an extension method for adding it to the builder:
Add it to your builder:
Anywhere your views access the root node using something like this you will get errors as the chosen node is not a direct descendent of your root node:
.. so you'll instead need to use something like this:
is working on a reply...