Copied to clipboard

Flag this post as spam?

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


  • Niels Lynggaard 193 posts 551 karma points
    Mar 28, 2019 @ 08:54
    Niels Lynggaard
    0

    Programatically add content to Grid

    Hi Guys!

    I am implementing an import of content from an old website to a new implementation in Umbraco 7,

    The nodes that I will be creating contains a grid and I was hoping to be able to populate this grid with a few richtext and image editors programatically.

    What is the best approach to adding rows & editors to the grid, programatically?

    Alternatively I'll just have to put all the content into a "normal" RTE-property, but I would very much prefer to be able to add content to the grid?

    How can this be done?

    Thanx, Niels

  • Chris Norwood 131 posts 642 karma points
    Mar 28, 2019 @ 09:11
    Chris Norwood
    100

    Hi Niels,

    I've actually recently had to do this myself - my code is probably not the "best" way of doing it, but here's a sample (this was in Umbraco 7.14.0).

    First, the classes I serialized the JSON for the grid to:

        //we need to return something like this:
            //the hierarchy is:
            //grid
            //  sections
            //      rows
            //          areas
            /*
        "{
          ""name"": ""1 column layout"",
          ""sections"": [
            {
              ""grid"": 12,
              ""rows"": [
                {
                  ""name"": ""Headline"",
                  ""areas"": [
                    {
                      ""grid"": 12,
                      ""controls"": [
                        {
                          ""value"": """ + escapedQuotes + @""",
                          ""editor"": { ""alias"": ""rte"" }
                        }
                      ]
                    }
                  ],
                  ""id"": ""9feb0fd9-513d-9a92-6d15-c78c242a3cf2""
                }
              ]
            }
          ]
        }";*/
    
            public class GridEditor
            {
                public string alias { get; set; }
            }
            public class GridControl
            {
                public GridEditor editor { get; set; }
                public string value { get; set; }
            }
    
            public class GridConfig
            {
                public string Class { get; set; }
            }
    
            public class GridArea
            {
                public int grid { get; set; }
                public GridConfig config { get; set; }
                public List<GridControl> controls { get; set; }
            }
    
            public class GridRow
            {
                public string name { get; set; }
                public List<GridArea> areas { get; set; }
                public string id { get; set; }
            }
    
            public class GridSection
            {
                public int grid { get; set; }
                public List<GridRow> rows { get; set; }
            }
    
            public class GridContent
            {
                public string name { get; set; }
                public List<GridSection> sections { get; set; }
    
            }
    

    //examples of how I used them to populate the grid - writer is a StreamWriter but you could just use Umbraco's own logger.

    var gridContent = new GridContent
                {
                    name = "1 Column layout",
                    sections = new List<GridSection>()
                };
    
    gridContent.sections.Add(
                        new GridSection()
                        {
                            grid = 12,
                            rows = new List<GridRow>()
                        }
                    );
    
    
    var newRow = GetGridRowFromContent(div, writer);
    
                            if (newRow != null)
                            {
                                gridContent.sections[0].rows.Add(newRow);
                            }
    
    //GetGridRowFromContent is a separate method, but you will need to implement it based on your content - here's my implementation:
    private static GridRow GetGridRowFromContent(HtmlNode topNode, StreamWriter writer)
            {
                try
                {
                    var colSize = MatrixConversionHelper.GetColumnName("100");
                    var newGridRow = new GridRow()
                    {
                        name = colSize,
                        areas = new List<GridArea>(),
                        id = Guid.NewGuid().ToString()
                    };
    
                    var newArea = new GridArea()
                    {
                        grid = MatrixConversionHelper.GetColumns(100),
                        config = new GridConfig { Class = "h-100" },
                        controls = new List<GridControl>()
                    };
    
    
                    newArea.controls.Add(new GridControl
                    {
                        editor = new GridEditor { alias = "rte" },
                        value = topNode.OuterHtml.Trim()
                    });
                    newGridRow.areas.Add(newArea);
    
                    return newGridRow;
                }
                catch (Exception ex)
                {
                    writer.Write("Could not create a row object with error: {0}", ex.Message);
                }
                return null;
            }
        //newContent is an instance of IContent retrieved or created via the ContentService.
        var jsonGridContent = JObject.FromObject(gridContent);
        newContent.SetValue("contentGrid", jsonGridContent.ToString());
    
  • Vasyl Kurtyanik 6 posts 26 karma points
    Oct 08, 2020 @ 11:15
    Vasyl Kurtyanik
    0

    MatrixConversionHelper - what is it?

  • Chris Norwood 131 posts 642 karma points
    Oct 08, 2020 @ 14:05
    Chris Norwood
    0

    Hi Vasyl,

    It was a class that I created for this specific import - it just calculated the required column name based on the width of the incoming content, but as per my comment in the code you'd need your own implementation - this was designed to handle HTML in a very specific format.

    The column names in question are the ones you define when setting up the Grid Component in the back office in Umbraco - so in this case it might return something like "Single Column".

    Hope that helps! :)

    Chris.

  • Niels Lynggaard 193 posts 551 karma points
    Mar 28, 2019 @ 14:02
    Niels Lynggaard
    0

    Thanx, Chris!

    I'll give your approach a good try tomorrow.

    /Niels

  • Niels Lynggaard 193 posts 551 karma points
    Apr 04, 2019 @ 07:30
    Niels Lynggaard
    0

    Yeah! It works great!

    I'm having a bit of trouble inserting MediaEditor this way, since Value of GridControl is of type "string", so it escapes the json of the object that I'm creating;

    public class MediaItem
    {
    
        public int id;
        public FocalPoint focalpoint;
        public string udi;
        public string image;
        public string altText;
    }
    public class FocalPoint
    {
        public double left;
        public double top;
    }
    

    So, when I do this;

    MediaItem newmediaeditor = new MediaItem();
                        FocalPoint fp = new FocalPoint();
                        fp.left = 0.5;
                        fp.top = 0.5;
                        newmediaeditor.focalpoint = fp;
                        newmediaeditor.image = m.Url;
                        newmediaeditor.id = mediaId;
                        newmediaeditor.udi = "umb://"+m.GetKey().ToString();
                        newArea.controls.Add(new GridControl
                        {
                            editor = new GridEditor { alias = "media" },
                            value = JObject.FromObject(newmediaeditor).ToString(Newtonsoft.Json.Formatting.None)
                             });
                        newGridRow.areas.Add(newArea);
    

    It inserts a media editor in the grid, but the value (string) is escaping all the quotes, thus not working correctly;

    {
          "label": "Fuld bredde",
          "name": "Fuld bredde",
          "areas": [
            {
              "grid": 12,
              "config": {
                "Class": null
              },
              "hasConfig": true,
              "controls": [
                {
                  "editor": {
                    "name": "Image",
                    "alias": "media",
                    "view": "media",
                    "render": null,
                    "icon": "icon-picture",
                    "config": {}
                  },
                  "value": "{\"id\":1349,\"focalpoint\":{\"left\":0.5,\"top\":0.5},\"udi\":\"umb://ef628051-95bc-4632-ad34-a770254340a0\",\"image\":\"/media/1043/boern-fra-indien-trail-700.jpg\",\"altText\":null}"
                }
              ]
            }
          ],
          "hasConfig": false,
          "id": "05832d5a-155c-45d5-9fdd-a4c6686c1d5b"
        }
    

    Any idea what type value can be for MediaEditor?

  • Niels Lynggaard 193 posts 551 karma points
    Apr 04, 2019 @ 07:32
    Niels Lynggaard
    0

    E.g I need to be able to add a GridControl with a value that is not string or somehow cause the value to not escape the json string... Hmm..

  • Niels Lynggaard 193 posts 551 karma points
    Apr 04, 2019 @ 07:45
    Niels Lynggaard
    0

    Nevermind

    I just changed the type on GridControl.Value from string to object. :)

    Cheers and THANX Chris!

    h5yr!

    /Niels

  • Chris Norwood 131 posts 642 karma points
    Apr 04, 2019 @ 07:59
    Chris Norwood
    0

    Excellent - really glad it helped you! I was lucky as I only had RTEs to insert into my grids, but I'll amend my code for future use as it may well be useful if I have to go through this process again, so #h5yr too! :)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies