FBA in SharePoint 2010 requires claims mode

If you have already set up Forms Based Authentication(FBA) in SharePoint 2010 public beta, you would have noticed not much of a change from SharePoint 2007. As you are aware, SharePoint 2010 includes new authentication model called Claims Based authentication. You can read more about this here. Since the SharePoint 2010 RTM, FBA now requires claims mode set up for the web application. Your membership provider and role provider now acts as the Identity Provider.

 

So, if you go to your web application settings, and choose to edit the Authentication Providers, you will notice the following:

 

image

 

Notice that there is a help on how to enable Forms Based Authentication in claims mode. You can click on it to read more about how to set up FBA.

 

Here is a simple PowerShell script which changes the web app’s authentication mode to claims based:

 

$webApp = Get-SPWebApplication “/">http://<web-app>/

$webApp.UseClaimsAuthentication = "True";

$webApp.Update();

$webApp.ProvisionGlobally();

 

Once you have executed the above PowerShell script, if you go to your web app’s authentication provider settings, you should see:

 

image

 

Clicking on Default, you will be able to select your identity provider for the claims based authentication:

 

image

 

If you are creating a new web app, you can initially choose which authentication mode you want:

 

image

 

You can refer more to this blog post by Steve on setting up FBA in SP2010: http://bit.ly/a5WhlE (or) this MSDN article: http://bit.ly/bUYvjC

Deactivate Features Deployment Step for SharePoint 2010

If you are developing SharePoint 2010 applications in Visual Studio 2010, you would wonder why there is no Deactivate Features deployment step available but only Activate Features deployment step.

image

This becomes a problem when you retract your solution as the features do not get deactivate from the site.

Let me introduce to my first Visual Studio 2010 Tools for SharePoint 2010 extension – Deactivate Features Deployment Step 

Deactivate Features Deployment Step is an extension for Visual Studio 2010 tools for SharePoint 2010. Use this deployment step to deactivate features in a local SharePoint site.

deactivate_features_step

It is available for download at the Visual Studio Gallery or from your Visual Studio 2010 Extensions Manager

image

SharePoint 2010: Extending a SharePoint Node in Server Explorer

SharePoint Server Explorer is a new addition to Visual Studio 2010 along with the Visual Studio Tools for SharePoint.

image

It is a very good tool if you want to browse the contents (site columns, content types, features etc.,) of the SharePoint site from Visual Studio. By default, it doesn’t do nothing much than showing what are available in the site.

image

As you can see, the context menu has very fewer items. Below is the Properties pane for the Holds list in the screenshot. The properties are stored in Annotations. To understanding what Annotations are, it is best to consider them as a Class with Properties. Those properties is what you see in the Properties pane below.

image

Again, its read only.

Can I Extend?

So, the next obvious question you would ask yourself (if you are a SharePoint developer) is – Can I extend this and add my own commands or nodes to the SharePoint Server Explorer?

Yes, you can extend the SharePoint Server Explorer to:

1) Create new nodes

2) Extend existing nodes

Give me an example?

Lets take the Features node

image

The Features node displays all the active features in the site. If you right click on a feature, you get very less options

image

How cool would be to add Deactivate option to the context menu and deactivate the selected feature? :)

image

[ By the way, the above screenshot is an actual extension built and not a Photoshop trick :) ]

Understanding the SharePoint Server Explorer

Before you start writing an extension, you should get to know the different types of SharePoint Server Explorer nodes.

image

The node that we are interested in is the FeatureNode.

Getting Started

MSDN has excellent articles explaining how to extend the Visual Studio Tools for SharePoint

Here is a pictorial representation of what we would be doing:

image

 

1. Create a class that implements IExplorerNodeTypeExtension

2. Handle the events

3. Access the properties of that node using Annotations

4. Perform SharePoint operations using Client Object Model

Step 1

Create a Windows Class Library project and add references to

  • Microsoft.VisualStudio.SharePoint

  • Microsoft.VisualStudio.SharePoint.Explorer.Extensions

  • System.ComponentModel.Composition

 

Step 2

Create a class and implement IExplorerNodeTypeExtension:

internal class FeatureNodeExtension : IExplorerNodeTypeExtension
{

}

 

Step 3

As we are interested in adding an item to the context menu, handle the NodeMenuItemsRequested. This is done in the Initialize method:

public void Initialize(IExplorerNodeType nodeType)
{
nodeType.NodeMenuItemsRequested +=
new EventHandler<ExplorerNodeMenuItemsRequestedEventArgs>
(nodeType_NodeMenuItemsRequested);
}

 

And here is the event handler:

void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
IMenuItem deactivateMenu = e.MenuItems.Add("Deactivate");
deactivateMenu.Click +=
new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}

We add the new menu item in the event handler above and also handle its own click event.

Step 4

As we want to deactivate a feature, we need to know the Feature Definition Id. They are already available in the Properties pane for a feature:

image

To access the Properties we need to access it via the Annotations object. Here is the code to access the Feature properties:

IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
definitionId = fn.Id;
featureName = fn.Name;

 

Next thing is to get the site at which this feature is installed. As the Server Explorer has already established the connection to the site, we can get it from its current context.

IExplorerNodeContext siteContext = e.Node.Context;

 

Here is how my event handler looks:

void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
siteContext = e.Node.Context;
IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
definitionId = fn.Id;
featureName = fn.Name;

IMenuItem deactivateMenu = e.MenuItems.Add("Deactivate");
deactivateMenu.Click += new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}

 

Step 5

We can now write code to deactivate the feature in the new menu item’s event handler using the Client Object Model:

void deactivateMenu_Click(object sender, MenuItemEventArgs e)
{
if (MessageBox.Show(confirmationMessage,String.Format("Deactivate {0} feature",featureName),
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation) == DialogResult.Yes)
{
IExplorerNode parentFeatureNode = e.Owner as IExplorerNode;
IExplorerNode featureNode = parentFeatureNode.ParentNode;

ClientContext clientContext = new ClientContext(siteContext.SiteUrl.AbsoluteUri);
Web site = clientContext.Web;
FeatureCollection siteFeatures = site.Features;

clientContext.Load(site, s => s.Title, s => s.Features);
siteFeatures.Remove(definitionId, false);

clientContext.ExecuteQuery();

clientContext.Dispose();

featureNode.Refresh();
}
}

Very simple indeed. Query and get only the Web and Features object, and then remove (deactivate) the feature from the site.

You can also do this asynchronously using the Asynchronous Pattern for Client OM.

Deploying the Extension

To deploy the extension, we need to include it in a .vsix package.

You can use the VSIX template to create the .vsix package.

image

Include the extension in the manifest file.

image

Chose the content as MEF Component  and select the extensions project as your source.

Build the project to generate the .vsix package and install the package.

‘Deactivate Extension’ for FeaturesNode done

And here is our menu item in the context menu:

image

 

 

When you click on it, you will get a confirmation message:

image

Clicking Yes will deactivate the feature and refresh the Features node.

You can download the source code and VSIX package below:

Item-level Permissions for Document Libraries – Release v1.1.0.0

Just released Item-level Permission for Document Libraries v1.0.0.0. You can get it here.

ilp_documents_settings_page

Changes in v1.1.0.0

- ILP now uses SharePoint Solution Installer for installation/un-installation

- Fixed a bug with Timer Job & RunWithElevatedPriviliges

- Changed the visibility of the ILP site columns, ILP list instance. They are now visible in the site.

- Added the ability for developers to hook their own event handlers. Read more here >> Info for developers

Known Issues

- If you are using the API to enable ILP & register your custom event handlers, you have to use the API again to disable ILP & un-register your custom event handlers to the corresponding document library or list.

Item Level Permission for Document Libraries – Release v1.0.0.0

 

[There is currently some problem with CodePlex and I am not able to upload my files or source code in my CodePlex project. This project will be eventually moved to CodePlex soon.]

This project is now available at CodePlex – http://ilp.codeplex.com 

--------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

ILP enables item-level permission for document libraries and also allows users to select a set of default permissions that can be applied to the new items and existing items in the document library.

Installation

Execute the install.bat to install. You will be prompted for two Urls – Web Application Url and Web Url.


ILP for Document Libraries will be activated in the Web Url you specify above. So in my above example screenshot, the ILP will be available for the root web / in the http:/sample web application.

How to activate for any other web?

Go to the Site Settings for your web and click on Site Features.


Activate the ILP:Item level permission library settings feature

ilp_feature_activate

Once activated, ILP will be available to that web.

To uninstall, execute the un-install.bat script.

Usage

You can locate the Item-level permissions for the document library in the document library's Settings Page under the Permissions and Management tab

ilp_settings

Click on the Item-level permissions for this document library to open the item-level permissions page


ilp_documents_settings_page

You can now specify your options

  • Require new items to inherit parent permissions?
    • Choosing Yes will enable item-level permission for this document library
    • Choosing No will disable item-level permission for this document library.
  • Default Permission Levels
    • Any additional permissions you might like to give to the new items
    • Choose a Permission Level and then select the groups. Groups == SharePoint Groups.
    • If left empty, nothing happens.
  • Permissions to existing items
    • This helps to update the existing items in the list.
    • If ILP is enabled
      • Choosing Yes will set ILP for existing items in the document library, inherit parent permissions and also apply any default permission levels (chosen in Step 2, if any).
      • Choosing No will not modify existing items in the document library.
    • If ILP is not enabled
      • Choosing Yes will disable ILP for existing items in the document library and copies the parent permissions back.
      • Choosing No will not modify existing items in the document library.

 

 

 

 

Developers, Developers, Developers – ILP API

If you are a devleoper and want to consume the ILP API, you can do so.

Download the latest ilp_api_{version}.zip. Unzip and add reference to the the Chaks.SharePoint.Docs.ILP.dll in your project

You can now use the Extension method EnableItemLevelPermissions on the SPList object.

Below is the declaration of the EnableItemLevelPermissions method:

ilp_enableitemlevelpermissions

It accepts ItemLevelPermissionSettings as the only parameter

ilp_itemlevelpermissionsettings

  • EnableItemLevelPermissions
    • Specify whether to enable ILP or not
  • DefaultGroups
    • List of default SharePoint groups you want to apply to the items
  • DefaultPermissionLevel
    • The default permission level you want to apply to the items
  • ApplyToExistingItems
    • Specify whether to apply the changes to the existing items or not

You can safely ignore EventReceiverAssembly and EventReceiverClass as it is internally used by the ILP to hook to the proper event receiver. From next release onwards, developers will be able to hook up to their own event receivers using these two peoperties.

Using the API

Below are some code samples on using the API

 

 

using Chaks.SharePoint.Docs.ILP;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite spSite = new SPSite("http://sample"))
            {
                using (SPWeb spWeb = spSite.RootWeb)
                {
                    SPList imagesList = spWeb.Lists["Site Collection Images"];

                    List<SPGroup> spGroups = new List<SPGroup>();
                    spGroups.Add(spWeb.SiteGroups[1]);
                    spGroups.Add(spWeb.SiteGroups[2]);

                    ItemLevelPermissionSettings settings = new ItemLevelPermissionSettings
                                                               {
                                                                   EnableItemLevelPermissions = true,
                                                                   DefaultPermissionLevel = spWeb.RoleDefinitions["Full Control"],
                                                                   DefaultGroups = spGroups,
                                                                   ApplyToExistingItems = true
                                                               };

                    imagesList.EnableItemLevelPermissions(settings);

                    Console.WriteLine("Permissions applied....Press any key to continue");
                }
            }

            Console.ReadKey();
        }
    }
}

You can pass null if you dont intend to apply any default permission level and default groups

ItemLevelPermissionSettings settings = new ItemLevelPermissionSettings
{
     EnableItemLevelPermissions = true,
     DefaultPermissionLevel = null;
     DefaultGroups = null;
     ApplyToExistingItems = true
};

Note

Even though ILP for Document Libraries is meant only for Document Libraries (as the same suggests), using the API, you can also apply it to a SharePoint List.Please note that, it does not override the SharePoint out of the box Permissions settings and thus if you have already set up unique permissions for a SharePoint list, they will also be applied along with the ILP settings.

Downloads

Set Available PageLayouts for your Site

Below is a code snippet for setting available page layouts for your site:

 

List<String> strPageLayoutsToPersist =

        new List<string> { "Home Page", 
                           "General Detail Page", 
                           "Email Me Page", 
                           "Category Page" 
                         };
using (SPWeb spWeb = spSite.RootWeb)
{
        PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(spWeb);
        
        // Get avaialble page layouts for our content types
        PageLayout[] myPageLayouts = pubWeb.GetAvailablePageLayouts().Cast<PageLayout>()
            .Where(p => strPageLayoutsToPersist.Contains(p.AssociatedContentType.Name))
            .ToArray();
 
        // Set the available page layouts to our content type
        pubWeb.SetAvailablePageLayouts(myPageLayouts, false);
 
        // Update the web
        pubWeb.Update();
}

 

This will hide every page layouts except those you specify in the strPageLayoutsToPersist

