Hi,
I’m implementing razor previews for block list editor back-office previews, using this article and accompanying repository as a reference.
Part of the solution is to use a custom API to return the populated HTML of each block by constructing a typed object from its JSON data. The pertinent code which does this is this method:
private async Task<string> GetMarkupForBlock(BlockItemData blockData)
{
// convert the json data to a IPublishedElement (using the built-in conversion)
var element = this._blockEditorConverter.ConvertToElement(blockData, PropertyCacheLevel.None, true);
// get the models builder type based on content type alias
var blockType = _typeFinder.FindClassesWithAttribute<PublishedModelAttribute>().FirstOrDefault(x =>
x.GetCustomAttribute<PublishedModelAttribute>(false).ContentTypeAlias == element.ContentType.Alias);
// create instance of the models builder type based from the element
var blockInstance = Activator.CreateInstance(blockType, element, _publishedValueFallback);
// get a generic block list item type based on the models builder type
var blockListItemType = typeof(BlockListItem<>).MakeGenericType(blockType);
// create instance of the block list item
// if you want to use settings this will need to be changed.
var blockListItem = (BlockListItem)Activator.CreateInstance(blockListItemType, blockData.Udi, blockInstance, null, null);
// render the partial view for the block.
var partialName = $"/Views/Partials/blocklist/Components/{element.ContentType.Alias}.cshtml";
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
viewData.Model = blockListItem;
var actionContext = new ActionContext(this.HttpContext, new RouteData(), new ActionDescriptor());
await using var sw = new StringWriter();
var viewResult = _razorViewEngine.GetView(partialName, partialName, false);
if (viewResult?.View != null)
{
var viewContext = new ViewContext(actionContext, viewResult.View, viewData, new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), sw, new HtmlHelperOptions());
await viewResult.View.RenderAsync(viewContext);
}
return sw.ToString();
}
This all works great. However, the model is returned without any Settings data. I wondered if anyone had any pointers as to how to append the settings data to the model too as I use that data to do some important stuff in the view. A lot of this stuff is over my head!
Many thanks for any help.
This is a companion discussion topic for the original entry at https://our.umbraco.com/forum/110114-append-settings-data-to-block-list-preview-model-generated-via-custom-api