Copied to clipboard

Flag this post as spam?

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


  • Martin Rud 232 posts 902 karma points c-trib
    Feb 16, 2021 @ 14:34
    Martin Rud
    0

    How to get node url in context of ContentService?

    Hi,

    I have this code:

    using System;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco.Core.Services.Implement;
    
    namespace Umbraco8.Components
    {
        [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
        public class SubscribeToPublishEventComposer : ComponentComposer<SubscribeToPublishEventComponent>
        { }
    
        public class SubscribeToPublishEventComponent : IComponent
        {
            public void Initialize()
            {
                ContentService.Publishing += ContentService_Publishing;
            }
    
            private void ContentService_Publishing(Umbraco.Core.Services.IContentService sender, Umbraco.Core.Events.ContentPublishingEventArgs e, RequestContext requestContext, UmbracoContext umbracoContext)
            {
                // From https://our.umbraco.com/documentation/reference/events/ContentService-Events
                foreach (var node in e.PublishedEntities)
                {
                    if (
                        node.ContentType.Alias == "siteNewsPage" || 
                        node.ContentType.Alias == "siteEvent"
                    )
                    {
                        string[] dateArray = node.GetValue<string>("date").Split('/');
                        node.SetValue("umbracoUrlAlias", dateArray[2].Substring(0, 4) + "/" + dateArray[1] + "/" + dateArray[0] + "/" + node.Url);
                    }
                }
            }
            public void Terminate()
            {
                //unsubscribe during shutdown
                 ContentService.Publishing -= ContentService_Publishing;
            }
        }
    }
    

    In this line I have an error ("node.Url" is not valid):

    node.SetValue("umbracoUrlAlias", dateArray[2].Substring(0, 4) + "/" + dateArray[1] + "/" + dateArray[0] + "/" + node.Url);
    

    How can I get the url of the node in this context? (I want to use only the last segment of the url, but that I can manage)

  • Malthe Petersen 68 posts 383 karma points c-trib
    Feb 16, 2021 @ 16:16
    Malthe Petersen
    0

    Hi Martin.

    If you need the whole URL I would suggest you listening to the CacheRefresher event instead of the ContentService events, as the IContent won't have the URL, only the UrlSegment for itself.

    UrlSegment would be: Node name: "About us" Url Segment: "about-us"

    But to me it seems more like you are trying to create a new URL for the content, is that right?

  • Martin Rud 232 posts 902 karma points c-trib
    Feb 16, 2021 @ 16:52
    Martin Rud
    0

    Yes, I want to create a new url for news and event items. Take a event with this url: domain.com/events/my-event with date = 2021-02-16

    I want umbracoUrlAlias to be "/events/2021-02-16/my-event". So I want to take the url (events/my-event) and split it by "/" so I get two segments ( (first, "events", and last, "my-event") and then put date in between.

    So what I need help for is to get the url ("events/my-event" - or "/events/my-event/")

  • Malthe Petersen 68 posts 383 karma points c-trib
    Feb 16, 2021 @ 18:13
    Malthe Petersen
    100

    I can see that you asked another question and one of the answers was to create a custom URL provider and content finder, I think that is the road you should be going.

    As far as I am concerned the IContent won’t contain the full URL, as it doesn’t know its ancestors per se, only the path and parent Id.

    You could though get the ancestors in the Content Service and then concatenate their URL segments to make an URL.

  • Thomas Kassos 54 posts 265 karma points
    Feb 16, 2021 @ 17:44
    Thomas Kassos
    0

    Hi Martin, You may be able to achieve that with the URL Provider https://our.umbraco.com/documentation/reference/routing/request-pipeline/outbound-pipeline

    About the code you posted I think you can have access to the umbraco helper and get the URL from there. https://our.umbraco.com/forum/umbraco-8/96270-using-umbracohelper-in-a-custom-class-in-v8#comment-304421

  • Thomas Kassos 54 posts 265 karma points
    Feb 16, 2021 @ 17:51
    Thomas Kassos
    0

    Oh btw try the published event, maybe the URL is null because it doesn't exist yet or you generate the URL based on the parent node and the name of the node you are saving

  • Martin Rud 232 posts 902 karma points c-trib
    Feb 16, 2021 @ 19:38
    Martin Rud
    0

    Thank you both. :) I tried looking into custom URL provider as suggested by Malthe. It is the most right way to do it - I knew, but thought it was very difficult. It wasn´t.

    I got it working with this (App_Code\dateRouting.cs):

    using Umbraco.Core.Models;
    using Umbraco.Core.Strings;
    
    namespace Umbraco8.Routing
    {
        public class DatePageUrlSegmentProvider : IUrlSegmentProvider
        {
    
                readonly IUrlSegmentProvider _provider = new DefaultUrlSegmentProvider();
    
                public string GetUrlSegment(IContentBase content, string culture = null)
                {
    
                    if (!(content.ContentType.Alias == "siteEvent" || content.ContentType.Alias == "siteNewsPage")) return null;
    
                    var segment = _provider.GetUrlSegment(content);
                    string[] dateArray = content.GetValue<string>("date").Split('/');
    
                    return string.Format("{1}-{0}", segment, dateArray[2].Substring(0, 4) + "-" + dateArray[1] + "-" + dateArray[0]);
                }
        }
    }
    

    And the registrating it (App_Code\registrateComposers.cs):

    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco8.Routing;
    
    namespace Umbraco8.Composers
    {
        public class RegisterCustomSegmentProviderComposer : IUserComposer
        {
            public void Compose(Composition composition)
            {
                composition.UrlSegmentProviders().Insert<DatePageUrlSegmentProvider>();
            }
        }
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft