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 142 posts 487 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 199 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.

Please Sign in or register to post replies

Write your reply to:

Draft