Before installing SharePoint it is important to give some thought to the account that will be used as the portal administrator. Not only is the admin account referenced throughout the portal (area/site ownership, document metadata, list properties, etc.) but it's also used for many basic functions that are central to portal operation - connections to the configuration database, content crawling, application pool identity, and so on. Because the portal administrator must have complete and total control over the SharePoint server(s), a good practice would be to use an account specifically for this purpose that has limited rights elsewhere in the domain.
Assuming that you have followed this methodology in your portal deployment, the next obvious question is: What happens when you change the portal administrator password? Alas, this is a simple question with a not-so-simple answer. There are several steps required to successfully implement this change and they must be done in a specific order. Download the following article which outlines the scope and implications of modifying administrative account properties and defines a procedure for implementing changes.
NOTE: This procedure has been tested for accuracy but each deployment is different; if you run across any variations please post comments and I will update the document accordingly.
Modifying Administrative Account Properties (PDF)
Thursday, November 10, 2005
Monday, November 07, 2005
Extreme SharePoint Design: Validating Area Titles
Most web-savvy tech types know better than to use "special" characters in URL fields - apostrophes, question marks, carets, ampersands, and the like. Unfortunately, this rule of thumb is lost on the average SharePoint user and an open text box with no validation is an invitation to wreak havoc on your carefully constructed portal navigation. IE will overlook most illegal characters but some third-party or custom developed navigational controls will not, so a good practice would be to discourage the use of symbols in Title and URL fields.
You can, of course, add big warnings to the admin pages warning against such malfeasance but we all know that the bigger the warning, the more often it is overlooked. So what to do? The best way to handle this situation is to check the user input against a list of disallowed characters and force text modifications before the field is posted. Fortunately, if your portal consists mostly of WSS sites, you've got it made - the WSS site creation form (scsignup.aspx) has built-in validation to prevent users from entering illegal characters in certain fields; however, if you make extensive use of SPS areas, the solution is not quite so simple. Here's how to replicate the WSS behavior in SPS:
First, create a script to check the user's input against your list of illegal characters, similar to the following:
<script>
function validateSiteName(ctlId)
{
var iChars = "!@#$%^&*()+=[]';,./{}\":<>?";
var ctlName = document.getElementById(ctlId) for (var i = 0; i < ctlName.value.length; i++)
{
if (iChars.indexOf(ctlName.value.charAt(i)) != -1)
{
alert ("The Title field contains special characters which are not allowed. Please remove them and try again.");
ctlName.focus();
return false;
}
}
}
</script>
This script defines the list of illegal characters (iChars), gets the ID of the input box (ctlName), then, if the text box isn't empty, steps through each character and matches it against the list. If a character matches one of the illegal characters, the script displays an alert box asking the user to remove the offending characters and returns the focus to the input field, preventing them from saving the form without fixing the problem.
Second, paste the script into the <HEAD> section of the area creation and modification pages (spnewcategory.aspx and speditcategory.aspx, respectively) or append the function to OWS.JS file (which is called from every page within the portal).
Third, call the script using the onBlur method from the form. Find the following code block on the page:
<SPSWC:InputFormTextBox
runat="server"
id="TextBoxTitle"
IsTextTrimmed = "true"
LabelTextLocId="SiteAdminCreateCategory_Title_Colon_Text" AccessKeyLocId="SiteAdminCreateCategory_Title_AccessKey"/>
Then add the onBlur event to the end:
<SPSWC:InputFormTextBox
runat="server"
id="TextBoxTitle"
IsTextTrimmed ="true"
LabelTextLocId="SiteAdminCreateCategory_Title_Colon_Text" AccessKeyLocId="SiteAdminCreateCategory_Title_AccessKey"
onBlur="validateSiteName(this.id);"/>
This will fire the validateSiteName function whenever the user clicks or tabs out of the input field.
Finally, save the modified pages to the 60\TEMPLATE\LAYOUTS\1033 directory and users will be unable to enter any illegal characters into the area title field, which is used by SPS to construct the bucketed URL, thereby preventing any incompatabilities with navigational tools and utilities.
You can, of course, add big warnings to the admin pages warning against such malfeasance but we all know that the bigger the warning, the more often it is overlooked. So what to do? The best way to handle this situation is to check the user input against a list of disallowed characters and force text modifications before the field is posted. Fortunately, if your portal consists mostly of WSS sites, you've got it made - the WSS site creation form (scsignup.aspx) has built-in validation to prevent users from entering illegal characters in certain fields; however, if you make extensive use of SPS areas, the solution is not quite so simple. Here's how to replicate the WSS behavior in SPS:
First, create a script to check the user's input against your list of illegal characters, similar to the following:
<script>
function validateSiteName(ctlId)
{
var iChars = "!@#$%^&*()+=[]';,./{}\":<>?";
var ctlName = document.getElementById(ctlId) for (var i = 0; i < ctlName.value.length; i++)
{
if (iChars.indexOf(ctlName.value.charAt(i)) != -1)
{
alert ("The Title field contains special characters which are not allowed. Please remove them and try again.");
ctlName.focus();
return false;
}
}
}
</script>
This script defines the list of illegal characters (iChars), gets the ID of the input box (ctlName), then, if the text box isn't empty, steps through each character and matches it against the list. If a character matches one of the illegal characters, the script displays an alert box asking the user to remove the offending characters and returns the focus to the input field, preventing them from saving the form without fixing the problem.
Second, paste the script into the <HEAD> section of the area creation and modification pages (spnewcategory.aspx and speditcategory.aspx, respectively) or append the function to OWS.JS file (which is called from every page within the portal).
Third, call the script using the onBlur method from the form. Find the following code block on the page:
<SPSWC:InputFormTextBox
runat="server"
id="TextBoxTitle"
IsTextTrimmed = "true"
LabelTextLocId="SiteAdminCreateCategory_Title_Colon_Text" AccessKeyLocId="SiteAdminCreateCategory_Title_AccessKey"/>
Then add the onBlur event to the end:
<SPSWC:InputFormTextBox
runat="server"
id="TextBoxTitle"
IsTextTrimmed ="true"
LabelTextLocId="SiteAdminCreateCategory_Title_Colon_Text" AccessKeyLocId="SiteAdminCreateCategory_Title_AccessKey"
onBlur="validateSiteName(this.id);"/>
This will fire the validateSiteName function whenever the user clicks or tabs out of the input field.
Finally, save the modified pages to the 60\TEMPLATE\LAYOUTS\1033 directory and users will be unable to enter any illegal characters into the area title field, which is used by SPS to construct the bucketed URL, thereby preventing any incompatabilities with navigational tools and utilities.
Tuesday, November 01, 2005
MySite Permissions
The MySite site definition (SPSMSITE) is intended to provide only the 'Private' and 'Public' page views for a user's personal site; all other functionality (lists, doc libs, etc.) is handled by the Personal definition (SPSPERS). When customizing these definitions (if you want to provide MySite functionality, you have no choice but to customize the existing definition - I know it's not supported but it's there just isn't any other way), it is important to remember that SPSMSITE is a full definition, with the same base set of included lists as all other defs.
While there are no direct links in the GUI for working with MySite lists, users can add list web parts from the tool pane and, by default, modify the list contents. Since MySite content is global (personal site content is localized to the individual user account), any changes to MySite lists will show up for all users; not an ideal situation.
To work around this issue, change the MySite permissions for Members and Contributors. Use the following URL syntax to access the MySite security page (there is no 'Manage Security' link for this area):
http://%lt;server name%gt;/mysite/_layouts/1033/spcatsec.aspx
Check the Contributor and Member groups (and any others you wish to modify), click 'Edit', and uncheck the 'Add Items' right under the Select Rights section. This will prevent users from doing and end-run around list security by dropping list web parts onto the MySite pages and modifying the content.
While there are no direct links in the GUI for working with MySite lists, users can add list web parts from the tool pane and, by default, modify the list contents. Since MySite content is global (personal site content is localized to the individual user account), any changes to MySite lists will show up for all users; not an ideal situation.
To work around this issue, change the MySite permissions for Members and Contributors. Use the following URL syntax to access the MySite security page (there is no 'Manage Security' link for this area):
http://%lt;server name%gt;/mysite/_layouts/1033/spcatsec.aspx
Check the Contributor and Member groups (and any others you wish to modify), click 'Edit', and uncheck the 'Add Items' right under the Select Rights section. This will prevent users from doing and end-run around list security by dropping list web parts onto the MySite pages and modifying the content.
Tuesday, October 18, 2005
New Customer Success Story
From time to time, when we're engaged on a project that is a bit out of the ordinary or involves a great deal of customization, I like to do a case study to highlight the challenges, achievements and lessons learned during the course of the engagement. We recently completed such a challenging assignment for a premier architectural services firm based in Ft. Worth, Texas. Their story contains valuable insights for companies of similar size who are considering a new portal implementation using SharePoint Products and Technologies.
If you, your firm, your clients, partners or other SharePointers are interested in reading the case study, it is available for download here.
If you have any questions or would like more details on the technical architecture/development/etc., feel free to post a comment with your email addy and I'll respond accordingly.
If you, your firm, your clients, partners or other SharePointers are interested in reading the case study, it is available for download here.
If you have any questions or would like more details on the technical architecture/development/etc., feel free to post a comment with your email addy and I'll respond accordingly.
Monday, October 10, 2005
Extreme SharePoint Design: Custom MySite Titles
When customizing personal sites (MySite), it is important to remember that you're really working with two site definitions - SPSMSITE (which provides the Public and Private default pages) and SPSPERS (which contains all the lists and libraries). SPSMSITE is nothing more than a launching pad for SPSPERS - the bulk of the functionality is in the personal site definition.
This is important to remember when modifying the menus, links and other navigational elements. In some instances, such as the public and private pages, you will be referring to MySite url's (/mysite/); in others, such as document libraries and lists, you will be referring to Personal url's (/personal/[username]/). This can be quite confusing when, for example, you need to create a site title that is displayed on every page and links back to either the public or private view.
The SharePoint object model has some built-in functions that help you determine your site context but they don't span multiple contexts (in other words, there's no way to know which mysite is associated with the current personal path a page is in) and they don't always expose data the way you need it. In the following example, we'll use various properties of the GetContextWeb method to create a personal site title based on the user's full name from Active Directory that, when viewed by the site owner, links back to the private home page, and when viewed by a reader, links back to the public page.
//Retrieve the site title, which should be the user's full name from AD
string strFullName = SPControl.GetContextWeb(Context).Title;
string strTitle;
int intLocation, intLength;
// Determine length of string, find comma separator if one exists
intLength = strFullName.Length;
intLocation = strFullName.IndexOf(", ");
// If a comma is not found (the user name is not separated into Last Name, First Name), set the Title value to the full Title from AD; otherwise, parse out the first name and last name, remove the comma and space, and reverse the strings to read First Name Last Name
if (intLocation == -1)
strTitle = strFullName;
else
strTitle = strFullName.Substring(intLocation + 1) + " " + strFullName.Substring(0,intLocation );
// Determine if the current user is the site author; if so, set the link href value to mysite and write out the Title. If the current user is only a reader, set the link href to the public url and write out the same Title value.
if (SPControl.GetContextWeb(Context).CurrentUser.LoginName == SPControl.GetContextWeb(Context).Author.LoginName)
{
Response.Write("<a href='/mysite/default.aspx'>" + strTitle + "</a>");
}
else
{
Response.Write("<a href='/mysite/public.aspx?accountname=" +
SPControl.GetContextWeb(Context).Author.LoginName + "'>" + strTitle + "</a>");
}
Note that you will only be able to execute this code from a user control; standard web part pages won't allow code execution. To call a user control from within a web part page, create an .ascx file, insert the required registrations (be sure to utilize Microsoft.SharePoint.WebControls) and code, then register the page location (usually the /bin folder on the virtual server), and call the registration from within the web part page.
This is important to remember when modifying the menus, links and other navigational elements. In some instances, such as the public and private pages, you will be referring to MySite url's (/mysite/); in others, such as document libraries and lists, you will be referring to Personal url's (/personal/[username]/). This can be quite confusing when, for example, you need to create a site title that is displayed on every page and links back to either the public or private view.
The SharePoint object model has some built-in functions that help you determine your site context but they don't span multiple contexts (in other words, there's no way to know which mysite is associated with the current personal path a page is in) and they don't always expose data the way you need it. In the following example, we'll use various properties of the GetContextWeb method to create a personal site title based on the user's full name from Active Directory that, when viewed by the site owner, links back to the private home page, and when viewed by a reader, links back to the public page.
//Retrieve the site title, which should be the user's full name from AD
string strFullName = SPControl.GetContextWeb(Context).Title;
string strTitle;
int intLocation, intLength;
// Determine length of string, find comma separator if one exists
intLength = strFullName.Length;
intLocation = strFullName.IndexOf(", ");
// If a comma is not found (the user name is not separated into Last Name, First Name), set the Title value to the full Title from AD; otherwise, parse out the first name and last name, remove the comma and space, and reverse the strings to read First Name Last Name
if (intLocation == -1)
strTitle = strFullName;
else
strTitle = strFullName.Substring(intLocation + 1) + " " + strFullName.Substring(0,intLocation );
// Determine if the current user is the site author; if so, set the link href value to mysite and write out the Title. If the current user is only a reader, set the link href to the public url and write out the same Title value.
if (SPControl.GetContextWeb(Context).CurrentUser.LoginName == SPControl.GetContextWeb(Context).Author.LoginName)
{
Response.Write("<a href='/mysite/default.aspx'>" + strTitle + "</a>");
}
else
{
Response.Write("<a href='/mysite/public.aspx?accountname=" +
SPControl.GetContextWeb(Context).Author.LoginName + "'>" + strTitle + "</a>");
}
Note that you will only be able to execute this code from a user control; standard web part pages won't allow code execution. To call a user control from within a web part page, create an .ascx file, insert the required registrations (be sure to utilize Microsoft.SharePoint.WebControls) and code, then register the page location (usually the /bin folder on the virtual server), and call the registration from within the web part page.
Friday, September 30, 2005
Search Index Rules Syntax
SharePoint does a pretty good job of handling long, complex or unique URLs within the interface; many lists use relative pathing, Area and Site URLs preserve spaces for easy readability, and so on. One instance where this is definitely NOT the case is the application of rules for inclusion and exclusion of content sources.
When creating a rule that references a URL path, such as http://servername/Area, you must replace any spaces and special characters (ampersands, apostrophes, commas, etc.) with the proper URL encoding (%20, %26, %2C, etc.). Otherwise, the MSSearch process will ignore the rule and continue evaluating results against valid rules.
Also, remember that the order of the rules is important. If you are trying to exclude the above URL, the Portal_Content index will have a default inclusion rule of http://servername/; any new rules you create will be processed after this rule is satisfied. Since the default rule includes all content, any antecedent rules will be ignored. To address this issue, simply move your exclusions to precede the blanket inclusion and the search service will properly exclude the specified content source.
When creating a rule that references a URL path, such as http://servername/Area, you must replace any spaces and special characters (ampersands, apostrophes, commas, etc.) with the proper URL encoding (%20, %26, %2C, etc.). Otherwise, the MSSearch process will ignore the rule and continue evaluating results against valid rules.
Also, remember that the order of the rules is important. If you are trying to exclude the above URL, the Portal_Content index will have a default inclusion rule of http://servername/; any new rules you create will be processed after this rule is satisfied. Since the default rule includes all content, any antecedent rules will be ignored. To address this issue, simply move your exclusions to precede the blanket inclusion and the search service will properly exclude the specified content source.
Thursday, September 29, 2005
Extreme SharePoint Design: 'Go Back To [Area/Site]' Link
The ability to call pages in the /_layouts/1033/ directory is very convenient; all the administration pages can be stored in one location and referenced from any area or site within the portal. SharePoint uses the SPControl.GetContextWeb(Context) and SPControl.GetContextSite(Context) functions to determine what context the user is in when a page is called, then presents the appropriate content. Pretty slick.
There's just one problem: when accessing these pages, users often get lost with no way to return to where they came from. Nothing is more frustrating than finding yourself seven steps into a wizard with no way to bail out but to smack the 'Back' button repeatedly. The solution is a 'Go Back To [Area/Site]' link at the top of each administration page which gives the user one-click access to the place they started from.
Insert the following code into AlternateHeader.aspx or directly into your administration pages just after the PageHeader section (if you're using heavily customized Site Definitions as I often do, most of your admin pages will have header code in them to overwrite AlternateHeader and PortalHeader; just paste the following code into the appropriate section and format it as needed):
<%
try
{
Response.Write ("<a href='" + SPControl.GetContextWeb(Context).Url + "'>Go Back to " + SPControl.GetContextWeb(Context).Title + "</a>");
}
catch
{Response.Write ("Portal Administration Page");
}
%>
The 'try' block creates a link back to the root of the referring area/site using the title field as the link text. The 'catch' block writes out a general statement that you can replace with anything you like, just in case the link fails to render properly.
NOTE: In 'Extreme SharePoint Design: Creating Custom User Menus', I used the same function to replicate the behavior of the 'Home' button on WSS sites. Use SPControl.GetContextWeb(Context) anytime you want to refer to the root URL of an area or site; use SPControl.GetContextSite(Context) to reference the site collection the current site belongs to.
UPDATE: I forgot to mention that you'll need to insert the following code at the top of alternateheader.aspx in order for SharePoint to parse inline code blocks on the page (otherwise you will receive the dreaded 'External component has thrown an exception' error):
<%@ Page language="C#" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
There's just one problem: when accessing these pages, users often get lost with no way to return to where they came from. Nothing is more frustrating than finding yourself seven steps into a wizard with no way to bail out but to smack the 'Back' button repeatedly. The solution is a 'Go Back To [Area/Site]' link at the top of each administration page which gives the user one-click access to the place they started from.
Insert the following code into AlternateHeader.aspx or directly into your administration pages just after the PageHeader section (if you're using heavily customized Site Definitions as I often do, most of your admin pages will have header code in them to overwrite AlternateHeader and PortalHeader; just paste the following code into the appropriate section and format it as needed):
<%
try
{
Response.Write ("<a href='" + SPControl.GetContextWeb(Context).Url + "'>Go Back to " + SPControl.GetContextWeb(Context).Title + "</a>");
}
catch
{Response.Write ("Portal Administration Page");
}
%>
The 'try' block creates a link back to the root of the referring area/site using the title field as the link text. The 'catch' block writes out a general statement that you can replace with anything you like, just in case the link fails to render properly.
NOTE: In 'Extreme SharePoint Design: Creating Custom User Menus', I used the same function to replicate the behavior of the 'Home' button on WSS sites. Use SPControl.GetContextWeb(Context) anytime you want to refer to the root URL of an area or site; use SPControl.GetContextSite(Context) to reference the site collection the current site belongs to.
UPDATE: I forgot to mention that you'll need to insert the following code at the top of alternateheader.aspx in order for SharePoint to parse inline code blocks on the page (otherwise you will receive the dreaded 'External component has thrown an exception' error):
<%@ Page language="C#" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Updated SharePoint Resources List
Heather has updated her SharePoint Resources List with a bunch of new content. This should be your first stop for tips, tricks, and general How-To's.
If you're looking for a list of tools and utilities, including commercial and non-commercial software, web parts, add-ons, and the like, I maintain a brief list here and Joris Poelmans has a monster list here.
BTW, whatever happened to the Sharepoint Template Project???
If you're looking for a list of tools and utilities, including commercial and non-commercial software, web parts, add-ons, and the like, I maintain a brief list here and Joris Poelmans has a monster list here.
BTW, whatever happened to the Sharepoint Template Project???
Wednesday, September 28, 2005
New Blog Template
Shane was kind enough to let me know that the blog template I was using didn't render properly in Firefox, so I switched it up to something new. Not very compelling, I know, but I don't have time at the moment to whip up a better one (the stock Blogger templates just don't give you much to choose from).
Drop a comment and let me know if this one works any better...
Drop a comment and let me know if this one works any better...
Tuesday, September 27, 2005
Extreme SharePoint Design - Creating Custom User Menus
Finally, after much delay, the lastest installment in the Extreme SharePoint Design series is finished. In this installment we will explore the creation of custom menus using the default Actions and Views menus in SharePoint Portal Server 2003.
Originally intended to be a much shorter article, I kept finding additional things I felt needed to be included to present a complete picture, so the final version is rather lengthy. Hence the linked PDF as opposed to one big blog post. Download the article here (right-click, choose 'Save Target As'):
Extreme SharePoint Design - Creating Custom User Menus (PDF, 464k)
Enjoy!
Originally intended to be a much shorter article, I kept finding additional things I felt needed to be included to present a complete picture, so the final version is rather lengthy. Hence the linked PDF as opposed to one big blog post. Download the article here (right-click, choose 'Save Target As'):
Extreme SharePoint Design - Creating Custom User Menus (PDF, 464k)
Enjoy!
Subscribe to:
Posts (Atom)