Programmatically Add Links to the QuickLaunch

Last week I did a post on feature receivers. In this post, I’m going to show you how to manipulate the quicklaunch bar using a feature receiver. Now, since I already did the step by step in last week’s post, I’m only going to go through the code this time. Click the link above if you need a refresher on feature receivers.

Ok, let’s take a look at the code. As we did last week, we created a class and inherited from SPFeatureReceiver. In this example, only FeatureActivated and FeatureDeactivating are overriden. In FeatureActivated, a spweb object is created using the property passed to the method. Next, a SPNavigationNodeCollection is created using web.Navigation.QuickLaunch. As I’m sure you already guessed, this object is a collection of nodes used in the QuickLaunch. Now, we need an SPNavigationNode to add to the QuickLaunch. In the FeatureActivated method, 2 nodes are created. The first node is just used as a header. 3 parameters are passed; Title, Url and a boolean. True indicates that the url is an external url.

Notice that both SPNavigationNodes are added to the quicklaunch differently. The first is using the .AddAsFirst method. This will create a node at the top of the QuickLaunch’s node collection (this becomes node 0). The second node is going to be a submenu item to the first node. Since the first node is 0, we use quickLaunch[0].Children.AddAsFirst(quickLaunchItem). This line will grab the 1st node, and add our node to its children.

The FeatureDeactivating method is used to remove these nodes from the quicklaunch. If you look at the code, you’ll see that I’m going through the nodeCollection backwards. The reason I start from the end is because if I used a foreach loop, once the first node is deleted, the count gets thrown off and an error is generated. (Go ahead, give it a try and see what I mean).

Now, before I activate my feature, my quickLaunch looks like this:

After activation, it will look like this:

Simple huh? Oh, and if you want to manipulate the links in the top navigation bar (the tabs above your quicklaunch bar and content area, you’ll still use the SPNavigationNodeCollection but instead of using web.Navigation.QuickLaunch, you’ll want to use web.Navigation.TopNavigationBar.

Working with a Wiki

Search for wiki in wikipedia and you’ll get the following:

A wiki is a collection of Web pages designed to enable anyone with access to contribute or modify content, using a simplified markup language.

Wikis are often used to create collaborative websites and to power community websites…

Wikis are used in business to provide intranet and knowledge management systems.

Simply put, wikis in SharePoint pages that allow groups of people to share information and ideas on the fly in a quick and easy way. There are 2 ways to create wikis.

  1. Create a wiki site by going through the same process of creating a site and just selecting Wiki Site from your list of templates.
  2. Create a wiki page library.

It doesn’t really matter which of these methods you choose. Method 1 will create a subsite with a Wiki Pages library that will contain your wikis. Method 2 will create a Wiki Pages library on the site that you’re currently on. You may want to use the 1st method if the permissions on the current page don’t work with what you want to do with your wiki. For instance, if you want everyone in the company to contribute, you may not want to put the wiki in your department’s site because members of other departments won’t have contributor rights. Instead, you may want to create a subsite with unique permissions and grant everyone, or specific groups contributor rights. In both cases, a Home page and a How To Use This Wiki Site page are created.

The How To page will explain how to use a wiki so I’m going to take this time to highlight some of the things mentioned in the file and show you how the process of editing a page looks. I’m going to edit the default home page created. Below is an image of the page before any changes.

As you can see in the image, the quick launch bar contains a link to the Wiki Pages library and shows each page in the library below it. You’ll also notice 3 buttons above the top-right corner of the content area (Edit, History, Incoming Links).

When you click on the Edit button in the top-right corner, an edit page containing a text editor will load. As you can see below, editing a page can be very simple and will take very little time showing employees how to contribute to the wiki. As you can see, I’m going to change the “Your” in the title with a red “MY”.

Making this change and clicking the OK button will take you back to the page with my text changes. If we click on the History button, we will be able to see our changes highlighted and references to several versions of the page on the left. You’ll see a legend just below the toolbar showing that deleted text will be highlighted in gray while new text will be indicated by a yellow highlight. The left column, as I mentioned earlier, shows the different versions of this page. The current version is at the top of the list. If I were to click on version 1.0, I will see an unedited version of my document. If you have more versions, you will see any changes made to the document up until that version and who made the change that resulted in that version. You’ll also see an option to restore that version in the toolbar.

Now, what if you to add a link to another wiki page. Easy. Just write the name of the page that you’re going to create enclosed with 2 square brackets on each side. The next image has an example highlighted. [[More Information]] will create a link to a page but I haven’t created the page yet.

When you click the ok button, you’ll see a link with a dotted underline beneath the text. This dotted line indicates that a page doesn’t exist yet. When you click on the link, a new page edit form loads and you can begin creating your content. When you click OK, the page is created. Go back to your original page and the line becomes solid underneath the link.

Well, that was my brief look at wikis. Very simple isn’t it. Again, wikis are good for getting employees to contribute content to a topic on the fly. As you saw, its very easy to create pages and links. The editor is a typical editor control that requires very little time to get used to and restoring previous versions of a page is very simple.

If you are having trouble deciding when to use a wiki, here are a few ideas:

  1. Information on a product that you provide.
  2. Ideas/changes/features for that product.
  3. A SharePoint wiki??? A quick source on how to use SharePoint maybe.

Anonymous Access

Earlier today, I was asked if a site could display a certain set of information to the public and company specific information to authenticated employees without having to create two sites. The answer is yes. One way to accomplish this is to use anonymous access.

In this post, I’m going to show you how to give your site anonymous access and how to lock down other pages (webs) and lists.

First, go to the Application Management tab in Central Administration. Find the section titled “Application Security” and click on the “Authentication providers” link.

When this page loads, select your zone. In my case, I’m selecting Default.

The Edit Authentication page will load and you’ll want to make sure that “Enable anonymous access” is checked. Once that’s done, click the save button and go back to your site.

What we just did in Central Administration was to tell our site that it can go ahead and make data public. Now we’re going to go to the site and set what we want public. Now, in this example, I want you to notice the top navigation bar. I have two tabs (Home and Private). Also notice in the quick launch (the navigation on the left side of the page) that I have four lists showing. When we’re done, I’m going to make the the “Private” web and the Audit list only accessible to authenticated users.

Go to the Site Actions menu and click on Site Settings. Under the Users and Permissions section, click on the “Advanced permissions” link.

In the permissions page, click on the Settings button in the menu and you’ll see a new menu item for Anonymous Access. Click on that link you’ll be redirected to a page with 3 options.
  1. Entire Web Site – gives full access to unauthenticated users.
  2. Lists and Libraries – gives unauthenticated users access to only those lists that allow access to unauthenticated users.
  3. Nothing – Access is only granted to authenticated users.

We’re going to select Entire Web site and click OK. At this point, an unauthenticated user can now go to my site and access everything (sort of). They won’t have access to the Site Actions menu, they can view items in a list but by default they can only view. They can’t edit or add unless the list is specifically setup to allow then to add/edit/delete items.

Now its time to start locking content down. The first thing that I want to do is lock the private site. To do this, I go to the Site Actions menu in the Private site and select Site Settings. I will again go to the Users and Permissions section and select Advanced permissions. So far, these are the same steps we followed earlier. When we get to the Permissions page, the Settings menu item is missing. The reason being that it’s inheriting permission from the parent site. Click on the Actions button and select Edit Permissions.

You’re going to be prompted with a message telling you that you’re about to create unique permissions. Click OK.

When you do this, the Settings button will return. Click on Settings and select Anonymous Access.

This time, Entire Web site will be selected. Change this selection to Nothing and click the OK button to save your changes.

At this point, unauthenticated users can come to my site and they will not be able to see the Private page. They won’t see a link for it in the top nav and they won’t be able to go directly to the site using the url unless they gave provide a valid username and password.

Now we want to go back to the Home page and remove the unauthenticated user’s access to the Audit list.

I’m going to go to the Audit list and click on the Settings button then click on the List Settings menu item.

When the Customize page loads, click on the “Permissions for this list” link under “Permissions and Management”

When the page loads, click on Settings in the menu and select “Anonymous Access”. On this page, you will be able to specify what Anonymous users can do with your list. You’ll notice that by default the View Items checkbox is the only one selected. Uncheck this option and click OK.

Now we’re all set. The Home page is now available publicly; except for its Audit list and the Private site which are now available only for authenticated users. The image below shows what an unauthenticated user will see. You’ll see that the Private site link is missing and the Audit list’s link is also missing. Again, even if the user knows the url, they won’t be able to access the site or the list. They will be immediately prompted for credentials.

Feature Receivers

Sometimes, you may want some custom code to run when an event is fired. In this post, I’ll walk you through feature receivers. A feature receiver is code that is fired when 1 of 4 possible events occur. The events are FeatureActivated, FeatureDeactivating, FeatureInstalled, and FeatureUninstalled.

To create a feature receiver, you’ll need to create a feature.xml file and a receiver class that inherits from Microsoft.SharePoint.SPFeatureReceiver (Add a reference to Microsoft.SharePoint.dll).

The feature.xml file is set up a little bit differently than a typical feature file. You’ll need to add two attributes. ReceiverAssembly and ReceiverClass. ReceiverAssembly will be made up of a namespace, version, culture, and PublicKeyToken. ReceiverClass will be the namespace.class. The following image will show you what the feature.xml should look like.

Next, you’ll want to create your feature receiver class. Add a new class item to your project and inherit from the SPFeatureReceiver class. You’ll need to override the events that you’re planning on using. In the following example, I’m overriding each method that is called when their corresponding event is fired.

For simplicity, I have each one calling the same AddAuditItem. This AddAuditItem method will add an item to the Audit list with information about the current feature. A reference to the SPFeatureReceiverProperties variable used by the caller is passed to this method as well as a string that indicates which event is being used.

Now we can deploy and test our feature receiver. Nothing special has to be done to deploy the feature portion. When you compile your code, place your assembly in the GAC and activate your feature.

I went ahead and activated and deactivated this feature and here are the results:

WebPart Connections

Up until this point, I’ve been building on webpart development by adding features to the helloWorld webpart. I started by showing you how to create a web part step-by-step in one of my first posts HelloWorld WebPart (From Start to Finish). I followed that with Creating WebPart Verbs. Next, I showed you how to add properties to your webpart in WebPart Properties and WebPart Properties Part 2: EditorPart. Now, I’m going to show you how to connect two webparts for the purpose of sharing data.

I’m going to modify our good old helloWorld webpart again. Last time, I showed you how to create a dropdown list, in the webpart’s editorPart, that contained text that was assigned to the webpart’s label. This time, we’re going to create a second webpart that will contain a dropdown with a list of messages. The helloWorld webpart will connect to the new webpart and display the selected text.

Here’s a list of everything that we’ll need to do to make two webparts talk to eachother:

  1. Create an interface
  2. Create a webpart that implements the interface
  3. Add a public function that returns your interface
  4. Add a method to your helloWorld webpart that will get your connection

Sounds simple. Let’s get started.

First, we’re going to create our interface. To do this, just add a new class item to your project, and replace “class” with interface. Below is an image of my interface. You’ll also need to add an empty property.

Ok, step one is done. Step two, create a webpart that will provide data. As you can see in the next image, I created a new class called MessageProvider that inherits WebPart and implements IMessages (I should’ve made this IMessage instead of IMessages, oops). You’ll also see that a dropdown is going to be created. The dropdown will contain the same values as the dropdown found in the editorPart created in a previous post.

Override the CreateChildControls method and create your dropdown. I cheated this time and hardcoded all of my values.

Now we need to setup the required property. I say required because we’re implementing an interface and the property in the interface is mandatory. If you attempt to compile your code without adding the Message property, Visual Studio will get mad. So, here’s my Message property in the MessageProvider class. This code will just check that something other than “-Select-” is chosen and assigns it to Message.

The last thing we need to do to this class is step 3: Add a public function that returns your interface. Take a look at the first line. You’ll see that we’re making this a ConnectionProvider. The string parameter is a display name. When you attempt to connect to this provider, it will be identified as “Messages Provider”.

Now we’re at the final step. We need to modify helloWorld to accept a connection. First, we’re going to add an instance variable. Add the following to your webpart’s list of instance variables: private IMessages provider = null;

Now we’ll add our method. In the following image, you’ll see the new method. GetConnectionProviderInterface accepts 1 parameter of type IMessages. We’re going to assign the value of that parameter to our provider instance variable. This will give us a way to access the public property that we created in the MessageProvider webpart. Again, notice that I have a little extra above the method. This time, you’ll see ConnectionConsumer and the string is again a display name.

Now that we have an object that can give us the value of the MessageProvider’s properties, we’ll need to modify the helloWorld webpart’s CreateChildControls method to use the value. You’ll see the following code checks that the provider object isn’t null then assigns the value to the label control.

Now, deploy the webparts and you’ll be ready to connect them. As you can see in the images below, the menu contains a new item called “Connections”. This option is only available when the page is in edit mode. So, click on Site Actions > Edit Page. View the menu for either webpart. They’ll both have a Connection item but the Provider webpart will have a “Send” followed by the display name that we gave the ConnectionProvider and the Consumer webpart (helloWorld) will have a “Get” followed by the display name that was givent to the ConnectionConsumer. Select the appropriate item in either menu. You only have to set the connection on one webpart.

Now that the webparts are connected, you can select an item from the dropdown and the selected item’s text will appear as the text in the helloWorld label control.

SharePoint and the Recession

I came across two brief articles and although they were posted a while back, I figure they’re still pretty good to take a look at considering the current economic situation that we’re in.

The first article was posted on April 02, 2009 (The Ultimate Business Timesaver). This article describes some simple solutions provided by SharePoint that has saved companies a lot of time and money.

The second article was posted on February 27, 2009 (SharePoint Solutions: Smart Investments in a Recession). This article gives you a few reasons to make the move to SharePoint and mentions a few things to consider to avoid some of the common mistakes made when implementing a SharePoint solution.

WebPart Properties Part 2: EditorPart

This is a continuation of a previous post entitled WebPart Properties. In the previous post, I showed you how to create a property used to store information for your webpart. In this post, I’ll show you how to use that same property to store text from a dropdown list that appears in the editorPart.

The first thing to do is remove the attributes from the Text property in the webpart class. This isn’t necessary but if you don’t remove it, a textbox will appear in your editorPart. There is one more change that will need to be made to the Hello class but we’ll wait til the end to make that change.
Next, create a new class library, call it HelloWorldEditorPart and inherit from the EditorPart class. (EditorPart comes from System.Web.UI.WebControls.WebParts). As you can see in the image below, I’m going to create 2 controls. A label and a dropdown list. The label wasn’t really necessary, but I just threw it in there. The dropdown list will contain items from a custom list called Messages. Messages contains 1 column (the Title field) and 3 items.
Now that we know which controls we’ll be using, we’ll need to instantiate and populate them. First, override the CreateChildControls method. As you can see in the image below, I assigned a string to Messages. Again, the label wasn’t necessary. I could’ve easily added text using html. Next, create 3 objects. An spweb, splist and splistItemCollection. This will be the first time we’ll be using SharePoint objects so you’ll have to reference the Microsoft.SharePoint dll. This dll is located at C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI. Don’t forget to add Using Microsoft.SharePoint to the top of your class.

In the code above, you’ll see that the spweb object is given the context of the current web. The Messages list is located in the current web, so I created an splist object and assigned currentWeb.Lists[“Messages”] to it. If you drop this webpart on another web somewhere that doesn’t contain a list called Messages, this webpart will fail. Then I created a spListItemCollection that contained the items of the Messages list. Finally, I setup my dropdown list. DropDownMessages.DataTextField is set to Title (the default column of the list) and DropDownMessages.DataValueField assigns the unique listitem ID to each item in the dropdown.
Now, we’re going to override the RenderContents method. We haven’t used this method until now. This method is used to organize your controls in an order specified by you using html. If you look at the image, you’ll see the two controls are using a method called RenderControl. This is used to display the control on the editor. You’ll see writer.Write(”
“) between the controls. This is there to place a break between the controls. If the break wasn’t there, the controls would be side by side with no space.

The last thing that needs to be done to the editorPart is for us to override two methods required to save the data back to the webPart. Override ApplyChanges and SyncChanges. ApplyChanges will fire when you click the apply button in the editorPart. As you can see in the image, I’m creating a Hello object and assigning it the text from the dropdown. In the Sync method, I’m taking the text that’s stored in the property and selecting it in the dropdown.

Now, we’re done with the EditorPart and we need to make one last change to the webPart class. We’ll need to tell the webpart that there is a custom EditorPart that it has access to. Override the CreateEditorParts method. First, you’ll need to create an instance of your editor webpart. You’ll see this done in the first line. Then give it an ID. Create an arrayList and add the object that you just created to it. Finally, return an EditorPartCollection object with the base.CreateEditorParts() and your arrays. This will display the typical content in the editorPart as well as your new customized part.

Now we can look at our results. Click on Modified Shared Web Part from your web part’s menu and you’ll see the label control followed by a dropdown list populated with the contents of the Messages list like the image below.
I’ll select the first item in the dropdown and the label control in my webpart, which displays the value assigned to the Text property, will be updated when I click on OK or Apply with the selected Text of the dropdown.