Using KeywordQuery to search in your SharePoint site

There are various ways that you can query the Search Service in your SharePoint site:

1) Using the Search Web Service

2) Using the SharePoint Object Model

There are yet again two ways you can use the Search, using the Object Model:

i) KeywordQuery

ii) FullTextSqlQuery

I think it is a good option to use Object Model when you want to customize the Search (mostly in your WCM websites), and KeywordQuery comes in very handy!

Using KeywordQuery to search is pretty simple! (provided you have set up your Search properly)

KeywordQuery keywordQuery = new KeywordQuery(SPContext.Current.Site);
keywordQuery.ResultTypes = ResultType.RelevantResults | ResultType.SpecialTermResults;
keywordQuery.StartRow = 1;
keywordQuery.RowLimit = 5;
keywordQuery.SortList.Add("Rank", SortDirection.Descending);
keywordQuery.EnableStemming = true;
keywordQuery.TrimDuplicates = true;
keywordQuery.IgnoreAllNoiseQuery = true;
keywordQuery.HiddenConstraints = "scope:" + "\"" + SearchScope + "\"";
keywordQuery.QueryText = SearchText;
ResultTableCollection searchResults = keywordQuery.Execute();

As you can see above, I have combined the result type to be both RelevantResults and SpecialTermResults

Note: In WSS, only RelevantResults will work

One other thing to note in the above code is how we specify the scope using the HiddenConstraints

The search results are returned as a table collection. You can access the search tables as follows:

ResultTable relevantResultsTable = searchResults[ResultType.RelevantResults];
ResultTable specialTermResultsTable = searchResults[ResultType.SpecialTermResults];

If you want to load these into a DataSet with tables RelevantResults and SpecialTermResults respectively, then:

// Relevant Results table
DataTable relevantResults = new DataTable();
relevantResults.TableName = "RelevantResults";
 
// SpecialTerms Results table
DataTable specialTermResults = new DataTable();
specialTermResults.TableName = "SpecialTermResults";
 
// Search Results DataSet
DataSet resultSet = new DataSet();
 
 // Relevant Results
relevantResults.Load(relevantResultsTable, LoadOption.OverwriteChanges);
resultSet.Tables.Add(relevantResults);
 
// SpecialTerms Results
resultSet.Tables.Add(specialTermResults);
specialTermResults.Load(specialResultsTable, LoadOption.OverwriteChanges);

You can now easily databind this DataSet

 

 

If you have worked with the Search Web Service, you will notice that the properties in KeywordQuery and the Search Query XML are similar

<?xml version="1.0" encoding="utf-8" ?>
<QueryPacket xmlns="urn:Microsoft.Search.Query" Revision="1000">
<Query domain="QDomain">
 <SupportedFormats><Format>urn:Microsoft.Search.Response.Document.Document</Format></SupportedFormats>
 <Context>
  <QueryText language="en-US" type="STRING" >  SCOPE:"All Sites"</QueryText>
 </Context>
<SortByProperties><SortByProperty name="Rank" direction="Descending" order="1"/></SortByProperties>
 <Range><StartAt>1</StartAt><Count>5</Count></Range>
 <EnableStemming>true</EnableStemming>
 <TrimDuplicates>true</TrimDuplicates>
 <IgnoreAllNoiseQuery>true</IgnoreAllNoiseQuery>
 <ImplicitAndBehavior>true</ImplicitAndBehavior>
 <IncludeRelevanceResults>true</IncludeRelevanceResults>
 <IncludeSpecialTermResults>true</IncludeSpecialTermResults>
 <IncludeHighConfidenceResults>true</IncludeHighConfidenceResults>
</Query></QueryPacket>

(Above Search Query XML was generated using SharePoint Search Service Tool)

Customizing the 404 Redirection in SharePoint

By default, SharePoint takes you to its own 404 NOT FOUND page if you enter an Url which does not exist in the site.

image

It is very easy to customize this behaviour and let SharePoint redirect 404 errors to the page you want to.

The important file that manages this 404 redirection is -

12\TEMPLATE\LAYOUTS\1033\sps404.html

This HTML file controls the redirection

<script language="javascript">
    var requestedUrl = escapeProperly(window.location.href);
    STSNavigate("/_layouts/spsredirect.aspx?oldUrl=" + requestedUrl);
</script>

So, to create your own custom 404 redirection, all you need to do is:

1) Make a copy of sps404.html, for example – mysite404.html - and place it in the same folder 12\TEMPLATE\LAYOUTS\1033\

