Monday 27 August 2007

Adding custom help pages to SharePoint is complex!

Something I've been curious about for a while now is how to extend the SharePoint help system. A while back I wrote about how to modify 'system' pages in SharePoint by effectively adding new pages - the examples I used were:

  • a custom Recycle Bin page which displays only items deleted by the current user
  • a custom Central Admin page which has a message specific to my fictional organization's administrators

When implementing customizations like this, I thought it would be useful to be able to add custom help to accompany the new functionality. So today I set about digging around the SharePoint help system to see how to do this. Unfortunately my answer so far is that it's pretty difficult and I haven't figured out all the pieces! However, I thought I'd detail what I found in the hope that either it's still useful to somebody, or that someone who knows can perhaps leave a comment or link and complete the jigsaw.

So to be clear, I'm talking about how to add custom application help pages here - nothing to do with the 2 .chm files which are the WSS and MOSS SDK references. In site or central admin pages, the application help pages are linked to from help icon on the top bar:

As you'd expect, this icon (and the link behind it) is provided by the master page for the page. Clicking the link calls a JavaScript function called TopHelpButtonClick() in core.js to open the help window - on most pages a parameter of 'NavBarHelpHome' is passed, though notably pages which link to a page other than the default help page override this value. Since all pages in say, Central Admin share the same master page (and the JS call is in the master page, not the actual page) the code in core.js checks to see if the page itself has specified an override. Individual pages can therefore override the help location specified in the master page using a script block such as:

<script type="text/javascript" language="JavaScript">

       var navBarHelpOverrideKey = "OSSCentralAdmin";

</script>


Core.js will then build a link with this override parameter in rather than 'NavBarHelpHome', meaning that pages can easily link to a custom page rather than the default. In order to link to a custom help page, your page will need to override this value.

The value used here links to a value in a set of mapping files stored in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\XML\HELP. In the case of the value shown above, we find that one of the mapping files, 'OssSearchAdmin_HelpKeymap.xml', contains the following:

 

<helpmap>

    <key>OSSCentralAdmin</key>

    <collectionId>MS.SEARCH.ADMIN.manifest</collectionId>

    <contextId>MS.SEARCH.ADMIN.OSSCentralAdmin</contextId>

</helpmap>


The set of mapping files in this directory all contain similar entries, i.e. a corresponding entry for each page which specifies an override to the default help page. Since these files don't appear to follow any naming convention, I'd venture that any XML file with the correct schema can be dropped in here and the help system will pick it up. When it comes to finding what these references point to, things get interesting! An initial search across the '12' directory using Visual Studio 'find in files' yields no results, but as with most of these things it's worth digging further. In the '\12\HCCab\1033\' directory are a set of .cab files which store the help files used in the SharePoint help system. In the example above, the 'MS.Search.Admin.HC.cab' file is the file which is referenced. Looking inside, we see a number of files, one of which is named 'MS.SEARCH.ADMIN.manifest.xml', which you'll notice is the value for the <collectionId> in the mapping above. The contents of one such .cab file look like:



So a quick recap of so far - we've found how to override the initial help page which is displayed, and how the key specified links to a set of help files packaged as a cab file in the 'HCCab\<localeId>' directory.

The manifest file is obviously key to how the index of the files in the .cab are linked. Incidentally, for those familiar with building SharePoint solution packages, the schema used here is completely unrelated to the 'manifest.xml' file used there. Looking at the contents of one of these manifest files, the first thing that strikes me is it looks like a system-generated file - for one thing there are many parent/child and link relationships which would be complex to document by hand. An extract looks like:

<?xml version="1.0"?>

<helpCollection>

  <name>SearchCentralAdmin</name>

  <id>MS.SEARCH.ADMIN.manifest</id>

  <changedDate>2006-10-13 21:53:57Z</changedDate>

  <createdDate>2006-10-13 21:53:57Z</createdDate>

  <author>Microsoft</author>

  <version>11.0.9413.2</version>

  <lcid>1033</lcid>

  <defaultHelpItem>MS.SEARCH.ADMIN.HA10175815</defaultHelpItem>

  <brandingImage />

  <rootCategory>MS.SEARCH.ADMIN.CH10176169</rootCategory>

  <feedback show="False" />

  <helpItems>

    <helpItem>

      <id>MS.SEARCH.ADMIN.HA10047848</id>

      <parents>

        <parent sortOrder="4" primary="true">MS.SEARCH.ADMIN.CH10176336</parent>

        <parent sortOrder="4" primary="true">MS.SEARCH.ADMIN.CH10176336</parent>

      </parents>

      <relatedItemsPointingToMe>

        <item sortOrder="1">MS.SEARCH.ADMIN.HA10047848</item>

        <item sortOrder="1">MS.SEARCH.ADMIN.ManageSearchService</item>

        <item sortOrder="1">MS.SEARCH.ADMIN.SearchServerSettings</item>

      </relatedItemsPointingToMe>

    </helpItem>

    <helpItem>

      <id>MS.SEARCH.ADMIN.HA10047852</id>

      <parents>

        <parent sortOrder="6" primary="true">MS.SEARCH.ADMIN.CH10176338</parent>

      </parents>

      <relatedItemsPointingToMe>

        <item sortOrder="1">MS.SEARCH.ADMIN.LogSummary</item>

        <item sortOrder="1">MS.SEARCH.ADMIN.LogViewer</item>

      </relatedItemsPointingToMe>

    </helpItem>


However, one thing which does check out is that the file referenced in the <defaultHelpItem> is indeed the page which is loaded initially when the help window opens. So that's something!

 

I can't help thinking though, that a help file generator has been used and it would probably be necessary to use the same approach to add custom help pages. When I started delving I mainly expected to find some .chm files generated by nDoc or Sandcastle somewhere, but it does seem like something I'm not familar with has been used. Robohelp perhaps?

 

If anybody can shed any light on this I'd be interested to hear. In the meantime, I note that others have found alternative ways around the problem, by passing a custom parameter and then modifying core.js to intercept this and open up a completely custom help window, rather than plugging into the existing help system as such. Ragav Jagannathan's post on his approach can be found here - http://ragavj.blogspot.com/2007/04/custom-help-window-can-be-opened-by.html. As Ragav rightly points out, customizing the core.js file is unsupported so you should probably think carefully before going down this route.

[Update - Nick Swan MSN'd me to point out that there is a document library in the Central Admin website which contains help files. Interestingly, it's the same set of files stored in the HCCab folder on the filesystem! It's difficult to tell from the IIS logs which set of files are actually pulled in, as they seem to be dynamically loaded through the '/_layouts/helpContent.aspx' and '/_layouts/help.aspx' pages. Interesting!]

 

11 comments:

SIMANTA said...

hi chris,

1.Create a Blank Site.
2.Edit the Home Page of the Site.
3.On the Home page of the site there are two Web Part Zones (Left & right).
4.On the Left Web Part Zone add two Web Part Controls.

5.From Add Web Part Dialog box select SearchBox web part.

6.By default this web part displays a dropdown and a text box control.
7.If you want to exclude the drop down change the below property - Scopes Dropdown – Dropdown mode - select this (Do not show Scopes Drop down).

8.From Add Web Part Dialog box select Page Viewer Web Part web part.
9.Modify the Page Viewer Web Part’s Link property to your (HelpIndex) file.
10.This help index file contains the list of help module names.
11.Each of the help Module name links it to the relevant (.htm files present in the _layouts/html folder).

12.This Tempalte.htm (Hotel Bookings_template.HTM /
13.Invitations_template.HTM / Travel Assistance_template.HTM

14.Hometemplate.HTM /CoreRegistration_template.HTM) file contains a
(html frame) that internally opens the help content files (HomepageTOC.mht / CoreRegistration.mht / Hotel Bookings.mht / Invitations.mht / Travel Assistance.mht).

15.These (.mht) files are MS word Help User manual files saved as Single
Web Page In the (.mht) format.

16.Create a Shared Service Provider for this site and enable the search settings for the same.

17.Create a document library and upload these user manuals if you want to show search results should display link to help module documents.

18.Create Custom lists for each module where each of the new item will contain the sections of the single help content module. This gives a better user navigation experience because Once the search results are displayed ,user only needs to click on the link that directly displays the searched document rather than opening the whole document.

Chris O'Brien said...

Simanta,

Hmm I see where you're going there but that's not really the solution I was looking for. I guess I'm after something properly integrated with the existing help framework rather than a roll your own solution.

Thanks for the idea though.

Chris.

Anonymous said...

Hi Chris,

I was explored the same thing and I found something interesting. Even we delete the .cab files in \12\HCCab\1033\, the help system works. So the files are not taken from the cab files.

There is a type, Microsoft.Sharepoint.Help.SPhelpMerge, which allows to merge/un-merge one or more HC group of files. I tried merging these help files with the following code:
// where i kept the .metadata file, and 3 metadata file for the 3 category
string mypath = @"C:\SampleHelp\ABC.XYZ.HC"
MergeHCOutcome result;
result = helpmerge.InstallOneHelpCollection(mypath, "ABC.XYZ", 1033,
false, false,true,true, false);
The result returned as MergeHCOutcome.MergeSuccess.
but, I am not getting my custom help displayed when I request it. I am getting the following error:
Cannot display help.
Technical details: HC not found. (abc.xyz.manifest , 1033).
There is no documentation for this SPHelpMerge class, so I feel very difficult to understand its behavior. I also opened a thread in the forum here http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1966496&SiteID=1
I hope we can narrow down this issue soon.

Murugan G.

Chris O'Brien said...

Murugan,

That's good investigative work! I actually noticed your forum post when I started looking into this.

I wonder if SPHelpMerge can be examined in Reflector? I'll try and have a look when I get time.

In the meantime if you find a solution, I'd be interested to hear!

Cheers,

Chris.

Yongwei Xing said...

Hi chris
I want to modify the help system od sharepoint server 2007.But I find what you write dose not work.Do you find a way to modify the default help system?

Thanks!

Mulder

Chris O'Brien said...

Hi Mulder,

I'm afraid I didn't get chance to look at this any further, so I don't have a solution for modifying the existing help framework.

I'm a bit confused as to what you've found that doesn't work (since I don't present a solution in this article), but if you're referring to the "modifying 'system' pages" (not help pages) bits I mentioned early in the article, you can find my code samples linked to from that article (Modifying 'system' pages in SharePoint safely. Those samples definitely work.

HTH,

Chris.

Yongwei Xing said...

Hi Chris

Thanks!

Mulder

Anonymous said...

Hi Chris,

I figured it out :). We have to install .cab file, which contains xml, htm, cs, jif and other help contents, using HCInstal.exe. Once installed the files in the 12hive\HCCab\1033 folder is just used for further updating. The help request served from the Document Library in the CA, which pointed out by Nick Swan.

I have written an article in Codeproject.com Integrating Custom Help Pages to the SharePoint 2007 Help System

Which explains all my findings.

I hope it will help.

Cheers,
Murugan G.

Chris O'Brien said...

Hi Murugan,

So 4 months later we have an answer! Impressive stuff, well done. Next time I need to add custom help pages I'll definitely check your process out.

Thanks for the article and link!

Chris.

Anonymous said...

Hi Chris, We have french language pack in our environment. I have created a french site one of the standard template. When i click on the help icon, i dont find the contents div which consists "Introduction", "Business Intelligence" etc., Can you please let me know which file would have been missed? Do the language packs should be reinstalled? Will it affect the existing sites?

Chris O'Brien said...

@Anonymous,

Sorry, I have no idea. Suggest posting in the forums.

Chris.