Copied to clipboard

Flag this post as spam?

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


  • _R 13 posts 143 karma points
    Apr 18, 2023 @ 12:47
    _R
    0

    Currently I am using Umbraco 10 and my goal is to access umbracoNode entity within the existing Umbraco API. From the source in GitHub I do not see any service which does access this entity while it's very important for our team to build a website via the migration composer.

    The primary goal is to generate documentTypes which are added underneath a specific Document Types path: -Document Types (can be extracted via the tree service) -Components (stored in umbracoNodes which refs from cmsContentType) -My auto generated path (added and extracted via source)

    Folders are added as umbracoNode when applying it by hand. Or am I missing something since I am new to Umbraco?

    Soo, in a nutshell: I want to add and control folder path via source (Umbraco API) in order to add my custom components inside this folder.

  • Keith 74 posts 240 karma points
    Apr 18, 2023 @ 13:15
    Keith
    0

    Hi,

    If you want to create content nodes programatically, you need the content service:

    https://docs.umbraco.com/umbraco-cms/reference/management/services/contentservice/create-content-programmatically

    You work with instances of IContent, not umbracoNode. In the example above, they have a hardcoded parent id, but you could get that using the content service too with something like this:

            var parentContent = contentService.GetRootContent().FirstOrDefault(content => content.Name == "The Parent Node");
            var newContent = contentService.Create("New of new node", parentContent.Id, "childNodeContentType");
    
  • _R 13 posts 143 karma points
    Apr 18, 2023 @ 13:39
    _R
    0

    Thanks for the fast response. When I use that contentService and ask for root nodes I only get the Content nodes and not the Settings Component nodes which are stored in the umbracoNodes table. When applying the request myself, I see that it is calling the mediaTypeService as described here: https://github.com/umbraco/Umbraco-CMS/blob/33adbf41fa1f5c5d0759c70a7116114107addf56/src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs

    Is this also a good solution or should I still follow your solution. In the second case I am missing some info since I only retrieve Content Nodes and not from settings.

  • Keith 74 posts 240 karma points
    Apr 18, 2023 @ 13:53
    Keith
    0

    You can work with contentTypes programatically too. To do that, you would use the contentType service, like you mention above.

    https://docs.umbraco.com/umbraco-cms/reference/management/services/contenttypeservice

    But this depends on what you need to do. The "content types", "data types", "media types" etc in the "Settings" section are like the schema of your data. The nodes in the "Content" section are like the data records themselves.

    Do you need to programatically generete the schema for your data? If so, youll need ot use the content type service to create new content types. I have never done this, so I cant help unfortunately. If not, then the content service is the right way to go... use it to create content in the "Content" section.

  • _R 13 posts 143 karma points
    Apr 19, 2023 @ 07:09
    _R
    0

    Thanks for your reply Keith,

    You say that 'settings are like the schema of your data'. The folders in the settings section are stored in the database as configuration as 'unmbracoNode'. The content in de settings section the same but have a DB reference to 'cmsContent'. Since the Umbraco API does not provided some sort of node service for settings, I simulated a folder create request via the CMS towards my local instance. From there I see that this request is:

    //localhost:44328/umbraco/backoffice/umbracoapi/contenttype/PostCreateContainer?parentId=32911&name=Newly added folder by code
    

    The requested controller makes use of the 'MediaTypeService'. Therefor I implemented and simulated this myself in an Umbraco migration like this:

    var addedMediaType = _mediaTypeService.CreateContainer(
                32911,
                Guid.NewGuid(),
                "Newly added folder by code",
                -1);
    

    Somehow this does not work while it should be. I'm almost there but can not figure out why. The returned object has an error message which tells me that the parent container does not exist while this parent truly exists in the database. Do you have any clue about this? Any suggestion would by very nice.

  • _R 13 posts 143 karma points
    Apr 19, 2023 @ 08:27
    _R
    100

    I found the solution and actually it was simple which is almost always the case :-)

    I did not looked well into the API docs and services in GitHub. De path from which the front end requests was 'contenttype' and not 'mediaType'. The correct Controller uses the ContentTypeService and from there I can access the CreateContainer method.

    Soo the solution is as follows for everybody who wants to create folders underneath a specific parent node:

       var nodeNew = _contentTypeService.CreateContainer(
                parentContainer.Id,
                Guid.NewGuid(),
                "Newly added folder by code",
                -1);
    
  • Keith 74 posts 240 karma points
    Apr 19, 2023 @ 08:33
    Keith
    0

    Hi,

    I am still not clear on what you are trying to achieve though. I understand you are programatically adding nodes into the settings tree, but it is not clear to me why you are doing this.

    When migrating a site to umbraco, you would manually create the content types, like "news article", "blog post", "campaign page" etc etc.., then programatically create the actual content of the site in the content section.

    By programatically creating document types, you are programatically creating the schema of the site, the definition of the content nodes that are allowed be created and what properties they are allowed have. I am not sure this will achieve your goal.

  • _R 13 posts 143 karma points
    Apr 19, 2023 @ 08:47
    _R
    0

    The reason why I want to do this is because, first of all I want to organize my custom components and nested content in a way that it must be clear for our customers which ones are ours and which ones are default Umbraco/uSkinned.

    Now, those custom components are created by us, not by customer. For our multi environment we need to generate these custom components programmatically and lucky us, not by hand for every new instance;-)

    Next we are using uSkinned as a great addition to our Umbraco. Therefor we get additional components and also additional customized uSkinned components with nested content etc...

    Does this answer your question enough?

  • Keith 74 posts 240 karma points
    Apr 19, 2023 @ 10:04
    Keith
    0

    OK

    I'll stop asking questions :)

    If you have found a solution, thats the important thing.

    But Ill just say one more thing though. We have multiple instances of our site running too. We use uSync to deploy all of our document types when we launch a new instance. The steps are:

    • Create the document types manually once, locally in the umbraco UI
    • Export as XML using uSync
    • Commit the XML to the repository
    • Configure the live instances to import the XML on startup

    Then whenever you create a new document type or make changes to the document types, all instance of the site pick them up automatically from the repo.

  • Keith 74 posts 240 karma points
    Apr 18, 2023 @ 13:19
    Keith
    0

    I was migrating data from a custom built site to Umbraco and exposed a rest API for this kind of thing:

        [HttpPost]
        public ActionResult<GetContentModel> Post([FromBody] PostContentModel model)
        {
            var newContent = contentService.Create(model.Name, model.ParentId, model.ContentTypeAlias);
    
            if (model.Properties != null)
            {
                foreach (var property in model.Properties)
                {
                    if (newContent.HasProperty(property.Key))
                    {
                        var valueAsUdi = ValueAsUdi(property.Value);
                        if (valueAsUdi != null)
                        {
                            newContent.SetValue(property.Key, valueAsUdi);
                        }
                        else
                        {
                            newContent.SetValue(property.Key, property.Value);
                        }
                    }
                }
            }
    
            if (model.Publish)
            {
                contentService.SaveAndPublish(newContent);
            }
            else
            {
                contentService.Save(newContent);
            }
    
            return Ok(new { Id = newContent.Id });
        }
    

    and my post payload is this:

    public class PostContentModel
    {
        public int ParentId { get; set; }
        public string ContentTypeAlias { get; set; }
        public string Name { get; set; }
        public IDictionary<string, object> Properties { get; set; }
        public bool Publish { get; set; }
    }
    

    So that meant that an external system could pull data from the old besopoke database and insert umbraco nodes, without having to pollute the umbraco solution with lots of migration business logic

Please Sign in or register to post replies

Write your reply to:

Draft