Thursday, March 19, 2009

SharePoint Data Zoom Web Part brings NVelocity, MVC to SharePoint


In the coming days, SharePoint Solutions will be releasing our new SharePoint Data Zoom Web Part. With just about all the effort of falling off a truck, this new web part will allow you to pull data from nearly any data source and integrate it directly inline with your SharePoint content. This is made possible with the help of a powerful template engine called NVelocity, but more on that later. (Note: NVelocity is a port of the Apache Velocity template engine to .NET. To find out more about template engines and template languages, start with this article on Wikipedia.)
To determine if the Data Zoom Web Part is right for you, take a look at the following snippet and ask yourself, "would I like to create data-driven web parts literally this easily"?
<p>Hello $customer.Name!</p>
<table>
#foreach( $widget in $widgetsOnSpecial )
#if ( $customer.hasPurchased($widget) )
<tr>
<td>
$lob.getPromo( $widget )
</td>
</tr>
#end
#end
</table>
If you answered "yes", (or "yeah, dude" for you left-coasters) then you're probably ready to take a ride on the Data Zoom express.
Did I mention we're giving it away for free?
The SharePoint Data Zoom Web Part is the brainchild SharePoint Solutions' software production manager Jeremy Luerkens. After using the NVelocity template engine in another platform, Jeremy felt that the SharePoint world just had to get some of that too. NVelocity is a template engine that allows you to manage your web content according to the Model-View-Controller (MVC) model. With MVC, web page designers can focus solely on creating a well-designed site, and programmers can focus solely on writing quality, robust code to support it.
Out-of-the-box, the SharePoint Data Zoom Web Part will include access to site and cross-site list data within your SharePoint environment. Imagine iterating over list items as easily as in the code listing above. We've included a multitude of helper utilities for accessing, manipulating and formatting data. Everything is accessible from a convenient command menu right within the Data Zoom's source editor. We're also including the SharePoint Data Zoom Extension for Syndication free with the Data Zoom. With this extension, you'll have complete control over fetching and integrating RSS and ATOM feeds into your SharePoint pages. Consider this simple snippet to render a feed:
## Renders an RSS or ATOM feed
##
#foreach($item in $feed.items)
#beforeall
<br/><h2 class="ms-standardheader">$feed.Title.Text</a></h2>
<ul>
#each
<li>
<h3 class="ms-linksectionheader"><a href="$item.Links.get_Item(0).Uri.ToString()">$item.Title.Text</a></h3>
<span class="ms-vb" >$item.PublishDate.ToString()</span>
<blockquote class="ms-vb">$item.Summary.Text</blockquote>
</li>
#afterall
</ul>
#end

I just can't imagine how accessing and integrating data from disparate sources inside and outside SharePoint could be any easier than this, while still maintaining complete control over how and where the data is rendered. For data sources other than SharePoint lists and syndication feeds, we've created several Data Zoom Extensions. In the next few weeks, we'll be releasing extensions for access to a variety of data sources including salesforce.com, Microsoft SQL server and Active Directory. Along with our partners, we'll be creating even more extensions which will allow you to integrate data from just about any source you can find.
Stay tuned for much more on this innovative new web part from SharePoint Solutions.



Saturday, February 21, 2009

Expanding the Size of Announcements Web Part


The announcements web part that is displayed on a team site will limit the amount of body text that is displayed. Here's a simple way to expand the size of the displayed announcements web part on a team site while retaining a similar format.
Start with a Team Site and modify an announcement to contain a large amount of text. This example uses an extreme amount of text!











Next, open the page with SharePoint Designer. Click on the announcements web part and you'll notice a List View Options button is displayed in the upper left corner of the web part. Click on Change Layout.






Select the Layout tab and select the layout that is 3rd or 4th from the bottom of displayed layouts and click OK.




Click Yes to the Site Definition Page Warning dialog. You are now "un-ghosting" the page from the site definition and a custom version of the page is being stored in the database. Save your work in SharePoint Designer.




Reload the page in your browser and look at the results. Notice the additional fields displayed at the bottom of the announcement. Let's get rid of them.






Go back to SharePoint Designer and click on the List View Options button again but this time select Fields. Highlight the fields you want to remove and click the Remove button and then click OK. Save your work in SharePoint Designer and go back and reload your browser to see the results.






The extra fields are now gone.


Sunday, February 01, 2009

Give Blood to your Workflow


Give the gift of life.
What does this have to do with SharePoint workflows? Last week I was teaching our Mission: Automation class where we cover InfoPath and workflows created with SharePoint Designer. One of the things we like to do in these classes is take some ideas from our students on business problems that they are trying to solve using SharePoint workflows and attempt to outline the solution and partially implement it during class (if it doesn't become overly complicated). This particular idea was generated by Janice and here was her problem.
Janice is the blood drive coordinator at her place of business. She wanted to figure out a way to use SharePoint and InfoPath to allow people to register for times to give blood. I thought this sounded like a great example of a scheduling application that many people could find other applications for, so I started down the road of creating the "Blood Drive Scheduling Application" during the class. It uses an InfoPath form that an employee fills out to reserve a time slot for donating blood. In this case, there are two donating stations and each one is scheduled at 15 minute intervals during the day. In other words, for each 15 minute interval during the day, we can schedule a maximum of two people to donate at one time.
If someone changes their mind about the time slot they've reserved, we want to give them a way to make a change. However, we don't want to give them the ability to change the original form…they will simply request a cancellation and submit another form for a new time slot. Some of this has to do with who has security to the different lists that we'll be using in SharePoint to solve this problem.
Now, before we get started let me say that there are a number of ways to solve this problem. I was going for a solution that could be implemented during the class and illustrated some of the features of InfoPath and SPD workflows. This is only one solution. Much more elegant solutions could be implemented!
In this solution we're going to use several lists. Blood Drive Reservations will be a forms library where we'll store the completed InfoPath forms. Departments contains a list of the departments at the company. Time Slots contains a list of all the available time slots during the day when a donation reservation can be made. We'll have a Cancellations list that we can use for someone to request a cancellation of their reservation. Finally, we'll use the built-in Tasks list to assign tasks when a cancellation is requested.
First we'll start out by creating a custom list that has two columns. One is the time for each of the 15 minute time slots during the day that we want to schedule and the other column is for recording how many reservations have been made for the time slot. Here's what the table looks like in datasheet view.


I created all the time slots for 8:00 AM thru 5:00 PM.
Next up is to create the InfoPath form and library in which the completed forms will be stored. The form is pretty simple for our example. Greg suggested we add the department field so there could be some competitive statistics compiled between the different departments. Nothing like a little competition during blood letting!


The four fields defined in our form's data source are DonorName, DonorEmail, DonorDept and TimeSlot.


The DonorName and DonorEmail are populated using default values obtained by calling the GetUserProfileByname method in the web service, UserProfileService, referenced at http://server/_vti_bin/userprofileservice.asmx. This web service will return name/value pairs from the user profile store that is part of SharePoint and normally configured to synchronize with Active Directory. The PreferredName and WorkEmail are used in this example.






The DonorDept field is populated by creating a data connection to a SharePoint list containing departments. Nothing really complicated here.


Now, the time slot field is populated in a rather unique way. The idea here is to filter the available time slots based on the value in Counter field in the Time Slot list. We're going to be updating the Counter field with a workflow whenever a new reservation is submitted. We need to create a view on the field that is filtered to only show time slots when the value of the counter is less than 2. I created a view called AvailableTimeSlots and added the simple filter as shown.


Now we're going to use a trick to populate the DonorTimeSlot field. We're going to create a data source to an XML file and reference the SharePoint URL protocol supported by OWSSVR.DLL. This is documented in the WSS SDK and is referenced as follows. http://server/path/sitename/_vti_bin/owssvr.dll?Cmd=Display&XMLDATA=TRUE&List={ListGUID}&View={ViewGUID}. The exact URL for our example is http://portal.awbikes.local/sitedirectory/bd/_vti_bin/owssvr.dll?Cmd=Display&XMLDATA=TRUE&List={BAA912CA-D4D4-4786-B2B8-B33DA8691CA4}&View={35F16EC8-64E9-4BCE-8C8A-CD3D142AD894}.


The GUIDs for the List and View can be found by selecting the Modify View link in the view selector and decoding the GUIDs in the URL that is displayed.
http://portal.awbikes.local/SiteDirectory/bd/_layouts/ViewEdit.aspx?List=%7BBAA912CA%2DD4D4%2D4786%2DB2B8%2DB33DA8691CA4%7D&View=%7B35F16EC8%2D64E9%2D4BCE%2D8C8A%2DCD3D142AD894%7D&Source=http%253A%252F%252Fportal%252Eawbikes%252Elocal%252FSiteDirectory%252Fbd%252FLists%252FTime%2520Slots%252FAvailableTimeSlots%252Easpx


The List GUID and View GUID are URL encoded, and you can "un-encode" them if you want to (but you don't have to) by replacing %7B with a left curly brace { and %7D with a right curly brace }. %2D can be replaced with hyphens. In the example above, %7BBAA912CA%2DD4D4%2D4786%2DB2B8%2DB33DA8691CA4%7D becomes {BAA912CA-D4D4-4786-B2B8-B33DA8691CA4}.
In the next dialog on the Data Connection Wizard, choose the option to Access the data from the specified location.


Give the data connection a name and make sure you automatically retrieve data when the form is opened and click Finish.


You can see the completed URL n the Summary section. I like the way the URL looks when the GUIDs are un-encoded…just easier on the eyes.
On the list box entries for the DonorTimeSlot field you need to reference this data source, OWSSVR, and select the entries as shown.




This will populate the DonorTimeSlot list with the filtered list from the AvailableTimeSlots view.
When we publish our form we will promote all of our fields so they appear as metadata columns in SharePoint.


Now, on to our first workflow.
The first workflow is fairly simple. When a new form is added we want to increment the value of the counter in the Time Slots list for the time slot selected. If two people select the same time slot, the value will be incremented to 2 and the time slot will no longer show up as an available time slot on the drop-down list in our form (because of the filter we created for our AvailableTimeSlots view). Within this workflow, we can also send a confirmation email to the donor. If we really want to get fancy, we can send a reminder email 24 hours before the scheduled appointment. Here's the workflow in SPD.
First, let calculate the new counter value by retrieving the value currently in the time slot and adding 1. We'll save this calculated value in a variable called IncrementedTimeSlotCounter.


To retrieve the current value of the counter we perform a lookup which reads as
Select Counter from Time Slots where Time Slots:Title equals Blood Drive Reservations:Donor Time Slot.
We are matching up the Title in the Time Slot list (e.g. 8:15 AM) with the time slot selected by the donor on the form from the drop-down list. Then we simply add 1 to it and store it in a variable.




Next we update the value of the counter in the Time Slots list. In this example, we've created another step in the workflow to do this.




Here's the screen shot of selecting the Counter field to update in the Time Slots list.


In the "Find the List Item" section, here's the lookup. Again, we're matching up the Time Slots:Title field with the Current Item:Donor Time Slot field (Current Item being our item we're working on in the Blood Drive Reservations list).


Now let's create a workflow that sends a confirmation email and a reminder email. We'll send the confirmation email right away and pause until early in the morning on February 3rd and then send a reminder email. We can do this with a new workflow that also starts when the item is created. It is okay to have multiple workflows running. Here's what it looks like (nothing fancy). We can reference the Donor Time Slot in the email by clicking the Add Lookup to Body button.


The second step we'll use the Pause Until Date action and put in a pause with a hard date of February 3rd and a time of 4 a.m. Just a quick and dirty reminder email.


We're all set on the reservation side. Now, on to the cancellation process. Here's the way the cancellation process will work.
We really don't want end users to be able to delete reservation in the list and we can control that by creating a permission level that is similar to Contribute but without the permissions to edit and delete. We can alter the security settings on the reservation list so that our Visitors have this permission level for the reservation list.


If someone wants to cancel, they can insert an item in the Cancellations list. They can select themselves from a drop-down list of people who have reservations and click OK to create the request. I chose to do it this way so we can get a good match on the Donor Name. There are other ways to handle this, but this is quick and dirty.


Once they create a cancellation request, a task is assigned to Connie via a workflow. In this workflow I Iogged some variables to the workflow history list for debugging purposes and then assigned a task to Janice, er, I mean, Connie using the Collect Data from a User action. Logging information to the history list is a very valuable technique for troubleshooting and validating information in the workflow. I normally use three actions in sequence to do this: Build Dynamic String, Set Workflow Variable and Log to History List.


Tasks are very important to understand in workflows. They are so important they get their own categorization in the Actions selection list.


Collect Data from a User allows you to assign a task and, when that task is edited, a custom form is displayed with fields on it that you define in the workflow. In this case we are going to ask Connie if it is okay to delete the reservation with a Yes/No drop-down. Another workflow, Delete Reservation, was created to start on a change to the Tasks list. It's job is to determine what the response was (Yes or No) and lookup and delete the reservation. One of the reasons this method was chosen was because the workflow runs with the credentials of the person who started it. Connie will have the permissions required to delete the item in the reservations list, while the donor does not. It also allows her to verify that the person has requested to delete their reservation and not somebody else's. Here's what the Collect Data from a User action looks like.










Next we'll take a look at the Delete Reservation workflow. This workflow is created on the Tasks list. It has three steps. In the first step we set some variables that we'll use in the workflow. These are very important because we are looking up the IDs of the Blood Drive Reservation we need to delete as well as the Time Slot we need to decrement so it is again available. The key to these lookups begins with the fact that workflow tasks hold some very important information. The contain a "foreign key" back to the ID of the item in the original list.


The first thing we need is the ID of the reservation we might be deleting. To get this we choose to lookup the ID field from the source Blood Drive Reservations. We are going to find this by first matching the name selected in the Cancellations list with the Donor Name in the Blood Drive Reservations list. To find the correct item in the Cancellations list, we need to reference the Workflow Item ID in the Tasks list (our current list) and match that to the ID of the item in the Cancellations list. It is very important to understand that you have access to the Workflow Item ID in the Tasks list. This can be very confusing if you are new to SharePoint Designer workflows, but with some patience it can be understood without having to be a programmer.


Once we have the ID of the reservation, we can find the ID of the time slot that is referenced on the reservation. We'll use this to update the counter on the time slot. We want to find the ID of the time slot so we match the Donor Time Slot on the Blood Drive Reservations list (e.g. 8:30 AM) with the Title on the Time Slots list. We can find the Donor Time Slot by matching the ID of the Blood Drive Reservation with the ID that we looked up in the previous action and stored in the variable ReservationID.


The next step is just some more logging of messages and variables to the history list for debugging purposes. In this example I'm logging the IDs I looked up to insure that I have the right ones.


The final step is to actually delete the reservation. First we look up the current value of the time slot of the reservation to be deleted and subtract 1 and store the result in a variable called DecrementedTimeSlotCounter. This is easy to do since we have already looked up the value of the ID of the time slot that we need to update in the Set variables step.


We can then update the counter value, again using the ID of the time slot that we previously set in the variable TimeSlotID.


Finally we can delete the reservation by using the ID of the reservation that we previously stored in the variable ReservationID.


I know this has been a long post, but hopefully it helps some folks out there become more familiar with SPD workflows. This solution is far from perfect and there are several other ideas I would probably incorporate, but it provides a good demonstration of creating a scheduling application with workflows. I hope you've enjoyed it and learned at least one thing (always my goal).
I'm on my way to bed so I can get on a plane tomorrow to do some training in San Antonio, Texas…a short flight from Dallas. Y'all take care!
Give the gift of life…donate often!

Tuesday, January 27, 2009

Updated Workflow Essentials Product Release


We've just released an update to our popular Workflow Essentials software product. This release includes improvements to the Create Site by Template, Get User Property, Get User Display Name, Get User Manager, Get User Title and Get User Department activities. A complete change log can be found here.

New SharePoint Workflow Resource Center



We've just launched a new SharePoint Workflow Resource Center on our site. We've been heavy into SharePoint workflows since the release of the 2007 versions of MOSS and WSS. We have done a lot of training on the subject, a lot of blogging, consulting projects and most recently, developed an add-on, Workflow Essentials.

So, we felt it was time to pull all of these resources together in one easy to use, easy to find place on our site. If you are interested in leveraging SharePoint's built-in workflow engine to its fullest, I encourage you to visit the new Workflow Resource Center.

Tuesday, January 20, 2009

Installing Adobe’s 64-bit PDF iFilter 9 on MOSS


I was recently working on a new installation for a client and convinced them to put their installation on a 64-bit machine. Their installation was only a single server install, but I still set up service accounts for all the bits (more specifically, I set up SPService for the app pool account and SPSearchReader for the content crawling account). After I got SharePoint installed and running, I went after the search to make sure it worked with all the necessary file types, PDF being a very important one.

In December of 2008, Adobe released their 64-bit iFilter 9, so I thought I'd give it a try. Adobe has an installation procedure, but for some reason I overlooked it on the first try.


After installing the iFilter I added the PDF extension to the list of file types to be crawled. I also installed the Acrobat reader on the machine so I could open the documents after I found them. I started a full crawl and ended up with about 3000 items in the search index from my test set of data. "Good," I thought. As I started performing some searches I found that I couldn't find any PDF documents. So, I checked the crawl logs. Here's where I found the message, "The filtering process could not process this item. This might be because you do not have the latest file filter for this type of item. Install the corresponding filter and retry your crawl." Well, I had just installed the iFilter, so what was up? It started smelling like a security problem

One of the first security issues that sounded plausible was the security settings around the DCOM components. This is where your service account needs to be able to launch the IIS WAMREG admin Service. So, I launched dcomcnfg and edited the security to allow local launch and local activation for my two service accounts, SPService and SPSearchReader. I ultimately removed SPSearchReader, as it was not necessary.


After making these changes and retrying crawls multiple times and even rebooting the server, I was still getting the same error message. What were the potential issues? I thought about and researched several potential issues that came to mind.

  • User rights assignment for the SPService or SPSearchReader accounts?
  • DCOM permissions for IIS WAMREG admin Service.
  • DCOM permissions for the Adobe iFilter thunking component (but this is native 64-bit, right? No more thunking.).
  • Other Adobe DCOM object that needs permission updates?
  • Directory permissions for the directory where the iFilter is installed? It already had read/execute for authenticated users.
  • Adding the iFilter directory to the PATH environment variable?

I added the directory path where the iFilter is installed to the PATH environment variable. In this case, I added C:\Program Files\Adobe\AdobePDF9iFilter64\bin. I even rebooted the server. Same result.

I resorted to making SPService a member of the administrators group. Of course it worked after doing that. That's the answer to every security problem, right? I took the SPSearchReader out of the administrator group and it continued to index PDFs. So, I took SPService out of the administrator group and lo and behold, it continued to work!

In one of the steps of the Adobe installation procedure (4.b.i), they mention changing the key \\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\12.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf to the GUID {E8978DA6-047F-4E3D-9C78-CDBE46041603}. The original value was {4C904448-74A9-11D0-AF6E-00C04FD8DC02}. This appears to be a very important step! I tested the crawl using the new value of the GUID provided and the value that was already there. My tests showed that, if you don't update the GUID, the iFilter won't be able to index the PDF content. Perhaps this was my problem all along! I'm not completely sure and the only way I can make it fail now is by changing this registry key back to its original value.


After the PDF iFilter was working, I also installed the Microsoft iFilter pack and registered it with MOSS, according to article 946336. This is where I found there is a problem with the 64-bit Visio iFilter. Supposedly there is/will be a hotfix, but I couldn't find one.

Monday, January 12, 2009

It is about time: CTP of Visual Studio 2008 extensions for SharePoint v1.3


Microsoft has released a Community Technology Preview of Visual Studio 2008 extensions for SharePoint v1.3.  VSeWSS 1.3 is an interim release for SharePoint Developers until Visual Studio 2010 comes out.

 A few new feature that you may agree "it's about time" that got included:
  • 64-bit support.  Yeah!
  • Deployment will now optionally remove conflicting existing features on the development server prior to redeployment. Previously any feature name conflicts would result in an error.
  • Ancillary assemblies such as for business logic can now be added to the SharePoint Solution WSP.
  • For advanced users a fast deploy is included to update only the compiled assembly on the SharePoint development installation.
Several other new features are in the CTP.  Final release slated for Spring 2009.  Download the CTP  bits here.

ExCM, SPA featured in SharePoint Case Study from Microsoft


Microsoft has written a new SharePoint Customer Solution Case Study featuring our Extranet Collaboration Manager and Site Provisioning Assistant products. The customer featured in this case study is global management consultancy A.T. Kearney.

Case Study: Global Management Consultancy Boosts Client Service, Competitiveness, with Extranet. A.T. Kearney, based in Chicago, Illinois, is a leading management consultancy that serves clients in all major industries as well as government agencies. It has more than 2,500 employees worldwide.

We are excited and proud to provide a prestigious organization such as A.T. Kearney with our software and services in order to further their business goals and facilitate their success in the marketplace. We're also very happy to see Microsoft author a Customer Solution Case Study which features our products and recognizes the value our add-ons provide to SharePoint customers.


If you would like to download a PDF of this Customer Solution Case Study, please go here.

Monday, December 15, 2008

New Release of Extranet Collaboration Manager


Our software team is continuously working to improve and enrich the feature set of our Extranet Collaboration Manager product. This latest release ExCM is no exception, containing a long list of improvements which further establish ExCM as the premiere solution available today for managing your SharePoint-based extranet. Just take a look at these new features:
Feature: User Defined Invitation Expiration Length
The expiration length of an invitation can now be set by an administrator. Possibly values include 3 days, 1 week, 2 weeks, 1 month, 2 months, 3 months, 6 months and 1 year.
Feature: E-mail Address as Username
Administrators can configure a site to use the e-mail address as the user name. This option is applied to the registration, add user and manage profile pages.
Feature: Invitation Zone Targeting
Administrators can specify the SharePoint zone used during an invitation. This feature is especially useful in a dual zone authentication environment where you want all invitation requests to send the user to the Extranet zone (even if the invitation is sent by an internal user).
Feature: New E-mail Messages and Improved E-mail Tokenization
Each e-mail message now supports over 160 standard e-mail tokens (see help documentation for full list). Each token now includes an HTML encoded version to allow better e-mail client support. The addition of the new tokens provides a very flexible e-mail message system. Standard token groups include...
    • ExtranetUrls
    • ExtranetUser (Only when user is present)
    • ExtranetUser.Profile (Only when user profile is present)
    • Site
    • SiteCollection
    • User (Current SharePoint User)
    • WebApplication
    • Zone.Current
    • Zone.Default
    • Zone.Invitation
New e-mail messages have been provided to include the new tokens. The new messages include a better HTML format, Invitation URL support, Extranet User Profile attributes. The goal was to allow an administrator to setup the user profile attributes and invitation zone and not have to worry about modifying the e-mail messages.
Feature: Password Information Message
Administrators can provide a password information message which provides insight to the required password complexity during user registration, password reset and add user pages.
Feature: View Users in Role
Site Collection Administrators can new view all extranet accounts that are members of a selected role.
Feature: Password Reset Support for User with Identical E-mail Addresses
When a user attempts to reset the password for their account and one or more accounts are using the same e-mail address, the user is presented with a list of matching accounts and is asked to select the matching account. After the correct account is selected the user can continue to reset their password.
Feature: Removed Delegation and Mail Provider Configuration
The Delegation Provider and Mail Provider configuration options have been deprecated. These options were deprecated to simplify the interface and eliminate confusion. Implementation of this feature will be altered to provide greater functionality in a future release.
Feature: Improved Installation Experience
The ExCM installation experience has been improved. Improvements include an improved interface which is easier to follow. The SPSolutions.SharePoint.Delegation.wsp and the SPSolutions.SharePoint.Delegation.Templates.Membership.wsp solutions have been merged together to provide an easier installation experience. As a result the Membership Delegation Templates feature has been merged with the Delegation Web Components feature.
The Site Provisioning Assistant installation has been separated from the Extranet Collaboration Manager during the Enterprise Edition installation. The Site Provisioning Assistant Application is still bundled together in this package.
Feature: New Trial Licensing Model
Installation of a trial license is no longer required to evaluate the product. The application creates a 30-day trial license when first accessed.
Download an evaluation copy of ExCM or contact our sales team to arrange a demonstration.