Today's question - well, this week's anyway - from the newsgroups is how do you link to a specific page within a 'Save As Web' site?
Linking to files
Normally, if you want to link between files, say Excel to a specific page in Visio, you'd add a hash symbol and the page name to the end of your link. For example:
C:\MyVisioFile.vsd#Page-2
This format is similar in style to URLs containing 'fragment identifiers' (ie a link to a named anchor tag, with no href, so that the page is presented at a specific position).
Unfortunately you can't use the same syntax for Save As Web. The reason for this is that there's only one top level page to link to. However, we can use the above familiar method as we'll see later on. First, I'll do a quick run through of the basic structure of the 'Save As Web' output.
Save As Web structure
As I mentioned, the Save As Web addon produces a single 'holder' page. In the same directory, a folder called filename_files is created that contains all of the supporting files. You can see the basic structure in the image below and although this represents a vml type output, other gif or jpeg types produce a very similar file set.
Looking at the above structure, Drawing1.htm contains two frames, one for the lefthand toolbar column and one for the main diagram itself*. The toolbar frame also contains a frame that holds the 'widgets' (ie Pan and Zoom, Search and other components). (*Note that the main diagram pages are the vml_n.htm ones with the gif equivilents standing by incase the viewing browser doesn't support vml.)
Most of the heavy lifting is done within the frameset.js Javascript file and it's there that we can find the page navigation functionality. The GoToPage() function, about half way down the file, takes a page index as a parameter and is called when the user clicks on the green button in the toolbar.
A page specific URL solution
The following solution is restricted to a) the user's browser having Javascript enabled and b) that browser being Internet Explorer (version 5 or above), those being the requirements for vml viewing.
So, given the process in the previous section we need to be able to do three things:
- Add a page index reference to the URL in a valid format
- Extract the index from the URL
- Use index within the GoToPage() function
In order to pass the page index reference I'm suggesting that you append the standard URL with a hash symbol, the word 'Page' and a digit indicating the page index (1 based). For example:
http://www.mydomain.com/Drawing1.htm#Page2
From the browser's point of view this appears to be fragment identifier and so works as a valid address*. It doesn't matter that an anchor tag named 'Page2' doesn't exist as when it's not found the page just displays at the top as normal. (*Note that this appears not to work if the page is located on the same PC such as 'C:\...')
The index extraction and page setting can then be accomplished by adding a single function to the main web page, (in the above case Drawing1.htm).
Walkthrough
- Open your Visio document and select File / Save as Web Page...
- In the subsequent Save dialog, select an appropriate file location and click the Publish... button
- In the Save as Web Page dialog select the desired options in the Publishing options and vml output under the Advanced tab
- Click OK and then locate you primary web page (eg Drawing1.htm) using Windows Explorer and open in Notepad or some other editor
- Copy and paste the code below into the file directly following the second script tag
window.onload = SetPageView;function SetPageView()
{
var sURL = document.URL;
var firstNumberIdx = sURL.indexOf( "#Page" ) + 4;
var nLast = sURL.length;
var sPageNumber = sURL.substring(firstNumberIdx + 1, nLast);
var cntPages = g_FileList.length;
var newPageNumber = parseInt(sPageNumber);
if (!(isNaN(newPageNumber))) {
if (newPageNumber >= 1 && newPageNumber <= cntPages) {
GoToPage (newPageNumber - 1)
}
}
}
What the above code is doing is this -
- The SetPageView function is called by the onload event of the window object.
- The URL is retrieve and set as a variable
- The indices of the first and last digits are identified and used to extract the desired page number as a string (sPageNumber), which is then converted to a integer (newPageNumber)
- The number is then checked to ensure that it is not 'Not-a-Number', or in clearer English that it is a number
- A further check ensures that this number sits within a valid range of available pages (found from an existing global variable named g_FileList)
- If all of the above checks are satisfied the number is then passed to the GoToPage function, which does it's magic and reveals the correct page. (If one of the checks fails then nothing happens and the default page (1) is set.)
Other options
The above solution is, of course, just one option. If you're integrating your web page into ASP.NET or some other server based technology then you may be able to pass in the page index as a parameter.
If you either don't need or are restricted to a non-Javascript environment then the image-based files are still there to link to directly (ie one of the gif_1.htm files in the above structure image).
If you simply want to change the default opening page from 1 to a different page then you can reset the global variable, g_CurPageIndex, to the desired index (zero based).
The possibilities are endless, or at least pretty extensive, so if you feel that I've missed out on a glaringly obvious one please do add a comment.
In the meantime, I hope this helps out.