Last active
July 26, 2024 05:58
-
-
Save DanDiplo/1e8e4dcd93bcc29115ef16c62e3d090a to your computer and use it in GitHub Desktop.
Create Blocklist JSON programmatically in Umbraco
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Helper service for creating JSON necessary for creating block list items programatically using Umbraco <see cref="ContentService"/> | |
/// </summary> | |
/// <remarks> | |
/// Based of this: https://github.com/umbraco/UmbracoDocs/blob/e64ec0e5b28b4e5a37b7865691621e45dd82701f/Getting-Started/Backoffice/Property-Editors/Built-in-Property-Editors/Block-List-Editor/index.md | |
/// It's intended for simple content | |
/// </remarks> | |
public class BlockListCreatorService | |
{ | |
/// <summary> | |
/// Creates the Block List JSON from the passed in collection of items. Each item needs to have the <see cref="JsonPropertyAttribute"/> that corresponds to the property alias of the element doc type it is based on | |
/// </summary> | |
/// <typeparam name="T">The type of your item</typeparam> | |
/// <param name="items">The collection of items to create</param> | |
/// <param name="contentTypeKey">The GUID for the element type (tip: you can look this up in God Mode!)</param> | |
/// <param name="settingsData">Optional settings data - defaults to empty settings</param> | |
/// <returns>JSON suitable for Block List</returns> | |
/// <exception cref="ArgumentNullException">Raised if items are null</exception> | |
public string GetBlockListJsonFor<T>(IEnumerable<T> items, Guid contentTypeKey, List<Dictionary<string, string>> settingsData = null) where T : class | |
{ | |
if (items == null) | |
{ | |
throw new ArgumentNullException(nameof(items)); | |
} | |
Blocklist blocklistNew = new Blocklist(); //initialize our new empty model to mimic proper JSON structure | |
var contentList = new List<Dictionary<string, string>>(); //initialize empty list where we will add our content items | |
var dictionaryUdi = new List<Dictionary<string, string>>(); // this contains content UDIs | |
foreach (var item in items) | |
{ | |
var udi = new GuidUdi("element", Guid.NewGuid()).ToString(); | |
PropertyInfo[] props = item.GetType().GetProperties(); | |
var propertyValues = new Dictionary<string, string>() | |
{ | |
{ "contentTypeKey", contentTypeKey.ToString() }, | |
{ "udi", udi.ToString() } | |
}; | |
foreach (PropertyInfo prop in props) | |
{ | |
object[] attrs = prop.GetCustomAttributes(true); | |
foreach (object attr in attrs) | |
{ | |
if (attr is JsonPropertyAttribute attribute) | |
{ | |
propertyValues.Add(attribute.PropertyName, prop.GetValue(item)?.ToString() ?? string.Empty); | |
} | |
} | |
} | |
contentList.Add(propertyValues); | |
dictionaryUdi.Add(new Dictionary<string, string> { { "contentUdi", udi } }); | |
} | |
blocklistNew.Layout = new BlockListUdi(dictionaryUdi); | |
blocklistNew.ContentData = contentList; //contentData is a list of our object | |
blocklistNew.SettingsData = settingsData ?? new List<Dictionary<string, string>>(); | |
return JsonConvert.SerializeObject(blocklistNew); | |
} | |
internal class Blocklist //this class is to mock the correct JSON structure when the object is serialized | |
{ | |
[JsonProperty("layout")] | |
public BlockListUdi Layout { get; set; } | |
[JsonProperty("contentData")] | |
public List<Dictionary<string, string>> ContentData { get; set; } | |
[JsonProperty("settingsData")] | |
public List<Dictionary<string, string>> SettingsData { get; set; } | |
} | |
internal class BlockListUdi //this is a subclass which corresponds to the "Umbraco.BlockList" section in JSON | |
{ | |
[JsonProperty("Umbraco.BlockList")] //we mock the Umbraco.BlockList name with JsonPropertyAttribute to match the requested JSON structure | |
public List<Dictionary<string, string>> ContentUdi { get; set; } | |
public BlockListUdi(List<Dictionary<string, string>> items) | |
{ | |
this.ContentUdi = items; | |
} | |
} | |
} | |
// Below is an example class that represents a Block List item. It's for a block list of Location items. | |
// The [JsonProperty] for each item should correspond to your property alias of the corresponding element you are creating. | |
public class Location | |
{ | |
[JsonProperty("displayName")] | |
public string Name { get; set; } | |
[JsonProperty("country")] | |
public string Country { get; set; } | |
[JsonProperty("address1")] | |
public string Address1 { get; set; } | |
[JsonProperty("address2")] | |
public string Address2 { get; set; } | |
[JsonProperty("city")] | |
public string City { get; set; } | |
[JsonProperty("postCode")] | |
public string PostCode { get; set; } | |
} | |
// You would then create a List of Locations ie. List<Location> locations = new List<Location>() and populate the data. You would then get your JSON back as: | |
var json = blockListCreatorService.GetBlockListJsonFor(locations, new Guid("07cc06f6-8f16-4a7f-90b9-b04c59bcdf97")); | |
// The GUID corresponds to the GUID of your block list element in Umbraco. Tip: You can use my God Mode package to find out the Guid easily - https://www.nuget.org/packages/Diplo.GodMode/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment