Umbraco 11 - Creating a Block Grid programmatically - Areas query

,

Hi All, I’m in the process of migrating some very large U7 sites into v11 (18k+ articles on this one) . I’ve taken the approach of starting from scratch, and exporting my old content as XML and importing it into a clean v11 install with some custom import scripts.

Generally it’s going very well and i’m making excellent progress, which is lovely.

I’ve got to the stage where I’m mapping my old DTGE content into the new Block Grid data type. I’ve managed to get everything from here working nicely:

However in my v11 setup I’d like to use areas going forwards, and force all my blocks to be inside layout areas (simply 6-6 and 12. However the documentation above includes this:

JsonProperty("areas")] // areas are omitted from this sample for abbreviation public object[] Areas { get; } = { };

Clearly this is what I need to implement, rather than adding my data to the root grid editor I need to add them to areas, but Im struggling to find any examples of this being done. Any pointers?

The layout is as follows:

So I’m looking to get my blocks inside those areas on import:

Currently they are just getting added into the root of the editor and outside of the areas.

Does that make sense? Many thanks in advance.


This is a companion discussion topic for the original entry at https://our.umbraco.com/forum/111014-umbraco-11-creating-a-block-grid-programmatically-areas-query

Hey All! - Umbraco v13

I managed to do this in Umbraco 13 programmatically if anyone is still wondering about this.

You will need to make sure you inject the ContentTypeService and DataTypeService

private readonly IDataTypeService _dataTypeService;
private readonly IContentTypeService _contentTypeService;

I am yet to put this into a service, but you can use this for the time being.

	var areaGuidKeyZero = GetAreaKeyGuidForLayout(BlockGridLayout_6_6_cols.ModelTypeAlias, "area_0");

Invoking the method passing in your BlockGrid alias, and the area label that you want.

In my case, I need the key for area_0.

		public string? GetAreaKeyGuidForLayout(string layoutAlias, string areaAlias)
		{
			var allContentTypes = _contentTypeService.GetAll();
			var layoutContentType = allContentTypes.FirstOrDefault(x => x.Alias == layoutAlias);
			if (layoutContentType == null)
			{
				Console.WriteLine($"Layout alias '{layoutAlias}' not found.");
				return null;
			}

			var layoutKey = layoutContentType.Key;
			var allBlockGridDataTypes = _dataTypeService.GetAll()
				.Where(dt => dt.EditorAlias == "Umbraco.BlockGrid");

			foreach (var dataType in allBlockGridDataTypes)
			{
				if (dataType.Configuration is not BlockGridConfiguration config)
					continue;

				foreach (var block in config.Blocks)
				{
					if (block.ContentElementTypeKey != layoutKey)
						continue;

					var area = block.Areas?.FirstOrDefault(a => a.Alias == areaAlias);
					if (area?.Key != null)
					{
						Console.WriteLine($"Match found in DataType '{dataType.Name}' (ID: {dataType.Id})");
						return area.Key.ToString();
					}
				}
			}

			Console.WriteLine($"No area with alias '{areaAlias}' found for layout '{layoutAlias}'.");
			return null;
		}

Then you can find the method here.

This will return the unique key you will need when creating your dynamic areas.

			var layoutItem = new BlockGridLayoutItemModel
			{
				ContentUdi = layoutUdi,
				ColumnSpan = 12,
				RowSpan = 1,
				Areas = new[]
					{
					new BlockGridLayoutAreaModel
					{
						Key = "afaecf29-bfd7-300d-ba04-8f8b3df5a751", // Area_0 Key
						Items = new[]
						{
							new BlockGridLayoutItemModel
							{
								ContentUdi = calcUdi,
								ColumnSpan = 6,
								RowSpan = 1,
								Areas = Array.Empty<BlockGridLayoutAreaModel>()
							}
						}
					},
					new BlockGridLayoutAreaModel
					{
						Key = "d28e8411-9172-3e63-a34d-513f7791e1ac", // Area_1 Key
						Items = new[]
						{
							new BlockGridLayoutItemModel
							{
								ContentUdi = videoUdi,
								ColumnSpan = 6,
								RowSpan = 1,
								Areas = Array.Empty<BlockGridLayoutAreaModel>()
							}
						}
					}
				}
			};

So in the above cove, I am creating my layout items, but I can replace the hardcoded GUIDS in each layout area with the method call.

So the final outcome would be

			var layoutItem = new BlockGridLayoutItemModel
			{
				ContentUdi = layoutUdi,
				ColumnSpan = 12,
				RowSpan = 1,
				Areas = new[]
					{
					new BlockGridLayoutAreaModel
					{
						Key = GetAreaKeyGuidForLayout(BlockGridLayout_6_6_cols.ModelTypeAlias, "area_0"), // Area_0 Key
						Items = new[]
						{
							new BlockGridLayoutItemModel
							{
								ContentUdi = calcUdi,
								ColumnSpan = 6,
								RowSpan = 1,
								Areas = Array.Empty<BlockGridLayoutAreaModel>()
							}
						}
					},
					new BlockGridLayoutAreaModel
					{
						Key = GetAreaKeyGuidForLayout(BlockGridLayout_6_6_cols.ModelTypeAlias, "area_1"), // Area_1 Key
						Items = new[]
						{
							new BlockGridLayoutItemModel
							{
								ContentUdi = videoUdi,
								ColumnSpan = 6,
								RowSpan = 1,
								Areas = Array.Empty<BlockGridLayoutAreaModel>()
							}
						}
					}
				}
			};

Of course this can be extended to return both the keys at once if you want. This is just a quick demonstration to solve the problem :slight_smile:

Hope this helps!