Archives

Archives / 2005 / December
  • Using VS2005 with SharePoint

    Hopefully everyone is happy and back at work and now eating leftover turkey and stuffing for the next few weeks. I know I am. The entire crew was over for the holidays yet the fridge is still full of goodies. Hmm, wonder if that veggie tray can keep for a year in the fridge?

    Anyways, with the release of VS2005 and the recent service packs for SharePoint there is still lots of confusion over building applications and web parts with VS2005 and what works and what doesn't. As there is confusion, it must mean the information out there isn't clear enough for people to understand. In my infinite wisdom I figure why not add another log on the fire so hopefully this post will either make things as clear as mud, or really leave you scratching your head.

    Getting Started
    First off, you must have the .NET framework (version 2.xx) installed on your server (and your dev envrionment if you have one) for all this to work. Before you go off and do that (if it hasn't already been done yet) make sure you have the absolute latest service packs for both Windows SharePoint Services and SharePoint Portal Server. Okay? Great. Now you're ready to rock.

    Building .NET Applications
    Obviously, with ASP.NET 2.0 installed and running on the server you can build a regular web app using 2.0 no problem. You can use any part of the new 2.0 framework like new controls, the membership provider, the sitemap, etc. but you cannot use System.UI.WebControls.WebParts (see below). Things to check on your setup:

    • Make sure you exclude the path to the application (the name of the virtual server) in your SharePoint configuration, otherwise it'll think it's part of the SharePoint system and try to do evil things to your app.
    • Make sure IIS is using 2.0 of the framework for your app. You can check this in the IIS manager. Right click and they'll be a new tab for setting the ASP.NET version on that virtual directory.

    Building Web Parts
    Here's where things get tricky. First off, forget about using the System.UI.WebControls.WebParts namespace or inheriting from that WebPart class. Those type of WebParts (very much the same as SharePoints) have their own manager and tie into various parts of the framework and the support just isn't there yet (as far as SharePoint goes). When V3 rolls around you'll be able to build WebParts using this framework and the ASP.NET 2.0 WebPart will be almost identical to the SharePoint WebPart class.

    Next is building SharePoint Web Parts (referencing the 1.1 assembly) with VS2005. It can be done but takes a little work. As there is no 2.0 template yet, you'll either need to have VS2003 hanging around to build you a skeleton Web Part or keep a blank one handy. In order for the web part to work with WSS you'll need to go into the site in IIS and ensure that the website is using ASP.NET 2.0. You will also need to use the stsadm forceupdate option to force SharePoint to perform the update (after you flip the website over to use 2.0), the command is:

    cd /d %commonprogramfiles%\Microsoft Shared\Web Server Extensions\60\Bin
    stsadm -o upgrade -forceupgrade

    You should do an IISRESET just to make sure everything is applied. Now development of Web Parts is the same as ASP.NET 1.1 except you can use .NET 2.0 features (like Generics, Anonymous Delegates, ObjectDataSource, etc.). The most important thing to note here is that you can ONLY do this with Windows SharePoint Services. SharePoint Portal Server has to run on ASP.NET 1.1. as 2.0 isn't supported. SQL 2005 and other "2.0-ish" features are supported, but the runtime isn't which means you can't compile a WebPart and have it work in Portal Server. A good reference as to what works and what doesn't based on service pack installed can be found here. Bottom line is that if you want to build ASP.NET 2.0 Web Parts using VS2005, you can only do it on a Windows SharePoint Services (WSS) site install (not SPS with WSS).

    Now if you want to build a 1.1 WebPart on SharePoint Portal Server that talks to an ASP.NET 2.0 application, that can be done because in IIS you can set the web site to use ASP.NET 2.0 and have the Portal Server WebPart communicate (through web services, remoting, etc.) to the 2.0 web part. It takes a little work, but if you keep your Web Parts to only presentation (which is what they're supposed to do) then there's nothing to say you can't have a 2.0 Business Layer talking to a 1.1 Web Part on Portal Server (using all the features of SPS like single sign-on, enterprise search, etc.). SharePoint Portal Server doesn't care that .NET 2.0 is installed on it, it just can't be targetted to use it.

    As an alternative option, you can use the Son of SmartPart (I think Jans hates that name). This little doofer uses the 2.0 framework and will just suck up little ASP.NET user controls and render them out via a Web Part in SharePoint. So yes, you can build something that looks and smells like a Web Part using .NET 2.0 and running on SharePoint right now but:

    • You must have the .NET framework 2.0 deployed to your server
    • You must be running the latest Service Packs for all products installed (SPS if present and WSS)
    • You can only deploy 2.0 assemblies to a WSS only setup, not WSS running under SPS (since you can't split the IIS virtual server into two and it has to be targetted to 2.0)

    That's a lot of musts but it can be done. I'm sure there might be other ways you can do it (and I hope I didn't miss anything), but for other ways you'll probably have to do some magic incantations and sacrifice a small marsupial to get it working.

    Hope that helps.

  • Merry Christmas All!

    No fancy "Twas the night before SharePoint" post. Just well wishes for you and yours during this festivus. Enjoy and be safe!

  • Tired of the boring old Quick Launch?

    Then try Bob Mixon's replacement Quick Launch! This is tres cool so thumbs up from me (and I didn't even know he was working on this). Not only does it look exactly like the default Quick Launch (meaning you could go and replace it on everyone's site without them knowing, sneaky huh?) but check out some other cool features he's added:

    • The ability to turn any set of lists on or off. So if you chose to not display Surveys, simply turn it off.
    • The ability to display separation lines below the grouping headers.
    • The ability to display an Actions section with access to manage site settings, users, content, and alerts.
    • The ability to display icons next to items
    • And, the best of all features, the ability to dynamically add any items to the quick launch bar (with your own groupings) through a standard SharePoint list.

    You totally have to check it out here. Go. Go now. What are you waiting for?

  • Hey Developers, Plugins for SharePoint Wanted!

    If there's one thing I really love, it's SharePoint (well, sometimes). And Plugins. Those cute little furry dll files that you drop into a directory and make programs do cool things. So why not combine the two?

    I'm putting together a SharePoint Admin Host tool that's driven entirely by plugins. How so you ask? Well, it's pretty simple. Using my SPS Wrapper classes and connecting to a SharePoint server via web services I have a host that will let you do pretty much whatever you want against the SharePoint information. A Plugin manager inside the host will look for dlls and load them at runtime. They also expose the wrapper classes to your plugin, so you can do things against SharePoint without doing any heavy lifting.

    The Host does two things for the plugins. First it connects, via web services, to the server and builds a tree of all areas, sites, lists, etc. (dynamically as you expand nodes on a treeview of your portal/wss site). Second, it communicates the selected node(s) to your plugin as a fully typed class that you can interact with. All without SharePoint on your client desktop.

    What can you do with this? You can build plugins for it silly. So lets say the user fires it up and connects to his portal then selects a few areas. You can write a plugin that creates a subarea (based on available templates from the portal) under each of the areas selected. Or the user selects all the sites in the tree. You can write a plugin that applies a theme against all of them in one fell swoop. Want to create client side reports from SharePoint data? No problem. It's all there, waiting to be unlocked. You just have to write the guts.

    So what do I need? I need developers to write plugins. Email me and I'll hook you up with a development kit. It includes one PluginInterface.dll that you'll reference in your assembly and derive your plugin classes from the public interface available. An API document on writing plugins with all the methods you need (there are only a few) and classes that you can use to access SharePoint information from. Sample plugins with source (C#). A lifetime subscription to Rice-a-Roni, the San Francisco treat, and the hosting program that will run all this junk (plus my undying support and other good stuff).

    Just send me off an email with your info, what plugins you're thinking about writing, your social security number, the number of Senators in Congress today, and anything else you can think of. I'll get you started and we'll look at forming a small community for this where people can download new plugins as they become availalble (much like the add-on community that exists for something like say FireFox).

  • Important SharePoint fix Available Now! Get them while they're hot!

    Well, important if you're Japanese and have a problem with the translated text for the Later than filter criteria field and for the Earlier than filter criteria field being switched. Here's your hotfix.

    Don't know how many Japanese readers I have (I wasn't able to get into the Google Analytics beta fast enough) and how many of those run SharePoint Portal Server but for those that are there and care, this ones for you!

    Isn't technology wonderful?

  • Use the Force Luke!

    A bit of a sidetrack as I was planning to blog with pics on the mod for putting your image above the menu bar (I still don't agree with Heather that her solution works, nyah) so I will get to that, but later.

    I did want to mention a couple of things about posting questions about SharePoint (in newsgroups, forums, wherever). First, please read your posts before you click the big send button. I don't know how many times we sit there trying to decipher a request when there's a typo in it. Really. It's quite simple. Proof read your post (being a blog, question on a forum, or an email) and make sure it sounds like it makes sense. Okay, maybe I'm guilty of this on my blog but like I said, there have been more times than I can remember where I've been reading the newsgroups and questions are being thrown about that make absolutely no sense. Relax, take your time, and read your own scribblings before you inject them onto the world. Gonzo journalism is great, but you need to master it before you can fire off posts without editing. Seriously. It will expedite the process of getting an answer if the guy on the other end of the line knows what you're asking.

    Next is the big one. Recently there's been a pretty meaty selection of posts and emails with people asking if SharePoint can do this or SharePoint can do that. Some don't even ask if the tool can do it but rather go to the big, dark place of "I have to implement x using SharePoint or I'll get <fired | castrated | exiled | etc.>". Guys (and girls), hate to break it to you but SharePoint is not a shape-shifting, set your phasers on stun, beast from 20,000 fathoms tool that is all things to all people all of the time.

    Yeah, drink that in for a minute.

    It has custom lists, document libraries, it's web based, can version documents, has security, audiences, single-sign on, blah, blah, blah, blah, blah, blah. However it does not: make you dinner; vacuum your living room; teach your 7 year old tennis; play ball with your dog; impregnate your cat; dust your buffet and hutch; talk to your Xbox 360 (well, maybe); or generally do stuff it wasn't designed for. Yeah, it's a great tool and one that is very powerful but you, as an implementer of SharePoint need to know the design boundaries of it and stop ripping it apart to do your bidding. You wouldn't use your light sabre for grating cheese would you? So stop making your SharePoint deployment do crazy things. Yes, it can do it but should it? Probably not.

    Give you a few examples. We all know that lookup lists are kind of clunky. The can only use lookup values from the current site, can't use calculated fields to lookup from, and they can't filter values in the lookup. These are design limitations. Live with it. Can you achieve these things? Sure. Write a wrapper to simulate the ListFormWebPart (i.e. rewrite it) and you make it do whatever you want. Write some funky JavaScript (like SharePoint doesn't have enough of this already) to filter your lists, call a web service, and otherwise rewrite the page on the fly. Create your own ISAPI filter to do what SharePoint doesn't do.

    C'mon people. Give your head a shake. If the answer to your problem isn't already in front of you then maybe it's not something that you should try to do. There's being creative, then there's just bastardizing the tool to make it do something. That's not creative, it's just plain dumb. Does Microsoft Word do a great job of editing information that might be better suited for a spreadsheet? Then use Excel. Use the right tool for the right job.

    Custom Web Parts can give you ultimate flexibility, but like anything they're expensive to develop. Yeah, even that 10 line Web Part to hide something on the page is 10 lines you have to feed, maintain, and grow. Update when the next version comes along. Add to version control. Document so when you get hit by a bus the next guy knows what it's used for. And so on. Development is fun but expensive so ask yourself if you can't solve a problem with an OOTB solution maybe adjust your problem (or it's parameters) so that it fits the technology you have to work from.

    Web Parts will give you what you need, but at a price and too much of a good thing might be too much on a Web Part Page. 20 Web Parts on a single page, while they're all doing "important stuff" might take 30 seconds or so to render per person (as it's fetching data from all over the planet). Having this as your home page in your organization might just bring down your SharePoint server. Is this a design flaw or a launch problem? It's responsible development that you need to look at holistically and not just from the "I need x to solve my problem" type of approach.

    In any case, you can achieve great things with a great tool but like any tool, you need to use it responsibly and with malice aforethought about what you're doing. Before you go off to build the uber-web part that will deliver everything under the sun, ask yourself if you really need it or can you leverage what you already have.

    Software development is full of compromises and sometimes you just have to say no. No to the communications person screaming that they want their image on the right instead of the left. No to the HR person yelling that they want the form to dynamically change based on the users gender and way that they're sitting in the chair. No to the finance guy that wants to use SharePoint as his SAP replacement and do the entire corporations payroll with custom lists and 8,000 lines of JavaScript for the business calculations.

    Trust me, you'll be better off in the long run.

  • Hurray for Stubbs!

    Thank the maker that Stubbs the Zombie, the only game in which you become the Zombie and get to do uber-cool things like eat brains and possess people (something I sometimes need to do at work) is now officially supported on the Xbox 360 (previously it wasn't listed on the backward compatible list). Very cool.

    Of course now there's the issue of me finding a 360 in Calgary, which is pretty much impossible. The Best Buy/Future Shop guys say "well, show up in the morning and maybe we'll have one". Uhh, no. Why can't I just walk in and get one? I mean, it's not like there's no demand (yeah, yeah, grumble, grumble, supply, supply). Bah, humbug!

  • Adventures in CSS: Putting a banner image above the menubar in WSS

    I recently did a theme on a site and the desire was to have the WSS sites look similar to the Portal areas. I don't know how many times I've seen this kind of request and it usually leads to all kinds of having to edit tons of pages directly, doing funky things with default.aspx, etc. Here's the styles you need to override in your theme to get a banner above the WSS menubar. The trick is all done through CSS by positioning the image and using offsets, so this shows up on all pages (including the admin pages).

    .ms-banner a {
     height: 100%;
     padding-top: 54px;
    }

    .ms-bannerframe img {
     display: none;
    }

    .ms-bannerframe td {
     padding-left: 8px;
    }

    .ms-bannerframe, .ms-grheaderbackground, .ms-stormefree {
     background-image: url(sitelogo.jpg);
     background-repeat: no-repeat;
     border-bottom: 0px solid;
     height: 72px;
    }

    A bit of explaination of the tags here. Heather Solomon had an excellent posting here about doing this by just overriding the .ms-bannerframe, etc. styles. The problem however is that if you want the effect of the menubar below the image, this doesn't work. There's a hard coded valign=middle in the default.aspx page that will always override any CSS style you apply to it.

    .ms-banner a
    Unlike the portal menus (where there's a style for every frickin' menu item, selected and unselected) the WSS menu is wrapped up in a single <A> tag. We override this to a) set it to 100% and b) push the text down towards the bottom of the <TD> that surrounds it. Why set it to 100% height? If we don't, the padding value doesn't work.

    .ms-bannerframe img
    This is overidden to hide the logo.gif image. As we now have a <TD> that is much larger than it was, the image gets stretched and looks silly so overriding this tag hides it.

    .ms-bannerframe td
    With the image hidden, it still has a <TD> that it lives inside so we need to push the <TD> over so the menu text has a bit of an indent.

    A couple of things to note. Change the sitelogo.jpg to whatever you want here. This should be an image that stretches across the page, but can be partial. Just use the background-color (not specified here) to be the background and blend your image into it. You'll have to change the height and offset values here to match your image. Also this CSS will hide the default logo.gif image that appears to the left of the menu. Why? Because this trick requires you to pad the <A> tags so it pushes them down onto the menu bar (which really is the background color) so the logo.gif image gets stretched as well. There may be a way to do this using margin-top or something which will push the text down without making the <TD> tag the full height, but I haven't tried that yet.

    Also a friend turned me onto a fantastic CSS resource here. It's a cheatsheet for CSS, but is very handy so if you're mucking about with Themes and Styles, check it out. Cheers!

    UPDATE: I've updated this blog to be a bit more clear on why the tags are doing what they do. I'll follow up tommorow with some screenshots as a picture is worth a few hundred lines in a blog somewhere.

  • SharePoint Builder and ClickOnce

    I've been pretty swamped trying to get Life 1.0 going and lots of little pet projects finished up. One of which is my SharePoint Builder tool, a visual xml builder editor that will let you modify ONET.XML and SCHEMA.XML files using properties and such (rather than text editing). It's been a long time trying to get it going but it looks like the next week or so will see the release to the testers (please no more requests for testing as I have a ton of people already).

    A couple of things about the project. I'm going to be deploying it via ClickOnce and it will be using the .NET 2.0 Framework. So far the tests are good. You just go to a website and click Install and down it comes. I've even tested it with a box that didn't have .NET 2.0 on it. Since I flagged the app to have this as a pre-requisite it just downloaded and installed it for me, then continued installing SharePoint Builder. The app will check online for new versions (if you're connected) and let you know of the an update. You'll have the choice to download it or not but it means I'll have 0-issues with keeping the program up to date. I think this is proabably the bigged and coolest feature I've found in .NET 2.0. I mean, I just publish it from the IDE and next time you launch the program you'll get any changes. No more having to send out emails to people. Of course we'll still be doing things like posting change logs and notes to let everyone know, but it's a very slick feature to have. Hopefully the testers will be kind to me as this will be my first ClickOnce deployed app. Lets see if everything goes well.

    I'll be posting new screenshots and feature information on the tool over the next week as things wind down with Christmas and all. Should be a fun week. Hope you're curled up in front of a fire somewhere warm (or some such silly thing that people do on Christmas).

  • Site Settings, Apply Theme, Apply, Lather, Rinse, Repeat

    Applying themes to WSS sites is sometimes like giving birth to a duck-billed platypus on a snowy day in the middle of springtime (can't wait to see the Google search referrals from that statement). I've blogged a little about this before so ignore my rant if you've heard this song already. If all you want to do is select Site Settings | Apply Theme then you're golden. If, however, you're a developer and you're trying to test your custom theme out you need to be aware of a few things.

    First, just copying a new THEMES.CSS file into your theme directory in the 60 hive and hitting F5 in your browser isn't going to do Jack. The theme is cached and worse yet, it's part of the site and lives in a virtual directory. In other words, there's no physical place it resides so when you get it served up to you in your browser, you're getting a cached version that's actually coming out of the ASAPI filter that SharePoint is controlling and serving the page through. Open a site in FrontPage and you'll see a themes directory in the navigation tree but this physically doesn't exist. Look at the source code for a page and you'll see something like this:

    <link rel="stylesheet" type="text/css" id="onetidThemeCSS" href="/sites/sitename/themes/mytheme/mytheme1011-109.css">

    (note the name of the them varies based on language, etc.). There is no themes/mytheme directory physical directory yet you can enter that url and up pops the mytheme1011-109.css file. Again, all the magic of the ISAPI filter at work.

    Second, as a developer, it's a PITA to go to Site Settings, Apply Theme to Site, Apply, lather, rinse, repeat. Not only that, you can't simply re-apply the same theme to your site. You have to apply a different theme to the site, THEN apply your custom theme to see the results. This is 600 or so clicks for any change you make to your theme. Needless to say, theme development is like any SharePoint development. Painful and slow.

    Okay, a couple of tricks to do to make this less cumbersome and hopefully will make your theme development a little easier on your grey matter. First, get your CSS editor installed on the server. I personally use TopStyle as I can visualize things in the editor, it reformats my output in a nice way (after you've been screwing around with all kinds of styles your CSS file gets a little messy) and it's a pretty slick product overall. Second, it's handy to create a web part to (somewhat) automate the process. Clicking through and going onto the Site Settings page over and over again can drive you to going postal.

    Let's create a super-simple web part with the Web Part Template starter in Visual Studio. Add a control (a button or hyperlink will do) to the web part and create a Click event for it. In the click event what you want to do is:

    • Get the SPWeb object for the site
    • Apply the default theme to the site
    • Apply your own theme
    • Redirect to the current page

    So how do we do this? Simple:

    protected override void CreateChildControls()
    {
       btnApplyTheme =
    new Button();
       btnApplyTheme.Text = "Apply Theme";
       btnApplyTheme.Click +=
    new EventHandler(btnApplyTheme
    Click);
    }

    private void btnApplyTheme_Click(object sender, EventArgs e)
    {
       SPWeb web = SPControl.GetContextWeb(
    this.Context);
       web.ApplyTheme("none");
       web.ApplyTheme("MyTheme");
       this.Context.Response.Redirect(web.Url.ToString());
    }

    The secret here is to call the ApplyTheme method twice. First with a parameter of "none" which will set it to the default, then with the string for your theme (whatever the name of the folder is in your THEMES directory). This will flush the page enough to reapply it, otherwise just calling it with your own theme won't work.

    Okay, install this web part onto your site (the default page will do fine) and open it in the browser. Open up the THEMES.CSS file in your favorite CSS editor and start editing. Save then click your button on your Web Part. Voila. The theme is applied with one click (almost).

    There's one problem with this. While it does work, you still need to hit F5 to refresh the page fully and see your changes. Why? Because information is still cached and you need to flush it. I have tried everything to try to do this in code but can't. Mainly because its a client side thing, but also you can't process the ASP.NET control's event AND call say an "onclick" JavaScript (like location.reload(true)) at the same time. At least I can't find a way to do this and I've tried things like setting the HttpResponse to expire, flushing the Cache with SetNoStore(), etc. Nothing seems to work but at least this is a two-click solution rather than 6.

    If anyone has a solution to the refresh problem, please feel free to email me or (preferably) post it in the comments. Also if you do theme development (Shane?) maybe you have some tips to share on how you do it. Hopefully this helps you with your theme creation.

  • Keeping your head above you while everyone else is losing theirs...

    A lot of times I see emails and posts that start like this:

    "I have to redesign our entire intranet using SharePoint..."

    or better yet:

    "We just bought a copy of SharePoint and now I'm being told I have to become the expert"

    And the best part (that your manager or the powers that be say to you right after they say the above):

    "Now that you're the new SharePoint expert what will our enteprise portal that you're delivering next week look like?"

    Guys, this is like someone coming to you and handing your a <insert foreign language here that you don't recognize> manual for programming a <insert device you've never even heard of or knew existed before>. Trust me. You will live in a world of pain and hurt and anguish and die a thousand deaths if you're tossed into this situation. Be afraid. Be very afraid.

    Okay, now that the melodrama is over, if you really do find yourself in this position here's a few things to keep in mind which might let you keep your sanity:

    • Rome wasn't burned in day. Even if you're the most incredible web designer or sysadmin or network guy, don't promise that you'll bone up on this stuff overnight and build Tweedledum his vast empire. SharePoint is a hydra with heads growing out of places you wouldn't believe. Every time you cut one off (or even consider doing it) 3 more grow in it's place. You CAN master it, but this is not a "Teach yourself SharePoint in 24 hours" type thing. It's a long term committment if you want to do it right. And you won't get it right the first time so don't kick yourself when something silly happens.
    • Read, read, read, then do some more reading. There are huge tracks of blogs out there (last count over a hundred of us) that have something useful (and not so useful) to say about SharePoint. There are some great starter books. Get out there and buy them. Again, tell your manager or the powers that be that you'll be locked away reading for awhile. That may be difficult for some to swallow, but again SharePoint is big and can be unruly if you dive in without knowing how deep the water is. Just breathe, relax, read a little, and wade in slowly.
    • Virtualization. Get yourself a copy of Virtual PC/VMWare/etc and some software. There are eval versions (120 day) of Windows 2003 Server and SharePoint so setup a machine and try them out. Install them using the Administration Guide to walk your through it. It doesn't take long (half a day for someone who's never done it) and you'll get used to how things work and fit together. Get your feet wet. In a virtual environment, it doesn't matter if you blow up the server. Just choose the previously saved undo disk and reboot. This will be a great experience without you killing your network as you try to build a giant infrastructure on your first day.
    • Don't be afraid to ask. Really. There are no stupid questions (well, okay depends on what day you ask me) but if you have a concern or something cry out. Jump onto the many resources and just scream, but be descriptive. Yelling at the top of your lungs might get you noticed, but if you can't command the English language and form coherent sentences, it'll be hard for us to know what you want. In any case, the help is out there but there are two caveats to that. First, the answer might not come quickly. While the newsgroups and that thing called the interweb is a cool place to get porn from, we're not all living and breathing there day and night (some are, but ignore them for now). So posting a message on a blog, forum, or newsgroup might not get an answer for a few days even. You need a little patience. Second, your question might not be answerable or you might not like the answer. For example if you say you just HAVE to have things setup a certain way but SharePoint doesn't work with that configuration. Well, there might be no answer except to either reconfig or not use SharePoint. So be prepared to adjust and adapt. SharePoint is certainly no silver bullet and might not do everything your want (or the way you want it). Be prepared to accept the things you cannot change (and scream about the work need to change the ones you can).

    Not sure if any of this helps, but I thought I would just spend a few minutes to spread some cheer as we slip into the horribly crowded malls and freezing weather that is Christmas. And what's SharePoint without pain. Easter maybe?

  • Renaming the "Web Part Page"

    Don't you just hate it when you create a document library to hold a bunch of custom web part pages, but then they all show "Web Part Page" in the browser title? I was messing around with lookups (to create a web part page menu system) and noticed that the only lookup field that was available was a field called "Title". Hmm, this wasn't the filename and wasn't in any view that I saw or property when you edit the page.

    Sure enough, there's a column in a document library called "Title" and when you base the template for the library on Web Part Pages, the default when creating new documents is, you guessed it, "Web Part Page".

    Patrick blogged awhile ago about changing the title here but there was always a belief that you had to edit a WPP in FrontPage (thus unghosting it) to change the real title (and thus the browser window title). Just follow these steps to do it without invoking the great white ghost (Office 2003 client is required here, see update below about the ghosting part):

    1. Create your document library and base it on the Web Part Page template (or use an existing one)
    2. Go to the "All Documents" view of the library and click on "Modify settings and columns"
    3. Select the "All Documents" view to modify it
    4. Click on the "Title" column to include it in the display
    5. Optionally change it's position from last to first (or second, or third, or...)
    6. Go back to the "All Documents" view and you'll see the new "Title" column (which should show all documents with a title of "Web Part Page")
    7. Click on "Edit in Datasheet" in the toolbar (this is what you need the Office 2003 client for, the Title property doesn't show up on the Edit form page for the library)
    8. Now change those ugly "Web Part Page" titles to something useful and meaningful to you and your loved ones 
    9. Launch one of the changed pages and bask in the glow of your accomplishments

    Simple but effective.

    Update: Thanks to comments from Daniel McPherson, I did some digging and testing. Turns out that the page does go unghosted when you edit the Title column. Check out Marice's posts here and Daniel's post here about it. Bummer. However at least this does provide an easier interface to change the title rather than cracking open the page in FrontPage to do it.

  • Deconstructing the QueryProvider

    SharePoint search capabilties are pretty powerful but when you're dealing with clients, more often than not, you need to build your own search mechanism because the client wants a custom page to look a certain way or they don't want to train users in how to use the advanced search (yeah, it happens) so I thought I would take you down the QueryProvider lane for a bit. Some of this information is documented in the SDK (and repeated here), however you need to sacrifice a small marsupial or skink to the great one if you want to actually try to pull it together to make any use of it. Hence the reason for this blog.

    We'll start with the QueryProvider, a simple class that you use to issue searching against SharePoint. The creation of it is documented in the SDK but briefly you build one like this:

    TopologyManager topology = new TopologyManager();
    PortalSite portal = topology.PortalSites[new Uri("http://servername")];
    PortalContext context = PortalApplication.GetContext(portal);
    QueryProvider queryProvider = new QueryProvider(context.SearchApplicationName);

    Note that the server name in the PortalSite creation must be the NETBIOS name of the server, not "localhost" because that won't work.

    Once you have your QueryProvider created the challenge of actually getting a query working is the main cause of anyone tearing their hair out. Why? Because a) the syntax is SQL-like, but not quite and b) trying to do a complex query will blow your head out the back of your skull. I could blog for days just on all the options in the Search query but there are 3 main groups that you need to worry about.

    SELECT
    This is the basic SELECT statement you would make in SQL and will return the fields you want in your output. Examples are "DAV:href" and "urn:schemas-microsoft-com:office:office#Author". URNs must be specified as delimited identifiers, enclosed in double quotation marks. You have to have at least one field so include something like "DAV:href" or something that will be there for any type of object. Otherwise, your query is going nowhere. Any other fields you add are up to you and will be returned in the DataSet once we execute the query. So at a minimum we're going to have the SELECT statement look like this:

    SELECT "DAV:href"

    It's also good to put in the "urn:schemas.microsoft.com:fulltextqueryinfo:sdid" column so you don't get an empty DataSet returned if there's no match in your query.

    FROM
    Okay, now that we have the fields we want, we have to tell SharePoint where we want to select from. This is generally two things:

    • Portal Content (i.e. stuff that exists in the portal)
    • Non-Portal Content (i.e. you know what this should be)

    That scope will cover off everything that's in SharePoint and everything in your WSS sites, the Profile Database (for searching people) and other goodies (like if you have your SharePoint server crawling a file share or something). You specify it like this:

    FROM ( TABLE PortalContent..Scope() UNION ALL TABLE NonPortalContent..Scope() )

    WHERE
    Finally we need to specify the WHERE clause, which filters the results of what we specified in our SELECT statement (otherwise we would get the entire contents of the portal coming back).

    There are a couple of ways of specifying search criteria. First you can just specify the column name and matching value:

    WHERE ("DAV:contentclass" = 'urn:content-class:SPSPeople')

    This will give you results of all the profiles in SharePoint. Another way is to find text using the CONTAINS or FREETEXT predicates. Here's a simple example:

    WHERE Contains('computer')

    This finds anything with the exact word of "computer" in it. CONTAINS allows you to use a wildcard for multiple matches, but only for prefix matching so this will work:

    WHERE Contains('computer*')

    This won't:

    WHERE Contains('*computer')

    Here's an example that only finds matches where the FirstName property of the users profile matches "gary".

    WHERE Contains("urn:schemas-microsoft-com:sharepoint:portal:profile:FirstName", '"gary"')

    This uses the column name (the first parameter to the Contains predicate) which tells us to only compare against the FirstName column. You can use "ALL" or "*" if you want to search all columns. The CONTAINS predicate is better suited for "exact matches, in contrast to the FREETEXT predicate, which is better suited to finding documents containing combinations of the search words spread throughout the column.

    You can also combine the search values (like looking for people with Gary as their first name) with the content-class so, for example, add this to your where clause to only search People records (rather than documents or sites by Gary):

    WHERE (Contains("urn:schemas-microsoft-com:sharepoint:portal:profile:FirstName", '"gary"')
    AND
    ("DAV:contentclass" = 'urn:content-class:SPSPeople'))

    Again, basic SQL syntax so remember to get your quotes, double quotes, and brackets correct as that's a common mistake trying to debug a query. There are other SQL statements that you can use here like ORDER BY (to specify how the returned values are sorted) and RANK BY. Additionaly you can also weight words using the IsAbout type, and other neat tricks like "this" NEAR "that". Check out the SDK Topic "General Query Language Information" for all the dirt. This posting is just meant to get your started.

    TOOLS
    There are some great tools out there to help you with building queries. One of them is the SharePoint Query Builder Tool. Invaluable as it will look at your SharePoint server, grab all the content sources and properties and build the SQL for you. You can then just use this as-is in your code or update it to accept values from say a TextBox control in a Web Part. Very handy to explore the Search features of SharePoint and see what works (and what doesn't) so I recommend you getting this. It's available free from here on GotDotNet.

    EXAMPLE
    Here's a simple example that gives you the bare minimum. It searches the Profile directory for people with first name of "John" and returns the link to the users MySite page.

    SELECT
    "DAV:href"
    FROM
    ( TABLE Portal
    Content..Scope() UNION ALL TABLE NonPortalContent..Scope() )
    WHERE
    Contains("urn:schemas-microsoft-com:sharepoint:portal:profile:FirstName", '"John"') AND
    ("DAV:contentclass" = 'urn:content-class:SPSPeople')

    Now take this query and call QueryProvider.Execute(query) with it (where query is the query above). The result is a DataSet but since I can't show you a DataSet, here's the result in XML (from the Web Service, but same results either way):

    <ResponsePacket xmlns="urn:Microsoft.Search.Response">
    <Response domain="QDomain">
    <Copyright>Microsoft (c) Office SharePoint (tm) Portal Server 2003</Copyright> 
    <Range>
    <StartAt>1</StartAt> 
    <Count>40</Count> 
    <TotalAvailable>1</TotalAvailable> 
    <Results>
    <Document xmlns="urn:Microsoft.Search.Response.Document">
    <Action>
    <LinkUrl fileExt="aspx">http://spsdev/MySite/Public.aspx?guid=3751B6E1-34C0-4B93-963B-B827BCFDF8A1</LinkUrl> 
    </Action>
    <Properties xmlns="urn:Microsoft.MSSearch.Response.Document.Document">
    <Property>
    <Name>DAV:href</Name> 
    <Type>String</Type> 
    <Value>http://spsdev/MySite/Public.aspx?guid=3751B6E1-34C0-4B93-963B-B827BCFDF8A1</Value> 
    </Property>
    </Properties>
    </Document>
    </Results>
    </Range>
    <Status>SUCCESS</Status> 
    </Response>
    </ResponsePacket>

    You can take this and use XSLT to format it. If you're using the DataSet, just bind it to a grid and you're off to the races. A more advanced blog would feature connecting this to the Search Results web part, but I'm not advanced and it's late on a Sunday evening so you should be able to take this and run with it, building your own queries and getting the results you want.

    To get to really understand what parameters you need, you'll need to check out the mapped properties in your search. Just crack open your portal and got to the Manage Properties of Crawled Content page (http://servername//_layouts/1033/Properties.aspx). This will show you the names of the properties that have been brought over from ActiveDirectory (for people) and ones that have been crawled from documents and content (like everything under urn:schemas-microsoft-com:office:office for Office documents).

    Also you might want to consider building a class or some helper methods to build your queries as you can get quite complex. Imagine if you were searching for all employees with a first name of "John" who reported to a manager named "Bob" and had a phone number starting with "416". Yeah, it can be a pretty ugly SQL statement at the end (and if you do manage to create one that complex send it to me so I have something to scare the kids next Halloween).

    Have fun!

  • Adventures with CEWP: The Real-Time Clock

    Todd Bleeker lives and dies by the Content Editor Web Part (CEWP) and so do I. This is such a great little thing to prototype ideas through, create small scripts to show what can be done and get solutions up and running quickly and easily before you break out the C# project. In fact, you can also do some amazing things with it by overriding styles and writing simple JavaScript in it.

    Recently someone asked how they would go about putting a clock on their site. You know, the real-time one you see ticking away on peoples sites. There are a gadzillion of them out there in JavaScript so why not chuck one into a CEWP to create a clock. Sure enough, CEWP is your friend and always comes through.

    You can check out (and use for your own nefarious devices) my JavaScript Clock Web Part here on my SharePoint playground site. Thanks to Maxx Blade's Clock for the JavaScript. Enjoy!

  • Plumbers @ Work, MSDN Flash, and Community Radio oh my

    I'm really happy to say that our podcast show about .NET, Plumbers @ Work, is featured in the latest MSDN Flash. If you haven't subscribed to MSDN Flash, I encourage you to do so. It puts you in touch with the .NET community, user groups, and much more (yes, another shameless plug for another mailing list to clutter your inbox).

    Another cool thing is that we have our very own tab on the Community Radio at MSDN Canada page. Very nice. Not sure if the RSS feed on that page works, but you can click on the Listen Now icon to listen to our first show. We're done taping and editing the second show and will have that online shortly so watch for that soon on our Plumbers @ Work site.

  • Kong and The Killer SharePoint App

    I recently picked up the 2-Disc Special Edition of King Kong. This is the original 1933 grandaddy of them all, not the crappy 1976 POS from Dino De Laurentiis. It's a great disc set for those that are fans of the genre and like this kind of stuff. What was really special was a lost sequence from the film. 

    Back in the first weeks of the films release, there existed a horrifying spider pit sequence. A short sequence after the sailors are felled from the log by Kong and fall into a pit. There in the pit, prehistoric spiders and insects devour the expendable crew. After a few viewings of the film, people were said to have had fainting spells over the horrifying nature of the sequence. The director, Merian C. Cooper, took the sequence out of the film himself (citing that it didn't flow and the focus should be kept on the great ape). The sequence exists in various treatments of the script, there are a few storyboards kicking around, and in the 1970s a photo emerged of a spider from the lost sequence that never was. To this day, nobody seems to have any restored footage for the part of the film (it's said that Cooper might have actually burned the footage, as he was known to do this).

    Enter Peter Jackson and Weta, the special effects magicians responsible for Lord of the Rings. Mr. Jackson is a huge fan of the original Kong (hence one of the key reasons why he's remaking it, coming out December 14). Just for "fun" the Weta team was tasked to recreate the lost spider pit sequence and patch it into the surrounding parts of the film on the DVD. They faithfully rebuilt original models (using an X-Ray from one of the only surviving models available today) and created new ones (based on sketches by Willis O'Brian for Kong) and engaged stop-motion animation, matte paintings, and other techniques used in the original Kong rather than todays typical computer animation techniques. The result is a sequence that the creators would be proud of, a seamless blend of 1932 footage with 2005 filming and gives the fans one filmakers take on what the sequence might have looked like.

    As we know, SharePoint is a technology platform. It's a platform very much like the special effects world of Hollywood in the early 30s. There are endless possiblities that you can extend and expand from. The problem is that we have yet to have a wizard like Willis O'Brian come along and merge the various capabilities of SharePoint into one entity that will stop us from looking at it as a tool with missing features. Michael Ekegren, in his latest blog, wonders about what a SharePoint resource portal should or could look like and what is it you need to do with a team site? There are web parts out there today and the SharePoint technology has been around and maturing for a couple of years now, yet we're still stuck in the stone ages when it comes to usability and functionality. The landscape out there is still just a simple class of Web Parts that provide us with navigation elements to supplement SharePoints simple UI (something that is addressed with the next release).

    What we're lacking is someone to come along and do what PJ and his Weta team did with Kong and fill that gap with something new, finish what was started so long ago. There must be a bigger and better use of SharePoint than just document storage and lists. Sure there are some "killer" tools like SmartPart which makes building Web Parts a breeze but that's limited to people who build things rather than use them. And yes, the next version will allow you to just drop in user controls and have them "become" Web Parts. With the release of ASP.NET 2.0 and the Web Part framework, we'll have 10 months or so of people building new Web Parts that can then be used in a SharePoint Team Site. Still, there's something we're missing here as we have a toolset that has unlimited possiblities but all we're doing with it is enhancing navigation controls.

    Or maybe SharePoint itself is the killer app, and we're just too close to the trees to the see the big monkey behind it.

  • SharePoint Connections 2006, I'll be there

    You know, I swear to god I thought I did a blog posting on Thursday and Friday this week. Hmm. Maybe the mind is going as I shift into old age mode.

    Anyways, just wanted to let everyone know that I'll be speaking at the SharePoint Connections 2006 conference in Orlando April 2-5. The session information isn't posted yet so I can't say specifically what we have cooked up for you guys, but it's focused on SharePoint (of course) with most focus on the current version, but they'll be some talk of the next release. If the public beta is out by then, we'll be able to incorporate those into demos but otherwise it'll be 2003 focused.

    More information to come later as it becomes available. The early bird registration cut-off is February 16 and you can save $100 on the fee. Check out the official site here for more info.