Visual Studio

.NET Musings

Wandering thoughts of a developer, architect, speaker, and trainer

NAVIGATION - SEARCH

Creating a WinJS Project Template

In my last post, I showed how to implement the User Interface Guidelines for JavaScript based Windows Store Applications.  To make developing applications easier, I’ve created a Visual Studio Project Template that contains the HTML and CSS I described in that post.  If you are impatient, and just want the file, you can download it here.

Creating the Template from a Project

The first step is to create your project in Visual Studio.  If you would like to use the project that I built in my last post, you can download it here. Once you have created your project, select “Export Template…” from the File menu (shown in Figure 1).

image
Figure 1 – Exporting a template (File menu)

The Export Template wizard consists of two screens.  The first lets you choose between a Project Template or an Item Template, and select the solution item that will be the basis for the template.  Select “Project template” and the “SimpleLayout” project (if you are using my sample, otherwise select the project that you want to use at the project template).

image
Figure 2 – Export Template item selection screen

The second screen allows you to set the template options.  In addition to the Template Name, make sure the “Automatically import the template into Visual Studio” is not checked.  We will bring the template into Visual Studio later in this post. Figure 3 shows how I filled out the wizard for this example.

image
Figure 3 – Template Options

Once you have filled out the screens and click “Finish”, Visual Studio will create a .zip file in the directly shown in the Output location on the screen.  By default, this location is “My Documents\Visual Studio 2012\Exported Templates\[TemplateName].zip”

Modifying Template Files

The files added to the template .zip file must be modified using Visual Studio’s template parameters (for more information, see this MSDN article). To modify them, uncompress the .zip file into another directory. 

The Application Manifest

The first file to update is “package.appmanifest”.  There are three changes that need to be made:

  • The Name GUID and UserName in the <Identity> tag
  • The DisplayName and PublisherDisplayName in the <Properties> tag
  • The DisplayName and Description in the <VisualElements> tag

The template values that will be used are as follows:

  • $guid1$ – A GUID to replace the project GUID
  • $projectname$ – The name provided by the user in the New Project dialog box
  • $username$ – The current user name

NOTE: The templates are case sensitive.

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
  <Identity
    Name="$guid1$"
    Version="1.0.0.0"
    Publisher="CN=$username$" />
  <Properties>
    <DisplayName>$projectname$</DisplayName>
    <PublisherDisplayName>$username$</PublisherDisplayName>
    <Logo>images\storelogo.png</Logo>
  </Properties>
  <Prerequisites>
    <OSMinVersion>6.2.1</OSMinVersion>
    <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="x-generate" />
  </Resources>
  <Applications>
    <Application 
      Id="App"
      StartPage="default.html">
      <VisualElements
        DisplayName="$projectname$"
        Logo="images\logo.png"
        SmallLogo="images\smalllogo.png"
        Description="$projectname$"
        ForegroundText="light"
        BackgroundColor="#464646">
        <DefaultTile ShowName="allLogos" />
        <SplashScreen Image="images\splashscreen.png" />
      </VisualElements>
    </Application>
  </Applications>
  <Capabilities>
    <Capability Name="internetClient" />
  </Capabilities>
</Package>

Listing 1 – package.appmanifest

The Project File

The project file has three very important changes:

  • The GUID in the <ProjectGuid> tag
  • The name of the key file in the <PackageCertificateKeyFile> tag
  • The name of the key file in the list of items in the <ItemGroup> tag

For the ProjectGuid, use the same GUID template that you used in the application manifest file (you can specify 10 different GUIDS with the template). 

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
<!-- Project Configurations omitted for brevity -->
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>$guid1$</ProjectGuid>
  </PropertyGroup>
  <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0'">
    <VisualStudioVersion>11.0</VisualStudioVersion>
  </PropertyGroup>
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
  <PropertyGroup>
    <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
    <TargetPlatformVersion>8.0</TargetPlatformVersion>
    <DefaultLanguage>en-US</DefaultLanguage>
    <PackageCertificateKeyFile>$projectname$_TemporaryKey.pfx</PackageCertificateKeyFile>
  </PropertyGroup>
  <ItemGroup>
    <AppxManifest Include="package.appxmanifest">
      <SubType>Designer</SubType>
    </AppxManifest>
    <Content Include="default.html" />
    <Content Include="images\logo.png" />
    <Content Include="images\smalllogo.png" />
    <Content Include="images\splashscreen.png" />
    <Content Include="images\storelogo.png" />
    <Content Include="js\default.js" />
    <Content Include="css\default.css" />
    <None Include="$projectname$_TemporaryKey.pfx" />
  </ItemGroup>
  <ItemGroup>
    <SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" />
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
  <!-- Project Build options omitted for brevity -->
</Project>

Listing 2 – The .jsporj file

The Default HTML File

There are two optional minor changes that can be applied to the default.html file.

  • Update the title to the Safe Project Name
  • Update the HTML comment for the project references

For both of these I use the $safeprojectname$ template, which is the user supplied project name with any invalid characters stripped out.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>$safeprojectname$</title>
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
        <!-- $safeprojectname$ references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>
    </head>
