Book is done – What happens now?

Well, sort of. I have written all the content, but there is still a lot to be done. Revisions, reviews, remakes, outtakes… The estimated date of release is still April, I’m afraid, and I’ll need every second of that time. However, I am now extremely relieved that I managed to meet, almost, the content deadline of December 31st.

Now that the all encompassing book writing process is done I have a ton of things that will happen in the upcoming months. And there are some freebies if you pay attention.

1. More SharePoint developer articles

You might have seen the first article I wrote this year, on RSS in SharePoint. That article is based on an idea I had for the book, that sadly didn’t make it into the final version. This is not the only outtake, however, so in the coming months I will be publishing articles based on either ideas I had that I never included or actual content that was left out.

I will start an article today that will focus on improving the feature management of SharePoint, for example. Perhaps I’ll even make it a series. I don’t have a release schedule yet, however, but if you read the feed you’ll be among the first to know.

2. Book as video

I am an extremely slow reader. I actually spend more time reading my own stuff than I do writing it. I rather wait for the movie than read a novel.

If you are anything like me you will be thrilled to know that almost the entire "Building the SharePoint User Experience" will be available as videos. Each chapter will be a separate video and cover everything that is in the book and even some more content that is relevant.

When I say almost that is because some chapters are not suited for video. Stuff like Questions from the Audience is not really something you can demo. Same applies for "The Mentality of a SharePoint developer". By the way, you can get the entire table of contents as well as several other exclusive excerpts when you sign up for the mailing list. Read on and you’ll see why doing so will also get you more free stuff.

3. Blog moving

Blogger has been kind to me, most of the time. However, now that the Understanding SharePoint website is starting to get a lot more content I want to move to a new platform. I wrote about this last summer and the time has now finally come.

I have not set a date for the move yet, as there are a lot of technicalities that needs to be sorted out first. The feed will remain the same and I’ll provide links from the old pages to the new pages.

4. XSLT course

As you may or may not have read, it seems that Microsoft is moving away from CAML and over to XSLT as a rendering language for views in WSS 4.

Now, CAML will continue to remain important. First of all, WSS 3 will be here for a long time. Many organizations are still working to move to WSS 3, and people are still developing for WSS 2. I am not saying you shouldn’t learn CAML at this point, I am just saying that you might want to start looking into XSLT.

To help you out I will be creating and publishing a six-part XSLT introduction course. The date of release is still not set, nor is the price. I am thinking somewhere around $20 bucks, but that is subject to change at any point. The topic of the course is to understand basic XSLT and XML as it relates to SharePoint. As details are revealed around Windows SharePoint Services v 4.0 I’ll release more information.

Here is where you want to pay attention: At some point in the near future I will send a token code to the book mailing list. That token is redeemable for a 100% discount on the course. Yup, that’s right, the members of the mailing list, every single one, will get that XSLT course absolutely free. The catch? You need to be on the list. Nothing else. The code will not be published again, and it will be verified towards the members of the list at the time of publication, so you cannot share or sign up later to get the free course.

5. Just Ask about SharePoint beta

Some of the more observant readers may have noticed that I have added a link to my links section. The link points to the new Just Ask section of the Understanding SharePoint website. The Just Ask website is a collection of questions I have received and answered around the various online forums, by email from readers, or in person. The idea is to create a series of highly focused and specific questions and answers to serve as a knowledge base for SharePoint developers and administrators.

Oh yeah, it’s still in beta. I need a lot of more functionality and a lot more content, but you are free to take a look now if you have questions about SharePoint. If you have comments or questions you want answered, let me know. If you want to contribute I’d love to hear from you.

6. SPTechCon seminars

I have mentioned this before, several times, but I will be holding several sessions on the upcoming SharePoint Technology Conference in San Francisco.

If you are in the area and interested in SharePoint I have been told there are still spots available. I will hold three sessions, a full day workshop that covers most of what the book will cover, a short and intense SharePoint architecture from the user experience session as well as a session on tips and tricks no how to speed up feature and solution generation time.

 

So yeah, even with book writing done there will still be a lot of things happening in the upcoming months.

See you around!

.b

Found this article valuable? Want to show your appreciation? Here are some options:

a) Click on the banners anywhere on the site to visit my blog's sponsors. They are all hand-picked and are selected based on providing great products and services to the SharePoint community.

b) Donate Bitcoins! I love Bitcoins, and you can donate if you'd like by clicking the button below.

c) Spread the word! Below, you should find links to sharing this article on your favorite social media sites. I'm an attention junkie, so sharing is caring in my book!

Pin It

Here’s what happens when you let people write their own titles and suffixes in forms

Microsoft’s Passport allows you to edit the your title and suffix as you like. I have had great fun over the years calling Microsoft support and waiting for the person to address me by name. They usually giggle when they realize that instead of the customary ‘Mr.’ or ‘Dr.’ and ‘the Third’ or ‘Esq.’ I have added my own version of title prefix and suffix.

So, this is the address page on the Architecture Journal I received from Microsoft the other day:

08.01.2009

Previously I have done similar with other profiles. I think I still have the frequent flyer card that says ‘Please provide a free drink to Bjørn Furuknap, and bill the airline’.

.b

Pin It

Consuming RSS or Atom feed in SharePoint using custom list, SPFolder, CustomAction, and NewPage

This article will demonstrate several techniques:

– Creating a list from a custom NewPage page

– Consuming an RSS feed into a SharePoint list

– Using a CustomAction with a code-behind assembly to update the feed

– Storing and retrieving custom list data in the SPFolder of the list

Yeah, I have missed writing online. And I have a ton of new ideas for articles for the next months. Make sure you follow the feed to keep up.

What you will need:

– SharePoint

– Visual Studio

WSPBuilder

Argotic Syndication Framework

The Argotic Syndication Framework is a free framework that has some really nice syndication features. Before you continue you should get that framework and install it.

The outline of the project we will create is as follows:

We will create a new list template. I will base this template off the custom list template and leave list creation details for you to want to read in the best SharePoint book ever. And it saves time… Our new list template will use the NewPage attribute to customize the list creation.

In our newly created list we will store feed items, either from an RSS or an ATOM feed. To store custom data, such as the feed Url and the last updated time, we will use the property bag of the SPFolder object.

Finally we will add an update button using a CustomAction element. Clicking the button will update the feed with new items.

You can see a demo of the entire solution here:

 

…or download it for you offline amusement at Googlepages.

Ok, on to the solution.

Adding ListTemplate element

Start out with a new WSPBuilder project. Name it whatever you like, I’ve called mine AdvancedListSample.

Add references to the four Argotic Framework assemblies that were installed, probably to C:\Program Files\Argotic\Microsoft .NET 2.0.

Next, add a new Feature with Receiver WSPBuilder item. You will find this item when you add a new item to the project, it should be listed under the WSPBuilder item type. I have called this item AdvancedList in my example.

Why add a feature with a receiver? Well, if you do, WSPBuilder will save you some time by creating a signing key, signing the assembly, and giving you the strong name of the assembly, which we will need later.

WSPBuilder will now create a folder structure for you that mimics [12] and the feature folder beneath it. Inside your feature folder, create a new folder called AdvancedList as well, just because I feel particularly uncreative today. The naming of this folder is important as it will hold the schema.xml file for our custom list template. The name of the folder must match the Name attribute of the ListTemplate element.

Next, to take an extremely simple approach, go to the [12]\TEMPLATE\FEATURES\CustomList\CustList folder and copy the entire schema.xml file from that folder. Paste the complete schema.xml file into your own solution. You can accomplish this by drag-and-dropping the file from CustList to your solution.

Your feature folder in solution explorer should now look like this:

RSS_in_SharePoint01

While you are in the [12] folder, open the [12]\TEMPLATE\FEATURES\CustomList\ListTemplates\CustomList.xml file and copy the Element inside that file. Paste the Element from CustomList.xml into you own elements.xml file. Then, modify the ListTemplate element as such (changes in bold)

http://schemas.microsoft.com/sharepoint/">
        NewPage="AdvancedListCreation.aspx"
      Name="AdvancedList"
      Type="10010"
      BaseType="0"
      OnQuickLaunch="TRUE"
      SecurityBits="11"
      Sequence="410"
      DisplayName="Advanced list"
      Description="$Resources:core,custList_Desc;"
      Image="/_layouts/images/itgen.gif"/>

If you feel like it, modify other attributes as well, but it is not necessary for our solution.

The NewPage attribute refers to a url in the Layouts folder. If you specify this attribute SharePoint will link to your custom page rather than the default Create List page. In our case, since we want the user to input additional data, we need to customize that page. More on that in a moment.

Great, ListTemplate code complete. On to the custom NewPage.

Custom list creation page

Next we want to add the page we will use to create our new list. Note that when you use a custom create page you will be responsible for actually creating the page. however, doing so is rather trivial in our case.

First, add a new folder to Solution Explorer, under the Template folder. Name the new folder Layouts. WSPBuilder will make sure that any file we put inside this folder will get provisione
d to the LAYOUTS folder and be available to our site.

In the new Layouts folder, add a new text file and name it AdvancedListCreation.aspx or the same name you used in the NewPage attribute. By adding a text file but naming it .aspx Visual Studio will recognize our file as an ASP.net page even if we are not developing a web solution.

Before we add any content to our new page, however, we want to set up the code-behind file. WSPBuilder has already created a FeatureCode folder for us containing an AdvancedList.cs file. You can use that file, or create a new one, but modify the content as such:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using Argotic.Syndication;

namespace AdvancedListSample
{
    public class AdvancedList : LayoutsPageBase
    {
    }
}

This is all we need for now, we will add plenty of logic to this file later.

Note that we are inheriting from the LayoutsPageBase. This class will give us some free stuff with regards to security for pages stored in the Layouts folder.

Back to the AdvancedListCreation.aspx page we now need to reference our new page code behind class. To do so, add the following code to the top of the page:

<%@ Assembly Name="" %>
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="AdvancedListSample.AdvancedList" %>

Note that Visual Studio will complain about not finding the master file:

Error    1    File ‘~/_layouts/application.master’ was not found.   

It will also complain about the PlaceHolderMain later. You can safely ignore these errors.

The Name attribute of the Assembly tag must be set to the strong name of your assembly. However, since we used a feature with receiver earlier, WSPBuilder has both signed and written the strong name for us. It is stored in the Feature.xml file:

RSS_in_SharePoint02

Just copy the string from the ReceiverAssembly attribute and paste it into the Name attribute of your Assembly tag.

Cool trick, eh? No more using reflector or crafting the strong name from the GAC.

Oh, and important: Delete the ReceiverAssembly and ReceiverClass attributes from the Feature element now, we won’t use them and they will cause our feature activation to crash since we have changed the class.

Adding content and code-behind to the custom page

Next it is time to add some content to our page. For your own scenarios you will of course add different fields, but stick with this example for the moment and get adventurous later, will you?

Add the following code to the AdvancedListCreation.aspx:


   

       

           

           

       

       

           

           

       

       

           

           

       

       

           

           

       

   

                               
                                /Lists/
                               
                           

Yeah, I’m using tables for layout. So sue me, I’m lazy.

In the demo video I also had an updatefrequency field, but I removed it here since I’m not using it.

Switch back to the AdvancedList.cs file, the code behind file for our page, and add the following code to the class. I’ve added inline comments where appropriate:

public class AdvancedList : LayoutsPageBase
{
    protected TextBox tbListName;
    protected TextBox tbListUrl;
    protected TextBox tbFeedUrl;
    protected Button buSubmit;

    protected override void OnInit(EventArgs e)
    {
        EnsureChildControls();
        buSubmit.Click += new EventHandler(buSubmit_Click);
    }

    void buSubmit_Click(object sender, EventArgs e)
    {
        // Get reference to current website
        SPWeb web = SPContext.Current.Web;

        // Create new list and get reference to list and SPFolder
        Guid listId = web.Lists.Add(tbListName.Text.ToString(), "", "Lists/" + tbListUrl.Text.ToString(), Page.Request["FeatureId"].ToString(), 10010, "100");
        SPList newList = web.Lists[listId];
        newList.OnQuickLaunch = true;
        SPFolder listFolder = newList.RootFolder;

        // Add custom data to the SPFolder
        listFolder.Properties.Add("FeedUrl", tbFeedUrl.Text.ToString());

     &#1
60;  // Get feed using Argotic Syndication Framework           
        Uri FeedUrl = new Uri(listFolder.Properties["FeedUrl"].ToString());
        GenericSyndicationFeed feed = GenericSyndicationFeed.Create(FeedUrl);

        // Iterate the feed
        foreach (GenericSyndicationItem feedItem in feed.Items)
        {
            // Create new SharePoint items for each feed item
            SPListItem listItem = newList.Items.Add();
            listItem["Title"] = feedItem.Title;
            listItem.Update();
        }
        // Update the LastUpdated time
        listFolder.Properties.Add("LastUpdate", DateTime.Now);

        // And then save the changes to the folder and the list.
        listFolder.Update();
        newList.Update();

        // Redirect user to newly created list.
        Page.Response.Redirect(newList.DefaultViewUrl, true);

    }

}

What we are doing here is just to add protected properties that match the controls we put in the ASP page. By doing this we can access the controls directly from the code behind.

Next we override the OnInit method and add an event handler to the submit button. That submit button event just creates the list for us and then uses Argotic to get the feed items.

Now, this latter part requires a bit of explanation. First of all, note that we are getting a reference to the SPList.RootFolder. The reason is that we want to store custom data in our list. However, unlike many other objects, SPLists do not have property bags to store custom data. They do have a folder object, though, and the SPFolder objects to have property bags.

So, we are retrieving the RootFolder to store the custom properties, such as feed url and the time when we last updated items from the feed.

I won’t explain the Argotic details, both because they are extremely simple and because the documentation explains everything very well.

Next, feel free to deploy your solution and activate the new feature to see what happens. You should get your list template in the Custom lists column of the Create page.

RSS_in_SharePoint03

You should also see your new custom create page when you click the link.

RSS_in_SharePoint04

You should even get the expected results, a new list containing the items from the feed you entered, when you hit Create list. Still, we want more. We want to be able to update our list on demand.

Adding CustomAction to update feed

What we are going to do now is add that fancy Update feed button to our toolbar.

RSS_in_SharePoint05

The way we are going to do this is by using a CustomAction. CustomActions are great for expanding the existing menus of SharePoint. In out example we will be adding the CustomAction using the elements.xml file and adding our logic to a code-behind file.

First, add a new empty class to your solution. I have called mine AdvancedListUpdater.cs. As always call it whatever you like in your own project.

In the new file, add the following code:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI;
using Argotic.Syndication;
using Argotic.Common;

namespace AdvancedListSample
{
    public class AdvancedListUpdater : WebControl
    {
        protected override void OnLoad(EventArgs e)
        {
            EnsureChildControls();
        }

        protected override void CreateChildControls()
        {
            LinkButton link = new LinkButton();
            link.Text = "Update feed";
            link.Click += new EventHandler(link_Click);
            this.Controls.Add(link);

            Label lastUpdated = new Label();
            lastUpdated.Text = " Last updated: " + SPContext.Current.List.RootFolder.Properties["LastUpdate"].ToString();
            this.Controls.Add(lastUpdated);
        }

        void link_Click(object sender, EventArgs e)
        {
            SPList list = SPContext.Current.List;
            SPFolder listFolder = list.RootFolder;
            Uri FeedUrl = new Uri(listFolder.Properties["FeedUrl"].ToString());
            DateTime lastUpdated = (DateTime)listFolder.Properties["LastUpdate"];
            GenericSyndicationFeed feed = GenericSyndicationFeed.Create(FeedUrl);
            foreach (GenericSyndicationItem feedItem in feed.Items)
            {
        &#16
0;       if (feedItem.PublishedOn > lastUpdated)
                {
                    SPListItem listItem = list.Items.Add();
                    listItem["Title"] = feedItem.Title;
                    listItem.Update();
                }
            }
            listFolder.Properties["LastUpdate"] = DateTime.Now;

            listFolder.Update();
            list.Update();
        }

    }
}

The CreateChildControls method adds two controls, a linkbutton and a label, and attaches an event handler to the linkbutton. The label is updated with the LastUpdate property of the root folder of the current list. This is the property we stored when we created the list and will be updating when we update the feed.

The link_Click handler gets a reference to the current list (using SPContext.Current.List) and gets the SPFolder object of that list. We then, similarly to the creation process, iterate through the items. We only update items that have been published after the last update time, however, do avoid duplicates. You might want to add better logic for this.

Yeah, and you do want to add error handling. I haven’t here. You must add error handling. For crying out loud: ADD ERROR HANDLING!

Final step is to add the actual CustomAction in the elements file. Open the elements.xml and add the following code:


  ControlAssembly=""
  ControlClass="AdvancedListSample.AdvancedListUpdater"
  RegistrationType="List"
  RegistrationId="10010"
  Location="ViewToolbar"
  Title="Update Feed"
  Sequence="400">

In the ControlAssembly, add the strong name of your assembly, the same string you added to the top of the ASPX page.

Notice that since we are using the ControlAssembly and ControlClass attributes we get code-behind logic. That is the logic we added in the AdvancedListUpdater.cs just now.

Build, deploy, and test!

If everything works as expected: Great, you’ve been good.

If you didn’t get the expected results: Retrace your steps. Or, send me feedback about what didn’t work, at furuknap<[at]>gmail.com or as a comment and I will be sure to help out if I can.

Or, you can download the entire solution from here

.b

Pin It