Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Mårten 2 posts 73 karma points
    Nov 02, 2022 @ 12:30
    Mårten
    1

    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:

    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?

    TIA

  • E 3 posts 73 karma points
    Nov 02, 2022 @ 13:27
    E
    0

    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

  • Mårten 2 posts 73 karma points
    Nov 02, 2022 @ 14:03
    Mårten
    0

    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

  • Phil 9 posts 110 karma points
    Jun 07, 2024 @ 09:16
    Phil
    0

    For anyone else who finds this thread, I worked out a solution for this scenario which seems to work quite nicely.

    1. 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);
      }
      
      }
    2. 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;
          }
      }
      
    3. Add it to your builder:

      builder.CreateUmbracoBuilder()
          .AddBackOffice()
          .AddWebsite()
          .AddDeliveryApi()
          .AddComposers()
          .AddSharedContentFinder()
          .Build();
      
    4. 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);
    
Please Sign in or register to post replies

Write your reply to:

Draft