Friday 16 May 2008

Extending the functionality of the EXPORT Operation of STSADM

With this task it was important to understand the functionality of the current export operation to see whether it was possible to extend it or create a new functionality altogether.
I assumed that the items to be exported were lists, document libraries, blogs, task lists and the like. I tried to imagine having to export my blog from one portal to another.
SharePoint Content Deployment and Migration API
WSS and MOSS use this API at various different places:
* Content Deployment
* STSADM -o export and import
* Copy/Move operations in Site Manager
* Variations
* MCMS 2002 database migration to MOSS 2007
yy

The Content Deployment and Migration API provides the following features:

  • export an entire site collection
  • export a specific site inside a site collection including or excluding content in subsites
  • export a list or document libraries or even of a folder inside a document library
  • export a single list items or documents from a document library
  • export dependent objects (like images referenced by a page) by following links
  • generate as a compressed export file or in uncompressed format
  • allow export with a define a maximum size for the generated compressed file (multiple export files will be created if required)
  • allow incremental export of items based on a given change token. This will export all items that have been created, changed or deleted after the timestamp in the change token.
  • import the exported content with or without identiy preservation (means items will keep their GUID or not)
  • import the exported content under the same or a differnt parent in the destination database
  • do link fixup during import.

In particular we are interested in the use of a change token to export changes only made since the last export.

Programming Reference

Assembly: Microsoft.SharePoint.dll
Namespace: Microsoft.SharePoint.Deployment

Important Objects in the API:

  • SPExport - controls the Export process
  • SPExportSettings - used to configure the export process
  • SPExportObject - defines which objects need to be exported
  • SPImport - controls the import process
  • SPImportSettings - used to configure the import process

The SPExport Class supports exporting specified content from a source Windows SharePoint Services site collection to a cabinet (.cab) file in XML format. This class participates with other classes in the Deployment namespace to support importing, exporting, publishing, and migrating Windows SharePoint content, as well as supporting backup and restore capabilities.

** You can initiate an export operation by first initializing an instance of the Microsoft.SharePoint.Deployment.SPExportSettings class with the required export settings, and then passing the SPExportSettings object to the constructor of SPExport class; you then call the SPExport.Run method.

The following code example demonstrates how to perform an incremental export. Notice that the code sets the ExportMethod property to ExportChanges and then provides a change token.

settings.ExportMethod = SPExportMethodType.ExportChanges;
settings.ExportChangeToken = "1;1;87a71761-2987-48eb-9d29-48428270e01;632937036861200000;5512";

Reference: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.deployment.aspx

To export an entire site collection:

SPExportSettings settings = new SPExportSettings();
settings.SiteUrl = "http://localhost:2000";
settings.ExportMethod = SPExportMethodType.ExportAll;
settings.FileLocation = @"c:\export";
settings.FileCompression = false;
settings.CommandLineVerbose = true;
SPExport export = new SPExport(settings);
export.Run();

where a SPExportSettings object is created to define the general configuration settings for the export to be performed. As we did not select a specific object to export the configured site collection will be selected for export. Then the SPExport object is created based on the configured settings and the export is started by calling the Run method.

The settings being used in the code above:

  • SiteUrl - this property defines which site collection the export should use. All objects being exported always have to be in the same site collection. The Content Deployment and Migration API cannot access items in different site collections in a single operation.
  • ExportMethod - this property allows to define whether to perform an incremental export (value = ExportChanges) or everything (value = ExportAll). Be aware that ExportChanges would require to provide an Export Change Token in a separate property.
  • FileLocation - this property defines where to store the exported content. The value should point to be an empty directory. If the directory does not exist it will be created during export. If file compression is being used, then only the compressed files will be stored on this location. The uncompressed files will be stored in the directory identified by the value of the system wide TMP environment variable. So you need to ensure that the directory the TMP environment variable points to also needs to have sufficient space available.
  • FileCompression - this property defines whether the content should be compressed into a CAB file. If you need to archive the exported content or need to transfer it to a different machine you should choose to compress. If you only export the content to import it afterwards using code on the same machine and don't need to archive (e.g. a copy or move operation) then you should decide to disable the compression as this is significantly quicker.
  • CommandVerbose - this parameter allows to control if the API should provide some verbose output. If you have ever seen the generated output when running STSADM -o export: this is exactly the flag the generates this output. If the value is false no output is generated.

