ModelsBuilder in Custom package
# package-development
t
I'm currently in the process of creating a starter kit for Umbraco. I will generate the main starter kit package, but it will reference a custom class library I've created that will have some extensions, helper methods etc. The question I have is, can the class library referenced by the starter kit package contain references to Umbraco models builder models, so long as they use the default
Umbraco.Cms.Web.Common.PublishedModels
namespace? I read a post from #byteeditor on creating starter kits and they say the class library should not contain any references at all to Models Builder models (https://byteeditor.net/blog/how-to-create-a-website-starter-kit-for-umbraco/#:~:text=The%20code%20in,used%20in%20views.). But I see in some other starter kits (e.g. Clean by @CodeSharePaul and Atomic Starter Kit by @Rosen Petrov ) that models builder models are referenced quite commonly in the class library associated with their starter kits. I completely understand that if a consumer using my starter kit has defined a custom models builder namespace, my starter kit might not work/break on their website. But are there any other reasons why I should avoid using models builder models in the class library?
r
If you create a package that reference Models builder you create a dependency you don't want. Indeed Namespace but also if your customer generates models in a different folder/project you will get all sorts of Reference issues. I would not go that route for a starterkit..
c
The way my package references models build is only in the views that ship with the package. They come from the default models builder namespace and they are only the models that get created as part of the package anyway. This allows you to use any models builder mode you want.
I don't reference any of the models builder classes in any c# code that is shipped in the package.
t
Oh, sorry. I think I misread the namespace in some of your view components and thought it was referencing the actual models builder namespace. My bad. I apologise.
It was actually
Umbraco.Cms.Core.Models.PublishedContent
rather than
Umbraco.Cms.Web.Common.PublishedModels
. Sorry
c
Don't worry, it's a tricky one. I was quite happy with how it worked out for me. I'm happy to get on a 15 minute call with you at some point if you like to explain how mine is working
t
Thanks. I really appreciate that. I've watched both your how to videos (several times) and carefully examined your code. So it's been very useful.
In some of my existing sites, I'd had something like this in my class library:
Copy code
using Umbraco.Cms.Web.Common.PublishedModels;
using Umbraco.Cms.Core.Models;

namespace MyPackage.Web.ViewModels;

public class HeaderViewModel
{
    /// <summary>
    /// The logo appearing within the header.
    /// </summary>
    /// <remarks>This will be an Umbraco media type of either <see cref="Image"/> or <see cref="UmbracoMediaVectorGraphics"/>.</remarks>
    public MediaWithCrops? Logo { get; set; }

    /// <summary>
    /// The items for the primary navigation within the header.
    /// </summary>
    public IEnumerable<WebsiteNavigationItem> PrimaryNavigationItems { get; set; } =
        Enumerable.Empty<WebsiteNavigationItem>();
}
But I guess I shouldn't really put that into the class library associated with my starter kit then?
Cause of the dependency of
WebsiteNavigationItem
is a published model.
c
I think that is where things will start to break, I got around that by having a constructor in my HeaderViewModel where I could pass in the properties to it rather than expecting certain models builder models to be there. And if someone changes a model they can always edit the view in mine to update the model name
t
Ahhh... I see (https://github.com/prjseal/Clean/blob/main/Clean.Core/Models/ViewModels/PageHeaderViewModel.cs). That's a neat way to work around it. I hadn't thought of that.
Although, I guess for something like the
BackgroundImage
or
Categories
properties, when they use them in the view would they typecast them to the proper models builder type, so they can get the proper object properties?
c
It depends what you are doing. My starter kit was originally built to be a simple site to show off umbraco so I kept it really simple. Have you considered using a dotnet template?
t
Yes. I have. And I was actually going to head down that direction. I read and watched the great resources on it by Aaron Sadler.
But, what changed my direction is that I found out we will mostly be supporting Umbraco Cloud installations instead.
For Umbraco Cloud it seemed difficult to go down the dotnet template route because the cloud installation with the Umbraco source code typically exists first from creating a new Cloud project and then you clone that down and commence development from there. So what I had decided to do, is make a starter kit for prepopulating the content and component library (on either a cloud install or self-hosted install) and create some custom nuget packages for any supporting extension type code that is commonly added to all our sites (e.g. http extensions, umbraco application builder extensions etc.). Then the cloud sites can have the starter kit and our nuget packages added as dependencies to the default installation you clone down. And I could create a dotnet template for self-hosted installs with the project structure and standards we typically use. The dotnet template would also make use of the starter kit and custom nuget packages. With this setup, the majority of the supporting code for both our Cloud and self-hosted solutions is nicely encapsulated into a couple of maintainable packages.
m
Just as an aside.. For views at least (which a simple starterkit could conceivable just be a series of views/partials), can this not be mediated to allow modelsbuilder to be used by moving the
using Umbraco.Cms.Web.Common.PublishedModels;
out of views and into the
_ViewImports.cshtml
then whatever modelsbuilder namespace is required by the end user can be used?
t
It could save a user having to update all the name spaces in their view files, yes. But I imagine that having the namespace in the
_ViewImports.cshtml
would have to be documented as a prerequisite for installation of the starter kit, because I don't believe it's in that file by default.
m
or you can programmatically add with a migration.. Or I think you can have a _viewImport in any folder to add additional.. a folder with all your package views in it.. and then either extend the places that mvc looks for partials etc.. or make sure your view paths are all correct?
t
Possibly. I'd have to investigate that.
But as to dynamic @using imports for code... beyond my ken... 🙂
6 Views