Apply Workflows to folders

In my last blog-post I described how to enable meta-data for folders. Even though you can configure workflows for your custom content-type (of type “folder”), there seems to be no way to actually start those workflows. There is no context-menu entry to start such workflows as for any other content-type.

But there is a way! If you happen to know the right URL to start workflows … just call /_layouts/Workflow.aspx?ID=[ItemID of the folder]&List=[GUID of the list]. Just insert the appropriate values and off you go.

Folders with Meta-Data in SharePoint

When working with document libraries you can use folders to structure your documents within the library. This is ok, but a better approach to structure documents would be by assigning meta-data to the documents and create the structure based on this meta-data.

But sometimes you actually do need to have folders. For example you have bunch of documents which belong together. You could ZIP them up and thus have just one item in the document library, but this will stop you from being able to edit those documents directly in SharePoint. With SharePoint 2010 you could use document-sets, but what to do when you’re stuck with SharePoint 2007? Well, in this case you have to use folders.

OK, so folders it is. But how can I add meta-data to folders? When adding new columns to a library these will be available for all documents added to the library but not for folders. Here’s a trick to work around this problem:

  1. instead of added columns to the document library, create websitecolumns.
  2. create a new content-type, which derives from “document” to hold the actual documents of the document library. Add the websitecolumn created in step 1 to the content-type.
  3. create a new content, which derives from the type of “folder”. This content-type is being uses to create folders with meta-data in the document library. Add the websitecolmn of step 1 to the content-type.
  4. in the document library activate the use of content-types and deactivate the usage of folders(!), since we want to use our own content-type to create folders.
  5. add the in step 2 & 3 created content-types to the list and alter the order of the content-types in such a way the “document” type is not at position one. The first content-type of the list is always the default content-type and thus cannot be deleted. Once you alter the ordering you can delete the “document” content-type and just have your two custom content-types.

So now you can add folders to the document-library which also have meta-data. Interesting enough is the fact, that you can create a new content-type based on a content-type folder and then add this newly created content-type to the document library, but you cannot add the “raw” folder content-type to the library. However.

Active-Directory Groups in SharePoint

When adding an Active-Directory group to SharePoint, for SharePoint this group is like any other (user) account. SharePoint doesn’t care whether the account added is a group or just a single user. Because of this “ignorance” of SharePoint not the group-members are being added to SharePoint, but the AD-group. This group can then be used just like any other SharePoint user.

But there are a couple of caveats:

  • let’s take a task-list for example. When a task is being assigned to a person in a task list, this person will get an email notification of the task assignment. When a task is being assigned to a SharePoint group (not an AD-group!), then every member of the group gets the email notification. Also when looking at the task-list every group-member will see the task, as long as no group member has assigned the task to himself. Every group member can assign the task to himself, and by this the task will only show up in the users task-list, not anymore in the view of the other group members.
    When a task is being assigned to an AD-group no one receives an email, because SharePoint want’s to send an email to the groups email-address (since SharePoint doesn’t know that an AD-group is a group which consists of members, and hence it believes it’s a single user). And because SharePoint believes the AD-group is a single user the task can not be assigned to a member of the group – and also the task is not shown to the members of the group.
  • When assigning an AD-group individual permissions on a site I usually can send an email to the user notifying them about the new permissions. with AD-groups this doesn’t work as well, since usually AD-groups don’t have an email-address and SharePoint is unable to iterate over all the members of the AD-group. The same is true for setting up notifications for lists and libraries, these cannot be set to an AD-group.

Permission by obfuscation

… or how to hide certain actions in SharePoint?

There are a couple of things, which can not be configured in SharePoint. For example you cannot configure, that users are not able to edit a list in datasheet view or in Excel or Access. Bummer!

But with a couple of lines of JavaScript this isn’t really a challenge.

<script language="javascript" type="text/javascript" src="/Scripts/jquery-1.4.2.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
  $("[id$='_EditInGridButton']").remove();
  $("[id$='_ExportToSpreadsheet']").remove();
  $("[id$='_ExportToDatabase']").remove();
});
</script>

Just place this code in a Content-Editor-WebPart on the page and off you go!

The ultimate list of GUIDs

I’m not really sure, what is disturbing me more – the fact that I am actually searching for a GUID on Google, or the fact that there exists a list of GUIDs.

OK, so I have sharepoint manifest file, which is part of a site-template. This template has a whole lot of features, which have been added by sharepoint to the manifest and actually not needed at all. But all those features are only being described by their GUIDs – so who is who?

Lucky for me Robert Bogue has a blog-post, where he features a list of MOSS 2007 GUIDs. This was perfect to identify the features und to remove all the unwanted features from the manifest.

Naming of columns in SharePoint lists

You have to watch out, when choosing your column-names in SharePoint lists. A column can have any name and can easily been changed.

Good to know is the fact, that a column has actually two names. An internal name and a display name. When a new column is being created the choosen name is being used for both names, the internal as well as the display name. If you change the column name later on, you actually only change the display name, not the internal name.

So far, so good. If you create a new column called “Employee Name” then the internal name will be actually “Employee_x0020_Name”. This doesn’t look good and doesn’t feeld good when working with CAML queries or XSLT in SharePoint Designer.

A better approach would be to chose “EmployeeName” as the column name and then change the display name to “Employee Name” later on. This way you will get a nice and clean internal column name.

Half-day events in SharePoint

The Story

If you’ve been working with SharePoint you might have been working with calendar lists already. This is an easy to use way to add events to a web-based calendar. Like Outlook this features a checkbox to mark an event as a full-day event and thus omitting the start and end time (actually that’s not correct, behind the scenes the event starts ad 00:00 and ends at 23:59).

Recently someone asked on how to add a functionality like the full-day feature, but for half-day events. So you could just select wether an event should take place in the morning or in the afternoon.

That sound fairly simple to do.

How it’s done

OK, so I start by creating a new calendar from scratch. Next move to add an new item – and this is where we want to make our modifications to the form to allow selecting half-day events.

Because this view can not be edited directly in the browser you have to tweak SharePoint a little bit by altering the URL by adding toolpaneview=2 to the querystring.

Next you drag a content-editor-webpart below the editform and switch to the HTML source view.

I usually keep a copy of jQuery around, so I just add

<script language="javascript" src="/_layouts/jQuery/jquery-1.4.2.min.js" type="text/javascript"></script>

in the source-view. You might have to adjust the URL pointing to jQuery at this point. If you have no access to the file-system on your SharePoint server you could also just create a document library and place the jQuery library there and put the path in the above reference.

Next we add two buttons (this might not be the most pretty solution, but this is mostly about showing how this could be done!).

<input type=button value="morning" id="btnMorning">
<input type=button value="afternooen" id="btnAfternoon">

So the final step would be to hook to the click-events of the two buttons. Whenever one of the buttons are pressed, we just change the hour-selection for the start end end time of the event.

So the complete source looks like this:

<script language="javascript" src="/_layouts/jQuery/jquery-1.4.2.min.js" type="text/javascript"></script>
<input type=button value="morning" id="btnMorning">
<input type=button value="afternoon" id="btnAfternoon">
<script language="javascript">
  var startTime = $("#" + g_strDateTimeControlIDs["SPEventDate"] + "Hours");
  var endTime = $("#" + g_strDateTimeControlIDs["SPEndDate"] + "Hours");
$("#btnMorning").click(function() {
  startTime.val("08:");
  endTime.val("12:");
});
$("#btnAfternoon").click(function() {
  startTime.val("12:");
  endTime.val("18:");
});
</script>

Neat, if I may say so myself!

Adding Attachments to SharePoint blogs

While SharePoint 2007 does offer a blog-template, this is actually quite minimalistic. Even though you can usually add attachments to every list item in sharepoint, this is not possible for blog posts.

Well, actually, attachments are enabled for blog posts, and if you’re using an editor such as Windows Live Writer all images and files are being added as attachments to the current post. But this just isn’t possible if you’re stuck with the web-editor for writing new posts.

So I did some digging on what’s needed to get SharePoint to offer attachments for blog posts.

First of all you should be aware, that you’re going to modify some files dear and near to SharePoint – this might not always be the recommended way 🙂

OK, let’s get started. Since we already noticed that attachments are enabled on the list of posts, we somehow need to get this darn button in the toolbar to appear.

Since the blogging feature is built-in into SharePoint it’s view definition is found in the DefaultTemplates.ascx within the %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\12\Template\ControlTemplates. Within this file are a whole lot of Rendering-Templates defined. Based on the existing BlogForm Template I created my own Template called BlogFormExt.

