May 10, 2012
by Mike Oryszak
0 comments

Update on the Book Project

Over the past year I’ve spend a pretty significant amount of time working on a project for Packt Publishing to deliver a SharePoint book focused on creating business solutions.  The project has been pretty daunting with 10 chapters and about 300 pages since I do have a day job and significant community involvement, but it is nearly done.

The full body of work which represents my effort is now available for pre-order with additional information found here:  SharePoint 2010 Business Application Blueprints.  The book is scheduled to ship in July, so I’m excited to see it make its way through the final production steps.

PactPub has also decided to publish the content in a roll-up book Compendium: The Best of Packt for Extending SharePoint which was published in January 2012 and is currently available for purchase.  It contains two of my chapters along with chapters from some of the other SharePoint 2010 related books published by PacktPub.  The two chapters I contributed include:

Chapter 1: Understanding SharePoint Development Choices
Chapter 2: Building an Engaging Community Site
I encourage everyone to check it out.

April 23, 2012
by Mike Oryszak
0 comments

Excuse the clutter

Due to some issues with my old host I had to make a quick move.  It will take some time for things to settle in, but I hope to have all of the resources references cleaned up soon.

January 9, 2012
by Mike Oryszak
0 comments

SharePoint Saturday Virginia Beach–Wrap-up

SharePoint Saturday Virginia Beach was a huge success again and a great way to kick off the new year.  Attendance has really grown, and I believe there were close to 350 people there between the attendees, sponsors, speakers, and volunteers.  Great job as always by the volunteers making this one of the best run events I have ever been apart of!

Thank you to the people that attended my sessions.  Below are the covered materials.

Developing Reusable Workflow Solutions – SlidesSPBlueprints.Activities Code

How Many Sites Do I Need?!?! – Slides

 

Hope to see all of you again at another event.  Next on the schedule for me is the Atlanta SharePoint User Group on Monday 1/16 where I will be presenting the Reusable Workflow session again followed by SharePoint Saturday Philly on Feb 4th where I will be doing a session on planning for SharePoint Search!

January 1, 2012
by Mike Oryszak
0 comments

A Look Ahead

The past year was an interesting one filled with highs and lows for me both personally and professionally.  Looking forward to 2012 I am very optimistic that it will be a great year for many.

This morning I received the email that I was renewed as a SharePoint MVP for another year; upping the total count to 3 years.    I am very grateful for the support of the community and hope to continue to maintain the high levels of contributions.  With the high number of events though, it is unlikely that I will be able to do nearly as many as I would like to.  My first quarter schedule already includes:

I will also be attending the Microsoft MVP Global Summit in Bellevue, WA February 25th to March 2nd.

In other news, the SharePoint 2010 Business Application Blueprints is coming along with the first draft nearing competition.  I am not exactly sure what the publish date will be, but I hope it is no later than May or June.  As it gets closer I’ll be sure to post information on availability.

I would like to wish everyone a Happy New Year, may it bring health and prosperity to all of you!

October 22, 2011
by Mike Oryszak
0 comments

SharePoint Saturday Richmond

SharePoint Saturday Richmond is scheduled for Saturday November 5th.  It is a free event with great content for End Users, Power Users, Developers, Architects, and IT Pros.  With a great lineup of speakers there is sure to be great content giving attendees a chance to expand their SharePoint knowledge and also to network with other IT professionals.

Registration is now open and can be found here:  http://spsric.eventbrite.com/?ref=ecount

I’ll be presenting a developer session titled Developing Reusable Workflow Features.

This session will cover a series of techniques on how to increase overall reuse within your SharePoint Workflow projects as well as provide an overview of how to create custom Workflow Activities in Visual Studio 2010 that can be leveraged in your SharePoint Workflows to connect to system services like the User Profiles and Business Connectivity Services.

I hope anyone in the area can make it out.

September 7, 2011
by Mike Oryszak
0 comments

Presenting Charlotte SPUG–Developing Reusable Workflow Features

I am scheduled to present at the September meeting for the Charlotte SharePoint User Group and will be presenting my session on planning and developing for reuse within workflows.  A full session abstract is below.

Session Abstract

A key component to developing and maintaining a suite of workflow processes is consistency and reusable features.  This session will provide an overview of how to approach reusable workflows and custom Workflow Activity features that can be used to develop a portfolio of workflow processes.  We will walk through some specific examples that you can leverage in your own SharePoint workflow projects.

Meeting Details

Date/Time:  Wednesday September 21st 2:30-5:30pm

Location:  National Gypsum,  2001 Rexford Road, Charlotte, NC 28211

URL:  http://www.casug.org/SitePages/Home.aspx

 

I’m looking forward to the meeting and hope for a full house!

September 3, 2011
by Mike Oryszak
2 Comments

User Profiles – Adding a Custom Tab and Page

The User Profile Pages within the MySites area of SharePoint 2010 is significantly more robust than in previous versions.  I really like the concept of making it a central/social hub and using it as a central place to hold and maintain content.  While I generally shy away from major customizations to the Personal sites (aka My Content), the My Site Host that stores the User Profile Pages and Activity Stream provides a great place to load centralized content and features.  It could be for integrating into other social applications your organization might use, or perhaps a place to hold executive Dashboards.  Since the My Site Host is shared between all users within that profile store it is easier to maintain than the individual Personal sites.

I have found myself in a number of conversations recently with people asking about how to customize and extend the User Profile Pages but I have not seen any good sources of information on how to approach it.  Today we will look at how you can define a custom ApplicationPage that uses the User Profile format and how to link to it from within the tabs present in the User Profiles section.

Managing User Profile Tabs

For those that are not aware, the horizontal tabbed navigation displayed in the User Profiles section is actually powered by the QuickLaunch menu for the MySite Host site.  You can add a new tab simply by adding a new Heading entry for the QuickLaunch. 

Here is a screenshot of the tabbed QuickLaunch on the User Profile page.

Here is what the QuickLaunch configuration looks like:

 

Custom User Profile ApplicationPage

The sample code included in this project includes the standard formatting for the page so that it blends in perfectly with the other pages within the section.  Your custom page has access to the full Server OM and can include complex user controls or visualizations.

[sourcecode type="plain"]
<%@ Page language="C#" DynamicMasterPageFile="~masterurl/custom.master" Inherits="Microsoft.SharePoint.Portal.WebControls.PersonalAdminPage,Microsoft.SharePoint.Portal,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="OSRVUPWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server.UserProfiles, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SEARCHWC" Namespace="Microsoft.Office.Server.Search.WebControls" Assembly="Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderLeftNavBarDataSource" runat="server">
<SPSWC:DataSourceReplacer runat="server" ControlID="PlaceHolderLeftNavBar/QuickLaunchNavigationManager/QuickLaunchMenu">
<SPSWC:MySiteDataSource runat="server" ShowStartingNode="False" SiteMapProvider="MySiteLeftNavProvider" />
</SPSWC:DataSourceReplacer>
</asp:Content>

<asp:Content ID="Content2" contentplaceholderid="PlaceHolderPageTitle" runat="server">
Custom Page Title
</asp:Content>

<asp:Content ID="Content3" contentplaceholderid="PlaceHolderPageTitleInTitleArea" runat="server">
Custom Page Title
</asp:Content>

<asp:Content ID="Content4" contentplaceholderid="PlaceHolderSiteName" runat="server">
<SPSWC:PersonalSpaceMainHeading TitleMode="true" runat="server" />
</asp:Content>

<asp:Content ID="Content5" contentplaceholderid="PlaceHolderMain" runat="server">
<Sharepoint:FormDigest runat="server" id="FormDigest" />

<div class="s4-notdlg noindex">
<a id="A1" href="javascript:;" onclick="javascript:this.href=’#SkipContactCard’;" class="ms-SkiptoMainContent" runat="server">
<SPSWC:StringValueEx ResourceFile="spscore" LocId="SkipContactCard_Text" runat="server" />
</a>
</div>
<SPSWC:ProfilePropertyLoader id="m_objLoader" LoadFullProfileOfCurrentUser="true" runat="server" />
<div class="ms-profilepageheader">
<table border="0" cellpadding="3" cellspacing="0" ID="ZoneTable" width="100%" class="ms-tztable">
<!– business card zone –>
<tr><td colspan=3 width="100%" style="padding:24px">
<table class="ms-contactcardtext3" cellspacing=0 cellpadding=0 width="100%">
<tr>
<td width="150" valign="top">
<div class="ms-contactcardtext3" style=""width:100%;">
<SPSWC:LocalTimeControl runat="server" />
</div>
<div class="ms-profilepicture ms-contactcardpicture ms-largethumbnailimage">
<SPSWC:ProfilePropertyImage PropertyName="PictureUrl" RenderWrapTable="False" ShowPlaceholder="true" id="PictureUrlImage" ImageSize="Large" CenterVertically="true" runat="server"/>
</div>
<div class="ms-contactcardtext3" style="width:100%;">
<div><SPSWC:EditProfileButton runat="server" id="ddlEditProfile" /></div>
<div><SPSWC:AddToColleaguesButton runat="server" id="TBBAddtoColleagues" class="ms-my-addcolleague"/></div>
</div>
</td>
<td valign="top" width="320">
<div style="min-height:175px">
<div class="ms-contactcardtext2 ms-identitypiecenotediv">
<SPSWC:StatusNotesControl runat="server"/>
</div>
<div style="padding-top: 50px;vertical-align:top;" class="ms-name ms-contactcardtext1" id="ProfileViewer_Name">
<SPSWC:PersonalSpaceMainHeading TitleMode="false" runat="server"/>
</div>
<div style="padding-left: 20px;" class="ms-contactcardtext3" id="ProfileViewer_ValueTitle">
<SPSWC:ProfilePropertyValue PropertyName="Title" runat="server"/>
</div>
<div style="padding-left: 20px;" class="ms-contactcardtext3" id="ProfileViewer_ValueDept">
<SPSWC:ProfilePropertyValue PropertyName="Department" runat="server"/>
</div>
<br/>
<div style="padding-left: 20px;" class="ms-contactcardtext3" id="ProfileViewer_ValueOfficePhone">
<SPSWC:ProfilePropertyValue PropertyName="WorkPhone" dir="ltr" runat="server"/>
</div>
<div style="padding-left: 20px;" class="ms-contactcardtext3" id="ProfileViewer_ValueOfficeLocation">
<SPSWC:ProfilePropertyValue PropertyName="Office" runat="server"/>
<SPSWC:ProfilePropertyCheckValue PropertyNames="Office,Location" runat="server" Text=", "/>
<SPSWC:ProfilePropertyValue PropertyName="SPS-Location" runat="server"/>
</div>
<div style="padding-left: 20px;" class="ms-contactcardtext3" id="ProfileViewer_ValueEmail">
<SPSWC:ProfilePropertyValue PropertyName="WorkEmail" runat="server" PrefixBrIfNotEmpty="true"/>
</div>
<br/>
<div style="padding-left: 20px;display:none;" class="ms-contactcardtext3" id="ProfileViewer_ProfileDetails" >
<SPSWC:ProfileDetailsViewer id="ProfileViewer" Collapsible="false" runat="server" />
</div>
</div>
<div style="padding-left: 20px;" class="ms-contactcardtext3">
<SPSWC:ContactCardDetailsLink AboutMeId="ProfileViewer_ValueAboutMe" ProfileDetailsId="ProfileViewer_ProfileDetails" EllipsisId="ProfileViewer_Ellipsis" runat="server" />
</div>
</td>
<td valign="top" width="418">
<div style="padding: 50px 5px 0px 15px; overflow:hidden; min-height: 142px; height: 142px;" class="ms-contactcardtext3" id="ProfileViewer_ValueAboutMe">
<SPSWC:ProfilePropertyValue PropertyName="AboutMe" runat="server" PrefixBrIfNotEmpty="false"/>
</div>
<div style="padding-left: 15px;display:none" id="ProfileViewer_Ellipsis" class="ms-contactcardtext3"></div>
</td>
</tr>
</table>
</td></tr>
</table>

<SharePoint:AspMenu
ID="MySiteSubNavigationMenu"
Runat="server"
EnableViewState="false"
DataSourceID="MySiteSubNavDS"
AccessKey="<%$Resources:wss,navigation_accesskey%>"
UseSimpleRendering="true"
UseSeparateCss="false"
Orientation="Horizontal"
StaticDisplayLevels="1"
MaximumDynamicDisplayLevels="0"
PopOutImageUrl=""
SkipLinkText=""
CssClass="s4-sn">
</SharePoint:AspMenu>
<SPSWC:MySiteDataSource
ShowStartingNode="False"
SiteMapProvider="MySiteSubNavProvider"
id="MySiteSubNavDS"
runat="server"/>

</div>

<a name="SkipContactCard" tabindex=0></a>

<div class="ms-profilepagecontent">
Your Page Content Here!
</div>
</asp:Content>
[/sourcecode]

Managing the QuickLaunch Entries

For this to be a robust feature the QuickLaunch entries should be managed as part of the feature activation/deactivation process so a FeatureReceiver has been added to the project to add and remove the entries respectively.

[sourcecode type="plain"]
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Navigation;
using Microsoft.SharePoint.Security;

namespace CustomMySitePage.Features.Customer_User_Profile_Page
{
[Guid("d2754488-4038-42fd-9c9e-f93f19d4e093")]
public class Customer_User_Profile_PageEventReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
SPNavigationNode node = new SPNavigationNode("Custom Page", web.Url + "/_layouts/CustomMySitePage/PageTemplate.aspx");
web.Navigation.QuickLaunch.AddAsLast(node);
}
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
SPNavigationNodeCollection nodeCol = web.Navigation.QuickLaunch;
foreach (SPNavigationNode node in nodeCol)
{
if (node.Title == "Custom Page")
{
node.Delete();
}
}
}
}
}
}
[/sourcecode]

Deployed Custom Tab and Page

Here is a final look at what it looks like with the feature activated and the Tab and Page available.

 

 

Template Project Source Code

The source code for this project is available for download here:  CustomMySitePage Project 

I will not be providing support for the code as it is merely an example of how the pages within the User Profile section of MySites works.