2) Modify the STSNavigate with your page Url:

STSNavigate("/how-to-join/Pages/default.aspx?oldUrl=" + requestedUrl);

Remember that as long as the Url is valid, your redirection will work

3) You have to now set the mysite404.html as your 404 redirection page for your web application.

You can do this via the SharePoint object model. Instead of writing a console app to do this, it is always better to deploy the 404 redirection using a feature which would set the 404 redirection.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPWebApplication webApplication = properties.GetSite().WebApplication;
    webApplication.FileNotFoundPage = "mysite404.html";
    webApplication.Update();
}

Note: The FileNotFound is set to NULL by default

Note: You can *only* set a 404 redirection per web application

Deploy the feature, activate it and your custom 404 redirection is ready to go!

Using the Reusable Content to style HTML Contents

Sometimes in your WCM website, you might want users to enter some content in a content area but still apply those styles for the content.

Using the RichHTMLField control, users can enter rich HTML content, but if the content needs some styling or formatting to be applied, then its pretty hard to do it via the editor.

image

What you see above is some content without any styling applied. When you render the field value, the content will be applied without any styling as well. If you still need to apply the styling, you can do it by switching to HTML mode, as shown below.

image

This would be a pretty difficult job for the content editors especially if they want to do the same thing at multiple places.

Is there something that would make the job easier?

 

Yes, and they are called Reusable Contents!

In your Publishing Website, you can see a List called Reusable List. You can use this List to upload your HTML template (with all those styles and formatting) and reuse them across the site and is also accessible right away from the RichHTMLField control!

Content Category

Content Category identifies where the reusable content is going to be available. This is initially empty. So if you want to use in places like RichHTMLField controls, then you need to populate the content category as WYSIWYG Templates

Go to your Reusable List settings and choose the Content Category column from the Columns

image

Under the Additional Column Settings enter the choice - WYSIWYG Templates

image

Now, you can add the new reusable content item

image

Make sure you choose Reusable HTML as the Content Type and WYSIWYG Templates as the Content Category. (Choose to automatically update based on your needs. If you are going to use reusable content as a HTML template for styles or formatting, then it is better not to automatically update)

The reusable content will now be available in the RichHTMLField controls of your website

image

Below is an example of the reusable content popup

image

You can choose the reusable item you want to insert using the above popup.

Using same custom edit forms across different Lists in SharePoint

We have a customer who has 5 different Lists and all the Lists have same content type associated with it. They wanted a custom edit form for this content type and want to use it across those 5 different Lists to enter data. We created the custom edit form very easily and uploaded the form to the Layouts folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS) so that we can load it in the code-behind.

The problem arose when we wanted to use the same custom edit form across different List as these custom edit forms are bound to a specific List

<ParameterBindings>
            <ParameterBinding Name="ListItemId" Location="QueryString(ID)" DefaultValue="0"/>
            <ParameterBinding Name="ListID" Location="None" 
                     DefaultValue="{7A0F7220-4967-4061-985D-D78F4435B071}"/>
            <ParameterBinding Name="dvt_apos" Location="Postback;Connection"/>
            <ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
            <ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
</ParameterBindings>

 

As you can see in the above snippet, it is clearly bound to a List with ID {7A0F7220-4967-4061-985D-D78F4435B071}

So, how can you associate this custom edit form to work across a different List? I don't want to create x-number of forms for x-number of Lists!

Well, out of luck, we actually figured it out how to do so! – Setting the DefaultValue of the ListID to 0

If you put 0 instead of the List ID, it automagically identifies the List that the form is bound to during runtime and works like a charm!

So, here is my XML schema after the change:

<ParameterBindings>
            <ParameterBinding Name="ListItemId" Location="QueryString(ID)" DefaultValue="0"/>
            <ParameterBinding Name="ListID" Location="None" DefaultValue="0"/>
            <ParameterBinding Name="dvt_apos" Location="Postback;Connection"/>
            <ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
            <ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
</ParameterBindings>

Its weird, but true :)

Customizing the Site Actions menu

In the WCM projects that I am working, the first thing the client says when they see a demo of ‘editing a page’ is - “Why is this Site Actions’ design not in sync with our website design?”

Unlike in Intranet websites, where this doesn’t come to a much concern, it does look odd when you have applied your branding in the SharePoint WCM website.

So, can we customize the look and feel of the Site Actions menu? – Of course, YES!