<SharePoint:RenderingTemplate ID="BlogFormExt" runat="server">
    <Template>
        <SPAN id='part1'>
            <SharePoint:InformationBar runat="server"/>
            <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator="&nbsp;" runat="server">
                    <Template_RightButtons>
                        <SharePoint:SaveAsDraftButton Text="<%$Resources:wss,tb_saveasdraft%>" runat="server"/>
                        <SharePoint:PublishButton Text="<%$Resources:wss,tb_publish%>" runat="server"/>
                        <SharePoint:GoBackButton runat="server"/>
                    </Template_RightButtons>
            </wssuc:ToolBar>
            <SharePoint:FormToolBar runat="server"/>
            <p><a href="javascript:UploadAttachment();">Attach Me!</a></p>
            <TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 width=100%>
            <SharePoint:ChangeContentType runat="server"/>
            <SharePoint:FolderFormFields runat="server"/>
            <SharePoint:ListFieldIterator runat="server"/>
            <SharePoint:ApprovalStatus runat="server"/>
            <SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>
            </TABLE>
            <table cellpadding=0 cellspacing=0 width=100% style="margin-top: 10px;"><tr><td class="ms-formline"><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></td></tr></table>
            <TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px"><tr><td width=100%>
            <SharePoint:ItemHiddenVersion runat="server"/>
            <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator="&nbsp;" runat="server">
                    <Template_Buttons>
                        <SharePoint:InitContentType runat="server"/>
                        <SharePoint:CreatedModifiedInfo runat="server"/>
                    </Template_Buttons>
                    <Template_RightButtons>
                        <SharePoint:SaveAsDraftButton Text="<%$Resources:wss,tb_saveasdraft%>" runat="server"/>
                        <SharePoint:PublishButton Text="<%$Resources:wss,tb_publish%>" runat="server"/>
                        <SharePoint:GoBackButton runat="server"/>
                    </Template_RightButtons>
            </wssuc:ToolBar>
            </td></tr></TABLE>
        </SPAN>
        <SharePoint:AttachmentUpload runat="server"/>
    </Template>
</SharePoint:RenderingTemplate>

Important are the two highligthed lines. The first line adds a link to display a dialog to upload an attachment, the orher line adds the actual code for the dialog and stuff.

OK, so now we habe our new layout in place, that allows us to add attachments to new posts. Next we need to alter our blog to make use of this new template definition.

So using SharePoint-Designer open up the blog and navigate got the posts list. Open up the NewPost.aspx and find the webpart-element in the code view. There should be a line like

<TemplateName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">BlogForm</TemplateName>

which you wand to edit to

<TemplateName xmlns="http://schemas.microsoft.com/WebPart/v2/ListForm">BlogFormExt</TemplateName>

This will use our new template-definition instead of the build-in template view.

This is basically all you need to do – well you also might want to edit the EditPost.aspx to use a template which enables the upload of new attachments; but I leave that to you.

Oh – one final note: this enables uploading attachments to a blog-post, but the attachments are not automatically displayed for e.g. as a list of items in the end of the post. You will have to add the links to the attachments in your post manually!.

Strange behaviors in SharePoint deployment

Today I had some really strange experiences while deploying some SharePoint application using a custom build WSP file.

First, I tried to re-deploy an existing solution, but that didn’t seem to succed. At least my SharePoint site replied with a “Service unavailable” notice. So I though, I should retract the solution – maybe someting in my updated solution broke my SharePoint site.

So doing a

stsadm –o retractsolution –name myapp.wsp –allcontenturls –immediate

also just failed on me. So next I was stuck. I couldn’t neither delete the solution nor retry to retract the solution because everytime I got the message, that another job is currently retracting this solution. This is why I couldn’t do anything at the moment. But what now? It didn’t seem like the was any other job running.

So I gathered a list of all running deployments using

stsadm –o enumdeployments

and then

stsadm –o canceldeployment –id

to actually cancel the running deployment. After that I could issue

stsadm –o deletesolution –name myapp.wsp –force

This actually remove the solution – but I had to find, that this wasn’t the cause for my “service unavailable”. So all this for nothing!

The strange thing about that is, that only one out of a dozen websites was not working. Then it strike me – looking at the IIS admin I found, that the app-pool associated with this SharePoint site was stopped – restarting the app-pool solved my “service unavailable” immediately.

Chuck Norris and SharePoint 2010

Top ten facts about Chuck Norris and SharePoint 2010:

  1. Chuck Norris never starts an Approval workflow in SharePoint. Chuck doesn’t need approval.
  2. Chuck Norris isn’t afraid to customize, one look and SharePoint runs at peak performance.
  3. Putting Chuck Norris in the SharePoint Visitors group is futile. Chuck always has Full Control.
  4. Chuck Norris doesn’t have a SharePoint Disaster Recovery Plan. He doesn’t recover data, only hostages.
  5. Chuck does not subscribe to Alerts. He knows what is happening before it happens.
  6. Chuck Norris IS the Governance Plan.
  7. In SharePoint 2010, the Farm Administrators group is being renamed to ‘Chuck’s Group’.
  8. Chuck Norris never get’s unexpected errors with SharePoint because he is always ready for everything.
  9. Chuck Norris doesn’t prepare for SharePoint 2010. SharePoint 2010 prepares for him.
  10. SharePoint 2010 was a Chuck Norris idea.

chucknorris