Copied to clipboard

Flag this post as spam?

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


  • Kevin Meilander 82 posts 408 karma points c-trib
    Mar 05, 2021 @ 22:39
    Kevin Meilander
    0

    Fallback for the URL on MultiUrlPicker if language is not published

    I'm trying to setup my multi-lingual site so if my page doesn't have a published version for the language I'm in, it shows the English content.

    Since the language version has not been created yet, it doesn't have a URL so my plan was to link the user to the English URL rather than the translated one. If I select a page using a MultiUrlPicker and the language I'm in is published, it will work fine and return the correct link. However if the language for that page is not published, it will return "#"

    Is there a way to set the fallback logic on a MultiUrlPicker field so if the users language isn't published for the selected page, it returns the default language's URL rather than defaulting to "#"?

    I can't see an easy way to do it, but curious if any one else has came across this issue.

  • kalspih 8 posts 78 karma points
    Mar 07, 2021 @ 20:17
    kalspih
    0

    What languages do you have deo with besides English?

  • Kevin Meilander 82 posts 408 karma points c-trib
    Mar 08, 2021 @ 14:13
    Kevin Meilander
    0

    I've got 6 other languages, and English set as my site's default language.

  • Kevin Meilander 82 posts 408 karma points c-trib
    Mar 08, 2021 @ 17:18
    Kevin Meilander
    0

    It looks like this is also true for a IPublishedContent Url() property.

    It looks like I can specify the culture for the requested URL, but I can't set a fallback like I can for a Value().

    Do I just need to handle this myself and check if the language is published before getting the URL and if not get the English URL, or is there a way to have Umbraco do this step?

  • Kevin Meilander 82 posts 408 karma points c-trib
    Dec 10, 2021 @ 22:47
    Kevin Meilander
    0

    Posing my solution here (since I just searched for the same problem again and forgot I had solved it)

    I ended up overriding the DefaultUrlProvider and made a new GetUrl method that would do the fallback to the default language on the URL.

    Here is the code in v8:

        /// <summary>
        /// This overrides the Default URL provider so that if a page isn't published, the GetURL() will fallback and return the english URL instead of the default value of "#"
        /// This should work for all instances of Url() including PublishContent and MutltiNodeLinks
        /// </summary>
        public class UrlProviderWithFallbackLanguage : DefaultUrlProvider
        {
            private readonly ILocalizationService _localizationService;
    
            public UrlProviderWithFallbackLanguage(IRequestHandlerSection requestSettings, ILogger logger, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, ServiceContext serviceContext)
                :base(requestSettings, logger, globalSettings, siteDomainHelper)
            {
                _localizationService = serviceContext.LocalizationService;
            }
    
    
            public override UrlInfo GetUrl(UmbracoContext umbracoContext, IPublishedContent content, UrlMode mode, string culture, Uri current)
            {
                var urlInfo = base.GetUrl(umbracoContext, content, mode, culture, current);
                //If we return null, fallback to the default langauge 
                if(urlInfo == null)
                {
                    var defaultLanguageCode = _localizationService.GetDefaultLanguageIsoCode();
                    urlInfo = base.GetUrl(umbracoContext, content, mode, defaultLanguageCode, current);
                }
                return urlInfo;
            }
    

    And then register class this in the compositions so the site will use it.

      composition.UrlProviders().Append<UrlProviderWithFallbackLanguage>();
    

    Or, if you're using v9, here is the class:

    /// <summary>
    /// This overrides the default fall back logic of the GetValue() calls to fallback to langauge by default.  (Umbraco v9)
    /// </summary>
    public class UrlProviderWithFallbackLanguage : DefaultUrlProvider
    {
        private readonly ILocalizationService _localizationService;
    
        public UrlProviderWithFallbackLanguage(ILocalizationService localizationService, IOptions<RequestHandlerSettings> requestSettings, ILogger<DefaultUrlProvider> logger, ISiteDomainMapper siteDomainMapper, IUmbracoContextAccessor umbracoContextAccessor, UriUtility uriUtility)
            : base(requestSettings, logger, siteDomainMapper, umbracoContextAccessor, uriUtility)
        {
            _localizationService = localizationService;
        }
    
        public override UrlInfo GetUrl(IPublishedContent content, UrlMode mode, string culture, Uri current)
        {
            var urlInfo = base.GetUrl(content, mode, culture, current);
            //If we return null, fallback to the default langauge 
            if (urlInfo == null)
            {
                var defaultLanguageCode = _localizationService.GetDefaultLanguageIsoCode();
                urlInfo = base.GetUrl(content, mode, defaultLanguageCode, current);
            }
            return urlInfo;
        }
    }
    

    Another update I made for my translated site, I also updated the fallback logic for my GetValue() method, so the modal builder would fallback each field to the default language if not set. This is a slightly different problem, but I figured I could add my code here just in case anyone finds it helpful.

    /// <summary>
    /// This overrides the default fall back logic of the GetValue() calls to fallback to langauge by default.  (Umbraco v8)
    /// </summary>
     public class CustomPublishedValueFallback : PublishedValueFallback
    {
        public CustomPublishedValueFallback(ServiceContext serviceContext, IVariationContextAccessor variationContextAccessor)
            : base(serviceContext, variationContextAccessor)
        {
    
        }
    
        public override bool TryGetValue<T>(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value, out IPublishedProperty noValueProperty)
        {
            //When no fallback, use ToLanguage by default
            if (!fallback.Any(f => f == Fallback.DefaultValue || f == Fallback.Language || f == Fallback.Ancestors))
            {
                fallback = Fallback.ToLanguage;
            }
    
            return base.TryGetValue(content, alias, culture, segment, fallback, defaultValue, out value, out noValueProperty);
        }
    }
    

    And then register class this in the compositions so the site will use it.

      composition.RegisterUnique<IPublishedValueFallback, CustomPublishedValueFallback>();
    
  • Mikael Axel Kleinwort 154 posts 499 karma points c-trib
    Mar 05, 2022 @ 17:36
    Mikael Axel Kleinwort
    0

    Hi Kevin,

    I am having exactly the same issue in V8, so I am happy to see your solution here.

    Are you sure what you posted for v8 is correct? YOur text mentions you override default DefaultUrlProvider and create a new GetUrl() method, however, your v8 code looks like something else.

    So this code of yours

    composition.UrlProviders().Append<UrlProviderWithFallbackLanguage>();
    

    doesn't seem to do anything with your v8 code.

    Any input appreciated! Thank you!

  • Kevin Meilander 82 posts 408 karma points c-trib
    Mar 07, 2022 @ 14:04
    Kevin Meilander
    0

    Hi Mikael,

    You're right, I had copied the wrong code in to my answer for my v8 solution. That code was overriding the GetValue() method so my Modals builder would use the language fallback logic.

    I updated my post above with the right code, which will override the DefaultUrlProvider to add some fallback logic.

    Hopefully that makes more sense now.

  • Wojciech Tengler 96 posts 202 karma points
    Jan 18, 2024 @ 16:36
    Wojciech Tengler
    1

    Hi,

    We recently encountered the same problem.

    Finally, we implemented a CustomUrlProvider with a little bit more logic respecting a fallback language.

    We also decided to respect if the main content is provided for published language variant.

    You can find an explanation and solution in the article: Problem with linking in Umbraco across pages in different cultures.

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies