Sitemap Macro

I wrote a Visual Studio macro to walk an ASP.NET 2.0 project and create a web.sitemap based on the physical layout of files.

Download.

The macro requires a reference to System.Xml.dll. The macro won’t overwrite or synchronize an existing web.sitemap file, it’s only meant to save some typing if you have an existing project and want to add a sitemap. Once the macro creates the sitemap, you can go in and modify the titles, descriptions, and layout.

Update: Fixed the macro to work with IIS based projects, and added Dan Kahler's suggestion to prompt user to overwrite existing file.

Print | posted @ Wednesday, November 30, 2005 4:46 AM

Comments on this entry:

Gravatar # re: Sitemap Macro
by Keyvan Nayyeri at 11/30/2005 8:21 AM

Well done;
But a question. As you wrote here:
Private ReadOnly validSiteMapNodes() As String = {".ASPX", ".HTML", ".HTM"}
By default it tries to find all pages and add them to SiteMap file but if someone tries to add pages based on Queries he will be unsuccessful.
So probably each developer needs to write same Macro based on his Queries to generate his own SiteMap file? In most cased we have just one .ASPX page but handle many pages on it ;)
And another question: Why it's necessary to have a default start page for project to generate its SiteMap node? Maybe I try set my /Weblog/default.aspx page as default but my home page is /default.aspx file. Which file will be defined as my Home Page in SiteMap file?
  
Gravatar # re: Sitemap Macro
by scott at 11/30/2005 1:31 PM

Hi Keyvan:

Good questions. As I said, the macro only builds a sitemap based on the physical layout. If you do any URL re-writing, virtual path provider trickery, or query string magic - it won't know about those URLs. At least it gives you a starting point to copy and paste additional siteMapNodes - I was just looking to avoid some typing.

As for the default start page - the site map has to have a root <siteMapNode> to represent the top of the navigation tree. For me, the best way to determine the root node was just to look at the start page property. It's not a requirement for sitemaps in general.
  
Gravatar # re: Sitemap Macro
by Paul Litwin at 12/1/2005 7:20 AM

I have been thinking that such a utility would be cool to create. And you beat me to it. Cool.

Okay at the risk of sounding like an idiot...I've never used VS macros before. How do I make use of your macro. I've been playing around with the VS Macros menus, IDE, explorer, etc. and am totally clueless. I want to use your macro but do not know what to do to use it.
Thanks,
Paul
  
Gravatar # re: Sitemap Macro
by scott at 12/1/2005 2:13 PM

I fixed one little bug and uploaded a new version.

Paul, I should have left installation instructions:

1) Open macro explorer (Alt + F8)

2) Right click MyMacros, select New Module (the module name can be anything)

3) Right click the new module and select Edit

3) Replace the contents of the new module with the contents of SiteMapModule.vb

4) Right click References under MyMacros and add a reference to System.Xml

Hopefully that is enough to get you running. Now in the Macro Explorer window of VS.NET you can right click and run the macro...
  
Gravatar # re: Sitemap Macro
by scott at 12/1/2005 3:25 PM

I learned something new -

In step 2 I said the module name can be anything.

Turns out, the name of the module must match the name of the Public Module definition inside.

In other words, I use

Public Module SiteMapModule
'''
End Module

So the module itself must be called SiteMapModule. You can right click the module in Macro Explorer and select "Rename" if it's not named properly..

  
Gravatar # re: Sitemap Macro
by Paul Litwin at 12/1/2005 8:20 PM

That worked. Thanks!
Paul
  
Gravatar # re: Sitemap Macro
by Dan Kahler at 12/1/2005 8:30 PM

Hey Scott, this is really handy - thanks! Works like a champ.

I've found a small modification that's useful to me:

Within the ProcesWebSite sub, I've modified the MsgBox line within "If HasSiteMap(...)" to ask if you'd like to overwrite the existing sitemap file (MsgBoxStyle.YesNo), and moved the Return statement inside this If block. This little tweak saves another step, especially if you're rapidly prototying page organization.

As always, EXCELLENT work.
  
Gravatar # re: Sitemap Macro
by scott at 12/2/2005 12:05 AM

Dan: I really thought you should run with it some more and create something that keeps the sitemap in synch with an existing project ;)
  
Gravatar # re: Sitemap Macro
by Kerric at 12/2/2005 8:22 PM

I tried to install and run the macro in VS2005

I had a problem running the macro and got the following error

URI formats are not supported.

When debugging the code, i noticed that you use the path of the web project and append the name web.sitemap. In VS2005 the path of the webproject is a url in my case to the my localweb server. Im not familiar with the framework for VS Studio is there another property which can find the physical path of the project?
  
Gravatar # re: Sitemap Macro
by scott at 12/2/2005 8:37 PM

Hi Kerric:

I'll have to investigate that one. I've only used the macro with a file system based project, not one hosted in IIS. It might be an easy fix (just use a different project property).
  
Gravatar # re: Sitemap Macro
by Scott at 12/2/2005 10:03 PM

Ok, updated file in place to work with IIS projects.
  
Gravatar # re: Sitemap Macro
by Bill at 12/3/2005 8:42 PM

Are you good at every area of .NET or what. Wayyy cool man!
  
Gravatar # re: Sitemap Macro
by Neal at 1/24/2006 2:05 PM

This is awesome. How would you generate the web.sitemap upon page load? In other words how could I accomplish this without the macro?
  
Gravatar # re: Sitemap Macro
by scott at 1/24/2006 2:09 PM

Neal:

You could use the same code that is in the macro to walk the filesystem and make a web.config file. I'd try to do this from Application_Start instead of a Page_Load.
  
Gravatar # re: Sitemap Macro
by Neal at 1/24/2006 4:15 PM

Could you plz give me an example?
  
Gravatar # re: Sitemap Macro
by Scott at 1/25/2006 2:49 AM

Actually Neal, after thinking about this, the proper way to generate a sitemap at runtime would be to write a custom provider. That's a little more than a simple example :)

There is a white paper on the topic here: msdn.microsoft.com/.../default.asp
  
Gravatar # re: Sitemap Macro
by Sharbel at 2/22/2006 5:08 PM

Hey Scott,

Nice Macro! I do have a little problem, it seems that the directories and filetypes listed in the validSiteMapNodes() and the excludeDirectoriesPrefix() are not being enforced correctly?

For example, in my /images directory, I have a bunch of .jpg/.gif/.png etc type files. An XML node is created for each one, however, no URL attribute is inserted, just a title. I would assume that the whole Node should be foregone?

Moreover, I edited the excludeDirectoriesPrefix() to include a few directories I didnt want crawled, but they still are crawled.

Are these known problems?
  
Gravatar # re: Sitemap Macro
by scott at 2/23/2006 6:43 AM

Sharbel:

I'm not aware of any problems - could it be a case sensitivity issue?
  
Gravatar # re: Sitemap Macro
by Robert J. Bullock at 3/23/2006 1:59 PM

Dude, you just saved me 6-8 hours of annoying sitemap editing! THANK YOU!!!
  
Gravatar # re: Sitemap Macro
by Sal at 3/29/2006 3:53 PM

I 2nd the saving of time! Thanks!
  
Gravatar # A small modification
by Joel Reinford at 4/10/2006 6:39 PM

Scott:

This macro is a real time saver. I suggest making the file extension list and excludeddirectory list non-case sensitive by using .StartsWith(name.ToUpper) in each of the two methods below. You're already forcing the item name to uppercase so it just makes sense to force the search string to uppercase too.

Joel Reinford
Data Management Solutions LLC

Private Function IsValidDirectory(ByVal item As EnvDTE.ProjectItem) As Boolean

If item.ProjectItems Is Nothing Then
Return False
Else
For Each name As String In excludeDirectoriesPrefix
If item.Name.ToUpper().StartsWith(name.ToUpper) Then
Return False
End If
Next
End If

Return True

End Function

Private Function IsValidFile(ByVal item As EnvDTE.ProjectItem) As Boolean

For Each name As String In validSiteMapNodes
If item.Name.ToUpper().EndsWith(name.ToUpper) Then
Return True
End If
Next

Return False

End Function
  
Gravatar # re: Sitemap Macro
by ben at 5/2/2006 4:03 AM

error in code:

Dim dte1 As New EnvDTE.DTE
'For Each project As EnvDTE.Project In DTE.Solution.Projects
For Each project As EnvDTE.Project In dte1.Solution.Projects

  
Gravatar # re: Sitemap Macro
by scott at 5/2/2006 4:13 AM

Ben: You shouldn't need that code. You'll want a reference to the existing DTE, not a new one. What problem were you having?
  
Gravatar # re: Sitemap Macro
by Joseph Leonard at 6/29/2006 5:32 PM

Can't get this to work. VS 2005 says following:
Private siteMap As XmlDocument Error "XmlDocument" not definded.

Also pressing F5 does nothing. No error messages and macro does not run.

Is there a walk-through on setting this up?
  
Gravatar # Sitemap Macro instructions?
by John Roberts at 6/29/2006 5:35 PM

Instructions not correct for VS 2005:
I fixed one little bug and uploaded a new version.

4) Right click References under MyMacros and add a reference to System.Xml (There is no such choice after right clicking here. Unable to continue with setup.)

Also how does one RUN the macro?
  
Gravatar # re: Sitemap Macro
by Darin at 7/3/2006 9:52 PM

Any chance that this would work in Visual Studio 2003?
  
Gravatar # re: Sitemap Macro
by scott at 7/4/2006 3:52 AM

Darin:

The macro itself might work in 2003 (I have not tried it), but the sitemap features are 2.0 only, so it may not be useful.
  
Gravatar # re: Sitemap Macro
by Sean Loughrey at 10/14/2006 4:41 AM

This is a great utility. One thing I found is that this will not work if using the web application project add-in. I kept getting a '0' web-site processed message. To test this I created and empty web project and added my file and it worked perfectly. I think I need to change the webProjectKind As String = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}" reference. Can anyone tell where to find the reference for this. Scott. Good work as always.
  
Gravatar # re: Sitemap Macro
by scott at 10/16/2006 3:21 AM

Sean:

For now, you might just remove the code that checks for the project type. I'll try to get out an update that works with WAP this week.
  
Gravatar # re: Sitemap Macro
by Tatyana at 10/23/2006 8:14 PM

how does one RUN the macro? I do not see the option to run if right click on macro ...
  
Gravatar # re: Sitemap Macro
by Keith at 11/8/2006 4:23 PM

Tatyana: I noticed that Scott hasn't replied to your question yet, so I will help him out:

If you name the macro SiteMapModule (you have to name the module the same as the module name in the code), in your Macro Explorer, it will show the CreateWebStemap method under the macro. (If it doesn't, you don't have the module's name set correctly.) You can then right-click on the method (in this case, there is only one: CreateWebSitemap) and get the Run menu option.

HTH
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 2 and 3 and type the answer here: