Elizabeth Murray and Jonathan Gordon
Visual Studio Team
Microsoft Corporation
March 2003
Summary: This article provides an in-depth look at the structure of the Microsoft® Visual Studio® .NET 2003 Start Page and shows you how to customize the Start Page by adding new content. Several examples are provided, along with the XML used to define the content. In addition, the process for retrieving and displaying information on the Start Page is explained. After reading this article, you will be able to create and deploy to multiple machines new tabs for the Visual Studio Start Page that display custom content and interact with local add-ins or remote Web Services. (39 printed pages)
Contents
Introduction
How the Start Page Works
Adding Customized Content to the Start Page
Testing and Troubleshooting Start Page Content
Deploying Custom Start Page Content
Advanced Elements
Conclusion
Examples of Custom Content
Introduction
The Visual Studio .NET Start Page is displayed each time you start the integrated development environment (IDE). The default content provides the latest developer news and promotes interaction with the online developer community.
In Visual Studio .NET 2003, the Start Page changed to include three panes: Projects, Online Resources, and My Profile. The contents of Projects is now displayed in a tool window while Online Resources and My Profile still display in a Web browser window, using the same model as the Visual Studio .NET 2002 Start Page. By changing the type of window used to display the Projects pane the IDE now opens more quickly.
To supplement the default content, you can customize the Start Page by adding new content to the Online Resources pane in the form of custom tabs. Custom tabs are the pages of content you see within the Online Resources pane, such as the default Search Online and Get Started tabs. You cannot add new panes to the Start Page. The default Start Page content remains; you can add new content but you cannot customize the existing default content. Default content for the Online Resources pane is provided from a server. The local machine no longer stores static content; therefore, you must be connected to the Internet or a network to view the default Online Resources content.
This article provides several examples of how to create new Start Page content and add it to the existing Online Resources pane. To create new Start Page content, you need to have some familiarity with XML and a text editor such as the Visual Studio Code Editor or Notepad.
How the Start Page Works
The Online Resources pane consists of a client-side .htm page, in this case default.htm, which displays a list of tabs. These tabs are based on tab definition files that are authored using XML. Default tab definition files are stored on a server whereas custom tab definition files are stored locally. When you select a tab, Visual Studio reads the related tab definition file for the tab. If a feed is included in the tab definition file, then the content for the tab is downloaded from a server, as specified in the tab definition file. If the file does not contain a feed, static content in the tab definition file is displayed instead. See Figure 1 below.
.gif)
Figure 1
A client-side schema validation file, vstab.xdr located in a resource .dll, validates all the content before transforming and rendering it in the Start Page. After the content has been validated, the content is rendered as HTML using a client-side transform, vshome.xsl also located in a resource .dll. If the content fails to pass validation, then the tab does not appear on the Start Page. Each time a tab is rendered, the contents of the tab is cached on your local machine. If the feed for the content is unavailable, for example if you are not connected to the Internet, you can still view the most recently retrieved content for the tab.
Tab Definition File Format
Custom content for the Start Page is defined in tab definition files that are written using XML. A tab definition file can contain one or more tabs. The XML used to define the custom content must conform to the Start Page XML schema found in vstab.xdr in order to appear on the Start Page.
Note The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, places, or events is intended or should be inferred.
The XML elements and attributes listed below provide the basics for a tab definition file for a custom Start Page tab.
<TabDefinition>
<Tab ID="uniquename" Name="displayname">
<Application ID="uniquename">
<PaneSet ID="uniquename">
<Pane ID="uniquename" Title="displayname">
<LinkGroupSet ID="uniquename">
<LinkGroup ID="uniquename" Title="displayname">
</LinkGroupSet>
</Pane>
</PaneSet>
<Data>
<Context>
<Links>
<LItemEx>
<LItem ID="uniquename" LinkGroup="linkgroupid"
URL="urlpath"> displaytext </LItem>
</LItemEx>
</Links>
</Context>
</Data>
</Application>
<Feeds>
<Feed>
<Source LCID="locale" URL="urlpath">
<Arg Name="name"></Arg>
</Source>
</Feed>
</Feeds>
</Tab>
</TabDefinition>
Adding Customized Content to the Start Page
You can customize the Start Page by adding custom tabs with static or dynamic content to the Online Resources pane. Other types of modifications to the Start Page are possible, but remain unsupported by Microsoft. Some additional information to keep in mind when creating custom content:
- All content must conform to the Start Page schema, vstab.xdr, or the content will not render on the Start Page.
- Client-side script is not allowed in Start Page content.
- You cannot change the order that default tabs appear on the Online Resources pane in the Start Page. Default tabs appear first and then custom tabs.
- You cannot change the content or format for any of the default tabs provided with Visual Studio.
Custom Content and Security
Content sent from the server as well as content stored on the client is validated to ensure that it conforms to the Start Page schema before it is rendered on the Start Page itself. Client-side content is as secure as any file that is stored locally on a machine.
Because content on the server is delivered via HTTP, it is recommended that content on the server, prior to delivery to the client, is verified to make sure no malicious content is returned to the client. In Example 4, serverFeed.asp contains JavaScript code that validates the XML returned by serverFeed.xml:
// The following function takes an xml document and selects content based
on a given xpath query, ensuring that the resulting xml contains URLs
that begin with either http:, https:, news:, ms-help: or vs:.
function replaceBadURLs(xpath, xmlDocument)
{
var i = 0;
var regex = "^http:|^https:|^news:|^ms-help:|^vs:";
// search for appropriate URL format
var nodes = xmlDocument.selectNodes(xpath);
// select xml using xpath query
for(i = 0 ; i < nodes.length ; i++)
// check that each item conforms to appropriate URL format
{
if(!nodes.item(i).text.match(regex))
// If item does not conform, zero out the item
{
nodes.item(i).text = "";
}
}
}
Performance Considerations
You should check that the time it takes to render the content of a tab on the Start Page is acceptable. A tab that takes too long to load might cause the user to discontinue using the tab or the Start Page.
Referencing images on a remote server in a tab definition file, including a large amount of content in the tab definition file, and poor server performance can all contribute slower rendering times. If a local tab definition file contains references to network or Web content, this content might load slowly when the Start Page attempts to retrieve this content for the Online Resources pane. To decrease the load time for the Online Resources pane, you should use the <Feed> element to retrieve content from a network or Web site. Always test tab performance before deploying custom tabs to a production environment.
Elements and Attributes
Basic elements and attributes
The following elements and attributes provide the basic framework for the tab definition file.
- <TabDefinition></TabDefinition>
- Required. The root element that contains all of the child elements for the file.
- <Tab></Tab>
- Required. A child element of the <TabDefinition>. At least one <Tab> element is required in a tab definition file. This element takes the attributes ID, Name, and Filterable.
- <Application></Application>
- Required. A child element of the <Tab> element that defines the user interface for the tab. This element takes the ID attribute.
- ID attribute
- Required. A unique ID for the element.
- Name attribute
- Required. The display name for the element.
- Filterable attribute
- Optional. Takes the values True and False. If true, then the Filter drop-down list is displayed and eligible content on the tab is filtered based on the filter you selected. If False, the drop-down is not displayed and content is not filtered. For more information on filtering content, see "Tab Data Elements and Feeds" in this paper.
The following code is an example of a simple tab definition file that contains information for two custom Start Page tabs, Tab1 and Tab2. Tab1 contains filterable, dynamic content while Tab2 contains unfiltered, static content.
<TabDefinition>
<Tab ID="MyTab" Name="Tab1" Filterable="true">
<Application ID="MyApp">
<!--Place UI elements in this section.-->
</Application>
<Data>
<---Place offline Data elements in this section-->
</Data>
<Feeds>
<!--Place Feed elements in this section-->
</Feeds>
</Tab>
<Tab ID="MyOtherTab" Name="Tab2" Filterable="false">
<Application ID="MyOtherApp">
<!--Place UI elements in this section.-->
<Data>
<---Place static Data elements in this section-->
</Data>
</Application>
</Tab>
</TabDefinition>
User Interface Elements
The user interface for custom content is defined within the <Application> element of the tab definition file. Each user interface for a tab is defined using either of these two elements: <PaneSet> or <Pane>.
The following table lists the elements covered in this section.
- <PaneSet></PaneSet>
- Optional. Defines that content displays on multiple panes within sub-tabs. This element takes the ID attribute. To view a pane set, see Example 2.
For example, the following XML fragment defines multiple panes within sub-tabs:
<Application ID="MyApp">
<PaneSet ID="MyPaneSet">
<Pane ID="MyPane1" Title="My First Pane">
<!--Place UI elements in this section.-->
</Pane>
<Pane ID="MyPane2" Title="My Second Pane">
<!--Place UI elements in this section.-->
</Pane>
</PaneSet>
</Application>
- <Pane></Pane>
- Optional. Defines that content displays in a single pane. This element takes the attributes ID and Title. To view a pane, see Example 2.
For example, the following XML fragment defines a single pane.
<Application ID="MyOtherApp">
<Pane ID="MyPane1" Title="My First Pane">
<!--Place UI elements in this section.-->
</Pane>
</Application>
Within the <Pane> element, the following UI elements can be used to display content.
- <Image></Image>
- Optional. Allows a graphic to be displayed on a pane. This element takes the ID, Source, Height, Width, and AltText attributes.
For example:
<Image ID="MyImage" Source="http://www.test-1.msn.com/warning.gif"
Height="40" Width="40" AltText="My Image" />
- <TextSpan></TextSpan>
- Optional. Displays static text that can be formatted. <TextSpan> can optionally contain the <Break> and <Image> elements. This element takes the ID, FontFamily, and FontSize attributes.
For example, the following XML fragment is a simple text span:
<TextSpan ID="TextSpanSimple">This is a Simple TextSpan</TextSpan>
For example, the following XML fragment is a formatted text span:
<TextSpan ID="TextSpanFormatted" FontFamily="Tahoma" FontSize="14">
This is a TextSpan in Tahoma, 24pt</TextSpan>
For example, the following XML fragment includes <Image> and <Break> elements as part of the <TextSpan> element:
<TextSpan ID="TestTextSpan">
<Image ID="TestSpanImage1" Source=
"http://www.test-1.msn.com/warning.gif"
Height="40" Width="40" AltText="Image 1 Inside Span" />
Text for Image 1 inside TextSpan
<Image ID="TestSpanImage2" Source=
"http://www.test-1.msn.com/warning.gif"
Height="40" Width="40" AltText="Image 2 Inside Span" />
Text for Image 2 inside TextSpan
<Break/>
<Image ID="TestSpanImage3" Source="http://www.test-1.msn.com/
warning.gif"
Height="40" Width="40" AltText="Image 3 Inside Span" />
Text for Image 3 inside TextSpan
</TextSpan>
- <Break></Break>
- Optional. Inserts a line break.
- <HRule></HRule>
- Optional. Displays a horizontal rule.
- <Title></Title>
- Optional. Displays text as bold.
For example:
<Title>This is a title.</Title>
- <Hyperlink></Hyperlink>
- Optional. Displays a hyperlink. This element takes the ID, URL, and Relative attributes.
For example, this XML fragment links to an image on the Web server www.test-1.msn.com:
<Hyperlink ID="TestHyperlink1"
URL="http://www.test-1.msn.com/warning.gif">Hyperlink</Hyperlink>
For example, this XML fragment links to a topic in MSDN help. The Relative attribute specifies that the local Help collection is queried, ms-help://<collection>, for the value specified in the URL attribute before navigating to the topic.
<Hyperlink ID="TestHyperlink2" Relative="1"
URL="/ms.msdnvs/vsintro7/HTML/vxoriWhatsNewInVisualStudio.htm">
Hyperlink to Help topic</Hyperlink>
- <LinkGroup></LinkGroup>
- Optional. Defines the placement of a set of LItem elements within a <Pane> or <PaneSet> element. This element takes the ID and Title attributes.
For example:
<LinkGroup ID="LG1" Title="My LinkGroup" />
<Data>
<Context>
<Links>
<LItemEx>
<LItem ID="LI1" LinkGroup="LG1" Image="http://www.test-
1.msn.com/warning.gif">LItem in My Link Group</LItem>
<Blurb>Text describing LItem.</Blurb>
</LItemEx>
</Links>
<Context>
<Data>
- <LinkGroupSet><LinkGroupSet>
- Optional. A set of <LinkGroup> elements.
For example:
<LinkGroupSet>
<LinkGroup ID="LG1" />
<LinkGroup ID="LG2" />
</LinkGroupSet>
- ID attribute
- Required. A unique ID for the element.
- Title attribute
- Required. Display name for the element.
- Source attribute
- Required. A full path or URL for an image.
- Height attribute
- Optional. The vertical size of an image, specified in pixels.
- Width attribute
- Optional. The horizontal size of an image, specified in pixels.
- AltText attribute
- Optional. The text that appears if the image does not display on the pane.
- FontFamily attribute
- Optional. Specifies the font used to display text, such as Tahoma or Verdana.
- FontSize attribute
- Optional. The size of the font, specified in points.
- URL attribute
- Required. An absolute Web URL that must start with http:, https:, news:, ms-help: or vs:. Use with the Relative attribute to specify a relative URL, such as an MSDN Help topic
- Relative attribute
- Optional. Takes the value 1. Use this attribute to point to a URL for a topic included in MSDN Help. This attribute indicates that the value provided by the URL attribute is found in the MSDN Help collection.
Tab Data Elements and Feeds
The <Data> element in the tab definition file contains content for a tab displayed as links that can include an optional summary or image. The <Feed> element allows you to display static links when you are offline but also allows you to point to the server and pass arguments to receive updated content when connected to the Internet.
The following elements are covered in this section:
- <Data></Data>
- Optional. A list of links displayed on the tab.
- <Context></Context>
- Required. Used to define groups of <LItem> elements that can be optionally filtered. This element takes the <Attributes> and <Links> elements and is a child of the <Data> element.
For example:
- <Attributes></Attributes>
- Optional. Used to specify attributes for the content in the <Context> element so that links can be filtered within the tab using pre-defined Help filters. This element takes the <AItem> element.
- <AItem></AItem>
- Optional. Used to specify an attribute to associate with the set of links within the <Context> element so that they interact with pre-defined Help filters. This element takes the Name and Value attributes.
- <Links><Links>
- Required. A set of links that may be optionally filtered on a tab. Parent element for <LItemEx> and <LItem>.
- <LItemEx></LItemEx>
- Optional. A parent element without any attributes that contains the <LItem> and the optional <Blurb> element.
For example:
<LItemEx>
<LItem ID="LI1" LinkGroup="LG1"
Image="http://www.test-1.msn.com/warning.gif">LItem with text and
an image.</LItem>
<Blurb>Text describing LItem.</Blurb>
</LItemEx>
- <LItem></LItem>
- Required. A hyperlink, such as http, https, ms-help, mail, or news that can include an image. This element takes the ID, LinkGroup, and Image attributes.
- <Blurb></Blurb>
- Optional. Contains static text for the <LItemEx> element.
- <Feeds></Feeds>
- Optional. A child element of <Tab> that defines how to download server-side content for a tab.
- <Feed></Feed>
- Required. A child of the Feeds element.
- <Source></Source>
- Required. This element points to content on the server. Takes the LCID and URL attributes.
- <Arg></Arg>
- Optional. This element passes additional arguments along with the Feed URL. Takes the Name attribute.
For example:
<Feeds>
<Feed>
<Source LCID="1033" URL="http://myserver/myfeed.aspx">
<Arg Name="feedName">defaultFeed</Arg>
</Source>
</Feed>
</Feeds>
This feed will result in the following URL being called to retrieve content for the tab: <http://myserver/myfeed.aspx?hasArgs=y&feedName="defaultFeed"&FeedLCID=1033&UserLang=en-us>.
- ID attribute
- Required. A unique ID for the element.
- URL attribute
- Required. An absolute Web URL that must start with http:, https:, news:, ms-help: or vs:.
- Image attribute
- Required. A full path or URL for an image.
- LinkGroup attribute
- Optional. The ID for the <LinkGroup> element that the LItem participates in.
- Name attribute
- Required. The name of a Help attribute category. For more information on Help attributes, see "Creating and Using Filters" in the MSDN Library Help.
- Value attribute
- Required. A Help attribute value.
A <Data> element example:
<Data>
<Context>
<Attributes>
<AItem Name="DocSet" Value="Visual Studio" />
<AItem Name="Product" Value="VS" />
</Attributes>
<Links>
<LItemEx>
<LItem ID="LI1" LinkGroup="LG1" URL="
http://www.test-1.msn.com/warning.gif" Image="
http://www.test-1.msn.com/warning.gif
">This link displays when the Visual Studio filter is applied.</LItem>
<Blurb>Blurb describing Link</Blurb>
</LItemEx>
</Links>
</Context>
</Data>
- LCID attribute
- Optional. The locale ID number for the language to be targeted.
| Language | LCID |
| Traditional Chinese | 1028 |
| German | 1031 |
| English | 1033 |
| French | 1036 |
| Italian | 1040 |
| Japanese | 1041 |
| Korean | 1042 |
| Simplified Chinese | 2052 |
| Spanish | 3082 |
New User Interface Elements
The following elements are new for Visual Studio .NET 2003:
- <Table></Table>
- Optional. Parent element for <TableRow> and <TableCell>. This element takes the optional ID, Align, Border, CellPadding, CellSpacing, Height, Width, and Title attributes.
For example:
<Table Border="1" Height="200" Width="200">
<TableRow>
<TableCell ColSpan="3" Align="center"
Valign="middle"><TextSpan>Cell
1</TextSpan></TableCell>
</TableRow>
<TableRow>
<TableCell RowSpan="2"><TextSpan>Cell 2</TextSpan></TableCell>
<TableCell><TextSpan>Cell 3</TextSpan></TableCell>
<TableCell><TextSpan>Cell 4</TextSpan></TableCell>
</TableRow>
<TableRow>
<TableCell><TextSpan>Cell 5</TextSpan></TableCell>
<TableCell RowSpan="2"><TextSpan>Cell 6</TextSpan></TableCell>
</TableRow>
<TableRow>
<TableCell><TextSpan>Cell 7</TextSpan></TableCell>
<TableCell><TextSpan>Cell 8</TextSpan></TableCell>
</TableRow>
</Table>
- <TableRow></TableRow>
- Required. Parent element for <TableCell>. This element does not take attributes.
- <TableCell></TableCell>
- Required. Used to contain content in a table. This element takes the optional ID, Align, ColSpan, NoWrap, RowSpan, and Title attributes.
- <ListBox></ListBox>
- Optional. Parent element for <ListBoxItem>, which is used to display items in a drop-down list. This element takes the optional ID and Size attributes.
For example:
<ListBox>
<ListBoxItem>One</ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
<ListBoxItem>Three</ListBoxItem>
</ListBox>
- <ListBoxItem></ListBoxItem>
- Optional. Items in a list. Used within the <ListBox> element. This element takes the optional ID and Value attributes.
For example:
<ListBoxItem Value="Value1">Item 1</ListBoxItem>
- <RadioGroup></RadioGroup>
- Optional. Parent element for <RadioButton>. This element takes the optional ID, GroupName, Selected, and BreaksBetween attributes.
For example:
<RadioGroup ID="radio1" BreaksBetween="true">
<RadioButton Checked="true">Option 2</RadioButton>
<RadioButton>Option 1</RadioButton>
</RadioGroup>
- <RadioButton></RadioButton>
- Optional. A radio button. Used with the <RadioGroup> element. This element takes the optional ID, AccessKey, and Checked attributes.
- <RootNode></RootNode>
- Optional. A parent node without any attributes that contains the <ContainerNode> element. Use this element to create a tree-like user interface.
For example:
<RootNode>
<ContainerNode ID="MyContainer1" AltText="My Container"
Title="Container" OpenedImage="vs:/images_greenfolder.gif"
ClosedImage="vs:/images_greenfoldero.gif" Height="13" Width="16"
State="closed">
<ItemNode>
<Hyperlink ID="TestHyperlink1A"
URL="http://localhost/warning.gif">Hyperlink</Hyperlink>
</ItemNode>
<ItemNode>
<Hyperlink ID="TestHyperlink1A1"
URL="http://localhost/warning.gif">Hyperlink</Hyperlink>
</ItemNode>
<ContainerNode ID="MyContainer2" Title="Container"
OpenedImage="vs:/images_greenfolder.gif"
ClosedImage="vs:/images_greenfoldero.gif" Height="13" Width="16"
State="closed">
<ItemNode>
<Hyperlink ID="TestHyperlink1A2"
URL="http://localhost/warning.gif">Hyperlink</Hyperlink>
</ItemNode>
</ContainerNode>
</ContainerNode>
</RootNode>
- <ContainerNode></ContainerNode>
- Required. Use as a container in a tree user interface. This element contains the <ItemNode> element and takes the optional ID, AltText, Title, OpenedImage, ClosedImage, Height, Width, and State attributes.
- <ItemNode></ItemNode>
- Optional. A parent node without any attributes that contains controls or text in a tree control.
- <TextField></TextField>
- Optional. A text box that takes user input. This element takes the optional ID, Size, and MaxLength attributes.
<TextField ID="TestTextField" Size="50" MaxLength="20">My Text
Field</TextField>
- <PasswordField></PasswordField>
- Optional. Use to display text entered at * characters to keep passwords and other information confidential. This element takes the optional ID, Size, and MaxLength attributes.
- <Button></Button>
- Optional. A button. This element takes the optional ID and Text attributes.
For example:
<Button ID="TestButton" Text="Button" />
- <CheckBox></CheckBox>
- Optional. A check box. This element takes the optional ID, Checked, and AccessKey attributes.
For example:
<CheckBox ID="TestCheckBox" Checked="true" AccessKey="x">Check
Box</CheckBox>
- <HiddenField></HiddenField>
- Optional. A hidden field. This element takes the optional ID attribute.
For example:
<HiddenField ID="TestHiddenField">My Hidden Field</HiddenField>
- <FileField></FileField>
- Optional. A file picker field. This element takes the optional ID, Size, and MaxLength attributes.
For example:
<FileField ID="TestFileField" Size="50" MaxLength="20" />
- <Label></Label>
- Optional. A text label. This element takes the optional ID, AccessKey, and For attributes.
For example:
<Label ID="TestLabel" AccessKey="L" For="TestTextField">Label:</Label>
- BreaksBetween attribute
- Required. Choose the values true or false. Select true if you want each radio button to appear on a separate line. Select false if you want each radio button to appear adjacent to one another on a single line.
- Border attribute
- Optional. The size of the border for the table.
- Height attribute
- Optional. The vertical size of the control.
- Width attribute
- Optional. The horizontal size of the control.
- ColSpan attribute
- Optional. Determines the number of columns a table cell extends across in the table.
- Align attribute
- Optional. Determines where text is aligned horizontally in the table cell. Choose from the following values: center, left, and right.
- Valign attribute
- Optional. Determines where text is aligned vertically in the table cell. Choose from the following values: baseline, bottom, center, middle, and top.
- RowSpan attribute
- Optional. Determines the number of rows a table cell extends in a table.
- Title attribute
- Optional. Determines the display name of a <ContainerNode> in a tree user interface or title of a table.
- OpenedImage attribute
- Optional. Determines graphic used for <ContainerNode> when expanded.
- ID attribute
- Optional. A unique ID for the element.
- CellPadding attribute
- Optional. The amount of padding around cells within the table.
- CellSpacing attribute
- Optional. The amount of spacing between cells within the table.
- Title attribute
- Optional. The title of the control.
- NoWrap attribute
- Optional. Determines whether or not to wrap text in a table cell.
- Size attribute
- Optional. Number of items to display in a ListBox or size of a TextField or PasswordField.
- Value attribute
- Optional. Value when a ListBox item is selected.
- GroupName attribute
- Optional. Name to associate with all RadioButton elements in a RadioButtonGroup.
- Selected attribute
- Optional. Selected RadioButton within RadioButtonGroup.
- AccessKey attribute
- Optional. Keyboard access key for control.
- For attribute
- Required. ID of the control to associate with a label.
- Checked attribute
- Optional. RadioButton is checked.
- AltText attribute
- Optional. The text that appears when the mouse is hovering over the ContainerNode.
- ClosedImage attribute
- Optional. Determines graphic used for <ContainerNode> when collapsed.
- State attribute
- Optional. State of <ContainerNode>. Choose the values opened or closed.
- MaxLength attribute
- Optional. Maximum number of allowed characters.
Testing and Troubleshooting Start Page Content
If customized content does not display as you expected, try the following steps:
- View .xml files in a Web browser to check for parsing errors.
- Use the Paste as HTML command on the Edit menu when copying and pasting examples from this white paper into .xml files in Visual Studio. If you use the Paste command, the XML designer might add code that does not conform to the Start Page schema.
- Close and then start Visual Studio again. Tab content that is delivered from a server-side .xml file might not update in the Start Page when you use Refresh.
You can also create a validation .htm file to check your XML against and uncover errors.
Create a Simple XML Validation File
The following procedure creates an .htm file that contains script to validate the XML in your custom Start Page content. To use this validation script, you must be connected to the Internet.
To use the simple XML validation file
- Copy the following code and paste it into a text editor, such as Visual Studio Code Editor or Notepad.
<html>
<head>
<title>Start Page Content Validation Tool</title>
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intellisense/ie5">
<script id="clientEventHandlersJS" language="javascript">
<!--
//Global variables
var g_MSXML_DOM = "MSXML2.DOMDocument.3.0";
var g_MSXML_Schema_DOM = "MSXML2.XMLSchemaCache.3.0";
var g_valError;
var g_valSchema = new ActiveXObject(g_MSXML_Schema_DOM);
//This function validates the tab xml
function fnLoadAndValidate(oTab, xmlobj)
{
//Set list of errors to ""
g_valError = "";
try {
//Checks that xml passes schema validation
try {
xmlobj.validateOnParse = true;
xmlobj.schemas = g_valSchema;
xmlobj.loadXML(oTab.xml);
if (xmlobj.parseError != 0) {
g_valError = "Content validation error: " +
xmlobj.parseError.reason;
return false;
}
} catch (e) {
g_valError = "XML parse or validation error: " + e.message;
return false;
}
} catch (e) {
g_valError = "General validation error: " + e.message;
return false;
}
return true;
}
//This function is called when the "Validate" button is clicked (after
loading a tab definition file) and validates all tabs found in the
definition file
function validateTab(tabFile) {
var xmlTmp = new ActiveXObject(g_MSXML_DOM);
var errorList = "";
//Load file specified in file field on page
xmlTmp.load(SelectFile.value);
//Finds all tabs in the file
var tabList = xmlTmp.selectNodes("//Tab");
//For each tab, validates xml against the schema
for(var o = 0; o!=tabList.length;o++)
{
objNode = tabList.nextNode();
tabName = objNode.getAttribute("Name");
//If the tab fails validation, add an error to list of errors
if(!fnLoadAndValidate(objNode, xmlTmp))
errorList += "Tab : " + tabName + "\n" + g_valError +"\n";
}
//If errors were found, prompt with list, otherwise prompt with
success
if(errorList!="")
alert("Validation errors found\n\n" + errorList);
else
alert("No validation errors found.");
}
//On window load, opens the schema validation file (vstab.xdr)
//NOTE: Content validation requires an active Internet connection.
function window_onload() {
try {
g_valSchema.add("",
"http://msdn.microsoft.com/vsdata/xdr/vstab_2003.xdr");
RenderInput.style.display = "inline";
} catch (e) {
RenderError.innerHTML = "Error accessing schema file
(vstab.xdr). If problem persists, contact Administrator.<p/>NOTE:
content validation requires an active internet connection.";
}
}
//-->
</script>
</head>
<body language="javascript" onload="return window_onload()">
<span>Start Page Content Validation Tool</span>
<hr>
<div ID="RenderInput" style="DISPLAY: none">
Content definition file:
<BR>
<INPUT ID="SelectFile" type="file" size="60">
<INPUT ID="Validate" style="height: 20" type="button"
value="Validate" onclick="validateTab()">
</div>
<div ID="RenderError"></div>
</body>
</html>
- Save the file as an .htm page.
- In a Web browser, open the .htm page.
- On the validation page, click Browse to locate the .xml file you intend to validate.
- Click Validate.
The validation file checks that the XML is formatted correctly in the file, that required attributes are provided for their associated elements, and that elements are used correctly.
Deploying Custom Start Page Content
Custom tab content is delivered using tab definition files on the client and the server. Custom tab definition files on the client must be stored in a specific location on your machine for the Start Page to recognize them. URLs in these files can point to content returned from a server.
If content is meant to be updated frequently, a server-side feed should be used. Content on the server can be updated without affecting the client and allows for delivery of content to multiple machines from a single source on a regular basis. The Online Community, Headlines, and Downloads tabs in the Start Page are defined this way. If content is not meant to be updated frequently, or never updated, only a client- side tab definition file is required. The Get Started tab in the Start Page is an example of such a tab.
Tab definition files can be deployed with locale-specific content as well, thereby providing the ability to show custom tabs for multiple languages based on machine regional settings.
When the Start Page is displayed, specific locations are searched on your machine for custom tabs. If tab definition files are found in these locations, content within these files are displayed on the Start Page. When a tab is selected, the client content is rendered. If a server feed is defined, the server content is then downloaded, replacing content from the client, and displayed within the Start Page.
To deploy custom tabs on the client
- Browse to the <Visual Studio install path>\Common7\IDE\HTML\Custom\ directory. If the Custom directory does not exist, create it.
- Copy the tab definition files, *.xml, into the directory.
- Start Visual Studio .NET and view the Online Resource pane of the Start Page. Custom tabs appear near the bottom of the tab list.
If you cannot see your custom tabs, you might have errors in your XML. See the section Testing and Troubleshooting Start Page Content Issues for more information.
To deploy locale-specific custom tabs on the client
- Browse to the <Visual Studio install path>\Common7\IDE\HTML\<Locale ID>\Custom\ directory. If \...\<Locale ID>\Custom\ does not exist, create the directory.
For example: c:\Program Files\Visual Studio .NET\Common7\IDE\HTML\1033\Custom\ for English.
| Language | Locale ID |
| Traditional Chinese | 1028 |
| German | 1031 |
| English | 1033 |
| French | 1036 |
| Italian | 1040 |
| Japanese | 1041 |
| Korean | 1042 |
| Simplified Chinese | 2052 |
| Spanish | 3082 |
- Copy the tab definition files, *.xml, into the appropriate locale directories.
Content that is meant to be updated from a server has two parts: the client-side tab definition file that contains a pointer to the appropriate server and server-side files that render the XML and check that the XML conforms to the Start Page schema. These files can be anything from a simple XML file deployed to a Web server to a complete .NET application or even an XML Web Service on a server that returns XML. For example, you can use an .asp file that points to an XML tab definition file, as in Example 4.
To deploy dynamic content on the server
- Include a pointer in the <Feed> section of the client tab definition file that references the server, application path, or output file.
- Browse to the <Visual Studio install path>\Common7\IDE\HTML\Custom\ directory. If the Custom directory does not exist, create it.
- Copy the tab definition files, *.xml into the directory.
- On the server, make sure that the server-side files are in place.
Advanced Elements
You now have greater flexibility to define custom tabs with new elements available with Visual Studio .NET 2003. Using these new elements, you can interact directly with Visual Studio add-ins from a Start Page tab.
The following table contains the advanced elements covered in this section:
- <AddInWorker></AddInWorker>
- Optional. Used to connect to a Visual Studio add-in loaded into Visual Studio. Parent element for <RenderArgs> and <RenderInput>. This element takes the ID, ActionID, RenderAreaID, ProgID, Method, and ErrorMessage attributes.
For information on creating add-ins, see the topic "Creating Add-ins and Wizards" on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxconcreatingautomationobjects.asp.
- <Action></Action>
- Optional. Used to call an add-in and parent element for <InvokeMethod>. This element takes the ID attribute.
- <InvokeMethod></InvokeMethod>
- Optional. Used to call a Visual Studio add-in or Web site. This element takes the ToolID attribute.
- <RenderArgs></RenderArgs>
- Optional. List of arguments to pass to a Visual Studio add-in and parent element for the <RenderArg>. This element takes the ItemID and ItemProp attributes.
- <RenderArg></RenderArg>
- Optional. Argument to pass to a Visual Studio add-in method.
- <RenderInput></RenderInput>
- Optional. List of elements to use when interacting with a Visual Studio add-in. Elements can be any of the documented set of user interface elements defined within the schema.
- ID attribute
- Required. A unique ID for the element.
- ItemID attribute
- Required. ID of a custom tab element to build an argument to pass to a Visual Studio add-in method.
- ItemProp attribute
- Optional. Attribute of a custom tab element, referenced by the ItemID attribute, to build an argument to pass to a Visual Studio add-in method. If not specified, the element itself is passed to the add-in method allowing for the add-in to directly interact with an element on a custom tab.
- ToolID attribute
- Required. The ID of the Visual Studio add-in. The ActionID attribute uses the value of this attribute.
- ActionID attribute
- Required. The ID of Visual Studio add-in action that is provided by the ToolID attribute of the <InvokeMethod> element.
- ProgID attribute
- Required. The programmatic ID of the Visual Studio add-in.
- Method attribute
- Required. The method of the Visual Studio add-in to call when the add-in is invoked.
- ExecuteOnRender attribute
- Required. Indicates whether to call the Visual Studio add-in method when the tab is rendered. Use the values true or false.
- RenderAreaID attribute
- Required. ID of element used to render results returned from the Visual Studio add-in.
<AddInWorker> Example
The following code is an example of a simple tab definition file that is used to call a Visual Studio add-in and render results within a table cell.
<TabDefinition>
<Tab ID="vs_AddInWorkerTab" Name="Add-in Worker" Filterable="false">
<Application ID="VSAddInWorkerTab">
<Action ID="MyAddInInvoke">
<InvokeMethod ToolID="MyAddInInvoke" />
</Action>
<Pane ID="MyAddInPane" Title="My Add-In">
<Break/>
<TextSpan>Text to pass to add-in:</TextSpan>
<Break/>
<AddInWorker ID="MyAddIn" ActionID="MyAddInInvoke"
RenderAreaID="RenderMyAddInXML" ProgID="MySPAddin.Connect"
Method="HelloWorld" ExecuteOnRender="false">
<RenderArgs>
<RenderArg ItemID="MyAddInField" ItemProp="value" />
</RenderArgs>
<RenderInput>
<TextField ID="MyAddInField"></TextField>
<Button Text="Go" AccessKey="G"
OnClick="MyAddInInvoke"></Button>
</RenderInput>
</AddInWorker>
<Table ID="RenderMyAddInTable">
<TableRow>
<TableCell ID="RenderMyAddInXML"></TableCell>
</TableRow>
</Table>
</Pane>
</Application>
</Tab>
</TabDefinition>
The following code is the Visual Studio add-in method called by the Add-in worker above.
public string HelloWorld(string MyAddInArg)
{
string returnXML;
returnXML = "<TextSpan>AddInWorker received: " + MyAddInArg +
"</TextSpan>";
return returnXML;
}
Conclusion
As this paper has illustrated, you can add custom content to the Visual Studio Start Page and deploy that content to multiple machines. The content can be static, or you can choose to provide changing content by hosting files on a server. Whichever method you choose, customizing the Start Page is a way to adapt the IDE to your needs or the needs of your organization.
For more information, see the topic "Start Page" in MSDN.
Examples of Custom Content
The following samples are provide to give you ideas about ways in which you can customize the Visual Studio Start Page. Use the Paste as HTML command on the Edit menu when copying and pasting the example code into XML files in Visual Studio. See the section Deploying Custom Start Page Content for information on how to view these samples in the Start Page.
Examples 1, 2, and 3 can be deployed and viewed without making any modifications to the XML that is provided. Example 4 requires changes in the XML provided here and contains commented instructions on the types of modifications needed for the tab to display.
Example 1: Simple Tab
This example displays a single tab with static hyperlinks. Two of the hyperlinks have descriptive text and graphics associated with them whereas the other two do not.
.gif)
Figure 2. Simple tab
The XML used to create this example is listed below:
<?xml version="1.0" encoding="UTF-8" ?>
<TabDefinition>
<Tab ID="simple_tab" Name="Example 1: Simple Tab" Filterable="false">
<Application ID="Simple_App">
<Pane ID="Main_Pane">
<TextSpan ID="Tab_Description" FontSize="16">Example 1--A
Simple Custom Tab</TextSpan><Break/>
<Break/>
<TextSpan ID="disclaimer">Note: The contents and the code for
this sample tab originated as part of the white paper "Customizing the
Visual Studio Start Page" and are not supported by Microsoft Product
Support Services.</TextSpan>
<Break/>
<HRule/>
<LinkGroupSet>
<LinkGroup ID="WebSites" Title="Hyperlinks with graphics
and text"/>
<LinkGroup ID="SearchEngines" Title="Simple hyperlink
list"/>
</LinkGroupSet>
</Pane>
<Data>
<Context>
<Links>
<LItemEx>
<LItem ID="LI1" LinkGroup="WebSites"
Image="http://www.microsoft.com/library/homepage/images/mslogo-blue.gif"
URL="http://www.microsoft.com">Microsoft</LItem>
<Blurb>Microsoft Home Page</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI2" LinkGroup="WebSites"
Image="http://msdn.microsoft.com/library/shared/toolbar/graphics/banners/
MSDN_banner.gif" URL="http://msdn.microsoft.com">MSDN</LItem>
<Blurb>Microsoft Developer Network</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI3" LinkGroup="SearchEngines"
URL="http://search.microsoft.com">Search Microsoft</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI4" LinkGroup="SearchEngines"
URL="http://search.microsoft.com/advanced_search.asp?siteid=us/dev">Search
MSDN</LItem>
</LItemEx>
</Links>
</Context>
</Data>
</Application>
</Tab>
</TabDefinition>
Example 2: Multi-Pane Tab
This example displays a single tab that contains three panes of content: Sites, Search, and Other. Each pane contains hyperlinks.
.gif)
Figure 3. Multi-Paned Custom tab
The XML used to create this example is shown below:
<?xml version="1.0" encoding="UTF-8" ?>
<TabDefinition>
<Tab ID="tabbed_tab" Name="Example 2: Multi-Paned Tab"
Filterable="false">
<Application ID="Tabbed_App">
<PaneSet ID="Main_PaneSet">
<Pane ID="Sites_Pane" Title="Sites">
<TextSpan ID="SitesTab_Description" FontSize="16">Example
2--A Multi-Paned Custom Tab</TextSpan><Break/>
<Break/>
<TextSpan ID="disclaimer">Note: The contents and the code for
this sample tab originated as part of the white paper "Customizing the
Visual Studio Start Page" and are not supported by Microsoft Product
Support Services.</TextSpan>
<Break/>
<LinkGroup ID="WebSites" Title="Hyperlinks with graphics
and text"/>
</Pane>
<Pane ID="Search_Pane" Title="Search">
<TextSpan ID="SearchTab_Description" FontSize="16">Example
2--A Multi-paned custom tab.</TextSpan><Break/>
<LinkGroup ID="SearchEngines" Title="Simple hyperlink
list"/>
</Pane>
<Pane ID="Other_Pane" Title="Other">
<TextSpan ID="Tab_Description" FontSize="16">Example 2--A
Multi-paned custom tab</TextSpan><Break/>
<LinkGroup ID="OtherSites" Title="Simple hyperlink list"/>
</Pane>
</PaneSet>
<Data>
<Context>
<Links>
<LItemEx>
<LItem ID="LI1" LinkGroup="WebSites"
Image="http://www.microsoft.com/library/homepage/images/mslogo-blue.gif"
URL="http://www.microsoft.com">Microsoft</LItem>
<Blurb>Microsoft Home Page</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI2" LinkGroup="WebSites"
Image="http://msdn.microsoft.com/library/shared/toolbar/graphics/banners/
MSDN_banner.gif" URL="http://msdn.microsoft.com">MSDN</LItem>
<Blurb>Microsoft Developer Network</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI3" LinkGroup="SearchEngines"
URL="http://search.microsoft.com">Search Microsoft</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI4" LinkGroup="SearchEngines"
URL="http://search.microsoft.com/advanced_search.asp?siteid=us/dev">Search
MSDN</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI5" LinkGroup="OtherSites"
URL="http://www.gotdotnet.com">GotDotNet</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI6" LinkGroup="OtherSites"
URL="http://msn.com">MSN</LItem>
</LItemEx>
</Links>
</Context>
</Data>
</Application>
</Tab>
</TabDefinition>
Example 3: Tab with Static Content
This example displays a single tab with static hyperlinks. Two of the hyperlinks have descriptive text and graphics associated with them whereas the other two do not.
.gif)
Figure 4. Tab with static content
The XML used to create this example is shown below:
<?xml version="1.0" encoding="UTF-8" ?>
<TabDefinition>
<Tab ID="static_tab" Name="Example 3: Tab with Static Content"
Filterable="false">
<Application ID="Static_App">
<Pane ID="Main_Pane">
<TextSpan ID="Tab_Description" FontSize="16">Example 3--Tab
with Static Content</TextSpan><Break/>
<Break/>
<TextSpan ID="disclaimer">Note: The contents and the
code for this sample tab originated as part of the white paper
"Customizing the Visual Studio Start Page" and are not supported
by Microsoft Product Support Services.</TextSpan>
<Break/>
<LItemEx>
<LItem ID="LI1" LinkGroup="WebSites"
Image="http://www.microsoft.com/library/homepage/images/
mslogo-blue.gif" URL="http://www.microsoft.com">Microsoft</LItem>
<Blurb>Microsoft Home Page</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI2" LinkGroup="WebSites"
Image="http://msdn.microsoft.com/library/shared/toolbar/
graphics/banners/MSDN_banner.gif"
URL="http://msdn.microsoft.com">MSDN</LItem>
<Blurb>Microsoft Developer Network</Blurb>
</LItemEx>
<HRule/>
<LItemEx>
<LItem ID="LI3" LinkGroup="SearchEngines"
URL="http://search.microsoft.com">Search Microsoft</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI4" LinkGroup="SearchEngines"
URL="http://search.microsoft.com/advanced_search.asp?siteid=us/dev">
Search MSDN</LItem>
</LItemEx>
<HRule/>
</Pane>
</Application>
</Tab>
</TabDefinition>
Example 4: Tab with Live Content
This example displays a single tab with hyperlinks, graphics, and text. The content for the tab is provided by a tab definition file on the server. Content that is meant to be updated from a server has two parts: the client-side tab definition file that contains a pointer to the appropriate server and server-side files that render the XML and check that the XML conforms to the Start Page schema.
.gif)
Figure 5. Tab with Live Content
In order to view this example content, you need to create three files: a tab definition file for the client (example4.xml), a tab definition file for the server (serverFeed.xml), and an .asp feed file for the server (serverFeed.asp) that also validates the XML. In addition, example4.xml needs to be changed to point to the Web server where serverFeed.asp and serverFeed.xml have been saved.
Client-side tab definition file content: example4.xml
This client XML references an .asp file, serverFeed.asp, that must be located on a Web server, referred to in the XML as http://www.test-1.msn.com. If the server is unavailable, the tab displays the text "Unable to load content from the server."
<?xml version="1.0" encoding="UTF-8" ?>
<TabDefinition>
<Tab ID="live_tab" Name="Example 4: Tab with Live Content"
Filterable="true">
<Application ID="Live_App">
<Pane ID="Main_Pane">
<Break/>
<TextSpan ID="Tab_Description">Unable to load content from the
server.</TextSpan>
</Pane>
</Application>
<Feeds>
<Feed>
<!--Replace "http://www.test-1.msn.com/serverFeed.asp" in the
<Source> element below with the path to where the server .asp file is
located.-->
<Source LCID="1033" URL="http://www.test-1.msn.com/
serverFeed.asp">
<Arg Name="feedName">defaultFeed</Arg>
</Source>
</Feed>
</Feeds>
</Tab>
</TabDefinition>
Server-side tab definition file content: serverFeed.xml
This example server XML must be saved in the root directory of the host Web server as serverFeed.xml. When the client tab definition file calls serverFeed.asp, the .asp file points to serverFeed.xml.
<?xml version="1.0" encoding="UTF-8" ?>
<TabDefinition>
<Tab ID="live_tab" Name="Live" Filterable="true">
<Application ID="Live_App">
<Pane ID="Main_Pane">
<Break/>
<TextSpan ID="Tab_Description" FontSize="16"> Example 4--A Tab
with Live Content</TextSpan> <Break/>
<Break/>
<TextSpan ID="disclaimer">Note: The contents and the code for
this sample tab originated as part of the white paper "Customizing the
Visual Studio Start Page" and are not supported by Microsoft Product
Support Services.</TextSpan>
<Break/>
<HRule/>
<LinkGroupSet>
<LinkGroup ID="WebSites" Title="Hyperlinks with graphics
and text"/>
<LinkGroup ID="SearchEngines" Title="Simple hyperlink
list"/>
</LinkGroupSet>
</Pane>
<Data>
<Context>
<Links>
<LItemEx>
<LItem ID="LI1" LinkGroup="WebSites"
Image="http://www.microsoft.com/library/homepage/images/mslogo-blue.gif"
URL="http://www.microsoft.com">Microsoft</LItem>
<Blurb>Microsoft Home Page</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI2" LinkGroup="WebSites"
Image="http://msdn.microsoft.com/library/shared/toolbar/graphics/banners/
MSDN_banner.gif" URL="http://msdn.microsoft.com">MSDN</LItem>
<Blurb>Microsoft Developer Network</Blurb>
</LItemEx>
<LItemEx>
<LItem ID="LI3" LinkGroup="SearchEngines"
URL="http://search.microsoft.com">Search Microsoft</LItem>
</LItemEx>
<LItemEx>
<LItem ID="LI4" LinkGroup="SearchEngines"
URL="http://search.microsoft.com/advanced_search.asp?siteid=us/dev">Search
MSDN</LItem>
</LItemEx>
</Links>
</Context>
</Data>
</Application>
</Tab>
</TabDefinition>
Server-side ASP content: serverFeed.asp
The VBScript below directs the Start Page tab to use the file serverFeed.xml for its content. The ASP code ensures that valid XML is returned to the Start Page. This file must be saved in the root directory of the host Web server as serverFeed.asp.
<% @ CODEPAGE="65001" LANGUAGE="VBScript" %>
<% IF (Request.QueryString("feedName") = "defaultFeed") THEN
Response.ContentType = "Text/XML"
Response.Redirect "serverFeed.xml"
END IF
%>
<!--This function ensures that URLs returned to the client are safe for
use with the Start Page.-->
function replaceBadURLs(xpath, xmlDocument)
{
var i = 0;
var regex = "^http:|^https:|^news:|^ms-help:|^vs:";
var nodes = xmlDocument.selectNodes(xpath);
for(i = 0 ; i < nodes.length ; i++)
{
if(!nodes.item(i).text.match(regex))
{
nodes.item(i).text = "";
}
}
}