Skip to content

Commit 98ae93f

Browse files
committed
feat(sdk): add template support for project and item templates
Add MSBuild-based support for including VS project and item templates in VSIX packages, bypassing the broken VSIX Manifest Designer. New item types: - VsixProjectTemplate: folder-based project templates - VsixItemTemplate: folder-based item templates - VsixTemplateZip: pre-built template zip files - VsixTemplateReference: reference templates from another project Features: - Auto-discovery of templates in ProjectTemplates/ and ItemTemplates/ - Auto-zip folder-based templates during build - Hook into VSSDK's GetVsixSourceItems for VSIX inclusion - Build warnings for missing manifest Content entries (VSIXSDK010-014) Includes documentation in docs/templates.md. Closes #21 Closes #22
1 parent 43e9c23 commit 98ae93f

5 files changed

Lines changed: 581 additions & 0 deletions

File tree

docs/templates.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# Template Support
2+
3+
This document explains how to include Visual Studio project templates and item templates in your VSIX extension using CodingWithCalvin.VsixSdk.
4+
5+
## Background
6+
7+
The built-in VSIX Manifest Designer in Visual Studio cannot enumerate SDK-style projects when adding template assets. This is because the designer uses legacy DTE extenders that are registered for the old project system, not the Common Project System (CPS) used by SDK-style projects.
8+
9+
Additionally, SDK-style projects don't define the `TemplateProjectOutputGroup` and `ItemTemplateOutputGroup` MSBuild output groups that VSSDK expects for template assets.
10+
11+
This SDK provides MSBuild-based template support that bypasses these limitations entirely.
12+
13+
## Item Types
14+
15+
The SDK provides four item types for including templates:
16+
17+
| Item Type | Description |
18+
|-----------|-------------|
19+
| `VsixProjectTemplate` | A folder containing a `.vstemplate` file for a project template |
20+
| `VsixItemTemplate` | A folder containing a `.vstemplate` file for an item template |
21+
| `VsixTemplateZip` | A pre-built template zip file |
22+
| `VsixTemplateReference` | Reference a template folder from another project |
23+
24+
## Auto-Discovery
25+
26+
By default, the SDK automatically discovers templates in your project:
27+
28+
- **Project templates**: Any subfolder in `ProjectTemplates/` containing a `.vstemplate` file
29+
- **Item templates**: Any subfolder in `ItemTemplates/` containing a `.vstemplate` file
30+
31+
### Example Project Structure
32+
33+
```
34+
MyExtension/
35+
MyExtension.csproj
36+
source.extension.vsixmanifest
37+
ProjectTemplates/
38+
MyProjectTemplate/
39+
MyProjectTemplate.vstemplate
40+
MyProject.csproj
41+
Class1.cs
42+
ItemTemplates/
43+
MyItemTemplate/
44+
MyItemTemplate.vstemplate
45+
MyClass.cs
46+
```
47+
48+
With this structure, no additional configuration is needed. The SDK will:
49+
1. Find the templates automatically
50+
2. Zip each template folder during build
51+
3. Include the zips in the VSIX at `ProjectTemplates/` and `ItemTemplates/`
52+
53+
### Disabling Auto-Discovery
54+
55+
To disable automatic template discovery:
56+
57+
```xml
58+
<PropertyGroup>
59+
<EnableDefaultVsixTemplateItems>false</EnableDefaultVsixTemplateItems>
60+
</PropertyGroup>
61+
```
62+
63+
### Changing Default Folders
64+
65+
To use different folder names:
66+
67+
```xml
68+
<PropertyGroup>
69+
<VsixProjectTemplatesFolder>Templates\Projects</VsixProjectTemplatesFolder>
70+
<VsixItemTemplatesFolder>Templates\Items</VsixItemTemplatesFolder>
71+
</PropertyGroup>
72+
```
73+
74+
## Manual Template Configuration
75+
76+
### Folder-Based Templates
77+
78+
If your templates are in non-standard locations, add them explicitly:
79+
80+
```xml
81+
<ItemGroup>
82+
<VsixProjectTemplate Include="MyTemplates\ConsoleApp" />
83+
<VsixItemTemplate Include="MyTemplates\NewClass" />
84+
</ItemGroup>
85+
```
86+
87+
### Pre-Built Template Zips
88+
89+
If you have pre-built template zip files:
90+
91+
```xml
92+
<ItemGroup>
93+
<VsixTemplateZip Include="Templates\MyTemplate.zip" TemplateType="Project" />
94+
<VsixTemplateZip Include="Templates\MyItem.zip" TemplateType="Item" />
95+
</ItemGroup>
96+
```
97+
98+
### Template References
99+
100+
To include a template from another project in your solution:
101+
102+
```xml
103+
<ItemGroup>
104+
<VsixTemplateReference Include="..\MyTemplateProject\MyTemplateProject.csproj"
105+
TemplateType="Project"
106+
TemplatePath="Templates\MyProjectTemplate" />
107+
</ItemGroup>
108+
```
109+
110+
The `TemplatePath` is relative to the referenced project's directory.
111+
112+
## Manifest Configuration
113+
114+
Visual Studio requires `<Content>` entries in your `.vsixmanifest` to register templates. Add these to your manifest:
115+
116+
```xml
117+
<Content>
118+
<ProjectTemplate Path="ProjectTemplates" />
119+
<ItemTemplate Path="ItemTemplates" />
120+
</Content>
121+
```
122+
123+
The SDK will emit warnings if you have templates defined but missing manifest entries:
124+
- **VSIXSDK011**: Project templates defined but no `<ProjectTemplate>` in manifest
125+
- **VSIXSDK012**: Item templates defined but no `<ItemTemplate>` in manifest
126+
127+
## Target Subfolders
128+
129+
To organize templates into subfolders within the VSIX:
130+
131+
```xml
132+
<ItemGroup>
133+
<!-- Will be placed at ProjectTemplates/CSharp/ -->
134+
<VsixProjectTemplate Include="ProjectTemplates\MyTemplate" TargetSubPath="CSharp" />
135+
136+
<!-- Will be placed at ItemTemplates/Web/ -->
137+
<VsixItemTemplate Include="ItemTemplates\MyItem" TargetSubPath="Web" />
138+
</ItemGroup>
139+
```
140+
141+
## Complete Example
142+
143+
### Project File
144+
145+
```xml
146+
<Project Sdk="CodingWithCalvin.VsixSdk/1.0.0">
147+
148+
<PropertyGroup>
149+
<Version>1.0.0</Version>
150+
</PropertyGroup>
151+
152+
<!-- Templates are auto-discovered, but you can add more explicitly -->
153+
<ItemGroup>
154+
<VsixTemplateReference Include="..\SharedTemplates\SharedTemplates.csproj"
155+
TemplateType="Project"
156+
TemplatePath="Templates\SharedProject" />
157+
</ItemGroup>
158+
159+
</Project>
160+
```
161+
162+
### Manifest File
163+
164+
```xml
165+
<?xml version="1.0" encoding="utf-8"?>
166+
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
167+
<Metadata>
168+
<Identity Id="MyExtension" Version="1.0.0" Language="en-US" Publisher="MyCompany" />
169+
<DisplayName>My Extension</DisplayName>
170+
<Description>Extension with templates</Description>
171+
</Metadata>
172+
<Installation>
173+
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.0,19.0)">
174+
<ProductArchitecture>amd64</ProductArchitecture>
175+
</InstallationTarget>
176+
</Installation>
177+
<Content>
178+
<ProjectTemplate Path="ProjectTemplates" />
179+
<ItemTemplate Path="ItemTemplates" />
180+
</Content>
181+
</PackageManifest>
182+
```
183+
184+
### Template File (.vstemplate)
185+
186+
```xml
187+
<?xml version="1.0" encoding="utf-8"?>
188+
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
189+
<TemplateData>
190+
<Name>My Project Template</Name>
191+
<Description>A sample project template</Description>
192+
<Icon>__TemplateIcon.ico</Icon>
193+
<ProjectType>CSharp</ProjectType>
194+
<DefaultName>MyProject</DefaultName>
195+
<ProvideDefaultName>true</ProvideDefaultName>
196+
</TemplateData>
197+
<TemplateContent>
198+
<Project File="MyProject.csproj" ReplaceParameters="true">
199+
<ProjectItem ReplaceParameters="true">Class1.cs</ProjectItem>
200+
</Project>
201+
</TemplateContent>
202+
</VSTemplate>
203+
```
204+
205+
## Validation Warnings
206+
207+
| Code | Description |
208+
|------|-------------|
209+
| VSIXSDK010 | `VsixTemplateZip` item missing `TemplateType` metadata |
210+
| VSIXSDK011 | Project templates defined but no `<ProjectTemplate>` in manifest |
211+
| VSIXSDK012 | Item templates defined but no `<ItemTemplate>` in manifest |
212+
| VSIXSDK013 | `VsixTemplateReference` item missing `TemplateType` metadata |
213+
| VSIXSDK014 | `VsixTemplateReference` item missing `TemplatePath` metadata |
214+
215+
## Troubleshooting
216+
217+
### Templates not appearing in Visual Studio
218+
219+
1. Ensure your manifest has the appropriate `<Content>` entries
220+
2. Check that the template zip files are included in the VSIX (open the .vsix as a zip)
221+
3. Verify the `.vstemplate` file has correct `<ProjectType>` or `<TemplateGroupID>`
222+
4. Reset the Visual Studio template cache: delete `%LocalAppData%\Microsoft\VisualStudio\<version>\ComponentModelCache`
223+
224+
### Build errors about missing template folders
225+
226+
Ensure the template folder exists and contains a `.vstemplate` file. For `VsixTemplateReference`, verify the `TemplatePath` is correct relative to the referenced project.
227+
228+
### Templates in wrong location in VSIX
229+
230+
Check the `TargetSubPath` metadata if you're using custom paths. By default, templates are placed directly in `ProjectTemplates/` or `ItemTemplates/`.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<Project>
2+
<!--
3+
CodingWithCalvin.VsixSdk - Sdk.Vsix.Templates.props
4+
5+
Template support for VSIX projects. Defines item types for including
6+
project templates and item templates in VSIX packages.
7+
8+
This bypasses the broken VSIX Manifest Designer which cannot enumerate
9+
SDK-style projects for template assets.
10+
-->
11+
12+
<PropertyGroup>
13+
<!-- Enable/disable automatic template discovery -->
14+
<EnableDefaultVsixTemplateItems Condition="'$(EnableDefaultVsixTemplateItems)' == ''">true</EnableDefaultVsixTemplateItems>
15+
16+
<!-- Default folders for template discovery -->
17+
<VsixProjectTemplatesFolder Condition="'$(VsixProjectTemplatesFolder)' == ''">ProjectTemplates</VsixProjectTemplatesFolder>
18+
<VsixItemTemplatesFolder Condition="'$(VsixItemTemplatesFolder)' == ''">ItemTemplates</VsixItemTemplatesFolder>
19+
</PropertyGroup>
20+
21+
<!--
22+
Item type definitions:
23+
24+
VsixProjectTemplate - A folder containing a .vstemplate file for a project template
25+
Will be zipped and included in the VSIX at ProjectTemplates/
26+
27+
VsixItemTemplate - A folder containing a .vstemplate file for an item template
28+
Will be zipped and included in the VSIX at ItemTemplates/
29+
30+
VsixTemplateZip - A pre-built template zip file to include directly
31+
Specify TemplateType="Project" or TemplateType="Item"
32+
33+
VsixTemplateReference - Reference a template folder from another project
34+
Specify TemplateType="Project" or TemplateType="Item"
35+
TemplatePath is relative to the referenced project directory
36+
37+
Usage:
38+
<VsixProjectTemplate Include="ProjectTemplates\MyTemplate" />
39+
<VsixItemTemplate Include="ItemTemplates\MyItem" />
40+
<VsixTemplateZip Include="Templates\PreBuilt.zip" TemplateType="Project" />
41+
<VsixTemplateReference Include="..\MyTemplateProject\MyTemplateProject.csproj"
42+
TemplateType="Project"
43+
TemplatePath="Templates\MyProjectTemplate" />
44+
-->
45+
46+
<ItemDefinitionGroup>
47+
<VsixProjectTemplate>
48+
<!-- Default output subfolder within ProjectTemplates in the VSIX -->
49+
<TargetSubPath></TargetSubPath>
50+
</VsixProjectTemplate>
51+
52+
<VsixItemTemplate>
53+
<!-- Default output subfolder within ItemTemplates in the VSIX -->
54+
<TargetSubPath></TargetSubPath>
55+
</VsixItemTemplate>
56+
57+
<VsixTemplateZip>
58+
<!-- Must specify Project or Item -->
59+
<TemplateType></TemplateType>
60+
<!-- Optional subfolder within the template type folder -->
61+
<TargetSubPath></TargetSubPath>
62+
</VsixTemplateZip>
63+
64+
<VsixTemplateReference>
65+
<!-- Must specify Project or Item -->
66+
<TemplateType></TemplateType>
67+
<!-- Path to the template folder relative to the referenced project -->
68+
<TemplatePath></TemplatePath>
69+
<!-- Optional subfolder within the template type folder -->
70+
<TargetSubPath></TargetSubPath>
71+
</VsixTemplateReference>
72+
</ItemDefinitionGroup>
73+
74+
</Project>

0 commit comments

Comments
 (0)