From bdbaad9ea8a6c5e7fa8ae9d342b8078b67c5d2f6 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Tue, 28 Jul 2026 14:03:32 -0700 Subject: [PATCH 01/11] Initial outline --- docs/core/tools/templates.md | 201 +++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 docs/core/tools/templates.md diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md new file mode 100644 index 0000000000000..8db87cb80c787 --- /dev/null +++ b/docs/core/tools/templates.md @@ -0,0 +1,201 @@ +--- +title: .NET templates overview +description: Learn how .NET templates work, how they're structured, and what you can do with them using the dotnet new command and Visual Studio. +author: adegeo +ms.author: adegeo +ms.topic: overview +ms.date: 07/28/2026 +ai-usage: ai-assisted + +#customer intent: As a .NET developer, I want to understand how .NET templates work so that I can use, create, and distribute templates for projects and files. + +--- + + + +# What are .NET templates? + +[Introduce the .NET template system: what templates are, what they produce (projects, files, resources), and why they exist. Mention that both the `dotnet new` CLI command and Visual Studio use the same template engine. Briefly mention built-in templates that ship with the SDK and the ability to install community or custom templates.] + + + +## Template types + +[Explain the two main types of templates: item templates and project templates. Describe what each type produces and when to use each.] + + + +## Template structure + +[Explain how a template is structured on disk — the source files plus the required `.template.config/template.json` configuration file.] + + + +### The template.json file + +[Explain the `template.json` configuration file: what it does, required fields, and optional fields that enable advanced features.] + + + +### Template parameters (symbols) + +[Explain the `symbols` section in template.json, which defines parameters that users can pass when creating from a template.] + + + +## Template packages + +[Explain what a template package is: a NuGet package containing one or more templates. Describe how packages enable distribution of templates.] + + + +## Install and uninstall templates + +[Describe how to install templates from the various sources and how to list and uninstall them.] + + + +## Template localization + +[Explain that templates support localization so template metadata appears in the user's language.] + + + +## Visual Studio integration + +[Explain how templates created with the .NET template engine also appear and work in Visual Studio.] + + + +## Related content + +- [Tutorial: Create an item template](../tutorials/cli-templates-create-item-template.md) +- [Tutorial: Create a project template](../tutorials/cli-templates-create-project-template.md) +- [Tutorial: Create a template package](../tutorials/cli-templates-create-template-package.md) +- [dotnet new command](dotnet-new.md) +- [dotnet/templating GitHub repo wiki](https://github.com/dotnet/templating/wiki) +- [Template samples](https://aka.ms/template-samples) From 616cdf8310ac1c9992e4eda515c28e930563c51f Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Tue, 28 Jul 2026 15:11:37 -0700 Subject: [PATCH 02/11] Finish template types section --- docs/core/tools/templates.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md index 8db87cb80c787..165127d7b2c7d 100644 --- a/docs/core/tools/templates.md +++ b/docs/core/tools/templates.md @@ -53,6 +53,7 @@ The following files were used as source material: - Tutorial 1 (item template): docs/core/tutorials/cli-templates-create-item-template.md - Tutorial 2 (project template): docs/core/tutorials/cli-templates-create-project-template.md - Tutorial 3 (template package): docs/core/tutorials/cli-templates-create-template-package.md +- template.json schema: https://www.schemastore.org/template.json When linking to these tutorials, use relative paths from docs/core/tools/. When linking to learn.microsoft.com content, use the /dotnet/... URL path. @@ -74,17 +75,29 @@ When linking to learn.microsoft.com content, use the /dotnet/... URL path. ## Template types -[Explain the two main types of templates: item templates and project templates. Describe what each type produces and when to use each.] - +The .NET template engine supports three types of templates: item templates, project templates, and solution templates. + +- **Item templates** generate one or more files, such as a code file, configuration file, or other resource, without generating an entire project around them. For example, an item template might produce a class file that adds a set of extension methods, or a JSON configuration file that follows a standard layout your team uses. To learn how to build an item template, see [Tutorial: Create an item template](../tutorials/cli-templates-create-item-template.md). + +- **Project templates** generate a complete project structure. When you run `dotnet new console`, for example, the console project template produces a `.csproj` file, a `Program.cs` file, and any other files that make up the project. Use a project template when you want to give users a full project starting point rather than individual files. To learn how to build a project template, see [Tutorial: Create a project template](../tutorials/cli-templates-create-project-template.md). + +- **Solution templates** generate a solution with one or more projects. Use a solution template when you want to scaffold an entire multi-project structure — for example, an API project paired with a test project — in a single step. + +When you create your own template, you declare its type using the `tags.type` field in the `template.json` configuration file. The valid values are `"project"`, `"item"`, and `"solution"`. These values let users filter results when they search for templates with `dotnet new search` or `dotnet new list`. + +> [!TIP] +> Project templates appear in the Visual Studio **Create a new project** dialog, but item templates don't appear in the **Add** > **New Item** dialog. You can use item templates from the `dotnet new` CLI. + ## Template structure [Explain how a template is structured on disk — the source files plus the required `.template.config/template.json` configuration file.] From 302929b0f25afbf750014a40daf8dc3e9c0bdfbd Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Tue, 28 Jul 2026 16:47:34 -0700 Subject: [PATCH 03/11] Finish template structure section --- docs/core/tools/templates.md | 91 +++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md index 165127d7b2c7d..d3de2c276056e 100644 --- a/docs/core/tools/templates.md +++ b/docs/core/tools/templates.md @@ -100,8 +100,6 @@ When you create your own template, you declare its type using the `tags.type` fi ## Template structure -[Explain how a template is structured on disk — the source files plus the required `.template.config/template.json` configuration file.] - -### The template.json file +A template is a folder on disk that contains two things: your source files and a special `.template.config` subfolder. When you run `dotnet new `, the template engine copies your source files to the output location and applies any configuration you've defined. + +```text +mytemplate/ +├── console.cs +├── readme.txt +└── .template.config/ + └── template.json +``` + +The source files can be any type of file. The template engine doesn't require you to inject special tokens or markers into your source code. It uses your files as-is, which means you can build, run, and debug a template's source project exactly like a normal .NET project. To turn an existing project into a template, add a `.template.config/template.json` file to the project root. + +You can optionally inject substitution tokens tied to template parameters (symbols) directly into your source files and file names, but doing so means those files are no longer runnable as a normal .NET project. -[Explain the `template.json` configuration file: what it does, required fields, and optional fields that enable advanced features.] +The only required file inside `.template.config` is `template.json`. That file tells the template engine everything it needs: the template's name, short name, author, classifications, and any parameters users can pass when they create from the template. + +### The template.json file -### Template parameters (symbols) +The `template.json` file is the only required piece of configuration in a template. It lives inside the `.template.config` folder and tells the template engine how to present and process your template. The following table describes the common fields: + +| Field | Type | Description | +|---|---|---| +| `$schema` | URI | The JSON schema for `template.json`. Set to `https://json.schemastore.org/template` to enable IntelliSense in editors like Visual Studio Code. | +| `author` | string | The author of the template. | +| `classifications` | array(string) | Tags users can use to find the template with `dotnet new search` or `dotnet new list`. These appear in the **Tags** column of the template list. | +| `identity` | string | A unique identifier for this template. | +| `name` | string | The display name of the template shown to users. | +| `shortName` | string | The short name users pass to `dotnet new` to create from this template, such as `console` or `classlib`. | +| `sourceName` | string | A string in your source files and file names that the template engine replaces with the name the user provides via `-n` or `--name`. If the user doesn't provide a name, the current directory name is used. | +| `preferNameDirectory` | boolean | When `true` and the user provides a name but no output directory, the template engine creates a new directory with that name instead of writing files into the current directory. Defaults to `false`. | + +Two fields deserve extra attention. The `sourceName` field is how templates handle naming: set it to a string that appears in your file names and source code (such as `MyTemplate`), and the template engine replaces every occurrence with whatever name the user passes when creating the template. The `classifications` field controls discoverability — choose tags that accurately describe your template's purpose so users can find it when searching. + +Here's a minimal `template.json` for a console template: + +```json +{ + "$schema": "https://json.schemastore.org/template", + "author": "Your Name", + "classifications": [ "Common", "Console" ], + "identity": "MyCompany.ConsoleTemplate.CSharp", + "name": "My Console App", + "shortName": "myconsole", + "sourceName": "MyConsoleApp" +} +``` + +The full schema is available at [JSON Schema Store](https://www.schemastore.org/template.json). For advanced configuration options such as conditional file inclusion, post-creation actions, and multi-project templates, see the [dotnet/templating GitHub wiki](https://github.com/dotnet/templating/wiki). -[Explain the `symbols` section in template.json, which defines parameters that users can pass when creating from a template.] +### Template parameters (symbols) +The `symbols` section in `template.json` defines the parameters users can pass when creating from your template. Each symbol becomes a CLI option on `dotnet new `, so a symbol named `ClassName` becomes `--ClassName` (or `-C` if you define a short name). + +Each symbol entry supports the following common settings: + +| Setting | Description | +|---|---| +| `type` | Must be `"parameter"` for user-facing parameters. | +| `description` | Shown in the template help output when users run `dotnet new -?`. | +| `datatype` | The expected data type, such as `"text"`, `"bool"`, or `"choice"`. | +| `replaces` | A string in your source file contents that the template engine replaces with the parameter value. | +| `fileRename` | A string in your source file names that the template engine replaces with the parameter value. | +| `defaultValue` | The value used when the user doesn't supply the parameter. | + +The `replaces` and `fileRename` settings are how symbols drive substitution. When a user provides a value, the template engine replaces every occurrence of the `replaces` string inside file contents and every occurrence of the `fileRename` string in file names. If the user doesn't provide a value, the `defaultValue` is used instead. + +For example, the following symbol lets users set the class name when they create from the template. The file is renamed and the class inside it is updated to match: + +```json +"symbols": { + "ClassName": { + "type": "parameter", + "description": "The name of the code file and class.", + "datatype": "text", + "replaces": "StringExtensions", + "fileRename": "StringExtensions", + "defaultValue": "StringExtensions" + } +} +``` + +With this symbol defined, a user can run `dotnet new --ClassName MyHelpers` to produce a file named `MyHelpers.cs` containing a class named `MyHelpers`. Without the flag, the file and class keep the default name `StringExtensions`. + +To see all available parameters for any installed template, pass `-?` to the template's short name: + +```dotnetcli +dotnet new -? +``` + ## Template packages [Explain what a template package is: a NuGet package containing one or more templates. Describe how packages enable distribution of templates.] From 79e063c120d07e1a5e1211c0521d9723b638bef8 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Tue, 28 Jul 2026 16:55:53 -0700 Subject: [PATCH 04/11] Finish template packages --- docs/core/tools/templates.md | 84 +++++++++++------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md index d3de2c276056e..61e8c1ff7fa0b 100644 --- a/docs/core/tools/templates.md +++ b/docs/core/tools/templates.md @@ -100,23 +100,6 @@ When you create your own template, you declare its type using the `tags.type` fi ## Template structure - - A template is a folder on disk that contains two things: your source files and a special `.template.config` subfolder. When you run `dotnet new `, the template engine copies your source files to the output location and applies any configuration you've defined. ```text @@ -135,31 +118,20 @@ The only required file inside `.template.config` is `template.json`. That file t ### The template.json file - - The `template.json` file is the only required piece of configuration in a template. It lives inside the `.template.config` folder and tells the template engine how to present and process your template. The following table describes the common fields: -| Field | Type | Description | -|---|---|---| -| `$schema` | URI | The JSON schema for `template.json`. Set to `https://json.schemastore.org/template` to enable IntelliSense in editors like Visual Studio Code. | -| `author` | string | The author of the template. | -| `classifications` | array(string) | Tags users can use to find the template with `dotnet new search` or `dotnet new list`. These appear in the **Tags** column of the template list. | -| `identity` | string | A unique identifier for this template. | -| `name` | string | The display name of the template shown to users. | -| `shortName` | string | The short name users pass to `dotnet new` to create from this template, such as `console` or `classlib`. | -| `sourceName` | string | A string in your source files and file names that the template engine replaces with the name the user provides via `-n` or `--name`. If the user doesn't provide a name, the current directory name is used. | -| `preferNameDirectory` | boolean | When `true` and the user provides a name but no output directory, the template engine creates a new directory with that name instead of writing files into the current directory. Defaults to `false`. | +| Field | Type | Description | +|-----------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `$schema` | URI | The JSON schema for `template.json`. Set to `https://json.schemastore.org/template` to enable IntelliSense in editors like Visual Studio Code. | +| `author` | string | The author of the template. | +| `classifications` | array(string) | Tags users can use to find the template with `dotnet new search` or `dotnet new list`. These appear in the **Tags** column of the template list. | +| `identity` | string | A unique identifier for this template. | +| `name` | string | The display name of the template shown to users. | +| `shortName` | string | The short name users pass to `dotnet new` to create from this template, such as `console` or `classlib`. | +| `sourceName` | string | A string in your source files and file names that the template engine replaces with the name the user provides via `-n` or `--name`. If the user doesn't provide a name, the current directory name is used. | +| `preferNameDirectory` | boolean | When `true` and the user provides a name but no output directory, the template engine creates a new directory with that name instead of writing files into the current directory. Defaults to `false`. | -Two fields deserve extra attention. The `sourceName` field is how templates handle naming: set it to a string that appears in your file names and source code (such as `MyTemplate`), and the template engine replaces every occurrence with whatever name the user passes when creating the template. The `classifications` field controls discoverability — choose tags that accurately describe your template's purpose so users can find it when searching. +Two fields deserve extra attention. The `sourceName` field is how templates handle naming: set it to a string that appears in your file names and source code (such as `MyTemplate`), and the template engine replaces every occurrence with whatever name the user passes when creating the template. The `classifications` field controls discoverability; choose tags that accurately describe your template's purpose so users can find it when searching. Here's a minimal `template.json` for a console template: @@ -179,15 +151,6 @@ The full schema is available at [JSON Schema Store](https://www.schemastore.org/ ### Template parameters (symbols) - - The `symbols` section in `template.json` defines the parameters users can pass when creating from your template. Each symbol becomes a CLI option on `dotnet new `, so a symbol named `ClassName` becomes `--ClassName` (or `-C` if you define a short name). Each symbol entry supports the following common settings: @@ -228,17 +191,20 @@ dotnet new -? ## Template packages -[Explain what a template package is: a NuGet package containing one or more templates. Describe how packages enable distribution of templates.] +A template package is a NuGet (_.nupkg_) file that bundles one or more templates together. When you install a template package, the .NET template engine registers every template inside it at once. This makes packages the standard way to distribute templates: you can publish a single package to nuget.org, a private NuGet feed, or share a local _.nupkg_ file, and users install the whole collection with one command. - +To build a template package, you use a C# project file (_.csproj_) configured to act as a **packaging project** rather than a compilation project. The key settings that make this work are: + +| Setting | Value | Purpose | +|------------------------|------------|--------------------------------------------------------------| +| `PackageType` | `Template` | Marks the package as a template package so it appears in `dotnet new search` results. | +| `IncludeContentInPack` | `true` | Includes content files in the NuGet package. | +| `IncludeBuildOutput` | `false` | Prevents compiled binaries from being added to the package. | +| `ContentTargetFolders` | `content` | Places your template folders inside the `content` folder of the NuGet package, which is where the template engine expects to find them. | + +The easiest way to create a packaging project is the `templatepack` project template, provided by the [Microsoft.TemplateEngine.Authoring.Templates](https://www.nuget.org/packages/Microsoft.TemplateEngine.Authoring.Templates) NuGet package. Install that package once, then run `dotnet new templatepack -n ` to scaffold a ready-to-use packaging project. The generated project already includes the correct `.csproj` settings, a `content` folder for your templates, and MSBuild tasks for template validation and optional localization. + +For a full walkthrough of creating, packing, and publishing a template package, see [Tutorial: Create a template package](../tutorials/cli-templates-create-template-package.md). ## Install and uninstall templates @@ -276,7 +242,7 @@ dotnet new -? [Explain how templates created with the .NET template engine also appear and work in Visual Studio.] +- A NuGet package ID, which installs the latest version from nuget.org: + + ```dotnetcli + dotnet new install AdatumCorporation.ConsoleTemplate.CSharp + ``` + +- A NuGet package ID with a custom feed URL, using `--nuget-source` to point to a private or internal NuGet feed: + + ```dotnetcli + dotnet new install AdatumCorporation.ConsoleTemplate.CSharp --nuget-source https://mynugetfeed.example.com/v3/index.json + ``` + +- A path to a local _.nupkg_ file: + + ```dotnetcli + dotnet new install ./AdatumCorporation.ConsoleTemplate.CSharp.1.0.0.nupkg + ``` + +- A path to a directory that contains the template (the folder with `.template.config` inside): + + ```dotnetcli + dotnet new install ./mytemplate/ + ``` + + Installing from a directory is especially useful during template development because it lets you test your template without packing it first. + +> [!WARNING] +> Templates can execute MSBuild tasks and arbitrary code during project creation. Only install templates from sources you trust. + +To see all installed template packages and the exact command to uninstall each one, run `dotnet new uninstall` with no arguments: + +```dotnetcli +dotnet new uninstall +``` + +To uninstall a specific template package, pass the NuGet package ID or the file system path that you used when you installed it: + +```dotnetcli +dotnet new uninstall AdatumCorporation.ConsoleTemplate.CSharp +``` + +The built-in SDK templates don't appear in the uninstall list and can't be removed with `dotnet new uninstall`. ## Template localization From d7f2c40c5c906ab086f5df7594ad9b87bc097d93 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Tue, 28 Jul 2026 17:24:46 -0700 Subject: [PATCH 06/11] Finish template visual studio --- docs/core/tools/templates.md | 91 ++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md index 21cca96cfac31..68f4d6a6f0172 100644 --- a/docs/core/tools/templates.md +++ b/docs/core/tools/templates.md @@ -75,16 +75,6 @@ When linking to learn.microsoft.com content, use the /dotnet/... URL path. ## Template types - - The .NET template engine supports three types of templates: item templates, project templates, and solution templates. - **Item templates** generate one or more files, such as a code file, configuration file, or other resource, without generating an entire project around them. For example, an item template might produce a class file that adds a set of extension methods, or a JSON configuration file that follows a standard layout your team uses. To learn how to build an item template, see [Tutorial: Create an item template](../tutorials/cli-templates-create-item-template.md). @@ -96,7 +86,7 @@ The .NET template engine supports three types of templates: item templates, proj When you create your own template, you declare its type using the `tags.type` field in the `template.json` configuration file. The valid values are `"project"`, `"item"`, and `"solution"`. These values let users filter results when they search for templates with `dotnet new search` or `dotnet new list`. > [!TIP] -> Project templates appear in the Visual Studio **Create a new project** dialog, but item templates don't appear in the **Add** > **New Item** dialog. You can use item templates from the `dotnet new` CLI. +> Project and solution templates appear in the Visual Studio **Create a new project** dialog, but item templates don't appear in the **Add** > **New Item** dialog. You can use item templates from the `dotnet new` CLI. ## Template structure @@ -107,14 +97,15 @@ mytemplate/ ├── console.cs ├── readme.txt └── .template.config/ - └── template.json + ├── template.json + └── icon.png ``` The source files can be any type of file. The template engine doesn't require you to inject special tokens or markers into your source code. It uses your files as-is, which means you can build, run, and debug a template's source project exactly like a normal .NET project. To turn an existing project into a template, add a `.template.config/template.json` file to the project root. You can optionally inject substitution tokens tied to template parameters (symbols) directly into your source files and file names, but doing so means those files are no longer runnable as a normal .NET project. -The only required file inside `.template.config` is `template.json`. That file tells the template engine everything it needs: the template's name, short name, author, classifications, and any parameters users can pass when they create from the template. +The only required file inside `.template.config` is `template.json`. That file tells the template engine everything it needs: the template's name, short name, author, classifications, and any parameters users can pass when they create from the template. You can also place an `icon.png` file in the `.template.config` folder. The terminal doesn't display icons, but Visual Studio shows the icon next to your template in the **Create a new project** dialog. A 128×128 PNG works well. ### The template.json file @@ -255,29 +246,67 @@ The built-in SDK templates don't appear in the uninstall list and can't be remov ## Template localization -[Explain that templates support localization so template metadata appears in the user's language.] +The .NET template engine supports optional localization of template metadata. When you provide localization files, hosts such as `dotnet new` and the Visual Studio **New Project** dialog display the template's name, description, and symbol information in the user's language instead of the original authored language. - +The following template fields support localization: + +- `name` +- `author` +- `description` +- Symbol `description` and `displayName` +- Description and display name for each choice in a choice parameter +- Post action `description` and `manualInstructions` + +To add localization, create a `localize` subfolder inside `.template.config` and add one JSON file per language. Name each file `templatestrings..json`, where `` matches a valid name, such as `pt-BR`, `zh-Hans`, or `de`. Each file contains key-value pairs where the key is a path to the element in `template.json`, using `/` as a delimiter for nested fields. + +For example, given a `template.json` with the following content: + +```json +{ + "$schema": "https://json.schemastore.org/template", + "author": "Microsoft", + "classifications": [ "Config" ], + "name": "EditorConfig file", + "description": "Creates an .editorconfig file for configuring code style preferences.", + "symbols": { + "Empty": { + "type": "parameter", + "datatype": "bool", + "defaultValue": "false", + "displayName": "Empty", + "description": "Creates empty .editorconfig instead of the defaults for .NET." + } + } +} +``` + +A Brazilian Portuguese localization file named `templatestrings.pt-BR.json` would look like this: + +```json +{ + "author": "Microsoft", + "name": "Arquivo EditorConfig", + "description": "Cria um arquivo .editorconfig para configurar as preferências de estilo de código.", + "symbols/Empty/displayName": "Vazio", + "symbols/Empty/description": "Cria .editorconfig vazio em vez dos padrões para .NET." +} +``` + +The template engine parses these files when it loads template information, and it returns localized values automatically based on the current UI culture—no extra steps are required from the user. + +Localization is optional. If you don't include localization files, the template works normally and always displays the values from `template.json`. For more information, see the [dotnet/templating wiki localization page](https://aka.ms/templating-localization). ## Visual Studio integration -[Explain how templates created with the .NET template engine also appear and work in Visual Studio.] +Visual Studio's **Create a new project** dialog uses the .NET template engine for .NET project templates. Templates you create for `dotnet new` work in Visual Studio too, without any extra configuration. When you install a template package with `dotnet new install`, Visual Studio automatically detects and surfaces those templates in the dialog. - +**Project and solution templates** appear in the **Create a new project** dialog alongside the built-in SDK templates. Users can find your template by name, language, or by the tags from the `classifications` field in `template.json`. Accurate classifications help your template surface in the right filter categories, so choose them carefully. To give your template a polished appearance in the dialog, add an `icon.png` to the `.template.config` folder — Visual Studio displays it next to your template's name. + +**Item templates** don't currently appear in the **Add** > **New Item** dialog. Users can still create from item templates using `dotnet new ` in the terminal, but Visual Studio doesn't surface them in its item-creation UI. + +To make your template discoverable to Visual Studio users who haven't installed it yet, publish your template package to nuget.org. The **Create a new project** dialog includes an **Install more templates from the online search** option that searches nuget.org for template packages. When a user installs your package through that option, Visual Studio uses the same install mechanism as `dotnet new install`. + +For deeper guidance on Visual Studio-specific integration—such as controlling template sort order and configuring additional IDE-specific options—see [Sayed Hashimi's template-sample repository](https://github.com/sayedihashimi/template-sample). ## Related content From 60d4445e877e39db4fa77495caff5664ddf79ff7 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 29 Jul 2026 15:09:34 -0700 Subject: [PATCH 07/11] Finish up --- docs/core/tools/templates.md | 135 ++++++++++++++--------------------- 1 file changed, 55 insertions(+), 80 deletions(-) diff --git a/docs/core/tools/templates.md b/docs/core/tools/templates.md index 68f4d6a6f0172..6afe8904da27a 100644 --- a/docs/core/tools/templates.md +++ b/docs/core/tools/templates.md @@ -4,74 +4,20 @@ description: Learn how .NET templates work, how they're structured, and what you author: adegeo ms.author: adegeo ms.topic: overview -ms.date: 07/28/2026 +ms.date: 07/29/2026 ai-usage: ai-assisted #customer intent: As a .NET developer, I want to understand how .NET templates work so that I can use, create, and distribute templates for projects and files. --- - - # What are .NET templates? -[Introduce the .NET template system: what templates are, what they produce (projects, files, resources), and why they exist. Mention that both the `dotnet new` CLI command and Visual Studio use the same template engine. Briefly mention built-in templates that ship with the SDK and the ability to install community or custom templates.] +A .NET template is a blueprint that generates projects, files, or other resources from a predefined structure. When you run `dotnet new console`, the .NET template engine reads the console project template and produces a working project in your current directory. Visual Studio's **Create a new project** dialog also uses the .NET template engine for .NET project templates, so templates you create for the CLI work in Visual Studio too. + +The .NET SDK ships with built-in templates for common starting points like console apps, class libraries, and ASP.NET projects. To see every template currently installed, run `dotnet new list`. Beyond the built-in templates, you can install community templates from NuGet or build your own. - +This article focuses on how templates are structured. It also provides an overview of how to install and distribute templates. For step-by-step instructions to create and package templates, see the [Related content](#related-content) section. ## Template types @@ -103,24 +49,26 @@ mytemplate/ The source files can be any type of file. The template engine doesn't require you to inject special tokens or markers into your source code. It uses your files as-is, which means you can build, run, and debug a template's source project exactly like a normal .NET project. To turn an existing project into a template, add a `.template.config/template.json` file to the project root. -You can optionally inject substitution tokens tied to template parameters (symbols) directly into your source files and file names, but doing so means those files are no longer runnable as a normal .NET project. +You can optionally inject substitution tokens tied to template parameters (symbols) directly into your source files and file names. If the tokens aren't valid source code, you can't build, run, or debug the source project before you deploy it as a template. The tokens don't affect projects that users create from the deployed template because the template engine replaces them during project creation. The only required file inside `.template.config` is `template.json`. That file tells the template engine everything it needs: the template's name, short name, author, classifications, and any parameters users can pass when they create from the template. You can also place an `icon.png` file in the `.template.config` folder. The terminal doesn't display icons, but Visual Studio shows the icon next to your template in the **Create a new project** dialog. A 128×128 PNG works well. ### The template.json file -The `template.json` file is the only required piece of configuration in a template. It lives inside the `.template.config` folder and tells the template engine how to present and process your template. The following table describes the common fields: - -| Field | Type | Description | -|-----------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `$schema` | URI | The JSON schema for `template.json`. Set to `https://json.schemastore.org/template` to enable IntelliSense in editors like Visual Studio Code. | -| `author` | string | The author of the template. | -| `classifications` | array(string) | Tags users can use to find the template with `dotnet new search` or `dotnet new list`. These appear in the **Tags** column of the template list. | -| `identity` | string | A unique identifier for this template. | -| `name` | string | The display name of the template shown to users. | -| `shortName` | string | The short name users pass to `dotnet new` to create from this template, such as `console` or `classlib`. | -| `sourceName` | string | A string in your source files and file names that the template engine replaces with the name the user provides via `-n` or `--name`. If the user doesn't provide a name, the current directory name is used. | -| `preferNameDirectory` | boolean | When `true` and the user provides a name but no output directory, the template engine creates a new directory with that name instead of writing files into the current directory. Defaults to `false`. | +The `template.json` file is the only required piece of configuration in a template. It lives inside the `.template.config` folder and tells the template engine how to present and process your template. The following table describes common required and optional fields: + +| Field | Type | Required | Description | +|-----------------------|---------------|----------|-------------| +| `$schema` | URI | No | The JSON schema for `template.json`. Set to `https://json.schemastore.org/template` to enable IntelliSense in editors like Visual Studio Code. | +| `author` | string | No | The author of the template. | +| `classifications` | array(string) | No | Tags users can use to find the template with `dotnet new search` or `dotnet new list`. These values appear in the **Tags** column of the template list. | +| `description` | string | No | A description of what the template creates. | +| `identity` | string | Yes | A unique identifier for the template. | +| `name` | string | Yes | The display name of the template shown to users. | +| `shortName` | string | Yes | The short name users pass to `dotnet new` to create from the template, such as `console` or `classlib`. | +| `sourceName` | string | No | A string in your source files and file names that the template engine replaces with the name the user provides via `-n` or `--name`. If the user doesn't provide a name, the engine uses the current directory name. | +| `preferNameDirectory` | boolean | No | When `true` and the user provides a name but no output directory, the template engine creates a new directory with that name instead of writing files into the current directory. The default is `false`. | +| `tags` | object | No | Metadata that identifies properties such as the template language and type. Use `tags.language` for the language and `tags.type` for `project`, `item`, or `solution`. | Two fields deserve extra attention. The `sourceName` field is how templates handle naming: set it to a string that appears in your file names and source code (such as `MyTemplate`), and the template engine replaces every occurrence with whatever name the user passes when creating the template. The `classifications` field controls discoverability; choose tags that accurately describe your template's purpose so users can find it when searching. @@ -131,10 +79,15 @@ Here's a minimal `template.json` for a console template: "$schema": "https://json.schemastore.org/template", "author": "Your Name", "classifications": [ "Common", "Console" ], + "description": "Creates a console application.", "identity": "MyCompany.ConsoleTemplate.CSharp", "name": "My Console App", "shortName": "myconsole", - "sourceName": "MyConsoleApp" + "sourceName": "MyConsoleApp", + "tags": { + "language": "C#", + "type": "project" + } } ``` @@ -182,9 +135,9 @@ dotnet new -? ## Template packages -A template package is a NuGet (_.nupkg_) file that bundles one or more templates together. When you install a template package, the .NET template engine registers every template inside it at once. This makes packages the standard way to distribute templates: you can publish a single package to nuget.org, a private NuGet feed, or share a local _.nupkg_ file, and users install the whole collection with one command. +A template package is a NuGet (`.nupkg`) file that bundles one or more templates together. When you install a template package, the .NET template engine registers every template inside it at once. Packages are the standard way to distribute templates. You can publish a single package to NuGet.org or a private NuGet feed, or share a local `.nupkg` file. Users install the whole collection with one command. -To build a template package, you use a C# project file (_.csproj_) configured to act as a **packaging project** rather than a compilation project. The key settings that make this work are: +To build a template package, use a C# project file (`.csproj`) configured to act as a **packaging project** rather than a compilation project. The key settings that make this work are: | Setting | Value | Purpose | |------------------------|------------|--------------------------------------------------------------| @@ -193,7 +146,21 @@ To build a template package, you use a C# project file (_.csproj_) configured to | `IncludeBuildOutput` | `false` | Prevents compiled binaries from being added to the package. | | `ContentTargetFolders` | `content` | Places your template folders inside the `content` folder of the NuGet package, which is where the template engine expects to find them. | -The easiest way to create a packaging project is the `templatepack` project template, provided by the [Microsoft.TemplateEngine.Authoring.Templates](https://www.nuget.org/packages/Microsoft.TemplateEngine.Authoring.Templates) NuGet package. Install that package once, then run `dotnet new templatepack -n ` to scaffold a ready-to-use packaging project. The generated project already includes the correct `.csproj` settings, a `content` folder for your templates, and MSBuild tasks for template validation and optional localization. +The `templatepack` project template provides the easiest way to create a packaging project: + +1. Install the [Microsoft.TemplateEngine.Authoring.Templates](https://www.nuget.org/packages/Microsoft.TemplateEngine.Authoring.Templates) NuGet package: + + ```dotnetcli + dotnet new install Microsoft.TemplateEngine.Authoring.Templates + ``` + +1. Create the packaging project: + + ```dotnetcli + dotnet new templatepack -n + ``` + +The generated project includes the correct `.csproj` settings, a `content` folder for your templates, and MSBuild tasks for template validation and optional localization. For a full walkthrough of creating, packing, and publishing a template package, see [Tutorial: Create a template package](../tutorials/cli-templates-create-template-package.md). @@ -201,19 +168,19 @@ For a full walkthrough of creating, packing, and publishing a template package, To install a template, use the `dotnet new install` command with a source argument. The source can be any of the following: -- A NuGet package ID, which installs the latest version from nuget.org: +- A NuGet package ID, which installs the latest stable version from the NuGet sources configured for the current directory: ```dotnetcli dotnet new install AdatumCorporation.ConsoleTemplate.CSharp ``` -- A NuGet package ID with a custom feed URL, using `--nuget-source` to point to a private or internal NuGet feed: +- A NuGet package ID with a custom feed URL. The `--nuget-source` option uses the specified feed, in addition to the configured NuGet sources, for this installation command only: ```dotnetcli dotnet new install AdatumCorporation.ConsoleTemplate.CSharp --nuget-source https://mynugetfeed.example.com/v3/index.json ``` -- A path to a local _.nupkg_ file: +- A path to a local `.nupkg` file: ```dotnetcli dotnet new install ./AdatumCorporation.ConsoleTemplate.CSharp.1.0.0.nupkg @@ -236,12 +203,20 @@ To see all installed template packages and the exact command to uninstall each o dotnet new uninstall ``` -To uninstall a specific template package, pass the NuGet package ID or the file system path that you used when you installed it: +To uninstall a specific template package, pass its identifier. For a package installed from a NuGet source or a local `.nupkg` file, use the NuGet package ID. For a template installed from a directory, use the directory path. + +Use the package ID to uninstall a NuGet package: ```dotnetcli dotnet new uninstall AdatumCorporation.ConsoleTemplate.CSharp ``` +Use the directory path to uninstall a template installed from a directory: + +```dotnetcli +dotnet new uninstall ./mytemplate/ +``` + The built-in SDK templates don't appear in the uninstall list and can't be removed with `dotnet new uninstall`. ## Template localization From 40c8fb305db3b4f5005ed0bb15518e6d2c52fe23 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 29 Jul 2026 15:09:52 -0700 Subject: [PATCH 08/11] Redirect; TOC; Links --- .openpublishing.redirection.core.json | 4 + docs/core/tools/custom-templates.md | 325 ------------------ docs/core/tools/dotnet-new-details.md | 2 +- docs/core/tools/dotnet-new-install.md | 2 +- docs/core/tools/dotnet-new-list.md | 2 +- docs/core/tools/dotnet-new-sdk-templates.md | 2 +- docs/core/tools/dotnet-new-search.md | 2 +- docs/core/tools/dotnet-new-uninstall.md | 2 +- docs/core/tools/dotnet-new-update.md | 2 +- docs/core/tools/dotnet-new.md | 2 +- .../cli-templates-create-template-package.md | 4 +- docs/navigate/tools-diagnostics/toc.yml | 4 +- 12 files changed, 16 insertions(+), 337 deletions(-) delete mode 100644 docs/core/tools/custom-templates.md diff --git a/.openpublishing.redirection.core.json b/.openpublishing.redirection.core.json index 225cad1072d97..285c5abb30a31 100644 --- a/.openpublishing.redirection.core.json +++ b/.openpublishing.redirection.core.json @@ -1707,6 +1707,10 @@ "source_path_from_root": "/docs/core/tools/csproj.md", "redirect_url": "/dotnet/core/project-sdk/msbuild-props" }, + { + "source_path_from_root": "/docs/core/tools/custom-templates.md", + "redirect_url": "/dotnet/core/tools/templates" + }, { "source_path_from_root": "/docs/core/tools/dotnet-add-package.md", "redirect_url": "/dotnet/core/tools/dotnet-package-add" diff --git a/docs/core/tools/custom-templates.md b/docs/core/tools/custom-templates.md deleted file mode 100644 index 8d9b73a116d18..0000000000000 --- a/docs/core/tools/custom-templates.md +++ /dev/null @@ -1,325 +0,0 @@ ---- -title: Custom templates for dotnet new -description: Learn about custom templates for any type of .NET project or files. -author: adegeo -ms.date: 05/20/2020 ---- - -# Custom templates for dotnet new - -The [.NET SDK](https://dotnet.microsoft.com/download) comes with many templates already installed and ready for you to use. The [`dotnet new` command](dotnet-new.md) isn't only the way to use a template, but also how to install and uninstall templates. You can create your own custom templates for any type of project, such as an app, service, tool, or class library. You can even create a template that outputs one or more independent files, such as a configuration file. - -You can install custom templates from a NuGet package on any NuGet feed, by referencing a NuGet *.nupkg* file directly, or by specifying a file system directory that contains the template. The template engine offers features that allow you to replace values, include and exclude files, and execute custom processing operations when your template is used. - -The template engine is open source, and the online code repository is at [dotnet/templating](https://github.com/dotnet/templating/) on GitHub. More templates, including templates from third parties, can be found using [`dotnet new search`](dotnet-new-search.md). For more information about creating and using custom templates, see [How to create your own templates for dotnet new](https://devblogs.microsoft.com/dotnet/how-to-create-your-own-templates-for-dotnet-new/) and the [dotnet/templating GitHub repo Wiki](https://github.com/dotnet/templating/wiki). - -> [!NOTE] -> Template examples are available at the [dotnet/templating](https://aka.ms/template-samples) GitHub repository. - -To follow a walkthrough and create a template, see the [Create a custom template for dotnet new](../tutorials/cli-templates-create-item-template.md) tutorial. - -## .NET default templates - -When you install the [.NET SDK](https://dotnet.microsoft.com/download), you receive over a dozen built-in templates for creating projects and files, including console apps, class libraries, unit test projects, ASP.NET Core apps (including [Angular](https://angular.io/) and [React](https://reactjs.org/) projects), and configuration files. To list the built-in templates, run the `dotnet new list` command: - -```dotnetcli -dotnet new list -``` - -## Configuration - -A template is composed of the following parts: - -- Source files and folders. -- A configuration file (*template.json*). - -### Source files and folders - -The source files and folders include whatever files and folders you want the template engine to use when the `dotnet new