<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19451733</id><updated>2011-07-28T12:16:56.943-04:00</updated><category term='calendar'/><category term='developer tools'/><category term='Community Server 2007'/><category term='powershell'/><category term='Community Server 2.1'/><category term='themes'/><category term='ftp'/><category term='symbolic link'/><title type='text'>Arrested Development</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeffesp.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19451733.post-7528805149034832144</id><published>2009-08-03T10:56:00.008-04:00</published><updated>2009-08-09T12:12:14.004-04:00</updated><title type='text'>Thoughts on TDD and BDD</title><content type='html'>&lt;p&gt;I just finished reading Martin Fowler's &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks Aren't Stubs&lt;/a&gt;. This is a great document because it gives some names to things that I hadn't been able to name before. Classicist vs. Mockist TDD is a key distinction that we have been struggling to define as we develop more concrete testing methods at work. To know that other people, who know what they are doing, have also dealt with it helps us to know that we are not just making things up.&lt;/p&gt;&lt;p&gt;My key conclusion from this is that I follow a Classic TDD model. I don't want to care about the behavior of my methods and therefore I am not going to do strict mocking where I verify that certain methods have been called. The interesting wrinkle here is that I really want to use a mocking framework for the ease with which I can create a stub or dummy object. This isn't well supported in all of the frameworks, but I have heard that &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; is going to be what I want to look at.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Fowler's article linked to Dan North's &lt;a href="http://dannorth.net/introducing-bdd"&gt;BDD introduction&lt;/a&gt;. I hadn't understood BDD before, and I can't claim that I really do at this point, but there is some interesting content in this introduction. The first few paragraphs of this description really seems to address a number of problems that I have had with TDD and unit testing in general. Here are the questions he poses: &lt;ul&gt;&lt;br /&gt;&lt;li&gt;Where to start?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;What to test and what not to test?&lt;/li&gt; &lt;br /&gt;&lt;li&gt;How much to test in one go?&lt;/li&gt; &lt;br /&gt;&lt;li&gt;What to call their tests?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;And how to understand why a test fails?&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;I had yet to come up with satisfactory answers to these question. But North has a simple answer for all of them: write your test names like sentences. If my test class is named FooLookupTests and my test method is named FindFooByIdTest(), I can write "Foo lookup - find foo by id." When the test classes and methods create this structure, then I am working in the right direction. When they do not create this structure, then I need to review what I am testing and refactor my tests and possibly the code under test to follow this guideline.&lt;/p&gt;&lt;p&gt;After this simple suggestion, North goes on to point out how he developed the BDD method from this insight. On my first evaluation of this description, I do not like it. While I like North's initial insight and I think his answer to the questions above is very insightful and useful, I can't see myself adopting a full BDD process. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; my coworker John mentioned that the main point of North's introduction is more that the test methods need to be named in a testShould...() format. Certainly the BDD people would argue that you are doing it wrong if your test methods aren't of this form. For my purposes, I don't think this is strictly necessary, but is a useful point to keep in mind.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-7528805149034832144?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=7528805149034832144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7528805149034832144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7528805149034832144'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2009/08/thoughts-on-tdd-and-bdd.html' title='Thoughts on TDD and BDD'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-7803751717132117741</id><published>2009-07-28T11:01:00.002-04:00</published><updated>2009-07-28T11:06:19.360-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='powershell'/><title type='text'>Subversion Rename using Powershell</title><content type='html'>I am working on an ASP.NET project that is hosted in subversion. I mainly use the command line client to work with things, but occasionally that doesn't easily get me where I need to be. I wanted to rename a page with it's codebehind, so I did the following:&lt;div&gt;&lt;pre&gt;get-childitem MyPage.aspx* | %{ svn rename $_ $($_.ToString() -replace 'MyPage', 'new-page') }&lt;/pre&gt;This isn't anything new for powershell veterans, but it is the first time I found the immensely useful 'replace' string operation.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-7803751717132117741?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=7803751717132117741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7803751717132117741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7803751717132117741'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2009/07/subversion-rename-using-powershell.html' title='Subversion Rename using Powershell'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-7814766205482638259</id><published>2009-04-07T17:01:00.005-04:00</published><updated>2009-04-07T17:06:25.566-04:00</updated><title type='text'>Zebra (alternating color) Tables in ASP.NET</title><content type='html'>This is just a small note to say that I love doing this: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;tr class='&amp;lt;%# ((IDataItemContainer)Container).DisplayIndex % 2 == 0 ?&lt;br /&gt; "CommonListRow" : "CommonListRowAlt"  %&amp;gt;'&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When using any type of ASP.Net repeating control (such as asp:Repeater). It is much more maintainable than copying and pasting code between the &amp;lt;ItemTemplate&amp;gt; and &amp;lt;AlternatingItemTemplate&amp;gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-7814766205482638259?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=7814766205482638259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7814766205482638259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7814766205482638259'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2009/04/zebra-alternating-color-tables-in.html' title='Zebra (alternating color) Tables in ASP.NET'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-9012646895853896078</id><published>2009-02-20T11:11:00.001-05:00</published><updated>2009-04-03T21:52:18.652-04:00</updated><title type='text'>Community Server Training</title><content type='html'>We have been working hard here at the ATGi world headquarters to create a curriculum for Community Server training. It is now available for registration and I am looking forward to the class in April.  Check it out &lt;a href="http://www.atgi.com/training.aspx"&gt;here&lt;/a&gt; for more information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-9012646895853896078?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=9012646895853896078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/9012646895853896078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/9012646895853896078'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2009/02/community-server-training.html' title='Community Server Training'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-2019777591601307637</id><published>2008-10-30T10:35:00.001-04:00</published><updated>2009-04-03T21:45:43.774-04:00</updated><title type='text'>Windows Server 2008 Domain Controller Backup</title><content type='html'>All the information you need can be pulled from &lt;a href="http://technet.microsoft.com/en-us/library/cc771290.aspx"&gt;TechNet&lt;/a&gt;, but I have condensed it here.&lt;br /&gt;&lt;br /&gt;You need to run the following command to get the system state backup, which is what you can use to restore a DC it fails and you need to restore to a different machine, or to a new install on the same machine.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wbadmin start systemstatebackup -backupTarget:&lt;driveletter&gt;:&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Be sure to run it in cmd and not in powershell because powershell does not like the -backupTarget: part of the command.  If you normally work in PSH, then a cmd /c "wbadmin ..." will allow you to run this command.&lt;br /&gt;&lt;br /&gt;A few other notes that are valuable:&lt;br /&gt;&lt;br /&gt;When you are saving system state you must backup to a drive, it can't be a network share.&lt;br /&gt;&lt;br /&gt;And can't be one of the source drives of the backup, but you can get around that.  To get around the drive limitation create a DWORD in the registry at:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;HKLM\SYSTEM\CurrentControlSet\Services\wbengine\SystemStateBackup\AllowSSBToAnyVolume&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and set the value to 1.  This allows you to backup to a source drive of the backup. The TechNet article says there can be issues with this, but allows you to do it anyway and from what I can tell does not have issues.  This is a bit frightening, but seems to be the best we can do with the tools provided.&lt;br /&gt;&lt;br /&gt;If you have the space, you can also backup the entire machine with a job defined through the GUI (or wbadmin). This will allow you to restore to the machine the backup was pulled from. It is good idea to have both this kind of backup and the system state backup.&lt;br /&gt;&lt;br /&gt;Microsoft would ultimately like to sell you their &lt;a href="http://technet.microsoft.com/en-us/dpm/default.aspx"&gt;System Center Data Protection Manager&lt;/a&gt; (DPM) product and that is why there are not as many options for wbadmin as there were for ntbackup.  We don't need (or have the hardware to support) DPM here, so we are currently making do with some wbadmin and some scripts cobbled together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-2019777591601307637?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=2019777591601307637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/2019777591601307637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/2019777591601307637'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2008/10/all-information-you-need-can-be-pulled.html' title='Windows Server 2008 Domain Controller Backup'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-8077518915313621671</id><published>2008-10-14T10:41:00.001-04:00</published><updated>2009-04-03T21:43:08.188-04:00</updated><title type='text'>Good Software</title><content type='html'>One of the guys on a private mailing list asked about what software people couldn't live without.  Here's my list.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.flos-freeware.ch/notepad2.html"&gt;Notepad2&lt;/a&gt; - I rename it to n2 and put it in my PATH.  Then it is just a WindowsKey + R, n2 away. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1843"&gt;Firebug&lt;/a&gt; - Couldn't style a webpage without it.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://sourcegear.com/diffmerge/"&gt;DiffMerge&lt;/a&gt; - Comparing versions of code is pretty and easy. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.pigdin.im/"&gt;Pidgin&lt;/a&gt; - Allows me to be on MSN and Google Talk. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://jgpaiva.donationcoders.com/gridmove.html"&gt;GridMove&lt;/a&gt; - I have a 1920x1200 screen which is too much real estate to only use one window at a time, but Windows doesn't have a good way to manage my application windows. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Depending on what I am working on, either &lt;a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx"&gt;VS 2008&lt;/a&gt;, or &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; + &lt;a href="http://ctags.sourceforge.net/"&gt;ctags&lt;/a&gt;. &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-8077518915313621671?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=8077518915313621671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8077518915313621671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8077518915313621671'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2009/04/good-software.html' title='Good Software'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-6608609076049078549</id><published>2008-10-03T21:33:00.001-04:00</published><updated>2009-04-03T21:36:44.203-04:00</updated><title type='text'>Powershell Tricks</title><content type='html'>Here are two things that I haven't found written about other places, but that are hinted at in the help for New-Object.&lt;br /&gt;&lt;br /&gt;Open an explorer window in the current directory:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;gt; $shell = New-Object -comObject shell.application&lt;br /&gt;&amp;gt; $shell.Explore("$(resolve-path .)")  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;You can present a folder selection dialog to a user:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;gt; $shell.BrowseForFolder(0, "Title", 0, "c:\") | get-member&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   TypeName: System.__ComObject#{a7ae5f64-c4d7-4d7f-9307-4d24ee54b841}&lt;br /&gt;&lt;br /&gt;Name                       MemberType Definition&lt;br /&gt;----                       ---------- ----------&lt;br /&gt;CopyHere                   Method     void CopyHere (Variant, Variant)&lt;br /&gt;DismissedWebViewBarricade  Method     void DismissedWebViewBarricade ()&lt;br /&gt;GetDetailsOf               Method     string GetDetailsOf (Variant, int)&lt;br /&gt;Items                      Method     FolderItems Items ()&lt;br /&gt;MoveHere                   Method     void MoveHere (Variant, Variant)&lt;br /&gt;NewFolder                  Method     void NewFolder (string, Variant)&lt;br /&gt;ParseName                  Method     FolderItem ParseName (string)&lt;br /&gt;Synchronize                Method     void Synchronize ()&lt;br /&gt;Application                Property   IDispatch Application () {get}&lt;br /&gt;HaveToShowWebViewBarricade Property   bool HaveToShowWebViewBarricade () {get}&lt;br /&gt;OfflineStatus              Property   int OfflineStatus () {get}&lt;br /&gt;Parent                     Property   IDispatch Parent () {get}&lt;br /&gt;ParentFolder               Property   Folder ParentFolder () {get}&lt;br /&gt;Self                       Property   FolderItem Self () {get}&lt;br /&gt;ShowWebViewBarricade       Property   bool ShowWebViewBarricade () {get} {set}&lt;br /&gt;Title                      Property   string Title () {get}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Use above to select something:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;gt; $shell.BrowseForFolder(0, "Title", 0, "c:\").Self.Path&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb773205(VS.85).aspx"&gt;MSDN&lt;/a&gt; gives the information you need for the third argument.  It is a 'flags' field that can be any combo of ulFlags on that page.&lt;br /&gt;&lt;br /&gt;See $shell | Get-Member for more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-6608609076049078549?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=6608609076049078549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6608609076049078549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6608609076049078549'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2008/10/here-are-two-things-that-i-havent-found.html' title='Powershell Tricks'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-1781088637165441465</id><published>2007-06-11T15:52:00.000-04:00</published><updated>2009-04-03T21:32:59.031-04:00</updated><title type='text'>Creating an ASP.NET Membership Database for Community Server</title><content type='html'>With the addition of Morpheus in Community Server 2007, the ability to integrate CS and another ASP.NET site using the ASP.NET membership provider got a lot easier.  A recent KB article details sharing the same login and password data for multiple installations of Community Server.  The steps outlined there are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Install CS multiple times.  One install will be membership master, others are children.&lt;/li&gt;&lt;li&gt;Add a connection to the children's connectionStrings.config.&lt;/li&gt;&lt;li&gt;Modify the children's web.config.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This is super simple and works great for multiple communities.  To develop an ASP.NET web app and share the login with CS you need to take a few more steps.&lt;br /&gt;&lt;br /&gt;The basic steps needed to share a membership database with CS and an ASP.NET application are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Install/deploy your application.&lt;/li&gt;&lt;li&gt;    Install CS 2007.&lt;/li&gt;&lt;li&gt;    Take a few stored procedures from CS and add to your membership database.&lt;/li&gt;&lt;li&gt;    Modify CS connectionStrings.config.&lt;/li&gt;&lt;li&gt;    Modify CS web.config.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Install Your Application&lt;br /&gt;&lt;br /&gt;The key is the application must be configured to use ASP.NET Membership with the System.Web.Security.SqlMembershipProvider (or a custom provider that follows the provider model).  Since I am just testing this out, I used "aspnet_regsql.exe -E -S localhost -A m" as documented to create my membership database.  This gave me a new database named aspnetdb on my local instance of SQL Server.  I then went on to create a web application with two pages - a default.aspx and a login.aspx.  Default tells you whether you are logged in, and Login lets you login.  The zipped project can be downloaded here.&lt;br /&gt;Once that application is configured properly, take note of the connection string and the name attribute of the &amp;lt;authentication&amp;gt; &amp;lt;forms&amp;gt; element in web.config.&lt;br /&gt;&lt;br /&gt;Install CS 2007&lt;br /&gt;&lt;br /&gt;Nothing special here.  A default installation will work just fine.  You need to remember the application name (the default seems to be 'dev'), admin username, admin email, and admin password you use when installing the application.&lt;br /&gt;&lt;br /&gt;Take Stored Procedures from CS 2007&lt;br /&gt;&lt;br /&gt;This is where you do most of the work.  We need to execute some CREATE scripts as well as hack together a new one (or copy some data).&lt;br /&gt;&lt;br /&gt;Creating the Default Users&lt;br /&gt;&lt;br /&gt;Before you can use Community Server with another application, you need to provide the default users that CS assumes are available.  This can be done by modifying an existing stored procedure or by copying data.  I modified an existing procedure - cs_system_CreateCommunity.  I included something like lines 57-66, and 529-580 excluding 544-556 and 570-579.  Anything that dealt with the aspnet_Applications, Membership, or Users tables was included, and everything else was left out.  I then executed this procedure with application name and admin user information that was used when installing CS.&lt;br /&gt;&lt;br /&gt;It might be much easier copy the data from another database or use the aspnet_* stored procedures on the membership database.&lt;br /&gt;&lt;br /&gt;Copying the cs_Membership_* procedures&lt;br /&gt;&lt;br /&gt;Five stored procedures must be copied from the CS database to the membership database - they are the cs_Membership_* procedures that are created during the CS install.  I did this in SQL Management Studio by scripting the SPs as CREATE scripts and then executing them against my membership database.&lt;br /&gt;&lt;br /&gt;Modify CS Install&lt;br /&gt;&lt;br /&gt;Add a connection string to connectionStrings.config.  Change the name attribute in the &amp;lt;authentication&amp;gt; &amp;lt;forms&amp;gt; element.  Also change the connectionStringName in the &amp;lt;membership&amp;gt; &amp;lt;provider&amp;gt; attribute to match the values of the same elements from your application.&lt;br /&gt;Conclusion&lt;br /&gt;&lt;br /&gt;You can now create a user in your 'other' web application and when the visit the community pages of your site, they will automatically be logged in and able to interact just like they created their account on the CS install itself.&lt;br /&gt;&lt;br /&gt;Note: I have not yet used this method on a production site, nor have I fully tested it. I cannot guarantee that it will work in all situations. I am relatively confident that it will work fine for any site as CS is using the membership database only for the username and password, and stores everything else in other tables.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-1781088637165441465?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=1781088637165441465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/1781088637165441465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/1781088637165441465'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/06/creating-aspnet-membership-database-for.html' title='Creating an ASP.NET Membership Database for Community Server'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-6918233841464030862</id><published>2007-05-02T16:56:00.001-04:00</published><updated>2009-04-03T21:29:02.806-04:00</updated><title type='text'>Community Server *_override.config</title><content type='html'>Although there have been a couple examples of how to use the *_override.config files in Community Server floating around, I haven't found a good reference on what is available.  Fortunately, Telligent makes the source available for much of the CS platform.  Looking at how these files work resulted in the following longer than expected information.&lt;br /&gt;&lt;br /&gt;The first thing that must be recognized is the format of the override file.  The following schema is a rough approximation of what will work.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0"?&amp;gt; &lt;br /&gt;&amp;lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;gt; &lt;br /&gt;    &amp;lt;xs:element name="Overrides"&amp;gt; &lt;br /&gt;        &amp;lt;xs:sequence&amp;gt; &lt;br /&gt;            &amp;lt;xs:element name="Override"&amp;gt; &lt;br /&gt;                &amp;lt;xs:complexType mixed="true"&amp;gt;&lt;br /&gt;                &amp;lt;xs:attribute name="xpath" type="xs:string" use="required"/&amp;gt;&lt;br /&gt;                &amp;lt;xs:attribute name="mode" type="xs:string" use="required"/&amp;gt;&lt;br /&gt;                &amp;lt;xs:attribute name="name" type="xs:string"/&amp;gt;&lt;br /&gt;                &amp;lt;xs:attribute name="value" type="xs:string"/&amp;gt;&lt;br /&gt;                &amp;lt;xs:attribute name="where" type="xs:string"/&amp;gt;&lt;br /&gt;            &amp;lt;/xs:element&amp;gt;&lt;br /&gt;        &amp;lt;/xs:sequence&amp;gt;&lt;br /&gt;    &amp;lt;/xs:element&amp;gt;&lt;br /&gt;&amp;lt;/xs:schema&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The following operations (values for mode) are available to alter attributes within the configuration files.&lt;br /&gt;&lt;br /&gt;  1. new&lt;br /&gt;&lt;br /&gt;     Creates a new attribute on the node selected with the xpath expression.  The name,value pair of the attribute are specified as name and value in the &lt;override&gt; element.  If the attribute already exists an exception is thrown.&lt;br /&gt;&lt;br /&gt;  2. change&lt;br /&gt;&lt;br /&gt;     Replaces the value of the attribute with the one specified in the &lt;override&gt; element.  The attribute must exist or an exception is thrown.&lt;br /&gt;&lt;br /&gt;  3. remove&lt;br /&gt;&lt;br /&gt;     Deletes the attribute from the element.  The attribute must exist or an exception is thrown.&lt;br /&gt;&lt;br /&gt;The following operations (values for mode) are available to change elements within the configuration files.  They all ignore the name and value attributes in the override element you are creating.&lt;br /&gt;&lt;br /&gt;  1. add&lt;br /&gt;&lt;br /&gt;     The content inserted is the InnerXML of the Override element.  This is the only place that the where attribute can be used, and only one value is valid.  If you specify where="start" then it will be added as the first child of the node selected by the xpath attribute, otherwise it will be added as the last child of the selected node.  It would be nice if the where attribute could also be a xpath expression that would allow the element to be inserted as a sibling at the point selected by the where expression.&lt;br /&gt;&lt;br /&gt;  2. update&lt;br /&gt;&lt;br /&gt;     Simply replaces the content of the node selected by the xpath with InnerXML of the Override element.&lt;br /&gt;&lt;br /&gt;  3. remove&lt;br /&gt;&lt;br /&gt;     Deletes all descendent nodes of the selected element.  Be careful with this one as you can remove a bunch of elements without realizing it.&lt;br /&gt;&lt;br /&gt;&lt;/override&gt;&lt;/override&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-6918233841464030862?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=6918233841464030862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6918233841464030862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6918233841464030862'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/05/although-there-have-been-couple.html' title='Community Server *_override.config'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-416480701518118033</id><published>2007-03-30T15:13:00.001-04:00</published><updated>2007-03-30T15:36:57.494-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calendar'/><category scheme='http://www.blogger.com/atom/ns#' term='Community Server 2.1'/><title type='text'>CS: Date Chooser TinyMCE Plugin</title><content type='html'>&lt;p&gt;The &lt;a href="http://communityserver.org/files/folders/csmodules/entry513095.aspx"&gt;calendar&lt;/a&gt; component for &lt;a href="http://communityserver.org/"&gt;Community Server&lt;/a&gt; is great.&amp;nbsp; It allows the integration of the forum posts and calendar events.&amp;nbsp; You can create an event about about the "Party at Joe's" and then the discussion of who brings the party supplies can occur on the forum.&amp;nbsp; &lt;a href="http://www.danbartels.com/Default.aspx"&gt;Dan&lt;/a&gt; even provided an extension to FreeTextBox that enables a date chooser dialog.&amp;nbsp; The only issue is that CS now uses TinyMCE as the editor and the latest version of FTB so that Dan's extension no longer works.&amp;nbsp; So I created a Date Chooser plugin for TinyMCE to solve this problem.&lt;/p&gt; &lt;p&gt;Download it &lt;a href="http://www.atgi.com/jeffesp/download.html"&gt;here&lt;/a&gt; - see Readme.txt for install instructions.&amp;nbsp; Read on for some implementation details.&lt;/p&gt; &lt;p&gt;Since I needed a modal dialog just like the content selector in CS I started by copying and renaming the directory for that plugin.&amp;nbsp; I also copied the image for the date picker out of Dan's FTB extension.&amp;nbsp; Once armed with these two pieces of the puzzle I did the following.&lt;/p&gt; &lt;p&gt;Edit editor_plugin.js to refer to DatePicker instead of ContentSelector where relevant and change the implementation of the open and addContent methods in the date picker class.&amp;nbsp; The code looks like this:&lt;/p&gt;&lt;textarea class="js:nogutter" name="code" columns="70"&gt;&lt;br /&gt;execCommand : function(editor_id, element, command, user_interface, value) {&lt;br /&gt;    switch (command) {&lt;br /&gt;        case "csDatePicker":             &lt;br /&gt;            TinyMCE_DatePickerPlugin._openDatePicker(editor_id);&lt;br /&gt;            return true;&lt;br /&gt;     }          &lt;br /&gt;        // Pass to next handler in chain      &lt;br /&gt;        return false;&lt;br /&gt;},&lt;br /&gt;_openDatePicker : function(editor_id) {   &lt;br /&gt;    TinyMCE_DatePickerPlugin._currentEditor = tinyMCE.getInstanceById(editor_id);   &lt;br /&gt;    TinyMCE_DatePickerPlugin._currentBookmark = this._currentEditor.selection.getBookmark();       &lt;br /&gt;    &lt;br /&gt;    Telligent_Modal.Open('/calendar/MCEDatePicker.aspx', 400, 250, this._addContent);  },     &lt;br /&gt;&lt;br /&gt;_addContent : function(content) {      &lt;br /&gt;    if (content != null) {          &lt;br /&gt;        TinyMCE_DatePickerPlugin._currentEditor.selection.moveToBookmark(this._currentBookmark);        &lt;br /&gt;        TinyMCE_DatePickerPlugin._currentEditor.execCommand("mceInsertRawHTML", false, content);   &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;  &lt;p&gt;The main things to note are line the call to Telligent_Modal.Open() and execCommand call in _addContent.&amp;nbsp; The open call loads the modal dialog - with a size and a callback of the _addContent function.&amp;nbsp; The execCommand() call takes the content from the dialog and inserts it in the editor pane of the current post.&lt;/p&gt; &lt;p&gt;MCEDatePicker.aspx is not very interesting.&amp;nbsp; It contains a Generic control that loads the MCEDatePickerModal.ascx skin.&amp;nbsp; This file is much more interesting. The first thing to examine is the markup:&lt;/p&gt;&lt;textarea class="html:nogutter" name="code" columns="70"&gt;&lt;br /&gt;&amp;lt;div align="center" style="padding: 10px"&amp;gt;     &lt;br /&gt;    &amp;lt;CA:Calendar runat="server" ID="Calendar1" SelectedDate='&amp;lt;%# DateTime.Today %&amp;gt;' &lt;br /&gt; CalendarCssClass="calendar" DayCssClass="day" DayHoverCssClass="dayhover" &lt;br /&gt; SelectedDayCssClass="selectedday" ShowNextPrev="true" &lt;br /&gt; NextImageUrl='&amp;lt;%# CommunityServer.Components.Globals.GetSkinPath() + "/images/calendar/next_wht.gif" %&amp;gt;'&lt;br /&gt; PrevImageUrl='&amp;lt;%#  CommunityServer.Components.Globals.GetSkinPath() + "/images/calendar/prev_wht.gif" %&amp;gt;'&amp;gt;     &lt;br /&gt;    &amp;lt;/CA:Calendar&amp;gt; &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;br /&gt;&amp;lt;div align="right"&amp;gt;&lt;br /&gt; &amp;lt;asp:Button ID="bSelect" runat="server" Text="Select Date" OnClientClick="ReturnDate()" /&amp;gt;     &lt;br /&gt; &amp;lt;asp:Button ID="bCancel" runat="server" Text="Cancel" OnClientClick="window.parent.Telligent_Modal.Close(null);" /&amp;gt; &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/textarea&gt;&lt;p&gt;This code displays a ComponentArt Calendar control and a couple buttons that act on the control.&amp;nbsp; We end up with this modal dialog that allows you to pick a date from the calendar view.&lt;/p&gt; &lt;p&gt;The _addContent callback implemented above will run when the modal dialog is closed. It is closed with the following code which is renedered to the client as the page is loaded:&lt;/p&gt;&lt;textarea class="js:nogutter" name="code" columns="70"&gt;&lt;br /&gt;function ReturnDate() {  &lt;br /&gt;    var newDate =  Calendar1.ClientID.FormatDate(Calendar1.ClientID.GetSelectedDate(), '[cal]MM-dd-yyyy[/cal]');  &lt;br /&gt;       if(newDate.length &amp;gt; 0)   &lt;br /&gt;            window.parent.Telligent_Modal.Close(newDate);  &lt;br /&gt;       else   &lt;br /&gt;            window.parent.Telligent_Modal.Close(null); &lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;  &lt;p&gt;As you might guess when looking at this code Calendar1.ClientID doesn't exist in the client code. This bit of javascript is dynamically created on the server and registered as a script block using the ClientID property.&amp;nbsp; The key thing to note in this code is the call to the Telligent_Modal.Close() function.&amp;nbsp; When called, this will in turn run the callback specified for the modal when it was opened - inserting the date into the editor.&lt;/p&gt; &lt;p&gt;The last piece of the puzzle requires adding the calendar button to the interface.&amp;nbsp; Part of this is setup in editor_plugin.js and part of it is done by changing the skin used for the editor.&amp;nbsp; In the Editor-Standard and Editor-Enhanced skin files, the 'datepicker' plugin was added to the plugins and theme_advanced_buttons1_add options on the editor control.&lt;/p&gt; &lt;p&gt;Many thanks to my employer (&lt;a href="http://www.atgi.com/"&gt;ATGi&lt;/a&gt;) since I developed this on work time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-416480701518118033?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=416480701518118033' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/416480701518118033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/416480701518118033'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/cs-date-chooser-tinymce-plugin.html' title='CS: Date Chooser TinyMCE Plugin'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-6223408476844887363</id><published>2007-03-22T12:37:00.001-04:00</published><updated>2007-03-26T11:50:54.244-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Community Server 2007'/><category scheme='http://www.blogger.com/atom/ns#' term='themes'/><title type='text'>Community Server 2007 Themes - Part 3</title><content type='html'>The first thing you encounter when you load the default community server site is the home page.&amp;nbsp; This is mainly controlled by the "main" master page with a couple small changes in the "home" master page.&amp;nbsp; I want to pick apart one portion of the header in the "main" master page and make a small change to it in my process of learning about themes in CS 2007.  &lt;h5&gt;Master.Master&lt;/h5&gt;The header and footer have all kinds of content specified that will show based on various configuration values and conditions.These serve as a great introduction to the new capabilities in CS 2007. Look at the “CommonTitleBarSearchArea” &amp;lt;td&amp;gt; in the header. This section is a great introduction to the new controls implemented in CS 2007.&lt;br /&gt;First we have a user control: &lt;br /&gt;&lt;textarea name='code' class="html:nogutter"&gt;&amp;lt;div class="CommonUserArea"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;div id="welcome"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSUserControl:UserWelcome runat="server" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/textarea&gt;&lt;br /&gt;Nothing special is going on here.Continuing in the code, we have the beginning of the search form control.The properties of the control are mapped to the other controls on the page. &lt;br /&gt;&lt;textarea name='code' class="html:nogutter"&gt;&amp;lt;div class="CommonSearch"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:SearchForm runat="server"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;QueryFilterDropDownListId="TitleBarSearchDropDownList"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;QueryTextBoxId="TitleBarSearchText" SubmitButtonId="TitleBarSearchButton"&amp;gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;The SearchForm is not limited to a static layout - the FormTemplate portion begins by laying out a table:&lt;br /&gt;&lt;textarea name="code" class="html:nogutter"&gt;&amp;lt;FormTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;table cellpadding="0" cellspacing="0" border="0" align="right"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;tr valign="middle"&amp;gt;&lt;/textarea&gt;&lt;br /&gt;And then it continues by defining two controls in the first &amp;lt;td&amp;gt;.Those controls are the text box for the search, and an ASP drop down list.The things to note here are the following: &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The id’s match the declaration in the SearchForm control.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is a PlaceHolder control wrapping the drop-down list. Its purpose is to control the visibility of the drop-down.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The ResourceControl control is going to pull the text that it displays from the specified resource name in the current resource culture.The “TitleBar_SearchIn” element in resources.xml for the current culture provides the values for the drop-down list. I am not sure how exactly the resource values are tied to the drop-down list. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;textarea name='code' class="html:nogutter"&gt;&amp;lt;td nowrap="nowrap"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:DefaultButtonTextBox ID="TitleBarSearchText" runat="server" Columns="15" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MaxLength="64" ButtonId="TitleBarSearchButton" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:PlaceHolder runat="server"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;DisplayConditions&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:ControlVisibilityCondition ControlId="TitleBarSearchDropDownList"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ControlVisiblilityEquals="true" runat="server" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/DisplayConditions&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ContentTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:ResourceControl runat="server" ResourceName="TitleBar_SearchIn" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;asp:DropDownList runat="server" ID="TitleBarSearchDropDownList" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ContentTemplate&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/CSControl:PlaceHolder&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/td&amp;gt;&lt;/textarea&gt;&lt;br /&gt;The next table cell is a little simpler – it only has the search button in it.Again, note the matching id, and that the link button is using the culture to provide internationalization of the “Search” text through the resources file. &lt;br /&gt;&lt;textarea name='code' class="html:nogutter"&gt;&amp;lt;td&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;span class="CommonSearchButtonOuter"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:ResourceLinkButton ID="TitleBarSearchButton" runat="server"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CssClass="CommonSearchButton" ResourceName="Search" /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/td&amp;gt;&lt;/textarea&gt;&lt;br /&gt;In these few lines of code there have been a number of new things that have a great deal of power behind them. Some of them are:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;The ability to control visibility through DisplayConditions, &lt;br /&gt;&lt;li&gt;The ability to provide your own templates for standard controls – like the template for the search in the SearchForm. &lt;br /&gt;&lt;li&gt;And the ability to declare controls that pull the text presented to the user from the Resources file which will provide for an internationalized interface. &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;h5&gt;Making a Change to the Search Box&lt;/h5&gt;&lt;br /&gt;If you wanted to display the search box only for registered users when they are logged in, you could do something like what I would do in ASP.NET - add some code that executes on databinding for the Visible property of the control.&amp;nbsp; It would need to get an instance of the user object and check its roles attribute. But CS provides a better way - we alreadly looked at it - the &amp;lt;DisplayConditions&amp;gt; element of a CSControl.&amp;nbsp; Adding this snippet of code:&lt;br /&gt;&lt;textarea name='code' class="html:nogutter"&gt;&amp;lt;DisplayConditions&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;CSControl:UserInRoleCondition Role="Registered Users" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UseAccessingUser="true" runat="server" /&amp;gt;&lt;br /&gt;&amp;lt;/DisplayConditions&amp;gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;will make it so the search is only available to member. This is so easy.&lt;br /&gt;&lt;h5&gt;Moving Forward&lt;/h5&gt;&lt;br /&gt;This is the end of my initial investigation into CS 2007 themes.&amp;nbsp; I am planning on continuing this work by creating a theme (even though I am no designer) and moving away from Blogger to a new site running CS with that theme. I am especially interested in trying out &lt;a href="http://blogmailr.com/"&gt;BlogMailr&lt;/a&gt; with it as well because I am tried writing posts in textareas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-6223408476844887363?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=6223408476844887363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6223408476844887363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/6223408476844887363'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/community-server-2007-themes-part-3.html' title='Community Server 2007 Themes - Part 3'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-8546002626566888531</id><published>2007-03-22T09:19:00.001-04:00</published><updated>2007-03-22T09:33:07.827-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Community Server 2007'/><category scheme='http://www.blogger.com/atom/ns#' term='themes'/><title type='text'>Community Server 2007 Themes - Part 2</title><content type='html'>&lt;h5&gt;Master Pages&lt;/h5&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;The initial intent of this post was to show diagrams of the Main, Blogs, Files, Forums, and Photos master pages in Community Server 2007 (in the style of &lt;span style="color:#800080;"&gt;&lt;a href="http://jeffesp.blogspot.com/2007/03/master-pages-in-community-server.html"&gt;this post&lt;/a&gt;&lt;/span&gt;).&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;I find a visual representation of the page is very helpful to me so I took some time to investigate the layout of the pages and create diagrams. As I dug into the new master pages I found the main pages for the Blogs, etc. are not very interesting. Each page basically added the main content (such as the forum list) and a few items in the sidebar. These are all obvious looking at the rendered page. So I want to spend most of this post dedicated to the Main master page. &lt;/p&gt;&lt;h5&gt;Main&lt;/h5&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;Changing my diagram from CS 2.1 to match CS 2007 results in the following:&lt;/p&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;&lt;a href="http://bp1.blogger.com/_rUnj-QbnFdw/RgKCwozrKLI/AAAAAAAAABA/ev6mJiGcMpM/s1600-h/CSMasterPage2k7.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5044738304707864754" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp1.blogger.com/_rUnj-QbnFdw/RgKCwozrKLI/AAAAAAAAABA/ev6mJiGcMpM/s320/CSMasterPage2k7.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;The first thing to note is this is an ASP 2.0 Master page.&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;Community Server is .Net 2.0 only, instead of allowing .Net 1.1 or 2.0 deployment like CS 2.1.&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;Differences between the new and old seem to be minimal once you are past the use of ASP master pages instead of the custom master pages.&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;The following image is a comparison of the two pages. &lt;/p&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;&lt;a href="http://bp0.blogger.com/_rUnj-QbnFdw/RgKESYzrKOI/AAAAAAAAABY/qCNRpahUBCw/s1600-h/MasterPageLayoutCompare.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_rUnj-QbnFdw/RgKESYzrKOI/AAAAAAAAABY/qCNRpahUBCw/s320/MasterPageLayoutCompare.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5044739984040077538" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="MARGIN: 0in 0in 10pt"&gt;The change that sticks out in this comparison is the addition of a placeholder around the left and right content regions. Since CS 2007 allows for three different site layouts (3 column, 2 column with left for main content, 2 column with for main content), the other main changes to the main master page support this using the placeholders. Looking at this diagram it seems like there really isn’t much change – the body table is really only missing two &amp;lt;td&amp;gt; elements one for the right column and one for the left.But the real change is actually at the top of the file in the Page_Init method. It adds the missing &amp;lt;td&amp;gt; elements based on the configuration. One thing to note is that the “left” content renders above the “right” content when configured for either 2 column mode.&lt;/p&gt;&lt;h5&gt;Blogs&lt;/h5&gt;&lt;p&gt;Since the Blog main page wasn't very interesting, I went to look for an individual blog master page. What I found here wasn't entirely surprising. Each blog theme has a master page, and a whole set of styling information. The dynamic style aspx that I talked abut in my last post is used here as well. &lt;/p&gt;&lt;p&gt;The main difference in 2007 is in the number of files that need to be changed to create a theme - it looks like you can create a theme in 10-12 files including a preview image for the control panel and a print CSS. &lt;a href="http://getben.com/archive/2007/01/09/introduction-to-chameleon-differences-from-cs2-1.aspx"&gt;Ben Claims 8&lt;/a&gt; files are all you need - I got my number from inspecting the distributed themes. My guess is this is a difference in number of files required to make a theme, and the number that make a theme with extra images, etc. Either way, it is still a huge decrease from the 55 that were a part of the theme in CS 2.1.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-8546002626566888531?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=8546002626566888531' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8546002626566888531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8546002626566888531'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/community-server-2007-themes-part-2.html' title='Community Server 2007 Themes - Part 2'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_rUnj-QbnFdw/RgKCwozrKLI/AAAAAAAAABA/ev6mJiGcMpM/s72-c/CSMasterPage2k7.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-8929017212351127042</id><published>2007-03-20T16:06:00.000-04:00</published><updated>2007-03-22T09:35:13.012-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Community Server 2007'/><category scheme='http://www.blogger.com/atom/ns#' term='themes'/><title type='text'>Community Server 2007 Themes – Part 1</title><content type='html'>I am currently learning about the new theme system (Chameleon) in Community Server 2007. There are a number of good resources on this around the web. I hope that this will be one more. I am going to start with the basic theme capabilities and the layout of the site, and then move to the more complex portions of Chameleon as I encounter them.&lt;br /&gt;&lt;h4&gt;Theme Creation&lt;/h4&gt;&lt;br /&gt;Themes have changed quite a bit in CS 2007. The first thing that you run into with the themes is the new interface in the Control Panel to change the theme. To have a style to work from, I picked my corporate site (&lt;a href="http://www.atgi.com"&gt;ATGi&lt;/a&gt;). I was able to change the CS site from the default theme to something decently close to our corporate site with only a few minutes work. The steps I followed were outlined on &lt;a href="http://getben.com/archive/2007/02/15/creating-new-themes-in-cs2007.aspx"&gt;Ben Tiedt’s Blog&lt;/a&gt;. All that I had to do was enter the color codes I pulled from the source site in the right place, save, and preview my changes. As the last step, Ben tells us we need to update theme.config but doesn’t tell us why. I am going to guess one reason is the default values are used for the "reset to defaults" function in the theme configuration section of the control panel.&lt;p style="TEXT-ALIGN: center" align="center"&gt;&lt;a href="http://bp1.blogger.com/_rUnj-QbnFdw/RgA_kIzrKKI/AAAAAAAAAA4/uaCUYCeQ7VE/s1600-h/CS2k7ATGi.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5044101472727017634" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp1.blogger.com/_rUnj-QbnFdw/RgA_kIzrKKI/AAAAAAAAAA4/uaCUYCeQ7VE/s320/CS2k7ATGi.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;It looks like the CS developers took the path of making the easy things easy and the difficult things possible with this update to the theme system. I don’t know if they will come through in the screenshot, but the bullets in the right content area are still the default theme’s dark green.&lt;br /&gt;In order to change them I needed to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Find the CSS class for the bullets,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Find that class in Common.css,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;And then add the right content to the CSS Overrides configuration area of the theme.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p style="TEXT-INDENT: 0.25in"&gt;Here’s what I added to the theme to change the bullets: &lt;/p&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;UL.CommonSidebarList LI&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;{&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;color: #c54545;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;Since the CS developers couldn’t predict what users want to change, they provided a method to change pretty much any part of the site without violating the idea of managing the theme through the Control Panel. Just by the addition of that one text area, they have made it so I should never touch the base CSS files again.&lt;h4&gt;Theme Application&lt;/span&gt;&lt;/h4&gt;So far we have a good start, but there are some things going on behind the scene to get the changes made to the theme applied to the site. What follows is a summary of some of that information. I am not sure any of this information is necessary when creating a theme but it is useful to know how changes in one area propagate through the system.&lt;br /&gt;Theme changes made in the Control Panel interface are saved to the Community Server database in the cs_ThemeConfigurationData table. It looks to be stored as a list of property names and a list of property values. I assume there is deserialization code and/or a data provider for this information. (Side note: There is also a cs_ThemeConfigurationData_TEMP table that I can only assume is used for the "Live Preview" function). To see where this data is used we need to look for is the stylesheets that are applied to the site. If we look in the main master page for the theme (master.Master), we see the following:&lt;blockquote&gt;&lt;br /&gt;&lt;div style="font-family:courier new;"&gt;&amp;lt;CSControl:Style runat="server" visible = "true" /&amp;gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family:courier new;"&gt;&amp;lt;CSControl:Style runat="server" visible = "true" Href="../style/Common.css" /&amp;gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family:courier new;"&gt;&amp;lt;CSControl:Style runat="server" href="../style/common_print.css" media="print" /&amp;gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="font-family:courier new;"&gt;&amp;lt;CSControl:Style runat="server" Href="../style/DynamicStyle.aspx" EnsureNotCachedOnPreview="true" /&amp;gt;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The first three lines look pretty standard to any web developer – they are the inclusion of some styling information for the screen and for print. The last one is the interesting one. An aspx page is specified as the file containing the styling information. Looking at this file, we see the clever thing done to apply the information saved in the theme. Each CSS class is defined with some server side code. When it executes, it will pull information from the theme data (with an optional default). Here’s the body/html class:&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;div&gt;body, html&lt;/div&gt;&lt;br /&gt;&lt;div&gt;{&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;div&gt;background-color: &amp;lt;%= ColorTranslator.ToHtml(ThemeData.GetColorValue("siteBackgroundColor", ColorTranslator.FromHtml("#606060"))) %&amp;gt;;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;background-image: &amp;lt;%= UrlOrNone(ThemeData.GetUrlValue("siteBackgroundImage", null))%&amp;gt;;&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div&gt;}&lt;/div&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;The background color and image are loaded with the ThemeData.Get*Value() methods. Without access to the code I can’t say for sure, but my guess is the provider for the theme data first tries the database, and failing that uses any defaults specified. I also can’t say where or if the defaults provided in theme.config are used in this process. The ThemeData is an instance of the Telligent ConfigurationDataBase class, which has Get/Set methods for some of the basic types (int, bool, string, object), some more complex types (DateTime, Guid), as well as some interesting web specific ones (Url, Color).&lt;h4&gt;Next Time&lt;/h4&gt;&lt;p&gt;I am going to go through the master pages and see what is going on with them. I hope to create a set of diagrams like in my last post on Community Server, but one for each section of the application (home, blogs, forums, etc).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-8929017212351127042?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=8929017212351127042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8929017212351127042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/8929017212351127042'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/community-server-2007-themes-part-1-i.html' title='Community Server 2007 Themes – Part 1'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_rUnj-QbnFdw/RgA_kIzrKKI/AAAAAAAAAA4/uaCUYCeQ7VE/s72-c/CS2k7ATGi.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-7132815956817012623</id><published>2007-03-20T14:10:00.001-04:00</published><updated>2007-03-27T09:30:33.882-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='developer tools'/><category scheme='http://www.blogger.com/atom/ns#' term='ftp'/><title type='text'>Windows Explorer FTP</title><content type='html'>&lt;p&gt;Uploading a new site to an FTP server is fun.&amp;nbsp; Here's what we do:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Login to the site through Windows Explorer,  &lt;li&gt;Select all files on local staging server,  &lt;li&gt;Copy files to server.  &lt;li&gt;Wait (copy dialog is telling me estimated 2 minutes),  &lt;li&gt;Wait (copy dialog is telling me estimated 5 more minutes),  &lt;li&gt;Wait (copy dialog is telling me estimated&amp;nbsp;6 more minutes),  &lt;li&gt;Cancel Transfer.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I must have waited at least 30 minutes for the transfer to complete.&amp;nbsp; The estimated times are total lies.&amp;nbsp; Here's the solution to the problem:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Google "FTP Client",  &lt;li&gt;Download &lt;a href="http://filezilla.sourceforge.net/" target="_blank"&gt;FileZilla&lt;/a&gt;,  &lt;li&gt;Install,  &lt;li&gt;Login to FTP server,  &lt;li&gt;In the Transfer menu, select Overwrite &amp;gt; Overwrite If Newer  &lt;li&gt;Select latest files,  &lt;li&gt;Copy files to server,  &lt;li&gt;Wait ~5 minutes for transfer to complete.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The right tools make all the difference.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-7132815956817012623?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=7132815956817012623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7132815956817012623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/7132815956817012623'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/windows-explorer-ftp.html' title='Windows Explorer FTP'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-9108902114948259724</id><published>2007-03-09T15:18:00.001-05:00</published><updated>2007-03-20T16:34:56.190-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Community Server 2.1'/><category scheme='http://www.blogger.com/atom/ns#' term='themes'/><title type='text'>Master Pages in Community Server</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;p&gt;I have been working on small &lt;a title="Community Server" href="http://communityserver.org/"&gt;Community Server&lt;/a&gt; project and learning a bit about the way they do things. The problem I needed to solve a couple days ago dealt with the requirement that some content show up on all pages in the system. This seems like a no brainer - just add some content to Master.ascx in the current theme and be done with it. The issue is the definition of all. If I add content to the main master page, it will show up on every single page including pages like login and logout. This was not the intent of the requirement even though it was the wording of the requirement. So I needed to add this content to the all* pages. Where the * implies the content doesn't show up on pages where it does not make sense. Faced with the option of adding the content to individual pages or individual master pages, which would be a maintenance pain, I came up with the following solution.&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Add a new CS:MPSection to Master.ascx; give it the id "rcrcommon".&lt;br /&gt;&lt;li&gt;Create a new master page - call it RightContentMaster.ascx. RightContentMaster has the shared content on it and uses Master.ascx as its master page. The shared content is in a CS:MPContent control with the id "rcrcommon". I changed HomeMaster, BlogMaster, ForumMaster, etc. to use RightContentMaster as their ThemeMasterFile.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;This allowed pages that rely solely on Master.ascx for layout to continue to function and display as they always have, but added my new content to the rest of the pages in the system. The reason this works is the inheritance of the master pages that CS has provided and the way I was able to insert my new master page into that rendering pipeline so only the pages I need get the content, but it is on 90% of the pages in the site.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I decided I needed to know more about how the master pages in CS work and how I can work with them. I started by reading &lt;a href="http://gabe19.blogspot.com/2006/07/overview-of-customizing-community.html"&gt;Jeff's overview post&lt;/a&gt; on this topic to get a baseline for what is going on with the system:&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;The most common base implementation of a master page is of 3 sections called 'lcr' (left side content), 'bcr' (body content, and 'rcr' (right side content). You can either define controls for every descendent page in these sections in the master page, or override master page content by declaring CS:MPContent controls with these ids on your aspx page. Skins should not implement these content controls. For example, if you wanted to understand how each thing is showing up on default.aspx, you would open default.aspx and find the 'ThemeMasterFile' attribute on the page level CS:MPContainer control. If you navigate to the HomeMaster.ascx file you'll see that the only thing being added here are some style includes in a "HeaderRegion", and the 3 content sections.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;Jeff tells us that a page using a master file has two important things it can do.&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;"define controls for every descendent page in these sections in the master page"&lt;br /&gt;&lt;li&gt;"override master page content by declaring CS:MPContent controls with [the same] ids on your aspx page"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Looking at Master.ascx in CS, we find a page with the following layout:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://bp1.blogger.com/_rUnj-QbnFdw/RfHBazlXLyI/AAAAAAAAAAo/NZ8eCe2sOIE/s1600-h/MasterPageLayout.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5040022124271972130" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp1.blogger.com/_rUnj-QbnFdw/RfHBazlXLyI/AAAAAAAAAAo/NZ8eCe2sOIE/s320/MasterPageLayout.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The regions highlighted in blue are the ones most often changed, but there are a bunch of things that can be done with this layout including changing headers and footers and even adding content outside of the page form.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Armed with this knowledge, I made the changes outlined above. An updated diagram of Master.ascx looks like this:&lt;/p&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://bp3.blogger.com/_rUnj-QbnFdw/RfHBiTlXLzI/AAAAAAAAAAw/ovH94BY68Gc/s1600-h/MasterPageLayout2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5040022253120991026" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp3.blogger.com/_rUnj-QbnFdw/RfHBiTlXLzI/AAAAAAAAAAw/ovH94BY68Gc/s320/MasterPageLayout2.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;My RightContentMaster page overrides the rcrcommon content area to add my content to most of the pages. Here are the advantages of this method as I see them:&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;I can control the pages where this content is shown by switching between RightContentMaster.ascx and Master.ascx as the base ThemeMasterFile.&lt;br /&gt;&lt;li&gt;I only have one place to edit this content (RightContentMaster.ascx).&lt;br /&gt;&lt;li&gt;If I ever need to change the content on a page I should be able to override the rcrcommon section with a new one.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;The main disadvantage that I see is the need to change other master pages to use RightContentMaster. If anyone has any thoughts on this way of doing things, I would love to hear them.&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-9108902114948259724?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=9108902114948259724' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/9108902114948259724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/9108902114948259724'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/master-pages-in-community-server.html' title='Master Pages in Community Server'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_rUnj-QbnFdw/RfHBazlXLyI/AAAAAAAAAAo/NZ8eCe2sOIE/s72-c/MasterPageLayout.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-4140239430225010336</id><published>2007-03-06T12:20:00.001-05:00</published><updated>2007-03-27T09:31:07.102-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='developer tools'/><category scheme='http://www.blogger.com/atom/ns#' term='symbolic link'/><title type='text'>Symbolic Links (Junctions) for NTFS</title><content type='html'>&lt;p&gt;This isn't anything new, but Sysinternals (now owned by Microsoft) released a tool called &lt;a href="http://www.microsoft.com/technet/sysinternals/FileAndDisk/Junction.mspx"&gt;junction&lt;/a&gt; that allows creation of symbolic links in NTFS.  If you aren't familiar with symbolic links, they are a Unix concept that makes a file or directory look like it resides in one place on the file system, when it really is someplace else.  This in itself isn't worth a blog post, but I think one thing that I recently did with it was pretty neat and wanted to write it up.  &lt;/p&gt;&lt;p&gt;I regularly use about 3 different computers.  Because of differences in hardware configuration the drive letter for my USB flash drive is different at each location.  So I created a new directory - &lt;span style="font-family:Courier New;font-size:85%;"&gt;C:\flash\&lt;/span&gt; - and then created a junction (symbolic link) pointing that directory to drive letter of my flash.  I see two benefits here.  One is that I don't have to remember what system I am on, and can just hit &lt;span style="font-family:Courier New;font-size:85%;"&gt;C:\flash&lt;/span&gt; whenever I need something from my drive.  The second advantage is that any programs I run from my flash can have a absoulte path to &lt;span style="font-family:Courier New;font-size:85%;"&gt;C:\flash&lt;/span&gt; for any data they need.&lt;/p&gt;&lt;p&gt;I have also added &lt;span style="font-family:Courier New;font-size:85%;"&gt;C:\flash\bin&lt;/span&gt; to my profile PATH so any utilities I have saved to my flash are only a &amp;lt;windows key&amp;gt;+r away.&lt;/p&gt;&lt;p&gt;Next up is moving &lt;span style="font-family:Courier New;font-size:85%;"&gt;C:\Documents and Settings\&lt;/span&gt; to another drive and creating a junction to point to it so I can blow away my install drive whenever I want and not worry about loosing any data.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-4140239430225010336?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=4140239430225010336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/4140239430225010336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/4140239430225010336'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2007/03/symbolic-links-junctions-for-ntfs.html' title='Symbolic Links (Junctions) for NTFS'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113564498500569927</id><published>2005-12-26T19:56:00.000-05:00</published><updated>2005-12-26T19:57:31.423-05:00</updated><title type='text'>Decision of the Day: A Ghost from Christmas Past</title><content type='html'>Just about to go watch &lt;a href="http://www.fox.com/arresteddev/"&gt;Arrested Development&lt;/a&gt;, and I went searching for &lt;a href="http://appellatedecisions.blogspot.com/"&gt;Bob Loblaw's Law Blog&lt;/a&gt;.  Apparently it is real.  Or pseudoreal, because it has content.  Not that I read it or anything.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113564498500569927?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113564498500569927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113564498500569927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113564498500569927'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/12/decision-of-day-ghost-from-christmas.html' title='Decision of the Day: A Ghost from Christmas Past'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113345276183884477</id><published>2005-12-02T17:05:00.000-05:00</published><updated>2005-12-02T16:09:19.333-05:00</updated><title type='text'>Unit Testing with ASP.NET 2.0</title><content type='html'>&lt;a href="http://gabe19.blogspot.com/2005/11/unit-testing-aspnet-20-forms-auth-site.html"&gt;Jeff&lt;/a&gt; figured out a major headache I was having when trying to run unit tests on the website I am working on. There are a number of things I think about this. First, how did the guys at Microsoft think that I would be able to unit test a site that uses forms authentication? Are they assuming no one actually uses forms authentication? I am sure the guys in Redmond are working the hardest to do things right, but I mean, come on. Have I missed something fundamental here? Why is it so difficult to unit test properly with the new testing framework?&lt;br /&gt;&lt;br /&gt;The saga continued when I got back to my office. See, the website we are working on was configured to run in IIS. When I fix my web.config so I can run tests with forms auth enabled, I suddenly get a error message saying that I am not an administrator and I shouldn't be running tests in IIS unless I am. See, I have set my development environment up so I can run and debug websites in IIS, even though I am just a lowly &lt;span style="FONT-STYLE: italic"&gt;user&lt;/span&gt;. I am not an administrator and I don't want to be. Many people have explained the benefits of running without administrator privileges, but here is Visual Studio telling me that I have to have them.&lt;br /&gt;&lt;br /&gt;So I relent and say that I will follow the recommendation of moving the website to run in Casini (the development web server, new in VS 2005) instead. I go looking for the 'Convert this Website to Casini' wizard so I can move on with my life. But this doesn't seem to exist. So I am stuck with deleting my old project from version control; creating a new project, this time using the internal development web server; checking that back into version control and moving on with my life.&lt;br /&gt;&lt;br /&gt;I don't want to sound entirely negative on the whole thing, I know that complex systems like this are very difficult to implement properly. I admire what has been accomplished. It seems like the testing framework is very complete, and will make my life easier once I learn it. But it also seems like some fundamental use cases were never written.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113345276183884477?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113345276183884477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113345276183884477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113345276183884477'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/12/unit-testing-with-aspnet-20.html' title='Unit Testing with ASP.NET 2.0'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113347655075716352</id><published>2005-12-01T17:33:00.000-05:00</published><updated>2005-12-01T17:35:50.783-05:00</updated><title type='text'>Photo: Rim of the World, near Yosemite National Park</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3698/1925/1600/row-yosemite-jeff-062-good-.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3698/1925/400/row-yosemite-jeff-062-good-.jpg" alt="" border="0" /&gt;&lt;/a&gt;Since 'development' is not only what I do for a living, but a hobby, I am going to include pictures on this blog as well.  Here's one from the road on the way into Yosemite National Park.  It was taken over a year ago, but it is still one of my favorite photos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113347655075716352?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113347655075716352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113347655075716352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113347655075716352'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/12/photo-rim-of-world-near-yosemite.html' title='Photo: Rim of the World, near Yosemite National Park'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113338137519771067</id><published>2005-11-30T14:57:00.000-05:00</published><updated>2005-11-30T15:14:36.060-05:00</updated><title type='text'>Errors when Running VS 2005 Unit Tests</title><content type='html'>[To keep things on the up and up: I am using beta software and it looks like this is fixed in the release.  I am still going to complain because I am still using the beta so I can integrate with Team System.]&lt;br /&gt;&lt;br /&gt;Here's a fun one. When you go to run tests in VS 2k5 occasionally an error dialog pops up. The text of the dialog says "Operation is not valid due to the current state of the object." Here's a screenshot:&lt;br /&gt;&lt;br /&gt;&lt;img alt="error dialog box" src="http://photos1.blogger.com/blogger/3698/1925/320/error_msg.jpg" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;As if there is only ever one object that has state.  And I know which object that is, and how to fix things.  &lt;br /&gt;&lt;br /&gt;So, how to fix this problem - delete your ProjectName.suo file.  First close VS, then delete it, then open your project again.  The .suo is regenerated, and you can then run the test.  &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=137501&amp;amp;SiteID=1"&gt;Here&lt;/a&gt; is where I found the solution (with thanks to &lt;a href="http://gabe19.blogspot.com"&gt;Jeff G.&lt;/a&gt; for help on this one.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113338137519771067?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113338137519771067' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113338137519771067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113338137519771067'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/11/errors-when-running-vs-2005-unit-tests.html' title='Errors when Running VS 2005 Unit Tests'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113336211181126677</id><published>2005-11-30T09:31:00.002-05:00</published><updated>2009-08-04T23:15:08.814-04:00</updated><title type='text'>Swap Control and Caps Lock</title><content type='html'>&lt;span style="font-weight:bold;"&gt;EDIT:&lt;/span&gt; You should use &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897578.aspx"&gt;Ctrl2Cap&lt;/a&gt; to do this!&lt;br /&gt;&lt;br /&gt;I come from a unix background. Therefore, I like my control to be where caps lock normally is. And just so it's still available, I like caps lock where control is. This is commonly referred to as swapping control and caps lock. &lt;a href="http://www.sun.com/"&gt;Sun&lt;/a&gt; does this all the time. Or at least used to. It's been years since I used one of their systems. On a windows system, this can be accomplished by swapping the functionality of the keys. &lt;a href="http://www.manicai.net/comp/swap-caps-ctrl.html"&gt;This page&lt;/a&gt; has all the details you need. Summary for the lazy: &lt;blockquote&gt;Add a binary registry key called "Scancode Map" at&lt;br /&gt;"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout" with the value of "00000000 00000000 03000000 3A001D00 1D003A00 00000000".&lt;/blockquote&gt;&lt;br /&gt;Anyhow, swapping the functionality of these two keys does a few things.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Reduces the distance my pinky travels to hit the control key. I used to use Emacs all day everyday - when you do that, it's essential that the control key is easily accessible. Even in a Windows world, it's still kind of nice since a lot of shortcuts use the control key.&lt;/li&gt;&lt;li&gt;Reduces the number of times that I mistakenly hit the CAPS LOCK KEY AND END UP WITH A BUNCH OF TEXT IN ALL CAPS.&lt;/li&gt;&lt;li&gt;Causes other people grief when they try to use my keyboard and end up with a 'S' in their document when all they wanted to do was save something by hitting 'Ctrl+s'.&lt;/li&gt;&lt;li&gt;Causes me grief because Remote Desktop is crap. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Just so we are clear here, I am talking about the control key at the bottom left of the keyboard. It's the only one I ever use. The one on the right side might as well not even exist.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113336211181126677?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113336211181126677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113336211181126677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113336211181126677'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/11/swap-control-and-caps-lock.html' title='Swap Control and Caps Lock'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19451733.post-113335987883802394</id><published>2005-11-30T09:07:00.000-05:00</published><updated>2005-11-30T10:57:00.803-05:00</updated><title type='text'>Errors with WSS 2.0</title><content type='html'>After installing WSS 2.0 on my system, everything seemed to work fine except Web Parts. None of them would display. The error message was:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;Web Part Error: This page has encountered a critical error. Contact your system administrator if this problem persists.&lt;/span&gt;&lt;/blockquote&gt;Searching through IIS logs didn't tell me anything. Looking online, I found a few newsgroup articles, and some forum posts about this error. On one forum, it said something about using ASP.NET v1.1 instead of ASP.NET v2.0. I only had the web service extension for 2.0 available, so I needed to go on a hunt for how to install the web service extension for 1.1. This was also fun because I didn't know what I was looking for at the time. But then I found this command on MSDN:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;"%windir%\Microsoft.NET\Framework\version\aspnet_regiis.exe" -i&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Fill in version with 1.1.xxxyyy and things almost magically work. After I did that, I needed to go in and change the version of ASP.NET that was used for WSS, then everything was dandy.As a side note, there are apparently a good number of options to aspnet_regiis.exe that are useful. This &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpgrfASPNETIISRegistrationToolAspnet_regiisexe.asp"&gt;page&lt;/a&gt; has all the gritty details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19451733-113335987883802394?l=jeffesp.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19451733&amp;postID=113335987883802394' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113335987883802394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19451733/posts/default/113335987883802394'/><link rel='alternate' type='text/html' href='http://jeffesp.blogspot.com/2005/11/errors-with-wss-20.html' title='Errors with WSS 2.0'/><author><name>Jeff Espenschied</name><uri>http://www.blogger.com/profile/07993506569382785387</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_rUnj-QbnFdw/Sdq9QZK3roI/AAAAAAAAAFU/Z0yCdfB0quA/S220/jeffesp.jpg'/></author><thr:total>3</thr:total></entry></feed>