To export specific items like lists, document libraries, list items or documents from a document library:

SPSite site = new SPSite("http://localhost:2000");
SPWeb web = site.OpenWeb("/SomeWeb");
SPList list = web.Lists["MyList"];
SPListItem listItem = list.Items[0]; // select the first list item

SPExportObject exportObject = new SPExportObject();
exportObject.Id = list.ID;
exportObject.Type = SPDeploymentObjectType.List;

SPExportObject exportObject = new SPExportObject();
exportObject.Id = listItem.UniqueId;
exportObject.Type = SPDeploymentObjectType.ListItem;

where the object type will change as per the type you are trying to export.

To export incremental items
If incremental export should be done it is required to save the Change Token of the last full or incremental export. This change token needs then be provided in the ExportSettings to allow the Content Deployment and Migration API to determine which items have changed as follows:
SPExportSettings settings = new SPExportSettings();
...
SPExport export = new SPExport(settings);
export.Run();
string ChangeToken = settings.CurrentChangeToken;
CurrentChangeToken is a read-only parameter populated during export. It contains the Change Token right after the export. So doing an incremental export providing this change token in the future will export all items that have been created, changed or deleted in the configured scope after the change token was generated.
The following code implements an export
SPExportSettings settings = new SPExportSettings();
settings.ExportMethod = SPExportMethodType.ExportChanges;
settings.ExportChangeToken = oldChangeToken;
...
  • ExportMethod - this property allows to define whether to perform an incremental export (value = ExportChanges) or everything (value = ExportAll).
  • ExportChangeToken - this property defines which items to export when using incremental deployment. the incremental export will only export items that have been created, changed or deleted in the configured scope after the change token was generated.
Anothwer way to extend the functionality of stsadm is to create a class that implements the ISPStsadCommand
although i had trouble finding a command to export only items changed form the last export!
References:

http://technet.microsoft.com/en-us/library/cc262759.aspx an explanation of the stsadm operation

http://technet.microsoft.com/en-us/library/cc263384.aspx stsadm operations out of the box

http://blogs.technet.com/stefan_gossner/archive/2007/08/29/deep-dive-into-the-sharepoint-content-deployment-and-migration-api-part-2.aspx

http://www.aisto.com/roeder/dotnet/ This is one magical tool I would recommend everyone use. Reflector is the class browser, explorer, analyzer and documentation viewer for .NET. Reflector allows to easily view, navigate, search, decompile and analyze .NET assemblies in C#, Visual Basic and IL. just install it and piiunt it to stsadm or any program and it will break down every single class, attribute, method and operations for the program!!!

http://www.andrewconnell.com/blog/articles/MossStsadmWcmCommands.aspx

http://msdn.microsoft.com/en-us/library/aa367988.aspx Command Line parameters

http://msdn.microsoft.com/en-us/library/aa979099.aspx The sharepoint Deployment object model

Tuesday 13 May 2008

Adding a custom disclaimer page to a Moss 2007 site

I had a task for a client of adding a compulsary terms and conditions page to a portal site. The requirement was for each user to be presented with this aspx page when they first log on to the portal, and then they have to either accept of reject the disclaimer. It they reject it the browser is closed. If they accept the value was to be saved somewhere so the data could be accessed in case of a query. This is especially needed when dealing with financial or legally regulated clients. There needed to be some way of catching every call to the portal and a check to see whether the user trying to log on has accepted the disclaimer or not then they would be redirected correctly.

My plan was first to use a list to store the accepted information but this would need to be more secure and uneditable so I opted for adding a custom attribute to the user profile for each user.
I would incorporate the disclaimer aspx page into the site by making it a site collection feature. I used visual studio to create my solution.

I used a codeplex template and modofied it to install the disclaimer page to my portal.

http://www.codeplex.com/stsdev

STSDEV is a proof-of-concept utility application which demonstrates how to generate Visual Studio project files and solution files to facilitate the development and deployment of templates and components for the SharePoint 2007 platform including Windows SharePoint Services 3.0 (WSS) and Microsoft Office SharePoint Server 2007 (MOSS). Note that the current version of the stsdev utility only supports creating projects with the C# programming language.

I realised I needed an http handler to intercept every request for every url in the portal, this would perform the functionality of checking for the required value in the user profile. I wrote a class which intercepts the HTTP request pipeline before the default landing page loads,and this class performs a check on a custom profile attribute of our sharepoint user session. I used a Boolean flag to indicate if the user has accepted terms and conditions for site usage. If not, the user is redirected to a custom aspx page from th Http module code, which presents the disclaimer text and a couple of buttons to handle whether the user accepts it or not.

If the user clicks ok, I simply made the call to the user profile properties store and it updates the Boolean field accordingly, and then redirect the browser to the default landing page. The next time a user session is launched for accessing the intranet, the Http module will again intercept the request, the flag will be true, and we do nothing (the request continues on to the default landing page).

To accomplish this required some familiarity with Http modules in ASP.net in general, and also usage of the SharePoint object model to access the user properties. I would recommend starting out with a simple asp.net application with a couple of pages, and write a small class for the Http module which performs a redirect based on a Boolean flag held in a custom user profile attribute, created in the SharedServices admin console, and call the userprofile object to check for the property value in code. I used the UserProfileManager class, which references the Microsoft.Office.Server dll in the project, you can then get user profile info along the following lines...

using Microsoft.Office.Server.UserProfiles

//Get the current user
SPWeb litwareWeb = SPControl.GetContextWeb(Context);SPUser currentUser = litwareWeb.CurrentUser;//Create a new UserProfileManagerUserProfileManager pManager = new UserProfileManager();//Get the User Profile for the current userUserProfile uProfile = pManager.GetUserProfile(currentUser.LoginName);
And then access the properties within the UserProfile class using the collection reference (uProfile[‘CustomAttribute’].value or something like that...)

Using the template you will need to modify the ProjectFolder variable in the .targets file before you build the project –
E.G. "C:\Documents and Settings\tenille\My Documents\Visual Studio 2005\Projects\DisclaimerPage"

Code Examples:

The User Profile Check Class :

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.Office.Server.UserProfiles;
using System.Web.UI;
using System.Configuration;
namespace GLGCustomPages
{
public class UserProfileCheck : IHttpModule
{
public UserProfileCheck()
{ }
#region IHttpModule Members
public void Dispose()
{ }
public void Init(HttpApplication app)
{
// Hook into Release Request
app.ReleaseRequestState += new EventHandler(ReleaseRequest_Handler);
}
///
///

///
///
void ReleaseRequest_Handler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
//HttpContext context = app.Context;
//context.User.Identity.Name;
if (!app.Request.RawUrl.Contains("Disclaimer.aspx"))
{
string originatingUrl = app.Request.Url.ToString();
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
SPWeb currentWeb = site.RootWeb;
SPUser currentUser = currentWeb.CurrentUser;
//Create a new UserProfileManager
UserProfileManager pManager = new UserProfileManager();
//Get the User Profile for the current user
try
{
UserProfile uProfile = pManager.GetUserProfile(currentUser.LoginName);
if (uProfile["DisclaimerAcceptance"].Value.Equals(false))
{
app.Response.StatusCode = 301;
app.Response.AddHeader("Location", "http://" + app.Request.ServerVariables["HTTP_HOST"].ToString() + "/Pages/Disclaimer.aspx?Source="+ app.Server.UrlEncode(originatingUrl));
app.Response.End();
}
}
catch (Exception ex)
{
}
}
}
}
#endregion
}
}

The Disclaimer Page Class File:


using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Administration;
namespace GLGCustomPages
{
public class DisclaimerPage : Page
{
//add in any page control references here
protected Button AcceptDisclaimer;
protected Button DeclineDisclaimer;
protected UserProfileManager pManager;
protected override void OnInit(EventArgs e)
{
AcceptDisclaimer.Click += new EventHandler(AcceptDisclaimer_Click);
DeclineDisclaimer.Click += new EventHandler(DeclineDisclaimer_Click);
base.OnInit(e);
}
protected void AcceptDisclaimer_Click(object sender, EventArgs e)
{
using (SPSite site = new SPSite(SPContext.Current.Web.Url))
{
SPWeb currentWeb = site.RootWeb;
SPUser currentUser = currentWeb.CurrentUser;
//Create a new UserProfileManager
UserProfileManager pManager = new UserProfileManager();
//Get the User Profile for the current user
UserProfile uProfile = pManager.GetUserProfile(currentUser.LoginName);
uProfile["DisclaimerAcceptance"].Value = true;
uProfile.Commit();
Response.Redirect(Request.QueryString["Source"].ToString());
}
//update the user profile attribute and then redirect to the default page
}
protected void DeclineDisclaimer_Click(object sender, EventArgs e)
{
//Response.Write("");
//close the browser event initiated from the client
}
}
}

Note: A snk file must be created in order for it to work.

The elements.xml and feature.xml files must be modofied correctly to build the project.

When deploying the feature, it must be activated in site collection settings and the user profile attribute must be made editable for users who are logging in for the first time. There was a lot of work involved and many errors later I managed to get it working. Any comments or modifications are most welcome.

Ghosting and Unghosting in SharePoint

Sharepoint 2007, built in ASP.NET 2.0, doesn't do that. That is a good thing, because all your customization doesn't get litterred all over the place as multiple files. Your customization sits in the database.

You see, ASP.NET 2.0 has a new concept called Virtual Page Parser. That allows the Sharepoint runtime to query for the aspx as a combination of what is on the file system, and what is in the database. That combination, then appears as a single aspx, and is then run through the pipe of ASP.NET - hence ending up as a class somewhere deep inside temporary asp.net files.
The huge advantage of this approach is of course the ability to revert back to what used to be your page before you completely mucked it up.

In SharePoint Portal Server 2003 (and WSS 2.0) it was a simple task to discover the ghosted status of pages in your SharePoint environment. Simply run "select * from docs where content is not null and leafname like '*.aspx' and listid is null". And to reghost them, all you have to do is set the content to null again.

In Microsoft Office SharePoint Server 2007 (and WSS 3.0), things have become substantially more complicated. In order to alleviate the performance impact of customizing (unghosting) pages, and to alleviate the design burden of modifying SharePoint's look and feel, Microsoft uses Master Pages and Page Layouts to handle the design of a single page in SharePoint. Unfortunately, this means that the content field is almost never null for a page in the database. So how do you figure out if a page is customized?

1. The SPFile object has a property called CustomizedPageStatus, which maps to an enumeration. The values of the enumeration are Customized, Uncustomized and None. (I really wonder what "None" means in this context. It seems to me customized and uncustomized are mutually exclusive, as well as comprehensive.) In the case of a Publishing Page object, i.e. an ASPX page in a "Pages" library with the publishing feature activated, this enumeration always == Customized. I check it like this:
foreach (SPListItem item in List.Items)
{
if (PublishingPage.IsPublishingPage(item))
{
NumberOfPages++;
PublishingPage pPage = PublishingPage.GetPublishingPage(item);
if (pPage.ListItem.File.CustomizedPageStatus == SPCustomizedPageStatus.Customized)
{
Console.WriteLine(pPage.Url + " is customized.");
}
}
}

2. The second way is to use PublishingPage.IsDisconnected. This method works much better than the first I mentioned, except in one (admittedly extreme) circumstance. This circumstance is when you have a publishing page object which does not have any assigned page layout. (Even customized (unghosted) pages have a page layout to fall back on.) The only time I have seen this circumstance is when migrating a SharePoint Portal Server 2003 portal, with a custom site definition for areas, and having a "Page Template Upgrade Definition" file fail. The upgrade will still work (no errors, no warnings), but the pages created have no page layout and are "broken".

3. Use SharePoint designer, the easiest way! SharePoint Designer seems to infallibly detect the customization status for any page. The trouble here of course, is that SharePoint Designer can not be put into a script like the first two methods, there fore limiting optimization.

Making SharePoint Help More Context Sensetive

You can perform more advanced customization of the Help system. For example, each default page has one or more unique Help topics associated with it. These associations are maintained in a table in the Help ASPx home page. By editing this table, you can make your custom Help topics appear in the list of context-sensitive topics for a particular page in your Web site. For more information about advanced customization of Help, see the Microsoft Windows SharePoint Services Software Development Kit.

References
http://lblstrategies.sharepointsite.com/_vti_bin/help/1033/sts/html/wsaextr8.htm
http://ragavj.blogspot.com/2007/04/custom-help-window-can-be-opened-by.html

This method is most suitable when attempting to “take over” the Help link on all Area AND Site pages.

In the ows.js file (located at \\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\LAYOUTS\1033), there is a JavaScript function called HelpWindowHelper(). It is below:

function HelpWindowHelper(strParam){ var strHelpUrl; if (strParam == "") strHelpUrl = "/_layouts/" + L_Language_Text + "/help.aspx" + "?LCID=" + L_Language_Text; else strHelpUrl = "/_layouts/" + L_Language_Text + "/help.aspx" + strParam + "&LCID=" + L_Language_Text; var wndHelp = window.open(strHelpUrl, "STSHELP", "width=270,height=500,menubar,scrollbars,toolbar,resizable"); wndHelp.focus();}

All SharePoint-based Help links run through this function. SharePoint is actually smart enough to pass a parameter telling the function where it came from and allows it to pop up page specific help. I altered this function to change the 'window.open' line to go to my help file (in our case, we actually used a WSS site with tabs for various help topics; you could also use simple HTML).
var wndHelp = window.open(“http://...my help page..“, "STSHELP", "width=270,height=500,menubar,scrollbars,toolbar,resizable");

With this one line change, all SharePoint help links pop up our custom help page!

Lets say you didn't want to lose the valuable targeted help pages. For example, if someone is adding a listing, and clicks help, then they probably want the targeted help that SharePoint provides. But at the top level of an area, if a user clicks help, they probably want our general "Help" site. This is how I handled it. I wrapped the original window.open call with the following: if (strParam.toLowerCase() == "?key=helphome") { strHelpUrl = "http://it/SharePointHelp/default.aspx%22 var wndSPSHelp = window.open(strHelpUrl, "SPSHELP"); wndSPSHelp.focus(); } else { // Original code var wndHelp = window.open(strHelpUrl, "STSHELP", "width=270,height=500,menubar,scrollbars,toolbar,resizable"); wndHelp.focus(); } That way, any page that would go to the SharePointHelp.htm home page, would go instead to our SharePoint site's help page. There is an exception, however. Some context-sensitive topics don't have help pages.

For example, "Manage Users". If you click help there, it passes the context in, but help.aspx doesn't find a topic, and so it sends the user to the help home page. So I added a prominent new link on that home help page to point to our SharePoint site help:

General Help:


http://it/SharePointHelp/default.aspx">
SharePoint Resources


Reference: http://blogs.officezealot.com/mauro/archive/2005/01/15/3857.aspx

My Way of Adding Custom Help Pages to SharePoint

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 Template.htm (GLG_template.HTM /

13.NAV_template.HTM / NAV 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 / NAV Help.mht / Invitations.mht / NAV 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.

Notes: It is not a good idea to build on the standard sharepoint help collection and modifying it to be client specific as any updates such as a service pack will overwrite the core.js file and update all the content and xml files.

It is possible to integrate a URL to link to a specific help page (any URL will do) from the help button on the drop down of a webpart. But to find the page will be laborious as all Moss 2007 help pages are not easily named and hard to find which one it corresponds to. Also the context help is not very sensitive. The only way I have found is not brilliant but it does work:

Popping up a custom help window (as opposed to a SharePoint Help window) while clicking on context sensitive help links on MOSS sites can be done by changing the "Core.js" file which can be found at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\Core.js" on your MOSS web server. Once you locate the file, find the Javascript function "HelpWindowHelper()" and change it to suite your requirements. An example is provided below:function HelpWindowHelper(strParam){var strHelpUrl;if (typeof(strParam)=="undefined"){strHelpUrl="/_layouts/help.aspx?Lcid="+L_Language_Text;}else if (strParam == "&Key=Custom") /* Present new Custom Help Windows when parameter is 'Custom' */{strHelpUrl="/pages/CustomHelp.aspx?Lcid="+L_Language_Text+strParam;}else{strHelpUrl="/_layouts/help.aspx?Lcid="+L_Language_Text+strParam;}var wndHelp=window.open(strHelpUrl, "STSHELP","height=500,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no,width=475");wndHelp.focus();}Please note that this change should be tracked and documented as its a unsupported hack for future Service Pack releases of MOSS 2007 (as SPs might overwrite "Core.js" with its own new version, in which case you will loose your changes if you havent documented them). This is not ideal as a backup of the core.js file could need to be kept before installing an update and re-instated after an update is applied.

Using List Templates

When a user creates a new list, he or she selects a list template to use in creating the list. Windows SharePoint Services includes many list templates by default, and users can customize an existing list and save the customized list as a new list template. List templates created by other users or software vendors can also be imported to the site collection template gallery.
You must have the Manage Lists right to create a list template. The Manage Lists right is included in the Web Designer and Administrator site groups by default. To add or import a list template to the site collection gallery, you must have the Add Item right for the list template gallery, which is included by default in the Web Designer and Administrator site groups for the top-level Web site in a site collection.
A list template is a file that includes all of the design information about the list, such as:

• The columns and fields in the list.
• Any views created for the list.
• List content (optional).

List templates do not include:

• Security settings, such as a list of users or groups with permissions to the list from which the template was created
• Lookup field links. Although lists can contain lookup fields that reference data in another list, that other list (and its data) is not included when you save a list template.
List templates are stored as files with the .stp extension.

Using List Templates

Users can create lists based on templates available on the server or on the site collection. To create a list based on a template, the user can go to the Create page in a site, and then click the list name to create. Custom list templates are listed on the Create page alongside the default set of list templates from the site definitions.
Important - When a user creates a list, he or she can select a list template from the set of list templates on the server and the site collection. This set is filtered based on the site language and the site definition ID that your site is based on. For example, a site based on the Meeting Workspace template has a different site definition ID from a site based on the Team Site template. If you create a Meeting Announcements custom list template from the Announcements list in a site based on a Meeting Workspace template, that template is not available from within a site based on the Team Site template.

Creating Templates
Members of the Administrator site group for a site can create a template based on that site.

To Create a site template

1. On the site, click Site Settings.
2. Under Administration, click Go to Site Administration.
3. Under Management and Statistics, click Save site as template.
4. In the File name box, type the filename to use for the site template file.
5. In the Template title box, type the title you want to use for the template in the site template gallery.
6. In the Template description box, type a description for the site template.
7. If you want to include the existing site content, select the Include content check box.
8. Click OK.

You must be a member of the Web Designer or Administrator site group to be able to create a list template.

To Create a list template

1. Navigate to the list you want to save as a template.
2. Under Actions, click Modify settings and columns.
3. On the Customize page, under General Settings, click Save list as template.
4. In the File name box, type the filename to use for the template file.
5. In the Template title box, type the title you want to use for the template in the list template gallery.
6. In the Template description box, type a description for the template.
7. If you want to include the existing content, select the Include content check box.
8. Click OK.

Managing the List Template Gallery

List templates are managed at the site collection level. You must be an administrator of the top-level Web site in a site collection to manage the list template gallery.
When a user creates a list template, it is automatically added to the list template gallery for the site collection. If you want to import a list template from an .stp file, you can do so from the Manage List Template Gallery page.

To Add a template to the list template gallery
1. On the top-level Web site, click Site Settings.
2. Under Administration, click Go to Site Administration.
3. Under Site Collection Galleries, click Manage list template gallery.
4. On the List Template Gallery page, click Upload Template.
5. In the Name box, type the path to the template, or click Browse. You can upload multiple templates by clicking Upload Multiple Files.
6. Click Save and Close.

To Delete a template in the list template gallery
1. On the top-level Web site, click Site Settings.
2. Under Administration, click Go to Site Administration.
3. Under Site Collection Galleries, click Manage list template gallery.
4. On the List Template Gallery page, click the Edit icon next to the template name.
5. On the List Template Gallery: page, click Delete.Important - After you add or delete a template from the central template gallery, you need to restart the Web service in Internet Information Services (IIS). You can restart all of IIS at once by running iisreset on the command line, or just restart the specific Web sites in Internet Information Services (IIS) Manager. If you are in a server farm environment, you must restart the Web services for each front-end Web server in your server farm.

SharePoint Disaster Recovery notes

STSADM.exe can be used for backing up site collections subsites, pages, document files andlibraries and lists, Security and permission settings, Feature settings NOT for restoring the portal. Use Spsbackup.exe and smmigrate.exe (approved by Microsoft) but very tricky!!! Could use MOSS Back up and restore utility - http://searchexchange.techtarget.com/generic/0,295582,sid43_gci1275871,00.html , very good tutorialon how it works. Other resources include http://technet.microsoft.com/en-us/library/cc261687.aspx http://blogs.msdn.com/joelo/archive/2007/03/09/sharepoint-backup-restore-high-availability-and-disaster-recovery.aspx BRAINSTORM - Use 3rd party back up e.g. Attix 5 to back up databases and MOSS Backup utility to back up the rest, full back up of entire week every friday and incremental every other day. Then in event of site going down we can restore the site using most recent back up. But for fastest restoration, creation of mirror portal to run alongside live portal so site can be restored on mirrored location. Back ups to be stored on seperate server in different location. Must research to prove these concepts!

Tuesday 8 April 2008

Steps to Install Custom Help Pages to SharePoint


  • Manifest.xml file defines the available help items and its relationship in the help collection. Every object, like help topic, help category, image, CSS, JS is represented as helpItem in the manifest file. HelpItem types currently available
    • HelpCategory: Represents a group of topics. Generally the help topics are grouped into category and sub-category. A help category can have one or more subcategory or help topics.
    • HelpTopic: Represents a single help page in the application, e.g. Customize Web Parts.
    • HelpContext: Represents a help context. This is used to provide context sensitive help for pages. For example MS_WSS_ItemLevelPermissions.
    • HelpImage: Represents an image. The images used in the help pages, help topic, are represented as helpImages. The help system fetches the corresponding image display when we request a help topic.
    • HelpCss: Represents the *.css file used in the help pages. We have no need to include this as usual in the *.htm pages. The help system does this for us.
    • HelpScript: Represents the *.js files used in the help pages. It works the same as helpCss.


    • Other elements include <lcid>: The locale Id of the help collection. 1003 is for English.
    • <rootCategory>: The root category for the help collection. This helpItem is parent for all the main categories in the help collection.
    • <helpItem>: Represents each help item in the help collection.
    • <parent>: The parent help item for this help Item. An help item can have more than one parent, so that the help item can participate in more than one help category. The sort order specifies, the position of the help item when it is displayed under this parent.
    • <relatedItemsPointingToMe>: This element is used to achieve two different functionalities. One is to display list of helpItems, help topics, in the "See also" section. The other one is to map an HelpContext Item.
  • Metadata Files - For every helpItem element in the manifest file, there is one metadata file, which describes the helpItem. This metadata files tell whether the helpItem is a helpCategory, helpTopic, helpImage, or helpContext. In the metadata, the filename really doesn't mater, only the extension and the content matter. But generally the filename will be the combination of Id and extension. The id value should match with the helpItem's Id value otherwise the help collection will not be installed properly. The name is used to display in the help category and help topics.
  • Content Files - Every helpTopic, HelpImage, HelpCss, and HelpScript in the help collection have a corresponding content file. For helpTopic it is a *.htm file. HelpContext and HelpCategory will not have any content files. We do not need to do anything special for including the CSS and JS files. If it is part of the help collection, it will be added to the page when we request for a particular help topic by the SharePoint help system. The HTM file should not be defined as the conventional *.htm file. Rather the file should only contain the content and should not contain the HTML or body element. the real HTML file is constructed by the SharePoint help system and this content is included as part of the generated HTML file and rendered to the client.


  • Set Up the Folder Structure as follows:

  • Once files are set up and displayed as in the image, we need to create a CAB file for SharePoint to recognise:
    • Set up a command prompt to run from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN:
      • cabarc -r -p n MS.OSS.HC.cab *.* (where MS.OSS.HC should be replaced with the name of the help collection you are trying to install). I copied all installation applications to my desktop to make things easier and pointed the cmd there.
      • Copy the .cab file to the 12hive\HCCab\1033 folder


  • Create the HelpMap.xml file - Context sensitive help in SharePoint is implemented using:
    • Helpmap file for each helpcollection
    • HelpContext help item, and
    • Associating the helpcontext with an helptopic


    The helpmap files reside in the 12hive\TEMPLATE\XML\HELP folder. The following extract is from Oss.xml file, which is the helpmap file Office SharePoint Server help collection:


    <helpmaps>
    <helpmap>
    <key>AboutGroups</key>
    <collectionId>MS.OSS.manifest</collectionId>
    <contextId>MS.OSS.AboutGroups</contextId>
    </helpmap>
    <helpmap>
    <key>AboutSubsites</key>
    <collectionId>MS.OSS.manifest</collectionId>
    <contextId>MS.OSS.AboutSubsites</contextId>
    </helpmap>
    <!-- other help mapgs -->
    <helpmaps>


    • The Key element represents the helpcontextkey, the CollectionId element represents the helpcollection to which the helpcontext belongs to. And the ContextID is used to define Helpcontext helpitem in the manifest file and helpcontext metadata.
    • Copy the helpmap xml file to 12hive\TEMPLATE\XML\HELP folder
  • In order for SharePoint to recognise that you want your new hel page collection to be displayed when the user clicks on the hel button you need to override the helpcontext key declaration in the javascript file - core.js as follows:
  • Install the CAB file to install the HELP collection to the Portal
    • Once we have the CAB file, we can use the HCINSTAL.EXE, which is available in <12Hive>\Bin directory. We can either install one or all the help collection. The CAB file can be placed anywhere and the path can be given as an argument to hcinstal.exe. But we can place the CAB file in the <12hive>\HCCab\1033 folder and use the following command to install the help collection.
    • Hcinstal.exe /act InstallAllHCs (Once again this should point to the correct directory - C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN
    • The above console application returns 4 if the help collection is installed properly. If nothing is done, this will return 32. When something is wrong with the help content, it will return 256.
    • If the commands have worked Go to the Central Administration site -> view all site content -> helpFold (document library). This is document library which is populated when we install the help content. The help content is placed in a different folder like, manifest, metadata, content for each locale. You should see your installed help files in the folders.


    References: http://www.codeproject.com/KB/sharepoint/CustomHelpPages_SP2007.aspx



Zootmastaflex

Zootmastaflex
The Queen of RockStars!