<body class="contentHost">
    <div class="appTitle">
        <h1>Header</h1>
    </div>
    <div class="backButton">
        <button class="win-backbutton"></button>
    </div>
    <div class="appSubTitle">
        <h2>Subheader</h2>
    </div>
    <div id="contentTarget" class="mainContent">
        <h3>Body Text</h3>
    </div>
</body>
</html>

Listing 3 – The Default HTML File

The VSTemplate

The are several changes to the generated template file, all in the <TemplateContent> tag:

  • Update the Project TargetFileName in the <Project> tag
  • Update the ReplaceParameters attribute for the “package.appxmanifest” file in the <ProjectItem> tag
  • Update the TargetFileName and ReplaceParameters attibutes for the key file in the <ProjectItem> tag

The ReplaceParameters attribute instructs the New Project dialog to look into the referenced file and replace any project templates found with the correct values.  The TargetFileName attribute specifies how the referenced file will be named named.

<VSTemplate Version="3.0.0" 
    xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" 
    Type="Project">
  <TemplateData>
    <Name>BlankApplicationWithLayout</Name>
    <Description>Blank Application With MS Recommended Layout
       </Description>
    <ProjectType>JavaScript</ProjectType>
    <ProjectSubType>Windows Store</ProjectSubType>
    <SortOrder>1000</SortOrder>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>BlankAppWithLayout</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
    <LocationField>Enabled</LocationField>
    <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
    <Icon>__TemplateIcon.ico</Icon>
  </TemplateData>
  <TemplateContent>
    <Project TargetFileName="$projectname$.jsproj" 
         File="SimpleLayout.jsproj" ReplaceParameters="true">
      <Folder Name="css" TargetFolderName="css">
        <ProjectItem ReplaceParameters="true" 
            TargetFileName="default.css">default.css</ProjectItem>
      </Folder>
      <Folder Name="images" TargetFolderName="images">
        <ProjectItem ReplaceParameters="false" 
            TargetFileName="logo.png">logo.png</ProjectItem>
        <ProjectItem ReplaceParameters="false" 
            TargetFileName="smalllogo.png">smalllogo.png</ProjectItem>
        <ProjectItem ReplaceParameters="false" 
            TargetFileName="splashscreen.png">
                   splashscreen.png</ProjectItem>
        <ProjectItem ReplaceParameters="false" 
            TargetFileName="storelogo.png">storelogo.png</ProjectItem>
      </Folder>
      <Folder Name="js" TargetFolderName="js">
        <ProjectItem ReplaceParameters="true" 
            TargetFileName="default.js">default.js</ProjectItem>
      </Folder>
      <ProjectItem ReplaceParameters="true" 
            TargetFileName="default.html">default.html</ProjectItem>
      <ProjectItem ReplaceParameters="true" 
            TargetFileName="$projectname$_TemporaryKey.pfx">
                   SimpleLayout_TemporaryKey.pfx</ProjectItem>
      <ProjectItem ReplaceParameters="true" 
            TargetFileName="package.appxmanifest">
                   package.appxmanifest</ProjectItem>
    </Project>
  </TemplateContent>
</VSTemplate>

Listing 4 – The VSTemplate File

Adding the Template to Visual Studio

After updating the files, they need to be added back into the generated .zip file that was exported earlier in the process.  Once the zip file contains all of the updated files, there are two ways to register your project template with Visual Studio. 

Using The User Templates Setting

Under Tools –> Options –> Projects and Solutions, one of the settings is “User project template location:”.  Any template .zip files will be automatically pulled into Visual Studio. (If you have Visual Studio open when you copy the file, it won’t show until the next restart of Visual Studio.)

image
Figure 4 – User project templates location

The one downside of this method is that the template will only show up under JavaScript and not JavaScript –> Windows Store.

image
Figure 5 – New Project Dialog

Adding to Visual Studio Install Directory

The second option is to add the files (not in the .zip file) to a new subdirectory in “<VS11 Install Directory>\Common7\IDE\ProjectTemplates\JavaScript\Windows Store\1033”, and then run (as administrator) “devenv.exe /InstallVSTemplates” from a command prompt.

Summary

When you have something good, it’s even better if it’s easy to re-use.  If you have a great starting point for your Windows 8 projects, package it up, and add it to your environment as a project template.  You can even share it with your coworkers!

About the author

Philip Japikse

2012STLDODN.93x112 Philip Japikse an international speaker, a Microsoft MVP, INETA Community Champion, MCSD, CSM/ CSP, and a passionate member of the developer community, Phil Japikse has been working with .Net since the first betas, developing software for over 20 years, and heavily involved in the agile community since 2005. Phil works as a Developer Evangelist for Telerik's RadControls for Windows 8 as well as the Just family of products (JustCode, JustMock, JustTrace, and JustDecompile) and co-hosts the Hallway Conversations podcast (www.hallwayconversations.com). Phil is also the Lead Director for the Cincinnati .Net User’s Group (http://www.cinnug.org). You can follow Phil on twitter via www.twitter.com/skimedic read his Telerik blog at http://blogs.telerik.com/skimedic and his personal blog at www.skimedic.com/blog.

 

Managed Windows Shared Hosting by OrcsWeb