I thought this was a often used functionality of WSS, but when I started googling I guess I was wrong.

I needed to add some custom action to the list items in my document list. Sharepoint made this very easy to do. This article describes it pretty good: http://msdn.microsoft.com/en-us/library/ms473643.aspx.

I followed the example, only using this custom action: UserInterfaceCustomActions.ECBItemToolbar. This is the one that is shown in the action toolbar of an item. Here is the result:

Copy to public.

As I was following this example I noticed that when I tried to install the feature there was an error in the XML:

Feature definition with Id 2aeaccad-cf77-4d38-86a2-4fca58bbc0cc failed validation, file 'UICustomActions.xml', line 8, character 5:
The 'Type' attribute is not declared.

This is how it looked like at the Microsoft site:

<!-- Per Item Dropdown (ECB)-->  
<CustomAction     
 Id="UserInterfaceCustomActions.ECBItemToolbar"    
 RegistrationType="List"    
 RegistrationId="101"    
 Type="ECBItem"     
 Location="EditControlBlock"    
 Sequence="106"    
 Title="Copy to public">    
 <UrlAction Url="/_layouts/CustomActions.aspx?ECBItem"/>  
</CustomAction>


This is how it should look like:

<!-- Per Item Dropdown (ECB)-->  
<CustomAction     
 Id="UserInterfaceCustomActions.ECBItemToolbar"   
 RegistrationType="List"    
 RegistrationId="101"    
 Location="EditControlBlock"    
 Sequence="106"    
 Title="MY ECB ITEM">    
 <UrlAction Url="/_layouts/CustomActionsHello.aspx?ECBItem"/>  
</CustomAction>


The Type attribute is not allowed. Get rid of the "Type" attribute and it will work, strange that Microsoft has this in their example. When you want to deploy the item to all type of list on the website, remove the RegistrationId attribute. For a custom list type the registrationId = "100".  RegistrationId="101" is for document libraries.

You can find a list of all attributes for the custom action element here: http://msdn.microsoft.com/en-us/library/ms460194.aspx.

After I installed and activated the feature, I needed to restart IIS and it worked. Then I made some changes to the XML and wanted to update the feature. Here is the command to do that:

stsadm -o installfeature -filename UserInterfaceCustomActions\feature.xml -force 

Followed by an iisreset everytime you made changes.

So it's very easy to do this. You can use a webpart page in combination with custom webparts to handle the action. I will keep on developing in this area, you can expect more info later.

When you would like to install different features for different sites, create as many directories in the Features dirrectory as you like. I used UserInterfaceCustomActions as directory like the example, but this is not a mandatory name, when you start developing, choose the names of these directories wisely, so you can distinguish the features. E.g. MyCompanyTaskManagement\Feature.xml and MyCompanyFinance\Features.xml. This way we instantly know what the features are for.

As I was deploying the first features to test sites, I noticed that I only could deploy to the entire site collection. If I tried to deploy to a subsite I got this error: The specified feature applies to the entire site collection, but the specified URL refers to a particular sub site.  To apply this feature to the entire site collection, use the root URL ...  At first I couldn't find the problem, because I was trusting on the example on the Microsoft site. But for the second time I noticed there was an error in their example. In the feature.xml they put "Site" as scope:

<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="6FA98D7A-D802-4f30-8473-0F9B00DD8F7C"
     Title="UI Custom Actions"
    Description="Custom action on list items."
    Version="1.0.0.0"
    Scope="Site"
    xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="CustomActions.xml" />
  </ElementManifests>
</Feature>
 

Then they suggest this for the activation of the feature:

stsadm -o activatefeature -filename UserInterfaceCustomActions\feature.xml -url http://Server/Site/Subsite

Which is not correct, because if they use Site as scope, it is not permitted to activate it to a subsite, but it is required to activate it on site collection level. So the solution to this problem is: Use scope="Web" in the feature.xml. Then it is allowed to activate it for a subsite!

You can find the scopes and more on the feature.xml file here.

When you need security on your feature, its really easy. Just add the Rights to the custom action XML. The list of all the rights you can use can be found here.I used the AddListItems to make sure only users with sufficient rights could view the feature. Here's the example of the XML:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="UserInterfaceCustomActions.ECBItemToolbar"
    RegistrationType="List"
    RegistrationId="100"
    ImageUrl = "/_layouts/images/WRI16.GIF"
    Location="EditControlBlock"
    Sequence="106"
    Title="Add progress">
    <UrlAction Url="serverurl/TM/default.aspx?qID={ItemId}"/>
  </CustomAction>
  <CustomAction
    Id="UserInterfaceCustomActions.ECBItemToolbar"
    RegistrationType="List"
    RegistrationId="100"
    ImageUrl = "/_layouts/images/EML16.GIF"
    Location="EditControlBlock"
    Sequence="106"
    Rights="AddListItems"
    Title="Send alert">
    <UrlAction Url="serverurl/TM/default.aspx?qMailID={ItemId}"/>
  </CustomAction>
</Elements>
 

As I was developing further, I had 2 different lists on the subsite. Now they both had this functionality available. But I needed to provide the listID as parameter, so I would know which list the items comes from. This I managed by adding an extra querystring to the URLAction. Now it looks like this:

    <UrlAction Url="serverurl/TM/default.aspx?qMailID={ItemId}&amp;qlistID={ListId}"/>

Be sure to check the casing in the code, the first time I wrote {ListID} with capital D, it wouldn't work. Again thanks to Microsoft example. They really have to check their code before posting it public. the & sign has to be replaced by &amp;  

Here's a quick list of all Rights you can use for a feature:

AddAndCustomizePages
AddDelPrivateWebParts
AddListItems
ApplyStyleSheets
ApplyThemeAndBorder
ApproveItems
BrowseDirectories
BrowseUserInfo
CancelCheckout
CreateAlerts
CreateGroups
CreateSSCSite
DeleteListItems
DeleteVersions
EditListItems
EditMyUserInfo
EmptyMask
EnumeratePermissions
FullMask
ManageAlerts
ManageLists
ManagePermissions
ManagePersonalViews
ManageSubwebs
ManageWeb
Open
OpenItems
UpdatePersonalWebParts
UseClientIntegration
UseRemoteAPIs
ViewFormPages
ViewListItems
ViewPages
ViewUsageData
ViewVersions

If you want to have several right, seperate them by a comma Eg.:

Rights="AddListItems,ViewPages"