Marathon Consulting is an Umbraco Gold Partner, and Premium Sponsor of the Umbraco U.S. Summit coming this fall. Their own Senior Web Technology Consultant Aaron Sawyer is here to give you a sneak peek into his upcoming talk on MVC-Modeled Block List Editors.
Would you prefer to watch and listen rather than read? Then secure your spot at the hybrid Umbraco U.S. Summit.
Otherwise, let's dive in.
MVC-Modeled Block List Editors
The Umbraco Block List editor is a list-editing property editor powered by predefined Element Types. It was introduced with Umbraco 8 and is a simplified solution for rendering user-determined content onto a webpage. Instead of complicated columns and rows like the grid, the Block List editor only deals in a single list of blocks.
By default, the Umbraco Block List editor will send your request to a view file, passing in a generic BlockListItem object. This naturally causes many developers to place their logic into the view file, which is contrary to MVC standards.
This means that the view file’s code may be written many different ways:
- Declaring C# variables at the top of the file followed by C# logic and any loops and output later
- C# logic defined within functions in the view file
- C# logic scattered throughout the view file; HTML is output whenever and wherever
Which results in:
- Inconsistent code from one Block List editor to the next
- Inconsistent code from one developer to the next
- Additional difficulty making updates, as you have no idea what you will find!
- Having to parse through logic and HTML when making updates
- A long view file, which also contains controller logic
There is a simple solution that makes use of the view components. Instead of scattering logic within a view, we can place it within a view component, which makes our processing architecture fall more in line with MVC modeling.
A view component is a self-contained unit of processing logic with a single entry point that takes in parameters and outputs a view. View components are like an HTML partial in that they output HTML, but unlike them in that they contain logic. They don’t simply render a given model – they contain logic to do processing and use a view file to output HTML.
This solution was not something I came up with on my own; I came across it while watching a YouTube video by Jon D. Jones,"Ninjas Guide To Umbraco V9 Content Modeling" so many thanks to his insight.
You can make a simple edit to the ~\Views\Partials\BlockList\default.cshtml file to make it render a view component for each Block List editor. The Block List editor default.cshtml will then hand off control to a view component matching the Block List editor alias. You can create a ViewComponent class and a structured model, populate an instance of the structured model, and hand that off to a view file.
- Modify the default rendering of the Block List editor processor
- Create the desired structured model class to populate or skip this step and reuse the generated model if you are using models builder and don’t want custom fields
- Create the ViewComponent class to handle the logic and populate the model
- Create a view file to render the populated model on the front end.
Step 1: Edit the ~\Views\Partials\BlockList\default.cshtml file.
Comment out the original PartialAsync line.
I suggest that we take this a step further and gracefully handle any errors that may occur:
Step 2: Create a model or reuse the generated Block List model.
If you are using models builder and you don’t need any custom fields on the view page, you can reuse the generated model of the Block List editor instance; otherwise, just create a model with the fields you want to pass to the page.
I typically build my Umbraco sites with a separate “Core” project that contains C# libraries, so I place the class files like this in that project.
Step 3: Create the ViewComponent.
Preprocessing logic will occur here, where it should be. I typically place this in my “Core” project in a folder named appropriately (e.g. /BlockList/).
Step 4: Create the view.
Rendering logic belongs here (ex. loops). In my project, this lives in /Views/Partials/blocklist/Components/BlogFeed.cshtml.
I typically build my Umbraco sites with a separate “Core” project that contains C# libraries, so I place the class files in that project, and the view in the “Web” project.
That’s it! Now when the block renders, it will pass through a view component where we do our business layer/preprocessing logic, a model is generated, and it gets sent to the view file.
What are the benefits of using structured MVC for blocklists?
- No preprocessing logic in the view file!
- The view file is small, only containing basic rendering logic
- The view component always contains the backend preprocessing logic
- Code is easier to understand
- Future updates are faster and easier
- It feels civilized
Are there downsides?
Yes, but they are few.
- More work up front – you have to create a view component, view, and if you aren’t using the generated block list editor model, a Model class
- If using a custom model, simple edits like adding a new field require you to edit the model, view component, and view
Is it worth it?
I would say yes. I would rather have the benefits with a little leg work! Clean code and consistency are very good things.
If you're interested in looking further into this, the code can be found here.