| Brian's profilePoints to sharePhotosBlogLists | Help |
|
|
2/11/2009 IMPORTANT: Good bye live spaces! Hello Word Press!!!AS OF TODAY, THIS BLOG WILL NO LONGER BE RUNNING HERE! PLEASE UPDATE YOUR FAVOURITES AND RSS FEEDS! After almost a year of using Spaces for my blog (being the Microsoft fan boy that I am, I can admit it) I have decided it was time for a change. This was mostly inspired by the fact that I decided I wanted a more professional blog, and while spaces is fine for a basic blog, there are more powerful tools out there for me, and I chose WordPress as the most suitable for me. Anyway, I have migrated the full contents of this blog to the new address, so eventually I will delete this space but I’ll leave it around for the time being until I’m sure everything is fine. But you should go and check out the new blog and update your RSS feeds!
2/5/2009 How to configure proxy settings for SharePointIf you have a SharePoint site that is sitting behind a proxy and you are using things like the XML Reader web part to access external content, then you need to configure SharePoint to go through the proxy to get the data. Now fortunately for us SharePoint is based on ASP.NET 2.0 we can configure the proxy in the same was as a regular .NET web app – through the web.config file. Here is a sample: 1: <system.net> 2: <defaultProxy useDefaultCredentials="true"> 3: <proxy usesystemdefault="False" proxyaddress="http://[proxy address]:8080" bypassonlocal="True" /> 4: </defaultProxy> 5: </system.net> 6: All you need to do is to set the proxy address together with the port number into the property there and put that in the web.config and then that’s all you need – problem solved! 2/4/2009 Hiding elements on a publishing page when fields are blankThis has been something that bugs me about most page layouts I have done before – you have a field like the description or something like that and when you put it in you have to put it in a <p> tag to get it to render properly. The problem then is that if you don’t populate the field you then don’t want the <p> tag outside the element to render otherwise you will have some unwanted white space. I had a quick Google around and found a pretty good solution for this at http://social.technet.microsoft.com/Forums/en-US/sharepointecm/thread/dcfc5fe2-5ee1-439a-af44-b59b5c6f59bd/. Essentially the solution involves creating a custom control based on the security trimmer control, and telling it to trim the components inside it when the specific field is blank. I found the code example at that URL didn’t quite work, so here is my code with some minor adjustments made: 1: public class HideWhenBlank : SPSecurityTrimmedControl 2: {3: public String FieldNameToCheck { get; set; } 4: 5: protected override void Render(System.Web.UI.HtmlTextWriter output) 6: {7: SPListItem item = null; 8: WebPartDisplayMode mode = ((SPWebPartManager)this.Page.Master.FindControl("wpmMain")).DisplayMode; 9: if (mode.Name == "Design") 10: {11: base.Render(output); 12: }13: else if (SPContext.Current != null) 14: { 15: item = SPContext.Current.ListItem;16: if (!String.IsNullOrEmpty(FieldNameToCheck) && item != null) 17: {18: if (!ValueIsNullOrBlank(item[FieldNameToCheck])) 19: {20: base.Render(output); 21: } 22: } 23: } 24: } 25: 26: private Boolean ValueIsNullOrBlank(Object data) 27: {28: if (data == null || String.IsNullOrEmpty(Convert.ToString(data).Trim())) 29: {30: return true; 31: }32: else 33: {34: return false; 35: } 36: } 37: }Compile this class and you can go and use this one in your page layouts like this: 1: <MyCustomTagPrefix:HideWhenBlank runat="server" FieldNameToCheck="Comments"> 2: <p> 3: <!-- Some sort of custom publishing element in here --> 4: </p> 5: </MyCustomTagPrefix:HideWhenBlank> So basically in this example when the comments field is empty, then the <p> tag as well as anything else inside the custom tag won’t be rendered. The tag will always allow the content to be rendered in edit mode though which means you can always add a value later. Thsi is nice and easy to implement and can help tidy up your page layouts a bit. 1/30/2009 SPDisposeCheck goes public!If you are a SharePoint developer, then chances are that you know of the fact that there are several SharePoint objects that always need to be disposed of correctly in order to prevent memory leaks (and if you don’t know about this, then learn about it real quick! There is a good article over at MSDN - Best Practices- Using Disposable Windows SharePoint Services Objects). Anyway, there has been a tool in the works for a little while now to help developers get this right – SPDisposeCheck. What this tool will do is assess a /NET library (either a DLL or EXE file) and it will tell you about all the lines of code that you need to change in order to meet the best practices for memory management in SharePoint. I’ve seen this tool in action a few months back (wasn’t allowed to say anything about it at that point) and I gotta tell you its pretty awesome. From what we found it was pretty good at picking up any of the issues we had in our code, with a couple of small exceptions and one or two false positives. The point is though that it greatly reduced the likelihood of human error when we reviewed the code because the tool would do it for us, and do it much quicker too. Now the catch with this tool is that it isn’t officially supported by Microsoft, so don’t go throwing it around on every SharePoint machine you have – but every one of your SharePoint developers should have a copy of this tool on their development environments, and its probably not a bad idea to enforce its use as part of some sort of code review process as well. So go and download this tool now! It is at http://code.msdn.microsoft.com/SPDisposeCheck Source: http://blogs.msdn.com/pandrew/archive/2009/01/29/spdisposecheck-v1-3-1-is-released.aspx 1/27/2009 Creating web applications through command line actionsWhen deploying SharePoint sites I personally am a big fan of the good old batch file - they are simple enough to put together and with a bit of knowledge of the commands that stsadm offers you can create quite a powerful deployment that is reproducible and not prone to human error that you might get when deploying things that require user interaction with the UI. The scenario that I find is the most common is that you need to deploy your solutions to a SharePoint farm and then create a site that uses them. For example I could have a solution for an intranet site that after I deploy the WSP I would like to create the site based off the templates in the solution. To do this there are a few steps to go through to get this going:
The first step most people who deploy solutions via command line will be familiar with - the addsolution and deploysolution commands. Basically addsolution is used to store a WSP file in the configuration database so that it can be deployed to the farm, and deploysolution will deploy the solution to the farm from the configuration database. Here is a basic sample of these commands: 1: stsadm -o addsolution -filename MySolution.wsp 2: stsadm -o deploysolution -name MySolution.wsp -immediate -allowgacdeployment -allcontenturls 3: 4: stsadm -o execadmsvcjobsThe addsoltuion command is very straight forward, just give it the path to your WSP file and it is a happy camper. The deploysolution command has plenty of options to it, such as allowing the solution to put resources in the GAC, allowing it to deploy CAS policies, which URLs it should be deployed to, and when it should be deployed. This command will create a timer job, and in this case you will want to use the -immediate tag so that when the next line runs the timer job will be executed immediately. Thats it for the first part! The next thing we want to do is to create a web application. Now I'm assuming here that you know what the URLs and application pool details will be, as you will need them in this command. Here is a sample: 1: stsadm -o extendvs -description "ShrePoint - My new site -url %internalUrl% -ownerlogin %siteCollectionAdmin% -owneremail %siteCollectionAdminEmail% -databasename %databaseName% -exclusivelyusentlm -donotcreatesite -apidname %appPoolName% -apidlogin %appPoolUser% -apidpwd %appPoolPassword% -apidtype configurableid -allowanonymous 2: The command we use here is extendvs. It will create a web application for us, here are a few things you should know about it:
From here we can now create a site collection in our web application, here is a command that will do this: 1: stsadm -o createsite -url %internalUrl% -title "My new site" -owneremail %siteCollectionAdminEmail% -ownerlogin %siteCollectionAdmin% -sitetemplate STS#0 2: So most of the options here are self explanatory, with the siteTemplate attribute specifying what type of site to create. Once this is done we through in an IIS reset and your new site is good to go 1: iisreset 2: What I would recommend to anyone who is going to batch deployments like this is to come up with a common file and put all the appropriate variables at the top (you can see the variables in my examples). Then create a copy of the batch file for each environment and and put in the appropriate details into the variables at the top. That way there is less messing around with the batch files at each deployment, which means less chance for things to not be done correctly. Also it might be worth not including the password to your service account in the batch file, and having whoever is responsible for the deployment putting that in manually before it is run, just to keep things a bit tighter from a security perspective. Other than that, your good to go! And to finish up, here are some references to the commands I’m talking about from TechNet:
1/23/2009 Interesting issue with publishing pages provisioned from the page layoutThis is a bit of an interesting issue that I came across yesterday afternoon while working on a clients intranet site. Basically it has to do with how you provision publishing pages in MOSS – if you provision a page from the page layout file (using the setuppath attribute in your module element) after the page is provisioned if you go to the page settings page where you would normally change the layout, the option to do so will not be there. Let me explain in detail what I am talking about here: If you go on over to MSDN (http://msdn.microsoft.com/en-us/library/ms441170.aspx) you will see the usual way for provisioning a file through a feature, and it looks something like this: 1: <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 2: <Module Name="SubSiteHome" Url="$Resources:cmscore,List_Pages_UrlName;" Path=""> 3: <File Url="default.aspx" Type="GhostableInLibrary" > 4: <Property Name="Title" Value="My Page Title" /> 5: <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/MyPageLayout.aspx, ~SiteCollection/_catalogs/masterpage/MyPageLayout.aspx" /> 6: <Property Name="ContentType" Value="My Content Type" /> 7: </File> 8: </Module> 9: </Elements> Now, this method works fine and will deploy a copy of the file default.aspx that you will have in your features directory. But as a good friend of mine Zak Azeez once showed me, you can provision a publishing page directly from the page layout (provided you know where it sits in the 12 hive). This means you don’t need to have the pesky default.aspx file that only has one line of code sitting around. To do this, you provision the file like this: 1: <Module Name="SubSiteHome" Url="$Resources:cmscore,List_Pages_UrlName;" Path="" SetupPath="FEATURES\PageLayoutFeatureName"> 2: <File Url="MyPageLayout.aspx" Name="default.aspx" Type="GhostableInLibrary"> 3: <Property Name="Title" ValueMy Page Title" /> 4: <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/MyPageLayout.aspx, ~SiteCollection/_catalogs/masterpage/MyPageLayout.aspx" /> 5: <Property Name="ContentType" Value="My Content Type" /> 6: <Property Name="PublishingAssociatedContentType" Value=";#My Content Type;#[ContentType ID goes here];#" /> 7: </File> 8: </Module> In this method you use the SetupPath attribute of the module element and point it to the feature folder that has the page layout that you want your new publishing page to use. Then when you provision the file the Url attribute is the file name of the page layout and the Name attribute is what you want it to be called when it is provisioned. After that the only extra attribute you need to use is the PublishingAssociatedContentType (just like you would when you provision the page layout to the master page gallery) and your all set. So the interesting thing I discovered was that any pages that I had provisioned using the second method would not let me change the page layout. I would browse to the page settings page and all the other properties would be there (title, description, contact, scheduling etc) but the normal drop down with the list of page layouts to change to wasn’t there, while on pages provisioned with the first method I discussed can quite happily change their layout. I’m assuming this is something that was perhaps by design and that we just weren’t aware of (it is actually going to help now because this was I can prevent users from changing the page layout on important pages in the site) but still something we didn’t know about and I thought was worth sharing. Hope someone else finds this useful too! 1/11/2009 Things I want to achieve in 2009Well its my last day of holidays and its back to the office for me tomorrow. I’m keen to get back to the projects I am working on and I’m out to make this year bigger and better than last year, which will take some effort because last year was such a massive year for me. Last year saw me start work with Unique World, become a co-manager of the Canberra SharePoint User Group, start this very blog and get plenty of good stuff in to it, which in turn helped me get my skills with all aspects of SharePoint to a level even I didn’t think they would – and then to top it all off I finally got my MCAD as well. So how on earth do I plan to top that all this year? Well my first idea is to release a project on CodePlex – I have a couple of good ideas that could help SharePoint developers out there, I just need to find the time to put them together and get them out there! Next I want to try to increase the readership of my blog – I know I get plenty of traffic from Google but I want to try to come up with some way to get more people sitting on my RSS feed. I want to find more places that I can do presentations (I really enjoyed presenting at Office DevCon last year and I always like talking to the Canberra SP User Group) so I might start looking outside of Canberra to do them. And last but certainly not least I want to make sure that the projects I am working on for our clients really shine and are things I can be proud of. So I think I’m ready to hit the ground running – look out 2009 because I’m out to make it a big one! 12/30/2008 How to get TFS to automate your WSP builds with WSPBuilderNow this is what happens when I have too much time on my hands over the holidays (you would think I would have something better to do, and yet here I am anyway!). Essentially I had rebuilt my laptop and I have included TFS in the setup for my source control on local projects that I was working on (for example, when I'm on site with a client and not connected to the corporate source control solution, this makes for a good backup). Anyway I wanted to look into something that I know has plagued me on other projects, and that was how to use the TFS Build Server to automatically build our WSP files for us as part of its automated builds. So here is how I got that right (and I'll warn you now, this is gonna be a long blog post!), but the thing is I don't have a massive amount of experience with TFS outside of the basic stuff, I also am keen to see if anyone out there has ideas on how to improve this process for everyone. Essentially what I wanted to work was when I do a local build of a project that it gives me a copy of the WSP file that isn't checked in and is just local to my environment, so I can test it on my local server before checking the code in. Then when I check the code in I want an automated build to take place and drop the WSP file in a location I specify. Step One: Install WSPBuilder on the build server So the first thing I decided upon was that I was using WSPBuilder for my WSP files, I have used WSPBuilder for every SharePoint project I have worked on and I like the way it all ties in to Visual Studio, so it seemed that the next step for me was to get WSPBuilder to make my automated build WSP files. To do this, the software needed to be installed on the build server, so that was step 1. Step Two: add WSPBuilder to the paths environment variable My next issue was that I wanted to be able to create the WSP files from the build action when I build from the client and when TFS does the builds. This meant that I would put the majority of the actions into the post build activities of each project. This raised an interesting issue for me - my host OS where I do my development is 64-bit and my TFS server (which is the build box) is 32-bit (see my previous rant about TFS not running on 64-bit). This meant that the path to the WSP builder app was going to be different on each box (because of the "program files" and "program files (x86)" thing). So to simplify the post build actions a bit I decided to add the WSPBuilder path (C:\Program Files (x86)\WSPTools\WSPBuilderExtensions) to the PATH system variable on both the development box and the build box. Step Three: Set files included in the WSP file to copy to output directory Now, when TFS does a build in the directory that it puts the DLL's it will only give you the DLL's themselves, not the files that also need to go into your WSP. My idea for a way around this is to put all of the files that get deployed to the 12 hive (so everything in my projects that isn't code) to copy to the output directory on build (this is done by selecting the file in the solution explorer of Visual Studio, and in the properties window set the item to be Content, and to copy if newer). This would mean that my compiled DLL's and all the other files for the 12 hive would be in the same directory at the same time on the TFS server, ready for the WSP builder call to run. Step Four: Add the post build activity to the appropriate projects Now that we know all the files will be where we need them to, we can add the post build actions. Add this to the post build of each project that should output a WSP file: 1: IF ("$(OutDir)")==("bin\Debug\") GOTO LocalBuild 2: 3: :TfsBuild 4: 5: MD "$(TargetDir)bin\Debug\" 6: COPY "$(TargetDir)*.dll" "$(TargetDir)bin\Debug\" 7: WSPBuilder -SolutionPath "$(TargetDir)" - OutputPath "$(TargetDir)" 8: RENAME "$(TargetDir)Debug.wsp" "$(ProjectName).wsp" 9: RMDIR "$(TargetDir)bin" /S /Q 10: RMDIR "$(TargetDir)12" /S /Q 11: 12: GOTO Finish 13: 14: :LocalBuild 15: 16: WspBuilder -SolutionPath "$(ProjectDir)" -OutputPath "$(TargetDir)" 17: 18: :FinishThis code is broken down into the following key actions:
So with this post build action in place, when we do a build, either local or on the build server, we will have a new WSP file ready to roll. Step Five: Create a new build in TFS This is pretty straight forward, create a new build that targets the debug build of the solution. Nothing too complicated here other than to just make sure you choose the debug option - WSPBuilder expects everything to be in the debug folder. Step Six: Add additional reference paths Now unless your TFS server happens to be a MOSS server as well (which may be the case since it requires WSS for it to run) chances are you are referencing DLL's in your code that the build server won't know about, which will cause your new build to fail. There are a couple of solutions here, the first is to just GAC what you need, but I personally don't like this one. The second option that I did is to create a folder on the build server and add it as an additional reference path. This tells the TFS builder to look for referenced DLLs in a specific location. To do this, open the TFSBuild.proj file that is created for your TFS build and add this to the appropriate section (the very last one by default, read the comments to be sure). 1: <AdditionalReferencePath Include="C:\Assemblies" /> Then you can set this folder up as a network share and drop referenced assemblies in there as required. Step Seven: Add a pre-build action Now this isn't required if your solution only has one project and one WSP file, but if like my example I had set up here locally it has two projects that each have a WSP file then you might need to add this to the pre-build of each project (and I can't explain exactly why it works yet, I'm tired and was just happy that it all works in the first place). 1: IF ("$(OutDir)")==("bin\Debug\") GOTO Finish 2: 3: DEL "$(TargetDir)*.dll" /F /S /Q 4: 5: :FinishIf you don't put this in then you will find that the DLL's from the first projects that are build will make their way into the second and subsequent WSP files. Put this in and all seemed to work well for me. So now if you put all of that together and run an automated build (I've been testing this with a build on each check-in) you should find that your drop location will now contain all the DLL's, PDB and config files, as well as your WSP files! Now while this is working for me, there are things I do plan to improve about this process to make it a bit more streamlined, so if you have any suggestions I would love to hear them, just leave me a comment. One thing I have on my to-do list is to automate the upgrade of the solution to a specified server - this would mean that you could automate your WSP file builds nightly and deploy them to a staging server automatically over night. If I do that I'll be sure to add more to my blog here, and also I do plan on putting this up at http://SharePointDevWiki.com to see what else people can add to it (again, too tired to do it now and my Xbox is calling me to spend some time with it before I go back to work, so it will be there soon). I hope this helps someone else out there! 12/23/2008 Team Foundation Server 2008 and 64-bit – its just not meant to beMy first blog post while I’m on holidays, and its to complain about a big lack of functionality in Team Foundation Server. Basically this all started while I was rebuilding my laptop (still a work in progress, but coming along well) and when it came time for me to install TFS 2008 on the box I get a big error message saying that it can’t install TFS on a 64-bit system! Now this just doesn’t make sense to me, with the way MS are pushing 64-bit, especially for server applications. I have read that TFS 2010 will have 64-bit support, but I can’t wait for it. So I got a few ideas for workarounds when I hit up Google for some info. Basically my fix will be to host the TFS application tier on a 32-bit virtual PC (running in HyperV). The data tier and the build server (I’m told) will still run fine on 64-bit, which means that I can still host the data and do my builds on the host OS. I will post here later once I have gone through the process to let you know how it went. In the mean time though, has anyone else run into this issue? What did you do to get around it? I would love to hear it! 12/20/2008 Planning to rebuild my dev environment and want second opinionsWhat does a SharePoint developer do when he is on holiday – well the most common answers would probably involve doing things that in no way relate to SharePoint. But for me, near the top of my list is rebuild the laptop that I use for my development. There are a few things that I do know that I will be putting on there, but I would be interested in hearing anyone else’s thoughts on what could go on there and how I can configure it. Here is what I do know it will have:
Right, so that gives a nice overview of the functionality I want this thing to have 9the laptop is a Dell XPS M1330, so it can handle it and do it quite well). There are a few things I am tossing around in my head that I am thinking about doing with it. Here is a list: Install Exchange Server 2007 instead of the POP3 service This is the first thing I’m not sure about – I currently haven exchange running on a VM so the accounts I set up in AD for testing things like emails from workflow all have mailboxes that I can easily access through different profiles in outlook. I haven’t used the POP3 service before but it was recommended to me by a colleague as it isn’t anywhere near as heavy as exchange. Would be interested to hear thoughts on it. WSPBuilder or custom scripts If you have ever talked to me about this or seen me give a presentation on anything to do with SharePoint you will know that I am huge fan of WSPBuilder (www.codeplex.com/wspbuilder). I do however find that it does a few funny little things sometimes (doesn’t always add safecontrols entries for me, the output WSP is different when you choose build to when you choose upgrade and tell it to do a build first, and a few other little things) so the thought of writing my own custom WSP generation scripts has been rolling around the back of my head for a while now. Of course the awesome thing about WSP builder is that it has templates for everything in Visual Studio, meaning adding features and other things to a solution is always a single click, so if I went with the scripts option I would also end up having to create some templates as well I think. Again would love to hear what others think about this. To virtualise or not to virtualise In my current setup I have a virtual PC that runs my complete development set up and I use one virtual PC for each environment. This is great for isolating code for each client, but means my VMs are quite fat and memory hungry. This time around each of my VMs will use services from the host (AD, SQL, Email, etc) but I am unsure as to whether or not I want to put my development tools on each VM. Essentially what I want is to be able to work with just one installation of Visual Studio on the host OS but then have an easy way to deploy the WSP to a predefined virtual server. This still allows me to isolate each SharePoint installation for each client/project and means I don’t need to have a copy of VS on each virtual machine (essentially meaning each VM would be nothing more than a MOSS install). I just don;t know how practical this would be to implement, and would love to hear others thoughts Source control One thing I don’t have with my current set up is local source control. I currently use Live Mesh to take backups of my code as I write it (it all syncs right up to my mesh) but I have been thinking about installing TFS on my host OS so I get full source control and bug tracking, at least for the stuff that I develop locally (obviously our bigger projects that involve more than just me writing code for them would have me using other source control solutions to work with the team and this might vary from client to client). Has anyone ever done this and do you think it would be worthwhile? I was thinking that I could still have Live Mesh sync the TFS data to my mesh as a plan “B” for disaster recovery.
So there you have it, those are some of the big ideas I have in mind for my rebuild. I will probably start it some time this week and II will be sure to share what the final outcomes are, but please leave me a comment here if you have thoughts on any of because I would love to hear it. 12/18/2008 Why I like using site definitions!I had a bit of a chat with Jeremy Thake yesterday about one of the pages on SharePointDevWiki.com - the discussion of site features vs site templates vs site definitions. I suppose most of the discussion came from the fact that there really wasn't a lot of discussion on the topic, which was a little weird because if you talk to a lot of SharePoint developers they all have their favourite and reasons why the other options are evil. So I went and put in some info about my strategy for doing sites, and I'll say it loud and proud, I'm in the site definition camp. There are however some catches to that - you need to do them right, and I think this is where a lot of the fear and loathing of site definitions comes from. I'll be clear here - if you are doing anything to the content databases (triggers or modifying stored procedures) then you are doing the wrong thing, and are one of the big reasons that site definitions have the rep they do. Now let me explain how I do mine though. I start by creating a new site definition (again, editing the OOTB ones is evil and you shouldn't ever do it) and I try to put an absolute minimum of content in to it. I then build all the functionality into individual features, and reference the features in the site definition (in the WebFeatures and SiteFeatures sections). Why do I do this? Basically it is easy to identify the different types of sites post deployment, and because all of your functionality is in features it is easy to turn on/off more features to add or remove functionality later as well. Here is what I put on SharePointDevWiki as an example of this method:
So there is my two cents on the topic, and I would love to hear anyone else's thoughts on the topic - just leave me a comment below! 12/17/2008 100 people to follow on TwitterJust a quick post this morning - Joel Oleson has put together a list of 100 SharePoint people to follow on twitter and I ended up making it on to the list (which I thought was kinda cool). Anyway if you use twitter and wanna keep in touch with what the big names in SharePoint are doing then head on over to http://www.sharepointjoel.com/Lists/Posts/Post.aspx?List=0cd1a63d-183c-4fc2-8320-ba5369008acb&ID=152 and start following some of those people! 12/12/2008 Creating CAML queries that use three or more filtersJust a quick one that a came across today - I have a scenario where I am building a CAML query on the fly based on the part of the site that a user is browsing. Essentially the query will have a number of statements that need to go into an <Or> clause. Now I got caught out by putting my query together like this: 1: <Where> 2: <Or> 3: <FieldRef Name="Field1" ... /> 4: <FieldRef Name="Field2" ... /> 5: <FieldRef Name="Field3" ... /> 6: </Or> 7: </Where> Now this worked fine when I ran it in the U2U Caml Creator tool (I manually typed the query in), but when I ran code that used this as part of an SPQuery I got the error message "Cannot complete this action, please try again". I had a look at it and it turns out that my query should have been written like this: 1: <Where> 2: <Or> 3: <Or> 4: <FieldRef Name="Field1" ... /> 5: <FieldRef Name="Field2" ... /> 6: </Or> 7: <FieldRef Name="Field3" ... /> 8: </Or> 9: </Where> Each <Or> operator (or any of the operators that combine two values for that matter) can only contain the two values, so to get the multiple or statements going. Makes sense when you think about it, but I had me. 12/11/2008 Making a context sensitive content query web part
Anyway, onto the serious stuff. The requirement I am solving with this one is to make a content query web part automatically pick up items from the current web without me having to tell it where that web is. let me explain that a bit better - I am using a delegate control to put a content query web part into a page layout, and the page layout will be used across the entire site collection. I want the content query web part to display items based on the current site when a user browses to a page that uses this layout - so in other words, the web part needs to be context sensitive ... sensitive to context (another Conker reference there). So the bad news is OOTB you need to specify the WebURL property to tell the web part where to get its items from, the good news though is that it is very, very easy to override the content query web part to add this functionality. Here is the entire class that I wrote to add this functionality: 1: public class CurrentSiteContentQuery : Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart 2: {3: protected override void OnInit(EventArgs e) 4: {5: base.OnInit(e); 6: this.WebUrl = this.WebUrl.ToLower().Replace("~site", SPContext.Current.Web.ServerRelativeUrl); 7: } 8: 9: }Yep, thats it. When I put "~site" into the WebURL property that will resolve to the current URL that is gets from the SPContext property. So now I just tell my delegate control to use my web part instead of the OOTB one and I'm done, context sensitive queries are now appearing in my page layouts. Its a beautiful thing. 12/8/2008 Using the delegate control to deploy a web part through featuresThis is something I had no idea about until a friend of mine, Zak Azeez (don't say I didn't give you credit for this one mate!) pointed it out to me when we were discussing how I could best put a predefined web part into the master page of a SharePoint site. He suggested that I use the delegate control to deploy it with a feature. Now I knew the delegate control was used to deploy ASCX pages that you could incorporate into a page (the best example of this is the OOTB search control that is in the top right corner of the default master page, it is done with a delegate control) but I had no idea you could actually deploy a web part in the same way. Here is a quick run down of the process (and it is really easy).
Pretty simple huh? What is even simpler is setting up the feature because its more or less a copy and paste from what you export from SharePoint when you get the web part out. here is a brief sample of how I put a content query web part in: 1: <Control ControlAssembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" 2: ControlClass="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart" 3: Id="MyControlId" 4: Sequence="200"> 5: <Property Name="FilterType3" /> 6: <Property Name="PageSize">-1</Property> 7: <Property Name="SortBy">{f69504ad-fd94-4e65-a31d-c456f8c7f1be}</Property> 8: <Property Name="ChromeState">Normal</Property> 9: <Property Name="AllowZoneChange">True</Property> 10: ...11: <Property Name="AllowClose">True</Property> 12: <Property Name="FilterField3" /> 13: <Property Name="CatalogIconImageUrl" /> 14: </Control> So you see the assembly and class attributes are put into the control node, and then all of the property tags are just copied and pasted from the external web part (make sure you remove the "type" attributes though, you don't need them here - also I think I needed to change the tags from property to Property (uppercase "P") so that it would be fine when it validated against the schema). So when I deploy that it will go and put a content query web part on the page for me. Obviously I didn't put all the properties from that web part on here (thus the dots in the middle) but you get the idea. What I do find to be very cool about this though is that it means my web part is now nicely tied to a feature, meaning that if we need to change the properties of the web part we can just update the feature and redeploy the WSP file, SharePoint will pick up the change when the application pool is recycled and the changes will appear to users - this makes the process of updating the web part so very very simple. Also it means if we don't want it anymore we can just disable to feature and the web part will no longer display, no editing of the master page is required. If you are putting web parts or controls onto your master page then this is definitely something you should consider doing. 12/4/2008 New SharePoint development wiki site needs your content!Big thanks to Jeremy Thake for getting this idea together - A new wiki site has been started that is going to be specifically aimed at SharePoint developers. Essentially what we are looking to do is to bring together all the data that is floating around your favourite search engine and link to it all on the wiki, so you can go to the wiki and get a good overview of heaps of stuff to do with a particular aspect of developing for and customising SharePoint. Personally I think this is a great idea and I'm looking forward to finding some time to put some content up on the site myself in the coming days and weeks, and if you want to contribute just head on over to the site and sign up. The URL is below! 12/2/2008 Planning on using the SharePoint API in your silverlight app? Better think again... and the issues keep on coming for my silverlight app! It looks like you can't reference Microsoft.SharePoint.dll in your silverlight projects (or a lot of other libraries for that matter) because they are not compiled for the silverlight runtime. For those who don't know, the silverlgiht runtime is essentially just a cut down version of the .NET framework (from what I have briefly read about it anyway) and so you can't use just any code in your silverlight app. This is why when you install the visual studio tools for silverlight you see the "Silverlight class library" project type - this is used to compile a library against the silverlight library so will make sure you don't reference anything you shouldn't. So in this case, my work around will be to use web services - silverlight is perfectly capable of calling them, so I can still get the data I need from SharePoint from the out of the box web services. Now I know this will work, but I would have much preferred to call the SharePoint API directly. I suppose I'll just stop my whining and get down to writing the code, but if you are planning on writing a silverlight app for SharePoint make sure you keep this in mind. 12/1/2008 How to get silverlight and MOSS to play niceI have recently started putting together a silverlight control for use in a MOSS site I am working on for a client. I went and downloaded the Visual Studio 2008 SP1 tools for silverlight and installed them and got in and came up with a nice looking silverlight control that run fine when I ran it from Visual Studio. However I went and deployed my WSP to the local SharePoint farm and all over sudden none of my MOSS sites were working, not even central admin. I get this error when I try to browse to a SharePoint site:
And I see that this is also in the event log next to each of the above errors as well:
After some looking in to it a bit I found that the safecontrol entry for the library containing the code for my Silverlight code in the web.config of each web app was what was killing it. So after putting two and two together (and reading a few forum posts) I realised that my code had a dependency on the System.Windows DLL that silverlight provides. The solution then is to make sure that System.Windows.dll and System.Core.dll are copied to the GAC from the silverlight directory (which in this case is C:\Program Files (x86)\Microsoft Silverlight\2.0.31005.0). I'm still a little uncertain if I would go abotu putting those DLL's into my WSP file - I don't think I will, I will just document it as a separate process that needs to happen before the WSP file is deployed. Would be interested to hear anyone's thoughts on this though, especially if you have deployed silverlight to MOSS before and come across the same issue. 11/26/2008 Customising SharePoint navigation using OOTB featuresIf you have ever written a custom site definition, then chances are you have also probably wanted to control the site navigation settings for your new site def as part of the definition (rather than something that must be changed after the site is created, or something that you have to write your own feature for). Well as luck would have it there is an OOTB feature that you can use to set the navigation settings of your site, it's just that it's properties aren't very well documented. To control the navigation settings of your site you need to activate the 'NavigationProperties' feature and specify the properties that you want to apply to the site. The best place I have found to do this is in the onet.xml file for your site definition as you can specify appropriate properties for each configuration of your site. Here is an example of a basic implementation of this feature: 1: <WebFeatures> 2: ...3: <Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA"> 4: <!-- Per-Web Portal Navigation Properties--> 5: <Properties xmlns="http://schemas.microsoft.com/sharepoint/"> 6: <Property Key="InheritGlobalNavigation" Value="true"/> 7: <Property Key="IncludeSubSites" Value="true"/> 8: <Property Key="IncludePages" Value="false"/> 9: </Properties> 10: </Feature> 11: ...12: </WebFeatures> The above will activate the feature and tell the site to inherit the global navigation, and to show sub sites in the navigation but not to show pages. There is a pretty nice selection of properties to include with this feature if you want to (this is the undocumented part), here is a list of them and what they do:
The two enum options use the following options that are pretty self explanatory: OrderingMethod: Automatic, ManualWithAutomaticPageSorting, Manual Also I'll just quickly highlight the difference between global navigation and current navigation. The global navigation is the navigation that goes across the top of the page, and the current navigation refers to the quick launch that runs down the side of the page. One other thing that is worth mentioning is that the property "AutomaticSortingMathod" has a typo in the 'method' part of the name (a instead of e). This is deliberate, and not one of the many typos I know I make when I blog. If you reflect the feature receiver for this feature you will see it expects it to be spelt this way. So if you put some of these features together you get a lot of control over the navigation settings of your site without having to write and custom code to change the settings, and it is all still controlled through features. A great way to use this (and this is how I am implementing it currently) is for a portal site. I am using the portal provisioning provider (see my post about this at http://pointstoshare.spaces.live.com/blog/cns!AEC42F315B4528B0!3139.entry) to create a portal, and I list the sites in my portal.xml file in the order I want them to appear in the navigation. Then I set the navigation to orderthe pages by order date and then to not show pages so I get the sites I want in the global navigation. Here is the feature XML for that. 1: <Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA"> 2: <!-- Per-Web Portal Navigation Properties--> 3: <Properties xmlns="http://schemas.microsoft.com/sharepoint/"> 4: <Property Key="InheritGlobalNavigation" Value="true"/> 5: <Property Key="IncludeSubSites" Value="true"/> 6: <Property Key="IncludePages" Value="false"/> 7: <Property Key="OrderingMethod" Value="Automatic"/> 8: <Property Key="AutomaticSortingMathod" Value="CreatedDate"/> 9: </Properties> 10: </Feature> So there we have it, one of the longer blog posts I have put together in a little while. Hopefully you can use this to get your navigation settings right without having to write your own features for it! 11/25/2008 Announcing Isolator for SharePoint : Unit testing for SharePoint made easier
If you have been a SharePoint developer for any period of time, you might know that testing SharePoint applications can be a troublesome experience. Well thankfully there are people out there that are working to make this an easier process, such as the folks over at TypeMock. Here is some info from their web site about a new product call 'Isolator for SharePoint'
So, obviously I am trying to get myself a free license here so I can check the product out - If I do get one I will be sure to put info here about how the product goes! |
|
|