MOSS MVP

I've moved my blog to http://blog.falchionconsulting.com!. Please update your links. This blog is no longer in use--you can find all posts and comments at my new blog; I will no longer be posting to this site and comments have been disabled.

Tuesday, November 27, 2007

Customizing MySites

This posting doesn't actually have anything to do with stsadm (unless you count the fact that you need stsadm to install Features) but I figured I'd post this here regardless as I've seen a lot of questions out there regarding how to do this. My specific requirement was to remove the "Create Blog" button on the My Sites home page. There are two ways to accomplish this - one that's supported and one that's not. The easiest approach (and the unsupported approach) is to modify the default.aspx file located at "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\SPSPERS". In this file simply remove or comment out the CreateBlogButton web control (ID="TBBCreateBlogButton"). Note that I don't recommend doing this as modifying these files will violate your support with Microsoft but I figure it's at least worth mentioning that it's possible.

The other approach is to use a Feature. There's a great article by Steve Peschka on customizing My Sites which explains how to do all of this. There's also a template project which you can find on CodePlex. I used this project as a starting place and tweaked it to meet my needs. There's three approaches you can take to remove the create blog button (I won't bother to address the other customizations you can do as they are documented on the above sites and in the readme files provided with the download).

The first is to modify the master page and make the PlaceHolderMiniConsole control no longer visible. The problem with this approach is that it also hides any other buttons that may be loaded into this control. The second approach is to put some code into the master page in a server script tag - that code would then do a series of FindControl calls to get the TBBCreateBlogButton control and then hide it. The problem with this is that it requires you to make some web.config changes to allow code blocks - something I'd strongly recommend against doing unless you had no other choice. The third option (which is the one I took) is to have the MySiteCreatePart control look for and remove the button (again, using FindControl). The one downside of this is that the code to hide the button has to run every time the page is loaded.

There may be other ways to do this but I was not able to identify one. Just a quick overview of what Steve's code is doing - there are three components: the first is the MySiteStaplee which contains the custom master page and the MySiteStaplee.xml file which has all the settings that the MySiteCreatePart code utilizies. The custom master page is exactly like the default master page with the addition of two lines - one registers the MySiteCreatePart web control and the other adds the web control to the page in the Head section (you can modify this further to your heart's content). The second part is the MySiteStapler which simply associates the MySiteStaplee feature with the SPSPERS#0 site template (so when a site is created with this site template the MySiteStaplee feature will be activated). The third piece is the web control (MySiteCreatePart) which gets loaded up by the master page.

This approach of using a web control allows the code to manipulate the running page without having to embed server side script blocks which would open up security issues (note that this is a simple object inheriting from WebControl - it is not a WebPart object - it really is about as basic as you can get so it's real easy to work with). And finally, there's a web.config change that is necessary to mark the web control as a safe control. In order to do what I needed I had to modify the code that Steve provided.

The first thing I did was to clean it up a bit - I broke the main method into a couple of smaller methods to help in readability and I modified the code so that it properly disposed of the objects such as the SPLimitedWebPartManager object and the various WebPart objects (minor issue but this should help with memory management). The next thing I added was a new attribute to the MySiteStaplee.xml file. I wanted to make it so that I could control whether the button appeared or not via the XML file so I added a "removeBlogButton" attribute to the document element. This way the value can be changed in the future so that any new MySites created would reflect the change (to address existing MySites one would simply need to loop through all the sites and set a custom property to true or false (assuming of course that the feature has been installed)). With this attribute in place I was then able to set a property on the SPWeb object which I then check whenever the page is loaded. The final code changes I made was to support an additional action and handle deactivation of the feature - Steve's version only allowed Delete, Move, Add, and SetProperties, but I needed to be able to do a Close as well so I added that logic in. I also wanted it so that if the MySiteStaplee feature was deactivated that the original master page would be reassociated so I added that code in. The other changes I made to the MySiteStaplee.xml file were to simply move a couple of web parts around.

Download the original version for additional examples (I also included the original version within my download). Feel free to download my version of the MySiteCreate Feature and let me know if you have any issues.

Update 1/15/2008: I've fixed the batch files and updated the FeatureActivating event so that it won't activate the feature at the root site and in case it does it will only switch the master page if the template is SPSPERS.

30 comments:

bsieloff said...

Hi Gary,

I have looked through Steve's blog as well. I'm trying to do something simple.. or at least I think so. I just want to give the MySite the same look and feel as the blueband.master. (ie, large blue top nav bar). I don't need to change webparts /create blogs /etc. The thing with MySiteCreate_1.0 is that I'm now not sure where to find mysitestaplee.xml, mystiestaple.xml and feature.xml. I guess I should do a cut and paste from his original blog to create those files. Is what I want to do feasable? Also, Steve talks about his master, steve.master., may I just use blueband.master and have everything fall in place? Thanks for your help, -B

Gary Lapointe said...

I confirmed that the xml files are all in my download. You won't need the webpartcreate stuff if you don't need to change anything other than the master page. You can simply use the blueband.master file in place of steve.master (if you're downloading the original) or custom.master if you're downloading mine. Then just follow the instructions for installing the two features and you're done (you won't need to the stuff to register the safe control if you don't use the webpartcreate stuff).

Anonymous said...

Dear Gary,

Thank you very much for your post.

I am really really stuck and I am sure you can help very quickly - I am doing something goofy.

Like you, I needed a modified version of the mysitecreatepart. I added some lines of code which determine whether the user is staff or student (we are a school) and activates certain features on the mysite accordingly.

It seems to work, but only if I am creating a mysite when I am logged on as someone who is a local admin on the web server!

My process was this:

-Add my line of additional code (which as a test simply writes a line to the log) to Partcheck.cs's "protected override void OnLoad(EventArgs e)"
-build the assembly
-remove and reinstate the mysitecreatepart.dll to the GAC
-iisreset
-retry creating a mysite

When I'm logged on as a user who's a member of the machine's local admins group, I see my added line in the machine's application event log each time I visit the mysite
When I'm not, I don't see the line I added.

Any ideas? I am kind of stumped. I've even tried incrementing the version number and doing a full restart of the server.

Many thanks,
Fergus

Gary Lapointe said...

Fergus - it sounds like your users just don't have access to the log file. Remember that this code will run as the authenticated user and not the app pool account so those users will need rights to the log file or you'll need to wrap the logging code in a RunWithElevatedPrivileges block.

Adam Toth said...

Hi Gary,

Your project template was awesome, and all those extras like the batch files saved my bacon when I was under a huge time crunch to get this done for a client.

I ran into an issue with this, specifically with the setting of the master page in the FeatureActivated event. It seems that this doesn't just set the master page for that user's MySite, it also sets the master page for the MySite Host site one level up.

The drawback to this is that when you view the Profile page (person.aspx, which is on the MySite Host site, NOT the user's MySite), the custom master is used and the MySiteCreatePart runs through its code. The part tries to check the site's properties to see if the code has run before, but since this is on the MySite host, it hasn't, so the code runs.

Is there a way to only set the master page on the newly created MySite, and not on the MySite host or other site collections?

For my particular client, it is really problematic, since they are hosting their MySites as a separate site collection under their main portal (http://portal/mysites/personal/...), and so this feature is actually resetting the System Master page at the top level portal site collection as well.

Thanks,
Adam

Kaveh said...

Hi, Gary,

First of all, big thanks to you for putting this article up and also for putting your files up. I especially liked that you compiled your dlls as releases. Nice touch ;)

The good news is that I can deploy either your features or the original ones with no problems. Unfortunately, the moment I change the master page (specifically setting the miniconsole's visible property to false), I get a "File Not Found" error after I deploy and try to create a My Site. I can't figure it out and I am at my wit's end! I think a couple of other people have had this issue, and I'm wondering if you can shed any insight.

Thankee,
Kav

Gary Lapointe said...

Adam - sorry for not responding earlier (I've been on vacation for a couple of weeks and we're about to do our upgrade next week and I'm getting ready to start a new job right after that so I've been a bit preoccupied). I can't imagine why it's updating the root host site's master page - it's almost as if your individual my sites are being created as sub-sites and not site collections (not sure how that would happen though). It probably wouldn't take much effort to put some code in to check if the current web is the root web of the web application in which case don't swap the master pages. Beyond that I'm not sure what else to tell you without being able to see the environment.

Gary Lapointe said...

Kav - The file not found error suggest that the master page didn't get loaded into the gallery. Though the main page may fail you may still be able to see the master page gallery by keying the url in directly. Beyond that you could add some debugging code into the Feature to tell you if it is getting loaded. I've not had any issues with the original or mine so I'm not sure why you are getting this error (maybe a permissions problem with the file path where the master page is stored?). If I can be of any additional help please let me know.

Kaveh said...

Hey, Gary,

Thanks for the super quick response. I know that the master page is getting loaded because I can see it in the gallery in designer.

I'm not sure if I was clear, but I can get the feature to work when I leave the master pages untouched. It's just when I modify it slightly (turning miniconsole's visiblity to false, for example)everything barfs.

I'm going to get to the bottom of it and I will keep you posted.

Thanks,
kav

Gary Lapointe said...

Adam - I've figured the issue with the master page getting set at the root - I added some code to the FeatureActivated event to prevent the switching of the master page url when the web template is not a SPSPERS template. But the real fix was to simply not activate the feature at the host - stupid really - can't believe I missed that (not sure why the batch files from the code plex download were activating the feature at the root like that - unless I just missed something - been a long week so I probably just had a brain fart). The code change will end up just being a nice safety net in case someone does activate at the root again.

Adam Toth said...

You rock Gary!

Thanks, that makes sense. I guess all the batch file needed to do was install the feature, but not activate it. Activation should happen when a new MySite is created.

Sweet!

Jaydev said...

Hi Gary,

Nice article, just wanted to know couple of thing if you can help me to sort it out. I am actually trying to customize mysite where i dont need to change any look and feel design instead I need to put couple of my own webparts instead of builtin webpart comes in mysite. Above this, I also want to setup the calender and Outlook Inbox automatically whenever any user go to his/her mysite.

Any guess!!!!!

Cheers,
Jay

Gary Lapointe said...

Jay - you can do all of this using the feature described in this post. My sample sets the calendar web parts so you can see how that's done. For the most part you could rework a lot of this so that it doesn't change the master page out and simply uses the feature receiver to set the page up however you want when the feature is activated.

Samer said...

Hello Gary,

Your article is perfect and just the thing I need. I tried to click the link that is supposed to lead to www.thelapointes.com/blog/mycreate.zip but instead end up on:
http://stsadm.blogspot.com/

How can I get to your modification of Steve's code?

Thanks,

Samer

Gary Lapointe said...

Thanks for point out the dead link to me - some how the file got deleted - I've restored it so you should be able to download now. Sorry 'bout that.

Kannan said...

Hi,

I have a requirement to write a webpart for person.aspx. How can we know which user's profile is being viewed?

For example, when i view your profile how can my webpart know that the current page shows your information.

Your help would be much appreciated.

Thanks,
Kannan. A

Samer said...

Gary,

Following up from my note of 3/25, I installed everything (had to adjust the instructions slightly but I understood what you meant) and got it running. Now I have a few questions:

1) As the admin, I don't see the pared down list of Webparts. Is it because I am an admin? Getting the local LAN folks to get me a second account here is harder than it seems, otherwise I'd do this with a 'regular user' account and see.

2) My objective is to 'lock down' the Webparts to have specific, pre-populated Page Viewer, RSS Feed and one Content editor Webpart. I presume that's in the MySiteStaplee.xml file. Again, I ask because for me, as the admin, the 'Create Blog' button is still on on MySite even though I deleted it and created it with my new template (BTW, that part worked perfectly) and in the XML above, the removeBlogButton tag is set to true.

Any insight you can impart would be helpfull.

Thanks,

Samer Najia

Gary Lapointe said...

Samer - I'm honestly not sure why it's not working for you. It shouldn't matter that you are an admin - it should work the same way regardless of your access level. It sounds like the code just isn't getting executed - you could try attaching a debugger to it to see if the code is running.

Samer said...

Gary,

I'm stumped too. I went back to server admin to see if I forgot anything, after all, the new template comes up great and fine. Not sure now whether the XML is being read at all for MyStaplee. I may have to do this in code, which I'm hoping not to have to do.

Drew said...

Gary
This is so cool, thanks for taking the time and sharing your work. It worked perfectly and is much appreciated.

Drew

Matthias said...

Is there a way to get the email-adress from the current logged in user, so that i could use it as mailbox in owa webparts?

Gary Lapointe said...

Yes - you can get it via the profile properties (so using the sharepoint API) or you can get it from active directory (see System.DirectoryServices namespace).

paulshaver said...

Gary,

Thanks for taking the time to post this solution. I am reaping the havok of the person.aspx takeover due since i didn't see this article before deploying. If I uninstall this old feature and reinstall the new feature, will that take care of my issue?

paul

Gary Lapointe said...

Try deactivating from the root. If that doesn't resolve the issue then you may need to manually switch the master page back (I honestly can't remember if there was code in there to reset the masterpage on deactivation).

Anonymous said...

Really great feature. Worked exactly as described, and did exactly what we needed.

Anonymous said...

Hi Gary,

Thanks very much! I almost got it to work. But where's the code that handles the removeblogbutton setting?

Gary Lapointe said...

The code is in the PartCheck.cs file and the attribute is in the root element of the MySiteStaplee.xml file (removeBlogButton).

Siva Pittu said...

THanks for such a great post. I have the feature stapeling working great with an exception.

http://www.mysite.com/personal/derekc/default.aspx is not showing the custom master page.
http://www.mysite.com/sites/mysites/Person.aspx?accountname=domain\myname is showing the custom master page.

Please help us regarding this.....

We are struck with the above and need to deploy the MySite for enterprise.


thanks,

siva Pittu

Jen said...

When I deploy this code, the blog button goes away (as expected). However, I also wanted to remove the Create and Site Settings options under Site Actions as well as the "View all site content" button on the MySite.

I made changes to the master page (called steve.master here) to remove those additional items, but these changes are not being applied to the MySite, only to the MyProfile page. Any idea why the blog button removal works on the MySite but removing other items only changes the MyProfile page?

Gary Lapointe said...

Each my site is just another site collection so as long as the feature is getting activated and the master page applied then it should be working.