Jesper Mayntzhusen
Posted on September 30, 2021
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"
}
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
}
}
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\
You should see something like this:
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
-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.
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"
}
}
}
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"
}
}
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\
Now we can see the new param in the help description by running:
dotnet new test-bp --help
Let's install it while using the new param:
dotnet new test-bp -o MyTestSiteTwo --ProductName Sofa
If you open and compare your solution you can now see that filenames, namespace, etc have all been changed:
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
Posted on September 30, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.