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 190 posts 548 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 190 posts 548 karma points
    Mar 28, 2019 @ 14:02
    Niels Lynggaard
    0

    Thanx, Chris!

    I'll give your approach a good try tomorrow.

    /Niels

  • Niels Lynggaard 190 posts 548 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 190 posts 548 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 190 posts 548 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! :)

Please Sign in or register to post replies

Write your reply to:

Draft