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 261 posts 1022 karma points c-trib
    Mar 21, 2022 @ 13:21
    Martin Rud
    0

    How to set node property value and publish node from view?

    Hi forum,

    I have, with no luck, tried to find code examples on how to set a property value on a node and publish the node from a view.

    Something like:

        @using Umbraco.Cms.Web.Common.PublishedModels;
        @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
        @{
            Layout = null;
    
            IPublishedContent node = Umbraco.Content(1234);
            node.SetValue("propertyName", "new value");
            ....
    
            }   
        }
    

    How can this be done?

  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 21, 2022 @ 14:37
    Nik
    0

    Hey Martin,

    The answer is "yes it can be done", the real question though is should it be done.

    Could you provide more details on what you are actually wanting to achieve?

    Generally we don't want to be messing around with content in Views, instead controllers to handle form submissions etc is a better option.

    This is because every single time that page with that view gets loaded it will have to hit the database to a) retrieve content, and b) save it. Then it needs to update the cache, which means the content being shown on the page in question would be out of date as the value has now changed, but the front end has already pulled the content from the cache.

    Thanks

    Nik

  • Martin Rud 261 posts 1022 karma points c-trib
    Mar 21, 2022 @ 14:50
    Martin Rud
    0

    Thanks - good points. I haven´t made controllers yet so therefore I just by 'reflex' went with the view solution. But I would of course much rather do it the right way, the controller way.

    The background is: I have made a website (slide show) that will be shown on TV screens in shops etc. Its a Rasperry Pi that runs a browser with the url of the slide show. In Umbraco there is a node where the editor can tick a true/false property "Reload screen now".

    Every 10 s the website should check if it must reload and therefore my thought was letting the slide show page check domain.com/?altTemplate=reloadCheck and in that template check if property 'reloadScreen' is true og false. If true some JavaScript reloads the screen AND then the 'reloadScreen' property must be update to 'False' again so the screen won´t reload on and on.

    How would you do this with a controller?

  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 21, 2022 @ 15:00
    Nik
    0

    Hey Martin,

    If I was going to approach this this task I'd break the task out in to two parts.

    1. The checking process - I would create an API controller that accepts the current node key as a parameter. This could then be called by JS and it would pull the page from the cache to see if it needs to be reloaded.

    2. If the page is reloaded as a result of the API check, I'd append a Query String parameter to the URL, something like ?reload=true. Then I'd have 2 possible ways of handling this.

      a. Have a RenderController intercept the request and reset the property using the content service

      b. Have a second API end point that is "reset-reload-check" that is called by JS on page load before the other polling requests start that resets the property.

    On a related note, in order to set the values you need to use the IContentService, not the Umbraco.Content points. IPublishedContent objects won't persist back to the database, but IContent items will (you can't cast between the two)

    Thanks

    Nik

  • Martin Rud 261 posts 1022 karma points c-trib
    Mar 21, 2022 @ 18:20
    Martin Rud
    0

    Thanks. I have no come 25% or so of the way. But I am stuck where I now need to get the content node:

    using System.Collections.Generic;
    using Umbraco.Cms.Web.Common.Controllers;
    
    namespace MrWebApi.Controllers
    {
        public class ReloadController : UmbracoApiController
        {
            public Dictionary<string, string> Status()
            {  
    
                // Get content node by guid and retrieve value of property 'reloadScreen':
                ... what to do here....?    
    
                // Return json
                Dictionary<string, string> status = new Dictionary<string, string>();
    
                status.Add("status", "true");  // For now status is always 'true'
                return status;
            }
        }
    }
    
  • Nik 1617 posts 7263 karma points MVP 7x c-trib
    Mar 21, 2022 @ 22:20
    Nik
    0
    namespace MrWebApi.Controllers
    {
        public class ReloadController : UmbracoApiController
        {
            public object Status(Guid pageKey)
            {  
                 var page = Umbraco.Content(pageKey);
    
                 var refresh = page != null && page.Value<bool>("reloadScreen");
    
    
                 return new { refresh: refresh};
                 // This should return a json object with a property called "refresh" and a value of either true/false.
            }
    
            public object ClearRefresh(Guid pageKey)
            {
                try
                {
                      var contentNode = Services.Content.GetById(pageKey);
    
                      contentNode.SetValue("reloadScreen", false);
                      Services.Content.Save(contentNode);
    
                      return true;
                }
                catch(Exception ex)
                {
                      Logger.Error(GetType(), ex, "Error clearing refresh indicator");
                }
    
                return false;
            }
        }
    }
    

    Very loosely, something like this should do the job for you :-)

  • Martin Rud 261 posts 1022 karma points c-trib
    Mar 22, 2022 @ 06:07
    Martin Rud
    0

    Thanks :)

    VS gives error to both Umbraco.Content(pageKey) ('Umbraco' does not exist in the namespace) and Services.Content.GetById (The name 'Services' does not exist in the current context).

    I have tried a lot using statements, scrolled through 100's of fixed suggested by VS and Googled a lot with no luck. Could it be that your example code is not v9 compatible?

  • Damien Holley 180 posts 541 karma points
    Oct 05, 2022 @ 23:40
    Damien Holley
    0

    You will have to inject the service into the controller constructor to get the Content cache lookup.

    IServices etc.

Please Sign in or register to post replies

Write your reply to:

Draft