CSS Styles

If you have IE8 installed, fire up the Developer Tools. I selected the Site Actions menu and here are the styles associated with it

image

And within minutes I had the necessary CSS styles from the interactive team!

 

 

/*SITE ACTIONS*/
div#siteActionsWrapper {
    width: 975px;
    margin: auto;
    overflow: hidden;
}
    table.ms-siteaction {
        float: right;
        }
    .ms-siteactionsmenu div div div {
        margin-top:10px;
    }
    .ms-siteactionsmenu div div div a {
        display: block;
        line-height: 200px;
        overflow: hidden;
        width: 89px;
        height: 28px;
        }
    span#ctl00_siteActionsEditModeControl_authoringcontrols {
        width: 850px; 
        display: block;
    }
    td.ms-siteactionsmenu div div span div img {
        display: none;
    }
	 
.ms-siteactionsmenu div div div {
    background: 
	 transparent url(/_layouts/images/chaks/buttonSiteActions.png) 
	      no-repeat !important;
    border: 1px transparent solid !important;
}

The span#ctl00_siteActionsEditModeControl_authoringcontrols corresponds to the Page editing toolbar. Note the !important  - This overrides the SharePoint styling and applies our style!

Below is the screenshot of the customized Site Actions Menu and Page editing toolbar

image

SharePoint - Hiding Menu Items from the Edit Control Block

If you want to add a menu item to the Edit Control Block(ECB) in SharePoint, you can do so by writing a new Feature. But if you want to hide some of the  menu items, you cannot do so by writing a Feature. SharePoint uses its JavaScript file - core.js to render the ECB. MSDN has an excellent article explaining how to remove menu items from ECB.

So, I went ahead and did the changes by adding a new file called customcore.js and included the same in my Master page. I removed the Send To menu item in the JavaScript code. But the change was not reflecting and the ECB still had the Send To option. I checked my code several times and I was sure I had removed the Send To code in the JavaScript, but why is it showing still? I went back to the MSDN article and verified each step:

  • Copy the core.js file from its default location at <%Program files %>\common files\Microsoft shared\web server extensions\12\Template\layouts\1033, place it in the same folder, and rename as customcore.js file.
  • Make the necessary changes in the customcore.js file by removing unwanted ECB menu items.
  • To create the custom master page, make a copy of the default.master page and rename it as custom.master.
  • In the custom master page, add the following line to render the customcore.js file:

<SharePoint:ScriptLink language="javascript" name="core.js" Defer="true" runat="server"/>
<SharePoint:ScriptLink language="javascript" name="customcore.js" Defer="true" runat="server"/>

Save the custom.master page and upload it to the master pages gallery of the site. Then apply the custom.master page as the default master page for the site.

Everything was there! Hold on! -  In the 4th step we can see that even though we have our own customcore.js , we still need to add core.js! And that was the 'thing' I had missed.

I was under the impression that since my customcore.js is just a copy of core.js, it is enough if we included customcore.js in our master page. But SharePoint doesn't like that way. We have to render core.js no matter what and then include our own customcore.js. If you don't do so, then SharePoint will load the default core.js, ignore the customcore.js and you will lose your changes!

So, do not forget the 4th step whenever you hide menu items from the ECB :)

Extending SharePoint by Adding Custom Actions

So, you want to add your custom items in the SharePoint menus or toolbars ? You can do so by adding your own Custom Action. Custom Action is a SharePoint Feature which makes your life easier if you want to customize your site.

Some examples of where you might want to add items may be:

1) In the Upload Drop Down menu in the Document Library

sharepoint-custom-action-example

2) In the Edit Menu content block

sharepoint-custom-action-example1

If you do a web search, you will find that many people have achieved this by modifying a file called core.js. This is a JavaScript file used by SharePoint master page and has all the code in creating those menus.

But *it is not recommended* to change the SharePoint's core files.How do we do this then?

If you do sometimes want to hide items in the Edit Control Block, MSDN again has a neat article on how to perform this.

My only advice when doing customisations to a SharePoint website would be, *not to modify the default SharePoint files* !

Here is my modified Edit Control Block for my Document Library :

I have hidden the Send To menu and added a new action item - Send Item for Review

sharepoint-custom-action-item


Creative Commons License
Chaks' Corner Blog by Chakkaradeep Chandran is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
Based on a work at www.chakkaradeep.com.
Permissions beyond the scope of this license may be available at http://www.chakkaradeep.com.