Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Depending on which version of Umbraco CMS you are using, we distinguish between two package types, NuGet packages, and Package ZIP files.
Packages for Umbraco 10 and above are installed as NuGet packages.
The legacy, zip file package type is only available for Umbraco version 8 and earlier versions. Learn more about it in the Package zip Files section of this article.
A NuGet package is a standard way of delivering compiled code and configuration to a .NET project. NuGet packages contain dll-files and other files required for the solution. For more information on NuGet packages see Microsoft's An introduction to NuGet documentation.
NuGet packages can be installed using via the command line or through Visual Studio using either the Package Manager Console or the NuGet Package Manager.
See below, for an example of installing a package using the Package Manager Console in Visual Studio:
NuGet packages can include any solution files and can be configured to run PowerShell scripts after installation.
As NuGet packages are installed outside of the Umbraco website they cannot directly manipulate any of the Umbraco settings or content during their installation.
When adding or changing configuration of Umbraco as part of a NuGet package you need to develop code to run as part of a Migration. The Migration will run the first time the Umbraco site starts after the package is installed, applying the correct configuration.
Zip file packages are only available for Umbraco CMS 8 and earlier versions.
Refer to the NuGet Packages section above, if your website is using Umbraco 10 or a later version.
A package zip file can be installed directly through the Umbraco backoffice.
Packages zip files can contain:
Content
Solutions files (dll
s, App_Plugins
files, etc)
Document Types
Templates
Stylesheets
Macros
Languages
Dictionary Items
Data Types
Media
To include media in your package, select it in the "Media" section. Additionally, choose it in the "Package Files" section under "Path to file."
Information on how to list your package on the Umbraco Marketplace.
The is a website built and maintained by Umbraco HQ to support searching and reviewing packages.
It lists all commercial and open-source packages that the community has made available on NuGet.
More information, including details of the steps for listing, are available at the dedicated .
A package extends the functionality of Umbraco to provide additional functionality to editors, developers, site visitors, and all other types of users of Umbraco.
A package extends Umbraco to provide additional functionality to editors, developers, site visitors, and all other types of users of Umbraco. It can impact one or more of these groups of people depending on the type of package.
An Umbraco Package can be many things, but is generally characterized by:
Adding or extending functionality in the Umbraco CMS
Empowering people to do more and/or do things more efficiently
Engaging community members in collaboration and sharing
Solving real life problems
Inspiring people on what Umbraco can be made capable of
Packages provide a wide variety of functionality, and can often span multiple categories. In general, though, the functionality they provide fall into these main groups:
Packages for Umbraco 10 and above are installed as NuGet packages.
This short tutorial will teach you how to create a package in the Umbraco backoffice. It will also give a quick overview of what a generated package will contain.
Package authors who would like their UI to be multi-lingual can include their own set of language files as part of their package distribution.
Once you've created a package make it available on the Umbraco Marketplace to share it with the community.
Things you should know if you are developing for Umbraco Cloud.
Some guidance on how to maintain your package after release.
There are many ways to build and deploy your package to NuGet. You will likely have your own approach for organizing a solution and preferred tools for build and deployment.
If you are looking for inspiration to follow form some tried and tested packages, read more here.
A package that can be categorized as a Schema Extension will extend the default Umbraco Schema. Schema in this sense refers to things like Data Types, Property Editors, Document Types and Media Types. By extending Umbraco with packages such as editors are given greater capabilities when they are populating their content pages.
A Management Extension package helps you manage your site, and provides information to the users. Management extensions typically contain custom sections or dashboards to facilitate site management. is an example of a comprehensive management extension package with additional tools and information.
Starter kits are, as the name suggests, a package that helps you set up a starter version of whatever you want to build. Most starter kit packages are for starting a website, and include schema like Document Types and Templates as well as content nodes and media. There are also some specialized starter kits, for example for creating a blog. Umbraco HQ has released their , that creates a small site with the most commonly used features.
Content apps are almost like dashboards for content nodes that are intended to display node specific information. A good example of this is the content app. It shows you readability scores for your written content, directly on each content node.
This type of package can be a lot of things, and can include a number of the other package types. They are generally integrating a larger system into Umbraco. A good example could be an e-commerce package such as , that includes an entire webshop module for Umbraco.
Creating accessible packages extends on accessibility in an Umbraco context.
The Umbraco UI components have been built to be accessible and have accessibility tests built within them. Building the user interface (UI) using these Umbraco UI components ensures that the package is as accessible as the Umbraco backoffice.
In addition, any fixes and updates to the UI components will be pushed through to the packages when you rebuild them with the updates.
Accessibility testing is more a specialist skillset than it is automated testing. The purpose of this document is to outline what can be done to help build accessible packages. It is not a complete list of accessibility tests that can be performed.
Build the components using the Umbraco UI components as these have accessibility tests built within them.
Use the keyboard to tab through the elements on the page checking:
Does the element tabbed to have a focus state?
Does the tab order make sense?
More on focus, tab orders, other common interactions and techniques for keyboard testing can be found at WebAIM: Keyboard Accessibility
Check the UI with a screen reader.
Non Visual Desktop Access (NVDA) is a free Windows screen reader and some guidelines on screen reader testing are available from WebAIM: Web Accessibility In Mind
Install an accessibility testing tool as a plugin into your browser to run automated tests:
Tools like axe DevTools are built to reduce the number of false positives in a test.
If the UI does not follow the Umbraco Style, then check the contrast with a tool like the Web Content Accessibility Guidelines (WCAG) Contrast Checker. This will help ensure contrast.
Once you've created and published your package, here is what's involved in it's ongoing maintenance
Once you've created and published your package, what's involved in its ongoing maintenance?
Umbraco will regular release update to the CMS as patch or minor versions. These are verified to be backwards compatible. As such there's no expectation that a package may break when a new version of this type comes out.
When a new major version of Umbraco is released, there will be breaking changes. You should test your package on this latest version to confirm it still works. Unless there's been a significant change to the CMS, many packages will continue to work with the new major version without any update. However you may be using a service or API that has undergone a breaking change.
If this happens, the changes will be documented and you should be able to update your code, recompile and test. After that you can release a new major version of your own package.
Even if there are no breaking changes that affect you, it's worth also looking for any code you using that is marked as obsolete. Umbraco will obsolete public methods or constructors that are expected to be removed in a future major version.
When creating a package with Umbraco you will be taking a dependency on at least one Umbraco package. You will do this in the .csproj
file for your package:
As indicated, this states the package is compatible with Umbraco 10 and any future version. This would allow the developer to install the package into an Umbraco 12 or 13 solution for example.
If you want to maintain tighter control over this, you can specify an upper bound, like this:
This states that the package is compatible with Umbraco 10, 11 and 12, but not 13. Thus it prevents anyone installing your package into an Umbraco solution that you haven't verified compatibility with. Once you have, you can increase the bound or otherwise update the dependent Umbraco version as appropriate.
If you want to encourage feedback, feature requests, and issue reports then you should make available an issue tracker.
This can be provided as information about your package and will be linked from your package's page on the Umbraco Marketplace. Specifically you should populate the IssueTrackerUrl
field.
After some time it could be that your package should no longer be used. Perhaps it is now too old, or it has been superseded by another one that you recommend instead.
You can indicate this by deprecating your package on NuGet.
Information on good practices and common defaults for Umbraco package development.
This document provides guides and notes on package development. It includes good practice guidelines that will help you maintain and support your package through multiple releases and versions of Umbraco. These good practices are not prescriptive, but offer a guide as to what often works well, and not-so-well, when developing packages for Umbraco.
To extend the Umbraco backoffice, a package can provide files such as a package.manifest
and AngularJS views/controllers that should be stored within the App_Plugins
folder. It's recommended to put all files in a subfolder with a unique name, preferably using the package name, like App_Plugins\MyPackage
.
Files in the App_Plugins
folder will be publicly available on the website even though they are not in the wwwroot
folder. You should not store sensitive information in the App_Plugins
folder.
Files in the App_Plugins
folder should be considered immutable. This means that they are not something a user of your package is expected to change on their site.
The default delivery method for files to the App_Plugins
folder is via a .targets
file within a package. This means when a website is built, the files in this folder are copied over from the NuGet cache. When this happens, any changes a user might have made to these files will be lost. Equally, if the user performs a dotnet clean
on a solution, all files in the App_Plugins
folder will be deleted.
If you have files that you expect users of your package to alter you should not place them in the App_Plugins
folder.
Views are used to render content on the front end of a website. If your package provides a way for the user to present the content publicly, you should copy these files to the views folder.
As the files will still be copied during build you should ensure your target file does not overwrite newer or altered files. You should also ensure that it doesn't delete files on clean.
When you have a package that contains many views you might consider building a dotnet template or Razor Class Library (RCL) instead. By doing this, the files will not pollute your user's solutions.
Umbraco products store their licenses in /umbraco/Licences
. It is recommended for third-party packages that require license files to also store their license files in this location.
The default .gitignore
for Umbraco templates will include any files in the /Licenses
folder while ignoring most of the rest of the Umbraco folder.
The /umbraco/Licenses
folder does not exist on a fresh installation of Umbraco. You need to create it manually before you save your license file to this folder.
Umbraco (version 9 and up) is an ASP.NET Core application and can be run on multiple operating systems (Windows, Linux and macOS). When developing packages there are a few things you should be aware of for your package to run on all possible operating systems.
The Linux and macOS file systems are case-sensitive by default. This means that App_Plugins/myPackage
is a different location from app_plugins/MyPACKAGE
. When building your package you should ensure that you always refer to folders and paths in a consistent way.
A good way to ensure consistency is to use constants in your code to define file or folder locations.
You can adjust the case sensitivity of a Windows folder by running a command against a newly created/empty folder:
Some folders within Umbraco will already exist for all installations. If you access these folders, you need to be aware of the case used to ensure you end up in the correct place:
If you create a custom section/tree, Umbraco will build paths based on the name of that section or tree. These folder paths will be case-sensitive.
For example: if you have a custom tree with the treeAlias
of MyCustomTree
Umbraco will look for files in App_Plugins\MyPackage\backoffice\MyCustomTree\
.
You should never hardwire a file or folder location into code. Instead, it is recommended to follow either of the options below:
Access files using the ASP.NET Core file providers from IHostingEnvironment
.
Use the built-in methods to access well-known locations (see below).
The location of the Umbraco temp folder can be controlled via configuration and cannot be assumed. Use the IHostingEnvironment.LocalTempPath
variable to locate the temp folder.
If you require the path of a folder relative to the site root, you can use the IHostingEnvironment
method to map a path:
It is not recommended to assume things about the folder structure of a site or use direct I/O commands to access the file system. Access to the disk within an ASP.NET Core site is usually managed with File Providers. You can access the file providers from the IWebHostEnvironment
class.
Example: If you want to read robots.txt
from the wwwroot
folder, use WebRootFileProvider
in a controller to get to the root of the site and read the file:
This is the preferred method for file I/O. Not all files served up by a site are placed in the wwwroot
folder when you expect them to be. This is especially true if the site is using Razor Class Library projects to insert static files.
Building folder path strings manually can cause problems when swapping between file systems. Windows uses the backslash character ('\') to separate folders and files while Linux uses the forward slash ('/').
On Windows, a file might be located at d:\website\robots.txt
while on Linux this might look like /home/website/robots.txt
instead.
You should use the .NET Path
methods wherever possible when building paths to ensure that the correct path is built:
If you need to build a path manually, use Path.DirectorySeparatorChar
instead to get the correct separator for the file system.
Most packages will require some settings to be stored for the users to control in order to change the behavior of the package. Where you store these settings will depend a lot on the nature of the package.
Property Editors should store their settings as part of their Data Type in Umbraco. This is the standard way property editor behavior is controlled while it is familiar to users and supported by deployment tools.
You should not alter appsettings.json
via code.
Settings in ASP.NET Core are merged from a number of different locations at runtime. You cannot guarantee that appsettings.json
is the location that a setting is read from and your users may not want certain settings in that file. You can read settings from the configuration, but you cannot assume they have come from appsettings.json
.
There are many options for where you might save your settings and a lot will depend on the nature of your package.
Below you can find pros and cons for different places where you might save the settings for your package.
Settings can be saved to the database. Settings can be stored in the database using the Umbraco IKeyValueService
, and for more complex settings you can use a custom database table.
Pros:
Settings will be accessible directly from the database, and not dependent on deployed files on disk.
Cons:
Setup is required to create the database tables for the settings to live in.
The settings will only be available to the specific instance of the site, and any settings will not be deployed between a local, development, or staging site.
You can choose to save the settings to disk. As an example, the settings can be saved in the /config
folder at the root of the site.
Pros:
Settings will be accessible to the site and can be included in deployments between sites.
Cons:
You cannot guarantee that the folder or files will be present on a site or that they will be writable.
Using your own config means your users cannot harness the power of the .NET Core configuration system and move settings to environment variables or other key/value stores. This means that sensitive information may end up on disk.
You could choose to provide your users with a snippet they can copy into their appsettings.json
file. This will ensure that the settings are stored in the correct location.
Pro: Allows your users to fully control how and where the settings are stored (eg. secure key/value stores).
Con: Requires the user to edit files on disk to get the settings in place.
Things to consider for package development and usage in Umbraco Cloud
If you want to use or develop packages for Umbraco Cloud there are a few things to consider and be aware of. The two most important things to know about are
When developing a package you will sometimes store data, this can be data in many forms - Umbraco schema / content, package settings, etc.
When you develop a package for Umbraco Cloud there are a few things to be aware of when storing data, mainly whether you want that data to be specific to 1 environment or more.
Let's take a look at the most common ways of storing data in packages - and what to watch out for on Cloud.
A is some code that you run as part of a migration plan. That migration plan has an ID that is stored in the database (in the KeyValue table). This means that when you add new migrations Umbraco will only execute the ones that came after the one with the stored ID. The most important difference between a migration and a package action is when they are initialized. A package action runs on package install and uninstall, whereas a migration will run whenever you want it to run, see below for common examples.
As migration runs are stored in the database of the site it also means that they will run on each environment you trigger them on. The most common way to trigger a migration is to include them in a , which will ensure they run on site startup. This means any commands you have in your migration will automatically run when the site starts up. When your package code is pushed to a new environment it will run them from the beginning on that environment as no ID is saved in the database.
This is normally a good thing. However if you generate any Umbraco schema then Umbraco Deploy will automatically create based on that schema, and commit them to source control. This means that when you deploy all your files to the next environment the migration will run again, create duplicates and generate duplicate UDA files, which could end up causing a lot of issues.
You could consider creating Umbraco schema only during a package action, and then running things like creating database tables in migrations. Another good workaround could be to not run the migrations in a composer, but rather create a dashboard for the package where the user can choose which migrations to run themselves. The has an example of this.
You may sometimes choose to save data in a file. Could be a separate config file for your package or a to add an app setting to the web.config. If you do this be aware of two things:
If these files are generated on a Cloud environment they will not be stored in source control, and will be overwritten on next deployment. They need to be installed locally, committed to source control and then pushed up to the Cloud environments. We have an on allowing package creators to commit their files directly on Cloud, and it is possible to do so currently but not in a supported way, and it may change suddenly.
If you need the content of the files to be different on the different environments you will need to use environment specific .
A value connector is an extension to Umbraco Deploy that allows you to transform data when you deploy content of any kind between environments. When it comes to packages, one reason you need to consider these if you are supporting deploying content properties that rely on integer IDs. Content and other Umbraco data has two identifiers - an integer and a GUID. The GUID is consistent between environments but the integer ID is not. As such, if transferring content between environments and relying on integer IDs, you'll need to include a value connector to transform the value.
They also manage dependencies for property data. If you save an ID of an image in your property editor, you can make sure the related image media item is transferred too.
Folder | Note |
---|
You can read more about value connectors and other extensions to Umbraco Deploy .
/App_Plugins | Uppercase |
/App_Plugins/[Ll]ang | Uppercase |
/Views | Uppercase |
/umbraco/Licenses | Lowercase |
/config | Lowercase |
Suggestions for organizing and Umbraco package source code repository.
There are many ways to build and deploy your package to NuGet. You will likely have your own approach for organizing a solution and preferred tools for build and deployment.
It may be useful though to review some practices we share here, of how we build packages at Umbraco.
Some add-ons to the CMS created by Umbraco are closed-source, but we have some we make freely available with open-source repositories. An example is Umbraco.AuthorizedServices, that has a source code repository here on GitHub.
The solution consists of three projects.
The main package project lives in src/<ProjectName>
. It contains in the project file a dependency on Umbraco CMS:
Here we provide an upper bound on the package. This ensures that developers can only install it into projects that are using versions of Umbraco that we have tested the package with.
When the next major version of Umbraco is released, we'll test and either extend the range or release a new version, as appropriate.
We have a project for unit tests in tests/<ProjectName>.Tests
. It contains references to Umbraco.Cms.Tets
and a project reference to the package:
Finally there's an example Umbraco website that we use for manual testing of the package. It also has a project reference to the package project, allowing us to test updates as they are compiled.
As well as the projects, the following files are added to the solution:
.artifactignore - used by AzureDevOps services to control which files are uploaded when you publish. This helps to reduce pipeline execution time.
.editorconfig - used to enforce consistent coding styles for multiple developers working on the same project across editors and IDEs.
.gitignore - controls which files are added to source control.
Directory.Build.props - used to provide common setting across all projects in the solution.
global.json - ensures that the solution is always built with a consistent version of .NET. We add this when we have a solution that targets a single Umbraco major version.
LICENSE.md - indicates the license through which the code is available.
README.md - a top-level documentation page for the source code repository.
icon.png - an icon used for the package on NuGet and the Umbraco Marketplace.
version.json - provides package versioning information for use by Nerdbank.GitVersioning. We use this tool for generating version numbers.
We use AzureDevOps pipelines for continuous integration and releasing new versions of the package. The definition of how the project is built is defined in a .yaml
file that's part of the source code repository.
The file can be found here.
Even if using another tool it may be worth reviewing how we have setup our pipeline. It may be you can setup something similar with your own provider.
The build consists of two stages: building the solution and running unit tests. Only if both succeed is the build as a whole considered successful.
We release the package manually in AzureDevOps, with a two stage process. Firstly we release to a "pre-releases" feed, and then after manual approval, to NuGet.
The process of installing and, in turn, uninstalling packages in your Umbraco CMS website depends on the version and package type.
This article will cover the process of installing as well as uninstalling packages from your Umbraco CMS website.
As the article will cover both NuGet packages and zip file packages, it is important to know the distinction:
NuGet packages: Modern Umbraco (Umbraco 10+) and Legacy Umbraco (Umbraco 8 and earlier versions).
Package zip files: Legacy Umbraco (Umbraco 8 and earlier versions) only.
Learn more about the different types of packages in the Types of packages article.
In the Umbraco Backoffice, you will find a Packages section that displays the Umbraco Marketplace. From here you can browse all community-made as well as official Umbraco packages for the Umbraco CMS.
For Umbraco CMS version 8 and earlier versions, the Packages section displays the Packages site on Our.
Navigating to a specific package in the section will present you with an overview of the package, as well as an install snippet for NuGet CLI.
The packages can be installed by using:
NuGet Package Manager in Visual Studio
Package Manager Console in Visual Studio
.NET CLI (usually accessible from the terminal/command prompt of your system)
For example, to install the StarterKit package for the Umbraco CMS the command would be:
dotnet add package Umbraco.TheStarterKit
Navigating to the NuGet Package Manager in Visual Studio is more visual, and gives you an overview of already installed packages.
The Package Manager has an integrated search function that allows you to find any public NuGet package and install it on the project.
Once the package has been installed, it will show up under the Packages section in the backoffice, under Installed tab.
Package zip files are only available for Umbraco 8 or earlier versions.
Once you have downloaded an Umbraco package zip file, you can install it in the Umbraco backoffice by following the steps below:
Navigate to the Packages section.
Select Install local on the top-right side of the page.
Drag'n drop the package onto the page or use the file explorer to select the package zip file.
Accept terms of use to confirm the package installation.
The package will be installed and any necessary reboots of the site will be initiated.
You can also install packages directly when browsing the packages in the Umbraco backoffice. This is usually preferred in order to ensure that the package is compatible with the Umbraco CMS version used.
Navigate to the specific package you want to install.
Click Install package in the right-hand side of the page.
Confirm the installation.
The package will be install and the site will be rebooted.
Uninstalling packages is not always as straightforward as installing them.
In this section, we will provide two examples of uninstalling a package - the StarterKit package and the SEOChecker package.
Keep in mind that this particular guide targets a specific package. There are many packages out there, and each one is different. The exact steps presented here might not work the exact same way for all the packages, though the general approach should still apply.
The Starter Kit provides you with a boilerplate website solution to build upon. The package installs Document Types, Templates, media, content, and everything else needed to set up a small website. There is little custom code/functionality involved which is usually the case for such starter kit or sample-site packages.
To uninstall a package, either run a command or use the NuGet Package Manager in Visual Studio.
dotnet remove package Umbraco.TheStarterKit
If you are using Umbraco 8 or an earlier version you uninstall the packages directly from the Packages section of the Umbraco backoffice.
Navigate to the Installed tab in the Packages section.
Click Uninstall package next to the package you want to uninstall.
Confirm that action by checking Confirm package uninstall.
It is recommended to clean the solution after removing any package. This can be done by right-clicking the project in Visual Studio and choosing the Clean option, or using the dotnet clean
command.
With packages like the StarterKit, the process does not end there. While the package is gone, content - and everything else needed for the website - is still available in the backoffice. To fully remove this kind of package, additional steps are needed.
Keep in mind that this particular guide targets a specific package. There are many packages out there, and each one is different. The exact steps presented here might not work the exact same way for all the packages, though the general approach should still apply.
More advanced packages that add functionality on top of Umbraco, usually rely on providing custom, compiled code. That being said, many of such packages also implement custom Sections, Dashboards, editors, and views.
In this example, we will be using the SEOChecker package. This package allows developers of the site to add custom properties to Document Types used to track search engine optimization practices.
An example use case of the SEOChecker property on a Document Type, as presented in the Content section:
To uninstall the SEOChecker from a website, the first step is to remove the package via a dotnet
command or use the NuGet Package Manager.
The following command can be used for uninstalling the package:
dotnet remove package SEOChecker
After that, cleaning the solution is recommended.
If content on the website relies on having a custom Property Editor or a data source installed, those properties will default to a label
Data Type. All previously saved content in the property will in turn be converted to a string.
In the case of the SEOChecker, the custom property added from the package would look like this after all the package files have been removed:
Depending on the packages and the implementation, rendering of content from custom editors, or any frontend functionality dependent on external code, might not work correctly. It is always recommended to inspect the frontend of the site after removing any packages.
Tutorial to create a package in Umbraco
The goal of this tutorial is to extend Umbraco and create a package. The tutorial's starting point is to create a package out of the dashboard from the Creating a Custom Dashboard tutorial. The process is the same for most packages so feel free to follow along with something else.
To create a package, you first need to create a package schema through the Umbraco backoffice:
Go to the Packages
section.
Select Created
in the top-right corner of the screen.
Select the Create package
button.
On the Create package
page, there are fields that you can use to construct the contents of your package that are based on items from the backoffice.
Enter the package name at the top - we will call our dashboard the same as in the mentioned Tutorial: Custom Welcome Dashboard
.
We will now take a look at the different information that can be filled in:
These values are used to determine which backoffice items the package should contain. We will fill in the following things:
After filling out all the information, we can select Create to create the package schema. We will download it and take a closer look at what it contains.
If your package doesn't include backoffice specific items, the result from downloading it will be just a package.xml
file. Otherwise, if you select media files you will download a ZIP package that looks like this:
Additionally to the package.xml
, there is a folder containing the media items for your package. The rest of the information is recorded in the XML schema document.
The files that we created from the Creating a Custom Dashboard Tutorial will be discussed at a later point. Now, let's take a look at the package.xml
file:
You will notice that the values for each of the fields we provided can be found inside this XML file. But since our example doesn't require any backoffice items, just the package name is contained. In a different case, the other values will be kept under the respective XML tags.
This is the next step of preparing your package before install. Umbraco 9 only supports packages using NuGet installation, which enforces better practices for both source control and deployment. Here, you will find how to create a NuGet Package for the custom dashboard that will extend Umbraco's functionality.
NuGet is the standard package manager for .NET projects. More information about NuGet and how it works can be found on the Microsoft documentation pages for NuGet.
Assuming you have already installed the Umbraco templates, you can execute the following command in the .NET CLI to create a package project, that will include the necessary configuration for packing and installing your client-side assets:
For a guide on how to install the project templates, follow the 2 steps listed in the Install the template section.
The outcome is the files generated below:
Apart from the project file, you can find an empty package.manifest
inside the App_Plugins folder, which we will replace with the one created from the Creating a Custom Dashboard Tutorial. But more importantly, it also contains a build/CustomWelcomeDashboard.targets
file.
This file contains an msbuild
target that is executed when a project has a dependency on this package. It copies the App_Plugins
folder into the project on build. This is required for having Umbraco packages in a NuGet package format.
If you are planning to overwrite the contents of the App_Plugins folder, make sure that the subfolder containing your package contents has the same name as the one you specified after the --name
flag and that the package.manifest
has the correct path references to your files.
You can also add your custom C# files in the root of the package folder which will be part of the DLL of the package, but for our example, this won't be necessary.
As mentioned previously, let's navigate to the App_Plugins folder and replace its contents with the custom files we created for our new dashboard.
In this section, we will demonstrate how you can add metadata about the package and its creator(s).
Now that Umbraco 9 is built on ASP.NET Core, you can add values directly to the package csproj
file and it will pick them up. If you don't want to manually edit the csproj
file, you can right-click your project, go to Properties and then to Package. There you can insert your specific information:
Here is an example of some basic properties that you can specify in your project file:
The Title
, Description
, PackageTags
came with the template and we added some further information like Version
, Authors
, PackageProjectUrl
and PackageLicenseExpression
that we elaborate on below:
It is time to create the actual NuGet package (that is, a .nupkg file). Executing the dotnet pack
command in the package directory will take care of building the project and outputing the generated NuGet package in the bin
folder (the output on the CLI shows the full path to the .nupkg
file).
If you want to specify the output location, just execute the following command instead:
It will pack the project in the current directory and place the resulting package into the MyNugetPackages
folder.
To allow other people to use your package you will need to publish it to a public NuGet repository. The most common repository is at https://nuget.org.
There is comprehensive documentation on how to Publish a NuGet package to NuGet.org in the official NuGet documentation, as well as how to Publish to a private feed while developing.
You can install your newly created NuGet package using Visual Studio, Rider, Command Line or editing the project file directly.
We will continue using the CLI and first create a Umbraco project, and then add the package reference to it:
You can check that the NuGet package was referenced in your solution and that the App_Plugins assets were restored successfully. Our simple package is now installed and you can see the custom dashboard in the backoffice. No further actions are required for our example. However, we will go ahead and mention a few more steps necessary for the more complex packages.
A different approach when you want to test it locally without publishing it anywhere is to create a test site of the package. You can use our dotnet new umbraco
template, this time with a special flag -p
which will add a project dependency to our package and import the target file from that project. So when you build the new project, it will also copy the App_Plugins folder from the package project into the test project. In the same way, as if it was a NuGet reference.
This is the full command:
Afterwards, you can enter the CustomWelcomeDashboardProject
directory, build your Umbraco website using the dotnet build
command and then run the application.
We can run a migration plan for each package that contains Umbraco content (referenced in the package schema).
If you just want to ship a package that only installs the schema and the content you chose, then you can inherit from the AutomaticPackageMigrationPlan
as seen below, and specify the package name that will be displayed under the packages Installed tab in the backoffice. You will also need to embed the schema file in the same namespace.
Whenever the embedded package.xml file changes, the automatic package migration plan is executed again. This is due to the fact that the migration state is based on the file hash. Existing schema or content will not be overwritten in this process.
Instead of creating an automatic package migration plan, we will inherit from the PackageMigrationPlan
and again specify the name of the package in the base constructor. Further on, we will define the plan using a unique GUID - in the example below we have a single migration called MyCustomMigration
.
The custom migrations can inherit from PackageMigrationBase
where we can use helper methods to pick up the schema. But we can also use the regular MigrationBase
class.
Here we also added the ZIP file as an embedded resource to the package project.
Whichever migration plan you choose to create, you will be able to see that your package has been installed after the migration is completed.
When using a custom package migration plan, the current state is ignored by default. This causes it to execute all migrations again whenever this isn't the same as the final state of the plan (e.g. if you added a new migration). This is due to the IgnoreCurrentState
being set to true
in the PackageMigrationPlan
base class. You can override this property and set it to false
again to make it behave like regular migration plans and only run the migrations that have not yet been executed on the current environment.
After creating a migration plan, the content and schema will automatically be imported either during unattended package migration or from the Packages section in the backoffice.
By default, all these package migrations are executed unattended during startup but the solution owners can disable this in the configuration. IntelliSense can help, as well as provide further information about the PackageMigrationsUnattended
setting. Then in the Packages section, there will be an option to run the package migration for each package individually when the PackageMigrationsUnattended
is set to false
.
The configuration of package migrations can be different for each environment and makes it possible to have the migration executed unattended on the development environment, but leave them out or manually execute them on other environments. This is useful when you use a tool like Umbraco Deploy or USync as these will migrate the content.
Information on how to use language files to make your Umbraco package UI support multiple languages
Umbraco Core includes language files, but package authors must provide their own for multi-lingual UI.
For each language your package supports, you include an .xml file in the same format as the core language files, named with its language code. The language files must be located in a Lang
folder inside your package folder in App_Plugins
. If your package assets are in /App_Plugins/mypackage
all language files must be placed in the following locations:
English keys: /App_Plugins/mypackage/Lang/en-US.xml
Danish keys: /App_Plugins/mypackage/Lang/da-DK.xml
The App_Plugins
version of the Lang
directory is case sensitive on Linux systems, so make sure that it start with a capital L
.
Each language file can include one or more area. Each area contains a collection of language keys with the translation.
For reference on the language file format see the core
Property | Value | Note |
---|---|---|
Property | Value | Note |
---|---|---|
Content
Empty
Here, you can include content - e.g. if you want to create a starter kit. Not relevant for this package though.
Media
Empty
Here, you can include media - e.g. if you want to add media to the starter kit. Not relevant for this package though.
Document Types
Empty
Similar to the Content picker above. It is important to note that if you include content, you will need to also pick all its dependencies in this and the next steps for them to be packaged together!
Media Types
Empty
Similar to the Media picker above. It is important to note that if you include media, you will need to also pick all its dependencies in this and the next steps for them to be packaged together!
Macros
Empty
See Document Types
above
Languages
Empty
See Document Types
above - all text is hardcoded or within our own lang folder in this package, so this is not needed.
Dictionary
Empty
See Document Types
above
Data Types
Empty
See Document Types
above
Templates
Empty
See Document Types
above
Stylesheets
Empty
These will come from the wwwroot/css folder. If you have stylesheets you want to include from other locations (like App_Plugins folder) you can do so at a later step.
Scripts
Empty
These will come from the wwwroot/scripts folder. If you have scripts you want to include from other locations (like App_Plugins folder) you can do so at a later step.
Partial Views
Empty
See Document Types
above
Version
1.0.0
This is automatically set to 1.0.0 but can be changed as appropriate.
Authors
Your name
Here you get to take credit for your awesome work!
PackageProjectUrl
https://umbraco.com
This URL will be shown as the package's URL when others install it. It will likely be a Github repository, or similar.
PackageLicenseExpression
MIT
The license is set to MIT. Please consider how you want your package licensed. If in doubt when deciding an open-source license there are good resources available.