Creating a boilerplate Umbraco 9 site using project templates - part 1

jemayn

Jesper Mayntzhusen

Posted on September 30, 2021

Creating a boilerplate Umbraco 9 site using project templates - part 1

With Umbraco 9 freshly releases and running on .NET 5 lots of people need to change the way they work. One of those changes is probably to replace your current boilerplate solutions with a fresh one.

This blogpost will show you how to leverage the built in dotnet templates to do that in a very nice and easy way - let's get started!

Setting up a basic template based on an Umbraco site

Set up the site

Before we turn it into a template - is to create the basic site you want to reuse. For the purpose of this tutorial I will use the wonderful demo site made by Dennis Adolfi as a starting point: https://github.com/Adolfi/UmbracoNineDemoSite.git

Create the template files

In the root of the repository create a folder called .template.json. Inside it create a template.json file, with the following basic content:

{
    "$schema": "http://json.schemastore.org/template",
    "author": "Jesper Mayntzhusen",
    "classifications": ["Umbraco", "WebApp"],
    "identity": "Testing.Boilerplate",
    "name": "Testing boilerplate solution",
    "shortName": "test-bp",
    "tags": {
        "type": "project",
        "language": "C#"
    },
    "sourceName": "UmbracoNineDemoSite"
}
Enter fullscreen mode Exit fullscreen mode

image

Testing out the basic template

At this point we have what we need to pack the site up into a dotnet template - of course we will do lots more later. But first let's check that it works!

First of all, let's run a super helpful PowerShell script created by Microsoft Program Manager Sayed Ibrahim Hashimi:

function Reset-Templates{
    [cmdletbinding()]
    param(
        [string]$templateEngineUserDir = (join-path -Path $env:USERPROFILE -ChildPath .templateengine)
    )
    process{
        'resetting dotnet new templates. folder: "{0}"' -f $templateEngineUserDir | Write-host
        get-childitem -path $templateEngineUserDir -directory | Select-Object -ExpandProperty FullName | remove-item -recurse
        &dotnet new --debug:reinit
    }
}
Enter fullscreen mode Exit fullscreen mode

If you run this in a PowerShell terminal you can then run the function later on to clean up - more on that later.

In the terminal navigate to a folder you want to install your new site based on the template.

Install your new template with a path to your template repository - for me it in a sibling folder:

dotnet new --install ..\BoilerPlate\
Enter fullscreen mode Exit fullscreen mode

You should see something like this:

image

Note the shorthand for creating the new template is test-bp - which is what I set in the template.json file in the beginning.

Now that the template is installed we can use it to create our test site:

dotnet new test-bp -o MyTestSite
Enter fullscreen mode Exit fullscreen mode

-o specifies an output folder, and if no name is specified it will use the foldername so don't have to set -n as well

If you look at the new project it created you will see it is a copy of the one we cloned from Github - except it renamed all instances of UmbracoNineDemoSite to MyTestSite. This is because that was what we set as the sourceName in the template.json file.

image

Pretty easy so far!

Adding additional parameters

The sourceName parameter is a standard required parameter for dotnet templates - but if your sites are set up like ours you may need to run replacements more than for just 1 name. For that we can add additional custom parameters - these will all be available as command line params or form fields in VS.

There is another special parameter for setting the framework - for that we can add this in the template.json (remember to do this in the boilerplate solution - not the new one you created based on it):

Add it right at the end below sourceName:

    "sourceName": "UmbracoNineDemoSite",
    "symbols": {
        "Framework": {
            "type": "parameter",
            "description": "The target framework for the project.",
            "datatype": "choice",
            "choices": [
                {
                    "choice": "netcoreapp3.1",
                    "description": "Target netcoreapp3.1"
                }
            ],
            "replaces": "netcoreapp3.1",
            "defaultValue": "netcoreapp3.1"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

We can also create a second symbol similar to the sourceName param that replaces a value in the template files. The UmbracoNineDemoSite has Products that has controllers, a composer, view models - etc. Let's say we use this as a baseline for different shop sites and this new site is going to be about selling Sofas - we may want to replace Product with Sofa then:

Right below the Framework symbol we add the new ProductName param:

"symbols": {
    "Framework": {
        "type": "parameter",
        "description": "The target framework for the project.",
        "datatype": "choice",
        "choices": [
            {
                "choice": "netcoreapp3.1",
                "description": "Target netcoreapp3.1"
            }
        ],
        "replaces": "netcoreapp3.1",
        "defaultValue": "netcoreapp3.1"
    },
    "ProductName": {
        "type": "parameter",
        "defaultValue": "",
        "replaces": "Product",
        "datatype":"text",
        "fileRename": "Product",
        "description": "Product to be replaced"
    }
}
Enter fullscreen mode Exit fullscreen mode

WARNING: This could mess up your site if you use something too generic, Product is a terrible example - please use something that is way more specific!

Note that the replaces value is for within files, whereas the fileRename value is for actual filenames being changed, so you have a bit of granular control if you only want one type.

At this point we can reset and reinstall the template:

Reset-Templates; dotnet new --install ..\BoilerPlate\
Enter fullscreen mode Exit fullscreen mode

Now we can see the new param in the help description by running:

dotnet new test-bp --help
Enter fullscreen mode Exit fullscreen mode

image

Let's install it while using the new param:

dotnet new test-bp -o MyTestSiteTwo --ProductName Sofa
Enter fullscreen mode Exit fullscreen mode

If you open and compare your solution you can now see that filenames, namespace, etc have all been changed:

image

Closing note

There are lots more you can do, but will leave it at this for part 1. I hope this gave a good first view of setting up your own dotnet templates!

Thanks for reading! If you like this post, have any feedback, suggestions, improvements to my hacky code or anything else please let me know on Twitter - @jespermayn

💖 💪 🙅 🚩
jemayn
Jesper Mayntzhusen

Posted on September 30, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related