<?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-6958775774153114698</id><updated>2011-12-23T20:27:22.532-05:00</updated><category term='media'/><category term='fundamentals'/><category term='configuration tools'/><category term='integration'/><category term='customizations'/><title type='text'>Getting to Know Sitecore</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-5001012828455713954</id><published>2010-06-25T09:30:00.002-04:00</published><updated>2010-06-25T11:09:25.475-04:00</updated><title type='text'>This Blog Has Moved</title><content type='html'>Just wanted to let everyone know that as of this week, new posts to this blog can be located on the &lt;a href="http://www.sitecore.net/Community.aspx"&gt;Sitecore Community&lt;/a&gt;, under &lt;a href="http://www.sitecore.net/Community/Technical-Blogs.aspx"&gt;Technical Blogs&lt;/a&gt;.  Here's a &lt;a href="http://www.sitecore.net/Community/Technical-Blogs/Getting-to-Know-Sitecore.aspx"&gt;direct link&lt;/a&gt; to this blog at its new home.&lt;br /&gt;&lt;br /&gt;I've already posted a couple of articles:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/Community/Technical-Blogs/Getting-to-Know-Sitecore/Posts/2010/06/Using-Pipelines-With-UI-Customizations.aspx"&gt;Using Pipelines With UI Customizations&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/Community/Technical-Blogs/Getting-to-Know-Sitecore/Posts/2010/06/Local-Mail-Servers-and-Sitecore.aspx"&gt;Local Mail Servers &amp;amp; Sitecore&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-5001012828455713954?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/5001012828455713954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/06/this-blog-has-moved.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/5001012828455713954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/5001012828455713954'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/06/this-blog-has-moved.html' title='This Blog Has Moved'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-6981028437473151965</id><published>2010-05-27T08:00:00.004-04:00</published><updated>2010-05-27T13:47:01.005-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Keeping Media Metadata In Sync</title><content type='html'>When media files are uploaded to Sitecore, a Sitecore item is created.  This item represents the media file in Sitecore.  When you want to display information about the media file, you are displaying information about the item.  When the file is updated, Sitecore ensures that the fields on the item stay in sync with the file.&lt;br /&gt;&lt;br /&gt;Well, Sitecore does this for fields it is aware of.  This is handled by the Sitecore.Resources.Media.Media class (and the  classes that inherit from it). Thanks to the ImageMedia class, when you upload an image file, the height and width are read.  Sitecore does not include a class to handle Microsoft Word documents, so metadata from those files is NOT read.&lt;br /&gt;&lt;br /&gt;Creating a class to read metadata from Word documents, or any other file, is not hard to do.    Sitecore is already set up to allow it.  You just need to write the code that can read the metadata from the media file.  The &lt;a href="http://sitecoreexperience.spaces.live.com/blog/cns%21F413DDB1281D6EEA%21227.trak"&gt;Sitecore Experience blog has a post&lt;/a&gt; that explains how to do this.&lt;br /&gt;&lt;br /&gt;But what if you want a change to go the other direction?  What if you want to update the document title in a Word document using Sitecore?  This is also possible, but requires a little more work.  In this post I'm going to explain how to do this for a docx file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Triggering code when the Sitecore item is saved&lt;/span&gt;&lt;br /&gt;When the Sitecore item is changed, code needs to run that updates the corresponding media file.  This is accomplished by hooking into the "item:saved" event in web.config (or other config file).&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;&amp;lt;events&amp;gt;&lt;br /&gt;  &amp;lt;event name="item:saved"&amp;gt;&lt;br /&gt;      &amp;lt;handler type="Sitecore.Marketing.MediaLibrary.MediaItemSavedHandler, Sitecore.Marketing.MediaLibrary" method="OnItemSaved"/&amp;gt;&lt;br /&gt;  &amp;lt;/event&amp;gt;&lt;br /&gt;&amp;lt;/events&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And the MediaItemSavedHandler class must be defined.  The rest of the code in this post goes inside this class.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;public class MediaItemSavedHandler&lt;br /&gt;{&lt;br /&gt;   protected void OnItemSaved(object sender, EventArgs args)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Determining if the item represents a media file&lt;br /&gt;&lt;/span&gt;Since this event handler applies to all items, it is important to determine if the item that was saved represents a media file.  This can be accomplished by checking the item's template ID.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;Item item = Event.ExtractParameter(args, 0) as Item;&lt;br /&gt;bool isDocx = item.TemplateID.ToString().Equals("{7BB0411F-50CD-4C21-AD8F-1FCDE7C3AFFE}");&lt;br /&gt;if (!isDocx)&lt;br /&gt;{&lt;br /&gt;    return;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Determining if the title has actually changed&lt;/span&gt;&lt;br /&gt;Just because the item saved event is triggered doesn't mean it was triggered by a change to the title.  The EventArgs parameter will indicate if the title has changed:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;ItemChanges changes = Event.ExtractParameter(args, 1) as ItemChanges;&lt;br /&gt;Field titleField = item.Fields["Title"];&lt;br /&gt;bool hasTitleChanged = (changes.HasFieldsChanged &amp;&amp; titleField != null &amp;&amp; changes.IsFieldModified(titleField));&lt;br /&gt;if (!hasTitleChanged)&lt;br /&gt;{&lt;br /&gt;    return;&lt;br /&gt;}&lt;br /&gt;MediaItem media = new MediaItem(item);&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Updating the media file&lt;/span&gt;&lt;br /&gt;Next you need to update the media file in Sitecore.  Access to Sitecore media files is available through the WebDAV interface, but communicating with the WebDAV server is a topic for a separate post.  I'm going to take the easy way out here: I'm going to read the current file to a temp file, update the temp file, then replace the file in Sitecore.&lt;br /&gt;&lt;br /&gt;Additionally, I'm not going to include all of the code needed update the docx file.  I'll show you how to read a file from the media library and how to write a file to the media library.&lt;br /&gt;&lt;br /&gt;If you're familiar with how .NET handled I/O, there's not much to accessing the media file.  Here is an example of how to read and write Sitecore media files.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;protected string CreateTempFile(MediaItem media)&lt;br /&gt;{&lt;br /&gt;    string fileName = Path.GetTempFileName();&lt;br /&gt;    using (FileStream file = new FileStream(fileName, FileMode.Open))&lt;br /&gt;    {&lt;br /&gt;        Stream stream = media.GetMediaStream();&lt;br /&gt;        byte[] buffer = new byte[1024];&lt;br /&gt;        int count = stream.Read(buffer, 0, 1024);&lt;br /&gt;        while (count &amp;gt; 0)&lt;br /&gt;        {&lt;br /&gt;            file.Write(buffer, 0, count);&lt;br /&gt;            count = stream.Read(buffer, 0, count);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return fileName;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void ReplaceFileInSitecore(string fileName, MediaItem mediaItem)&lt;br /&gt;{&lt;br /&gt;    Media media = MediaManager.GetMedia(mediaItem);&lt;br /&gt;    using (FileStream stream = new FileStream(fileName, FileMode.Open))&lt;br /&gt;    {&lt;br /&gt;        media.SetStream(stream, "docx");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Content%20API%20Cookbook.aspx"&gt;Content API Cookbook&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb448854%28v=office.14%29.aspx"&gt;Microsoft's Open  XML SDK&lt;/a&gt; - classes that provide access to Open Office XML file format specifications, include docx files.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-6981028437473151965?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/6981028437473151965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/05/keeping-media-metadata-in-sync.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6981028437473151965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6981028437473151965'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/05/keeping-media-metadata-in-sync.html' title='Keeping Media Metadata In Sync'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-2139452520586250357</id><published>2010-05-24T08:00:00.007-04:00</published><updated>2010-09-21T15:53:01.214-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='configuration tools'/><title type='text'>Browser Settings for Sitecore</title><content type='html'>I am a big fan of using a virtualized development environment (I use &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;).  By running everything in a virtual machine, it's much easier to test systems, upgrade software, and keep my laptop from getting cluttered.  For me, the greatest advantage of working in a virtual machine is that I can easily roll-back changes I've made.&lt;br /&gt;&lt;br /&gt;But working in a virtual machine has resulted in me installing a lot more software than I would have otherwise.  Today, most installers are pretty streamlined and don't require much more than a little patience.&lt;br /&gt;&lt;br /&gt;Sometimes steps are required that cannot be handled by an installer and must be performed manually.  One of my least favorite of these is Internet Explorer configurations.&lt;br /&gt;&lt;br /&gt;Sitecore recommends Internet Explorer be configured in a certain way.  The &lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/IE%20Configuration%20Reference.aspx"&gt;Internet Explorer Configuration Reference&lt;/a&gt; available on &lt;a href="http://sdn.sitecore.net/"&gt;SDN&lt;/a&gt; explains how and why.&lt;br /&gt;&lt;br /&gt;The following code can be copied into a reg file and run in order to set the browser settings recommended in the SDN reference.  I'm including this information for demonstration purposes only.  Use at your own risk.&lt;br /&gt;&lt;br /&gt;UPDATED: 09/17/2010 - Certain revisions of Sitecore 6.2 and 6.3 may be easier to navigate if the option "allow script-initiated windows without size or position constraints" is disabled.  The settings below set that value to enabled.&lt;br /&gt;&lt;br /&gt;======&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;pre&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2]&lt;br /&gt;"2001"=dword:00000000&lt;br /&gt;"2004"=dword:00000000&lt;br /&gt;@=""&lt;br /&gt;"DisplayName"="Trusted sites"&lt;br /&gt;"PMDisplayName"="Trusted sites [Protected Mode]"&lt;br /&gt;"Description"="This zone contains websites that you trust not to damage your computer or data."&lt;br /&gt;"Icon"="inetcpl.cpl#00004480"&lt;br /&gt;"LowIcon"="inetcpl.cpl#005424"&lt;br /&gt;"CurrentLevel"=dword:00000000&lt;br /&gt;"Flags"=dword:00000043&lt;br /&gt;"1200"=dword:00000000&lt;br /&gt;"1400"=dword:00000000&lt;br /&gt;"2007"=dword:00010000&lt;br /&gt;"MinLevel"=dword:00010000&lt;br /&gt;"1A10"=dword:00000001&lt;br /&gt;"1001"=dword:00000001&lt;br /&gt;"1004"=dword:00000003&lt;br /&gt;"1201"=dword:00000003&lt;br /&gt;"1206"=dword:00000003&lt;br /&gt;"1207"=dword:00000000&lt;br /&gt;"1208"=dword:00000000&lt;br /&gt;"1209"=dword:00000003&lt;br /&gt;"120A"=dword:00000003&lt;br /&gt;"120B"=dword:00000000&lt;br /&gt;"1402"=dword:00000000&lt;br /&gt;"1405"=dword:00000000&lt;br /&gt;"1406"=dword:00000003&lt;br /&gt;"1407"=dword:00000000&lt;br /&gt;"1408"=dword:00000000&lt;br /&gt;"1409"=dword:00000000&lt;br /&gt;"1601"=dword:00000000&lt;br /&gt;"1604"=dword:00000000&lt;br /&gt;"1605"=dword:00000000&lt;br /&gt;"1606"=dword:00000000&lt;br /&gt;"1607"=dword:00000003&lt;br /&gt;"1608"=dword:00000000&lt;br /&gt;"1609"=dword:00000000&lt;br /&gt;"160A"=dword:00000000&lt;br /&gt;"1800"=dword:00000001&lt;br /&gt;"1802"=dword:00000000&lt;br /&gt;"1803"=dword:00000000&lt;br /&gt;"1804"=dword:00000000&lt;br /&gt;"1809"=dword:00000003&lt;br /&gt;"1A00"=dword:00020000&lt;br /&gt;"1A02"=dword:00000000&lt;br /&gt;"1A03"=dword:00000000&lt;br /&gt;"1A04"=dword:00000003&lt;br /&gt;"1A05"=dword:00000001&lt;br /&gt;"1A06"=dword:00000000&lt;br /&gt;"1C00"=dword:00010000&lt;br /&gt;"2000"=dword:00000000&lt;br /&gt;"2005"=dword:00000000&lt;br /&gt;"2100"=dword:00000000&lt;br /&gt;"2101"=dword:00000000&lt;br /&gt;"2102"=dword:00000000&lt;br /&gt;"2103"=dword:00000000&lt;br /&gt;"2104"=dword:00000000&lt;br /&gt;"2105"=dword:00000000&lt;br /&gt;"2106"=dword:00000000&lt;br /&gt;"2200"=dword:00000003&lt;br /&gt;"2201"=dword:00000000&lt;br /&gt;"2300"=dword:00000001&lt;br /&gt;"2301"=dword:00000003&lt;br /&gt;"2400"=dword:00000000&lt;br /&gt;"2401"=dword:00000000&lt;br /&gt;"2402"=dword:00000000&lt;br /&gt;"2600"=dword:00000000&lt;br /&gt;"2700"=dword:00000000&lt;br /&gt;"TemplateIndex"=dword:00011000&lt;br /&gt;"1806"=dword:00000001&lt;br /&gt;"2500"=dword:00000003&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;======&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-2139452520586250357?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/2139452520586250357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/05/browser-settings-for-sitecore.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/2139452520586250357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/2139452520586250357'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/05/browser-settings-for-sitecore.html' title='Browser Settings for Sitecore'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-809307482860662310</id><published>2010-04-01T07:00:00.005-04:00</published><updated>2010-04-01T07:00:08.575-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><title type='text'>Authentication Using the TC Integration Module 1.1</title><content type='html'>Happy &lt;a href="http://en.wikipedia.org/wiki/April_Fools%27_Day"&gt;April Fools Day&lt;/a&gt;. All things are subject to extra suspicion today, but I assure you this blog post is legit. Now then...&lt;br /&gt;&lt;br /&gt;In my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/installing-tc-integration-module-11.html"&gt;last post&lt;/a&gt; I walked through the installation process for the &lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent Community integration module for Sitecore&lt;/a&gt;.  In this post I will cover the topic of how authentication works in a little more detail.&lt;br /&gt;&lt;br /&gt;The majority of this post is just explanatory information.  The instructions on how to get the integration to work (meaning how to get the 2 cookies created) are at the end.  I put a "+" in front of those items in case you just want to get the integration to work and will worry about understanding it later :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Separate user accounts&lt;/span&gt;&lt;br /&gt;Sitecore and TC maintain their own, separate user accounts.  These accounts can stay in sync because they share the same user name.  After the integration is configured, Sitecore should be used to manage accounts.  This includes creating new accounts, setting passwords and assigning roles.&lt;br /&gt;&lt;br /&gt;If you are using the integration module with an existing TC instance, the TC users need to be "migrated" to Sitecore.  It's not a true migration because the user accounts will still exist in TC.  What it does is creates corresponding accounts in Sitecore, so TC users can be authenticated by Sitecore.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Migrating existing TC users&lt;/span&gt;&lt;br /&gt;Before you migrate existing TC users, be aware of a couple of things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;New accounts will be created in Sitecore.&lt;/li&gt;&lt;li&gt;All existing TC users will be migrated.  The migration script does not currently support any kind of filtering to control which users are migrated.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Existing TC content is not modified in any way.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Existing TC users will be renamed in TC.  The new user name will be the fully-qualified Sitecore user name.  This is the combination of a domain with the user name, such as extranet\rickfielder.&lt;/li&gt;&lt;li&gt;Do not run the migration script more than one time.&lt;/li&gt;&lt;li&gt;Do not run the migration script if the integration is already in use (meaning Sitecore users have already logged into TC).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Nbq2JlF0I/AAAAAAAADNc/5ArKTCubZEs/s1600/migrate+script.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 204px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Nbq2JlF0I/AAAAAAAADNc/5ArKTCubZEs/s320/migrate+script.jpg" alt="" id="BLOGGER_PHOTO_ID_5454804365324130114" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;TC user migration script&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;To migrate existing TC users:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log into Sitecore as an administrator.&lt;/li&gt;&lt;li&gt;Navigate to http://your-server/sitecore modules/Shell/CSSCIntegration/Security/csinstall.aspx.&lt;/li&gt;&lt;li&gt;Select the Sitecore domain the TC users should be created in.&lt;/li&gt;&lt;li&gt;Click the "move users" link.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_SD7mxqHQu2M/S7NcadIV7EI/AAAAAAAADNk/jISn8HSHe_c/s1600/moved+users.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 53px;" src="http://4.bp.blogspot.com/_SD7mxqHQu2M/S7NcadIV7EI/AAAAAAAADNk/jISn8HSHe_c/s320/moved+users.jpg" alt="" id="BLOGGER_PHOTO_ID_5454805183241776194" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;TC user migration script output&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The migration script generates 2 XML files.  These files are written to "[sitecore web root]\sitecore modules\Shell\CSSCIntegration\Security":&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;MovedUsers.xml &lt;/span&gt;describes the new accounts created in Sitecore.  This file contains the username and password for each migrated user.  Be aware that passwords are XML-encoded and may not necessarily work if copied directly from this file.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;FailedUsers.xml&lt;/span&gt; describes the TC users who could not be created in Sitecore.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Post-migration considerations&lt;/span&gt;&lt;br /&gt;Unfortunately, the migration script doesn't provide any way for an administrator to specify any properties on the Sitecore users that get created.  Aside from the Sitecore domain the users are added to.  So if you want TC users to be assigned a certain Sitecore role, this is something that you must do manually after the migration.&lt;br /&gt;&lt;br /&gt;Another thing to to consider after migrating users is that login, logout, password maintenance and new account creation are all handled by Sitecore.  Since TC provides users the ability to do these things, you should hide those link in TC user interface.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Authentication in Sitecore&lt;/span&gt;&lt;br /&gt;When using this integration, all authentication is handled by Sitecore.  When a user navigates to TC, TC looks for some cookies that Sitecore has created in order to know&lt;br /&gt;&lt;br /&gt;When a user logs into Sitecore, 2 cookies are created.  These cookies identify that a user has been authenticated and extra information from Sitecore about the user.  Since Sitecore and TC must be a part of the same domain, both cookies  will be available to TC when the browser navigates to TC.  So the user is not automatically logged into TC.  Rather, the cookies are set so that when the user navigates to TC, TC can automatically log him in at that point.&lt;br /&gt;&lt;br /&gt;The process by which these cookies are created is the same whether the user logs into a published Sitecore website or the Sitecore client - provided Sitecore is configured to create these cookies.&lt;br /&gt;&lt;br /&gt;This is not done automatically. The design allows you to control if and when this happens.  For example, you may want content authors to have access to TC but not website users.  Later in this post I'm going to walk through the configuration needed in order to instruct Sitecore to create these cookies for both published Sitecore websites and the Sitecore client.&lt;br /&gt;&lt;br /&gt;But what are these cookies and where do they come from?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Writing the authentication cookie&lt;/span&gt;&lt;br /&gt;The first cookie is the authentication cookie.  Sitecore creates a &lt;span style=";font-family:courier new;font-size:85%;"  &gt;System.Web.Security.FormsAuthenticationTicket&lt;/span&gt; instance.  This object identifies the user who has authenticated.  It also contains some data that needs to be transmitted to TC.  Specifically, it contains the TC roles that the TC user is assigned.&lt;br /&gt;&lt;br /&gt;The name of the authentication cookie is specified in Sitecore's web.config file, in the "authentication" section.  My Sitecore instance is configured to use the name ".CommunityServer".&lt;br /&gt;&lt;br /&gt;If you're interested in seeing the code that creates the authentication cookie, look at the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;assembly:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide.dll&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;namespace:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;class:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;SecurityUtil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;method:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;CreateCookies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Writing the user profile cookie&lt;/span&gt;&lt;br /&gt;The second cookie is the user profile cookie.  This cookie contains user profile values that are read from Sitecore and made available to TC, which sets those values on the corresponding TC user (or uses those values to create a new TC if one doesn't already exist).&lt;br /&gt;&lt;br /&gt;The following is an example of the (unencrypted) user profile cookie value:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;Email=Johnson@localhost.com&amp;amp;PublicEmail=Johnson@localhost.com&amp;amp;CommonName=John Johnson&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The values that are set in this cookie are determined by the "mappedProfileProperties" section from the Sitecore configuration file  "CommunityServerIntegration.config".  The only exception is the "Email"  value, which is transmitted automatically.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reading the authentication cookie&lt;/span&gt;&lt;br /&gt;When a user clicks a link that takes him to TC, the 2 cookies are available to TC.  Just like Sitecore, TC is configured use an authentication cookie named  ".CommunityServer".&lt;br /&gt;&lt;br /&gt;The TC security extension that was configuring during installation specifies that TC should use the following class to handle forms authentication:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;assembly:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="font-family:courier new;"&gt;Sitecore.CommunityServerSecurityIntegration.CommunityServerSide&lt;/span&gt;.dll&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;namespace:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Sitecore.CommunityServerSecurityIntegration.CommunityServerSide&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;class:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;SitecoreFormsAuthentication&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;&lt;/span&gt;The "ProcessRequest" method is responsible for reading the authentication cookie.  After the method confirms that the cookie is valid, it reads the roles that were passed from Sitecore.  This ensures the proper roles are assigned to the TC user.&lt;br /&gt;&lt;br /&gt;TC handles adding and removing roles from users who already exist in TC, but what about users who don't?  Remember, all user management is handled in Sitecore, so it's possible - and even likely - that a user will exist in Sitecore but not in TC.  TC will automatically create a new user in this case and will set the roles on the user.  The "PostCreateUser" method does this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reading the user profile cookie&lt;/span&gt;&lt;br /&gt;The "ProcessRequest" method also reads the user profile cookie.  It just checks to make sure a value has been set.  The underlying TC security extension infrastructure takes the information in that cookie and uses it to create a TC user if necessary and to populate the TC user.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How does Sitecore know when - and if - to write the cookies?&lt;/span&gt;&lt;br /&gt;You may not want every Sitecore user to have an account created in TC.  Therefore, it is important that you retain some control over when the cookies are written.  If no cookies are written, then no single sign-on to TC will occur.  The cookies are only written if you want them to be.  The next sections explain how to configure this.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;+Configuring a Sitecore website to  support single sign-on&lt;/span&gt;&lt;br /&gt;Website can handle authentication in a variety of ways.  This integration supports all of those.  However your site's login logic works, add a call to the following method after it runs.  This will cause Sitecore to create the 2 cookies that are required for single sign-on to TC:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;assembly:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="font-family:courier new;"&gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt;.dll&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;namespace:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;class:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;SecurityUtil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;method:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;AfterLogin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You also need to ensure the cookies are deleted when the user logs out.  Add the following method call before your code ends the user's session:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;assembly:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="font-family:courier new;"&gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt;.dll&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;namespace:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;class:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;SecurityUtil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;method:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;Logout&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;+Configuring the Sitecore client to support single sign-on&lt;/span&gt;&lt;br /&gt;Just like when supporting single sign-on from a published Sitecore website, when configuring single sign-on from the Sitecore client you need to instruct Sitecore to create (and delete) the 2 required cookies.&lt;br /&gt;&lt;br /&gt;Hooking into Sitecore's authentication functionality is done by modifying the "loggedIn" and "logout" pipelines.  These pipelines are defined in Sitecore's web.config file.&lt;br /&gt;&lt;br /&gt;Add the following processor as the first step in the "loggedIn" pipeline:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;processor mode="on" type="Security.CreateCSCookieProcessor, Sitecore.CommunityServerSecurityIntegration.SitecoreSide" /&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Add the following processor as the last step in the "logout" pipeline:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;processor mode="on" type="Security.RemoveCSCookieProcessor, Sitecore.CommunityServerSecurityIntegration.SitecoreSide" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next steps&lt;/span&gt;&lt;br /&gt;After the integration module is installed and configured, it's pretty much smooth sailing.  Accessing TC content can be handled in a number of way.  I described the options in my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/introduction-to-telligent-community.html"&gt;introduction to the integration&lt;/a&gt; post.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent  Community integration module&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-809307482860662310?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/809307482860662310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/04/authentication-using-tc-integration.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/809307482860662310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/809307482860662310'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/04/authentication-using-tc-integration.html' title='Authentication Using the TC Integration Module 1.1'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Nbq2JlF0I/AAAAAAAADNc/5ArKTCubZEs/s72-c/migrate+script.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-7047419613846456843</id><published>2010-03-31T08:00:00.010-04:00</published><updated>2010-03-31T17:37:10.440-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><title type='text'>Installing the TC Integration Module 1.1</title><content type='html'>In my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/introduction-to-telligent-community.html"&gt;last post&lt;/a&gt; I provided an overview of the &lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent Community integration module&lt;/a&gt; for Sitecore.  While the module comes with a lot of documentation - including instructions on how to install the module - sometimes it's helpful to have someone guide you through the process.  That's what I'm going to do.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;TC integration module architecture&lt;/span&gt;&lt;br /&gt;Before I get into the actual installation instructions, it's important to understand what you're going to install.  I will explain each section when I get to it, but here's a quick overview:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Authentication is handled by Sitecore using ASP.NET forms  authentication.&lt;/li&gt;&lt;li&gt;Sitecore is responsible for creating an authentication cookie that TC uses to provide single sign-on.&lt;/li&gt;&lt;li&gt;Sitecore passes user information to TC so TC knows which roles the user has been assigned to.&lt;/li&gt;&lt;li&gt;TC content is exposed to Sitecore through a REST API.&lt;/li&gt;&lt;li&gt;Additions to the Sitecore client are installed using a Sitecore package.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Pre-requisites&lt;/span&gt;&lt;br /&gt;Before you attempt to install the TC integration module version 1.1, be aware of the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You must be running Sitecore 6.1 or 6.2.&lt;/li&gt;&lt;li&gt;You must be running Telligent Community 5.0 SP1.  Version 5.5 might work, but I haven't tested it to know for sure.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sitecore and Telligent Community must be running in the website or TC must be running in a domain of the Sitecore server.  For example, if TC is using the domain "tc.test-server.com", then Sitecore must be using the domain "test-server.com".&lt;/li&gt;&lt;li&gt;You must have read/write permissions on the folders in which Sitecore and TC are installed.&lt;/li&gt;&lt;li&gt;You must have the ability to upload files to the folder in which Sitecore and TC are installed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You must have an administrator account on Sitecore and TC&lt;/li&gt;&lt;/ul&gt;If you have all of these things ready, you are safe to proceed.  Don't be overwhelmed by the number of steps.  It's not as bad as it may look :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1 - Download the integration module.&lt;/span&gt;&lt;br /&gt;The integration module can be downloaded from the Sitecore's SVN server.  The easiest way to get the module is to use an SVN client for Visual Studio like &lt;a href="http://ankhsvn.open.collab.net/"&gt;AnkhSVN&lt;/a&gt;.  You want to download the trunk code since this contains the latest bug fixes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2 (optional) - Compile the .NET assemblies.&lt;/span&gt;&lt;br /&gt;You don't have to recompile the .NET assemblies, but I think it's a good idea because it will ensure that you are using the latest available code.  Here's a description of each of the C# projects that make up the integration module so you understand what you are compiling:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Sitecore.CommunityServerSecurityIntegration.CommunityServerSide&lt;/span&gt; - This assembly is deployed to the TC server.  It contains code to support single sign-on as well as extensions to TC's REST API.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Sitecore.CommunityServerSecurityIntegration.SitecoreSide&lt;/span&gt; - This assembly is deployed to the Sitecore server.  It contains code that allows Sitecore to create the cookies that are used by TC and to migrate existing TC users into Sitecore.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Sitecore.CommunityServersIntegration.Controls&lt;/span&gt; - This assembly is deployed to the Sitecore server.  It is where the components that are used to access TC content are defined.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CSComponentWizard&lt;/span&gt; - This assembly is deployed to the Sitecore server.  It is where Sitecore client user interface additions are implemented.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3 - Deploy assemblies to TC.&lt;/span&gt;&lt;br /&gt;Copy the assembly "Sitecore.CommunityServerSecurityIntegration.CommunityServerSide.dll" to the TC server.  The assembly should go in the bin folder.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4 - Add a security extension in TC.&lt;/span&gt;&lt;br /&gt;New functionality can be added to TC using extensions.  A security extension allows TC to use cookies that are created by Sitecore for single sign-on.&lt;br /&gt;&lt;br /&gt;In order to use an extension, TC must be configured to allow extensions to run.  In the "communityserver.config" file in TC, set the following attribute:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;node path:/CommunityServer/Core/extensionModules&lt;/li&gt;&lt;li&gt;attribute name: enabled&lt;/li&gt;&lt;li&gt;attribute value: true&lt;/li&gt;&lt;/ul&gt;Next you need to specify that TC should use a custom class to handle forms authentication.  In the extensionModules node you just modified, find the FormsAuthentication security extension.  Hint: look for &lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;add name="FormsAuthentication"&lt;/span&gt;...  Replace the node with the following:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;name="formsauthentication" name="FormsAuthentication" extensiontype="Security" type="Sitecore.CommunityServerSecurityIntegration.CommunityServerSide.SitecoreFormsAuthentication, Sitecore.CommunityServerSecurityIntegration.CommunityServerSide" allowautouserregistration="true" userprofilecookie="CSUserProfile" useencryptedcookie="false" profilerefreshinterval="1" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's a breakdown of what the attributes mean:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;name &lt;/span&gt;- The name of the extension you are configuring.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;extensionType &lt;/span&gt;- TC supports a variety of extensions.  This specifies that this extension deals with security.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;type &lt;/span&gt;- The name of the class (and assembly) that implements the extension.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;allowAutoUserRegistration - When a user logs in from Sitecore, an authentication cookie is created.  TC uses that cookie to authenticate the user.  If the user doesn't already exist in TC, this setting instructs TC to create the user.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;userProfileCookie&lt;/span&gt; - The name of the cookie that contains user profile information about the user who has been authenticated by Sitecore.  TC uses the cookie's value to set values on the TC user.  Later you will configure the setting in Sitecore that sets this value.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;useEncryptedCookie&lt;/span&gt; -Specifies if the value saved in the userProfileCookie is encrypted.    Later you will configure the setting in Sitecore that sets this value.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;profileRefreshInterval&lt;/span&gt; - This value specifies the frequency with which TC will refresh user information.  The unit is in days, with 1 being the minimal value.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 5 - Enable REST API in TC.&lt;/span&gt;&lt;br /&gt;TC provides access to its content through a REST API.  This API must be enabled before Sitecore can use it.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log into TC using an administrator account.&lt;/li&gt;&lt;li&gt;Navigate to the TC control panel and click the "Site Administration" link.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click the "Manage REST API" tab.&lt;/li&gt;&lt;li&gt;Make sure the "Yes" option is selected and click the "Save" button.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 6 - Generate an application key in TC.&lt;/span&gt;&lt;br /&gt;Sitecore uses a TC admin account in order to retrieve content.  For this  to work, Sitecore needs the TC admin user name and an application key.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log into TC using the admin account you intend to have Sitecore use.&lt;/li&gt;&lt;li&gt;Edit the user's settings.&lt;/li&gt;&lt;li&gt;Navigate to the "Site Options" tab.&lt;/li&gt;&lt;li&gt;Scroll to the bottom of the screen and click the "Create and Edit Application Keys" link.&lt;/li&gt;&lt;li&gt;In the "name" field enter "Sitecore" and click the "Generate" button.&lt;/li&gt;&lt;li&gt;Write down the API key that is generated.  You will need this value when you configure the connection from Sitecore to TC.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 7 - Modify web handlers in TC.&lt;/span&gt;&lt;br /&gt;This integration module allows Sitecore users to filter and repurpose TC content.  In order to provide Sitecore users with a variety of ways to do this, TC's REST API had to be extended.&lt;br /&gt;&lt;br /&gt;This step involves changing the web handlers that process the REST calls.  These web handlers can be found in the api\ folder under TC.  The following files need to be modified.  The class name in each file needs to be changed to the value following the file name:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;groups.ashx:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;CommunityServer.WebServices.Services.CSIGroupsService&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;mediagallery.ashx:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;CommunityServer.WebServices.Services.CSIMediaGalleriesService&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;membership.ashx:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;CommunityServer.WebServices.Services.CSIMembershipService&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;search.ashx:&lt;/span&gt; &lt;span style=";font-family:courier new;font-size:85%;"  &gt;CommunityServer.WebServices.Services.CSISearchService&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 8 - Install the integration module deployment package in Sitecore.&lt;/span&gt;&lt;br /&gt;The deployment package is available in the file named "TCSC Integration - Sitecore side-1.1.x.zip".  Install this package using the Sitecore Installation Wizard.&lt;br /&gt;&lt;br /&gt;The package includes a number of Sitecore items and files that are copied to the filesystem.  Some of those files are .NET assemblies.  If you recompiled the assemblies earlier, you will want to copy those assemblies into the bin\ folder in Sitecore.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 9 - Add a connection string in Sitecore.&lt;/span&gt;&lt;br /&gt;Since TC is an external system that Sitecore is connecting to, an entry for TC must be added to Sitecore's connectionstring.config file.  Add the following to the configuration file:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;add name="tc" connectionstring="siteUrl=http://your-server.com/tc;username=admin;apiKey=c00y45fd" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Of course, the specific values you enter here will be different than the ones above.  Here's an explanation of the values in the connectionString attribute:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;siteUrl&lt;/span&gt; - The base URL to your TC server.  If you enter the URL in a browser you should be taken to the TC homepage.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;username&lt;/span&gt; - The name of the TC administrator account that Sitecore uses to communicate with TC.  This must be the same account you used earlier to generate the API key.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;apiKey&lt;/span&gt; - The API key value you generated earlier.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 10 - Modify the integration module configuration file in Sitecore.&lt;/span&gt;&lt;br /&gt;One of the files that is created by the deployment package is the integration module configuration file.  This file is located in the folder "app_config/include/".  The name of the file is "CommunityServerIntegration.config".&lt;br /&gt;&lt;br /&gt;Locate the node "/configuration/sitecore/settings".  This node defines the basic settings used by the integration module.  Here's a description of the settings:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CS.ProfileCookie&lt;/span&gt; - Remember the "userProfileCookie" attribute in TC's "communityserver.config" file?  This value must match that.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CS.EncryptProfile&lt;/span&gt; - This value must match the "useEncryptedCookie" attribute value from TC's "communityserver.config" file.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CS.ConnectionStringName&lt;/span&gt; - This value must match the name of the connection string you configured in Sitecore's "connectionstring.config" file.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Using the values I've already configured, this is what my settings node looks like:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;settings&amp;gt;&lt;br /&gt;&amp;lt;setting name="CS.ProfileCookie" value="CSUserProfile" /&amp;gt;&lt;br /&gt;&amp;lt;setting name="CS.EncryptProfile" value="false" /&amp;gt;&lt;br /&gt;&amp;lt;setting name="CS.ConnectionStringName" value="tc" /&amp;gt;&lt;br /&gt;&amp;lt;/settings&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 11 - Configure forms authentication settings in Sitecore.&lt;/span&gt;&lt;br /&gt;In order for single sign-on to work, both Sitecore and TC must use forms authentication.  Additionally, the forms authentication settings for both must match.  Make sure the "authentication" node in Sitecore's "web.config" file matches the node in TC's "web.config" file.&lt;br /&gt;&lt;br /&gt;The important part here is the the authentication form's name and domain match.  Here's the authentication node from my installation:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;authentication mode="Forms"&amp;gt;&lt;br /&gt;&amp;lt;forms name=".CommunityServer" protection="All" timeout="60000" loginurl="login.aspx" slidingexpiration="true" domain=".nicam.com" /&amp;gt;&lt;br /&gt;&amp;lt;/authentication&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The domain attribute is required if TC is running in a subdomain.  The dot before the domain name is needed in order for the browser to use the same cookie when sending requests to either the domain or the subdomain.&lt;br /&gt;&lt;br /&gt;Also - and this may be common knowledge among developers but it can't hurt to be repeated - be sure your domain has at least one dot in it already.  The cookie will not be written if your domain is simply "nicam".  It needs to be "nicam.com".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 12 - Ensure the machineKey values in Sitecore and TC match.&lt;/span&gt;&lt;br /&gt;The "machineKey" settings is important when using forms authentication in ASP.NET.  Both Sitecore and TC must have the same "machineKey" configuration.&lt;br /&gt;&lt;br /&gt;This configuration can be found in web.config.   If no "machineKey" configuration exists, it must be added.  Online tools are available - like &lt;a href="http://aspnetresources.com/tools/keycreator.aspx"&gt;this one&lt;/a&gt; - to generate the required settings.  After you generate the configuration, add it to web.config as the last tag before the closing "system.web" tag (&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;/system.web&amp;gt;&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 13 (optional) - Configure role and property mappings from Sitecore to TC.&lt;/span&gt;&lt;br /&gt;Sitecore's "CommunityServerIntegration.config" file contains 2 sections that allow Sitecore user settings to be mapped to TC user settings.&lt;br /&gt;&lt;br /&gt;The first mapping section is "rolesCorrespondence".  This section allows you to specify user roles in Sitecore but still take advantage of security in TC.  Sitecore roles are mapped to TC roles.&lt;br /&gt;&lt;br /&gt;When the authentication cookie is created, the Sitecore user's roles are checked against this setting.  The names of the appropriate TC roles are set in the authentication cookie.  When single sign-on happens in TC, the custom forms authentication class that TC uses reads the roles from the authentication cookie and adds those roles to the TC user.&lt;br /&gt;&lt;br /&gt;The following is an example of role mapping:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;rolesCorrespondence&amp;gt;&lt;br /&gt;&amp;lt;role communityserverrole="Employees" sitecorerole="sitecore\Author" /&amp;gt;&lt;br /&gt;&amp;lt;role communityserverrole="Visitors" sitecorerole="extranet\Nicam" /&amp;gt;&lt;br /&gt;&amp;lt;/rolesCorrespondence&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The second mapping section is "mappedProfileProperties".  This is where Sitecore user profile properties are mapped to TC user profile properties.  These values are passed to TC through the user profile cookie.&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&amp;lt;mappedProfileProperties&amp;gt;&lt;br /&gt;&amp;lt;property communityserverproperty="PublicEmail" sitecoreproperty="Email"&amp;gt;&lt;br /&gt;&amp;lt;property communityserverproperty="CommonName" sitecoreproperty="FullName"&amp;gt;&lt;br /&gt;&amp;lt;/mappedProfileProperties&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 14 - Enable the HTML editor for display templates&lt;/span&gt;&lt;br /&gt;Display templates determine how content retrieved from TC by the community component is formatted.  Sitecore users are able control this presentation by using a rich text editor to edit display templates.&lt;br /&gt;&lt;br /&gt;A couple of changes to the Sitecore file "/sitecore/shell/Controls/Rich Text Editor/Default.aspx" are required:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Change the "Inherits" attribute to "Sitecore.CommunityServerIntegration.Editors.CSRADEditor".  This class extends the standard Sitecore rich text editor to support the dropdown list that allows an editor to select the specific TC content fields to display.&lt;/li&gt;&lt;li&gt;At the bottom of the file, add a link to the Javascript file "/sitecore modules/Shell/CSSCIntegration/RichText Commands.js".  It is important that this be the last Javascript file that the browser loads.  Otherwise the code in the file may be overriden by another script.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next steps&lt;/span&gt;&lt;br /&gt;The integration module is installed, but there's more work to do.  Since Sitecore is handling authentication and is responsible for role management, existing TC users must be migrated into Sitecore.  Also, Sitecore needs to be configured to create the cookies (authentication and user profile) that TC needs in order to sign a user in.  I will cover these topics in my next post.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent Community integration module&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa480476.aspx"&gt;Explained: Forms Authentication in ASP.NET 2.0&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-7047419613846456843?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/7047419613846456843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/installing-tc-integration-module-11.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7047419613846456843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7047419613846456843'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/installing-tc-integration-module-11.html' title='Installing the TC Integration Module 1.1'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-418471757019505796</id><published>2010-03-29T21:00:00.004-04:00</published><updated>2010-03-30T09:13:49.988-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><title type='text'>Introduction to Telligent Community Integration Module for Sitecore</title><content type='html'>The &lt;a href="http://sdn.sitecore.net/Resources/Shared%20Source.aspx"&gt;Sitecore Shared Source Library&lt;/a&gt; has a lot of interesting and useful projects that are available for free.  In this post I want to introduce the &lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent Community integration module&lt;/a&gt;.  I will explain what the module does and show that it looks like in action.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Cqd5BYFKI/AAAAAAAADNU/gWEBbCOdq1g/s1600/tc01.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 176px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Cqd5BYFKI/AAAAAAAADNU/gWEBbCOdq1g/s320/tc01.jpg" alt="" id="BLOGGER_PHOTO_ID_5454046579245192354" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Sitecore website that incorporates Telligent Community content. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;For those of you who don't know, &lt;a href="http://telligent.com/products/telligent_community.aspx"&gt;Telligent Community&lt;/a&gt; is a .NET-based system for building and maintaining communities.  Inside Telligent Community, applications provide blog, wiki, forum and media gallery functionality.&lt;br /&gt;&lt;br /&gt;So what does this integration do?  Two things.  The first is integrated security.  Single sign-on between Sitecore and TC is supported.  Sitecore can be used to manage TC users and roles.&lt;br /&gt;&lt;br /&gt;The second is the ability to repurpose TC content in Sitecore.  The integration provides a variety of ways to incorporate TC content into a Sitecore website, including a wizard that allows Page Editor users to select the TC content they want to use.  It also provides a variety of ways to control how that content is presented, including a rich-text editor for building display templates.&lt;br /&gt;&lt;br /&gt;I will save the technical details on how all this works for later posts.  For now I want to focus on what the integration does rather than how it does it.  The easiest way to do this is through some videos.  And if you're only going to watch one video, I suggest video #2.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Video 1: Security integration features &lt;/span&gt;&lt;br /&gt;This video covers the module's security integration features.  It demonstrates how single sign-on works and how Sitecore is used for role management.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/QiYoHKq9cug&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/QiYoHKq9cug&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Security integration using the TC integration module 1.1.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;"&gt;Video 2: Content repurposing&lt;/span&gt;&lt;br /&gt;The integration module provides a number of ways to repurpose content.  This video explains these options.  It also covers the "community component", which is a Sitecore control that allows Sitecore content authors to repurpose Telligent Community content through a wizard interface. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/9_PaVU4gXKA&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/9_PaVU4gXKA&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Content repurposing using the TC integration module 1.1.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;"&gt;Video 3: Controlling presentation logic&lt;/span&gt;&lt;br /&gt;This video demonstrates how the integration module allows custom presentation logic to be defined in Sitecore and applied to Telligent Community content.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Xq09t7uA8Tk&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/Xq09t7uA8Tk&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Controlling presentation logic using the TC integration module 1.1.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/resources/shared%20source.aspx"&gt;Sitecore Shared Source Library&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://trac.sitecore.net/TelligentCommunityIntegration"&gt;Telligent Community Integration Module&lt;/a&gt; - You can download the source code, installation files and documentation here.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sharesitecore.wordpress.com/"&gt;Sitecore Shared Source Weblog&lt;/a&gt; - This blog is written by Sitecore's Shared Source Coordinator.  It's a great source of information on what's going on in the Shared Source world.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-418471757019505796?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/418471757019505796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/introduction-to-telligent-community.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/418471757019505796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/418471757019505796'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/introduction-to-telligent-community.html' title='Introduction to Telligent Community Integration Module for Sitecore'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_SD7mxqHQu2M/S7Cqd5BYFKI/AAAAAAAADNU/gWEBbCOdq1g/s72-c/tc01.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-7224493283731785908</id><published>2010-03-25T08:00:00.009-04:00</published><updated>2010-03-25T08:00:10.534-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='customizations'/><title type='text'>Custom Fields, Part 3</title><content type='html'>In my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-2.html"&gt;last post&lt;/a&gt; I explained how to create a custom user interface for editing a name in Page Editor.  I left off suggesting that there's a problem with the current implementation.  And there is: it is possible to circumvent the user interface by using the inline editing feature provided by the default field renderer.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_SD7mxqHQu2M/S6l3hdUgVLI/AAAAAAAADM8/mZ9tPv-UQY8/s1600-h/inline+edit+name+field.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 122px;" src="http://1.bp.blogspot.com/_SD7mxqHQu2M/S6l3hdUgVLI/AAAAAAAADM8/mZ9tPv-UQY8/s320/inline+edit+name+field.jpg" alt="" id="BLOGGER_PHOTO_ID_5452020240598717618" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Inline editing circumvents my new user interface.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Why is that happening?  Well, as far inline editing is concerned, Sitecore doesn't have any special instructions on how to handle a name field.  Therefore, Sitecore treats the field like a single-line text field.&lt;br /&gt;&lt;br /&gt;Since I created this special user interface to handle the name field, I want Sitecore to use that interface.  And while in some cases being able to use inline editing to modify a field value may be advantageous, in this case I want it disabled.&lt;br /&gt;&lt;br /&gt;In this post I'm going to cover 3 items:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Creating a custom field type to make it easier to work with the  components of a name (currently only first and last names, but could  later be expanded to more).&lt;/li&gt;&lt;li&gt;Controlling how the standard Field Renderer web control behaves when it  is used to render a custom field.&lt;/li&gt;&lt;li&gt;Configuring a custom field renderer control to make it easier to  configure the display formatting for a name field&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;Step 1 - Create new field type&lt;/b&gt;&lt;br /&gt;My first step it to create a new field type.  This will make it much easier for people working with the Sitecore API  to work with name fields.  Since I will need to work with field names in a later step, I will be the first person to benefit from this addition. &lt;br /&gt;&lt;br /&gt;Also, this code will serve as a replacement for the NameFieldUtils class.  Same logic, different location.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;public class NameFieldType : CustomField&lt;br /&gt;{&lt;br /&gt; public static string GetFullName(string firstName, string lastName)&lt;br /&gt; {&lt;br /&gt;     var name = new string[2];&lt;br /&gt;     name[0] = firstName;&lt;br /&gt;     name[1] = lastName;&lt;br /&gt;     return String.Join(" ", name);&lt;br /&gt; }&lt;br /&gt; public static string GetFirstName(string fullName)&lt;br /&gt; {&lt;br /&gt;     string[] parts = fullName.Split(' ');&lt;br /&gt;     if (parts.Length &amp;gt;= 1)&lt;br /&gt;     {&lt;br /&gt;         return parts[0];&lt;br /&gt;     }&lt;br /&gt;     return string.Empty;&lt;br /&gt; }&lt;br /&gt; public static string GetLastName(string fullName)&lt;br /&gt; {&lt;br /&gt;     string[] parts = fullName.Split(' ');&lt;br /&gt;     if (parts.Length &amp;gt;= 2)&lt;br /&gt;         return parts[1];&lt;br /&gt;     return string.Empty;&lt;br /&gt; }&lt;br /&gt; public NameFieldType(Field innerField) : base(innerField) { }&lt;br /&gt;&lt;br /&gt; public static implicit operator NameFieldType(Field field)&lt;br /&gt; {&lt;br /&gt;     if (field != null)&lt;br /&gt;         return new NameFieldType(field);&lt;br /&gt;     return null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public string FirstName&lt;br /&gt; {&lt;br /&gt;     get { return NameFieldType.GetFirstName(InnerField.Value); }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public string LastName&lt;br /&gt; {&lt;br /&gt;     get { return NameFieldType.GetLastName(InnerField.Value); }&lt;br /&gt; }&lt;br /&gt; public string FullName&lt;br /&gt; {&lt;br /&gt;     get { return InnerField.Value; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Step 2 - Register new field type&lt;/b&gt;&lt;br /&gt;When working with content using the Sitecore API, a class is used.  Different classes support different types of field.  Sitecore needs to know which class should be used for which field type.  This mapping is specified in the FieldTypes.config file.&lt;br /&gt;&lt;br /&gt;In order for Sitecore to be able to resolve the "Name Field" type to the NameFieldType class I just created, I need to add the following to the FieldTypes.config file:&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;fieldType name="Name Field" type="sctest.NameFieldType,sctest" /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3 - Write code that controls the inline editing interface&lt;/span&gt;&lt;br /&gt;Next I need to tell Sitecore how a name field value should be displayed in Page Editor.  There are a couple of things I want to configure.  First, I don't want users to be able to enter a value inline.  I want all name values to be entered through my custom interface.  I need to disable inline editing.  Second, I want my custom interface to appear when a user clicks a name value in Page Editor.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;public class GetNameFieldValue&lt;br /&gt;{&lt;br /&gt;public void Process(RenderFieldArgs args)&lt;br /&gt;{&lt;br /&gt;  switch (args.FieldTypeKey)&lt;br /&gt;  {&lt;br /&gt;    case "name field":&lt;br /&gt;    {&lt;br /&gt;      args.DisableWebEditContentEditing = true;&lt;br /&gt;      args.WebEditClick = "return Sitecore.WebEdit.editControl($JavascriptParameters,'sctest:EditNameButton');";&lt;br /&gt;      break;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Step 4 - Configure Sitecore to use the code&lt;/b&gt;&lt;br /&gt;The Sitecore's renderField pipeline is responsible for rendering fields in Page Editor.  The pipeline is defined in web.config.  One of the steps in the pipeline is to determine what value should be rendered for a specific field.  An addition to this pipeline is needed since I want to change the field renderer's default behavior.&lt;br /&gt;&lt;br /&gt;I need to add a processor to the renderField pipeline.  The processor will use the class I just created.  The path to this pipeline in web.config is /configuration/sitecore/pipelines/renderField.  The line should be added before the processor that uses the type Sitecore.Pipelines.RenderField.AddBeforeAndAfterValues.  After I make my addition the renderField pipeline looks like the following:&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;renderField&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.SetParameters, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.ExpandLinks, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetImageFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetLinkFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetInternalLinkFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetMemoFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetDateFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.GetDocxFieldValue, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="sctest.GetNameFieldValue, sctest"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.AddBeforeAndAfterValues, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;processor type="Sitecore.Pipelines.RenderField.RenderWebEditing, Sitecore.Kernel"/&amp;gt;&lt;br /&gt;&amp;lt;/renderField&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;After I compile my code I can test my changes.  I can no longer directly edit a name field value.  In addition, when I click the value in Page Editor, my custom user interface appears.&lt;br /&gt;&lt;br /&gt;The next thing I want to do is create a custom field renderer in order to provide some extra functionality for my custom field type.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 5 - Create a new field renderer&lt;/b&gt;&lt;br /&gt;My new field renderer is going to allow a developer to specify a formatting for a name.  By default the first name followed by last name will be displayed.  This is the value the default field renderer uses.  But my custom field renderer is going to support options that will display only the first name, only the last name, and the last name followed by the first name, in addition to the default display format.&lt;br /&gt;&lt;br /&gt;In order to accomodate this I need a custom field renderer that supports a format option.  Since a developer is able to set the format option value, I need to make sure this value is made available to Sitecore in the way Sitecore expects.  The following class does these things:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Assembly name:&lt;/span&gt; sctest.dll&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Namespace:&lt;/span&gt; sctest&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Class name:&lt;/span&gt; NameFieldControl&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Base class:&lt;/span&gt; Sitecore.Web.UI.WebControls.FieldControl&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;public class NameFieldControl : Sitecore.Web.UI.WebControls.FieldControl&lt;br /&gt;{&lt;br /&gt;  public string Format { get; set; }&lt;br /&gt;&lt;br /&gt;  protected override void PopulateParameters(Sitecore.Collections.SafeDictionary&amp;lt;string&amp;gt; parameters)&lt;br /&gt;  {&lt;br /&gt;      parameters.Add("format", this.Format);&lt;br /&gt;      base.PopulateParameters(parameters);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;Step 6 - Implement support for formatting options&lt;/b&gt;&lt;br /&gt;Now that I have the ability to support a format value, I need to implement the logic to use that value to determine the text that is displayed when a name field is displayed.  That is going to require a modification to the GetNameFieldValue class (the class that I added to the renderField pipeline).&lt;br /&gt;&lt;br /&gt;The format value that was set in the previous step is available in the pipeline through the RenderFieldArgs parameter.  I use that value to determine how to format the name field's value.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;public void Process(RenderFieldArgs args)&lt;br /&gt;{&lt;br /&gt;    switch (args.FieldTypeKey)&lt;br /&gt;    {&lt;br /&gt;        case &amp;quot;name field&amp;quot;:&lt;br /&gt;        {&lt;br /&gt;            //&lt;br /&gt;            //&lt;br /&gt;            NameFieldType field = args.Item.Fields[args.FieldName];&lt;br /&gt;            string displayValue = null;&lt;br /&gt;            //&lt;br /&gt;            //&lt;br /&gt;            var format = args.Parameters[&amp;quot;format&amp;quot;];&lt;br /&gt;            switch (format)&lt;br /&gt;            {&lt;br /&gt;                case &amp;quot;FirstNameOnly&amp;quot;:&lt;br /&gt;                    displayValue = field.FirstName;&lt;br /&gt;                    break;&lt;br /&gt;                case &amp;quot;LastNameOnly&amp;quot;:&lt;br /&gt;                    displayValue = field.LastName;&lt;br /&gt;                    break;&lt;br /&gt;                case &amp;quot;LastCommaFirst&amp;quot;:&lt;br /&gt;                    displayValue = string.Format(&amp;quot;{0}, {1}&amp;quot;, field.LastName, field.FirstName);&lt;br /&gt;                    break;&lt;br /&gt;                case &amp;quot;Complete&amp;quot;:&lt;br /&gt;                default:&lt;br /&gt;                    displayValue = field.FullName;&lt;br /&gt;                    break;&lt;br /&gt;            }&lt;br /&gt;            args.Result.FirstPart = displayValue;&lt;br /&gt;            args.DisableWebEditContentEditing = true;&lt;br /&gt;            args.WebEditClick = &amp;quot;return Sitecore.WebEdit.editControl($JavascriptParameters,'sctest:EditNameButton');&amp;quot;;&lt;br /&gt;            break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Step 7 - Use the custom field renderer&lt;/b&gt;&lt;br /&gt;Now I'm ready to use my custom field renderer.  I need to add the following code to the top of my sublayout:&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@ Register TagPrefix="sctest" Namespace="sctest" Assembly="sctest" %&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And then I need to use my new field renderer:&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;sctest:NameFieldControl ID="NameFieldControl1" runat="server" Field="Name" Format="LastCommaFirst" /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;When I view my site, I see that the name field is formatted as specified.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S6l2eVS5TqI/AAAAAAAADM0/gBqnm0bFtao/s1600-h/formatted+name+field+value.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 142px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S6l2eVS5TqI/AAAAAAAADM0/gBqnm0bFtao/s320/formatted+name+field+value.jpg" alt="" id="BLOGGER_PHOTO_ID_5452019087393246882" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Custom field renderer in action.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Next steps&lt;/b&gt;&lt;br /&gt;This is the end of my 3-part series on custom fields. You can download the finished source code &lt;a href="http://www.mediafire.com/?ncutxmmymic"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Want to learn more?&lt;/b&gt;&lt;br /&gt;See my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-2.html"&gt;previous post&lt;/a&gt; for good links.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-7224493283731785908?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/7224493283731785908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7224493283731785908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7224493283731785908'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-3.html' title='Custom Fields, Part 3'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_SD7mxqHQu2M/S6l3hdUgVLI/AAAAAAAADM8/mZ9tPv-UQY8/s72-c/inline+edit+name+field.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-4961085577023496123</id><published>2010-03-22T08:00:00.008-04:00</published><updated>2010-03-23T16:16:21.757-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='customizations'/><title type='text'>Custom Fields, Part 2</title><content type='html'>In my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-1.html"&gt;Custom Fields, Part 1&lt;/a&gt; post I demonstrated how to create a customized user interface for editing field content in Content Editor.  This post is going to cover how to do the same sort of thing for Page Editor.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-f2b4e21d14e676ac" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v3.nonxt7.googlevideo.com/videoplayback?id%3Df2b4e21d14e676ac%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330378431%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4CECEA10DF94BE2C9ACC2C1556607ACB28D3F9C4.518F46C2D57D7718F7B02882C1BD3C62CEF3A036%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Df2b4e21d14e676ac%26offsetms%3D5000%26itag%3Dw160%26sigh%3D81BcJ0TpdezwHKbhdQmCawo2P9g&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v3.nonxt7.googlevideo.com/videoplayback?id%3Df2b4e21d14e676ac%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1330378431%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4CECEA10DF94BE2C9ACC2C1556607ACB28D3F9C4.518F46C2D57D7718F7B02882C1BD3C62CEF3A036%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Df2b4e21d14e676ac%26offsetms%3D5000%26itag%3Dw160%26sigh%3D81BcJ0TpdezwHKbhdQmCawo2P9g&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Demonstration of the component described in this post.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I know that I promised a custom field render in my previous post, but that's going to have to wait until my &lt;i&gt;next&lt;/i&gt; post.  This post has more ground to cover than I expected!  But that's OK because a custom field renderer isn't needed to create the custom user interface.  The generic field renderer is able to handle the user interface we're going to build.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A word of warning&lt;/b&gt;&lt;br /&gt;But before I go any further I feel it is important to provide a warning.  When I started looking into custom field types I was very excited by the idea of them.  Then I talked to some colleagues and learned that custom field types are not all that common in the real world.  There are some good reasons for this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;They are not very flexible - If new content needs to be added to a custom field type, it can result in a lot of work.  The amount of work is hard to justify when you consider how easy it is to add a new field on a data template.  In other words, using data templates to define the content is easier than creating and maintaining custom fields.&lt;/li&gt;&lt;li&gt;The parts of Sitecore that are needed to create custom field types are not entirely documented.&lt;/li&gt;&lt;li&gt;Creating this type of customization is risky because of changes that might be made to the API or to the Sitecore user interface in the future.&lt;/li&gt;&lt;/ul&gt;Having said that, I still believe there is value is knowing how to do this.  The exercise has taught me a lot about how Sitecore handles content, as well as how the Sitecore client works.  Now, on to the code...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1 - Refactor name-parsing logic&lt;/span&gt;&lt;br /&gt;In my previous post I included name-parsing logic directly in the name field control.  If you remember, the purpose of this control was to display a custom interface for editing a name field using Content Editor.&lt;br /&gt;&lt;br /&gt;This time I am creating a custom interface for editing a name field using Page Editor, so I'm going to need name-parsing logic again.  Rather than duplicate the code, I'm going to create a utility class to hold that logic:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Assembly name:&lt;/span&gt; sctest.dll&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Namespace:&lt;/span&gt; Sctest&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Class name:&lt;/span&gt; NameFieldUtils&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Base class:&lt;/span&gt; System.Object&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;public class NameFieldUtils&lt;br /&gt;{&lt;br /&gt; public static string GetFullName(string firstName, string lastName)&lt;br /&gt; {&lt;br /&gt;   var name = new string[2];&lt;br /&gt;   name[0] = firstName;&lt;br /&gt;   name[1] = lastName;&lt;br /&gt;   return String.Join(" ", name);&lt;br /&gt; }&lt;br /&gt; public static string GetFirstName(string fullName)&lt;br /&gt; {&lt;br /&gt;   string[] parts = fullName.Split(' ');&lt;br /&gt;   if (parts.Length &amp;gt;= 1)&lt;br /&gt;   {&lt;br /&gt;       return parts[0];&lt;br /&gt;   }&lt;br /&gt;   return string.Empty;&lt;br /&gt; }&lt;br /&gt; public static string GetLastName(string fullName)&lt;br /&gt; {&lt;br /&gt;   string[] parts = fullName.Split(' ');&lt;br /&gt;   if (parts.Length &amp;gt;= 2)&lt;br /&gt;     return parts[1];&lt;br /&gt;   return string.Empty;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2 - Rename the NameField class to NameControl&lt;/span&gt;&lt;br /&gt;In order to avoid any possible confusion regarding the purpose of the various classes being created, rename the control created in the last post to NameControl.  Recompile your code.  Don't forget to change the control name in the core database, too (&lt;span style="font-family:courier new;"&gt;/sitecore/system/Field types/Custom Field Types/Name Field&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3 - Modify the OnLoad method from NameControl&lt;/span&gt;&lt;br /&gt;The name-parsing logic was moved into NameFieldUtils, so the OnLoad method should use NameFieldUtils.  OnLoad should look like the following:&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;protected override void OnLoad(EventArgs e)&lt;br /&gt;{&lt;br /&gt;   if (!Sitecore.Context.ClientPage.IsEvent)&lt;br /&gt;   {&lt;br /&gt;       //&lt;br /&gt;       //create the controls&lt;br /&gt;       var textFirstName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;       this.Controls.Add(textFirstName);&lt;br /&gt;       textFirstName.ID = GetID("textFirstName");&lt;br /&gt;       var textLastName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;       this.Controls.Add(textLastName);&lt;br /&gt;       textLastName.ID = GetID("textLastName");&lt;br /&gt;       //&lt;br /&gt;       //set the values on the textbox controls&lt;br /&gt;       textFirstName.Value = NameFieldType.GetFirstName(this.Value);&lt;br /&gt;       textLastName.Value = NameFieldType.GetLastName(this.Value); ;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;       //&lt;br /&gt;       //read the values from the textbox controls&lt;br /&gt;       var textFirstName = FindControl(GetID("textFirstName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;       var textLastName = FindControl(GetID("textLastName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;       //&lt;br /&gt;       //set the value on the NameControl control&lt;br /&gt;       var firstName = (textFirstName != null ? textFirstName.Value : string.Empty);&lt;br /&gt;       var lastName = (textLastName != null ? textLastName.Value : string.Empty);&lt;br /&gt;       this.Value = NameFieldType.GetFullName(firstName, lastName);&lt;br /&gt;   }&lt;br /&gt;   base.OnLoad(e);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is a good point to test your changes.  Recompile your code and make sure everything works as it did before you started reading this post.  No new functionality has been added to Sitecore yes, so your code should work the same as it did before.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4 - Create a layout&lt;/span&gt;&lt;br /&gt;The Sitecore client user interface is built using XAML.  This technology allows user interface components to be defined using XML.  An XML Layout can be used to define the user interface.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Switch to the core database.&lt;/li&gt;&lt;li&gt;Open Developer Center.&lt;/li&gt;&lt;li&gt;In the top menu, select File --New.&lt;/li&gt;&lt;li&gt;The New File window appears.  Select XML Layout from the Layouts category.&lt;/li&gt;&lt;li&gt;Click the Create button.&lt;/li&gt;&lt;li&gt;The new file wizard appears.  For the name enter "Name Field Editor Layout".  Then click the Next button.&lt;/li&gt;&lt;li&gt;For the location select the &lt;span style="font-family:courier new;"&gt;\Layouts\Dialogs&lt;/span&gt; node.  Click the Next button.&lt;/li&gt;&lt;li&gt;For the file location select the &lt;span style="font-family:courier new;"&gt;\Website\layouts&lt;/span&gt; node.  Click the Create button.&lt;/li&gt;&lt;li&gt;Click the Finish button.&lt;/li&gt;&lt;li&gt;The newly created XAML file appears in Developer Center.  This file can be edited using Developer Center, or by editing the file Test Field Editor Layout.xml directly from the file system.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Step 5 - Specify the user interface components&lt;/span&gt;&lt;br /&gt;The XML file created in the previous step must have controls in order to display a meaningful user interface.&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;&amp;lt;control xmlns:def="Definition" xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense"&amp;gt;&lt;br /&gt; &amp;lt;NameFieldEditorLayout&amp;gt;&lt;br /&gt;   &amp;lt;FormDialog Icon="Applications/32x32/text_marked.png" Header="Enter Name" Text="Enter the name." OKButton="OK"&amp;gt;&lt;br /&gt;     &amp;lt;GridPanel Columns="2"&amp;gt;&lt;br /&gt;       &amp;lt;Literal Text="First name:"/&amp;gt;&lt;br /&gt;       &amp;lt;Edit ID="FirstName" Width="300" /&amp;gt;&lt;br /&gt;       &amp;lt;Literal Text="Last name:"/&amp;gt;&lt;br /&gt;       &amp;lt;Edit ID="LastName" Width="300" /&amp;gt;&lt;br /&gt;     &amp;lt;/GridPanel&amp;gt;&lt;br /&gt;     &amp;lt;CodeBeside Type="sctest.NameFieldEditor,sctest.dll"/&amp;gt;&lt;br /&gt;   &amp;lt;/FormDialog&amp;gt; &lt;br /&gt; &amp;lt;/NameFieldEditorLayout&amp;gt;&lt;br /&gt;&amp;lt;/control&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Some of the code above is self-explanatory, I think.  Here's a description of the parts that aren't obvious:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;NameFieldEditorLayout&lt;/span&gt; - If you look in the core database you can find the item that was generated when you used Developer Center to create a new XML layout: &lt;span style="font-family:courier new;"&gt;/sitecore/layout/Layouts/Dialogs/Name Field Editor Layout&lt;/span&gt;.  One of the properties of this item is its control name: NameFieldEditorLayout.  This value was automatically generated by Developer Center.  When Sitecore uses the XML layout, it is going to look for the XAML file that has the definition of NameFieldEditorLayout.  By containing the tag NameFieldEditorLayout, this file becomes the file Sitecore will use.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;FormDialog&lt;/span&gt; - Creates a &lt;a href="http://en.wikipedia.org/wiki/Modal_window"&gt;modal window&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;GridPanel&lt;/span&gt; - Creates a 2-column table.  Each control inside the GridPanel tag gets its own cell.  The 1st control gets the 1st cell in the 1st column.  The 2nd control gets the 2nd cell in the 1st column.  The 3rd control gets the 1st cell in the 2nd column.  The 4th control gets the 2nd cell in the 2nd column.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;CodeBeside&lt;/span&gt; - Defines the file that will contain code like event handlers.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Step 6 - Create the CodeBeside file&lt;/span&gt;&lt;br /&gt;This file contains the code to handle events generated by the user interface.  There are 2 methods in this file:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;OnLoad&lt;/span&gt; - This code runs when the dialog window is loaded.  Specifically, the code sets the values of the FirstName and LastName input fields to be the current field value.  This is done by reading a query string value.  The query string value is set by code I will write in a later step.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;OnOK&lt;/span&gt; - This code runs when the OK button is clicked.  Specifically, the code passes the values in the FirstName and LastName input fields back to the code that opened the dialog window in the first place.  That, also, is code that I will write in a later step.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;public class NameFieldEditor : DialogForm&lt;br /&gt;{&lt;br /&gt;   protected Sitecore.Web.UI.HtmlControls.Edit FirstName;&lt;br /&gt;   protected Sitecore.Web.UI.HtmlControls.Edit LastName;&lt;br /&gt;   protected override void OnLoad(EventArgs e)&lt;br /&gt;   {&lt;br /&gt;       if (! Sitecore.Context.ClientPage.IsEvent)&lt;br /&gt;       {&lt;br /&gt;           //&lt;br /&gt;           //The values are not actually stored on the item itself&lt;br /&gt;           //until the save button is clicked, so we can't read&lt;br /&gt;           //the values from the item.  Instead, read the values&lt;br /&gt;           //from the webedit interface.  These values should have&lt;br /&gt;           //been included in the QueryString by the WebEditCommand&lt;br /&gt;           //instance that opened the dialog.&lt;br /&gt;           var name = Sitecore.Context.Request.QueryString["name"];&lt;br /&gt;           if ((name != null) &amp;amp;&amp;amp; (! string.IsNullOrEmpty(name)))&lt;br /&gt;           {&lt;br /&gt;               FirstName.Value = NameFieldType.GetFirstName(name); ;&lt;br /&gt;               LastName.Value = NameFieldType.GetLastName(name); ;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       base.OnLoad(e);   &lt;br /&gt;   }&lt;br /&gt;   protected override void OnOK(object sender, EventArgs args)&lt;br /&gt;   {&lt;br /&gt;       //&lt;br /&gt;       //Write the response value that will be available to the&lt;br /&gt;       //WebEditCommand class that caused this dialog to appear.&lt;br /&gt;       var xml = string.Format("&amp;lt;name&amp;gt;&amp;lt;first&amp;gt;{0}&amp;lt;/first&amp;gt;&amp;lt;last&amp;gt;{1}&amp;lt;/last&amp;gt;&amp;lt;/name&amp;gt;", FirstName.Value, LastName.Value);&lt;br /&gt;       SheerResponse.SetDialogValue(xml);&lt;br /&gt;       base.OnOK(sender, args);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 7 - Create an item for the user interface&lt;/span&gt;&lt;br /&gt;Sitecore needs to know that my user interface is available.  This is done by creating an item in the core database:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item to create the item on:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/content/Applications/Dialogs&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/templates/Common/Folder&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item Name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Name Field Editor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 8 - Identify the layout that applies to the user interface item&lt;/span&gt;&lt;br /&gt;Open the Presentation Details for the item created in the previous step.  Set the layout to be &lt;span style="font-family:courier new;"&gt;Layouts/Dialogs/Name Field Editor Layout&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 9 - Define buttons for the custom field type&lt;/span&gt;&lt;br /&gt;When a content author wants to set a value for a name field, I want the author to be able to click a button that will cause the name field editor dialog to appear.  I need to define the button.  But first I need to create a folder to hold the button.  Create the following item:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item to create the item on:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/system/Field types/Custom Field Types/Name Field&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/templates/Common/Folder&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item Name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;WebEdit Buttons&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next I create the button itself.  Create the following item:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item to create the item on:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/system/Field types/Custom  Field Types/Name Field/WebEdit Buttons&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/System/WebEdit/WebEdit Button&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Item Name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Edit Name&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A couple of field values must be specified for this item.  Set the following values:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Header:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Edit Name&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Click:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;javascript:return Sitecore.WebEdit.editControl($JavascriptParameters, "sctest:EditNameButton")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Tooltip:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Edit Name&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 10 - Register the command&lt;/span&gt;&lt;br /&gt;In the previous step I configured a button.  One of the settings was the Javascript code to run when the button is clicked.  The code tells Sitecore to execute a command named "sctest:EditNameButton" when the button is clicked.  I need to tell Sitecore what code corresponds to this command.  This is done by adding a command to the commands.config file.&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;&amp;lt;command name="sctest:EditNameButton" type="sctest.EditNameButtonCommand,sctest"&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 11 - Implement the command&lt;/span&gt;&lt;br /&gt;The class identified in the previous step contains the logic that is run when the specified command is executed (meaning when the edit name button is  clicked).&lt;br /&gt;&lt;br /&gt;This class extends Sitecore.Shell.Applications.WebEdit.Commands.WebEditCommand.  The class has 2 methods in it:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Execute&lt;/span&gt; - This method reads the current name field value.  It sets this value as a parameter, which is important because this will make the value available inside the &lt;span style="font-style: italic;"&gt;Run()&lt;/span&gt; method.  Then the method calls the &lt;span style="font-style: italic;"&gt;Run()&lt;/span&gt; method.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Run&lt;/span&gt; - If the code is running during a PostBack it means either the Cancel or the OK button was clicked.  If the Cancel button was clicked (there is no result, so args.HasResult is false) there is nothing else to do so the method returns.  If the OK button was clicked, the XML generated by NameFieldEditor.OnOK() is parsed and the first and last names are set for the field in Page Editor.&lt;br /&gt;&lt;br /&gt;If the code is not running during a PostBack, that means someone has clicked the edit name button.  The name field editor dialog window is displayed, and the current field value must be passed to the window.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;public class EditNameButtonCommand : WebEditCommand&lt;br /&gt;{&lt;br /&gt;   public override void Execute(CommandContext context)&lt;br /&gt;   {&lt;br /&gt;       //&lt;br /&gt;       //Read the value that is currently set on the field&lt;br /&gt;       //in the page editor.  Since the page editor interface&lt;br /&gt;       //only writes field values after the user clicks the&lt;br /&gt;       //save button it is important that the value be read&lt;br /&gt;       //from the page editor rather than the item itself.&lt;br /&gt;       var formValue = WebUtil.GetFormValue("scPlainValue");&lt;br /&gt;       context.Parameters.Add("name", formValue);&lt;br /&gt;       Sitecore.Context.ClientPage.Start(this, "Run", context.Parameters);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   protected void Run(ClientPipelineArgs args)&lt;br /&gt;   {&lt;br /&gt;       if (args.IsPostBack)&lt;br /&gt;       {&lt;br /&gt;           if (! args.HasResult)&lt;br /&gt;           {&lt;br /&gt;               return;&lt;br /&gt;           }&lt;br /&gt;           //&lt;br /&gt;           //Read the first and last names from the returned XML.&lt;br /&gt;           var dom = new XmlDocument();&lt;br /&gt;           dom.LoadXml(args.Result);&lt;br /&gt;           var firstName = dom.SelectSingleNode("/name/first").InnerText;&lt;br /&gt;           var lastName = dom.SelectSingleNode("/name/last").InnerText;&lt;br /&gt;           var fullName = NameFieldType.GetFullName(firstName, lastName);&lt;br /&gt;           //&lt;br /&gt;           //Set the first and last names.  These values should not be&lt;br /&gt;           //saved directly on the item.  The page editor will handle&lt;br /&gt;           //that when the user clicks the save button.  Instead, the&lt;br /&gt;           //values should be set in a way that the page editor will&lt;br /&gt;           //store the values until the user clicks the save button.&lt;br /&gt;           SheerResponse.SetAttribute("scHtmlValue", "value", fullName);&lt;br /&gt;           SheerResponse.SetAttribute("scPlainValue", "value", fullName);&lt;br /&gt;           SheerResponse.Eval("scSetHtmlValue('" + args.Parameters["controlid"] + "')");&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;           //&lt;br /&gt;           //get the url for the dialog that needs to be displayed&lt;br /&gt;           var db = Sitecore.Data.Database.GetDatabase("core");&lt;br /&gt;           var item = db.GetItem("{6C57B044-C860-4DAF-982E-5A64E467C1CD}");&lt;br /&gt;           var url = new UrlString(LinkManager.GetItemUrl(item));&lt;br /&gt;           //&lt;br /&gt;           //pass the current value to the dialog&lt;br /&gt;           var name = args.Parameters["name"];&lt;br /&gt;           if (name != null)&lt;br /&gt;               url.Add("name", name);&lt;br /&gt;           //&lt;br /&gt;           //display the dialog&lt;br /&gt;           Sitecore.Context.ClientPage.ClientResponse.ShowModalDialog(url.ToString(), true);&lt;br /&gt;           args.WaitForPostBack();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note: in order to compile this code, you may need to add a reference to the Sitecore.Client.dll assembly.  If using Visual Studio because to set CopyLocal to false.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 12 - Test the code&lt;/span&gt;&lt;br /&gt;After I compile my code I am ready to test it.  I need to make sure I have a field in a data template that uses the Name Field type.  In the sublayout (or rendering) you're using to display the field value, make sure you're using the field renderer to display the value.  You should be able to go into page editor and click the Edit Name button.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_SD7mxqHQu2M/S6bP80ygnXI/AAAAAAAADMk/2WiaKk_rqao/s1600-h/edit+names+button.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 147px;" src="http://4.bp.blogspot.com/_SD7mxqHQu2M/S6bP80ygnXI/AAAAAAAADMk/2WiaKk_rqao/s320/edit+names+button.jpg" alt="" id="BLOGGER_PHOTO_ID_5451273042848161138" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;And when I click the button, I see the name field editor.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S6bQBDNVBxI/AAAAAAAADMs/2IC_qQjPH3M/s1600-h/name+field+editor.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 172px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S6bQBDNVBxI/AAAAAAAADMs/2IC_qQjPH3M/s320/name+field+editor.jpg" alt="" id="BLOGGER_PHOTO_ID_5451273115438221074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next steps&lt;/span&gt;&lt;br /&gt;In my next post I will demonstrate how to create a custom field renderer.  Also, when you use the default field renderer on a name field, you may notice there is some unwanted functionality.  I'll tell you what it is in my next post - along with a solutions for it.  In the meantime, here's a hint: is there any way for a Page Editor user to circumvent the name field editor interface?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://learnsitecore.cmsuniverse.net/en/Developers/Articles/2009/10/My-First-Sitecore-XAML-Application.aspx"&gt;Writing My First XAML Application&lt;/a&gt; - Great tutorial that guides you through every step in creating a XAML application.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Articles/XML%20Sheer%20UI.aspx"&gt;XML/Sheer UI articles on SDN&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://alexeyrusakov.com/sitecoreblog/CategoryView,category,Sitecore,Sheer%2BUI.aspx"&gt;Alexey Rusakov's blog&lt;/a&gt; - Alexey has written a number of outstanding posts on this subject, and has tagged them for your convenience.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-4961085577023496123?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/4961085577023496123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/4961085577023496123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/4961085577023496123'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-2.html' title='Custom Fields, Part 2'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_SD7mxqHQu2M/S6bP80ygnXI/AAAAAAAADMk/2WiaKk_rqao/s72-c/edit+names+button.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-6925417932624602324</id><published>2010-03-05T07:00:00.016-05:00</published><updated>2010-03-31T21:40:00.635-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='customizations'/><title type='text'>Custom Fields, Part 1</title><content type='html'>Like most WCM systems, &lt;a href="http://www.sitecore.net/"&gt;Sitecore&lt;/a&gt; supports both structured and unstructured content.  The difference between structured and unstructured content can be explained through an example.  Let's say you want to allow a person from the marketing department to create a new press release for your website.  With structured content the person would need to provide a title, date, description, and an image.  With unstructured content the person would get a big HTML field and would provide any values he wants.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is a field type?&lt;/span&gt;&lt;br /&gt;When working with structured content, the concept of "content type" is important.  Is the content you're modeling a string, a date or an image?  If the content is a string, is formatting supported?  The answers to these questions determine what the user interface looks like for the people using the system.&lt;br /&gt;&lt;br /&gt;Sitecore has an interesting way of handling content type.  Content is defined using fields, and each field has a type.  Sitecore comes with a large number of different field types out of the box.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why should you be interested in custom field types?&lt;/span&gt;&lt;br /&gt;As powerful and flexible as Sitecore field types are, it is possible that you will encounter a requirement that would be much easier to meet if you create your own field type.&lt;br /&gt;&lt;br /&gt;Not all WCM systems can do this.  The impact of this is a significantly more complicated content model.  This means more work for developers to create and more work for content authors to use.  It also has a potentially devastating effect on workflow (imagine a proliferation of distinct pieces of managed content that somehow must be related).&lt;br /&gt;&lt;br /&gt;This functionality has so many applications.  It can be used to integrate with external data sources.  It can be used to create easier-to-use interfaces for text values (as this article will explain).  It can be used to facilitate content migration.  And much more.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How are custom field types handled in Sitecore?&lt;/span&gt;&lt;br /&gt;As you would expect, Sitecore provides many ways to handle custom field types.  And as you would expect, the method you choose depends on your requirements.  I'm going to cover a number of these in future posts.&lt;br /&gt;&lt;br /&gt;To give you an idea of the scope of this topic, developing a custom field requires you consider the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;How does a person edit field content in Content Editor mode?&lt;/li&gt;&lt;li&gt;How does a person edit field content in Page Editor mode?&lt;/li&gt;&lt;li&gt;How is field content stored in Sitecore?&lt;/li&gt;&lt;li&gt;How is field content accessed using the Sitecore API?&lt;/li&gt;&lt;li&gt;How is field content rendered in presentation logic?&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Not every custom field needs to have a custom solution for each of these.  This post covers only the first one.  I will explain how to create a custom interface for entering a text value.  I think this is a good place to start since a large part of creating custom field types is building the user interface for reading and writing field content.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://sdn.sitecore.net/"&gt;Sitecore Developer Network&lt;/a&gt; has an &lt;a href="http://sdn.sitecore.net/Articles/API/Creating%20a%20Composite%20Custom%20Field.aspx"&gt;excellent article&lt;/a&gt; that explains how to create something called a "composite custom field".  What this post covers is very similar to that, but is much simpler.  This will give me something to build on in subsequent posts.&lt;br /&gt;&lt;br /&gt;This post will explain how to create a custom field to make it a little easier to enter a person's name.  For the sake of simplicity, I am going to assume that a person has a first name (given name) and a last name (family name or surname).  The person's name will be stored as a single value in Sitecore, but the user interface will allow content editors to enter the values separately.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is a composite custom field?&lt;/span&gt;&lt;br /&gt;A composite custom field is made up of existing field types.  My custom field needs to support two separate text values.  Since Sitecore already has the Text field type, a composite custom field is appropriate.  I can use two Text fields to create my custom field.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1 - Create an HTML server control&lt;/span&gt;&lt;br /&gt;Using Visual Studio create the following class.  This control will generate the user interface Sitecore displays when someone edits the value of a field:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Assembly name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;sctest.dll&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Namespace:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Sctest&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Class name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;NameField&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Base class:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Sitecore.Web.UI.HtmlControls.Control&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2 - Override the OnLoad method&lt;/span&gt;&lt;br /&gt;In the &lt;span style="font-family:courier new;"&gt;Sctest.NameField&lt;/span&gt; class, override the &lt;span style="font-family:courier new;"&gt;OnLoad&lt;/span&gt; method.  This method is inherited from &lt;span style="font-family:courier new;"&gt;System.Web.UI.WebControl&lt;/span&gt;, which is a base class for &lt;span style="font-family:courier new;"&gt;Sitecore.Web.UI.HtmlControls.Control&lt;/span&gt;.  Just like with a standard ASP.NET web control, the purpose of this method is to load and set properties on child controls.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;protected override void OnLoad(EventArgs e)&lt;br /&gt;{&lt;br /&gt;base.OnLoad(e);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This control needs 2 textbox controls (first name and last name).  The first thing this method does is checks to see if these controls have already been loaded.  This is accomplished by checking the value of the &lt;span style="font-family:courier new;"&gt;IsEvent&lt;/span&gt; property on the &lt;span style="font-family:courier new;"&gt;ClientPage&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;protected override void OnLoad(EventArgs e)&lt;br /&gt;{&lt;br /&gt;if (!Sitecore.Context.ClientPage.IsEvent)&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;base.OnLoad(e);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ClientPage&lt;/span&gt; represents the current web form.  Checking &lt;span style="font-family:courier new;"&gt;ClientPage.IsEvent&lt;/span&gt; is very similar to checking &lt;span style="font-family:courier new;"&gt;Page.IsPostback&lt;/span&gt; in ASP.NET.  This layer of abstraction is important because it frees Sitecore from being tied to web forms.  But that's a topic for a later post.&lt;br /&gt;&lt;br /&gt;If &lt;span style="font-family:courier new;"&gt;ClientPage.IsEvent&lt;/span&gt; is not true it is likely that the 2 textbox controls have not already been created.  The textboxes need to be created.  The textbox controls also need to be added as children on the NameField control.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;//&lt;br /&gt;//create the textbox controls&lt;br /&gt;var textFirstName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;textFirstName.ID = GetID("textFirstName");&lt;br /&gt;var textLastName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;textLastName.ID = GetID("textLastName");&lt;br /&gt;//&lt;br /&gt;//add the textbox controls as children&lt;br /&gt;this.Controls.Add(textFirstName);&lt;br /&gt;this.Controls.Add(textLastName);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The current item may already have a value set for the name, so that value needs to be loaded into the control.  Sitecore handles the work of actually reading and writing field values.  It does so through the control's &lt;span style="font-family:courier new;"&gt;Value&lt;/span&gt; property.  The &lt;span style="font-family:courier new;"&gt;Value&lt;/span&gt; property is a string, which should come as no surprise since, internally, Sitecore stores content as text.&lt;br /&gt;&lt;br /&gt;The logic we will use is very simple.  The first space character in the value will serve as the separator between the first and last names.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;var firstName = "";&lt;br /&gt;var lastName = "";&lt;br /&gt;var currentValue = this.Value;&lt;br /&gt;var firstSpace = currentValue.IndexOf(' ');&lt;br /&gt;if (firstSpace == -1)&lt;br /&gt;{&lt;br /&gt;firstName = currentValue;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;firstName = currentValue.Substring(0, firstSpace);&lt;br /&gt;lastName = currentValue.Substring(firstSpace).Trim();&lt;br /&gt;}&lt;br /&gt;textFirstName.Value = firstName;&lt;br /&gt;textLastName.Value = lastName;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Next we need to consider the code that belongs in the else-block.  This code runs when &lt;span style="font-family:courier new;"&gt;ClientPage.IsEvent&lt;/span&gt; is true.  One important example of when this code will run is when an item is saved.  Specifically, this code will run when the item is saved using a &lt;span style="font-family:courier new;"&gt;ClientPage&lt;/span&gt; with this control on it.  For this reason, this code must take the values from the 2 textbox controls and set a value on the NameField control.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;var textFirstName = FindControl(GetID("textFirstName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;var textLastName = FindControl(GetID("textLastName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;var name = new string[2];&lt;br /&gt;name[0] = textFirstName.Value;&lt;br /&gt;name[1] = textLastName.Value;&lt;br /&gt;this.Value = String.Join(" ", name);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The complete code is the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;public class NameField : Sitecore.Web.UI.HtmlControls.Control&lt;br /&gt;{&lt;br /&gt;protected override void OnLoad(EventArgs e)&lt;br /&gt;{&lt;br /&gt;  if (!Sitecore.Context.ClientPage.IsEvent)&lt;br /&gt;  {&lt;br /&gt;    //&lt;br /&gt;    //create the controls&lt;br /&gt;    var textFirstName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;    this.Controls.Add(textFirstName);&lt;br /&gt;    textFirstName.ID = GetID("textFirstName");&lt;br /&gt;    var textLastName = new Sitecore.Shell.Applications.ContentEditor.Text();&lt;br /&gt;    this.Controls.Add(textLastName);&lt;br /&gt;    textLastName.ID = GetID("textLastName");&lt;br /&gt;    //&lt;br /&gt;    //get the current value&lt;br /&gt;    var firstName = "";&lt;br /&gt;    var lastName = "";&lt;br /&gt;    var currentValue = this.Value;&lt;br /&gt;    var firstSpace = currentValue.IndexOf(' ');&lt;br /&gt;    if (firstSpace == -1)&lt;br /&gt;    {&lt;br /&gt;      firstName = currentValue;&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;      firstName = currentValue.Substring(0, firstSpace);&lt;br /&gt;      lastName = currentValue.Substring(firstSpace).Trim();&lt;br /&gt;    }&lt;br /&gt;    //&lt;br /&gt;    //set the values on the textbox controls&lt;br /&gt;    textFirstName.Value = firstName;&lt;br /&gt;    textLastName.Value = lastName;&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;    //&lt;br /&gt;    //read the values from the textbox controls&lt;br /&gt;    var textFirstName = FindControl(GetID("textFirstName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;    var textLastName = FindControl(GetID("textLastName")) as Sitecore.Shell.Applications.ContentEditor.Text;&lt;br /&gt;    var name = new string[2];&lt;br /&gt;    name[0] = textFirstName.Value;&lt;br /&gt;    name[1] = textLastName.Value;&lt;br /&gt;    //&lt;br /&gt;    //set the value on the NameField control&lt;br /&gt;    this.Value = String.Join(" ", name);&lt;br /&gt;  }&lt;br /&gt;  base.OnLoad(e);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3 - Compile your code &lt;/span&gt;&lt;br /&gt;Compile your code and put the assembly in a directory that Sitecore will be able to find it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4 - Define a custom field type in Sitecore&lt;/span&gt;&lt;br /&gt;This step involves adding the custom field to the Sitecore client so that developers can use it.&lt;br /&gt;&lt;br /&gt;Step 4.1.  Log into the Sitecore Content Editor and connect to the core database.&lt;br /&gt;&lt;br /&gt;Step 4.2. Create the following item:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item to create the item on:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/system/Field types&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/templates/Common/Folder&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item Name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Custom Field Types&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Step 4.3. Create the following item:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item to create the item on:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/system/Field types/Custom Field Types&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/System/Templates/Template field type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Item Name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Name Field&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Step 4.4. Select the Name Field item.  Enter the following field values:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Control:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;myfields:NameField&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Step 4.5. Save your changes and switch to the master database.&lt;br /&gt;&lt;br /&gt;What you have just done is told Sitecore is that a new field type is available.  This field type is named "myfields:NameField".  How does Sitecore know what code to use when this field type is used?  That is configured in the next step.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 5 - Map the field prefix to an assembly and namespace&lt;/span&gt;&lt;br /&gt;The custom field's name (configured in the previous step) is a combination of a prefix (myfields) and a class name (NameField).  This step involves telling Sitecore which assembly contains the class NameField.&lt;br /&gt;&lt;br /&gt;This is done through the &lt;span style="font-family:courier new;"&gt;web.config&lt;/span&gt; file.  I added the following line to the &lt;span style="font-family:courier new;"&gt;/configuration/sitecore/controlSources&lt;/span&gt; node.  It tells Sitecore that any control identified using the prefix "myfields" can be located in the "sctest" assembly and is a part of the "sctest" namespace:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;source mode="on" namespace="sctest" assembly="sctest" prefix="myfields" /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How to use a composite custom field&lt;/span&gt;&lt;br /&gt;Now, when you configure a field in a Data Template, you should see a new option available in the list of field types.  I added the following field:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Data template:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;/sitecore/templates/Sample/Sample Item&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Field name:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Name&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Type:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;Name Field&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The Home item in my installation is an instance of this data template.  Using Content Editor, I see the following when I edit content:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_SD7mxqHQu2M/S5BZlZFp2xI/AAAAAAAADLs/xhC2HSEFpno/s1600-h/field.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 72px;" src="http://1.bp.blogspot.com/_SD7mxqHQu2M/S5BZlZFp2xI/AAAAAAAADLs/xhC2HSEFpno/s320/field.jpg" alt="" id="BLOGGER_PHOTO_ID_5444950448415562514" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I also modified the layout that is used for this item so that the name value appears on the website.  I added the following code inside the body:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;sc:text runat="server" field="Name" id="Text1"&gt;&lt;/sc:text&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next steps&lt;/span&gt;&lt;br /&gt;We have created a custom interface for configuring content using Content Editor, but this interface is not available in Page Editor.  The next step is to expand this functionality to Page Editor.  This will require a custom field renderer web control.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Articles/API/Creating%20a%20Composite%20Custom%20Field.aspx"&gt;Creating a Composite Custom Field (SDN)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;Data Definition Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;Sitecore training&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-6925417932624602324?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/6925417932624602324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6925417932624602324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6925417932624602324'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/03/custom-fields-part-1.html' title='Custom Fields, Part 1'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_SD7mxqHQu2M/S5BZlZFp2xI/AAAAAAAADLs/xhC2HSEFpno/s72-c/field.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-7881132081442019015</id><published>2010-02-22T22:00:00.001-05:00</published><updated>2010-02-23T10:19:39.336-05:00</updated><title type='text'>Blog Update</title><content type='html'>Just wanted to let everyone know about a small - but important - change I recently made on this blog.  I went back through my previous posts and added links to the relevant Sitecore resources so you can get more information on the topics discussed.  Look for the "Want to learn more?" section at the end of each post.  I will be including this information in all future posts as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-7881132081442019015?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/7881132081442019015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/blog-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7881132081442019015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/7881132081442019015'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/blog-update.html' title='Blog Update'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-5938386015769312797</id><published>2010-02-12T09:00:00.004-05:00</published><updated>2010-02-23T10:11:44.262-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>How Sitecore Determines Which Layout To Use</title><content type='html'>Recently I've written about the core components of Sitecore's approach to presentation logic: &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/defining-presentation.html"&gt;layouts&lt;/a&gt;  and controls (&lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/02/sublayouts-and-web-controls.html"&gt;.NET&lt;/a&gt;  and &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/02/renderings.html"&gt;XSLT&lt;/a&gt;) and &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/02/how-presentation-controls-are-used-in.html"&gt;placeholders&lt;/a&gt;.  I've explained how content is displayed in layouts, and how controls are positioned inside them.  What I haven't covered is how Sitecore knows which layout to use and when.  That is the topic of this post.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How content is viewed in Sitecore?&lt;/font&gt;&lt;br /&gt;When someone wants to view content from Sitecore, a request is made through a URL.  In Sitecore, every URL resolves to an item in the system.  What Sitecore returns when a request is made is a visual representation of the item that corresponds to the URL.  We know that layouts provide the basic structure of this visual representation, but how does Sitecore know which layout to apply to which item?&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;What is a device?&lt;/font&gt;&lt;br /&gt;A device represents a specific way of viewing content in Sitecore.  Sitecore analyzes a request in order to determine how the user wants to view content.&lt;br /&gt;&lt;br /&gt;This determination is based on rules a developer configures.  Sitecore allows the browser agent and query string values to be used to define rules.  (Of course, it is also possible to extend Sitecore to support other criteria.)  If you anticipate visitors will use desktop web browsers and mobile phones to access your site, you might configure 2 devices.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SD7mxqHQu2M/S2wRWf4LGLI/AAAAAAAADLA/68o70c8nuEY/s1600-h/iphone-device.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 136px;" src="http://3.bp.blogspot.com/_SD7mxqHQu2M/S2wRWf4LGLI/AAAAAAAADLA/68o70c8nuEY/s320/iphone-device.jpg" alt="" id="BLOGGER_PHOTO_ID_5434737928541247666" border="0"&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font style="font-style: italic;"&gt;Device configuration options.&lt;/font&gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It's important to note that devices themselves don't do anything.  A device does not specify which layout should be used.  Sitecore inspects incoming requests in order to determine which device is appropriate for each request.  After Sitecore figures this out, the device is just one of many pieces of information that are passed along to be used by other parts of the system.  Other parts of the system may contain conditional logic that considers the device as a part of its operation.&lt;br /&gt;&lt;br /&gt;I think the word device fails to convey the flexibility of devices.  A visitor to the website can start out using one device and then can switch to another device without leaving his browser. Devices could be used to try out new HTML using live content without disrupting the live site.  I'm not sure "device" is the best English word for the concept, but that is the word that Sitecore uses.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How are devices configured?&lt;/font&gt;&lt;br /&gt;Devices are configured under the &lt;font face="courier new"&gt;/sitecore/Layout/Devices&lt;/font&gt; node.  After you create a device, you can specify the browser agent value and/or the query string value that Sitecore should use to uniquely identify the device.  These values can be changed at any time in the future, so you don't need to be too worried about making a mistake.&lt;br /&gt;&lt;br /&gt;BTW, when you provide a browser agent value, Sitecore checks to see if your value is found in the &lt;a href="http://en.wikipedia.org/wiki/User_agent"&gt;User-Agent request header&lt;/a&gt;.  Sitecore performs a &lt;a href="http://msdn.microsoft.com/en-us/library/system.stringcomparer.ordinalignorecase.aspx"&gt;case-insensitive&lt;/a&gt; search using &lt;a href="http://msdn.microsoft.com/en-us/library/ms224425.aspx"&gt;IndexOf()&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How does a device relate to an item?&lt;/font&gt;&lt;br /&gt;When you want to view an item, you always view the item through a device.  Therefore it makes sense that device settings can be configured at the item level. However, since all items that are based on the same data template are probably displayed in the same way, a better place to configure device settings is on the data template itself (using standard fields, of course).&lt;br /&gt;&lt;br /&gt;By configuring the device settings on the data template you are setting a default value.  You're telling Sitecore that unless the device settings are overridden on a specific item, these are the settings Sitecore should use.  One of the device settings indicates which layout Sitecore should use.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Presentation Details&lt;/font&gt;&lt;br /&gt;The section of the Sitecore user interface that allows a layout to be specified for a device is called "presentation details".  Like I mentioned above, presentation details can be set on data templates and on individual items (though the former is preferred).&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;font size="2"&gt;&lt;a style="font-style: italic;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_SD7mxqHQu2M/S2wJsHryJDI/AAAAAAAADKw/BZg4OWCV6Bk/s1600-h/presentation-details.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 91px;" src="http://1.bp.blogspot.com/_SD7mxqHQu2M/S2wJsHryJDI/AAAAAAAADKw/BZg4OWCV6Bk/s320/presentation-details.jpg" alt="" id="BLOGGER_PHOTO_ID_5434729503910929458" border="0"&gt;&lt;/a&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font style="font-style: italic;"&gt;Presentation details in the Sitecore user interface.&lt;/font&gt;&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The presentation details section displays all of the devices that have been defined.  For each device, they layout that has been assigned for the device is displayed.  This is tell you that when a certain item is viewed using a certain device, a certain layout should be used.  These settings can be changed at any time.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S2wM9ZqKJlI/AAAAAAAADK4/yZs2KzAyvng/s1600-h/layout-details.jpg"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 186px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S2wM9ZqKJlI/AAAAAAAADK4/yZs2KzAyvng/s320/layout-details.jpg" alt="" id="BLOGGER_PHOTO_ID_5434733099328611922" border="0"&gt;&lt;/a&gt;&lt;font size="2"&gt;&lt;font style="font-style: italic;"&gt;The layout details screen lists devices and the layout assigned to each.&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;What's next?&lt;/font&gt;&lt;br /&gt;Now that I've gotten through the absolute basics of content modeling and presentation logic using Sitecore, I'm going to move onto different topics.  Hopefully some that won't take almost 10 posts to cover.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-5938386015769312797?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/5938386015769312797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/how-sitecore-determines-which-layout-to.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/5938386015769312797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/5938386015769312797'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/how-sitecore-determines-which-layout-to.html' title='How Sitecore Determines Which Layout To Use'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_SD7mxqHQu2M/S2wRWf4LGLI/AAAAAAAADLA/68o70c8nuEY/s72-c/iphone-device.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-8331870914732109724</id><published>2010-02-09T10:00:00.014-05:00</published><updated>2010-02-23T10:10:13.122-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>How Presentation Controls Are Used In Sitecore</title><content type='html'>My last several posts have covered controls  (&lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/02/sublayouts-and-web-controls.html"&gt;.NET&lt;/a&gt;  and &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/02/renderings.html"&gt;XSLT&lt;/a&gt;).  The purpose of controls are to allow presentation logic and functionality to be reused.  One thing I haven't explained is how controls are actually used.&lt;br /&gt;&lt;br /&gt;Controls can be used in two ways.  One way is probably pretty obvious: you can put presentation controls directly in a layout using web controls.  Sitecore provides web controls for positioning sublayouts and renderings.  Since Sitecore web controls are already ASP.NET web controls, they can be used as-is.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;sc:Rendering ID="Rendering1" runat="server" RenderingName="SiteNavigation"&gt;&lt;/sc:Rendering&gt;&lt;br /&gt;&lt;sc:Sublayout ID="Sublayout1" runat="server" Path="/layouts/products/ProductDetail.ascx"&gt;&lt;/sc:Sublayout&gt;&lt;br /&gt;&lt;custom:MyWebControl id="MyWebControl1" runat="server"&gt;&lt;/custom:MyWebControl&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Positioning presentation controls directly in a layout is sometimes called "static binding".  The words refer to the idea that the controls are positioned in the layout in a way that does not change.&lt;br /&gt;&lt;br /&gt;Which leads us to the second way to position controls: dynamically.  Using dynamic binding, a control is positioned in a layout by a content editor rather than a developer.  If you're comfortable with the concept of variables, the approach Sitecore uses will make perfect sense:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Developer creates a "placeholder" in a layout.  The placeholder is given a name.&lt;/li&gt;&lt;li&gt;Developer specifies the controls that a content editor will be allowed to put into the placeholder.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The content editor selects placeholder he wants to position a control in.&lt;/li&gt;&lt;li&gt;The content editor selects the control he wants to drop into the placeholder.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Step 1 involves inserting a web control into the layout.  Step 2 involves configuration inside Sitecore.  Steps 3 and 4 can be performed in a number of ways.  The following video demonstrates how to do it using Page Editor.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/hjValyEZVhw&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/hjValyEZVhw&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Now, there is a little more to working with placeholders than the 4  simple steps I listed above.  The missing piece is understanding how Sitecore knows to you the layout in the first place.  That is key because the placeholder is defined in the layout.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;I just tipped my hand, but defining content and presentation only get you so far. In order for either to be useful, they must work together. My next post will cover how you tell Sitecore which presentation should be used for which content.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-8331870914732109724?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/8331870914732109724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/how-presentation-controls-are-used-in.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8331870914732109724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8331870914732109724'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/how-presentation-controls-are-used-in.html' title='How Presentation Controls Are Used In Sitecore'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-6616365988186432232</id><published>2010-02-05T14:00:00.003-05:00</published><updated>2010-02-23T10:08:42.675-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Renderings</title><content type='html'>Presentation controls are an important part of Sitecore's strategy for displaying content.  When these controls are created using .NET they are either sublayouts or web controls.  When these controls are created using XSLT then are called "renderings"&lt;br /&gt;&lt;br /&gt;Renderings serve the same purpose as any other presentation control (they provide blocks of reusable presentation logic).  They are configured in the same way (they consist of a definition item as well as a physical file).  They are developed and deployed similarly (changes to the files the definition items point to can be changed and deployed without having to notify Sitecore).&lt;br /&gt;&lt;br /&gt;The idea with renderings is that Sitecore provides a view of itself in an XML structure, which can be transformed into HTML (or whatever presentation format you want) using XSLT.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;item name="Home" key="home" id="{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}" tid="{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}" mid="{00000000-0000-0000-0000-000000000000}" sortorder="-1" language="en" version="1" template="sample item" parentid="{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}"&gt;&lt;br /&gt;&lt;fields&gt;&lt;br /&gt;&lt;field tfid="{A60ACD61-A6DB-4182-8329-C957982CEC74}" key="text" type="Rich Text"&gt;&lt;br /&gt;&lt;content&gt;&lt;/content&gt;&lt;br /&gt;&lt;/field&gt;&lt;br /&gt;&lt;field tfid="{25BED78C-4957-4165-998A-CA1B52F67497}" key="__created" type="datetime"&gt;&lt;br /&gt;&lt;content&gt;&lt;/content&gt;&lt;br /&gt;&lt;/field&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/fields&gt;&lt;/item&gt;&lt;/pre&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Sample of the XML representation of a Sitecore item.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;XSL extension methods are used to display field values in renderings. Placeholders cannot be defined in renderings.&lt;br /&gt;&lt;br /&gt;One of the nice features available to you when using renderings is the Sitecore Developer Center.  This is a part of the Sitecore user interface where developers are able to work on and debug their code.  The Developer Center includes a preview screen that allows you to watch your XSLT execute as you write it.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/iCXRLCZ6Nok&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/iCXRLCZ6Nok&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Changes to XSLT files can be previewed inside Sitecore.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;XSLT or not?&lt;/span&gt;&lt;br /&gt;Using XSLT in Sitecore is something that people tend to feel passionate about.  I've heard the arguments (some of them, anyway), but there are 2 things that make me feel that - as a general rule - it's probably better to stay away from XSLT.&lt;br /&gt;&lt;br /&gt;First, .NET code runs much faster than XSLT code in Sitecore.  Some people argue that the proper use of Sitecore's caching features renders this a moot point.  I don't know enough about how Sitecore caching works to know how many situations this holds true for.  I know from working with other system that there are times when content just can't be cached.  For example, personalized navigation.&lt;br /&gt;&lt;br /&gt;My second issue involves code maintenance.  Trying to understand someone else's code is seldom a pleasant task, but trying to understand someone else's XSLT code takes unpleasant to another level.  With .NET code you have Visual Studio to help you in a variety of ways.  I'm not aware of any way to debug XSLT code running in Sitecore.  Sure, it might take 1/2 the time for you to write XSLT code, but I wonder if that efficiency evaporates when it's time for someone else to work with the code.&lt;br /&gt;&lt;br /&gt;Still, it is important to note that renderings are not a gratuitous or deprecated feature.  There are places they are genuinely useful.  In cases where you need to traverse multiple levels of the content tree (building navigation links, for example), using XSLT is a fast and powerful tool.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;Now that we've seen how controls are created, the next thing to cover is how are they used.  My next post will cover this topic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20XSL%20Reference.aspx"&gt;Presentation Component XSL Reference&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-6616365988186432232?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/6616365988186432232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/renderings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6616365988186432232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/6616365988186432232'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/renderings.html' title='Renderings'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-8315287960648848345</id><published>2010-02-01T21:00:00.011-05:00</published><updated>2010-02-23T10:06:51.126-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Sublayouts and Web Controls</title><content type='html'>Previously I explained what Sitecore's presentation controls are and why  they are important.  At this point you're probably ready for some  technical details.  These controls can be written using .NET for XSLT.   In this post I will discuss presentation controls written using .NET.&lt;br /&gt;&lt;br /&gt;When  creating presentation controls using .NET you have two choices: user  controls (which are called sublayouts in Sitecore) and web controls.   For both user controls and web controls, the advantages and  disadvantages inside Sitecore are the same in a regular ASP.NET  application.  Which you use depends on what you're trying to accomplish.   (Microsoft has a &lt;a href="http://support.microsoft.com/kb/893667"&gt;good  article&lt;/a&gt; that describes the differences between user controls and  web controls)&lt;br /&gt;&lt;br /&gt;And the user controls and web controls are plain  old ASP.NET controls.  There is no special Sitecore class to extend or  interface to implement.&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&lt;%@ Control Language="C#" AutoEventWireup="true" CodeBehind="HelloWorldSublayout.ascx.cs" Inherits="mysite.HelloWorldSublayout" %&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;[Hello, world.]&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Example of an ASP.NET user control.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;All  of your development can be done in Visual Studio.  Inside Sitecore, you  simply need to register the control.  After the control is registered  it can be used inside placeholders.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ZN6mb9aov3U&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/ZN6mb9aov3U&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Creating a sublayout using Sitecore.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The video above demonstrates how a sublayout is created inside Sitecore. The user creates a sublayout item, and then Sitecore generates the ascx file.  But there's a little more to it than that.&lt;br /&gt;&lt;br /&gt;When the user creates the sublayout, Sitecore creates a definition item for the sublayout.  A definition item is the object inside Sitecore that maps a logical component to a physical one.  Definition items are used in several places in Sitecore.&lt;br /&gt;&lt;br /&gt;In this case, the logical component is the sublayout and the physical component is the ASP.NET user control (ascx file).  The definition item merely points to a file on IIS.  The location of the file was specified on one of the screens in the "create sublayout" wizard and can be changed at any time using the Content Editor.&lt;br /&gt;&lt;br /&gt;The important thing to note is that the physical file can be edited outside of Sitecore.  After this happens, Sitecore doesn't need to be notified.  All Sitecore cares about is that it is able to locate a file at a certain location when a specific resource is requested.&lt;br /&gt;&lt;br /&gt;Pretty much everything I just wrote about sublayouts is also true of web controls.  In order to create a web control you use a different branch of the content editor (Layout\Renderings instead of Layout\Sublayouts).  The configuration of the definition item for a web control is slightly more manual than that of a sublayout (you need to point Sitecore to a specific .NET class rather than a file).  But I see these as minor differences.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;Presentation controls can be  written using another technology as well: XSLT.  My next post will describe how XSLT can be used to create presentation controls.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20API%20Cookbook.aspx"&gt;Presentation  Component API Cookbook&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-8315287960648848345?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/8315287960648848345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/sublayouts-and-web-controls.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8315287960648848345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8315287960648848345'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/02/sublayouts-and-web-controls.html' title='Sublayouts and Web Controls'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-4178677993051439428</id><published>2010-01-21T09:00:00.014-05:00</published><updated>2010-02-23T10:06:13.485-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Sitecore Presentation Controls</title><content type='html'>In &lt;a href="http://www.sitecore.net/"&gt;Sitecore&lt;/a&gt;, there are various web controls that can be used to &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/displaying-field-values-using-server.html"&gt;display the value of a field&lt;/a&gt;.  This is critical because content it stored in fields.  If you want to display the date assigned to a press release or an image of the cover of a book that you sell on your website, this is what you are interested in.&lt;br /&gt;&lt;br /&gt;However, presentation logic should be thought of as more than a bunch of individual values.  There are relationships between the fields being displayed.  You're not just displaying the title of a book along with its cover.  You are displaying details about a book.  Today it's the title and cover.  Tomorrow it might also include a summary of the book.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S1WteNqq7BI/AAAAAAAADKg/3PPXRn4Ebag/s1600-h/presentation+controls.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S1WteNqq7BI/AAAAAAAADKg/3PPXRn4Ebag/s320/presentation+controls.png" alt="" id="BLOGGER_PHOTO_ID_5428435660441316370" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Before presentation controls and after.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;A block of presentation logic in Sitecore is defined using a component called a "presentation control".  In this post I am going to give a quick overview of presentation controls.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is a presentation control?&lt;/span&gt;&lt;br /&gt;A presentation control allows presentation logic to be defined in a reusable component.  Some examples are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Book detail - displays the title, author, summary and price of a book along with an image of its cover, positioned in a certain way&lt;/li&gt;&lt;li&gt;Breadcrumb trail&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ad block - displays an image and a hyperlink&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Header block - displays an image, search box, an ad block and a home link&lt;/li&gt;&lt;/ul&gt;Sitecore supports 3 kinds of presentation controls: sublayouts, webcontrols and renderings.  Sublayouts and webcontrols are written using .NET.  Renderings are written using XSLT.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What are the benefits to presentation controls?&lt;/span&gt;&lt;br /&gt;One benefit of using presentation controls is that your presentation logic is encapsulated in a reusable component.&lt;br /&gt;&lt;br /&gt;Another benefit is that content editors are able to use the Sitecore page editor to drop presentation controls into their web pages.  This is a very powerful tool that can be offered to content editors, and one that I will cover in a future post.&lt;br /&gt;&lt;br /&gt;This is not so much a benefit of presentation controls so much as a benefit of Sitecore.  There is no new, proprietary technology that you need to learn in order to create presentation controls.  You can use .NET or XSLT.&lt;br /&gt;&lt;br /&gt;I spent many years teaching people how to use a product that depended on an unwieldy, proprietary language for presentation logic.  It's definitely to Sitecore's credit - and the benefit of people learning Sitecore - that they decided against reinventing the wheel.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;My next post will take a look at some of the technical details of presentation controls.  How are they written?  What do they look like?  How are they used?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20API%20Cookbook.aspx"&gt;Presentation  Component API Cookbook&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-4178677993051439428?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/4178677993051439428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/sitecore-presentation-controls.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/4178677993051439428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/4178677993051439428'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/sitecore-presentation-controls.html' title='Sitecore Presentation Controls'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_SD7mxqHQu2M/S1WteNqq7BI/AAAAAAAADKg/3PPXRn4Ebag/s72-c/presentation+controls.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-9117361243465243385</id><published>2010-01-18T09:00:00.017-05:00</published><updated>2010-02-23T10:05:18.155-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Displaying Field Values Using Server Controls</title><content type='html'>This post is part 3 of a not-yet-determined number of posts discussing presentation logic and &lt;a href="http://www.sitecore.net/"&gt;Sitecore&lt;/a&gt;.  My &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/positioning-content-for-display.html"&gt;previous post&lt;/a&gt; explained some of the options available for getting content to appear in a Sitecore website. I ended with a promise to cover some of the Sitecore server controls that are used to display content.&lt;br /&gt;&lt;br /&gt;Sitecore has a number of server controls that are used for different purposes. For this discussion there are 2 kinds of server controls to consider: those that display a single value and those that display other controls.  I will start with the former.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Controls that display content&lt;/span&gt;&lt;br /&gt;One of the most fundamental tasks performed by presentation logic is to display values.  If you are displaying content about a book, you might want to display the book's title and author and an image of its cover.&lt;br /&gt;&lt;br /&gt;In Sitecore, the book would be an item which was created using a data template.  The title, author and image are fields defined in the data template.  A layout is used when the book item needs to be displayed.  Server controls are used in the layout to position and render the field values.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;sc:FieldRenderer ID="FieldRenderer1" runat="server" FieldName="Description" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The specific type of server control is &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Sitecore.Web.UI.WebControls.FieldRenderer&lt;/span&gt;&lt;/span&gt;.  The class name reveals this server control's purpose: it renders the value of a field.  The various web controls that extend &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Sitecore.Web.UI.WebControls.FieldControl&lt;/span&gt;&lt;/span&gt; provide similar functionality.&lt;br /&gt;&lt;br /&gt;What's the difference FieldControl classes and FieldRenderer?  FieldRenderer is generic.  You give it the name of the field and it will render the value.  FieldControl classes target specific field types.  They recognize the unique capabilities of the different field types.  The following examples demonstrate what I mean.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;sc:Image ID="Image1" runat="server" Field="Image" MaxWidth="250" /&amp;gt;&lt;br /&gt;&amp;lt;sc:Date ID="Date1" runat="server" Field="Date" Format="MM/dd/yyyy" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see in the following example, the specific options that are available using FieldControl classes are available using FieldRenderer.  You just don't get Visual Studio showing what they are the way you do with FieldControls.  One thing to note is that FieldControl classes do not exist for every possible field type, so you'll probably be using FieldRenderer at least some of the time.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;sc:Image ID="Image1" runat="server" Field="Image" MaxWidth="250" MaxHeight="100" /&amp;gt;&lt;br /&gt;&amp;lt;sc:FieldRenderer ID="fr1" runat="server" FieldName="Image" Parameters="MaxWidth=250&amp;amp;MaxHeight=100" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;That gets us through the server controls that display field values.  But most of the time individual field values aren't displayed on their own.  Usually a number of fields are displayed together, forming a logical grouping of presentation logic.  In my next post I will describe how blocks of presentation logic can be defined in Sitecore.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20API%20Cookbook.aspx"&gt;Presentation  Component API Cookbook&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-9117361243465243385?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/9117361243465243385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/displaying-field-values-using-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/9117361243465243385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/9117361243465243385'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/displaying-field-values-using-server.html' title='Displaying Field Values Using Server Controls'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-3732861443865945772</id><published>2010-01-14T11:00:00.021-05:00</published><updated>2010-02-23T10:04:43.972-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Positioning Content For Display</title><content type='html'>With this post I want to continue discussing how Sitecore handles presentation logic.  My &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/defining-presentation.html"&gt;last post &lt;/a&gt;described layouts, which are just aspx files that Sitecore uses when someone wants to view content.&lt;br /&gt;&lt;br /&gt;Think of HTML.  Without content, HTML isn't very useful.  Sure, you can have a box with a blue border, but if you don't have any content to put into that box, what's the point?  I think of a Sitecore layout in much the same way.  Layouts don't have content, they just position content.&lt;br /&gt;&lt;br /&gt;So a key question to answer is how do you make content available to a layout?  With HTML you just type text or a URL into a tag.  With Sitecore you have some more sophisticated options available.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Positioning content using code&lt;/span&gt;&lt;br /&gt;Sitecore has an API that provides access to content, so content can be positioned for display using code.  For example, the following code could be added to the Page Load event handler in order to display the value of a field named "Text":&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;Item item = Sitecore.Context.Item;&lt;br /&gt;Response.Write(item.Fields["Text"].Value);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I am far from a Sitecore expert at this point, so I can't say for certain that there's anything wrong with this approach.  After all, it works.  If you're comfortable with writing code, Sitecore allows you to write code.&lt;br /&gt;&lt;br /&gt;However, even as someone new to Sitecore, I can see at least one possible problem with using this approach.  When content editors work in Sitecore, they use a WYSIWYG interface called "Page Editor".  The page editor allows a user to click on a value and start changing it.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/yI254Dg-J6M&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/yI254Dg-J6M&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;The problem is how does Sitecore know how to generate the interface that allows the editor to actually edit?  Unless you tell it, Sitecore doesn't know.  Again, you can write code to tell Sitecore to render the user interface so it enables the value to be edited.&lt;br /&gt;&lt;br /&gt;Maybe that's not a big deal in this example.  In some cases you might not want an editor to ever change a value (site name, for instance).  But some of the time - if not most of the time - you are going to want editors to be able to control the content.  This &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; a content management system :-)&lt;br /&gt;&lt;br /&gt;And this is a trivial example I'm using.  There are only 2 values to edit.  In the real-world it's not unusual to have a dozen or more.  This quickly becomes more work than expected just to set up, let alone maintain.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Positioning content using server controls&lt;/span&gt;&lt;br /&gt;Using the server controls that come with Sitecore is a much easier way to get content into a layout.  The following code is an example of how a Sitecore server control can be used to display the value of a field named "Text":&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;sc:FieldRenderer ID="FieldRenderer1" runat="server" FieldName="Text" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Aside from the generic advantages server controls offer over coding, you also get at least one significant Sitecore-specific advantage: these controls are self-aware.  By this I mean that they understand the environment in which they are being executed.&lt;br /&gt;&lt;br /&gt;For example, if the control is being executed on the published website, a text value may be rendered.  If the control is being executed inside the Page Editor interface, the control is able to determine if the current user has permission to edit the value.  If the user has permission, then extra code will be generated that will allow the user to edit the value.&lt;br /&gt;&lt;br /&gt;The value of this functionality becomes clear when you start thinking about content authoring and usability.  But that's a topic for another post.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;In my next post I plan to get into some of the specific Sitecore server controls that are used to access content.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20API%20Cookbook.aspx"&gt;Presentation  Component API Cookbook&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-3732861443865945772?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/3732861443865945772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/positioning-content-for-display.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/3732861443865945772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/3732861443865945772'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/positioning-content-for-display.html' title='Positioning Content For Display'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-1955558801294916589</id><published>2010-01-12T11:00:00.003-05:00</published><updated>2010-02-23T10:03:04.585-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Defining Presentation</title><content type='html'>Last week I wrote about &lt;a href="http://gettingtoknowsitecore.blogspot.com/"&gt;content modeling&lt;/a&gt; and &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/inheritance-content-modeling-sitecore.html"&gt;inheritance&lt;/a&gt;, two of the first topics you encounter when learning Sitecore.  Content modeling isn't the most exciting topic. You're really just defining data structures used to store content. There are only so many ways to skin that cat, and so many things that a WCM vendor can do to make this a difficult or complicated task.&lt;br /&gt;&lt;br /&gt;Handling presentation is another matter. A vendor can choose to use an existing technology for presentation logic.  Or, if the vendor is especially self-confident, it can create its own technology.  Sitecore uses the former option, with .NET and XSLT being the specific technologies.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is presentation?&lt;/b&gt;&lt;br /&gt;Just to be sure we're on the same page, I want to explain a little about what the term &lt;i&gt;presentation&lt;/i&gt; means when dealing with WCM.  Content modeling covers how content is defined.  In Sitecore, data templates and items are the main tools used to model content.  Content is &lt;span style="font-style: italic;"&gt;what &lt;/span&gt;gets displayed, and it is separate from &lt;span style="font-style: italic;"&gt;how &lt;/span&gt;it gets displayed.&lt;br /&gt;&lt;br /&gt;Presentation is responsible for describing how content should be displayed.  It says, for instance, that the image should go in the upper left-hand corner and the main text should be positioned below it.  Presentation is what makes it possible to view content on a website.  Content without presentation is like having records in a database without a query to retrieve them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How is presentation defined?&lt;/b&gt;&lt;br /&gt;Sitecore uses "layouts" to specify the overall positioning of content and the format of the content being displayed. The purpose of Sitecore items is to store content. The purpose of Sitecore layouts is to provide a visual representation of items. A layout's format is usually HTML, but it can be pretty much anything you want: XML, PDF, etc.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_SD7mxqHQu2M/S0v4aSM1SqI/AAAAAAAADG0/6BM79NpSUw4/s1600-h/layout.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 118px;" src="http://4.bp.blogspot.com/_SD7mxqHQu2M/S0v4aSM1SqI/AAAAAAAADG0/6BM79NpSUw4/s320/layout.jpg" alt="" id="BLOGGER_PHOTO_ID_5425703306543844002" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Uninteresting example of a Sitecore Layout.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Layouts are aspx files. And I don't mean a special kind of aspx file.  There is no special class that has to be used to create a layout.  There is no special interface that must be used to create the aspx file.  No new proprietary language, format, tags or syntax is needed. Sitecore websites can be designed and coded in the same manner as any ASP.NET website.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;So layouts are web pages, right?&lt;br /&gt;&lt;/span&gt;It seems important to remember that a layout is NOT a web page.  Sitecore uses layouts when it needs to display items.  A web page - when delivered by Sitecore - is a combination of a layout with Sitecore content.  Web pages don't exist &lt;span style="font-style: italic;"&gt;inside&lt;/span&gt; Sitecore.  Web pages are &lt;span style="font-style: italic;"&gt;generated by &lt;/span&gt;Sitecore.&lt;br /&gt;&lt;br /&gt;When you think of a web page, you think of something specific: a web page that describes an event or a place.  A Sitecore layout, on the other hand, has nothing specific in it.  It can display information about specific events or places, but it doesn't have any content of its own.  I'm tempted to describe a layout as a &lt;span style="font-style: italic;"&gt;presentation template&lt;/span&gt;, but since the word "template" already has a use in Sitecore, I'm not going to do that ;-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What's next?&lt;/span&gt;&lt;br /&gt;I've given an overview of what layouts are, but I haven't explained what goes into layouts.  In a way, there isn't anything to explain. Layouts are aspx files, so anything that goes into an aspx file can go into a layout.&lt;br /&gt;&lt;br /&gt;But, actually, there is more to explain.  Sitecore provides some server controls that make it easy to access content in a layout.  In my next post I'm going to explain about these server controls and the advantages you'll gain by using them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation  Component Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation  Component Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;&lt;span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry"&gt;&lt;/span&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-1955558801294916589?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/1955558801294916589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/defining-presentation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/1955558801294916589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/1955558801294916589'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/defining-presentation.html' title='Defining Presentation'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_SD7mxqHQu2M/S0v4aSM1SqI/AAAAAAAADG0/6BM79NpSUw4/s72-c/layout.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-1279390836586057487</id><published>2010-01-07T17:00:00.037-05:00</published><updated>2010-02-23T10:00:28.836-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Inheritance, Content Modeling &amp; Sitecore</title><content type='html'>In my &lt;a href="http://gettingtoknowsitecore.blogspot.com/2010/01/content-modeling-with-sitecore.html"&gt;previous post&lt;/a&gt; I discussed the most elementary aspects of content modeling with Sitecore.  When you are learning a WCM system, it's easy to stick with very simple content models.  The risk in this is that content models in the real world are not always simple.&lt;br /&gt;&lt;br /&gt;Until you encounter requirements that include overlap and interdependency it's easy to have an unrealistic opinion of how well your WCM models content.  So far I have been very impressed with Sitecore's approach to modeling content - specifically its support for inheritance.&lt;br /&gt;&lt;br /&gt;In this post I will cover inheritance and why it's such a great thing to have in a WCM.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is inheritance and how does it work?&lt;/b&gt;&lt;br /&gt;A data template is a collection of fields.  Those fields can be defined directly in the data template, or they can be "inherited" from other data templates.  When content is modeled, there is often overlap between very different content.  Inheritance allows the overlapping fields to be moved into separate data templates that can be used by any data template that needs the fields.&lt;br /&gt;&lt;br /&gt;Let's consider some content that might appear on a website: books, press releases and reviews.  The following table lists the fields that are needed for each content type:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="padding: 5px; font-size: 75%; font-weight: bold; text-align: center;"&gt;Data Template Name&lt;br /&gt;&lt;/td&gt; &lt;td style="padding: 5px; font-size: 75%; font-weight: bold; text-align: center;"&gt;Fields&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Book&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;title, description, image, category, author, price&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Press Release&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;title, description, image, category, date&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Review&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;title, description, image, book, reviewer name&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Using inheritance removes duplication by allowing common fields to be moved into more generic base data templates.  The following content model takes advantage of inheritance:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="padding: 5px; font-size: 75%; font-weight: bold; text-align: center;"&gt;Data Template Name&lt;br /&gt;&lt;/td&gt; &lt;td style="padding: 5px; font-size: 75%; font-weight: bold; text-align: center;"&gt;Fields&lt;br /&gt;&lt;/td&gt; &lt;td style="padding: 5px; font-size: 75%; font-weight: bold; text-align: center;"&gt;Inherits&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Content Base&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;title, description, image&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;[none]&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Content Meta Data&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;category&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;[none]&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Book&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;author, price&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Content Base, Content Meta Data&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Press Release&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;date&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Content Base, Content Meta Data&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Review&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;book, reviewer name&lt;br /&gt;&lt;/td&gt; &lt;td style="border: 1px solid rgb(136, 136, 136); padding: 5px; font-size: 75%;"&gt;Content Base&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;This explanation of inheritance may appear to contradict something I wrote about items above.  I wrote that an item is based on 1 and only 1 data template.  That is true of items, but it is not true of data templates.  A data template can be based on as many different data templates as you want.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S0v_V5aZdEI/AAAAAAAADHE/GXg4XuD-hIs/s1600-h/inheritance.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 151px;" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S0v_V5aZdEI/AAAAAAAADHE/GXg4XuD-hIs/s320/inheritance.jpg" alt="" id="BLOGGER_PHOTO_ID_5425710927751771202" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;The Book data template's path of inheritance as seen in Sitecore.  This example shows the Book data template inherits from the "Content Base" template, which inherits from the "Standard template" template, etc.  The "Content Meta Data" data template is also included, but is not shown in this screenshot due to space constraints. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Then what does it mean if an item is based on a data template that is based on multiple data templates?  A book item is an example of this.  The book item is based on the Book data template, but the Book data template is based on both Content Base and Content Meta Data.  This means that the book item is able to store content defined in 3 data templates: Content Base, Content Meta Data, and Book.&lt;br /&gt;&lt;br /&gt;You might be tempted to think that a book item is based on 3 data templates, but I don't think that's technically accurate.  When you create the book item you can only select 1 data template.  The fact that you &lt;i&gt;inherit from&lt;/i&gt; 2 other data templates is important, but it shouldn't be confused with the fact that the book item is &lt;i&gt;based on&lt;/i&gt; only 1 data template.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Why should you care about inheritance?&lt;/b&gt;&lt;br /&gt;There are many reasons to appreciate inheritance.  Being able to reuse content definitions makes it easier to make changes later.  Consistency is improved because common fields are defined once and used when needed.&lt;br /&gt;&lt;br /&gt;But I think the best benefit of inheritance is ease of use for non-technical users.  Remember, all of this inheritance is handled by the developer.  The content authors never see any of it directly, but they reap the benefits. From the author's perspective, all of the fields are just there.  There is no linking or connecting to a separate object in order to enter the values.  This means the author can work on the content in one piece, as it exists in the real world.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is life like without inheritance?&lt;/b&gt;&lt;br /&gt;This may seem like an obvious way to do things, but not all WCM systems are designed this way.  Consider RedDot CMS (now called Open Text Web Solutions Management Server) as an example.  In RedDot, it is possible to move common fields into a shared component.  This component is and always will be separate from the component that uses it.&lt;br /&gt;&lt;br /&gt;While setting these separate components up is not any more difficult than with Sitecore, the effects are far reaching and significant.  Instead of having to create one piece of content, RedDot requires multiple pieces of content be created and connected to one another.  Each piece of content is independent each other, meaning that they have their own security, workflow and publishing settings.  Content authors have a hard time understanding which pieces go together and which don't.  When blocks of content are missing from the website, they don't understand how that can be.&lt;br /&gt;&lt;br /&gt;So what ends up happening is the fields that should be separated out are duplicated wherever they are needed.  This makes life easier for content authors, but can result in a lot of duplication of work and added complication for developers.  On a large project, it is easy to forget all of the places where changes need to be made.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What's next?&lt;/b&gt;&lt;br /&gt;Data templates and inheritance seem to be 2 of the most important concepts to understand when first working with Sitecore.  Modeling content is at the core of a WCM system, and data templates and inheritance are at the core of modeling content with Sitecore.&lt;br /&gt;&lt;br /&gt;Being able to define content is crucial, but if you don't have any way to display content, you might as well not have any content at all.  My next post will cover my first impressions of the approach Sitecore uses to handle presentation logic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;Data Definition Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Cookbook.aspx"&gt;Data Definition Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-1279390836586057487?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/1279390836586057487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/inheritance-content-modeling-sitecore.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/1279390836586057487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/1279390836586057487'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/inheritance-content-modeling-sitecore.html' title='Inheritance, Content Modeling &amp; Sitecore'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_SD7mxqHQu2M/S0v_V5aZdEI/AAAAAAAADHE/GXg4XuD-hIs/s72-c/inheritance.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-677572920894334917</id><published>2010-01-06T19:00:00.014-05:00</published><updated>2010-02-23T09:58:49.996-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fundamentals'/><title type='text'>Content Modeling With Sitecore</title><content type='html'>One of the first technical topics you encounter when learning &lt;a href="http://www.sitecore.net/"&gt;Sitecore&lt;/a&gt; is how the system separates content from presentation.  In some ways this is a massive and complicated topic.  There are so many options and approaches that can be used.&lt;br /&gt;&lt;br /&gt;At the same time, its essence seems to be pretty simple.  Not simple in that it should be easy for anyone to understand or that it can be learned quickly.  I mean simple in the sense that there isn't much to it.  Yes, Sitecore provides a large number of tools for a developer to use to model content and design presentation, but there's a distinct logic and consistency to it.  Once you're able to get your head wrapped around that, the system isn't as overwhelming.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SD7mxqHQu2M/S0VXJvNI8oI/AAAAAAAADF0/30kds91i9yI/s1600-h/nyc+telephone+wires.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" id="BLOGGER_PHOTO_ID_5423837151039648386" src="http://2.bp.blogspot.com/_SD7mxqHQu2M/S0VXJvNI8oI/AAAAAAAADF0/30kds91i9yI/s320/nyc+telephone+wires.jpg" style="margin: 0px auto 10px; cursor: pointer; display: block; height: 198px; text-align: center; width: 320px;" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;New York's original telephone system provides a good metaphor.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If one of the first things you learn is how Sitecore separates content from presentation, probably the very first thing you learn is how Sitecore models content.  How does a developer configure Sitecore so content authors are able to create content on the site?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How is content described?&lt;/b&gt;&lt;br /&gt;Data Templates are used to model content.  A data template is a collection of "fields", with each field representing a specific piece of content.  Data templates are used to create "items".  An item provides the ability to save specific values for the fields.  Each item is based on 1 and only 1 data template.  To use an object-oriented programming analogy, data templates are classes and items are instances of those classes.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SD7mxqHQu2M/S0v64hmbrSI/AAAAAAAADG8/LaAuwGRlnZU/s1600-h/data+template.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 111px;" src="http://3.bp.blogspot.com/_SD7mxqHQu2M/S0v64hmbrSI/AAAAAAAADG8/LaAuwGRlnZU/s320/data+template.jpg" alt="" id="BLOGGER_PHOTO_ID_5425706025097080098" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Fields from a data template at they appear in Sitecore.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;For example, you might create a data template for a book.  A book has fields to store a title, author, description, image and price.  Each book item has its own title, author, description, image and price.  Examples of book items are "&lt;a href="http://en.wikipedia.org/wiki/Crime_and_Punishment"&gt;Crime and Punishment&lt;/a&gt;", "&lt;a href="http://en.wikipedia.org/wiki/Absurdistan_%28novel%29"&gt;Absurdistan&lt;/a&gt;" and "&lt;a href="http://en.wikipedia.org/wiki/Sum_%28novel%29"&gt;Sum&lt;/a&gt;" (which are 3 of the best books I read last year).&lt;br /&gt;&lt;br /&gt;This is a simple example.  In the real world, content is often much more complicated.  What if you need to model all sorts of books, with each type of book having different content requirements.  For example, the content for a novel might be very different from that of a journal or a reference volume or a technical manual.&lt;br /&gt;&lt;br /&gt;The way a WCM system provides handles content like this (meaning there are similarities along with differences) impacts so many different aspects of the system that it's hard to overstate its significance.  When a WCM doesn't do a good job, usability suffers, it becomes more difficult to introduce changes, duplication starts to appear, among other things.  And all of these things increase the cost of building and maintaining your website.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What's next?&lt;/b&gt;&lt;br /&gt;In my next post I will explore the concept of inheritance as it pertains to modeling content with Sitecore.  I am impressed with how Sitecore allows developers to use inheritance to create a content model that is easy to develop, maintain and use.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Want to learn more?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Reference.aspx"&gt;Data Definition Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Data%20Definition%20Cookbook.aspx"&gt;Data Definition Cookbook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sitecore.net/training.aspx"&gt;Sitecore training&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-677572920894334917?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/677572920894334917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/content-modeling-with-sitecore.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/677572920894334917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/677572920894334917'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/content-modeling-with-sitecore.html' title='Content Modeling With Sitecore'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_SD7mxqHQu2M/S0VXJvNI8oI/AAAAAAAADF0/30kds91i9yI/s72-c/nyc+telephone+wires.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6958775774153114698.post-8294688244064518205</id><published>2010-01-04T18:00:00.003-05:00</published><updated>2010-01-06T22:54:43.368-05:00</updated><title type='text'>Getting To Know "Getting to Know"</title><content type='html'>Hi there, and welcome to my blog.  If I'm not mistaken, this blog has earned the distinction of being the first new Sitecore blog of 2010.  Dubious, perhaps, but a distinction nonetheless.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SD7mxqHQu2M/S0VSoMTD7zI/AAAAAAAADFs/h1ZIMVj82VY/s1600-h/newborn.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 255px; height: 320px;" src="http://3.bp.blogspot.com/_SD7mxqHQu2M/S0VSoMTD7zI/AAAAAAAADFs/h1ZIMVj82VY/s320/newborn.jpg" alt="" id="BLOGGER_PHOTO_ID_5423832176687050546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Who am I?&lt;/span&gt;&lt;br /&gt;In late 2009 I joined &lt;a href="http://www.sitecore.net/"&gt;Sitecore&lt;/a&gt; as a Technical Architect.  I'm a member of the Product Marketing team.  As I've been telling my friends, the only bad part of the job is that it's not very easy to explain what I do.  My responsibilities include making sure that people inside the company have the technical product knowledge they need in order to get their jobs done, and to help partners develop quality integration between Sitecore and external systems.&lt;br /&gt;&lt;br /&gt;Prior to working at Sitecore, I worked at &lt;span style="text-decoration: line-through;"&gt;RedDot&lt;/span&gt; &lt;span style="text-decoration: line-through;"&gt;Hummingbird&lt;/span&gt; Open Text.  My role there ranged from training to helping partners implement &lt;span style="text-decoration: line-through;"&gt;RedDot&lt;/span&gt; Open Text Web Solutions products. And before that I worked as a trainer, developer and consultant for content management and custom application development.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What is the purpose of this blog?&lt;/span&gt;&lt;br /&gt;Eventually this blog will likely focus on integration topics, since working on integrations is one of my main responsibilities at Sitecore. I was inspired by the spirit of openness and sharing that I see at Sitecore, and I was eager to start sharing my experience and knowledge as soon as possible. But since the part of my job that deals with integrations won't be starting up for a little while, I had to think of something else.&lt;br /&gt;&lt;br /&gt;Since I am not only new to the company but new to the product, I decided to blog about my experience learning Sitecore.  I hope these posts will help people who are looking at or are new to the product see what it's like to enter the Sitecore world.&lt;br /&gt;&lt;br /&gt;While I am new to Sitecore, I am not new to web content management.  I may be learning features for the first time, but not the underlying concepts.  I haven't been working with Sitecore long, but I already see that a number of the most intractable and pervasive problems people have with other WCM systems can be solved elegantly - or avoided altogether - using Sitecore.  In addition to explaining features, I also hope to be able to explain why Sitecore's approach matters.&lt;br /&gt;&lt;br /&gt;So thanks for reading.  I hope you'll return!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6958775774153114698-8294688244064518205?l=gettingtoknowsitecore.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gettingtoknowsitecore.blogspot.com/feeds/8294688244064518205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/getting-to-know-getting-to-know.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8294688244064518205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6958775774153114698/posts/default/8294688244064518205'/><link rel='alternate' type='text/html' href='http://gettingtoknowsitecore.blogspot.com/2010/01/getting-to-know-getting-to-know.html' title='Getting To Know &quot;Getting to Know&quot;'/><author><name>Adam Conn</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-3iY95WM4JXA/AAAAAAAAAAI/AAAAAAAAAAA/GjgyidOmTks/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_SD7mxqHQu2M/S0VSoMTD7zI/AAAAAAAADFs/h1ZIMVj82VY/s72-c/newborn.jpg' height='72' width='72'/><thr:total>2</thr:total></entry></feed>
