<?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-8360277440872630202</id><updated>2012-02-02T14:01:38.270-05:00</updated><category term='Engagement Plan'/><category term='Nicam'/><category term='xml'/><category term='mike casey'/><category term='OMS'/><category term='integration'/><category term='content management'/><category term='Conditions'/><category term='cms'/><category term='appearance'/><category term='device'/><category term='Web Forms for Marketers'/><category term='Actions'/><category term='Sitecore 6.1'/><category term='Edit Frames'/><category term='Sitecore API'/><category term='rich text editor'/><category term='Rules'/><category term='sitecore'/><category term='Sitecore OMS'/><category term='Customer Engagement Platform'/><category term='content editor'/><category term='presentation'/><title type='text'>Content Management, Business Champions and Developers</title><subtitle type='html'>As you consider, start or continue your journey with Sitecore CMS, I would like to be there to catalog ideas, questions and conversations that I hear every day as I work with Sitecore partners, clients, prospects and developers.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mikecaseycms.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-5688226599740488329</id><published>2012-02-02T14:01:00.001-05:00</published><updated>2012-02-02T14:01:38.341-05:00</updated><title type='text'>The Customer Engagement Series: A quick time check</title><content type='html'>&lt;p&gt;In the spirit of quick rules examples, I recently had a question about simply doing something on the site based on what time it is.&amp;#160; Easy with Sitecore’s Rules Engine, but let’s mock something up to go through putting the pieces together.&lt;/p&gt;  &lt;p&gt;First, the item to represent the Rule Condition.&amp;#160; I created an item in this location:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;/sitecore/system/Settings/Rules/Conditional Renderings/Conditions/Events/Time Is Before Condition&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;….where the item itself is named “Time is Before Condition”.&amp;#160; Sitecore 6.5 has lots of categorization folders in this area (or you could create your own).&amp;#160; I decided Events was a good enough categorization for this condition.&amp;#160; This item is based on the data template:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;/sitecore/templates/System/Rules/Condition&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Here’s how the item looks:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-YPrAko5NzUY/TyrdhretuAI/AAAAAAAABRo/x9p736FH8BM/s1600-h/image3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-PTBrjoaa5yU/TyrdiIGwimI/AAAAAAAABRw/zdso1I03ZXk/image_thumb1.png?imgmax=800" width="600" height="232" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now someone who’s not a developer should be able to simply add a time to this condition.&amp;#160; Using the very handy Rule Set Editor in 6.5, we could easily string together a bunch of time conditions from top to bottom (“if it’s before 12:30 PM do this, if not but it’s still before 1:30 PM do this, etc.”)&lt;/p&gt;  &lt;p&gt;From the &lt;a href="http://sdn.sitecore.net/upload/sitecore6/rules_engine_cookbook_sc61_usletter.pdf"&gt;Rules Engine Cookbook&lt;/a&gt;, in describing the four parameters in the bracketed expression within the&amp;#160; Text field above:&lt;/p&gt;  &lt;p&gt;1. The name of the property that the parameter sets in the .NET class that implements the condition.   &lt;br /&gt;2. The name of an item beneath the /Sitecore/System/Settings/Rules/Common/Macros item providing predefined functionality, or an empty string. For example, to activate a user interface allowing the user to select an item from the content tree, specify the value tree.    &lt;br /&gt;3. URL parameters to the user interface activated by the macro specified by the previous parameter, or an empty string. For example, to specify the /Sitecore/Content/Home item as the root for a selection tree, enter root=/sitecore/content/home.    &lt;br /&gt;4. Text to display if the user has not specified a value for the parameter.&lt;/p&gt;  &lt;p&gt;With that, the condition will now display in the Rule Set Editor like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-RE1fuaPRkDo/TyrdjwTAYqI/AAAAAAAABR4/NIOwXFst6rE/s1600-h/image%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-SkJFGA5-cAs/TyrdkJ7XMcI/AAAAAAAABSA/I3832f6fpms/image_thumb%25255B1%25255D.png?imgmax=800" width="593" height="235" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;And the simple class that is called on when this rule is evaluated:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Sitecore.Rules;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Sitecore.Diagnostics;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Sitecore.Data;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Sitecore.Data.Items;&lt;br /&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Sitecore.Rules.Conditions;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Examples&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TimeIsBeforeCondition&amp;lt;T&amp;gt; : WhenCondition&amp;lt;T&amp;gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; T : RuleContext&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; TimeIsBeforeCondition()&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Execute(T ruleContext)&lt;br /&gt;        {&lt;br /&gt;            Assert.ArgumentNotNull(ruleContext, &lt;span class="str"&gt;&amp;quot;ruleContext&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            &lt;span class="rem"&gt;//if t1 is less than t2 then result is Less than zero&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;//if t1 equals t2 then result is Zero&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;//if t1 is greater than t2 then result isGreater zero &lt;/span&gt;&lt;br /&gt;            System.DateTime t1 = System.DateTime.Now;&lt;br /&gt;            System.DateTime t2 = System.Convert.ToDateTime(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Value);&lt;br /&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; i = System.DateTime.Compare(t1,t2);&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; i &amp;lt; 0;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Value { get; set; }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Note that the Value property is set by the value entered into the textbox above.&amp;#160; This certainly could be improved (beyond checking for errors) by enforcing a content item representing each hour to be chosen from a Tree View (though this of course doesn’t make sense when you want to provide minute by minute choices.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-5688226599740488329?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5688226599740488329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5688226599740488329'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2012/02/customer-engagement-series-quick-time.html' title='The Customer Engagement Series: A quick time check'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-PTBrjoaa5yU/TyrdiIGwimI/AAAAAAAABRw/zdso1I03ZXk/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-379104370815649403</id><published>2012-02-01T15:31:00.001-05:00</published><updated>2012-02-02T08:30:47.752-05:00</updated><title type='text'>The Customer Engagement Series: A quick connect to Facebook</title><content type='html'>&lt;p&gt;I am really excited about the huge growth in socially-connected Sitecore sites we’re going to see this year.&amp;#160; With the Sitecore Rules Engine, it just makes a lot of sense—make recommendations based on your visitor’s Likes, birthday, location…just about anything.&amp;#160; I like demonstrating the many ways Sitecore has made the mechanics of this--grabbing some profile information from Facebook and changing the page experience because of it--natural and simple.&amp;#160; The story gets even better when we consider how easy it is to introduce our own custom logic altogether—but for today, let’s stick to a use case and solution that doesn’t involve any coding.&lt;/p&gt;  &lt;p&gt;First, Sitecore has introduced a free module called &lt;a href="http://sdn.sitecore.net/Resources/Free%20Modules/Social%20Module.aspx"&gt;Sitecore Social Connected&lt;/a&gt;.&amp;#160; In about 20 minutes with the documentation, you can have this module installed and working.&amp;#160; Most of the time involves getting familiar with setting up a Facebook App if you’re not already.&amp;#160; Nothing that requires a developer here.&lt;/p&gt;  &lt;p&gt;The Social Connected feature contains lots of cool features—prebuilt Like and Tweet controls that you can use as is, login controls and functionality for Facebook, Twitter, LinkedIn and Google+.&lt;/p&gt;  &lt;p&gt;What I’d like to concentrate on in this quick article is the ability to allow your visitor to login using his Facebook credentials to customize his experience.&amp;#160; Remember that the Sitecore Rules Engine is a simple way to tie a &lt;strong&gt;Condition&lt;/strong&gt; (does it exist, yes/no) to an &lt;strong&gt;Action &lt;/strong&gt;(what should my control do differently as a result of the condition evaluation….show some different HTML, invoke a different control, message an external system).&lt;/p&gt;  &lt;p&gt;In Sitecore 6.5, there’s even a prebuilt condition that can allow a content editor / marketer to look for a specific profile value.&amp;#160; My use of the word profile here means a persistent attribute for a logged in user (the Sitecore .NET Profile table, a CRM via a connection, some external system—in this case Facebook).&lt;/p&gt;  &lt;p&gt;Here’s my Condition that looks in the “Movies” area of the logged in Facebook user profile for the word “Drive”:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-cyE_FUWwAGU/Tymg_iu2lRI/AAAAAAAABQ4/_dAL5VMis5I/s1600-h/SNAGHTML5807847%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="SNAGHTML5807847" border="0" alt="SNAGHTML5807847" src="http://lh6.ggpht.com/-Gr1208NU9qE/TymhABxUIZI/AAAAAAAABRA/OUasBapftk4/SNAGHTML5807847_thumb%25255B2%25255D.png?imgmax=800" width="466" height="590" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The Social Connected module comes preconfigured with mappings to lots of Facebook profile fields…through configuration you can extend these properties.&lt;/p&gt;  &lt;p&gt;Here’s the full fb_movies profile field for someone who has included the movie Drive in his list of Movies He Likes:&lt;/p&gt;  &lt;h5&gt;fb_movies&lt;/h5&gt; = data =&amp;gt; name =&amp;gt; Drive category =&amp;gt; Movie id =&amp;gt; 105687816178274 created_time =&amp;gt; 2012-02-01T13:55:03+0000 name =&amp;gt; The Town category =&amp;gt; Movie id =&amp;gt; 92320479952 created_time =&amp;gt; 2012-01-04T16:34:30+0000 paging =&amp;gt; next =&amp;gt; https://graph.facebook.com/me/movies?   &lt;p&gt;As you can see, we could have gotten a lot more fancy with our parsing of this or any other Facebook profile field, but the simple “Contains” operator from Sitecore does the trick here.&lt;/p&gt;  &lt;p&gt;Now, as a simple control (like the Sidebar control in the Sitecore Starter Kit site) can show a different content item / HTML block as a result of this conditional.&amp;#160; &lt;/p&gt;  &lt;p&gt;If Drive isn’t found in his movie Likes, use the default message and opportunity to ask him to sign up:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-prLeGT_doQ8/TymhAjdtzZI/AAAAAAAABRI/FeCFyJP4-NM/s1600-h/image%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-VeICHTMm9ak/TymhBNhZ9SI/AAAAAAAABRQ/IAiHFMUi6Bk/image_thumb%25255B1%25255D.png?imgmax=800" width="401" height="398" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;If he’s already logged in and Likes Drive, ask him to watch it again:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-NveKmCWPEU4/TymhBe9OzrI/AAAAAAAABRY/Rn4iOQOQsHc/s1600-h/image%25255B8%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-YjUhJ0kIBMU/TymhB-05F5I/AAAAAAAABRg/bXLyw-hmUhY/image_thumb%25255B4%25255D.png?imgmax=800" width="409" height="343" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;That’s all there is to it!&amp;#160; A simple Hack to write out all Facebook profile properties is helpful as you start to investigate what’s there for you to use:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;Sitecore.Security.Accounts.User user = Sitecore.Context.User; &lt;br /&gt;           Sitecore.Security.UserProfile profile = user.Profile; &lt;br /&gt;           litOutput.Text = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;           &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; attributeKey &lt;span class="kwrd"&gt;in&lt;/span&gt; profile.GetCustomPropertyNames()) &lt;br /&gt;           { &lt;br /&gt;               &lt;span class="kwrd"&gt;string&lt;/span&gt; attributeValue = profile.GetCustomProperty(attributeKey); &lt;br /&gt;               litOutput.Text += &lt;span class="str"&gt;&amp;quot;&amp;lt;h3&amp;gt;&amp;quot;&lt;/span&gt; + attributeKey + &lt;span class="str"&gt;&amp;quot;&amp;lt;/h3&amp;gt; =&amp;quot;&lt;/span&gt; + attributeValue + &lt;span class="str"&gt;&amp;quot;&amp;lt;br /&amp;gt;&amp;quot;&lt;/span&gt;; &lt;br /&gt;               &lt;br /&gt;           } &lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-379104370815649403?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/379104370815649403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/379104370815649403'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2012/02/customer-engagement-series-quick.html' title='The Customer Engagement Series: A quick connect to Facebook'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-Gr1208NU9qE/TymhABxUIZI/AAAAAAAABRA/OUasBapftk4/s72-c/SNAGHTML5807847_thumb%25255B2%25255D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-4029834347807799665</id><published>2012-01-31T16:08:00.001-05:00</published><updated>2012-01-31T16:08:26.418-05:00</updated><title type='text'>The Customer Engagement Series:  Investigating Engagement Plans</title><content type='html'>&lt;p&gt;One of the many interesting features in Sitecore’s Customer Engagement Platform is the ability to design and monitor “Engagement Plans”.&amp;#160; These Engagement Plans allow you to envision and lay out the path you are hoping your customers take—from entry point to ultimate goal.&amp;#160; I’ve had enough discussions about this feature in Sitecore 6.5 to know (at least) two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It’s really cool&lt;/li&gt;    &lt;li&gt;It’s pretty hard to describe and absorb in the short window of time people generally have to evaluate it&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;It’s not that the concept is above us, it’s just that the nature of an Engagement Plan is such that by definition it describes a process over time—a set of states, triggers and decision points that can confuse our already busy minds.&amp;#160; Sitecore 6.5 does a nice job at setting some of these up for us…one that I find particularly compelling is the Engagement Plan that is set up by default when using the Email Campaign Manager.&amp;#160; Below is a screenshot of this plan that is put in place automatically for all my Email Campaigns.&amp;#160; Don’t worry, we’re going to concentrate on a much simpler one today, but we can all agree that the States (the rectangles below) are all very understandable buckets we’d expect our audience to be in if they were part of your Email Campaign.&amp;#160; I’ll let you draw arrows and match the states:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You might have learned (via the Message Transfer Agent) that the email address you had was bad.&lt;/li&gt;    &lt;li&gt;Your recipient might have received the message but it’s sitting there in his inbox unopened.&lt;/li&gt;    &lt;li&gt;He might have opened the message but not yet visited your site.&lt;/li&gt;    &lt;li&gt;He might have followed the link in the email but became distracted as soon as he hit your landing page&lt;/li&gt;    &lt;li&gt;He might have spent time on your site after hitting the landing page, done something &lt;strong&gt;OF VALUE&lt;/strong&gt; on our site (your definition of &lt;strong&gt;value&lt;/strong&gt; of course)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-g3-Ru4u2EzM/TyhYNKh85WI/AAAAAAAABPI/uB5fjZ8ngw8/s1600-h/image%25255B3%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-Myk5yzWhuEI/TyhYNVeJBUI/AAAAAAAABPQ/mhTbes3THtM/image_thumb%25255B1%25255D.png?imgmax=800" width="597" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;OK, what we want to do today is create one of these from scratch.&amp;#160; A really simple one that will help us investigate the main concepts.&amp;#160; I encourage you to take a look at the &lt;a href="http://sdn.sitecore.net/upload/sitecore6/65/engagement_automation_cookbook_sc65-usletter.pdf" target="_blank"&gt;Engagement Automation Cookbook&lt;/a&gt; for a more thorough description of these mechanics.&lt;/p&gt;  &lt;p&gt;For this one, here’s the scenario:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Your visitor got to your site as part of a well-placed link on your company’s Facebook page.&lt;/li&gt;    &lt;li&gt;The link was trying to get that visitor to hit the landing page and fill out a registration form (the definition of &lt;strong&gt;valuable&lt;/strong&gt; in this scenario).&lt;/li&gt;    &lt;li&gt;If the visitor followed the link and got to the landing page but didn’t fill in the registration form, you want to give him five days of peace before you send him an email (OK, we might not do this in the real world, but it helps with the concept) telling him he better hurry up and fill in the form.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Here’s the overall model for our simple example:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/--aORFgQrDVI/TyhYOFpTOGI/AAAAAAAABPY/RaB8r2cTI_0/s1600-h/image%25255B8%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-1ttMvStkg8M/TyhYOT_08tI/AAAAAAAABPg/idrmVBNW86c/image_thumb%25255B4%25255D.png?imgmax=800" width="617" height="543" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;The top rectangle describes our initial state.&amp;#160; All visitors that have reached our site as a result of clicking on the Facebook wall link are part of this state.&amp;#160; As an aside, here’s the field (“Enroll in Engagement Plan”) in our overall Facebook Wall campaign where we can automatically place the visitor into this state:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-XzE4thKBfYw/TyhYO9IwyXI/AAAAAAAABPo/jZgmPDeIyoU/s1600-h/image%25255B13%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-hUZRgmzjcXI/TyhYPfNcJTI/AAAAAAAABPw/f1g3qCyNkis/image_thumb%25255B7%25255D.png?imgmax=800" width="621" height="448" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The state itself is pretty straightforward.&amp;#160; Think of these states as the “buckets” any of our audience members might be in at any time during this overall Engagement Plan.&amp;#160; Many things can move people from state to state—from their own actions (like opening an email or registering using a Web Forms for Marketers form) to our actions as site owners (manually moving members to a different state) to automated triggers (move them to a different state if they’ve been in this state for 5 days).&lt;/p&gt;  &lt;p&gt;When we take a closer look and edit the Conditions (the diamonds), we see a bit more detail:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-CZ-bJv9ab2s/TyhYPgXlIlI/AAAAAAAABP4/qUkVlT5PKV4/s1600-h/image%25255B18%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-BSngYj7Ck9Y/TyhYQBmAg4I/AAAAAAAABQA/NR6F18hj5vM/image_thumb%25255B10%25255D.png?imgmax=800" width="627" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here we are able to create a branching decision point—a Yes/No decision point where a particular condition will be evaluated.&amp;#160; In our example, it’s simply a check as to whether the current visitor in this Engagement Plan has filled in our contest registration form.&amp;#160; In our example, we simply apply the “Register” goal to the act of filling in the form.&amp;#160; Web Forms for Marketers makes this incredibly easy, as the out of the box submit actions include the ability to tie to this very goal.&amp;#160; For those of you new to CEP/DMS, a goal can be anything you deem an important event on your site, from filling in this form to downloading your newest whitepaper to following a particular trail through your pages.&amp;#160; The rules engine is fully at our disposal here as you can see from the capability to “Edit Rule” above.&lt;/p&gt;  &lt;p&gt;In our scenario, a YES answer to this condition means that we’ve achieved our modest objective….the campaign was a success and we have a &lt;strong&gt;VALUABLE&lt;/strong&gt; visitor.&amp;#160; Let’s put that visitor into the Valuable state bucket.&amp;#160; As we do that, we have an opportunity to perform any number of additional Actions—change a profile attribute in the CRM, send a thank you email, move them to another Engagement Plan:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-MstG_zI-1rw/TyhYQYTwhRI/AAAAAAAABQI/Y7Iq2sk1EiY/s1600-h/image%25255B22%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-_zqH0nh4-BA/TyhYQ48_mEI/AAAAAAAABQQ/TNwGjxlIJTg/image_thumb%25255B12%25255D.png?imgmax=800" width="604" height="262" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;OK, we’re done with our Valuable visitors.&amp;#160; Now to those procrastinators who have refused to fill in our registration form (even though they saw that juicy offer to on our landing page).&amp;#160; Our scenario states that we will wait 5 days and then really hound them with an email.&lt;/p&gt;  &lt;p&gt;Editing our condition gives us the ability to easily model this rule:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-dY0hOcZKWks/TyhYRFTbw7I/AAAAAAAABQY/tpafUFFmYFk/s1600-h/image%25255B27%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-bPiulmBi9fY/TyhYRnJz4kI/AAAAAAAABQg/wUm3maAwYkg/image_thumb%25255B15%25255D.png?imgmax=800" width="619" height="486" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Now, if 5 days has passed, we can send that reminder email to this group:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-M5ToDmdqLg4/TyhYSOu3n8I/AAAAAAAABQo/rQQSI8YnsNI/s1600-h/image%25255B31%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-Wgo-lbA9tZg/TyhYSa0NWuI/AAAAAAAABQw/38gnz3MM-Ak/image_thumb%25255B17%25255D.png?imgmax=800" width="613" height="265" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hopefully this article highlighted the basic concepts of the Sitecore Engagement Plans.&amp;#160; I will use this simple scenario and expand on it in the coming weeks to dive deeper into Sitecore’s Customer Engagement Platform.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-4029834347807799665?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4029834347807799665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4029834347807799665'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2012/01/customer-engagement-series.html' title='The Customer Engagement Series:  Investigating Engagement Plans'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-Myk5yzWhuEI/TyhYNVeJBUI/AAAAAAAABPQ/mhTbes3THtM/s72-c/image_thumb%25255B1%25255D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-2423544385976408327</id><published>2011-09-14T10:57:00.000-04:00</published><updated>2011-09-16T07:35:39.680-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Conditions'/><category scheme='http://www.blogger.com/atom/ns#' term='Customer Engagement Platform'/><category scheme='http://www.blogger.com/atom/ns#' term='Engagement Plan'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><category scheme='http://www.blogger.com/atom/ns#' term='mike casey'/><title type='text'>Sitecore Customer Engagement Platform: Segmenting the Audience</title><content type='html'>I'm amazed at the richness of the conditions that exist in Sitecore's Customer Engagement platform that can be used to strategize audience segmentation.&amp;nbsp; This new release takes huge leaps towards the very exciting goal of synthesizing customer activity--online, offline, implicit behavior, explicit profile attributes (either in Sitecore or external to it), channel activity based on email campaigns, mobile experiences, subscriptions, external social sites and much more.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;I've had lots of conversations recently that boil down to "where do I begin?"&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Mark Twain reminds us:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;"Never put off till tomorrow, what you can do the day after tomorrow." &lt;/em&gt;&lt;/blockquote&gt;Remember, this is a marathon, not a sprint.&amp;nbsp; The great thing is, you've chosen (or are now choosing) a Customer Engagement Platform that is built on the groundwork of THE world-class Sitecore Web Content Management System.&amp;nbsp; This is not a new building.&amp;nbsp; This is not new set of really high floors set&amp;nbsp;to topple.&amp;nbsp; This is an expansion of an amazing platform that is the right combination of high and wide, with incredibly sturdy sections all over the place that are ready for your designer touches, when you're ready.&amp;nbsp; (Walk around for a while).&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;But let's use another Twain quote as an addendum today:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;"All good things arrive unto them that wait - and don't die in the meantime"&lt;/em&gt;&lt;/blockquote&gt;After all, we are trying to have the best digital marketing strategy on the planet.&amp;nbsp; Put one foot in front of the other, eat the elephant one bite at at time, and now my trite quoting is officially done.&amp;nbsp; Let's look at a really simple starting plan:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-zo9h1Rf126k/TnCsCq79kkI/AAAAAAAABOE/zOHb1hDsSSE/s1600/Possible+Visitor+States.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="267" rba="true" src="http://3.bp.blogspot.com/-zo9h1Rf126k/TnCsCq79kkI/AAAAAAAABOE/zOHb1hDsSSE/s400/Possible+Visitor+States.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;In this scenario, we decide that our visitors (or potentially even more compelling--our members or customers), are in one of four states.&amp;nbsp; These states could also be envisioned as a sales funnel, with the first state I'll describe being the entry point to the funnel:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Just Browsing&lt;/strong&gt;.&amp;nbsp; Think of this as a default state where you don't want to make any assumptions yet.&amp;nbsp; You have content for this--compelling content pages that keep this visitor engaged and circling down the funnel.&amp;nbsp; In terms of Sitecore's Customer Engagement Platform, maybe this visitor hasn't yet hit your predefined and prestrategized thresholds of goal achievement or profile values.&amp;nbsp; You're just not ready to guide this visitor in any particular direction until she "tells" you a bit more about herself.&amp;nbsp; She also hasn't logged in (although this doesn't necessarily mean that she hasn't been to your site before).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Interested in featured product line.&amp;nbsp;&lt;/strong&gt;&amp;nbsp; It's the end of the quarter and you have three million of these widgets to sell.&amp;nbsp; The company is buzzing with ideas about how to promote and unload this last batch--from email newsletters going out to new subscribers, customer service agents noting the promotion to all call in customers, an add running directly on your home page and various landing pages pushing the widget.&amp;nbsp; While this impression is going to be everywhere--both online and off--you obviously don't want to assume someone is interested in the widget because they've heard about it.&amp;nbsp; Your criteria is more specific--it's the conversion, the achievement of a predefined goal you've identified as a confident assumption of customer engagement.&amp;nbsp; As we'll see, this doesn't have to be one thing.&amp;nbsp; Maybe he specifically searched Google for the exact part number of the&amp;nbsp;widget.&amp;nbsp; Maybe he opens the email, goes to the landing page, and fills out a form asking for pricing.&amp;nbsp; Maybe he's downloaded both the widget installation manual AND watched the Getting Started Video.&amp;nbsp; Maybe he's talked to a customer service agent and told him that he's "very interested" in purchasing by the end of the quarter.&amp;nbsp; However he got to to this state, now you're ready.&amp;nbsp; You're ready to change his experience as he gets to the next landing page two days before the quarter ends.&amp;nbsp; He now gets the very aggressive coupon clearly presented on his arrival.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ready to buy online.&lt;/strong&gt;&amp;nbsp; It's down to the wire and we only have a few days left to the quarter.&amp;nbsp; Salespeople are carefully watching the transition to this state.&amp;nbsp; These visitors have been presented the coupon (and maybe even that coupon was part of a multi-variate test where different messaging was presented).&amp;nbsp; There's been contact outside of the site, where customer service has entered detailed notes in the CRM&amp;nbsp;about the questions asked last week.&amp;nbsp; This company's DNS record is all over your Sitecore Analytics data--multiple employees of the company have filled out Web Forms for Marketers forms and we've tagged names and email addresses.&amp;nbsp; We see conversions all over the place, from downloads, to form submissions, to poll questions showing buying intent.&amp;nbsp; Finally, we see that a shopping cart has been started and 50,000 widgets are in it.&amp;nbsp; The shopping cart is almost complete.&amp;nbsp; It's the 30th.&amp;nbsp; Time for a call.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Existing customer.&lt;/strong&gt;&amp;nbsp; Any time during the month we can have an authentication event--someone logged in and we now know him.&amp;nbsp; Whether his profile data is directly in Sitecore's security tables or sitting in Dynamics, Salesforce or another CRM or home-grown system, we know have a rich set of profile information to work with as we customize this visiting experience.&amp;nbsp; Has he purchased the Widget in the past?&amp;nbsp; Has he purchased products that are profiled in a similar way?&amp;nbsp; Has he specifically told us that he wants to receive email campaigns with these types of offers?&lt;/li&gt;&lt;/ol&gt;With the four possible states fully described, let's see some conditions we could use to personalize the experience for our visitor.&amp;nbsp; In follow up posts, I'll keep this theme alive and talk about how we could monitor this with the new Customer Engagement Platform Engagement Plans.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Keep in mind that, while there is an incredible set of predefined conditions available in Sitecore by default, this condition engine is easily extensible to account for your own very specific conditions--conditions that may be based on information in Sitecore or in any external system in your overall solution.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;To keep the example simple, let's imagine a simple News Story that we're writing for our site.&amp;nbsp; You could think of this News Story as being a landing page, the Widget product page itself....whatever.&amp;nbsp; The point is that we can simply have an image control on this page that can show something different based on the state the visitor is in.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;It all starts with placing our simple Show Image control on the page.&amp;nbsp; We can easily do this in the Device Editor shown below, or we can do it directly in the Page Editor:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-SJ2yYL2h90U/TnC1wVRIBGI/AAAAAAAABOI/XBDkcu-uwHs/s1600/presdetails.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="438" rba="true" src="http://4.bp.blogspot.com/-SJ2yYL2h90U/TnC1wVRIBGI/AAAAAAAABOI/XBDkcu-uwHs/s640/presdetails.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Adding our Show Image control in Content Editor's Device Editor.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Now we can set up the set of conditions that will segregate our visiting audience into the four states.&amp;nbsp; For our example, we'll simply upload some images that are nice visual indications of the current visitor's state.&amp;nbsp; In the real world case, we might have the Image control vary the advertisement image, we may swap out the control altogether based on the visitor's state, we may have a very rich control that uses dramatically different logic, markup, access to external systems, etc.&amp;nbsp; Here's our images:&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-LSnipbLCfj4/TnC3V5_OF1I/AAAAAAAABOM/MNvkcbwgaqQ/s1600/funnels.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="78" rba="true" src="http://1.bp.blogspot.com/-LSnipbLCfj4/TnC3V5_OF1I/AAAAAAAABOM/MNvkcbwgaqQ/s640/funnels.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Funnel images to depict the visitor's state&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Now we are able to have our Show Image control easily switch between these images.&amp;nbsp; Techically the control itself is able to switch its Data Source....point to a different content item in the overall Sitecore content tree.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Now, personalizing the component is an exercise of thinking through all the conditions that would lead to our decision that this visitor is part of a particular state.&amp;nbsp; First one is easy (working from the top of the funnel down).&amp;nbsp; Here, we just have the "Just Browsing" image, since we're not ready to differentiate the experience for the visitor based on our current information.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HWFHx22J9dk/TnC5jqxcHRI/AAAAAAAABOQ/c59h0X97Bz8/s1600/defaultcondition.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="540" rba="true" src="http://2.bp.blogspot.com/-HWFHx22J9dk/TnC5jqxcHRI/AAAAAAAABOQ/c59h0X97Bz8/s640/defaultcondition.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Now, it's on to the Interested in Product state.&amp;nbsp; We've decided that we'll determine a visitor to be interested in the Widget product if ANY of these conditions exist (we could have used AND clauses to ensure multiple factors exist):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;This visitor is a known user that has received an email campaign focusing on widgets&amp;nbsp;from us and has opened the email.&lt;/li&gt;&lt;li&gt;This visitor has reached a landing page we set up (maybe by browsing through the site, maybe they saw the link in a featured search result, maybe a Facebook wall post) AND they've filled out the form that they see there.&lt;/li&gt;&lt;li&gt;This visitor reached our site by searching on a specific term in a search engine.&lt;/li&gt;&lt;/ol&gt;Here's what that set of conditions looks like using prebuilt conditions in Sitecore's Rule Set Editor:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-EuA7J_ahbIo/TnC7eYjWsDI/AAAAAAAABOU/KKOPhTobHKI/s1600/rule+set+editor.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="640" rba="true" src="http://2.bp.blogspot.com/-EuA7J_ahbIo/TnC7eYjWsDI/AAAAAAAABOU/KKOPhTobHKI/s640/rule+set+editor.png" width="516" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Rule Set Editor for our multiple, independent clause condition&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Similarly, we'll list the conditions that brings a visitor down to the "Ready to Buy" section of the funnel.&amp;nbsp; For our example, we decide that this person could:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Have an "Engagement Value" greater than 10.&amp;nbsp; This will be covered more in my follow up posts, but think of a combination of goals, events and conversions each having a specific value associated with them.&lt;/li&gt;&lt;li&gt;Have a user name&amp;nbsp;(could just be a tag that we've captured, doesn't need to be an authentication event) of Mike Casey.&amp;nbsp; Maybe our customer service agent has talked to Mike.&lt;/li&gt;&lt;li&gt;Be a member of the Flagged in CRM role.&amp;nbsp; More again in a future post, but our connection to a CRM could allow a non-CMS user (like a customer service agent working in a CRM) to affect the existance of this condition simply by completing their day-to-day tasks.&lt;/li&gt;&lt;li&gt;Have a lead profile score of greater than 25.&amp;nbsp; Since your content authors are able to assign profile values to the content they create, you are now able to determine a threshold at which you'd be confident on the lead value of this visitor.&lt;/li&gt;&lt;/ol&gt;Completing our rule set by including a check for a particular customer role (this could get a lot more interesting by tying our knowledge of this customer to this clause--what products did they buy, what are their site preferences, etc), we know have a fully built out set of conditions to match a visitor into the approrpriate state:&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Zih8xwALT04/TnC_TGW44PI/AAAAAAAABOY/zBw2tFH1WQ0/s1600/finishedconditions.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="530" rba="true" src="http://1.bp.blogspot.com/-Zih8xwALT04/TnC_TGW44PI/AAAAAAAABOY/zBw2tFH1WQ0/s640/finishedconditions.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Our finished set of conditions&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Hopefully this gets you thinking about where to start and how rich the set of prebuilt conditions in Sitecore really is.&amp;nbsp; Remember that you don't have to consider sweeping changes to your Web site based on these conditions--little things, nuanced changes in site navigation, featured image spots, customized landing pages can be incredibly powerful.&amp;nbsp; In future posts we'll dive deeper into the Engagement Plans that can help us move our audience along the path towards our predefined goals for our digital strategy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-2423544385976408327?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/2423544385976408327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/2423544385976408327'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2011/09/sitecore-customer-engagement-platform.html' title='Sitecore Customer Engagement Platform: Segmenting the Audience'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-zo9h1Rf126k/TnCsCq79kkI/AAAAAAAABOE/zOHb1hDsSSE/s72-c/Possible+Visitor+States.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-1908244859048267052</id><published>2011-09-08T11:02:00.001-04:00</published><updated>2011-09-14T11:00:25.750-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Customer Engagement Platform'/><category scheme='http://www.blogger.com/atom/ns#' term='content management'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><category scheme='http://www.blogger.com/atom/ns#' term='mike casey'/><title type='text'>New Patterns in the Customer Engagement Platform</title><content type='html'>I have to admit--at first I was pretty confused about this new Patterns feature in Sitecore 6.5.&amp;nbsp; I understood the intent of allowing content authors the ability to assign a set of profile values in one fell swoop, wrapping up a bunch of attributes into a package that could be easily assigned to a piece of content they are working on.&amp;nbsp; Now, when I'm writing an article for instance, I could envision "who" this article is most targeted towards, give that audience member a name and face and set of "typical" demographic information.&lt;br /&gt;&lt;br /&gt;The confusion in my head came down to terminology....profiles, profile cards, patterns, personas.&amp;nbsp; This won't be official documentation (Sitecore has plenty of that), but instead a quick and goofy example of how I started to get my own head around these concepts.&amp;nbsp; Specifically, this will dive into the Patterns concept, as I think you'll agree that this is an amazingly cool new feature in Sitecore's personalization engine.&lt;br /&gt;&lt;br /&gt;One statement that helped me understand the difference between Profile Cards and Patterns:&amp;nbsp; Profile Cards are for assigning attribute values to content items.&amp;nbsp; Patterns allow rules&amp;nbsp;to assess how closely a visitor matches an expected "mix" of attribute values.&lt;br /&gt;&lt;br /&gt;Now starts my goofy example.&amp;nbsp; Instead of wrapping my head around nebulous attributes (yours will of course be concrete and real-world), I wanted to think about three cartoon characters that differed along three attribute axes.&amp;nbsp; The three axes--partyer, academic and worker:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Homer Simpson&lt;/strong&gt; doesn't have a ton of redeeming qualities.&amp;nbsp; Donuts and beer provide sustenance.&amp;nbsp; He wins on the partyer scale:&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-p-FUIVFPJic/TmjG5GZtQ7I/AAAAAAAABMU/jpgWRtnIWnY/s1600/homer.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="209" nba="true" src="http://4.bp.blogspot.com/-p-FUIVFPJic/TmjG5GZtQ7I/AAAAAAAABMU/jpgWRtnIWnY/s320/homer.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;While still showing hope with a value of 1 for Worker and Academic, Homer is off the charts at 10 on the Partyer scale&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;strong&gt;Scooby Doo&lt;/strong&gt; is driven by snacks, but this leads to a particularly strong work ethic.&amp;nbsp; He wins on the Worker scale:&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Ly1G0TFfgBA/TmjHmIg06sI/AAAAAAAABMY/DhW6ALTLKMk/s1600/scooby.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="209" nba="true" src="http://4.bp.blogspot.com/-Ly1G0TFfgBA/TmjHmIg06sI/AAAAAAAABMY/DhW6ALTLKMk/s320/scooby.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Scooby's snacks drive his work ethic.&amp;nbsp; A smart and fun loving dog, he still gets 1's for Academic and Partyer&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;﻿&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;strong&gt;Brian Griffin&lt;/strong&gt;&amp;nbsp;gets a little tricky.&amp;nbsp; Martinis are definitely a weakness, but his self-proclaimed academic prowess is what we'll concentrate on.&amp;nbsp; And for this example's simplicity sake, we'll hide his partying ways:&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-2UL1iFFkxO4/TmjIyb3EXtI/AAAAAAAABMc/R_b05y0JEjw/s1600/brian.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="206" nba="true" src="http://2.bp.blogspot.com/-2UL1iFFkxO4/TmjIyb3EXtI/AAAAAAAABMc/R_b05y0JEjw/s320/brian.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;A true academic (let's concentrate on how he sees himself)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;OK, let's see what we've done here.&amp;nbsp; Below is the area of the content tree where we can model profile attributes, profile cards and patterns:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-eiibsZnrqt0/TmjJSIYorMI/AAAAAAAABMg/zAMhZfkpU44/s1600/content+tree.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" nba="true" src="http://1.bp.blogspot.com/-eiibsZnrqt0/TmjJSIYorMI/AAAAAAAABMg/zAMhZfkpU44/s1600/content+tree.png" /&gt;&lt;/a&gt;&lt;/div&gt;In the Marketing Center, under the Profiles item we see the overall Profile I created, called Characters.&amp;nbsp; Directly under Characters are the three Profile Keys (which I've been calling attributes) that make up the possible segregation within the profile.&amp;nbsp; Remember that this is a mix--I can be on a scale of values between all these Profile Keys.&amp;nbsp; Profile Keys have a minimum and maximum value so you can decide on the granularity that content authors will have as they assign these values.&lt;br /&gt;&lt;br /&gt;Notice there are no Profile Cards included above.&amp;nbsp; I kept this out on purpose--let's stick to one thing at a time.&amp;nbsp; Profile Cards would have allowed me to create a predefined mix of attributes that a content author could assign to a piece of content in one operation.&amp;nbsp; It could LOOK exactly like the patterns above, but a profile card's purpose is to promote the simple and consistent application of these Profile Keys to content.&amp;nbsp; The way I have it now (as we'll soon see) I will have to assign the value of 10 for Academic, 1 for Partyer and 1 for Worker individually.&amp;nbsp; Had I created a Profile Card, I could have assigned Brian Griffin to get the same result of those independent Profile Key assignments.&lt;br /&gt;&lt;br /&gt;But let's get back to Patterns.&amp;nbsp; As you can see, under the Pattern Cards item, I added three new Pattern Cards (those are the screen shots with the character images above).&amp;nbsp; Basically a Pattern is an anticipation of shapes between the axis in the overall Profile.&lt;br /&gt;&lt;br /&gt;Because Brian Griffin would be interested, I have to include the formula Sitecore uses to decide which Pattern is matched:&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;em&gt;Squared Euclidean Distance&lt;/em&gt;&lt;br /&gt;&lt;em&gt;d(p,q) = (p1&amp;nbsp;−&amp;nbsp;q1)2&amp;nbsp;+ (p2&amp;nbsp;−&amp;nbsp;q2)2&amp;nbsp;+ ... + (pi&amp;nbsp;−&amp;nbsp;qi)2&amp;nbsp;+ ... + (pn&amp;nbsp;−&amp;nbsp;qn)2&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;For you Homers...ah, forget it you already stopped reading.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://www.sitecore.net/Community/Technical-Blogs/Getting-to-Know-Sitecore/Posts/2011/07/Visualizing-Pattern-Cards.aspx"&gt;Adam Conn for a much more serious coverage of this subject&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In our example, let's think of it like this.&amp;nbsp; We're going to label a visitor of our site with one of these characters.&amp;nbsp; A visitor is always going to be one....they might move from being a Homer to a Brian as they start reading more about the Ivy League.&amp;nbsp; They might move from Brian to Scooby as they read about the Industrial Revolution.&amp;nbsp; But they will always be one.&lt;br /&gt;&lt;br /&gt;Now our controls on our Sitecore pages know who are visitor is at any one time and can start customizing the experience.&amp;nbsp; 10% off on Scooby Snacks, Happy Hour tickets, virtual tours of the Louvre.&amp;nbsp; Maybe it's not so dramatic--a movement of a message from the bottom right to the top left, a slight reordering of navigation elements.&lt;br /&gt;&lt;br /&gt;Two parts to accomplish this:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;First&lt;/strong&gt;, we have to get smart about our content authoring process, our workflow and review process.&amp;nbsp; Let's ensure that assigning Profile Keys is an important part of the content lifecycle.&amp;nbsp; Below you'll see an article that I'm writing called &lt;em&gt;Martinis and Novels&lt;/em&gt;&amp;nbsp;(shamelessly pandering to the Brian Griffin crowd).&amp;nbsp; In addition to the article itself, I've decided to apply the appropriate Profile Keys (remember for simplicity's sake I'm pandering to Brian's self-proclaimed academic prowess).&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-oLDU8dMqpcM/TmjVFZRmPsI/AAAAAAAABMk/YXuQkK-uDvg/s1600/articletagging.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="276" nba="true" src="http://3.bp.blogspot.com/-oLDU8dMqpcM/TmjVFZRmPsI/AAAAAAAABMk/YXuQkK-uDvg/s640/articletagging.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Clicking on the Profile icons on the right hand side of the Content Editor screen brings up this dialog&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left" class="separator" style="clear: both; text-align: center;"&gt;﻿&lt;/div&gt;&lt;br /&gt;&lt;div align="left"&gt;I've assigned the value of 10 for Academic, 1 for Partyer and 1 for Worker to my news article.&amp;nbsp; Now as a visitor browses to my article page, they accumulate those values for their session (or even across multiple sessions).&amp;nbsp; The "shape" of my article is a triangle that reaches high on the Academic scale and low on the other two. &lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp; &lt;/div&gt;&lt;div align="left"&gt;I'd now go through a similar exercise for my articles targeted at other audiences and each content item will carry its own shape.&amp;nbsp; Doughnuts and Beer will reach way over on the Partyer axis. &lt;/div&gt;&lt;div align="left"&gt;&amp;nbsp; &lt;/div&gt;&lt;div align="left"&gt;&lt;strong&gt;Second&lt;/strong&gt;, we want to implement a Rule on one of our controls that takes advantage of this shape matching.&amp;nbsp; We'll keep it simple and just show a different image (technically we'll change the Data Source of our control to point to a different content item containing an Image field).&amp;nbsp; Below shows how I can accomplish this in the Sitecore 6.5 Page Editor.&amp;nbsp; I have a simple control that renders an image.&amp;nbsp; It's default data source (the image it chooses) is the question mark.&amp;nbsp; Based on our pattern matching, though, I will switch the image to the appropriate content item that contains an image targeted towards that character: &lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-5AtUfKw1Z2I/TmjXj2ZE0pI/AAAAAAAABMo/d0JLIfhlDO4/s1600/personalize.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="420" nba="true" src="http://2.bp.blogspot.com/-5AtUfKw1Z2I/TmjXj2ZE0pI/AAAAAAAABMo/d0JLIfhlDO4/s640/personalize.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This is an pre-built rule available in Sitecore 6.5.&amp;nbsp; I am able to simply look for a condition where the pattern matches the Profile Key distribution of the current visitor.&amp;nbsp; By looking for these three conditions, I am able to easily move between the cases (as someone becomes more of a Brian than a Homer).&amp;nbsp; I could also easily switch out the control altogether.&lt;br /&gt;&lt;br /&gt;Keep in mind that these conditions can be much more elaborate.&amp;nbsp; Maybe this pattern matching is a single clause of an overall condition...think about the checks you could make to a CRM or any other persistent profile store in addition to the checks you can make against current visitor browsing patterns.&amp;nbsp; Sky's the limit...hopefully this gave you way to understand a simple scenario that can open up your significant real world ideas.&lt;br /&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-1908244859048267052?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/1908244859048267052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/1908244859048267052'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2011/09/new-patterns-in-customer-engagement.html' title='New Patterns in the Customer Engagement Platform'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-p-FUIVFPJic/TmjG5GZtQ7I/AAAAAAAABMU/jpgWRtnIWnY/s72-c/homer.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-4456432470561522696</id><published>2010-11-24T07:45:00.001-05:00</published><updated>2010-11-24T07:58:14.779-05:00</updated><title type='text'>My Widget Control</title><content type='html'>&lt;p&gt;I put the term widget in the same category as out-of-the-box.&amp;#160; Out-of-the-box is a very appropriate term for how and why we bought our favorite software package in 1995.&amp;#160; There was, in fact, a box with a stack of 3.5 inch disks, there was a printed instruction booklet, there was a set of well documented and well bordered features.&amp;#160; Maybe there was some extensibility—the hint of some macro-based or API strategy and the ability for a top-notch developer to crack into the box and extend it for your business’ purposes.&amp;#160; Fast forward to now.&amp;#160; There is no box (good for the company not packaging it and shipping it, good for the environment not digesting it), documentation is online (with the new challenge in finding a balance between release management and immediate editorial changes), and the installation involves saying OK and grabbing your next cup of coffee.&amp;#160; But, more importantly, whereas in 1995 you threw the box away and started marking up your copy of the instruction manual (errata available by including proof of purchase serial number—oh man, already threw the box away—and mailing to PO Box…), now, in 2010, you have entered into a relationship.&amp;#160; You don’t (and shouldn’t) expect your experience with this software to be boxed in.&amp;#160; You expect your documentation to be task driven, continually updated with new and more focused code samples.&amp;#160; You expect a community to be there when you enter your search phrase and wonder if anyone ever had that exact same challenge before.&amp;#160; You expect—and this is a really important one—you expect that the owner of the business process should be able to model that process with the software directly.&amp;#160; You expect the developer to run alongside the business process owner (no baton passing here), building features and functionality that are derived from the business process model conversation your software was able to facilitate.&lt;/p&gt;  &lt;p&gt;Sitecore does not ship in a box.&lt;/p&gt;  &lt;p&gt;One reason—the features wouldn’t fit inside.&amp;#160; Really, if anyone has recently had a demo of Sitecore, you have seen that the conversation can go for hours on end and still not touch half of the feature set.&amp;#160; Building a product on such a solid foundation has yielded an amazingly expansive structure above.&lt;/p&gt;  &lt;p&gt;The more important reason—Sitecore doesn’t claim to know your business better than you do.&amp;#160; With all of the amazing features available in the product, one thing always holds true and consistent—the feature is built with the dedication to your ability to change it and model it to your business process needs.&amp;#160; And if you’ve seen the demo, you realize that you’re using the incredibly intuitive Sitecore UI’s to do the modeling.&amp;#160; If you want a software company to tell you what your business process needs are, I think I still have a box somewhere in my attic.&lt;/p&gt;  &lt;p&gt;Oh yeah, the widget.&amp;#160; I couldn’t think of a better title for this control based on the disorganized rant of this blog.&amp;#160; While the widget is perfect for calculating throughput in a freshman Operations 101 class, I’ve found them to be less than satisfying in developing a Web site feature (“What is it?, “It’s the new widget we got out of the box because we bought on Black Friday”).&lt;/p&gt;  &lt;p&gt;Let’s use it today though, as we look at a couple of quick concepts—the use of Web Server controls, and playing around with &lt;a href="http://sdn.sitecore.net/Developer/Using%20Sitecore%20Fast%20Query.aspx"&gt;Fast Query&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Recently I worked on a proof of concept where it was important to show the ease of adding “widgets” to a Sitecore page.&amp;#160; The scenario is one that we’ve all thought through for our site—someone is writing a news article and they want to add some things to the right column next to the story itself.&amp;#160; For this, let’s consider the ability to add:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;An image &lt;/li&gt;    &lt;li&gt;A set of images &lt;/li&gt;    &lt;li&gt;Just any old block of HTML &lt;/li&gt;    &lt;li&gt;A really smart list of items that is relevant to my content item that I'm working on &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;A disclaimer here.&amp;#160; There are MANY ways of tackling this and this little story isn’t trying to be a best practices discussion about the best way to create the information architecture for ease-of-use and extensibility.&amp;#160; Instead, in going through this exercise we simply want to:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Go through the steps of “hooking up” a Web Server control &lt;/li&gt;    &lt;li&gt;Play around with a couple cool Fast Query expressions &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;To create the new Web Server control, let’s create a class.&amp;#160; The idea behind this class is that the Sitecore.Context.Item is going to have a Multilist field where a content author can select any of these prebuilt widgets to include on their page.&amp;#160; The widgets themselves will be of four different varieties that you can see in the switch statement.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Data.Items;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Links;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Web.UI.WebControls;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;examples&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;widget&lt;/span&gt;: Sitecore.Web.UI.&lt;span style="color: #2b91af"&gt;WebControl&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;        &lt;span style="color: green"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;DoRender(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;item = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Item;&lt;br /&gt;            &lt;span style="color: blue"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField &lt;/span&gt;widgetsField = (Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField&lt;/span&gt;)item.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widgets&amp;quot;&lt;/span&gt;];&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(widgetsField != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; widgetsField.Count &amp;gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget &lt;span style="color: blue"&gt;in &lt;/span&gt;widgetsField.GetItems())&lt;br /&gt;                    {&lt;br /&gt;&lt;br /&gt;                        &lt;span style="color: blue"&gt;switch &lt;/span&gt;(widget.TemplateName)&lt;br /&gt;                        {&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;HTML Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderHTMLWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Single Image Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderSingleImageWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Query Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderQueryWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Image Gallery Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderImageGalleryWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now we can compile our project…our new class isn’t ready to do anything just yet (we can investigate that later), but we can go through the steps to register the control with Sitecore.&amp;#160; To do this, we can use the Developer Center user interface.&amp;#160; We can also do this by simply creating a new content item and filling in the appropriate fields, but let’s use the Developer Center at least this first time.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Please see our full documentation set (especially the &lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Cookbook.aspx"&gt;Presentation Component Cookbook&lt;/a&gt; and &lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Presentation%20Component%20Reference.aspx"&gt;Presentation Component Reference&lt;/a&gt;) for much better documentation around this process.&amp;#160; Below are steps to get us going quickly….&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In Developer Center, click on File—&amp;gt;New.&amp;#160; From there you will see the ability to create a new Web Control.&amp;#160; Select Web Control and click Create.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TO0IvCENd6I/AAAAAAAABKY/NHtsqB4PSDU/s1600-h/image%5B6%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/TO0IvtUphbI/AAAAAAAABKc/vM7TzuwiODw/image_thumb%5B4%5D.png?imgmax=800" width="648" height="473" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Follow the Wizard until you get to the Configuration step:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TO0IwCL1m4I/AAAAAAAABKg/usd7ak7fouw/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/TO0Iw8OobHI/AAAAAAAABKk/UKqw2xxLsHI/image_thumb%5B7%5D.png?imgmax=800" width="424" height="452" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notes on these steps:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Name will be the name of the content item &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Tag Prefix/Tag will be how the control is registered on the page &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Be sure to check your namespace and the check in your project for your assembly name (and you don’t need to add the .dll extension). &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;Click the Test button to be sure your class was found in the assembly, and complete the Wizard by choosing where to create the Sitecore content item that represents your new control. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;After finishing the Wizard, the Developer Center will open to the item itself, so you can see how the item’s fields are populated with the results of your Wizard entry. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;To make your next Web Control, you could simply duplicate or copy/paste this item and change the fields to reflect your next class……or you can go through the Wizard steps again. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here’s my final:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TO0IxvL7UVI/AAAAAAAABKo/5qWoljcPo14/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/TO0IyTER-7I/AAAAAAAABKs/oJCj8mUFbwM/image_thumb%5B10%5D.png?imgmax=800" width="440" height="465" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And here’s how the control could be registered and included in an .aspx:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="background: yellow"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@&lt;/span&gt;&lt;span style="color: maroon"&gt;Register&lt;/span&gt;&lt;span style="color: red"&gt;TagPrefix&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;mc&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;examples&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;Assembly&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;myproject&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;%&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@&lt;/span&gt;&lt;span style="color: maroon"&gt;Page&lt;/span&gt;&lt;span style="color: red"&gt;Language&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;c#&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;CodePage&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;65001&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;AutoEventWireup&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;%&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;@&lt;/span&gt;&lt;span style="color: maroon"&gt;OutputCache&lt;/span&gt;&lt;span style="color: red"&gt;Location&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;None&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;VaryByParam&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;none&amp;quot;&lt;/span&gt;&lt;span style="background: yellow"&gt;%&amp;gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;lt;!&lt;/span&gt;&lt;span style="color: maroon"&gt;DOCTYPE&lt;/span&gt;&lt;span style="color: red"&gt;html PUBLIC&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: red"&gt;lang&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;xml&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;lang&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Insert the page title here.&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;title&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;head&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;form&lt;/span&gt;&lt;span style="color: red"&gt;method&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;mainform&amp;quot;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;&lt;/span&gt;&lt;span style="color: maroon"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;widget&lt;/span&gt;&lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;widget1&amp;quot;&lt;/span&gt;&lt;span style="color: red"&gt;xmlns&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: red"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;=&amp;quot;http://www.sitecore.net/xhtml&amp;quot;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;mc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: maroon"&gt;widget&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;form&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;body&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: maroon"&gt;html&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;font color="#000000" face="Trebuchet MS"&gt;Now we can get back to our class.&amp;#160; I’ve included the shell that we saw before, and added a method to return the results of a Sitecore Fast Query:&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Data.Items;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Links;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Web.UI.WebControls;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;examples&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;widget&lt;/span&gt;: Sitecore.Web.UI.&lt;span style="color: #2b91af"&gt;WebControl&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected override void &lt;/span&gt;DoRender(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;item = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Item;&lt;br /&gt;            &lt;span style="color: blue"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField &lt;/span&gt;widgetsField = (Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField&lt;/span&gt;)item.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widgets&amp;quot;&lt;/span&gt;];&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(widgetsField != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; widgetsField.Count &amp;gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget &lt;span style="color: blue"&gt;in &lt;/span&gt;widgetsField.GetItems())&lt;br /&gt;                    {&lt;br /&gt;&lt;br /&gt;                        &lt;span style="color: blue"&gt;switch &lt;/span&gt;(widget.TemplateName)&lt;br /&gt;                        {&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;HTML Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderHTMLWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Single Image Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderSingleImageWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Query Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                RenderQueryWidget(output, widget);&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Image Gallery Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: green"&gt;//todo:  RenderImageGalleryWidget(output, widget);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;RenderQueryWidget(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget)&lt;br /&gt;        {&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelTab&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelTab Div&lt;br /&gt;            &lt;/span&gt;output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelContent&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            &lt;span style="color: blue"&gt;string &lt;/span&gt;fastQuery = widget.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;            Sitecore.Data.&lt;span style="color: #2b91af"&gt;Database &lt;/span&gt;db = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Database;&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;[] results = db.SelectItems(fastQuery);&lt;br /&gt;            &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;result &lt;span style="color: blue"&gt;in &lt;/span&gt;results)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: blue"&gt;string &lt;/span&gt;menuTitle = result.Name;&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;] != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;].Value.ToString()))&lt;br /&gt;                    {&lt;br /&gt;                        menuTitle = result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;].Value.ToString();&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(result.Paths.IsMediaItem)&lt;br /&gt;                {&lt;br /&gt;                    output.Write(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;&amp;gt;{1}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;, Sitecore.Resources.Media.&lt;span style="color: #2b91af"&gt;MediaManager&lt;/span&gt;.GetMediaUrl(result), menuTitle));&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: blue"&gt;else&lt;br /&gt;                &lt;/span&gt;{&lt;br /&gt;                    output.Write(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;&amp;gt;{1}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;, Sitecore.Links.&lt;span style="color: #2b91af"&gt;LinkManager&lt;/span&gt;.GetItemUrl(result), menuTitle));&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelContentTab Div&lt;br /&gt;            &lt;/span&gt;output.RenderEndTag();&lt;span style="color: green"&gt;//Widget Div&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notice that the class inherits from the Sitecore.Web.UI.WebControl and must override the DoRender method (using and HTMLTextWriter object to add HTML to the output).&amp;#160; For our RenderQueryWidget method, here are the assumptions:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;The Context Item (which caused this control to be invoked because it was part of the item’s presentation details) has a MuliList field called “Widgets”. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;In that MultiList field are 1 to N of these Widget items. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;The Widget items can be of 4 different data templates, representing the different types of widgets available &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;If the Widget item is created from the Query Widget data template, the Widget item will have a single line text box with a Fast Query expression. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;The RenderQueryWidget will use that expression to grab the appropriate items from the content tree and render an unordered list of links to those items. &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;The output will be a series of divs with the ability to call out a CSS class to format them. &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here’s a screenshot of how the Query Widget data template could be created.&amp;#160; Some features to implement after this article.&amp;#160; Having a single-line text field for the fast query is obviously not the most intuitive business champion interface, so we can start thinking of the criteria (and the Sitecore field type to go with it) that would provide a better user interface experience.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TO0IzTGs5zI/AAAAAAAABKw/vO9-0QZ4nlE/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/TO0Iz3Sc_aI/AAAAAAAABK0/VQqwhKdcZwQ/image_thumb%5B13%5D.png?imgmax=800" width="707" height="324" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;For now, let’s concentrate on some of the Fast Queries we could use.&amp;#160; And for a detailed description of this feature, please see our &lt;a href="http://sdn.sitecore.net/Reference/Using%20Sitecore%20Query.aspx"&gt;Sitecore Query&lt;/a&gt; and &lt;a href="http://sdn.sitecore.net/Developer/Using%20Sitecore%20Fast%20Query.aspx"&gt;Fast Query&lt;/a&gt; documentation.&amp;#160; Also, if you want to test these expressions in your own installation, use the Developer Center Tools:XPath Builder feature.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="2" width="750"&gt;&lt;tbody&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;      &lt;td valign="top" width="353"&gt;Need&lt;/td&gt;&lt;br /&gt;&lt;br /&gt;      &lt;td valign="top" width="395"&gt;Fast Query to solve&lt;/td&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;      &lt;td valign="top" width="353"&gt;“Give me all the items that are based on the News Story Data Template (that are descendants of the content node)”&lt;/td&gt;&lt;br /&gt;&lt;br /&gt;      &lt;td valign="top" width="395"&gt;fast:/sitecore/content//*[@@templatename='news story'] &lt;/td&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;      &lt;td valign="top" width="352"&gt;“Give me all items that have been tagged with the Professional OMS Profile”&lt;/td&gt;&lt;br /&gt;&lt;br /&gt;      &lt;td valign="top" width="396"&gt;fast://*[@__Tracking = '%Professional%']&lt;/td&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt;&lt;br /&gt;    &lt;tr&gt;&lt;br /&gt;      &lt;td valign="top" width="352"&gt;“Give me items that are definitely products in the home site that have also been tagged with the Male OMS Profile” &lt;/td&gt;&lt;br /&gt;&lt;br /&gt;      &lt;td valign="top" width="397"&gt;fast:/sitecore/content/home//*[@@templatename='product' and @__Tracking='%Male%']&lt;/td&gt;&lt;br /&gt;    &lt;/tr&gt;&lt;br /&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here’s how the Widget content item for the previous example could look:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/TO0I0zrB9XI/AAAAAAAABK4/DGR4Vhjp3Ko/s1600-h/image%5B26%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_JjsHfCZ5On8/TO0I1V_EhZI/AAAAAAAABK8/UUJmRhrepf0/image_thumb%5B16%5D.png?imgmax=800" width="667" height="364" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, if you include a MultiList field (think of creating a separate Widgets Data Template and include it as an inherited template where needed).&amp;#160; This template could just contain the MultiLIst field itself (sourced to find widgets in the content tree) where an author could select the appropriate widget for their content item.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I end with the full class listing below so you could start thinking of improved and extended uses of this.&amp;#160; In this example, the Widget field itself is of a different type depending on the type of Widget (it’s an image field, it’s a Rich Text field, etc.).&amp;#160; Tongue firmly implanted in cheek, a widget, of course, can do anything!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Web.UI;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Data.Items;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Links;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Web.UI.WebControls;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Text;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;examples&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;widget &lt;/span&gt;: Sitecore.Web.UI.&lt;span style="color: #2b91af"&gt;WebControl&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected override void &lt;/span&gt;DoRender(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;item = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Item;&lt;br /&gt;            &lt;span style="color: blue"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField &lt;/span&gt;widgetsField = (Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField&lt;/span&gt;)item.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widgets&amp;quot;&lt;/span&gt;];&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(widgetsField != &lt;span style="color: blue"&gt;null &lt;/span&gt;&amp;amp;&amp;amp; widgetsField.Count &amp;gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget &lt;span style="color: blue"&gt;in &lt;/span&gt;widgetsField.GetItems())&lt;br /&gt;                    {&lt;br /&gt;&lt;br /&gt;                        &lt;span style="color: blue"&gt;switch &lt;/span&gt;(widget.TemplateName)&lt;br /&gt;                        {&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;HTML Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                RenderHTMLWidget(output, widget);&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Single Image Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                RenderSingleImageWidget(output, widget);&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Query Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                RenderQueryWidget(output, widget);&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;Image Gallery Widget&amp;quot;&lt;/span&gt;:&lt;br /&gt;                                RenderImageGalleryWidget(output, widget);&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                            &lt;span style="color: blue"&gt;default&lt;/span&gt;:&lt;br /&gt;                                &lt;span style="color: blue"&gt;break&lt;/span&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;RenderQueryWidget(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget)&lt;br /&gt;        {&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelTab&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelTab Div&lt;br /&gt;            &lt;/span&gt;output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelContent&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            &lt;span style="color: blue"&gt;string &lt;/span&gt;fastQuery = widget.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;            Sitecore.Data.&lt;span style="color: #2b91af"&gt;Database &lt;/span&gt;db = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Database;&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;[] results = db.SelectItems(fastQuery);&lt;br /&gt;            &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;result &lt;span style="color: blue"&gt;in &lt;/span&gt;results)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: blue"&gt;string &lt;/span&gt;menuTitle = result.Name;&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;] != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;].Value.ToString()))&lt;br /&gt;                    {&lt;br /&gt;                        menuTitle = result.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Menu Title&amp;quot;&lt;/span&gt;].Value.ToString();&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(result.Paths.IsMediaItem)&lt;br /&gt;                {&lt;br /&gt;                    output.Write(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;&amp;gt;{1}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;, Sitecore.Resources.Media.&lt;span style="color: #2b91af"&gt;MediaManager&lt;/span&gt;.GetMediaUrl(result), menuTitle));&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color: blue"&gt;else&lt;br /&gt;                &lt;/span&gt;{&lt;br /&gt;                    output.Write(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;&amp;gt;{1}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;, Sitecore.Links.&lt;span style="color: #2b91af"&gt;LinkManager&lt;/span&gt;.GetItemUrl(result), menuTitle));&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelContentTab Div&lt;br /&gt;            &lt;/span&gt;output.RenderEndTag();&lt;span style="color: green"&gt;//Widget Div&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;RenderImageGalleryWidget(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelTab&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelContent&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;&lt;br /&gt;            Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField &lt;/span&gt;imageList = (Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;MultilistField&lt;/span&gt;)widget.Fields[&lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;];&lt;br /&gt;            &lt;span style="color: blue"&gt;foreach &lt;/span&gt;(Sitecore.Data.Items.&lt;span style="color: #2b91af"&gt;MediaItem &lt;/span&gt;media &lt;span style="color: blue"&gt;in &lt;/span&gt;imageList.GetItems())&lt;br /&gt;            {&lt;br /&gt;                output.Write(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;@&amp;quot;&amp;lt;a href=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot; width=&amp;quot;&amp;quot;90px;&amp;quot;&amp;quot; alt=&amp;quot;&amp;quot;{1}&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/a&amp;gt;&amp;quot;&lt;/span&gt;, Sitecore.Resources.Media.&lt;span style="color: #2b91af"&gt;MediaManager&lt;/span&gt;.GetMediaUrl(media), media.Name));&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelContentTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.RenderEndTag();&lt;span style="color: green"&gt;//Widget Div&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;RenderSingleImageWidget(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelTab&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelContent&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;mw=300&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelContentTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.RenderEndTag();&lt;span style="color: green"&gt;//Widget Div&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;RenderHTMLWidget(&lt;span style="color: #2b91af"&gt;HtmlTextWriter &lt;/span&gt;output, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;widget)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;&lt;br /&gt;            output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelTab&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.AddAttribute(&lt;span style="color: #2b91af"&gt;HtmlTextWriterAttribute&lt;/span&gt;.Class, &lt;span style="color: #a31515"&gt;&amp;quot;WidgetPanelContent&amp;quot;&lt;/span&gt;);&lt;br /&gt;            output.RenderBeginTag(&lt;span style="color: #2b91af"&gt;HtmlTextWriterTag&lt;/span&gt;.Div);&lt;br /&gt;            output.Write(&lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(widget, &lt;span style="color: #a31515"&gt;&amp;quot;Widget&amp;quot;&lt;/span&gt;));&lt;br /&gt;            output.RenderEndTag();&lt;span style="color: green"&gt;//WidgetPanelContentTab Div&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;output.RenderEndTag();&lt;span style="color: green"&gt;//Widget Div&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:258e015c-93a6-4038-aba3-ba39c3b65109" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Sitecore" rel="tag"&gt;Sitecore&lt;/a&gt;,&lt;a href="http://technorati.com/tags/OMS" rel="tag"&gt;OMS&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Fast+query" rel="tag"&gt;Fast query&lt;/a&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-4456432470561522696?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4456432470561522696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4456432470561522696'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2010/11/my-widget-control.html' title='My Widget Control'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_JjsHfCZ5On8/TO0IvtUphbI/AAAAAAAABKc/vM7TzuwiODw/s72-c/image_thumb%5B4%5D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-8510404874074643585</id><published>2010-08-06T16:39:00.001-04:00</published><updated>2010-08-06T16:48:03.275-04:00</updated><title type='text'>Checking an external source for an OMS condition</title><content type='html'>&lt;p&gt;In talking through potential Online Marketing Suite scenarios with prospects, clients and partners these days, the discussion often leads to very interesting possibilities in evaluating external data sources as part of an overall personalization strategy.&amp;#160; For those of you that have worked with Sitecore, you know it’s built for this.&amp;#160; Rather than enforce a migration of data to the content repository, a well developed Sitecore strategy continues to take advantage of data and application functionality wherever it is best served from.&amp;#160; OMS is no different.&lt;/p&gt;  &lt;p&gt;The following is a simple example of a common scenario.&amp;#160; We want to develop an OMS condition that queries an external database and determines whether a product is available before showing the promotion our marketing team has created for it.&amp;#160; With the condition in place, it will be easy for us to build a rule that does something when the condition is true.&amp;#160; This is a classic “When” condition, and we can think of all kinds of rules that might be appropriate based on the boolean value returned.&lt;/p&gt;  &lt;p&gt;Many of my conversations lately have been around “Who does what in OMS?”.&amp;#160; A very fair question.&amp;#160; I get excited by the question, because it gives me confidence in the “newness”of what OMS is doing.&amp;#160; Sure, every piece of OMS could be developed separately (it is software, and everything is possible), but &lt;a href="http://www.sitecore.net"&gt;Sitecore&lt;/a&gt; has sparked the questions because it’s not JUST developers anymore.&amp;#160; While developers are certainly creating the great methods that evaluate conditions and implement rule-driven functionality, others (you get to decide who) are mapping the business processes and visualizing the results.&amp;#160; These two sides are equally important—if a Condition falls in the woods and nobody….you get the idea.&lt;/p&gt;  &lt;p&gt;Back to it.&amp;#160; 1st step is the condition definition itself.&amp;#160; Who does this?&amp;#160; Well, in most cases this one’s for the developer.&amp;#160; The reason is that we’re coding brand new logic here.&amp;#160; If you’re talking about the rich set of standard OMS Conditions (geolocation info, DNS info, authenticated user, the visitor entered as as part of an &lt;a href="http://www.sitecore.net/en/Products/Sitecore-Email-Campaign-Manager.aspx"&gt;Email Campaign&lt;/a&gt;, etc), then there’s no work to do here.&amp;#160; These Conditions are already defined and available to you as you build a rule to evaluate that particular Condition.&amp;#160; More on that later.&amp;#160; The screenshot below shows the beginning of the scrollable list of prebuilt Conditions:&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TFxzF0xbsCI/AAAAAAAABJY/yfFlaccarnU/s1600-h/image8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/TFxzGfzg6pI/AAAAAAAABJc/lACrDc2-S24/image_thumb6.png?imgmax=800" width="596" height="434" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; In standard Sitecore fashion, all prebuilt Sitecore functionality is built and referenced in the same way you’ll build yours.&amp;#160; If you look in the Content Editor under /sitecore/system/Settings/Rules/Conditional Renderings/Conditions/Area Code Condition, you’ll see the definition (the Item in the tree) that represents the condition.&amp;#160; Even though this is a standard OMS Condition, Sitecore shows you the class being used:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/TFxzGrinPLI/AAAAAAAABJg/QsvGGW5nvv0/s1600-h/image13.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/TFxzHGaZtsI/AAAAAAAABJk/YF0EfMETYlI/image_thumb9.png?imgmax=800" width="612" height="365" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You’ll notice that the AreaCodeCondition class in the Sitecore.Analytics assembly is referenced.&amp;#160; You’ll also see that the Text field allows you to define placeholders where a content author can enter additional parameters to the condition evaluation.&amp;#160; &lt;a href="http://mikecaseycms.blogspot.com/2009/11/oms-rules-engine-example.html"&gt;I talk a little more about these values here&lt;/a&gt;, and our&amp;#160; &lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Rules%20Engine%20Cookbook.aspx"&gt;Rules Engine Cookbook&lt;/a&gt; does a great job of going into more detail.&lt;/p&gt;  &lt;p&gt;So for our purposes today, it’s going to be even easier.&amp;#160; Rather that doing a compare of values between Analytics data and content author entered parameters, we’re simply going to check the “trueness” of a condition.&amp;#160; Does the product have any availability?&amp;#160; Based on the result, we can then decide what to do about it.&lt;/p&gt;  &lt;p&gt;The reason for the belaboring:&amp;#160; this is the thought process you’ll go through as you answer the “Who does what?” question with OMS.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A cross-functional team discusses the Conditions that need to be evaluated.&amp;#160; Some will exist in OMS already, some will need to have these comparisons / when-condition methods crafted to encapsulate your business rules, query external sources, etc. &lt;/li&gt;    &lt;li&gt;A cross-functional team discusses the Rules, the things that should HAPPEN when a Condition is evaluated.&amp;#160; Some will exist in OMS already (easily hiding or showing a control, having a control display a different piece of content, moving a control to a different area of the page, initiating a specific Email Campaign, etc.) and some will do fun and exciting things outside of the Sitecore application domain and context. &lt;/li&gt;    &lt;li&gt;A cross-functional team discusses where and when these rules are appropriate (the marching red ants theorem first developed in the 90’s has new corollaries). &lt;/li&gt;    &lt;li&gt;A cross-functional team ensures that both sides of the brain communicate, and that the development efforts and the business process mapping stay on the same (albeit flexibly winding) trail.&amp;#160;&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The point here isn’t that you need a huge cross-functional team.&amp;#160; The point is that if you’re a team of one (or 2, or 10, or 100), you need to think cross-functionality.&amp;#160; Nothing new here.&lt;/p&gt;  &lt;p&gt;Back to it.&amp;#160; Now that we’ve seen where the Condition definitions are, we’ll simply add our own and call out our own Class.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/TFxzHSFl0xI/AAAAAAAABJo/Ew8hR_QSStk/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_JjsHfCZ5On8/TFxzH1G3vSI/AAAAAAAABJs/CohnjHMuRNQ/image_thumb%5B1%5D.png?imgmax=800" width="581" height="376" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This condition is set up to take a look at the Northwind database, see if there is any Tofu available, and return true if so:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Diagnostics;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Rules.Conditions;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Rules;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Linq;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Data.Linq;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;nwind;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;Examples&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;NorthwindProductAvailable&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af"&gt;RuleCondition&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color: blue"&gt;where &lt;/span&gt;T : &lt;span style="color: #2b91af"&gt;RuleContext&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;        &lt;span style="color: green"&gt;// Methods&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;protected void &lt;/span&gt;WhenCondition()&lt;br /&gt;        {&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;public override void &lt;/span&gt;Evaluate(T ruleContext, &lt;span style="color: #2b91af"&gt;RuleStack &lt;/span&gt;stack)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(ruleContext, &lt;span style="color: #a31515"&gt;&amp;quot;ruleContext&amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(stack, &lt;span style="color: #a31515"&gt;&amp;quot;stack&amp;quot;&lt;/span&gt;);&lt;br /&gt;            stack.Push(&lt;span style="color: blue"&gt;this&lt;/span&gt;.Execute(ruleContext));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected bool &lt;/span&gt;Execute(T ruleContext)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;try&lt;br /&gt;            &lt;/span&gt;{&lt;br /&gt;                &lt;span style="color: #2b91af"&gt;Northwind_Extended &lt;/span&gt;db = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Northwind_Extended&lt;/span&gt;(&lt;span style="color: #a31515"&gt;@&amp;quot;Data Source=(local);Initial Catalog=Northwind; user=sa; password=*&amp;quot;&lt;/span&gt;);               &lt;br /&gt;                   &lt;span style="color: blue"&gt;var &lt;/span&gt;numUnits = (&lt;span style="color: blue"&gt;from &lt;/span&gt;m &lt;span style="color: blue"&gt;in &lt;/span&gt;db.Products&lt;br /&gt;                                &lt;span style="color: blue"&gt;where &lt;/span&gt;m.ProductName == &lt;span style="color: #a31515"&gt;&amp;quot;Tofu&amp;quot;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: blue"&gt;select &lt;/span&gt;m.UnitsInStock).SingleOrDefault();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                   &lt;span style="color: blue"&gt;return &lt;/span&gt;numUnits &amp;gt; 0;&lt;br /&gt;          &lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: blue"&gt;catch&lt;br /&gt;            &lt;/span&gt;{ &lt;span style="color: blue"&gt;return false&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That’s it.&amp;#160; &lt;a href="http://mikecaseycms.blogspot.com/2009/11/oms-rules-engine-example.html"&gt;As my previous post shows&lt;/a&gt;, now this condition is available to us to define any action to take after the evaluation of it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We’d certainly have a more complex business rule in the real world, and that would invariably lead to the ability to have marketers and other content authors being able to include their parameters to the condition evaluation.&amp;#160; By including tokens for replacement, this becomes a very easy exercise.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-8510404874074643585?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8510404874074643585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8510404874074643585'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2010/08/checking-external-source-for-oms.html' title='Checking an external source for an OMS condition'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_JjsHfCZ5On8/TFxzGfzg6pI/AAAAAAAABJc/lACrDc2-S24/s72-c/image_thumb6.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-3588226973842177429</id><published>2010-04-05T17:56:00.001-04:00</published><updated>2010-04-05T17:56:00.703-04:00</updated><title type='text'>Zen and the Art of CMS, Chapter 1</title><content type='html'>&lt;blockquote&gt;   &lt;p&gt;What you have to do, if you get caught in this gumption trap of value rigidity, is slow down—you’re going to have to slow down anyway whether you want to or not—but slow down deliberately and go over ground that you’ve been over before to see if the things you thought were important were really important and to…well…just &lt;em&gt;stare&lt;/em&gt; at the machine.&amp;#160; There’s nothing wrong with that.&amp;#160; Just live with it for a while.&amp;#160; Watch it the way you watch a line when fishing and before long, as sure as you live, you’ll get a little nibble, a little fact asking in a timid, humble way if you’re interested in it.&amp;#160; That’s the way the world keeps on happening.&amp;#160; Be interested in it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p align="right"&gt;Robert M. Pirsig,&lt;em&gt; Zen and the Art of Motorcycle Maintenance&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I’ve been looking for a model to use as an ongoing discussion of Sitecore.&amp;#160; I’ve decided on a tried and true classic (translation: might be outdated) in Bob Boiko’s &lt;a href="http://www.amazon.com/Content-Management-Bible-Bob-Boiko/dp/0764573713/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1270225827&amp;amp;sr=8-1" target="_blank"&gt;Content Management Bible&lt;/a&gt;.&amp;#160; With 40 chapters and over 1,000 pages, this should give me plenty as a structure to describe every part of the Sitecore CMS, sprinkling in my own lessons learned, discussions with Sitecore implementation partners and clients, and an occasional code sample here and there.&amp;#160; With any system there are absolutely great things and things that become absolutely great with the right mechanic.&amp;#160; There are always challenges.&amp;#160; In almost all cases these are very human challenges, where implementation details follow a frustratingly parallel and distinct path from poorly communicated expectations; where use cases are copied from comfortable but outdated business processes; where the the tool is used with unintended force until it strips the bolt; where the wrong tool is used altogether.&lt;/p&gt;  &lt;p&gt;Time to step back, take our time, stare at the machine.&amp;#160; With patience and focus, we’ll tune it for a very long and prosperous ride….&lt;/p&gt;  &lt;p&gt;Chapter 1, What is Content?&lt;/p&gt;  &lt;p&gt;For Sitecore, What is an Item?&lt;/p&gt;  &lt;p&gt;Boiko’s introduction allows us to consider the complementary and colliding concepts of information, data and content.&amp;#160; This introduction to core CMS concepts gives me an opportunity to talk about a core Sitecore concept—the &lt;strong&gt;Item&lt;/strong&gt;.&amp;#160; The &lt;strong&gt;Item&lt;/strong&gt; in Sitecore is the core unit of content.&amp;#160; An item is, on the surface, a collection of &lt;strong&gt;Fields&lt;/strong&gt;.&amp;#160; An Item is much more, though.&amp;#160; It is the container (the honey jar with the label in Boiko’s example) that describes its purpose, its relevance, its allowed position in the information architecture, its review process (workflow), its rules for validation (its page should be XHTML compliant, a particular field within it should be required, another field within should follow a regular expression describing U.S. zip codes, etc.), its access rights for various roles and users of the application.&lt;/p&gt;  &lt;p&gt;Let’s take a brief look at the Item, its lifecycle and some of the many things that it can do to help describe your information.&amp;#160; Sitecore has very rich documentation on the &lt;strong&gt;Item&lt;/strong&gt;, the &lt;strong&gt;Data Templates&lt;/strong&gt; that serve as the data and business rules model for the &lt;strong&gt;Item&lt;/strong&gt; and the various user interfaces used to create and maintain the rich content that this architecture promotes.&lt;/p&gt;  &lt;p&gt;Let’s create a new News Article and see what we have available to us.&amp;#160; Now, of course, the News Article we create has already been fully modeled for us.&amp;#160; A News Article &lt;strong&gt;Data Template&lt;/strong&gt; has been created in my site (ideally a cross-functional group got together and really talked about what a News Article is for our company) and is available for us to build a new News Article from.&amp;#160; In addition, this group got together and talked about where News Articles should appear in the site—from&amp;#160; presentation, navigation and content hierarchy perspectives.&amp;#160; As you can see below, there’s a News-and-Events area of the content hierarchy, and Sitecore dutifully guides me that my new News Article can go here.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/S7pcSiZwcsI/AAAAAAAABIM/zdPoY__SXc0/s1600-h/image3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/S7pcTqc_8WI/AAAAAAAABIQ/lpzchHQJzVU/image_thumb1.png?imgmax=800" width="472" height="351" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s name our new News Article:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/S7pcUWlBhEI/AAAAAAAABIU/hZZ8dO_v_Xw/s1600-h/image11.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/S7pcUhQTWgI/AAAAAAAABIY/70WojgdXUyA/image_thumb5.png?imgmax=800" width="372" height="143" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;…and our News Article is inserted into the content hierarchy.&amp;#160; Notice the right column, where sections upon sections of available fields await our editing.&amp;#160; Many of these are &lt;strong&gt;Standard Fields&lt;/strong&gt; (fields given to our new News Article by its automatic inheritance of the Sitecore Standard Template).&amp;#160; This automatically gives me an incredibly rich container of information—some fields I might never see, care about or maintain, but they are there to further describe my News Article and track its movement through the system.&amp;#160; I can see that this News Article has already begun its track through a workflow process (a handy automatic review process that the cross-functional group decided should be a requirement of all News Articles across the site and therefore set the rule on the Data Template for News Articles):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/S7pcVbqEiGI/AAAAAAAABIc/G9EfKO9vXo4/s1600-h/image7.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcV-AA0aI/AAAAAAAABIg/YC5VdnTSPFY/image_thumb3.png?imgmax=800" width="545" height="327" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As we start to expand some of these sections, we can get down to the Field level of detail.&amp;#160; Now we’re at the individual pieces of information that go into our container.&amp;#160; Some of these fields will be the core of the News Article itself.&amp;#160; A Title field may be automatically populated by the name of the News Article I just created.&amp;#160; Other fields may be populated with static text (to tell me as a content author what I should do with this field):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcWVrWAjI/AAAAAAAABIk/PvXPkiSMBtY/s1600-h/image16.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcW-SsivI/AAAAAAAABIo/WKgtNQBfRII/image_thumb8.png?imgmax=800" width="575" height="347" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Other fields may allow me to create links, references within my content hierarchy, tying together like-content:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcXJlTSrI/AAAAAAAABIs/dei9l-OhKu4/s1600-h/image21.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcYOR_xMI/AAAAAAAABIw/mcLLNmq6224/image_thumb11.png?imgmax=800" width="603" height="148" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Still other fields allow me to describe my content, targeting it towards specific personas, profiles, campaigns, describing it as appropriate for certain geographical locations, assessing a score or value in a sales or marketing category:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/S7pcYkNoL_I/AAAAAAAABI0/aO_rNkxK_ck/s1600-h/image33.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/S7pcY4_mFaI/AAAAAAAABI4/4XaWvVRBfoI/image_thumb19.png?imgmax=800" width="609" height="355" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;All along the way, as this new News Article moves from creation through edited versions to various workflow / review states to readiness for site publication, this container, this &lt;strong&gt;Item&lt;/strong&gt; contains all the fields necessary to track and report on this activity:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/S7pcZSAfCVI/AAAAAAAABI8/P1pbnfqDXrQ/s1600-h/image30.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/S7pcZgToGOI/AAAAAAAABJA/VAg-rtRUaCE/image_thumb16.png?imgmax=800" width="621" height="292" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;…and a consistent event architecture to react in your own way as this item moves through the process.&amp;#160; If I wanted to write to my own log file, communicate with another application, etc., I have a clear event model in place.&amp;#160; I could easily call out some Sitecore actions (as in this Validation action that is called out as someone Approves my News Article):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcaHEjhsI/AAAAAAAABJE/3rBtDKg3IZc/s1600-h/image41.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/S7pcbC6WyVI/AAAAAAAABJI/bsnpQiCOovk/image_thumb23.png?imgmax=800" width="634" height="398" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Or I could call my own Hello World code when the News Article is Saved:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcbVuW61I/AAAAAAAABJM/4-4H0YdvQJU/s1600-h/image37.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S7pcbxKINlI/AAAAAAAABJQ/Nl_p4DJCzrE/image_thumb21.png?imgmax=800" width="403" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Boiko's chapter 1 is certainly not a comprehensive coverage of Content Management.&amp;#160; Likewise, this article isn’t an in-depth, complete document on the Item in Sitecore.&amp;#160; Hopefully this scratched the surface about everything this honey jar is in Sitecore—with the rich field typing system, standard fields and other techniques that promote the meta-information surrounding the Item’s core informational fields, business rules (and I didn’t even yet mention presentation) containment, and an event model to track and react to everything the Item becomes along the way….&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-3588226973842177429?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3588226973842177429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3588226973842177429'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2010/04/zen-and-art-of-cms-chapter-1.html' title='Zen and the Art of CMS, Chapter 1'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_JjsHfCZ5On8/S7pcTqc_8WI/AAAAAAAABIQ/lpzchHQJzVU/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-3920571184624680746</id><published>2010-03-30T17:15:00.001-04:00</published><updated>2010-03-30T17:18:54.596-04:00</updated><title type='text'>Thinking about static files</title><content type='html'>&lt;p&gt;OK, this isn’t going to be a typical Sitecore article.&amp;#160; And this isn’t going to be a good code sample.&amp;#160; With those 2 caveats firmly in place…&lt;/p&gt;  &lt;p&gt;In my position I often try to think through good examples to highlight possible solutions, rather than developing them in a fully-built-out, real world deliverable.&amp;#160; I’ll leave the expansion of this one (and the well-built code sample) to our fantastic Sitecore developers at our company and within our partner and client ranks.&lt;/p&gt;  &lt;p&gt;In talking to many government and financial clients (this applies to many more, but those are two verticals where this is particularly important), the discussion often turns to auditing.&amp;#160; Not only auditing from an internal CMS-activity perspective (who changed which piece of content when, who approved what, etc.—Sitecore certainly has rich features around this activity), but from a web site visitor experience perspective.&amp;#160; What did I quote that person on Monday, October 12, 2009 at 2pm?&amp;#160; What was the banner ad in place when Customer Casey clicked through based on a multi-variate test I was performing?&lt;/p&gt;  &lt;p&gt;With the possibilities of very different presentations to different visitors (made possible by Sitecore’s Online Marketing Suite Rules Engine), I might want to ensure we have a record of those various situations or I might want to see what they will look like ahead of time.&lt;/p&gt;  &lt;p&gt;Now this is where developers might leave the article.&amp;#160; Again, this isn’t going to be a robust solution to the problem above.&amp;#160; This is demowear with a purpose.&amp;#160; The purpose is to start thinking about the real solution that could be put in place, and, along the way, to talk about a couple of entry points, events and hooks that Sitecore exposes which serve as great options to develop against.&amp;#160; As always, Sitecore provides the access to the entire CMS lifecycle.&lt;/p&gt;  &lt;p&gt;There are a number of tools on the market that perform the function of crawling a dynamically generated site for the purposes of creating an “offline” or file-system version of the site.&amp;#160; One of these tools that some of our clients have used with success is HTTrack (&lt;a href="http://www.httrack.com/"&gt;http://www.httrack.com/&lt;/a&gt;) .&amp;#160; &lt;/p&gt;  &lt;p&gt;I wanted to play around with this idea a bit in the Content Editor.&amp;#160; So I created a simple command button which would allow a content author to have any item in the tree highlighted and to create an HTML file based on that item’s default presentation:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7JqBWIGteI/AAAAAAAABH0/2yPNYURcAFQ/s1600-h/image2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_JjsHfCZ5On8/S7JqBjsWmuI/AAAAAAAABH4/mhgV3qN6EIA/image_thumb.png?imgmax=800" width="101" height="64" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Since I decided to place the command in the Preview chunk, the item in my Core database is at:&lt;/p&gt;  &lt;p&gt;/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Preview/CreateHTMLFile&lt;/p&gt;  &lt;p&gt;The command item looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/S7JqCNnExgI/AAAAAAAABH8/dIcGqx7rdgs/s1600-h/image4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_JjsHfCZ5On8/S7JqCu-QL2I/AAAAAAAABIA/C9wxgfxXnm4/image_thumb2.png?imgmax=800" width="561" height="408" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And the command is included in App_Config/Commands.config&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/S7JqCy3MbTI/AAAAAAAABIE/Q0WP84cX3fg/s1600-h/image8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S7JqDQ96QXI/AAAAAAAABII/3WYq0uu6UCs/image_thumb4.png?imgmax=800" width="668" height="130" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So the command calls a simple class where we’ll request the response based on the default presentation for the item.&amp;#160; The assumption here is that the item is published and available at the default url based on its location in the content tree.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;Examples&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;UrlReaderWriter &lt;/span&gt;: Sitecore.Shell.Framework.Commands.&lt;span style="color: #2b91af"&gt;Command&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;       &lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// &lt;/span&gt;&lt;span style="color: green"&gt;This command will create an HTML file based on a request to the currently selected item as it is responded to from the public site (Web)&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: gray"&gt;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name=&amp;quot;context&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt; &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;Execute(Sitecore.Shell.Framework.Commands.&lt;span style="color: #2b91af"&gt;CommandContext &lt;/span&gt;context)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: blue"&gt;if &lt;/span&gt;(context.Items.Length == 1)&lt;br /&gt;            {&lt;br /&gt;                Sitecore.Data.Items.&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;thisItem = context.Items[0];&lt;br /&gt;                Sitecore.Data.&lt;span style="color: #2b91af"&gt;Database &lt;/span&gt;web = Sitecore.Data.&lt;span style="color: #2b91af"&gt;Database&lt;/span&gt;.GetDatabase(&lt;span style="color: #a31515"&gt;&amp;quot;web&amp;quot;&lt;/span&gt;);&lt;br /&gt;                Sitecore.Data.Items.&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;webItem = web.GetItem(thisItem.ID);&lt;br /&gt;             &lt;br /&gt;                &lt;span style="color: blue"&gt;string &lt;/span&gt;itemUrl;&lt;br /&gt;                &lt;span style="color: blue"&gt;if &lt;/span&gt;(webItem != &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;                {&lt;br /&gt;                    &lt;br /&gt;                    itemUrl = Sitecore.Links.&lt;span style="color: #2b91af"&gt;LinkManager&lt;/span&gt;.GetItemUrl(webItem);&lt;br /&gt;                    &lt;span style="color: blue"&gt;string &lt;/span&gt;url = itemUrl.Replace(&lt;span style="color: #a31515"&gt;&amp;quot;/sitecore/shell/&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;);&lt;br /&gt;                    WriteFile(thisItem.Name, LoadSiteContents(url));&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;             &lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;public static string &lt;/span&gt;LoadSiteContents(&lt;span style="color: blue"&gt;string &lt;/span&gt;url)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;//create a new WebRequest object&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;WebRequest &lt;/span&gt;request = &lt;span style="color: #2b91af"&gt;WebRequest&lt;/span&gt;.Create(url);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;//create StreamReader to hold the returned request&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StreamReader &lt;/span&gt;stream = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StreamReader&lt;/span&gt;(request.GetResponse().GetResponseStream());&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;//StringBuilder to hold info from the request&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StringBuilder &lt;/span&gt;builder = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;StringBuilder&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: blue"&gt;try&lt;br /&gt;            &lt;/span&gt;{&lt;br /&gt;                &lt;span style="color: green"&gt;//now loop through the response&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: blue"&gt;while &lt;/span&gt;(!(stream.Peek() == 0))&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: green"&gt;//now make sure we're not looking at a blank line&lt;br /&gt;                    //if (stream.ReadLine().Length != null &amp;amp;&amp;amp; stream.ReadLine().Length &amp;gt; 0) builder.Append(stream.ReadLine()); &lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;(stream.ReadLine().Length &amp;gt; 0) builder.Append(stream.ReadLine());&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: blue"&gt;catch &lt;/span&gt;{ }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;//close up the StreamReader&lt;br /&gt;            &lt;/span&gt;stream.Close();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;//return the information&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;builder.ToString();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: blue"&gt;public static void &lt;/span&gt;WriteFile(&lt;span style="color: blue"&gt;string &lt;/span&gt;itemName, &lt;span style="color: blue"&gt;string &lt;/span&gt;fileText)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: green"&gt;// Write the string to a file.&lt;br /&gt;            &lt;/span&gt;System.IO.&lt;span style="color: #2b91af"&gt;StreamWriter &lt;/span&gt;file = &lt;span style="color: blue"&gt;new &lt;/span&gt;System.IO.&lt;span style="color: #2b91af"&gt;StreamWriter&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;HttpContext&lt;/span&gt;.Current.Server.MapPath(&lt;span style="color: #a31515"&gt;&amp;quot;~/App_Data/&amp;quot; &lt;/span&gt;+ itemName + &lt;span style="color: #a31515"&gt;&amp;quot;.html&amp;quot;&lt;/span&gt;));&lt;br /&gt;            file.WriteLine(fileText);&lt;br /&gt;            file.Close();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Some obvious things that this code needs:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;A better read of John West’s &lt;a href="http://sdn.sitecore.net/Reference/Sitecore%206/Dynamic%20Links.aspx"&gt;Dynamic Links Document&lt;/a&gt; to avoid the string replace for the URL.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;A better place to invoke this.&amp;#160; A button in Content Editor is OK….but better yet, this fits into the Publishing event to create files when necessary (based on data template, branch of the tree, etc.).&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;A better strategy than creating a WebRequest.&amp;#160; In reality, this would be interesting to build from the content in the Master db (get a snapshot of what is actually being published, maybe in contrast to what is currently in the Web db).&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;  &lt;li&gt;More variables (a drop-down added to the control button, for instance) where I can define the criteria for the presentation I’m trying to retrieve—device, OMS persona, security role, etc.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;But, I told you this was a cheap piece of demoware…you’re up!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-3920571184624680746?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3920571184624680746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3920571184624680746'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2010/03/thinking-about-static-files.html' title='Thinking about static files'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_JjsHfCZ5On8/S7JqBjsWmuI/AAAAAAAABH4/mhgV3qN6EIA/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-5326915241074213045</id><published>2010-01-18T12:18:00.001-05:00</published><updated>2010-01-18T12:18:52.401-05:00</updated><title type='text'>Adding Rendering Parameters to a Server Control</title><content type='html'>&lt;p&gt;Something I missed along the way is the ease with which you can add rendering parameters to a server control.&amp;#160; Many of the examples we use in training use content items to show how easily the values that a control renders can be changed by a content author.&amp;#160; Many times the update makes a lot of sense to become a parameter in the layout details themselves.&lt;/p&gt;  &lt;p&gt;Let’s take the example of the Footer control (Footer.cs) that is used in Sitecore developer training and is part of both the Starter Kit and Office Core example sites.&amp;#160; The Footer control looks to the content tree for its values.&amp;#160; A “Copyright” item allows content authors to affect the values that appear in the footer of the page:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/S1SX2jb45xI/AAAAAAAABG4/KxGlCWtuEaU/s1600-h/image3.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/S1SX4VSWFXI/AAAAAAAABG8/L6vpGwHoJzI/image_thumb1.png?imgmax=800" width="534" height="333" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Let’s assume that, in addition to wanting to define the actual text in the Copyright (year, holder, text, etc), we want our content authors to define whether or not the link to the Terms of Use should appear in the footer at all.&amp;#160; Now, this could certainly be accomplished in many ways.&amp;#160; An addition of a checkbox field (“Include Link Text”, for instance) on the Copyright item itself would allow the Footer control to show this link or not depending on a content author’s wishes.&amp;#160; For this example, though, let’s do it as part of the attributes of the control itself, in the hopes of a simple example leading to more complex real-world solutions.&lt;/p&gt;  &lt;p&gt;The Footer control item (under Layout—&amp;gt;Renderings—&amp;gt;Footer Control) has a field in the Editor Options section that allows us to define the Presentation Template that will drive our new attribute:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/S1SX5hzlZmI/AAAAAAAABHA/wPuR1jtzusA/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_JjsHfCZ5On8/S1SX61Ss-XI/AAAAAAAABHE/7nD0S7JGHGo/image_thumb%5B2%5D.png?imgmax=800" width="546" height="421" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, we can define a new template to hold these presentation attributes.&amp;#160; For our simple example, we’ll only define one—a checkbox field that will allow a content author (or more accurately a page designer….someone responsible now for the look and feel of the site) to decide whether or not our link text will appear on pages that use this Footer control.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/S1SX7vuongI/AAAAAAAABHI/xRBJKzTUgqI/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_JjsHfCZ5On8/S1SX8ZtFbcI/AAAAAAAABHM/axxXzoHTaXY/image_thumb%5B3%5D.png?imgmax=800" width="603" height="122" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This new template inherits from the&lt;em&gt;&lt;strong&gt; /sitecore/templates/System/Layout/Rendering Parameters/Standard Rendering Parameters&lt;/strong&gt;&lt;/em&gt; template.&amp;#160; We add our new IncludeTermsOfUse field to it.&lt;/p&gt;  &lt;p&gt;N0w, if we choose to add the Footer control to a page, we can also set this new attribute:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/S1SX9gKeDEI/AAAAAAAABHQ/vetMOLBKOv4/s1600-h/image%5B12%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_JjsHfCZ5On8/S1SX-rKj_-I/AAAAAAAABHU/ePEAkjs5mbM/image_thumb%5B5%5D.png?imgmax=800" width="525" height="376" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And do a simple check for its value in our presentation code:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// ...Link to &amp;quot;Terms of Use&amp;quot; text&lt;br /&gt;           &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;link_text = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;           &lt;span style="color: blue"&gt;if &lt;/span&gt;(IncludeTermsOfUse==&lt;span style="color: #a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;)&lt;br /&gt;               link_text = &lt;span style="color: #2b91af"&gt;FieldRenderer&lt;/span&gt;.Render(copyright_item, _linkTextField);&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-5326915241074213045?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5326915241074213045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5326915241074213045'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2010/01/adding-rendering-parameters-to-server.html' title='Adding Rendering Parameters to a Server Control'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_JjsHfCZ5On8/S1SX4VSWFXI/AAAAAAAABG8/L6vpGwHoJzI/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-8197705163404917389</id><published>2009-11-24T08:32:00.002-05:00</published><updated>2009-11-24T08:53:22.708-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rules'/><category scheme='http://www.blogger.com/atom/ns#' term='Conditions'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore OMS'/><category scheme='http://www.blogger.com/atom/ns#' term='OMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Actions'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>An OMS Rules Engine Example</title><content type='html'>Many of you have now at least seen a demonstration of the Sitecore Online Marketing Suite capabilities.&amp;nbsp; If not, make sure you contact us so we can show you the power of the personalization engine now central to the product.&amp;nbsp; In today’s discussion, I will go through a complete (albeit simple) example of what you can do with Rules Engine.&amp;nbsp; If you are a developer, this will get you started with the mechanics involved in hooking things up.&amp;nbsp; If you are a business champion, you will see the flexibility to match personalization rules with whatever business rules challenges you face.&lt;br /&gt;First, some terms:&lt;br /&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;&lt;span style="font-size: large;"&gt;Conditions&lt;/span&gt;&lt;/strong&gt; are tied to &lt;strong&gt;&lt;span style="font-size: large;"&gt;Actions&lt;/span&gt; &lt;/strong&gt;by&lt;strong&gt; &lt;span style="font-size: large;"&gt;Rules&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;Sitecore has generously provided quite a few conditions, many derived from the reverse DNS lookup functionality….things like:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgXgfhNZI/AAAAAAAABD8/ITeosdVn6IY/s1600-h/image%5B3%5D.png"&gt;&lt;img alt="image" border="0" height="334" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgXz0NaNI/AAAAAAAABEA/oxk196haE0g/image_thumb%5B1%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="569" /&gt;&lt;/a&gt; &lt;br /&gt;…but these conditions are all yours to define (like everything in Sitecore, you have complete flexibility to define your own items in the tree and these items can be representative of your own business logic).&lt;br /&gt;So, let’s take an oversimplified example:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;We want to send an Alert to a Web site visitor&lt;/li&gt;&lt;li&gt;The Alert should only be sent to someone who visits a News story (an item based on the News Article Data Template)&lt;/li&gt;&lt;li&gt;The Alert should only be sent on a particular day of the week, and a content author should be able to pick the day&lt;/li&gt;&lt;li&gt;The Alert should use an editable field of the News story as the message&lt;/li&gt;&lt;/ol&gt;Let’s look at the rules we have by default to start putting together the Conditions that will trigger this alert.&amp;nbsp; If we scroll down to the bottom of the Rule Set Editor (you get here by clicking Edit Rule in the Marketing Center when you’re working with an item based on a Rule template), we see the “Common” conditions:&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgYODITeI/AAAAAAAABEE/Oyr3OdNiIiU/s1600-h/image%5B7%5D.png"&gt;&lt;img alt="image" border="0" height="168" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgYhjhapI/AAAAAAAABEI/CPnH0cb_ozk/image_thumb%5B3%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="507" /&gt;&lt;/a&gt; &lt;br /&gt;(You won’t see “where today is a specific day of the week”…that’s the one we’ll add).&amp;nbsp; You will see “where item has specific template”.&amp;nbsp; Great.&amp;nbsp; That takes care of 1/2 of the condition.&amp;nbsp; Let’s investigate how this Common condition came to be.&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgY7Ycy1I/AAAAAAAABEM/c99m8m7Ugt8/s1600-h/image%5B11%5D.png"&gt;&lt;img alt="image" border="0" height="322" src="http://lh5.ggpht.com/_JjsHfCZ5On8/SwvgZOHlMFI/AAAAAAAABEQ/SE4VmI4XXYs/image_thumb%5B5%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="629" /&gt;&lt;/a&gt; &lt;br /&gt;Under System—&amp;gt;Settings—&amp;gt;Rules—&amp;gt;Common—&amp;gt;Conditions, we find this When Template Rule.&amp;nbsp; We see that the Class called (Type) is included in the 6.1 Kernel.&amp;nbsp; We know from other extensibility exercises (adding functionality to UI events, workflow, validation, etc.) that calling our own Class and business logic is very easily done.&amp;nbsp; For now, let’s look at the Text field of the existing Condition.&lt;br /&gt;where item has [templateid, Tree, root=/sitecore/templates, specific] template.&lt;br /&gt;Here is how the Rule will look when I add it in the Marketing Center:&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgZQ57zBI/AAAAAAAABEU/teDsc4tfR9c/s1600-h/image%5B15%5D.png"&gt;&lt;img alt="image" border="0" height="527" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgZ_ohGsI/AAAAAAAABEc/HpQosxGGQGs/image_thumb%5B7%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="434" /&gt;&lt;/a&gt; &lt;br /&gt;Notice that the word &lt;strong&gt;where&lt;/strong&gt; was automatically changed to a hyperlink.&amp;nbsp; Clicking this in the Rule Set Editor will automatically reverse the condition to &lt;strong&gt;except where&lt;/strong&gt;.&amp;nbsp; The Rule Set Editor will do this for &lt;strong&gt;where&lt;/strong&gt;, &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;if&lt;/strong&gt; clauses.&amp;nbsp; The other link is the word &lt;strong&gt;specific &lt;/strong&gt;which appears until we have chosen a specific Data Template to use for this Condition.&amp;nbsp; From the original Text field above, the 4 parameters are as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;templateid&lt;/em&gt;&lt;/strong&gt; is the name of the property that will be set in the .NET Class (Sitecore.Rules.Conditions.WhenTemplateIs)&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;Tree&lt;/em&gt;&lt;/strong&gt; is the name of a Macro that will be run in the UI.&amp;nbsp; Tree is one of the preset Macros, and will invoke the Content tree window where we can select the Data Template&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;root=/sitecore/templates&lt;/em&gt;&lt;/strong&gt; is the URL parameter sent to the UI invoked by the Tree macro and will become the source, or top level of the tree that we see as we are asked to select the Data Template&lt;/li&gt;&lt;div class="wlWriterEditableSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ba23a751-f0d6-4ffb-8b0f-d34ab0575454" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;Technorati Tags: &lt;/div&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;specific&lt;/em&gt;&lt;/strong&gt; is the text that is displayed before we select a value for this parameter (the Data Template)&lt;/li&gt;&lt;/ul&gt;Completing this part of the condition is easy…we simply select the News Article Data Template:&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgaFff2QI/AAAAAAAABEg/f_gOuiGb0Cs/s1600-h/image%5B19%5D.png"&gt;&lt;img alt="image" border="0" height="500" src="http://lh4.ggpht.com/_JjsHfCZ5On8/Swvgae4_J3I/AAAAAAAABEk/TpiZAw0SxJY/image_thumb%5B9%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="500" /&gt;&lt;/a&gt; &lt;br /&gt;Now, the second part of the condition requires us to invoke some of our own business logic.&amp;nbsp; We want to evaluate whether or not today is a certain day of the week, and we want the marketer setting the rule to be able to choose the day.&amp;nbsp; Let’s make some simple content items that represent the days of the week to allow for this choice:&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/Swvgai1Zn1I/AAAAAAAABEo/w1P_pPbP8gI/s1600-h/image%5B30%5D.png"&gt;&lt;img alt="image" border="0" height="148" src="http://lh6.ggpht.com/_JjsHfCZ5On8/Swvga68zFMI/AAAAAAAABEs/LFpWNfCPYiI/image_thumb%5B16%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="288" /&gt;&lt;/a&gt; &lt;br /&gt;These items don’t need any fields…we’ll just use their names to evaluate the day of the week.&amp;nbsp; Now we need to set up a new Condition definition:&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/SwvgbXdIYNI/AAAAAAAABEw/UTsfeJe4_Aw/s1600-h/image%5B29%5D.png"&gt;&lt;img alt="image" border="0" height="160" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgbtZhnkI/AAAAAAAABE0/kKC3roMZQ5c/image_thumb%5B15%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="615" /&gt;&lt;/a&gt; &lt;br /&gt;From our discussion above, we can now see that these parameters in the Text field will invoke the &lt;strong&gt;&lt;em&gt;Tree&lt;/em&gt;&lt;/strong&gt; Macro and allow the Marketer to choose from the days of the week Items.&amp;nbsp; The .NET Class (our new &lt;em&gt;&lt;strong&gt;WhenDay&lt;/strong&gt;&lt;/em&gt; Class) will have the &lt;em&gt;&lt;strong&gt;itemid&lt;/strong&gt;&lt;/em&gt; property set by this day of the week Item choice.&lt;br /&gt;For the developers, let’s take a look at the new WhenDay class.&amp;nbsp; It inherits from the Sitecore WhenCondition class to return a Boolean condition (whether or not today is the chosen day of the week).&amp;nbsp; Notice the itemid property that is set by selecting the Item.&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Rules;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Diagnostics;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Data;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Data.Items;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Rules.Conditions;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;namespace &lt;/span&gt;Examples&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;WhenDay&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: #2b91af;"&gt;WhenCondition&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span style="color: blue;"&gt;where &lt;/span&gt;T: &lt;span style="color: #2b91af;"&gt;RuleContext&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ID &lt;/span&gt;itemid;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;WhenDay()&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;.itemid = &lt;span style="color: #2b91af;"&gt;ID&lt;/span&gt;.Null;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;protected override bool &lt;/span&gt;Execute(T ruleContext)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: #2b91af;"&gt;Assert&lt;/span&gt;.ArgumentNotNull(ruleContext, &lt;span style="color: #a31515;"&gt;"ruleContext"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #2b91af;"&gt;Item &lt;/span&gt;item = ruleContext.Item;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(item != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: #2b91af;"&gt;Item &lt;/span&gt;item2 = item.Database.GetItem(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.ItemId);&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(item2 == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;return false&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(System.&lt;span style="color: #2b91af;"&gt;DateTime&lt;/span&gt;.Today.DayOfWeek.ToString() == item2.Name)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;return true&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: blue;"&gt;return false&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: green;"&gt;// Properties&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ID &lt;/span&gt;ItemId&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;get&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;return this&lt;/span&gt;.itemid;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: blue;"&gt;set&lt;br /&gt;&lt;/span&gt;{&lt;br /&gt;&lt;span style="color: #2b91af;"&gt;Assert&lt;/span&gt;.ArgumentNotNull(&lt;span style="color: blue;"&gt;value&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"value"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;this&lt;/span&gt;.itemid = &lt;span style="color: blue;"&gt;value&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we can finish our condition by adding the day of the week clause:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgcPfjqWI/AAAAAAAABE4/mwcTjQlPl7o/s1600-h/image%5B34%5D.png"&gt;&lt;img alt="image" border="0" height="398" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgcXtrAdI/AAAAAAAABE8/fVRaWHDzmVI/image_thumb%5B18%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="492" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With the &lt;strong&gt;Condition&lt;/strong&gt; completed, our &lt;strong&gt;Rule&lt;/strong&gt; can be completed by calling out an &lt;strong&gt;Action&lt;/strong&gt; to perform.&amp;nbsp; You can see some of the default Actions we could perform here….hiding a rendering, setting a placeholder for a rendering, changing the Data Source for a rendering, etc.&amp;nbsp; To simplify the example of invoking your own business rules, I simply created a class that sends a JavaScript Alert message to the visitor, using the Menu Tooltip field of the News Article as the message.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/Swvgcu8k1XI/AAAAAAAABFA/uEsiCx5ck6U/s1600-h/image%5B38%5D.png"&gt;&lt;img alt="image" border="0" height="227" src="http://lh3.ggpht.com/_JjsHfCZ5On8/Swvgc1CAhpI/AAAAAAAABFE/1eQ1pmPUo1o/image_thumb%5B20%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="558" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With the &lt;strong&gt;Action&lt;/strong&gt; created, we can now complete our &lt;strong&gt;Rule&lt;/strong&gt;, tying the &lt;strong&gt;Conditions&lt;/strong&gt; of the News Article Data Template and the chosen day of the week to the Alert &lt;strong&gt;Action:&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgdGybllI/AAAAAAAABFI/9evvZidLzJU/s1600-h/image%5B42%5D.png"&gt;&lt;img alt="image" border="0" height="255" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SwvgdQr6SzI/AAAAAAAABFM/haU98ZYWQho/image_thumb%5B22%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="559" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And the Marketer can add a quick Alert to the page he is responsible for:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/Swvgd7JVExI/AAAAAAAABFQ/Dd2BK0nwi7Y/s1600-h/image%5B46%5D.png"&gt;&lt;img alt="image" border="0" height="139" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgeEgoQUI/AAAAAAAABFU/zkwApiNJalY/image_thumb%5B24%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="526" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/SwvgeDhlLNI/AAAAAAAABFY/Vc-cBI3NfdM/s1600-h/image%5B50%5D.png"&gt;&lt;img alt="image" border="0" height="127" src="http://lh5.ggpht.com/_JjsHfCZ5On8/SwvgeuMTrJI/AAAAAAAABFc/us6_fOGDK1Q/image_thumb%5B26%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="313" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-8197705163404917389?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8197705163404917389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8197705163404917389'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/11/oms-rules-engine-example.html' title='An OMS Rules Engine Example'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_JjsHfCZ5On8/SwvgXz0NaNI/AAAAAAAABEA/oxk196haE0g/s72-c/image_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-3576454158001746268</id><published>2009-11-09T11:17:00.002-05:00</published><updated>2009-11-24T08:52:48.910-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Edit Frames'/><category scheme='http://www.blogger.com/atom/ns#' term='Nicam'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6.1'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>An Example of using Edit Frames in Nicam</title><content type='html'>For those of you that work with, or used to work with, 5.3 Green Dots Web Edit functionality, you might really appreciate the ease with which you can create contextual editing menus.&amp;nbsp; The 6.0 Page Editor (with all its significant usability features and improvements) might have left you questioning your ability to implement the same contextual functionality.&amp;nbsp; Enter Edit Frames as of 6.1, a great new feature that should have you dreaming up some incredibly focused Page Editor-based contextual editing functionality.&lt;br /&gt;John West, as always, has a great description of this functionality &lt;a href="http://sitecorejohn.spaces.live.com/blog/cns!960125F1D4A59952!384.entry"&gt;here&lt;/a&gt;.&lt;br /&gt;For my discussion today, I wanted to show a couple of quick examples of where this could be used.&amp;nbsp; As you know, Sitecore Data Templates promote the encapsulation of complex content types.&amp;nbsp; Some fields in these Data Templates are presentation-driven (Short Description, Image), while others are meta-driven (Rating, Keywords, Category).&amp;nbsp; The Content Editor interface shows all fields on both sides of this fence in a comprehensive, section-organized form view.&amp;nbsp; In Page Editor, we get the very handy inline frame editing of all presented fields.&amp;nbsp; But what about those meta-fields behind the scenes?&amp;nbsp; Page Editor presents the “Blue Boxes” to split the screen and get to those fields behind the presented page.&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhARggvBYI/AAAAAAAABCs/yJXom4R4hvU/s1600-h/image%5B7%5D.png"&gt;&lt;img alt="image" border="0" height="191" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SvhASoj8nvI/AAAAAAAABCw/PGkOnQCkQ9U/image_thumb%5B3%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="476" /&gt;&lt;/a&gt; &lt;br /&gt;Clicking on Edit the related item splits the screen and allows us to navigate the sections of fields that make up the News Article Data Template:&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_JjsHfCZ5On8/SvhATi2lrPI/AAAAAAAABC0/dKjBuqZQGrI/s1600-h/image%5B3%5D.png"&gt;&lt;img alt="image" border="0" height="306" src="http://lh5.ggpht.com/_JjsHfCZ5On8/SvhAUiLS9wI/AAAAAAAABC4/MQOTkkj_osc/image_thumb%5B1%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="581" /&gt;&lt;/a&gt; &lt;br /&gt;While this is intuitive and simple, we’re always striving to make this Page Editor experience as streamlined as possible.&amp;nbsp; Instead of splitting the screen and having to find a field (within what could be a very complex Data Template), it would certainly be nice to define the field(s) that the editor would be most interested in getting to, and to simplify and focus the editing interface even more.&lt;br /&gt;Edit Frames allow for just that.&amp;nbsp; Let’s take this same example.&amp;nbsp; We’re editing a News Article (Nicam Camera K200D) that has fields for Title, Short Description, Image, etc.&amp;nbsp; Via the Online Marketing Suite, we article authors also want to tag this piece with the appropriate keywords that match up to our profile keys.&amp;nbsp; Let’s build an Edit Frame around the article’s title that allows us to see the checklist of Keywords with which to tag this article.&lt;br /&gt;First, we need to define the Buttons that will be part of our Edit Frame contextual menu.&amp;nbsp; Sitecore provides a couple of handy default buttons (Insert and Edit).&amp;nbsp; For today, we’ll simply use the default behavior of Edit Field, but for you developers, you can already imagine that any command functionality can be invoked here.&amp;nbsp; The Buttons themselves are defined in the Core database (very much like the commands available to the Rich Text Editor).&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAV2I6mUI/AAAAAAAABC8/Fy6AFWLOw58/s1600-h/image%5B10%5D.png"&gt;&lt;img alt="image" border="0" height="161" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SvhAW3kg2cI/AAAAAAAABDA/_XP4AvAh704/image_thumb%5B4%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="244" /&gt;&lt;/a&gt; &lt;br /&gt;Switching to the Core database and navigating to /sitecore/content/Applications/WebEdit/Edit Frame Buttons will show us all Edit Frame toolbars configured for the site.&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAXju_dsI/AAAAAAAABDE/1T9h46Xk67o/s1600-h/image%5B16%5D.png"&gt;&lt;img alt="image" border="0" height="244" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SvhAYfZpMYI/AAAAAAAABDI/IXxP9v2kZls/image_thumb%5B6%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="226" /&gt;&lt;/a&gt; &lt;br /&gt;The system is installed with the Default toolbar in place.&amp;nbsp; If an Edit Frame does not specifically call out a Buttons property, the Default is used.&amp;nbsp; Let’s copy the Default item, paste it under Edit Frame Buttons, and rename it Keywords.&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAZUIoujI/AAAAAAAABDM/ugT_y7QPcvE/s1600-h/image%5B20%5D.png"&gt;&lt;img alt="image" border="0" height="277" src="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAaaIEXqI/AAAAAAAABDQ/1hVkuh3IqUo/image_thumb%5B8%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="420" /&gt;&lt;/a&gt; &lt;br /&gt;If you select the newly renamed Keywords item, you’ll see that the Edit Frame toolbar has fields for a Title and Tooltip.&amp;nbsp; Expand the Keywords item to reveal the default Buttons available to it.&amp;nbsp; We’re using the Edit Button (you can delete this Insert button), and selecting it shows the fields available to the Field Editor Button template that it is based on.&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAbMj5f2I/AAAAAAAABDU/gx48ZrSk5eA/s1600-h/image%5B24%5D.png"&gt;&lt;img alt="image" border="0" height="266" src="http://lh5.ggpht.com/_JjsHfCZ5On8/SvhAcE3I3HI/AAAAAAAABDY/GPyPdjRfHgs/image_thumb%5B10%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="431" /&gt;&lt;/a&gt; &lt;br /&gt;The Fields field allows a pipe-separated list of fields that will become readily available to the Page Editor.&amp;nbsp; For our example, we’re using only one:&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/SvhAdFKIkLI/AAAAAAAABDc/OJKntG_3isU/s1600-h/image%5B28%5D.png"&gt;&lt;img alt="image" border="0" height="189" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SvhAd9HIpeI/AAAAAAAABDg/-EefZhQLjuk/image_thumb%5B12%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="444" /&gt;&lt;/a&gt; &lt;br /&gt;Now, with the toolbar in place and configured, we simply need to add the Edit Frame to a presentation control.&amp;nbsp; This Edit Frame can be added, of course, to a .NET or XSLT control.&amp;nbsp; Since the news article already has a NewsItem xslt to present its fields, let’s add the frame there:&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:template &lt;/span&gt;&lt;span style="color: red;"&gt;match&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;*&lt;/span&gt;" &lt;span style="color: red;"&gt;mode&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;main&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sc:editFrame &lt;/span&gt;&lt;span style="color: red;"&gt;Buttons&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;/sitecore/content/Applications/WebEdit/Edit Frame Buttons/Keywords&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;h1&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sc:text &lt;/span&gt;&lt;span style="color: red;"&gt;field&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Title&lt;/span&gt;" &lt;span style="color: red;"&gt;select&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;.&lt;/span&gt;" &lt;span style="color: blue;"&gt;/&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;h1&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;sc:editFrame&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Notice the Buttons property calls out the path in the Core database to the Keywords toolbar we set up.&amp;nbsp; The &amp;lt;sc:editFrame&amp;gt; itself will present hover-over region including any HTML we wrap it with:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_JjsHfCZ5On8/SvhAeokU7lI/AAAAAAAABDk/UVJiuVatygk/s1600-h/image%5B32%5D.png"&gt;&lt;img alt="image" border="0" height="113" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SvhAfrWUjWI/AAAAAAAABDo/4RmFjflA9tY/image_thumb%5B14%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="453" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Clicking on the new Keywords (Default Title of the Keywords toolbar itself) drop-down shows us any buttons within the Toolbar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/SvhAgLLMGcI/AAAAAAAABDs/ooVm1zYW0aY/s1600-h/image%5B36%5D.png"&gt;&lt;img alt="image" border="0" height="80" src="http://lh4.ggpht.com/_JjsHfCZ5On8/SvhAg4gQ0UI/AAAAAAAABDw/mN6Os14_k-8/image_thumb%5B16%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="455" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And now we can easily edit the Keywords checklist field:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_JjsHfCZ5On8/SvhAh8ClenI/AAAAAAAABD0/0zfOR8vvqRo/s1600-h/image%5B41%5D.png"&gt;&lt;img alt="image" border="0" height="322" src="http://lh6.ggpht.com/_JjsHfCZ5On8/SvhAiqSPDkI/AAAAAAAABD4/WYecpLgkdYM/image_thumb%5B19%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline;" title="image" width="488" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That’s all there is to it.&amp;nbsp; This article simply covered the mechanics…now we can think through the many creative places where this technique makes sense to make the Page Editor even more powerful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-3576454158001746268?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3576454158001746268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3576454158001746268'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/11/example-of-using-edit-frames-in-nicam.html' title='An Example of using Edit Frames in Nicam'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_JjsHfCZ5On8/SvhASoj8nvI/AAAAAAAABCw/PGkOnQCkQ9U/s72-c/image_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-3057933519603960977</id><published>2009-09-04T17:06:00.004-04:00</published><updated>2009-11-24T08:52:17.441-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='integration'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore API'/><title type='text'>Some simple API code to insert Sitecore content items</title><content type='html'>Derek Roberti, Sitecore Director of Technical Services, recently put together an excellent paper on a question we often discuss in various sales and technical services conversations:&amp;nbsp; how are we going to integrate our external data with Sitecore?&amp;nbsp; While Derek’s paper does a much better job at getting to the very important details around this subject, I’d like to create a snippet today that illustrates one simple and fundamental concept to matching up external data with Sitecore data templates.&lt;br /&gt;I like to divide the discussion of integration of external data sources with the Sitecore content tree into the various "buckets" these integrations can fall into (there are more).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Presentation level integration, where standard controls coordinate fields from the CMS item with data from external sources (Web Service calls, db queries, enterprise system APIs, etc).&amp;nbsp; Often a key value (productID) allows the storage of descriptive, marketing-driven data in Sitecore, while allowing pricing and availability to remain the realm of the ERP system designed for its maintenance and accessibility.&amp;nbsp; This integration doesn’t require any API method in Sitecore, since no data is moved into the CMS—after presentation, the link is no longer necessary.&lt;/li&gt;&lt;li&gt;Content editor level integration, where lists and other data stored in external systems are referenced by content editors as they maintain Sitecore CMS items.&amp;nbsp; Custom editing interfaces, drop down and tree lists, etc. lookup values stored in external tables for the purposes of choosing values that will be stored in the CMS.&lt;/li&gt;&lt;li&gt;Data provider level integration, where permanent mappings exist between Sitecore data template fields and fields of an external system.&amp;nbsp; Data continues to be maintained in its native system, while the Sitecore content tree exposes these data as native to Sitecore.&amp;nbsp; Items take advantage of externally manageable fields of data while also taking advantage of native Sitecore functionality, validation, workflow, security and more.&lt;/li&gt;&lt;/ul&gt;Somewhere in the middle bullet (or maybe prevalent enough to be its own) is the simple need to map existing data to Data Template fields in the effort to create new Sitecore content items.&amp;nbsp; This is certainly an important stage of many migration projects, where current enterprise content (whatever its current format or storage mechanism) needs to be mapped to the new and well-thought out Sitecore-enabled information architecture.&lt;br /&gt;While this subject is an article in of itself, the effort can often be broken down to its main stages.&amp;nbsp; The purpose of this snippet is not to belittle the complexity and importance of any of these stages—deciding on an efficient mapping between current information and Sitecore Data Templates deserves the appropriate amount of&amp;nbsp;time, skill and effort.&amp;nbsp; Instead, I wanted to end with a quick code sample that shows the stages quickly.&amp;nbsp; This example simply takes in an XML node as a parameter (representing an external RSS Feed), parses the feed and maps a couple of its fields to our newly created Sitecore Data Template, inserting new items under the “News” section of the content tree.&amp;nbsp; &lt;br /&gt;The main stages:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Analyze current content, information, organization of data.&lt;/li&gt;&lt;li&gt;Create data template(s) in Sitecore to map current organization, taking advantage of Sitecore’s granular field types to encapsulate reusable components.&lt;/li&gt;&lt;li&gt;Identify the area of the content tree where this content will be inserted.&lt;/li&gt;&lt;li&gt;Map existing data to Data Template fields and create items under the appropriate parent.&lt;/li&gt;&lt;li&gt;Rinse and repeat.&lt;/li&gt;&lt;/ol&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;private void &lt;/span&gt;CreateRssItems(&lt;span style="color: #2b91af;"&gt;XmlNode &lt;/span&gt;rssItem)&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: green;"&gt;// login in as an admin User&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: blue;"&gt;new &lt;/span&gt;Sitecore.SecurityModel.&lt;span style="color: #2b91af;"&gt;SecurityDisabler&lt;/span&gt;())&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: green;"&gt;// The ContentDatabase points to the Master database.&lt;br /&gt;// This assumes that this code runs in the Sitecore client.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Item &lt;/span&gt;News = Sitecore.&lt;span style="color: #2b91af;"&gt;Context&lt;/span&gt;.Database.GetItem(&lt;span style="color: #a31515;"&gt;"/sitecore/content/Home/News"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(News != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;// add a new Item based on  the Document Template&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;title = rssItem.SelectSingleNode(&lt;span style="color: #a31515;"&gt;"title"&lt;/span&gt;).InnerText;&lt;br /&gt;title = &lt;span style="color: #2b91af;"&gt;Regex&lt;/span&gt;.Replace(title, &lt;span style="color: #a31515;"&gt;@"[\[\]?:\/*""&amp;lt;&amp;gt;|]"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;""&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: blue;"&gt;string &lt;/span&gt;description = rssItem.SelectSingleNode(&lt;span style="color: #a31515;"&gt;"description"&lt;/span&gt;).InnerText;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;// optionally, you can do this by referring to the content tree path&lt;br /&gt;// of the data template you will use to map fields&lt;br /&gt;&lt;/span&gt;Sitecore.Data.Items.&lt;span style="color: #2b91af;"&gt;Item &lt;/span&gt;NewRssItem = &lt;br /&gt;News.Add(title, Sitecore.&lt;span style="color: #2b91af;"&gt;Context&lt;/span&gt;.Database.GetTemplate(&lt;span style="color: #a31515;"&gt;"{A18D8CDE-AD94-4F84-BB74-648B20FE739A}"&lt;/span&gt;));&lt;br /&gt;&lt;span style="color: blue;"&gt;if &lt;/span&gt;(NewRssItem != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;// optionally, impersonate a user with appropriate security priveleges&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: blue;"&gt;new &lt;/span&gt;Sitecore.SecurityModel.&lt;span style="color: #2b91af;"&gt;SecurityDisabler&lt;/span&gt;())&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;(&lt;span style="color: blue;"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;EditContext&lt;/span&gt;(NewRssItem))&lt;br /&gt;{&lt;br /&gt;NewRssItem.Fields[&lt;span style="color: #a31515;"&gt;"Title"&lt;/span&gt;].Value = title;&lt;br /&gt;NewRssItem.Fields[&lt;span style="color: #a31515;"&gt;"Description"&lt;/span&gt;].Value = description;&lt;br /&gt;NewRssItem.Fields[&lt;span style="color: #a31515;"&gt;"__Display Name"&lt;/span&gt;].Value = title; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-3057933519603960977?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3057933519603960977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/3057933519603960977'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/09/some-simple-api-code-to-insert-sitecore.html' title='Some simple API code to insert Sitecore content items'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-4041974106033959659</id><published>2009-09-04T16:31:00.003-04:00</published><updated>2009-11-24T08:51:49.741-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web Forms for Marketers'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>One of those custom Web Forms for Marketers actions</title><content type='html'>I often have discussions with prospects and clients around the ease with which you can create custom submit actions for the Web Forms for Marketers module.&amp;nbsp; I finally had the opportunity to go through the mechanics and jot down the steps. &lt;br /&gt;Because of the great, simple, consistent Item paradigm in Sitecore, each of the actions used by the Web Forms for Marketers module are themselves part of the content tree:&lt;br /&gt;&lt;img alt="ActionsInContentTree" border="0" height="233" src="http://lh3.ggpht.com/_JjsHfCZ5On8/SqF2nW-MjwI/AAAAAAAABCk/bGZnB9nBVZM/ActionsInContentTree%5B4%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="ActionsInContentTree" width="244" /&gt;&lt;br /&gt;I copied the Save to Database action, pasted it and renamed it to “Save to CRM”.&amp;nbsp; We won’t implement anything like a CRM mapping today, but it sets up a good follow-up.&amp;nbsp; For today, just the mechanics….set up the item in the tree to call out to a class that follows the interface set up for an action, get access to the names and values of the submitted form.&lt;br /&gt;As with this same capability to our code from workflow actions, validation actions, etc., the WFFM action provides the same ability to call out our class:&lt;br /&gt;&lt;img alt="classSignature" border="0" height="154" src="http://lh5.ggpht.com/_JjsHfCZ5On8/SqF2n0_UWnI/AAAAAAAABCo/PxbZ4veGNQY/classSignature%5B4%5D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="classSignature" width="244" /&gt; &lt;br /&gt;Using .NET Reflector, I borrowed the implementation of the Send Mail action, stripped it down to just the code necessary to get access to the field names and values, and pasted it below:&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;System;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;System.Web;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Form.Core;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Form.Submit;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Form.Core.Client.Data.Submit;&lt;br /&gt;&lt;span style="color: blue;"&gt;using &lt;/span&gt;Sitecore.Data;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;namespace &lt;/span&gt;NiCam.Classes.Mike&lt;br /&gt;{&lt;br /&gt;&lt;span style="color: blue;"&gt;  public class &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;SaveToCRM &lt;/span&gt;: &lt;span style="color: #2b91af;"&gt;ISubmit&lt;br /&gt;&lt;/span&gt;  {&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;    public virtual void &lt;/span&gt;Submit(&lt;span style="color: #2b91af;"&gt;ID &lt;/span&gt;formid, &lt;span style="color: #2b91af;"&gt;AdaptedResultList &lt;/span&gt;fields)&lt;br /&gt;    {&lt;br /&gt;&lt;span style="color: blue;"&gt;       foreach &lt;/span&gt;(Sitecore.Form.Core.Controls.Data.&lt;span style="color: #2b91af;"&gt;AdaptedControlResult &lt;/span&gt;formField &lt;span style="color: blue;"&gt;in &lt;/span&gt;fields)&lt;br /&gt;       {&lt;br /&gt;&lt;span style="color: blue;"&gt;          string &lt;/span&gt;fieldName = formField.FieldName;&lt;br /&gt;&lt;span style="color: blue;"&gt;          string &lt;/span&gt;fieldValue = formField.Value;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This action will now be available to the Web Forms for Marketers UI drop down.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-4041974106033959659?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4041974106033959659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4041974106033959659'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/09/one-of-those-custom-web-forms-for.html' title='One of those custom Web Forms for Marketers actions'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_JjsHfCZ5On8/SqF2nW-MjwI/AAAAAAAABCk/bGZnB9nBVZM/s72-c/ActionsInContentTree%5B4%5D.png?imgmax=800' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-5281164761201091010</id><published>2009-08-24T16:32:00.000-04:00</published><updated>2009-09-04T17:48:59.213-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='device'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>A simple XML Device Presentation Layer</title><content type='html'>&lt;div style="border-bottom: medium none; border-left: medium none; border-top: medium none; border-right: medium none"&gt;At Sitecore we often talk about the many uses of the Device concept.&amp;#160; Sometimes this is obvious (a mobile device requesting content vs. a browser requesting content will expect some particulars around the HTML sent to it).&amp;#160; Sometimes it is a bit more subtle (Internet Explorer and Firefox continue to disagree about something, so I have a control that implements a method or CSS class a bit differently based on the detection of the browser).&amp;#160; One of the situations we often talk about is the ease of availability of an XML representation of each content item in the content tree.&amp;#160; This conversation often centers around integration points, where I can send an XSLT-translated XML document based on Sitecore content to an external application or Web service. &lt;/div&gt;  &lt;div style="border-bottom: medium none; border-left: medium none; border-top: medium none; border-right: medium none"&gt;&lt;/div&gt; I wanted to prove in a quick concept--creating a Device presentation layer that shows an XML document based on the requested content item.&amp;#160; I took the easy way out in many areas of this, and I welcome real world &amp;quot;yeah, but this is actually how you should do it&amp;quot; wherever appropriate.   &lt;br /&gt;  &lt;br /&gt;  &lt;div style="border-bottom: medium none; border-left: medium none; border-top: medium none; border-right: medium none"&gt;Basically, I started by creating the Device in Sitecore.&amp;#160; I called it XML and added it to the Devices in the content tree.&lt;/div&gt;  &lt;br /&gt;  &lt;div style="border-bottom: medium none; text-align: center; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;&lt;a style="margin-left: 1em; margin-right: 1em" href="http://1.bp.blogspot.com/_JjsHfCZ5On8/SpLPCQgTHcI/AAAAAAAABCA/E3d_El8s70g/s1600-h/SetUpXMLDevice.png" imageanchor="1"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_JjsHfCZ5On8/SpLPCQgTHcI/AAAAAAAABCA/E3d_El8s70g/s320/SetUpXMLDevice.png" lk="true" /&gt;&lt;/a&gt;&lt;/div&gt;  &lt;div style="border-bottom: medium none; text-align: left; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;The new XML device is defined by any URL with &lt;em&gt;xml=1&lt;/em&gt; included in the query string.&amp;#160; To keep things simple, I created a new Layout (.aspx) file to handle requests from the XML device.&amp;#160; The Layout has a statically placed control (RenderXML.ascx) that does the work of:&lt;/div&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;br /&gt;      &lt;div style="border-bottom: medium none; text-align: left; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;Creating an XML document out of the fields of the Sitecore context item (the currently requested item from the content tree)&lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;br /&gt;      &lt;div style="border-bottom: medium none; text-align: left; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;Transfer the request (Server.Transfer) to the newly created XML document (allowing the browser's CSS for XML files to format the display).&lt;/div&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;div style="border-bottom: medium none; text-align: left; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;The code that does this, in the Page_Load event within RenderXML.ascs.cs, is shown below:&lt;/div&gt;  &lt;div style="border-bottom: medium none; text-align: left; border-left: medium none; clear: both; border-top: medium none; border-right: medium none" class="separator"&gt;&lt;/div&gt; &lt;span style="color: blue"&gt;protected void&lt;/span&gt;Page_Load(&lt;span style="color: blue"&gt;object&lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Sitecore.Data.Items.&lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;thisItem = Sitecore.&lt;span style="color: #2b91af"&gt;Context&lt;/span&gt;.Item;   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;XmlTextWriter &lt;/span&gt;writer = &lt;span style="color: blue"&gt;new&lt;/span&gt;&lt;span style="color: #2b91af"&gt;XmlTextWriter&lt;/span&gt;(Server.MapPath(&lt;span style="color: #a31515"&gt;&amp;quot;/layouts/dynamic/XmlDevice.xml&amp;quot;&lt;/span&gt;),System.Text.&lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8);   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteStartDocument();   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteStartElement(&lt;span style="color: #a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteAttributeString(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;, thisItem.Name);   &lt;br /&gt;  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(Sitecore.Data.Fields.&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;fld &lt;span style="color: blue"&gt;in&lt;/span&gt;thisItem.Fields)   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteStartElement(&lt;span style="color: #a31515"&gt;&amp;quot;field&amp;quot;&lt;/span&gt;);   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteAttributeString(&lt;span style="color: #a31515"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;, fld.Name);   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteAttributeString(&lt;span style="color: #a31515"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;, fld.Value);   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteEndElement();  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteEndElement();   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.WriteEndDocument();   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; writer.Close();   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Server.Transfer(&lt;span style="color: #a31515"&gt;&amp;quot;/layouts/dynamic/XMLDevice.xml&amp;quot;&lt;/span&gt;);&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }  &lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-5281164761201091010?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5281164761201091010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/5281164761201091010'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/08/simple-xml-device-presentation-layer.html' title='A simple XML Device Presentation Layer'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_JjsHfCZ5On8/SpLPCQgTHcI/AAAAAAAABCA/E3d_El8s70g/s72-c/SetUpXMLDevice.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-4422003323255543903</id><published>2009-08-24T12:15:00.001-04:00</published><updated>2009-08-24T16:24:27.709-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rich text editor'/><category scheme='http://www.blogger.com/atom/ns#' term='content editor'/><category scheme='http://www.blogger.com/atom/ns#' term='appearance'/><title type='text'>Height of Rich Text Fields in Content Editor</title><content type='html'>&lt;div&gt;A short one for the Sitecore Admins out there. Question came up recently, "How do I make one of the Rich Text fields take up less screen real estate in Content Editor?"&lt;br /&gt;&lt;br /&gt;Note the Long Description field below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/_JjsHfCZ5On8/SdSxCdumNWI/AAAAAAAAA5g/2c0HWJTuOVM/s1600-h/LongDescOnlyTall.jpg"&gt;&lt;img style="WIDTH: 246px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5320071715729323362" border="0" alt="" src="http://2.bp.blogspot.com/_JjsHfCZ5On8/SdSxCdumNWI/AAAAAAAAA5g/2c0HWJTuOVM/s320/LongDescOnlyTall.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you are choose to see Standard Fields (View--&gt;Standard Fields), you'll be able to see the Appearance section of the template field. In this case, I expanded the node for my template and found the Long Description field. In the Long Description, I added the following to the Style field:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;height: 20px;&lt;/strong&gt;&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/_JjsHfCZ5On8/SdSyh3yg6LI/AAAAAAAAA5w/J-3Mz-LmQOo/s1600-h/heigh20px.jpg"&gt;&lt;img style="WIDTH: 320px; HEIGHT: 121px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5320073354812647602" border="0" alt="" src="http://2.bp.blogspot.com/_JjsHfCZ5On8/SdSyh3yg6LI/AAAAAAAAA5w/J-3Mz-LmQOo/s320/heigh20px.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now the field in Content Editor takes up only the 20px height:&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_JjsHfCZ5On8/SdSzD6oTVdI/AAAAAAAAA54/1klNQmESEn8/s1600-h/20pxLongDesc.jpg"&gt;&lt;img style="WIDTH: 320px; HEIGHT: 98px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5320073939690673618" border="0" alt="" src="http://1.bp.blogspot.com/_JjsHfCZ5On8/SdSzD6oTVdI/AAAAAAAAA54/1klNQmESEn8/s320/20pxLongDesc.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-4422003323255543903?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4422003323255543903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/4422003323255543903'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/08/height-of-rich-text-fields-in-content.html' title='Height of Rich Text Fields in Content Editor'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_JjsHfCZ5On8/SdSxCdumNWI/AAAAAAAAA5g/2c0HWJTuOVM/s72-c/LongDescOnlyTall.jpg' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-8360277440872630202.post-8140008943872710950</id><published>2009-08-21T09:39:00.003-04:00</published><updated>2009-09-04T19:22:21.041-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cms'/><category scheme='http://www.blogger.com/atom/ns#' term='content management'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><category scheme='http://www.blogger.com/atom/ns#' term='mike casey'/><title type='text'>Starting Out</title><content type='html'>&lt;div&gt;&lt;blockquote&gt;"It is content, or rather the consciousness of content, that fills the void. But the mere presence of content is not enough. It is style that gives content the capacity to absorb us, to move us; it is style that makes us care." --Tom Robbins, Another Roadside Attraction&lt;/blockquote&gt;A quick note about, well, what this is about. I want to capture (thoughts captured as blogs, blogs captured as more in-depth articles, more in-depth articles captured as--who knows?) an appreciation for the collaboration necessary in choosing and implementing a content management solution. This is of course true for all great software projects. This is of course true for all great projects. But with content management software projects, this collaboration seems to have a head start.&lt;br /&gt;&lt;br /&gt;It seems like everyone is at the table early on--project managers, marketers, champions, network administrators, developers. The goal is (at least in comparison to many failed projects in the past) clear--let's create a Web presence that means something, that reacts to my visitor, that learns from that visitor to enable the system to grow on its own, guided in its growth by agreed upon business rules. Let everyone's voice be heard--quickly, efficiently, without departmental roadblocks shriveling ideas on the vine. At the same time, let me ensure our company voice is succinct and targeted, consistent and powerful. OK, clear goals...but aggressive too. This will require everyone's attention.&lt;br /&gt;&lt;br /&gt;Developers will have to loosen the reins a bit, face the fears of a user community gone mad with the sweet taste of flexibility. Marketers will have to wield their new-found control with an architect's respect for foundations. Project managers will have to define communications workflows to keep the arrow pointing up and to the right. That's why you're all sitting at the table now....you're looking for the right tool to help you in this adventure.&lt;br /&gt;&lt;br /&gt;Content Management is not new to you. You have lots of content--it's sprawling all over your site right now, failing to report back to you its conversations. Content Management isn't new to me either. Actually, technically it is. I've only recently starting working in this exciting and growing area of software. But I've understood the need for great conversations among great people seeking great goals for a while now. I've had well over a decade of managing software projects from all corners of the table. Now I've been given the privilege of working with what I consider to be the best tool for this job--Sitecore.&lt;br /&gt;&lt;br /&gt;I will use this forum to relay the conversations I hear as groups like you make this very important decision to bring in an enterprise-level content management system. Depending on the day, I will dive into the technical and business considerations that are so important to this decision. I welcome your feedback and I appreciate your joining in this learning process. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8360277440872630202-8140008943872710950?l=mikecaseycms.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8140008943872710950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8360277440872630202/posts/default/8140008943872710950'/><link rel='alternate' type='text/html' href='http://mikecaseycms.blogspot.com/2009/08/starting-out.html' title='Starting Out'/><author><name>Mike Casey</name><uri>http://www.blogger.com/profile/13706803130170455024</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-VvcNBA6A_UU/TmobUPcQ5lI/AAAAAAAABMw/0BN97662_QI/s220/mike_casey.jpg'/></author></entry></feed>
