Copied to clipboard

Flag this post as spam?

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


  • Huw Reddick 495 posts 1467 karma points
    May 07, 2021 @ 09:23
    Huw Reddick
    0

    I don't know if what I am trying is possible, but here goes :)

    I have created a custom grid editor macro to display a submenu of child page which works great, however what I would like to be able to do is the following.

    If the content editor adds the custom macro content to a parent node, i would like to automatically add the same content macro to all the children of that node without the editor having to add it manually to all the child nodes.

    Does anyone know it this is possible, or will the content editor have to add them manually to all the child nodes?

  • Marc Goodson 1529 posts 10230 karma points MVP 6x c-trib
    May 08, 2021 @ 09:50
    Marc Goodson
    100

    Hi Huw

    Is the submenu always written out in a consistent location?

    If so, then I might instead have a checkbox on the Doc Type for the parent page called something like 'DisplaySubMenu'...

    ... and then in the template for the child pages, get a reference to the 'parent' node and read this value to determine whether to write out the Macro or not...

    Otherwise the grid stores the data and configuration in a single property value in JSON - so in theory, I mean in theory, you could read the JSON from that parent grid property, look for the existence of the macro, then get the JSON for the Child page, and decide based on the position in the parent grid, where to insert the macro within the child content grid JSON - and then render this merged JSON with the grid renderer file... but it might be a bit hard to understand from the editor perspective as to 'why' this is appearing on the child pages!

    Or

    You could have two grid properties, one for the specific page, and one for 'shared grid content', which would work if the shared content always needed to be rendered in the same position in the template, eg in it's own column or above or below the page grid content.

    Or

    if you want a single grid property, and editors to be able to choose on a page by page basis whether the Macro is inserted - then you could make it easy for editors to add the Sub Menu Macro or not by using Content Template blueprints.

    For the 'Child Type' you'd create two blueprint content templates, one with the SubMenu macro inserted into the grid and one without - then when editors created the Child Page, they'd have a choice over which template to start with...

    https://our.umbraco.com/Documentation/Getting-Started/Backoffice/Content-Templates/

    regards

    Marc

  • Huw Reddick 495 posts 1467 karma points
    May 08, 2021 @ 10:06
    Huw Reddick
    0

    Hi Marc,

    Thanks for the suggestions, I will have a play and see how I get on, I think my issue is basically understanding how to inject the macro automatically as the page is rendered using

    @Html.GetGridHtml(Model, "contentGrid", "Bootstrap3-Fluid")
    

    I assume I need to inject the macro into the JSON of the child pages in order for it to render there. WIll do some debugging and look at the JSON structure to see if I can figure it out :)

  • Marc Goodson 1529 posts 10230 karma points MVP 6x c-trib
    May 08, 2021 @ 14:23
    Marc Goodson
    0

    Hi Huw

    If you go with the 'DisplaySubMenu' Approach you can have

    @if (Model.Parent.Value<bool>("displaySubMenu")){
    Umbraco.RenderMacro("subNavMenu", new {someParameter="1233"})
    }
    

    Otherwise, if you are thinking of tackling the whole mangling around in JSON, and be cool to know what you find.

    I think the place you want to do your fooling around is in the 'PublishedRequest.Prepared' event:

    github.com/umbraco/Umbraco-CMS/blob/d428a4543f33bb7094cf7db5f6b6fdc2d1de3063/src/Umbraco.Web/Routing/PublishedRequest.cs#L101

    if you see the remarks:

    /// <remarks>When the event triggers, preparation is done ie domain, culture, document, template,
            /// rendering engine, etc. have been setup. It is then possible to change anything, before
            /// the request is actually processed and rendered by Umbraco.</remarks>
    

    Ther is documentation here, but not yet updated for V8:

    https://our.umbraco.com/documentation/reference/routing/request-pipeline/published-content-request-preparation

    I think basically you could mangle your model contentGrid property at this point, and then your GetGridHtml call would just work in the same way.

    Be interesting how you get on in practice! I expect the JSON to be very messy to mangle!

    regards

    Marc

  • Huw Reddick 495 posts 1467 karma points
    May 08, 2021 @ 15:26
    Huw Reddick
    0

    Hi Marc,

    I have no idea if this is the best way to do it, but it does what I need for the client :D

    In the Content template before the

    @Html.GetGridHtml(Model, "contentGrid", "Bootstrap3-Fluid")
    

    I did the following, bit of a hack but it works exactly as needed

    @{
        if (Model.Parent != null)
        {
            JObject parentGrid = Model.Parent.Value<JObject>("contentGrid");
            JArray controls = (JArray)parentGrid["sections"][1]["rows"][0]["areas"][0]["controls"];
    
            if ((string)controls[0]["value"]["macroAlias"] == "SideMenuMacro")
            {
                JArray test = (JArray)Model.Value<JObject>("contentGrid")["sections"][1]["rows"][0]["areas"][0]["controls"];
                test.Insert(0, controls.First);
            }
        }
    
    }
    
  • Huw Reddick 495 posts 1467 karma points
    May 08, 2021 @ 16:06
    Huw Reddick
    0

    couple of minor tweaks to stop it duplicating every time the page is refreshed :D

    if (Model.Parent != null)
    {
        JObject parentGrid = Model.Parent.Value<JObject>("contentGrid");
        if (parentGrid != null)
        {
            JObject thisGrid = Model.Value<JObject>("contentGrid");
    
            if ((string)thisGrid["sections"][1]["rows"][0]["areas"][0]["controls"][0]["value"]["macroAlias"] != "SideMenuMacro")
            {
                JArray controls = (JArray)parentGrid["sections"][1]["rows"][0]["areas"][0]["controls"];
                if ((string)controls[0]["value"]["macroAlias"] == "SideMenuMacro")
                {
                    JArray contentGrid = (JArray)Model.Value<JObject>("contentGrid")["sections"][1]["rows"][0]["areas"][0]["controls"];
                    contentGrid.Insert(0, controls.First);
                }
            }
        }
    }
    
  • Marc Goodson 1529 posts 10230 karma points MVP 6x c-trib
    May 08, 2021 @ 16:20
    Marc Goodson
    0

    Hi Huw

    I said the JSON might be messy :-P

    There is a package you can install that helps you work with grid elements in a more strongly typed way:

    https://github.com/skybrud/Skybrud.Umbraco.GridData

    (but it's good to get under the skin of the grid with JObject as you have done to get the understanding of how it works! - but sorry for not mentioning it earlier!)

    Anyway, 'I think' you could potentially do that 'fangling' of the JSON in the prepared event I mentioned above, or in a route hijacked MVC controller if you wanted to keep your views neater... but if it works... pragmatically that is the main thing!

    regards

    marc

  • Huw Reddick 495 posts 1467 karma points
    May 08, 2021 @ 16:37
    Huw Reddick
    0

    Will definitely look into that, thanks for pointing me in the right direction.

Please Sign in or register to post replies

Write your reply to:

Draft