<?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-5251195438749660493</id><updated>2012-01-09T14:31:55.980-08:00</updated><category term='URL Rewrite'/><category term='custom fields'/><category term='Sitecore Fields'/><category term='Dreamcore'/><category term='Links'/><category term='Sitecore Client Tools'/><category term='search'/><category term='index'/><category term='Sitecore 6'/><category term='lucene'/><category term='sitecore'/><category term='Page Editor'/><category term='IIS'/><category term='Rich Text Editor'/><category term='publishing'/><title type='text'>Sitecore Gadgets</title><subtitle type='html'>This blog is dedicated to Sitecore tools and customization</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2201011082132844336</id><published>2011-12-09T09:19:00.001-08:00</published><updated>2011-12-09T09:20:54.088-08:00</updated><title type='text'>Ensure valid Sitecore Internal Links in Page Editor (Update)</title><content type='html'>&lt;p align="left"&gt;A while back I published a &lt;a href="http://sitecoregadgets.blogspot.com/2011/06/ensure-valid-sitecore-internal-links-in.html" target="_blank"&gt;solution to ensure correct links in page editor&lt;/a&gt;. Some folks used it and provided a valuable feedback suggesting improvements for RegEx statements to match links. This post is intended to update the solution with suggested improvements. &lt;br&gt;&lt;br&gt;The suggested RegEx looks like this :&lt;br&gt;((http)|(https)):((//)|(&lt;a&gt;\\\\))({0}).*?(~/link.aspx&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;I updated both regular links and media links RegEx patterns with suggested modifications and re-assembled the package.&lt;/p&gt; &lt;p&gt;You can get from &lt;a href="http://dl.dropbox.com/u/35079964/Sitecore/Blog/Sitecore.Support.341310-1.0.1.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Kudos to anonymous developer who provided the updated RegEx!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-2201011082132844336?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/2201011082132844336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=2201011082132844336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2201011082132844336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2201011082132844336'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/12/ensure-valid-sitecore-internal-links-in.html' title='Ensure valid Sitecore Internal Links in Page Editor (Update)'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-8614023234415316726</id><published>2011-11-28T16:40:00.001-08:00</published><updated>2011-11-28T16:42:59.021-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='Rich Text Editor'/><title type='text'>Rich Text auto-save</title><content type='html'>&lt;p&gt;Another customization to address rising demand for auto save functionality in Rich Text fields. Per &lt;a href="http://outstandingsitecore.blogspot.com/" target="_blank"&gt;Derek’s&lt;/a&gt; suggestion I started with an approach that we found in our knowledge base system. I expected that some customization would be required as it was created a while back and we updated Rich Text editor since then. Here is what we’ve done to achieve the goal. The customization introduces a few changes to the following files at /sitecore/shell/Controls/Rich Text Editor folder:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;EditorPage.aspx – added some JS changes and changed class inheritance to a custom one.&lt;/li&gt; &lt;li&gt;EditorPage.js – made some JS changes.&lt;/li&gt; &lt;li&gt;EditorWindow.aspx – made some JS changes.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;One can use any merger tool to see what changes were made to aforementioned files. I also included a link to Sitecore package that contains required customization.&lt;/p&gt; &lt;p&gt;Keep in mind that the package contains a DLL so that app pool will be recycled during the package installation. &lt;br&gt;Please &lt;strong&gt;BACKUP&lt;/strong&gt; files listed above prior to installing the package.&lt;/p&gt; &lt;p&gt;Keep in mind that a Sitecore update that overrides any of the listed files will cease auto save functionality for RTE fields.&lt;/p&gt; &lt;p&gt;This feature was tested in Sitecore 6.4.1 Update-3 and Update-5 as well as Sitecore 6.5.0 Update-1.&lt;/p&gt; &lt;p&gt;&lt;a href="http://dl.dropbox.com/u/35079964/Sitecore/Blog/RichText-AutoSave-1.0.0.zip" target="_blank"&gt;Sitecore package link&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Enjoy!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-8614023234415316726?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/8614023234415316726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=8614023234415316726' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8614023234415316726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8614023234415316726'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/11/rich-text-auto-save.html' title='Rich Text auto-save'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-8345331445904662677</id><published>2011-10-27T13:58:00.001-07:00</published><updated>2011-10-27T14:15:39.626-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='URL Rewrite'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>Helicon URL Rewrite module with Sitecore in Integrated pipeline mode</title><content type='html'>&lt;p&gt;I recently happened to help a few customers resolve an issue with Helicon ISAPI URL Rewrite module when Sitecore runs in Integrated mode. So, I decided to make create a quick post about it as it took me awhile to figure out why this was happening. I even had to contact Helicon support channel to see if they had any insights into this issue.&lt;/p&gt; &lt;p&gt;The long story short Helicon module has to be configured in early request processing in order to work with Sitecore in Integrated pipeline mode. Here is the setting that you need to set up to make it happen: &lt;a title="http://www.helicontech.com/isapi_rewrite/doc/NotificationType.htm" href="http://www.helicontech.com/isapi_rewrite/doc/NotificationType.htm"&gt;http://www.helicontech.com/isapi_rewrite/doc/NotificationType.htm&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Now a few more details for those who still reading. So, why this becomes an issue when you run your Sitecore app in Integrated mode? The answer lies in the model that Integrated pipeline has. It’s different from Classic mode (aka IIS 6 model) which is based around ISAPI modules. For those who want to dive into details I’d recommend to read these articles: &lt;a href="http://msdn.microsoft.com/en-us/library/bb470252.aspx"&gt;ASP.NET Application Life Cycle Overview for IIS 7.0&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/aa347580(v=VS.90).aspx"&gt;Comparing Native-Code and Managed-Code Notifications [IIS 7]&lt;/a&gt;.&lt;br&gt;As all native and managed modules can subscribe to the same processing events when you run you app in integrated mode, the Helicon ISAPI module turns out to be not the first one that accepts a request. The first event that gets raised is Authentication one. Sitecore Http Module gets subscribed to that event thus it’s the first one who intercepts the request. After the Http Module the request gets changed and it points to the physical file, which is a physical layout page for your dynamically constructed page represented by a Sitecore item. As a result Helicon module gets a “wrong” URL.&lt;/p&gt; &lt;p&gt;If you’re not satisfied with this workaround, consider using official Microsoft &lt;a href="http://www.iis.net/download/URLRewrite"&gt;URL Rewrite&lt;/a&gt; module.&lt;/p&gt; &lt;p&gt;For those who are still looking for the solution it's a first link in this post &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://lh6.ggpht.com/-j-JQjtDC02E/TqnGCp2OuwI/AAAAAAAAIT4/CIxcUUMLBA8/wlEmoticon-smile%25255B2%25255D.png?imgmax=800"&gt;.&lt;/p&gt; &lt;p&gt;Hope this will save someone a bit of time.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-8345331445904662677?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/8345331445904662677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=8345331445904662677' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8345331445904662677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8345331445904662677'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/10/helicon-url-rewrite-module-with.html' title='Helicon URL Rewrite module with Sitecore in Integrated pipeline mode'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/-j-JQjtDC02E/TqnGCp2OuwI/AAAAAAAAIT4/CIxcUUMLBA8/s72-c/wlEmoticon-smile%25255B2%25255D.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-1614351291488337064</id><published>2011-09-09T14:47:00.001-07:00</published><updated>2011-09-20T17:20:43.344-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore Client Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><title type='text'>Advanced Publish Dialog</title><content type='html'>&lt;p&gt;Every once in a while our customers ask if it’s possible to terminate a publishing job. A demand for this functionality increased as our customers started pouring more and more content into their Sitecore implementations. Sometimes an innocent&amp;nbsp; publishing job could become vicious and freeze other publications. &lt;/p&gt; &lt;p&gt;In this blog post I’m going to present an approach that allows a user to cancel a triggered publishing job. This became possible as new publishing pipelines were introduced in Sitecore 6.&lt;/p&gt; &lt;p&gt;Main idea of this tool was to add flexibility to control Publish Dialog UI through Sitecore security mechanism. For instance, hide or disable publish options and&amp;nbsp; “Publish Subitems” checkbox using user security settings. This was implemented by introducing Sitecore setting items for Publish Dialog UI controls. The items located at /sitecore/system/Settings/Publish folder. &lt;/p&gt; &lt;p&gt;The security settings on publish option items as well as checkbox field, Disabled, control appearance and accessibility of the controls on Publish Dialog form.&lt;br&gt;There are a few more setting items under the /Behaviors branch described below:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Publish Cancel Behavior&lt;br&gt;Controls publish cancelling mechanism. If “Cancel with exception” field is checked, it throws an exception after publishing job is cancelled. This is necessary to suppress post publish events and prevent update of LastPublish property when needed.  &lt;li&gt;Cancel Button&lt;br&gt;Controls accessibility of “Cancel” button in Publish Dialog form. By default it has standard behavior – button is disabled after one starts publishing process. When enabled, it’s possible to cancel current publishing job.  &lt;li&gt;Confirm subitems publish&lt;br&gt;If enabled, it pops-up a confirmation dialog when “Publish Subitems” checkbox is selected. You can tweak the confirmation message at “/sitecore/system/Dictionary/A/Are you sure you want to publish subitems too” dictionary item in the Core database.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;There are two versions of this component:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;1. v1.1.1 – developed for AppPool running any .NET version&lt;/p&gt; &lt;p&gt;2. v1.2.0 – developed for AppPool running .NET 4.0 version ONLY. It takes advantage of a feature in .NET 4.0 that allows to speed up publishing by assigning multiple threads to publish items.&lt;/p&gt; &lt;p&gt;Setting that controls number of allowed threads for publishing process is located in /App_Config/Include/Sitecore.SharedSource.AdvancedPublishDialog.config file. By default allows 2 publishing threads.&lt;/p&gt;&lt;/blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;&amp;lt;!--  Max number of concurrent threads for publishing process.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;         If this setting is not set Environment.ProcessorCount variable will be used.&lt;/span&gt;&lt;br /&gt;&lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;setting&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;="Publishing.MaxConcurrentThreads"&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;="2"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&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;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To observe and cancel publishing jobs an additional application was added to the component – Publish Status Manager. A link to this app appears in Publish Dialog form if a user has access to the app. It’s also possible to open the app from Sitecore start button, again, if the user has access to it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;From within the app one can select a job and hit “Cancel” button to terminate it. By clicking “Cancel all”, all publishing jobs will be forced to be finished.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;A few words on how publishing cancel works and its consequences.&lt;br&gt;When one triggers publishing cancellation, the job gets set to Finished state which is utilized in customized ProcessQueue processor of &amp;lt;publish&amp;gt; pipeline to get off the publishing loop. If “Publish Cancel Behavior” is enabled (setting described above), then custom ProcessPublishCancel pipleline will throw an exception to suppress post publish events.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;The caveats of cancelling publishing process.&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Publishing of each item is an atomic operation. When you cancel the publishing, there is no mechanism to roll back changes for already processed items. The data for already published items will make their way to the publishing target database. The search indexes will index new data as soon as IndexingManager reads new entries from History table. New published data may not appear on the public site if old data sit in HTML cache of presentation controls and “publish:end” event did not rise to clear it out. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;The “Cancel with exception” behavior on “Publish Cancel Behavior” setting item can suppress “publish:end” event and leave LastPublish property unchanged. This could be required if one wants to re-publish processed items, which got published before the publishing job was cancelled, at next Incremental publishing.&lt;br&gt;If this setting is not set, then caches will be cleared for all processed items whenever publishing is terminated. The LastPublish property will be updated with publish cancellation time. Next Incremental publish will pick up items from the point where they were left when publish cancel event got fired.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Having said this, I’d recommend to leave “Cancel with exception” field unchecked unless you have a strong requirement to republish processed items along with those that were skipped by publish cancellation event.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here as screencast of quick overview of the component:&lt;/p&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:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:cfc54fee-dbbf-4607-80e4-2eb5161a12b7" class="wlWriterEditableSmartContent"&gt;&lt;div id="1f673caf-9983-4f76-93b5-f1362ab1362d" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=1LdhTmrJkPw&amp;amp;feature=youtube_gdata_player" target="_new"&gt;&lt;img src="http://lh4.ggpht.com/-LINi6EuKP5o/TnktRHhGXMI/AAAAAAAAITg/_-MO-qI1H3g/video068bd477d83d%25255B20%25255D.jpg?imgmax=800" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('1f673caf-9983-4f76-93b5-f1362ab1362d'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;object width=\&amp;quot;623\&amp;quot; height=\&amp;quot;350\&amp;quot;&amp;gt;&amp;lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/1LdhTmrJkPw?hl=en&amp;amp;hd=1\&amp;quot;&amp;gt;&amp;lt;\/param&amp;gt;&amp;lt;embed src=\&amp;quot;http://www.youtube.com/v/1LdhTmrJkPw?hl=en&amp;amp;hd=1\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;623\&amp;quot; height=\&amp;quot;350\&amp;quot;&amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/object&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="width:623px;clear:both;font-size:.8em"&gt;Advanced Publish Dialog for Sitecore&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;UPDATED on Sep 20, 2011&lt;br&gt;&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;Support for v1.1.x was dropped as v1.2.x does not require AppPool to run .NET 4.0. The link to v1.1.x is no longer available.&lt;/em&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Below are the links to the mentioned Sitecore packages:&lt;br&gt;Sitecore package of &lt;a href="http://svn.sitecore.net/AdvancedPublishDialog/Trunk/Data/Packages/AdvancedPublishDialog-1.2.1.zip"&gt;AdvancedPublishDialog&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If you have any enhancement ideas or additional features for this module, feel free to express them in the comments.&lt;br&gt;Enjoy!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-1614351291488337064?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/1614351291488337064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=1614351291488337064' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1614351291488337064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1614351291488337064'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/09/advanced-publish-dialog.html' title='Advanced Publish Dialog'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/-LINi6EuKP5o/TnktRHhGXMI/AAAAAAAAITg/_-MO-qI1H3g/s72-c/video068bd477d83d%25255B20%25255D.jpg?imgmax=800' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2339191710306805470</id><published>2011-06-28T15:50:00.000-07:00</published><updated>2011-12-09T09:22:28.073-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Page Editor'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><title type='text'>Ensure valid Sitecore Internal Links in Page Editor</title><content type='html'>&lt;p&gt;&lt;em&gt;&lt;strong&gt;(Updated on Dec 9, 2011)&lt;br&gt;Refer to &lt;a href="http://sitecoregadgets.blogspot.com/2011/12/ensure-valid-sitecore-internal-links-in.html" target="_blank"&gt;this post&lt;/a&gt; for updated solution.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;&lt;strong&gt;(Updated on July 27, 2011)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;A workaround developed for one of our customers incited me to blog about it as I can see how many other may get affected by this issue. &lt;/p&gt; &lt;p&gt;The issue was that whenever an editor opens RTE control in Page Editor, to get access to all provided functions, and saves the changes, all internal links (that start with “~/link.aspx”) get prefixed with the host name that is used in the browser to access the Page Editor. I could recreate this behavior only in IE browser and only when it runs in compatibility mode. Got same results in both IE8 and IE9 running in compatibility mode. Normal mode of IE8 does not cause the issue.&lt;/p&gt; &lt;p&gt;To address this issue I hooked into &amp;lt;saveUI&amp;gt; pipeline my processor that corrects internal links based on regex that is passed to match a part of the link. Here is the code I came up with:&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3437d138-122c-4e97-a696-06203372eef0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #fff; max-height: 500px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; System.Text.RegularExpressions;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Configuration;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Data.Fields;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Data.Items;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Pipelines.Save;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; Sitecore.Support.Pipelines.Save&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;EnsureRichTextRelativeLinks&lt;/span&gt;&lt;/li&gt; &lt;li&gt;   {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; Process(&lt;span style="color:#2b91af"&gt;SaveArgs&lt;/span&gt; args)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (args.HasSheerUI)&lt;/li&gt; &lt;li&gt;         {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; ((args.Result == &lt;span style="color:#a31515"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;) || (args.Result == &lt;span style="color:#a31515"&gt;&amp;quot;undefined&amp;quot;&lt;/span&gt;))&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               args.AbortPipeline();&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; args.Items.Length; i++)&lt;/li&gt; &lt;li&gt;               {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  &lt;span style="color:#2b91af"&gt;SaveArgs&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;SaveItem&lt;/span&gt; item = args.Items[i];&lt;/li&gt; &lt;li&gt;                  &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; contentItem = &lt;span style="color:#2b91af"&gt;Context&lt;/span&gt;.ContentDatabase.Items[item.ID, item.Language, item.Version];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (contentItem != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;                  {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                     &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;SaveArgs&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;SaveField&lt;/span&gt; field &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; item.Fields)&lt;/li&gt; &lt;li&gt;                     {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                        &lt;span style="color:#2b91af"&gt;Field&lt;/span&gt; fld = contentItem.Fields[field.ID];&lt;/li&gt; &lt;li&gt;                        &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (fld != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; fld.Type.Equals(&lt;span style="color:#a31515"&gt;&amp;quot;rich text&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                        {&lt;/li&gt; &lt;li&gt;                           &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(field.Value))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                           {&lt;/li&gt; &lt;li&gt;                              field.Value = EnsureRelativeLinks(field.Value);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                           }&lt;/li&gt; &lt;li&gt;                        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                     }&lt;/li&gt; &lt;li&gt;                  }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               }&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; EnsureRelativeLinks(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; fieldValue)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; internalLinkPattern = &lt;span style="color:#2b91af"&gt;Settings&lt;/span&gt;.GetSetting(&lt;span style="color:#a31515"&gt;&amp;quot;PageEditor.InternalLinkReplacePattern&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                          &lt;span style="color:#a31515"&gt;&amp;quot;((http)|(https)):((//)|(&amp;#92;&amp;#92;&amp;#92;&amp;#92;))({0}).*(~/link.aspx)&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; internalLinkReplacementValue = &lt;span style="color:#2b91af"&gt;Settings&lt;/span&gt;.GetSetting(&lt;span style="color:#a31515"&gt;&amp;quot;PageEditor.InternalLinkReplacementValue&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                                   &lt;span style="color:#a31515"&gt;&amp;quot;~/link.aspx&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; mediaLinkPattern = &lt;span style="color:#2b91af"&gt;Settings&lt;/span&gt;.GetSetting(&lt;span style="color:#a31515"&gt;&amp;quot;PageEditor.MediaLinkReplacePattern&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                       &lt;span style="color:#a31515"&gt;&amp;quot;((http)|(https)):((//)|(&amp;#92;&amp;#92;&amp;#92;&amp;#92;))({0}).*(~/media)&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; mediaLinkReplacementValue = &lt;span style="color:#2b91af"&gt;Settings&lt;/span&gt;.GetSetting(&lt;span style="color:#a31515"&gt;&amp;quot;PageEditor.MediaLinkReplacementValue&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515"&gt;&amp;quot;~/media&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt; linkPattern = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(internalLinkPattern, Sitecore.Web.&lt;span style="color:#2b91af"&gt;WebUtil&lt;/span&gt;.GetHostName()), &lt;span style="color:#2b91af"&gt;RegexOptions&lt;/span&gt;.IgnoreCase);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt; mediaPattern = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Regex&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(mediaLinkPattern, Sitecore.Web.&lt;span style="color:#2b91af"&gt;WebUtil&lt;/span&gt;.GetHostName()), &lt;span style="color:#2b91af"&gt;RegexOptions&lt;/span&gt;.IgnoreCase);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; value = linkPattern.Replace(fieldValue, internalLinkReplacementValue);&lt;/li&gt; &lt;li&gt;         value = mediaPattern.Replace(value, mediaLinkReplacementValue);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; value;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;   }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;I put regex pattern as well as replacement strings into include config file to make the adjustment easier if necessary. Here is how the config file looks like:&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:371f6dd3-b087-4256-ad86-6f77f10789b5" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #fff; max-height: 400px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px; white-space: nowrap"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;xmlns:patch&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;http://www.sitecore.net/xmlconfig/&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;  &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;sitecore&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;processors&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;saveUI&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#008000"&gt;Fix to address an issue of internal links being converted to absolute links &lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#008000"&gt;after saving content of RTE field in IE browser running in compatibility mode.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#008000"&gt;The fix is developed by Sitecore support and should be removed after the problem is fixed in the core product.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#008000"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;--&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;processor&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;mode&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;on&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;type&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Sitecore.Support.Pipelines.Save.EnsureRichTextRelativeLinks, Sitecore.Support.341310&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;patch:after&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;processor[@type=&amp;#39;Sitecore.Pipelines.Save.ConvertLayoutField, Sitecore.Kernel&amp;#39;]&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;saveUI&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;processors&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;settings&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000"&gt; RegEx pattern to ensure valid internal links during the save event in Page Editor. &lt;/span&gt;&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#008000"&gt;The issue occurs in IE browser running in compatibility mode.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;           &lt;span style="color:#008000"&gt;The pattern will be replaced to a value defined at PageEditor.InternalLinkReplacementValue&lt;/span&gt;&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#008000"&gt;The {0} parameter is used to insert a host name used in the browser to access Page Editor.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;--&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;setting&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;PageEditor.InternalLinkReplacePattern&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;value&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;((http)|(https)):((//)|(&amp;#92;&amp;#92;&amp;#92;&amp;#92;))({0}).*(~/link.aspx)&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000"&gt; Replacement string for regex pattern defined in PageEditor.InternalLinkReplacePattern setting.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#008000"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;--&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;setting&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;PageEditor.InternalLinkReplacementValue&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;value&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;~/link.aspx&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000"&gt; RegEx pattern to ensure valid media links during the save event in Page Editor. &lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;           &lt;span style="color:#008000"&gt;The issue occurs in IE browser running in compatibility mode.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#008000"&gt;The pattern will be replaced to a value defined at PageEditor.MediaLinkReplacementValue&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;           &lt;span style="color:#008000"&gt;The {0} parameter is used to insert a host name used in the browser to access Page Editor.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#008000"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;--&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;setting&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;PageEditor.MediaLinkReplacePattern&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;value&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;((http)|(https)):((//)|(&amp;#92;&amp;#92;&amp;#92;&amp;#92;))({0}).*(~/media)&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:#008000"&gt; Replacement string for regex pattern defined in PageEditor.MediaLinkReplacePattern setting.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;--&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;setting&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;PageEditor.MediaLinkReplacementValue&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;value&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;~/media&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;settings&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;  &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;sitecore&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;Oh yeah, I wasn’t sure if this could happen to media links (couldn’t reproduce it locally) but decided to add the same replacement functionality for “~/media” links as well. If you find it useless, feel free to remove that part :).&lt;/p&gt; &lt;p&gt;This code was developed and tested in Sitecore 6.4.1 rev.110324. It’s expected to work in any 6.4 version. Can’t see any problems with 6.5 but I haven’t tested it there.&lt;/p&gt; &lt;p&gt;As all the code fit into the snippet boxes above, I don’t provide links to sources for download. Though here is the &lt;a href="http://dl.dropbox.com/u/35079964/Sitecore/Blog/Sitecore.Support.341310-1.0.0.zip"&gt;link to Sitecore package&lt;/a&gt; that installs the fix.&lt;/p&gt; &lt;p&gt;Hope it saves you some time!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-2339191710306805470?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/2339191710306805470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=2339191710306805470' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2339191710306805470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2339191710306805470'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/06/ensure-valid-sitecore-internal-links-in.html' title='Ensure valid Sitecore Internal Links in Page Editor'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-1511356517441463981</id><published>2011-01-21T11:46:00.001-08:00</published><updated>2011-01-21T11:48:15.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dreamcore'/><title type='text'>Upcoming Sitecore event: Dreamcore 2011</title><content type='html'>The spring is coming and along with it our second &lt;a href="http://sitecore.net/dreamcore2011"&gt;Dreamcore&lt;/a&gt; event is coming too. If you want to know more about Sitecore’s functionality and the future of our product, book your seat in the &lt;a href="http://sitecore.net/dreamcore2011"&gt;Dreamcore 2011&lt;/a&gt; bullet train.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-1511356517441463981?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/1511356517441463981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=1511356517441463981' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1511356517441463981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1511356517441463981'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2011/01/upcoming-sitecore-event-dreamcore-2011.html' title='Upcoming Sitecore event: Dreamcore 2011'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-3031489257672163278</id><published>2010-10-26T14:25:00.001-07:00</published><updated>2010-10-26T14:25:08.512-07:00</updated><title type='text'>All-in-1 Workflow</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;In this article I’m going to describe an approach that we’ve taken creating a solution for a universal workflow requirement. The idea was to create one workflow for all content items as they all would follow the same workflow process.&lt;/p&gt; &lt;p&gt;Here is a use case that came from one of our wonderful customers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All content items should have the same workflow process.  &lt;li&gt;Different security roles may have or not have access to a workflow state at different parts of a content tree.  &lt;li&gt;Workbox should respect aforementioned security configuration.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;To understand what access rights provide editing permission to the user let’s take a look at the way Sitecore resolves access level to a content item.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check if a user has Read (item:read) access to an item. If so, the user will be able to see the item in a Content Editor.&lt;a href="http://lh4.ggpht.com/_gDIVYhqZmFo/TMdHJ4pdg7I/AAAAAAAAIL4/ThqgFT-1GQs/s1600-h/image5.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://lh5.ggpht.com/_gDIVYhqZmFo/TMdHKBSRCqI/AAAAAAAAIL8/-4ankaryFJc/image_thumb3.png?imgmax=800" width="289" height="172"&gt;&lt;/a&gt;  &lt;li&gt;Check if the user has Write (item:write) access to the item. If the item is in workflow, check whether the user has Write access to a workflow state the item is in (workflowState:write). If either of those access rights is not granted, reclaim modification access.&lt;br&gt;&lt;a href="http://lh4.ggpht.com/_gDIVYhqZmFo/TMdHKWJD3hI/AAAAAAAAIMA/UbnFjugNM8A/s1600-h/image17.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/_gDIVYhqZmFo/TMdHKlIUQbI/AAAAAAAAIME/Avu7lYdM0DU/image_thumb11.png?imgmax=800" width="372" height="148"&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;As you can see both Write and Workflow State Write access rights are required for a user to edit the item.&lt;/p&gt; &lt;p&gt;This is the approach we came up with to address all the requirements. We can meet all requirements by extending standard Workflow class and using it to run workflow process.&lt;/p&gt; &lt;p&gt;First. Define additional access right that along with Workflow state Write one would determine access to items in workflow at different parts of the content tree. In this approach we decided to use “workflowState:write” access right which is available only to workflow related items by default. In this case the only thing we need to do is to make it available for all of the items. And it could be easily configured in web.config file:&lt;br&gt;&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3dad40b5-edd6-41d1-9044-1d322c597110" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;rules&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;  &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;add&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;prefix&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;workflowState:write&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;typeName&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Sitecore.Data.Items.Item&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;rules&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Now you can set this right for any item in Security Editor. Just don’t forget to add an appropriate column to see it there.&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_gDIVYhqZmFo/TMdHLQ_dv3I/AAAAAAAAIMI/Fu9objWcBDs/s1600-h/image28.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://lh5.ggpht.com/_gDIVYhqZmFo/TMdHL-Mm2wI/AAAAAAAAIMM/2KAPoZVj6JU/image_thumb18.png?imgmax=800" width="468" height="101"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Second. Extend default Sitecore.Workflows.Simple.Workflow class to take into account new security configuration.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c7c1716c-c385-4324-9c45-e7babbc34608" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; TwinPeaks.Workflows&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Workflow&lt;/span&gt; : Sitecore.Workflows.Simple.&lt;span style="color:#2b91af"&gt;Workflow&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; CheckRequiredFieldName = &lt;span style="color:#a31515"&gt;&amp;quot;Check required&amp;quot;&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; Workflow(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; workflowId, &lt;span style="color:#2b91af"&gt;WorkflowProvider&lt;/span&gt; owner)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            : &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;(workflowId, owner)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            Owner = owner;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns workflow state commands.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;[] GetCommands(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateID = &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.GetStateID(item);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (stateID.Length &amp;gt; 0)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetCommands(stateID, item);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;[0];&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns workflow state commands.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateId&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow state ID&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;[] GetCommands(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId, &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(stateId, &lt;span style="color:#a31515"&gt;&amp;quot;stateID&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; stateItem = GetStateItem(stateId);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; workflowState = GetState(stateId);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (stateItem == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; || workflowState == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;[0];&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt;[] itemArray = stateItem.Children.ToArray();&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;ArrayList&lt;/span&gt; list = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArrayList&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; entity &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; itemArray)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (entity != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;                {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color:#2b91af"&gt;Template&lt;/span&gt; template = entity.Database.Engines.TemplateEngine.GetTemplate(entity.TemplateID);&lt;/li&gt; &lt;li&gt;                    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowState.CheckRequired &amp;amp;&amp;amp; !&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    {&lt;/li&gt; &lt;li&gt;                        &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (((template != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; template.DescendsFromOrEquals(&lt;span style="color:#2b91af"&gt;TemplateIDs&lt;/span&gt;.WorkflowCommand)) &amp;amp;&amp;amp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                        &lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(entity, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowCommandExecute, &lt;span style="color:#2b91af"&gt;Context&lt;/span&gt;.User) &amp;amp;&amp;amp;&lt;/li&gt; &lt;li&gt;                        &lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(item, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.FromName(&lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name), &lt;span style="color:#2b91af"&gt;Context&lt;/span&gt;.User))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                        {&lt;/li&gt; &lt;li&gt;                            list.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;(entity.ID.ToString(), entity.DisplayName,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                         entity.Appearance.Icon, &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;,&lt;/li&gt; &lt;li&gt;                                                         entity[&lt;span style="color:#a31515"&gt;&amp;quot;suppress comment&amp;quot;&lt;/span&gt;] == &lt;span style="color:#a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                        }&lt;/li&gt; &lt;li&gt;                    }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (((template != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; template.DescendsFromOrEquals(&lt;span style="color:#2b91af"&gt;TemplateIDs&lt;/span&gt;.WorkflowCommand)) &amp;amp;&amp;amp;&lt;/li&gt; &lt;li&gt;                        &lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(entity, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowCommandExecute, &lt;span style="color:#2b91af"&gt;Context&lt;/span&gt;.User))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    {&lt;/li&gt; &lt;li&gt;                        list.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;(entity.ID.ToString(), entity.DisplayName, entity.Appearance.Icon, &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;, entity[&lt;span style="color:#a31515"&gt;&amp;quot;suppress comment&amp;quot;&lt;/span&gt;] == &lt;span style="color:#a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    }&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;[])list.ToArray(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;WorkflowCommand&lt;/span&gt;));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns workflow state item&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateId&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow state ID&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; GetStateItem(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;ID&lt;/span&gt; iD = &lt;span style="color:#2b91af"&gt;MainUtil&lt;/span&gt;.GetID(stateId, &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (iD == (&lt;span style="color:#2b91af"&gt;ID&lt;/span&gt;)&lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ItemManager&lt;/span&gt;.GetItem(stateId, &lt;span style="color:#2b91af"&gt;Language&lt;/span&gt;.Current, &lt;span style="color:#2b91af"&gt;Version&lt;/span&gt;.Latest, Owner.Database, &lt;span style="color:#2b91af"&gt;SecurityCheck&lt;/span&gt;.Disable);&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns workflow state ID&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; GetStateID(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;WorkflowInfo&lt;/span&gt; workflowInfo = item.Database.DataManager.GetWorkflowInfo(item);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowInfo != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; workflowInfo.StateID;&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Need to override to respect new right in Workbox application&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[] GetItems(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (CheckStateAdvancedSecurity(stateId))&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(stateId, &lt;span style="color:#a31515"&gt;&amp;quot;stateID&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.IsTrue(&lt;span style="color:#2b91af"&gt;ID&lt;/span&gt;.IsID(stateId), &lt;span style="color:#a31515"&gt;&amp;quot;Invalid state ID: &amp;quot;&lt;/span&gt; + stateId);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[] itemsInWorkflowState =&lt;/li&gt; &lt;li&gt;                    Owner.Database.DataManager.GetItemsInWorkflowState(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowInfo&lt;/span&gt;(WorkflowID, stateId));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[] filteredItems = ApplyAdvancedSecurity(itemsInWorkflowState, stateId);&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (filteredItems != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                {&lt;/li&gt; &lt;li&gt;                    &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; filteredItems;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                }&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[0];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.GetItems(stateId);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Indicates if advanced security should be checked for a workflow state.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateId&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow satate ID&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; CheckStateAdvancedSecurity(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; workflowState = GetState(stateId);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowState != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; workflowState.CheckRequired &amp;amp;&amp;amp; !&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name))&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Filters out items that a user should not have access to.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;items&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;DataUri array of content items.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateId&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow state ID.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[] ApplyAdvancedSecurity(&lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[] items, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (items == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; || items.Length == 0)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[0];&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; workflowState = GetState(stateId);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowState == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[0];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;var&lt;/span&gt; filteredItems =&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                items.Where(&lt;/li&gt; &lt;li&gt;                    item =&amp;gt; Owner.Database.GetItem(item) != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                            &lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(Owner.Database.GetItem(item),&lt;/li&gt; &lt;li&gt;                                                           &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.FromName(&lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name),&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                           &lt;span style="color:#2b91af"&gt;Context&lt;/span&gt;.User));&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!filteredItems.GetEnumerator().MoveNext())&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DataUri&lt;/span&gt;[0];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; filteredItems.ToArray();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns an extended WorkflowState object.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateId&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow state ID.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; GetState(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(stateId, &lt;span style="color:#a31515"&gt;&amp;quot;stateId&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; stateItem = GetStateItem(stateId);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (stateItem != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt;(stateId, stateItem.DisplayName, stateItem.Appearance.Icon, stateItem[&lt;span style="color:#2b91af"&gt;WorkflowFieldIDs&lt;/span&gt;.FinalState] == &lt;span style="color:#a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;, stateItem[CheckRequiredFieldName] == &lt;span style="color:#a31515"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns access result of whether the user has write access to the item.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;account&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;User account&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;accessRight&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Access right&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt; GetAccess(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item, &lt;span style="color:#2b91af"&gt;Account&lt;/span&gt; account, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt; accessRight)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(account, &lt;span style="color:#a31515"&gt;&amp;quot;account&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(accessRight, &lt;span style="color:#a31515"&gt;&amp;quot;operation&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; stateItem = GetStateItem(item);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (stateItem == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;AccessPermission&lt;/span&gt;.Allow, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessExplanation&lt;/span&gt;(item, account, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.ItemDelete, &lt;span style="color:#a31515"&gt;&amp;quot;The workflow state definition item not found.&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;[0]));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (accessRight == &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.ItemWrite)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; GetWriteAccessInformation(item, account, stateItem);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.GetAccess(item, account, accessRight);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Resolves whether the user has write access to the item.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;account&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;User account.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;stateItem&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Workflow state item.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt; GetWriteAccessInformation(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item, &lt;span style="color:#2b91af"&gt;Account&lt;/span&gt; account, &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; stateItem)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; workflowState = GetState(stateItem.ID.ToString());&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowState != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; workflowState.CheckRequired)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(stateItem, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite, account) &amp;amp;&amp;amp; &lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(item, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite, account))&lt;/li&gt; &lt;li&gt;                {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                    &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;AccessPermission&lt;/span&gt;.Allow, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessExplanation&lt;/span&gt;(item, account, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.ItemWrite, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;The workflow state definition item allows writing (through the &amp;#39;{0}&amp;#39; access right).&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name), &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;[0]));&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;AuthorizationManager&lt;/span&gt;.IsAllowed(stateItem, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite, account))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;AccessPermission&lt;/span&gt;.Allow, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessExplanation&lt;/span&gt;(item, account, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.ItemWrite, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;The workflow state definition item allows writing (through the &amp;#39;{0}&amp;#39; access right).&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name), &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;[0]));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessResult&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;AccessPermission&lt;/span&gt;.Deny, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;AccessExplanation&lt;/span&gt;(item, account, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.ItemWrite, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;The workflow state definition item does not allow writing. To allow writing, grant the &amp;#39;{0}&amp;#39; access right to the workflow state definition item.&amp;quot;&lt;/span&gt;, &lt;span style="color:#2b91af"&gt;AccessRight&lt;/span&gt;.WorkflowStateWrite.Name), &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;[0]));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Returns workflow state item the content item is in.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Content item.&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; GetStateItem(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;WorkflowInfo&lt;/span&gt; info = item.Database.DataManager.GetWorkflowInfo(item);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (info != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; item.Database.SelectSingleItem(info.StateID);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;#region&lt;/span&gt; Properties&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowProvider&lt;/span&gt; Owner { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;#endregion&lt;/span&gt; Properties&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;To provide an ability to choose whether access to a workflow state should be combined with access to a content item, I extended System/Workflow/State template with a checkbox field that indicates whether a custom logic should be triggered. Here how it looks now:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_gDIVYhqZmFo/TMdHMHMv3VI/AAAAAAAAIMQ/EFmm2sT17RI/s1600-h/image34.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/_gDIVYhqZmFo/TMdHM1IUuGI/AAAAAAAAIMU/0XLHoJTeSac/image_thumb22.png?imgmax=800" width="241" height="207"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I extended WorkflowState class with an appropriate property for the new field.&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f760cfa9-2a3d-4151-ae36-3328312a58ae" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; TwinPeaks.Workflows&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt; : Sitecore.Workflows.&lt;span style="color:#2b91af"&gt;WorkflowState&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; WorkflowState(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; stateId, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; displayName, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; icon, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; finalState, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; checkRequired) : &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;(stateId, displayName, icon, finalState)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            CheckRequired = checkRequired;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Indicates if workflowState:write access right should be considered while resolving access to the item.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; CheckRequired { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;Now in order to make Sitecore use our new Workflow class we need to override WorkflowProvider to return our extended Workflow instance.&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7cb6e17c-5e8e-4e1c-af41-98666b049139" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Data;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Data.Items;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Diagnostics;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;using&lt;/span&gt; Sitecore.Workflows;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; TwinPeaks.Workflows&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; This class overrides required methods to return an object of extended Workflow class.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;WorkflowProvider&lt;/span&gt; : Sitecore.Workflows.Simple.&lt;span style="color:#2b91af"&gt;WorkflowProvider&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; WorkflowProvider(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; databaseName, &lt;span style="color:#2b91af"&gt;HistoryStore&lt;/span&gt; historyStore) : &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;(databaseName, historyStore)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt; GetWorkflow(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; workflowID = GetWorkflowID(item);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowID.Length &amp;gt; 0)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Workflow&lt;/span&gt;(workflowID, &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt; GetWorkflow(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; workflowID)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(workflowID, &lt;span style="color:#a31515"&gt;&amp;quot;workflowID&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Error&lt;/span&gt;.Assert(&lt;span style="color:#2b91af"&gt;ID&lt;/span&gt;.IsID(workflowID), &lt;span style="color:#a31515"&gt;&amp;quot;The parameter &amp;#39;workflowID&amp;#39; must be parseable to an ID&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.Database.Items[&lt;span style="color:#2b91af"&gt;ID&lt;/span&gt;.Parse(workflowID)] != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Workflow&lt;/span&gt;(workflowID, &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; GetWorkflowID(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;WorkflowInfo&lt;/span&gt; workflowInfo = item.Database.DataManager.GetWorkflowInfo(item);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (workflowInfo != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; workflowInfo.WorkflowID;&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt;[] GetWorkflows()&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item = &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.Database.Items[&lt;span style="color:#2b91af"&gt;ItemIDs&lt;/span&gt;.WorkflowRoot];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (item == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt;[0];&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt;[] itemArray = item.Children.ToArray();&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt;[] workflowArray = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IWorkflow&lt;/span&gt;[itemArray.Length];&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; itemArray.Length; i++)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                workflowArray[i] = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Workflow&lt;/span&gt;(itemArray[i].ID.ToString(), &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; workflowArray;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;Third. Configure Sitecore solution to work with this customization. Below is a complete example of UniversalWorkflow.config file that could be placed into /App_Config/Include folder to enable this customization:&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f134fdb0-25bc-411a-8a24-c38478736015" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;xmlns:patch&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;http://www.sitecore.net/xmlconfig/&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;  &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;sitecore&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;databases&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;database&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;id&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;master&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;workflowProvider&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;patch:attribute&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;name&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;type&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;TwinPeaks.Workflows.WorkflowProvider, TwinPeaks.Workflows&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;patch:attribute&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;workflowProvider&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;database&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;databases&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;accessRights&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;defaultProvider&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;config&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;rules&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515"&gt;add&lt;/span&gt;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;prefix&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;workflowState:write&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt; &lt;/span&gt;&lt;span style="color:#ff0000"&gt;typeName&lt;/span&gt;&lt;span style="color:#0000ff"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;Sitecore.Data.Items.Item&lt;/span&gt;&amp;quot;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;rules&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;accessRights&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;  &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;sitecore&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;p&gt;Why is this solution is worth to blog about? Because it allows us to address all the requirements by customizing only one thing – Workflow class. Both Workbox and Content Editor will respect security configuration if “check required” field is selected on a workflow state item.&lt;/p&gt; &lt;p&gt;Feel free to share your thoughts on this approach as well as suggest improvements or even better solution.&lt;br&gt;Hope you find it helpful.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-3031489257672163278?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/3031489257672163278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=3031489257672163278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/3031489257672163278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/3031489257672163278'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/10/all-in-1-workflow.html' title='All-in-1 Workflow'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_gDIVYhqZmFo/TMdHKBSRCqI/AAAAAAAAIL8/-4ankaryFJc/s72-c/image_thumb3.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-8670509970573191107</id><published>2010-10-20T15:17:00.000-07:00</published><updated>2011-03-09T12:49:45.313-08:00</updated><title type='text'>Sitecore Lucene index does not remove old data</title><content type='html'>&lt;p&gt;Looks like interest to Sitecore implementation of Lucene index has raised since &lt;a href="http://dreamcore.sitecore.net/" target="_blank"&gt;Dream Core&lt;/a&gt; event and developers have run into an issue with old data being kept in the index repository. In this article I want to show you how to go around this issue.&lt;br&gt;First of all let’s see why it’s happening. I ran into this issue when I started playing with new implementation of Lucene index in Sitecore 6. When I created an output of the results I saw duplicates of my data in there. I stated debugging my code and found that Lucene somehow recognizes raw GUID’s which breaks search criteria that Sitecore uses to find items during update/delete procedure. &lt;br&gt;To solve this issue I had to create additional field for Lucene index (_shorttemplateid) and store there short GUID for an item (item.ID.ToShortID()). Then override AddMatchCriteria method and dependent properties to use short template GUID for matching criteria. Below is the code example.&lt;br&gt;&lt;br&gt;&lt;/p&gt; &lt;p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:42b7f9bf-4f6c-4e13-b6d1-2f222b8d3f96" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 3em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; LuceneExamples&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;   &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DatabaseCrawler&lt;/span&gt; : Sitecore.Search.Crawlers.&lt;span style="color:#2b91af"&gt;DatabaseCrawler&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   {&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;#region&lt;/span&gt; Fields&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; _hasIncludes;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; _hasExcludes;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; _templateFilter;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArrayList&lt;/span&gt; _customFields;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#endregion&lt;/span&gt; Fields&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#region&lt;/span&gt; ctor&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; DatabaseCrawler()&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         _templateFilter = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt;();&lt;/li&gt; &lt;li&gt;         _customFields = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArrayList&lt;/span&gt;();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#endregion&lt;/span&gt; ctor&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#region&lt;/span&gt; Base class methods&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;// Should be overriden to add date fields in &amp;quot;yyyyMMddHHmmss&amp;quot; format. Otherwise it&amp;#39;s not possible to create range queries for date values.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#008000"&gt;// Also adds _shorttemplateid field which has a template id in ShortID format.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddAllFields(&lt;span style="color:#2b91af"&gt;Document&lt;/span&gt; document, &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; versionSpecific)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(document, &lt;span style="color:#a31515"&gt;&amp;quot;document&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         Sitecore.Collections.&lt;span style="color:#2b91af"&gt;FieldCollection&lt;/span&gt; fields = item.Fields;&lt;/li&gt; &lt;li&gt;         fields.ReadAll();&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (Sitecore.Data.Fields.&lt;span style="color:#2b91af"&gt;Field&lt;/span&gt; field &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; fields)&lt;/li&gt; &lt;li&gt;         {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(field.Key) &amp;amp;&amp;amp; (field.Shared != versionSpecific))&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; tokenize = &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.IsTextField(field);&lt;/li&gt; &lt;li&gt;               &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (IndexAllFields)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               {&lt;/li&gt; &lt;li&gt;                  &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (field.TypeKey == &lt;span style="color:#a31515"&gt;&amp;quot;date&amp;quot;&lt;/span&gt; || field.TypeKey == &lt;span style="color:#a31515"&gt;&amp;quot;datetime&amp;quot;&lt;/span&gt;)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  {&lt;/li&gt; &lt;li&gt;                     IndexDateFields(document, field.Key, field.Value);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  }&lt;/li&gt; &lt;li&gt;                  &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  {&lt;/li&gt; &lt;li&gt;                     document.Add(CreateField(field.Key, field.Value, tokenize, 1f));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  }&lt;/li&gt; &lt;li&gt;               }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;               &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (tokenize)&lt;/li&gt; &lt;li&gt;               {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                  document.Add(CreateField(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Content, field.Value, &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;, 1f));&lt;/li&gt; &lt;li&gt;               }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;         }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         AddShortTemplateId(document, item);&lt;/li&gt; &lt;li&gt;         AddCustomFields(document, item);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Loops through the collection of custom fields and adds them to fields collection of each indexed item.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;document&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Lucene document&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Sitecore data item&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddCustomFields(&lt;span style="color:#2b91af"&gt;Document&lt;/span&gt; document, &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;CustomField&lt;/span&gt; field &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; _customFields)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            document.Add(CreateField(field.LuceneFieldName, field.GetFieldValue(item), field.StorageType, field.IndexType, Boost));&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Creates a Lucene field.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;fieldKey&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Field name&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;fieldValue&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Field value&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;storeType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Storage option&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;indexType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Index type&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;boost&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Boosting parameter&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Fieldable&lt;/span&gt; CreateField(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; fieldKey, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; fieldValue, &lt;span style="color:#2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Store&lt;/span&gt; storeType, &lt;span style="color:#2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Index&lt;/span&gt; indexType, &lt;span style="color:#0000ff"&gt;float&lt;/span&gt; boost)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#2b91af"&gt;Field&lt;/span&gt; field = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Field&lt;/span&gt;(fieldKey, fieldValue, storeType, indexType);&lt;/li&gt; &lt;li&gt;         field.SetBoost(boost);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; field;&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Parses a configuration entry for a custom field and adds it to a collection of custom fields.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;node&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Configuration entry&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddCustomField(&lt;span style="color:#2b91af"&gt;XmlNode&lt;/span&gt; node)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#2b91af"&gt;CustomField&lt;/span&gt; field = &lt;span style="color:#2b91af"&gt;CustomField&lt;/span&gt;.ParseConfigNode(node);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (field == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;         {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;Could not parse custom field entry: &amp;quot;&lt;/span&gt; + node.OuterXml);&lt;/li&gt; &lt;li&gt;         }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         _customFields.Add(field);&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#008000"&gt;// Method should use _shorttemplateid to allow one create combined/boolean search queries with template id reference.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;// Also used to create a matching criteria for update/delete actions.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddMatchCriteria(&lt;span style="color:#2b91af"&gt;BooleanQuery&lt;/span&gt; query)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Database, Database)), &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Path, Sitecore.Data.&lt;span style="color:#2b91af"&gt;ShortID&lt;/span&gt;.Encode(Root).ToLowerInvariant())), &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (HasIncludes || HasExcludes)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; pair &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; TemplateFilter)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;               query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Constants&lt;/span&gt;.ShortTemplate, Sitecore.Data.&lt;span style="color:#2b91af"&gt;ShortID&lt;/span&gt;.Encode(pair.Key).ToLowerInvariant())), pair.Value ? &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.SHOULD : &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST_NOT);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;         }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;// Method should be overriden because _hasIncludes and _hasExcludes variables were introduced.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsMatch(&lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;          &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; flag;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(item, &lt;span style="color:#a31515"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;          &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!RootItem.Axes.IsAncestorOf(item))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          {&lt;/li&gt; &lt;li&gt;              &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          }&lt;/li&gt; &lt;li&gt;          &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!HasIncludes &amp;amp;&amp;amp; !HasExcludes)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          {&lt;/li&gt; &lt;li&gt;              &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          }&lt;/li&gt; &lt;li&gt;          &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!TemplateFilter.TryGetValue(item.TemplateID.ToString(), &lt;span style="color:#0000ff"&gt;out&lt;/span&gt; flag))&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          {&lt;/li&gt; &lt;li&gt;              &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; !HasIncludes;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;          }&lt;/li&gt; &lt;li&gt;          &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; flag;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;// Method required to override AddMatchCriteria one.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; IncludeTemplate(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; templateId)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(templateId, &lt;span style="color:#a31515"&gt;&amp;quot;templateId&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         _hasIncludes = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;         _templateFilter[templateId] = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#008000"&gt;// Method required to override AddMatchCriteria one.&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; ExcludeTemplate(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; templateId)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(templateId, &lt;span style="color:#a31515"&gt;&amp;quot;templateId&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         _hasExcludes = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;         _templateFilter[templateId] = &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#endregion&lt;/span&gt; Base class methods&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Converts Sitecore date and datetime fields to the recognizable format for Lucene API.&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;doc&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Lucene document object&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;fieldKey&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Field name&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;fieldValue&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Field value&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; IndexDateFields(&lt;span style="color:#2b91af"&gt;Document&lt;/span&gt; doc, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; fieldKey, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; fieldValue)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#2b91af"&gt;DateTime&lt;/span&gt; dateTime = Sitecore.&lt;span style="color:#2b91af"&gt;DateUtil&lt;/span&gt;.IsoDateToDateTime(fieldValue);&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; luceneDate = &lt;span style="color:#a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (dateTime != &lt;span style="color:#2b91af"&gt;DateTime&lt;/span&gt;.MinValue)&lt;/li&gt; &lt;li&gt;         {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            luceneDate = dateTime.ToString(&lt;span style="color:#2b91af"&gt;Constants&lt;/span&gt;.DateTimeFormat);&lt;/li&gt; &lt;li&gt;         }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         doc.Add(CreateField(fieldKey, luceneDate, &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;, 1f));&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; Adds template id in ShortID format&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;doc&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Lucene document object&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#808080"&gt;///&lt;/span&gt;&lt;span style="color:#008000"&gt; &lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color:#008000"&gt;Sitecore item&lt;/span&gt;&lt;span style="color:#808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddShortTemplateId(&lt;span style="color:#2b91af"&gt;Document&lt;/span&gt; doc, &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; item)&lt;/li&gt; &lt;li&gt;      {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         doc.Add(CreateField(&lt;span style="color:#2b91af"&gt;Constants&lt;/span&gt;.ShortTemplate, Sitecore.Data.&lt;span style="color:#2b91af"&gt;ShortID&lt;/span&gt;.Encode(item.TemplateID).ToLowerInvariant(), &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;, 1f));&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;#region&lt;/span&gt; Properties&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; HasIncludes&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _hasIncludes;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            _hasIncludes = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; HasExcludes&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _hasExcludes;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            _hasExcludes = &lt;span style="color:#0000ff"&gt;value&lt;/span&gt;;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; TemplateFilter&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; _templateFilter;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         }&lt;/li&gt; &lt;li&gt;      }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; RootItem&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      {&lt;/li&gt; &lt;li&gt;         &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;         {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; Sitecore.Data.Managers.&lt;span style="color:#2b91af"&gt;ItemManager&lt;/span&gt;.GetItem(Root, Sitecore.Globalization.&lt;span style="color:#2b91af"&gt;Language&lt;/span&gt;.Invariant,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                              Sitecore.Data.&lt;span style="color:#2b91af"&gt;Version&lt;/span&gt;.Latest,&lt;/li&gt; &lt;li&gt;                                                              Sitecore.Data.&lt;span style="color:#2b91af"&gt;Database&lt;/span&gt;.GetDatabase(Database),&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                              Sitecore.SecurityModel.&lt;span style="color:#2b91af"&gt;SecurityCheck&lt;/span&gt;.Disable);&lt;/li&gt; &lt;li&gt;         }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;      &lt;span style="color:#0000ff"&gt;#endregion&lt;/span&gt; Properties&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;   }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;&lt;/p&gt; &lt;p&gt;This should solve this issue as well as add Lucene recognizable format for Sitecore date and datetime field types. Also it will allow to build Combined and Boolean search queries.&lt;br&gt;&lt;/p&gt; &lt;p&gt;Update. Code for the Constants class:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt; &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; LuceneExamples&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Constants&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;    {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;       &lt;span style="color: #008000"&gt;// special field for template id in ShortID format&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ShortTemplate = &lt;span style="color: #006080"&gt;"_shorttemplateid"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt;       &lt;span style="color: #008000"&gt;// searchable date-time format. All datetime field&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; DateTimeFormat = &lt;span style="color: #006080"&gt;"yyyyMMddHHmmss"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt;       &lt;span style="color: #008000"&gt;// Path to lucene setting items: /sitecore/system/Settings/Lucene&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; LuceneSettingsPath = &lt;span style="color: #006080"&gt;"{89783047-026C-45B5-AB5B-338E4A22446C}"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;    }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Hope it saves someone a minute or two.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-8670509970573191107?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/8670509970573191107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=8670509970573191107' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8670509970573191107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8670509970573191107'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html' title='Sitecore Lucene index does not remove old data'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2315435169347766261</id><published>2010-10-01T16:40:00.001-07:00</published><updated>2011-03-09T12:48:25.360-08:00</updated><title type='text'>Remove old data form the index for Sitecore 6.2 (Update-4) and 6.3</title><content type='html'>&lt;p&gt;Previously I published &lt;a href="http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html"&gt;an article&lt;/a&gt; explaining how to fix a glitch in Sitecore index that keeps old data after updating an item. In this article I updated the code since some issues were fixed in Sitecore 6.2 (Update-4) and 6.3.&lt;/p&gt; &lt;p&gt;Starting from 6.2 (Update-4) and 6.3 the _template field in Lucene index stores an item ID in ShortID format. Now it’s even easier to customize the DatabaseCrawler as the following methods were made virtual: AddItem, IndexVersion, DeleteItem and DeleteVersion. Also fields _hasIncludes, _hasExludes and _templateFilder were made protected which helps to shrink the fix even more.&lt;/p&gt; &lt;p&gt;Here is the code that fixes the outlined problem for these releases:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:af188f33-01db-43fe-bf70-32e9f083109c" class="wlWriterEditableSmartContent"&gt; &lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt; &lt;div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px"&gt;Code Snippet&lt;/div&gt; &lt;div style="background: #ddd; max-height: 300px; overflow: auto"&gt; &lt;ol style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff"&gt;namespace&lt;/span&gt; Lucene.Search.Crawlers&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;DatabaseCrawler&lt;/span&gt; : Sitecore.Search.Crawlers.&lt;span style="color:#2b91af"&gt;DatabaseCrawler&lt;/span&gt;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; AddMatchCriteria(Net.Search.&lt;span style="color:#2b91af"&gt;BooleanQuery&lt;/span&gt; query)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Database, RootItem.Database.Name)), &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Path, &lt;span style="color:#2b91af"&gt;ShortID&lt;/span&gt;.Encode(RootItem.ID).ToLowerInvariant())), &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;._hasIncludes || &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;._hasExcludes)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;KeyValuePair&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt;&amp;gt; pair &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;._templateFilter)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                {&lt;/li&gt; &lt;li&gt;                    query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.Template, &lt;span style="color:#2b91af"&gt;ShortID&lt;/span&gt;.Encode(pair.Key).ToLowerInvariant())), pair.Value ? &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.SHOULD : &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST_NOT);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                }&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Item&lt;/span&gt; RootItem&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; Sitecore.Data.Managers.&lt;span style="color:#2b91af"&gt;ItemManager&lt;/span&gt;.GetItem(Root, Sitecore.Globalization.&lt;span style="color:#2b91af"&gt;Language&lt;/span&gt;.Invariant,&lt;/li&gt; &lt;li&gt;                                                                  Sitecore.Data.&lt;span style="color:#2b91af"&gt;Version&lt;/span&gt;.Latest,&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;                                                                  Sitecore.Data.&lt;span style="color:#2b91af"&gt;Database&lt;/span&gt;.GetDatabase(Database),&lt;/li&gt; &lt;li&gt;                                                                  Sitecore.SecurityModel.&lt;span style="color:#2b91af"&gt;SecurityCheck&lt;/span&gt;.Disable);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            }&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Query&lt;/span&gt; GetVersionQuery(&lt;span style="color:#2b91af"&gt;ID&lt;/span&gt; id, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; language, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; version)&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNull(id, &lt;span style="color:#a31515"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(language, &lt;span style="color:#a31515"&gt;&amp;quot;language&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af"&gt;Assert&lt;/span&gt;.ArgumentNotNullOrEmpty(version, &lt;span style="color:#a31515"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#2b91af"&gt;BooleanQuery&lt;/span&gt; query = &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;BooleanQuery&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;            query.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;TermQuery&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;Term&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;BuiltinFields&lt;/span&gt;.ID, GetItemID(id, language, version).ToLowerInvariant())), &lt;span style="color:#2b91af"&gt;BooleanClause&lt;/span&gt;.&lt;span style="color:#2b91af"&gt;Occur&lt;/span&gt;.MUST);&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;            &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.AddMatchCriteria(query);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; query;&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;        }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background: #f3f3f3"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Basically you need to make sure that the result of GetItemID method is in lower case as well as a term for _path field, in AddMatchCriteria method, is constructed with lower case query.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-2315435169347766261?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/2315435169347766261/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=2315435169347766261' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2315435169347766261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2315435169347766261'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/10/remove-old-data-form-index-for-sitecore.html' title='Remove old data form the index for Sitecore 6.2 (Update-4) and 6.3'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-1865361081035253937</id><published>2010-08-31T10:57:00.001-07:00</published><updated>2010-08-31T11:17:25.922-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lucene'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='index'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><title type='text'>Adding custom fields to the index</title><content type='html'>&lt;p&gt;In this post I want to show how to address a missing feature that was a part of “old” lucene index implementation. This article will provide an example how one can customize Lucene search configuration so that it’s possible to add custom fields to the index.&lt;/p&gt;  &lt;p&gt;First off, let’s create a configuration that would allow us to add additional fields to the indexed data.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;index &lt;/span&gt;&lt;span style="color: red"&gt;id&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;News&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Sitecore.Search.Index, Sitecore.Kernel&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;desc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;name&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;$(id)&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&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;param &lt;/span&gt;&lt;span style="color: red"&gt;desc&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;folder&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;_&lt;/span&gt;news&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&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;Analyzer &lt;/span&gt;&lt;span style="color: red"&gt;ref&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;search/analyzer&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;locations &lt;/span&gt;&lt;span style="color: red"&gt;hint&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;list:AddCrawler&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;examples-news &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;LuceneExamples.DatabaseCrawler,LuceneExamples&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Database&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;web&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Database&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;Root&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;/sitecore/content&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Root&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;IndexAllFields&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;IndexAllFields&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;include &lt;/span&gt;&lt;span style="color: red"&gt;hint&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;list:IncludeTemplate&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;news&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{788EF1BE-B71E-4D59-9276-50519BD4F641}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;news&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;tag&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;{4DD970FB-2695-4E50-96F3-A766F7D6CAF1}&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;tag&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;include&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;fields &lt;/span&gt;&lt;span style="color: red"&gt;hint&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;raw:AddCustomField&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;br /&gt;        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;field &lt;/span&gt;&lt;span style="color: red"&gt;luceneName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;author&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;storageType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;no&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;indexType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;tokenized&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;__updated by&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;field&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;field &lt;/span&gt;&lt;span style="color: red"&gt;luceneName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;changed&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;storageType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;yes&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;indexType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;untokenized&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;__updated&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;field&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;fields&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;examples-news&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;locations&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;index&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;There is a new configuration section in this example. It’s &amp;lt;fields&amp;gt; section that introduces two fields “author” and “changed”. These fields will be added to a fields collection of each indexed item. Basically, there is &lt;strong&gt;AddCustomField&lt;/strong&gt; method that gets called for every &amp;lt;field&amp;gt; configuration entry to identify a custom field that is going to be added to the fields collection.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Description of configuration attributes:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;luceneName&amp;#160; is a field name that appears in lucene index.&lt;/li&gt;&lt;li&gt;storageType&amp;#160; is a storage type for lucene field. It can have the following values:&lt;ul&gt;&lt;li&gt;no&lt;/li&gt;&lt;li&gt;yes &lt;/li&gt;&lt;li&gt;compress&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;indexType&amp;#160; is an index type for lucene field. It can have the following values:&lt;ul&gt;&lt;li&gt;no &lt;/li&gt;&lt;li&gt;tokenized &lt;/li&gt;&lt;li&gt;untokenized &lt;/li&gt;&lt;li&gt;nonorms &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Refere to Lucene documentation to find out what each of these options mean: &lt;a href="http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/document/Field.Store.html" target="_blank"&gt;store&lt;/a&gt; and &lt;a href="http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/document/Field.Index.html" target="_blank"&gt;index&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now all you need to do is to loop through the collection of custom fields in the overridden &lt;strong&gt;AddAllFields&lt;/strong&gt; method and add them to the indexed data.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I created a custom class called CustomField that helps to manage custom field entries. Below is the example of this class as well as additional methods for extended DatabaseCrawler. Since code for the DatabaseCrawler was already published in &lt;a href="http://sitecoregadgets.blogspot.com/2010/07/sitecore-lucene-index-does-not-remove.html" target="_blank"&gt;this blog post&lt;/a&gt;, I’m not going to duplicate it here.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here is a code for CustomField class.&lt;/p&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Xml;&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.Xml;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Lucene.Net.Documents;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;LuceneExamples&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CustomField&lt;br /&gt;   &lt;/span&gt;{&lt;br /&gt;      &lt;span style="color: blue"&gt;public &lt;/span&gt;CustomField()&lt;br /&gt;      {&lt;br /&gt;         FieldID = &lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.Null;&lt;br /&gt;         FieldName = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;         LuceneFieldName = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ID &lt;/span&gt;FieldID&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: blue"&gt;get&lt;/span&gt;;&lt;br /&gt;         &lt;span style="color: blue"&gt;private set&lt;/span&gt;;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public string &lt;/span&gt;FieldName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store &lt;/span&gt;StorageType { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index &lt;/span&gt;IndexType { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public string &lt;/span&gt;LuceneFieldName { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;private set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CustomField &lt;/span&gt;ParseConfigNode(&lt;span style="color: #2b91af"&gt;XmlNode &lt;/span&gt;node)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #2b91af"&gt;CustomField &lt;/span&gt;field = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;CustomField&lt;/span&gt;();&lt;br /&gt;         &lt;span style="color: blue"&gt;string &lt;/span&gt;fieldName = &lt;span style="color: #2b91af"&gt;XmlUtil&lt;/span&gt;.GetValue(node);&lt;br /&gt;         &lt;span style="color: blue"&gt;if &lt;/span&gt;(&lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.IsID(fieldName))&lt;br /&gt;         {&lt;br /&gt;            field.FieldID = &lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.Parse(fieldName);&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: blue"&gt;else&lt;br /&gt;         &lt;/span&gt;{&lt;br /&gt;            field.FieldName = fieldName;&lt;br /&gt;         }&lt;br /&gt;         field.LuceneFieldName = &lt;span style="color: #2b91af"&gt;XmlUtil&lt;/span&gt;.GetAttribute(&lt;span style="color: #a31515"&gt;&amp;quot;luceneName&amp;quot;&lt;/span&gt;, node);&lt;br /&gt;         field.StorageType = GetStorageType(node);&lt;br /&gt;         field.IndexType = GetIndexType(node);&lt;br /&gt;&lt;br /&gt;         &lt;span style="color: blue"&gt;if &lt;/span&gt;(!IsValidField(field))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;return null&lt;/span&gt;;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         &lt;span style="color: blue"&gt;return &lt;/span&gt;field;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;public string &lt;/span&gt;GetFieldValue(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;item)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.IsNullOrEmpty(FieldID))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;item[&lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.Parse(FieldID)];&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(FieldName))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;return &lt;/span&gt;item[FieldName];&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: blue"&gt;return string&lt;/span&gt;.Empty;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;private static bool &lt;/span&gt;IsValidField(&lt;span style="color: #2b91af"&gt;CustomField &lt;/span&gt;field)&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(field.FieldName) || !&lt;span style="color: #2b91af"&gt;ID&lt;/span&gt;.IsNullOrEmpty(field.FieldID)) &amp;amp;&amp;amp; !&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(field.LuceneFieldName))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;return true&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;br /&gt;      &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index &lt;/span&gt;GetIndexType(&lt;span style="color: #2b91af"&gt;XmlNode &lt;/span&gt;node)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: blue"&gt;string &lt;/span&gt;indexType = &lt;span style="color: #2b91af"&gt;XmlUtil&lt;/span&gt;.GetAttribute(&lt;span style="color: #a31515"&gt;&amp;quot;indexType&amp;quot;&lt;/span&gt;, node);&lt;br /&gt;         &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(indexType))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;switch &lt;/span&gt;(indexType.ToLowerInvariant())&lt;br /&gt;            {&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index&lt;/span&gt;.NO;&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;tokenized&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index&lt;/span&gt;.TOKENIZED;&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;untokenized&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index&lt;/span&gt;.UN_TOKENIZED;&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;nonorms&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index&lt;/span&gt;.NO_NORMS;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index&lt;/span&gt;.TOKENIZED;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color: blue"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store &lt;/span&gt;GetStorageType(&lt;span style="color: #2b91af"&gt;XmlNode &lt;/span&gt;node)&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: blue"&gt;string &lt;/span&gt;storage = &lt;span style="color: #2b91af"&gt;XmlUtil&lt;/span&gt;.GetAttribute(&lt;span style="color: #a31515"&gt;&amp;quot;storageType&amp;quot;&lt;/span&gt;, node);&lt;br /&gt;         &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(storage))&lt;br /&gt;         {&lt;br /&gt;            &lt;span style="color: blue"&gt;switch &lt;/span&gt;(storage.ToLowerInvariant())&lt;br /&gt;            {&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;no&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store&lt;/span&gt;.NO;&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store&lt;/span&gt;.YES;&lt;br /&gt;               &lt;span style="color: blue"&gt;case &lt;/span&gt;&lt;span style="color: #a31515"&gt;&amp;quot;compress&amp;quot;&lt;/span&gt;:&lt;br /&gt;                  &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store&lt;/span&gt;.COMPRESS;&lt;br /&gt;            }&lt;br /&gt;         }&lt;br /&gt;         &lt;span style="color: blue"&gt;return &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store&lt;/span&gt;.NO;&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;p&gt;And the code for additional methods for DatabaseCrawler.&lt;/p&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;br /&gt;/// &lt;/span&gt;&lt;span style="color: green"&gt;Loops through the collection of custom fields and adds them to fields collection of each indexed item.&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;document&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Lucene document&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;item&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Sitecore data item&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;private void &lt;/span&gt;AddCustomFields(&lt;span style="color: #2b91af"&gt;Document &lt;/span&gt;document, &lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;item)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: blue"&gt;foreach&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;CustomField &lt;/span&gt;field &lt;span style="color: blue"&gt;in &lt;/span&gt;_customFields)&lt;br /&gt;   {&lt;br /&gt;      document.Add(CreateField(field.LuceneFieldName, field.GetFieldValue(item), field.StorageType, field.IndexType, Boost));&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&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;Creates a Lucene field.&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;fieldKey&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Field name&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;fieldValue&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Field value&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;storeType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Storage option&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;indexType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Index type&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name=&amp;quot;boost&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Boosting parameter&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;private &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Fieldable &lt;/span&gt;CreateField(&lt;span style="color: blue"&gt;string &lt;/span&gt;fieldKey, &lt;span style="color: blue"&gt;string &lt;/span&gt;fieldValue, &lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Store &lt;/span&gt;storeType, &lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;.&lt;span style="color: #2b91af"&gt;Index &lt;/span&gt;indexType, &lt;span style="color: blue"&gt;float &lt;/span&gt;boost)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #2b91af"&gt;Field &lt;/span&gt;field = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Field&lt;/span&gt;(fieldKey, fieldValue, storeType, indexType);&lt;br /&gt;   field.SetBoost(boost);&lt;br /&gt;   &lt;span style="color: blue"&gt;return &lt;/span&gt;field;&lt;br /&gt;}&lt;br /&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;Parses a configuration entry for a custom field and adds it to a collection of custom fields.&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;node&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Configuration entry&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;AddCustomField(&lt;span style="color: #2b91af"&gt;XmlNode &lt;/span&gt;node)&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color: #2b91af"&gt;CustomField &lt;/span&gt;field = &lt;span style="color: #2b91af"&gt;CustomField&lt;/span&gt;.ParseConfigNode(node);&lt;br /&gt;   &lt;span style="color: blue"&gt;if &lt;/span&gt;(field == &lt;span style="color: blue"&gt;null&lt;/span&gt;)&lt;br /&gt;   {&lt;br /&gt;      &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Could not parse custom field entry: &amp;quot; &lt;/span&gt;+ node.OuterXml);&lt;br /&gt;   }&lt;br /&gt;   _customFields.Add(field);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Last thing that is left to do is to call AddCustomFields method from AddAllFields one.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="color: blue"&gt;protected override void &lt;/span&gt;AddAllFields (&lt;span style="color: #2b91af"&gt;Document&lt;/span&gt;document, &lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;item, &lt;span style="color: blue"&gt;bool &lt;/span&gt;versionSpecific) &lt;br /&gt; {&lt;br /&gt;   &amp;#160;&amp;#160;&amp;#160; ………………………………………&lt;br /&gt;   &amp;#160;&amp;#160;&amp;#160; AddCustomFields(document, item); &lt;br /&gt; }&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You can take it even further and add support for some field interpreter for each field configuration entry.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Hope you'll find it useful.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-1865361081035253937?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/1865361081035253937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=1865361081035253937' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1865361081035253937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1865361081035253937'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/08/adding-custom-fields-to-index.html' title='Adding custom fields to the index'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-5053570793654827073</id><published>2010-08-03T15:06:00.001-07:00</published><updated>2010-08-03T15:33:13.934-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='custom fields'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore Fields'/><title type='text'>Language filtered Multilist field</title><content type='html'>&lt;p&gt;Recently I happened to help one of our clients to create a custom Multilist field that gives you selecting options only if item has&amp;#160; at least one translated version in a current content language. From content author’s point of view it makes a lot of sense. Why to give them an option that is not useful?&lt;/p&gt;  &lt;p&gt;It’s being a while since I created a custom field that has to take into account content language selection. The main challenge for me was to retrieve that content language. I did remember that there is a property that the Content Editor (CE) sets at run-time for every field but could not recall its name. So after several minutes of browsing my code storage of all samples for all Sitecore versions, I finally found it. So, here are the properties that you need to define in your custom field if you are planning to use them afterwards:&lt;/p&gt;  &lt;p&gt;- ItemLanauage – represents a content language selected in the CE.&lt;/p&gt;  &lt;p&gt;- ItemID – contains the item ID the field belongs to.&lt;/p&gt;  &lt;p&gt;- ItemVersion – contains selected item version.&lt;/p&gt;  &lt;p&gt;- ReadOnly – indicates if field is a readonly. If it is, then it will be grayed out and not editable.&lt;/p&gt;  &lt;p&gt;- Source – represents the source value from field definition on a data template.&lt;/p&gt;  &lt;p&gt;- FieldID – contains the field ID.&lt;/p&gt;  &lt;p&gt;In my example I needed only ItemLanguage property. When I put things together the code looked like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Shell.Applications.ContentEditor;&lt;br /&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;Sitecore.Data.Items;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: blue"&gt;namespace &lt;/span&gt;Sitecore.Shell.Applications.ContentEditor.CustomExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;LanguageFilteredMultilist &lt;/span&gt;: Sitecore.Shell.Applications.ContentEditor.&lt;span style="color: #2b91af"&gt;MultilistEx&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;        &lt;span style="color: blue"&gt;#region &lt;/span&gt;Overrides&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;protected override &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;[] GetItems(&lt;span style="color: #2b91af"&gt;Item &lt;/span&gt;current)&lt;br /&gt;        {              &lt;br /&gt;            &lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;[] items = &lt;span style="color: blue"&gt;base&lt;/span&gt;.GetItems(current);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: blue"&gt;var &lt;/span&gt;filteredItems = items.Where(item =&amp;gt; &lt;br /&gt;                    {&lt;br /&gt;                        &lt;span style="color: blue"&gt;string &lt;/span&gt;lang = ItemLanguage;&lt;br /&gt;                        &lt;span style="color: blue"&gt;if &lt;/span&gt;(!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(lang))&lt;br /&gt;                        {&lt;br /&gt;                            &lt;span style="color: blue"&gt;var &lt;/span&gt;versions = Sitecore.Data.Managers.&lt;span style="color: #2b91af"&gt;ItemManager&lt;/span&gt;.GetVersions(item, Sitecore.Data.Managers.&lt;span style="color: #2b91af"&gt;LanguageManager&lt;/span&gt;.GetLanguage(lang, item.Database));&lt;br /&gt;                            &lt;span style="color: blue"&gt;return &lt;/span&gt;versions.Count &amp;gt; 0;&lt;br /&gt;                        }&lt;br /&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;span style="color: blue"&gt;return &lt;/span&gt;filteredItems.ToArray&amp;lt;&lt;span style="color: #2b91af"&gt;Item&lt;/span&gt;&amp;gt;();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: blue"&gt;#endregion &lt;/span&gt;Overrides&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: green"&gt;// Content Editor sets this property. It has a content language from the Content Editor.&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: blue"&gt;public string &lt;/span&gt;ItemLanguage&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: blue"&gt;get&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color: blue"&gt;set&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Simple enough isn’t it. Don’t forget to add your custom field to /App_Config/FieldTypes.config file if it’s supposed to contain references to other items. In my case it should be added since it’s a multilist. If you forget to do it, the LinkDatabase won’t update references for your field.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That’s all for now.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-5053570793654827073?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/5053570793654827073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=5053570793654827073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/5053570793654827073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/5053570793654827073'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/08/language-filtered-multilist-field.html' title='Language filtered Multilist field'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-791820903619949352</id><published>2010-07-02T16:54:00.000-07:00</published><updated>2010-07-02T16:57:06.331-07:00</updated><title type='text'>Teach User Manager how to search by email</title><content type='html'>A couple of days ago one interesting issue popped out in my Inbox. Our customer wanted to search users by email address in User Manager application. Quite legitimate request. Especially if you have an integration with AD or CRM or whatever external security system with large number of users. I tried a couple of configuration changes with no luck. Then checked our support portal knowledge base and saw several request like that. I was surprised by the fact that you cannot search users by email.&lt;br /&gt;&lt;div&gt;After spending several hours investigating how search functionality in User Manager works and doing some "shaman dancing" around it, I ended up with a solution that requires to override a standard Sitecore.Security.Accounts.UserProvider and change its method called "GetUsersByName". As it turned out, search functionality of User Manager calls the GetUserByName method when one searches for a user.&lt;/div&gt;&lt;div&gt;This is how it looks:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="padding: 0 0 0 30px;"&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;namespace Sitecore.SharedSource.Security.Accounts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    public class UserProvider : Sitecore.Security.Accounts.UserProvider&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        protected override IEnumerable&lt;user&gt; GetUsersByName(int pageIndex, int pageSize, string userNameToMatch)&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            return FindUsers(pageIndex, pageSize, userNameToMatch);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        protected IEnumerable&lt;user&gt; FindUsers(int pageIndex, int pageSize, string userNameToMatch)&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            Assert.ArgumentNotNull(userNameToMatch, "userNameToMatch");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            IEnumerable&lt;user&gt; users = null;&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            string userWithNoWildcard = StringUtil.RemovePostfix(Settings.Authentication.VirtualMembershipWildcard, StringUtil.RemovePrefix(Settings.Authentication.VirtualMembershipWildcard, userNameToMatch));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            if (Regex.IsMatch(userWithNoWildcard, @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$"))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                users = findByEmail(pageIndex, pageSize, userWithNoWildcard);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            else&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                users = findUsername(pageIndex, pageSize, userNameToMatch);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            return users;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        protected IEnumerable&lt;user&gt; findUsername(int pageIndex, int pageSize, string username)&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            int total;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            return new Enumerable&lt;user&gt;(delegate&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                    return Membership.FindUsersByName(username, pageIndex, pageSize, out total).GetEnumerator();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                },&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                delegate(object user)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                    return User.FromName(((MembershipUser)user).UserName, false);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                });&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        protected IEnumerable&lt;user&gt; findByEmail(int pageIndex, int pageSize, string userToMatch)&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            int total;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;            return new Enumerable&lt;user&gt;(delegate&lt;/user&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                    return Membership.FindUsersByEmail(userToMatch, pageIndex, pageSize, out total).GetEnumerator();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                },&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                delegate(object user)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                    return User.FromName(((MembershipUser)user).UserName, false);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;                });&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That's it! Simple enough, isn't it.&lt;/div&gt;&lt;div&gt;Thanks to &lt;a href="http://sitecoreblog.alexshyba.com/"&gt;Alex Shyba&lt;/a&gt; who helped me with some useful code!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After compiling the code and moving a dll to the /bin folder, don't forget to change a reference in web.config file to point it to a new UserProvider class.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;userManager defaultProvider="default" enabled="true"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;providers&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;clear /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;add name="default"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;x:attribute name="type"&amp;gt;Sitecore.SharedSource.Security.Accounts.UserProvider, &lt;span class="Apple-style-span" style="color: #6aa84f;"&gt;YOUR_DLL_HERE&lt;/span&gt;&amp;lt;/x:attribute&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/providers&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;lt;/userManager&amp;gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;For those who consider this so easy so that it's now worth to create a VS project I've built a ready-to-go Sitecore package with a dll and include file inside. Just install it and give it a try ;).&lt;/div&gt;&lt;div&gt;This is a &lt;a href="http://scusainc.com/SupportResources/ivan/Security/UserProvider/UserManager2-1.0.0.zip"&gt;Sitecore package&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enjoy!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-791820903619949352?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/791820903619949352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=791820903619949352' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/791820903619949352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/791820903619949352'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2010/07/teach-user-manager-how-to-search-by.html' title='Teach User Manager how to search by email'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-7431877801576788621</id><published>2009-11-25T14:33:00.000-08:00</published><updated>2009-11-25T16:29:23.588-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lucene'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='index'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>Working with Lucene Search Index in Sitecore 6. Part III - Code examples</title><content type='html'>&lt;div&gt;If you read my previous posts about Lucene search index, then you already know how to configure it and how it works in Sitecore application.&lt;/div&gt;&lt;div&gt;In this part we will take a look at API to see what can be achieved using the search index.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To search existing index we need to get an index instance somehow. I'm not going to show the code examples that you would write with old search index. If you're intrested in it, check out this article &lt;a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx"&gt;Lecene Search Engine&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;Additional layer of API for new search index resides under &lt;span class="Apple-style-span"  style="color:#009900;"&gt;Sitecore.Search&lt;/span&gt; namespace. In order to get a search index object, you would need to use members of SearchManager class.&lt;/div&gt;&lt;div&gt;To get an index by name use this line of code:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;Index indx = Search.Manager.GetIndex(index_name);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;If you want to use default system index, you can simply call &lt;span class="Apple-style-span"  style="color:#009900;"&gt;SystemIndex&lt;/span&gt; property of &lt;span class="Apple-style-span"  style="color:#009900;"&gt;SearchManager&lt;/span&gt; class. In order to use Sitecore API to look up for some info in the index, you need to created a search context.&lt;/div&gt;&lt;div&gt;It's easy to do by calling &lt;span class="Apple-style-span"  style="color:#009900;"&gt;CreateSearchContext&lt;/span&gt; method of the index object we got previously. It's also possible to create a search context by using one for the constructors of &lt;span class="Apple-style-span"  style="color:#009900;"&gt;IndexSearchContext&lt;/span&gt; class. In this case it will be easy to run search queries by passing a search index instance as a parameter to the search context.&lt;/div&gt;&lt;div&gt;To search information, we need to create a query and run it in the search context. Sitecore API has a few classes that you can use to build search queries. Let's take a look at each of them:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;FullTextQuery&lt;/span&gt; - this type of query searches the index by "_content" field. All information from text fields (such as "Single-Line Text", "Rich Text", "Multi-Line Text", "text", "rich text", "html", "memo") is stored there. Data in this field are indexed and tokenized. Which means that the search operations running on these data are very efficient.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;FieldQuery&lt;/span&gt; - this type of query allows you to search any field that was added to the index. By default database crawler adds all item fields to the index.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;CombinedQuery&lt;/span&gt; - this type of query was designed to allow you create complex queries with additional conditions. For instance to find items which have specific work in title and belong to some category. When you add search queries to this type of query, you need to supply &lt;span class="Apple-style-span"  style="color:#009900;"&gt;QueryOccurance&lt;/span&gt; parameter. It's Enum type that has the following members:&lt;/div&gt;&lt;div&gt; - Must - it's a logical AND operator in Lucene boolean query.&lt;/div&gt;&lt;div&gt; - MustNot - it's a logical NOT operator in Lucene boolean query.&lt;/div&gt;&lt;div&gt; - Should - it's a logical OR operation in Lucene boolean query.&lt;/div&gt;&lt;div&gt;You can read more about this operators in &lt;a href="http://lucene.apache.org/java/2_3_2/queryparsersyntax.html"&gt;Query Parser Syntax article&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All of these query types are derived from &lt;span class="Apple-style-span"  style="color:#009900;"&gt;QueryBase&lt;/span&gt; class.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;There is one thing left until we jump from the theory to some code samples. To run defined queries, you need to use one of &lt;span class="Apple-style-span"  style="color:#009900;"&gt;Search&lt;/span&gt; methods of &lt;span class="Apple-style-span"  style="color:#009900;"&gt;IndexSearchContext&lt;/span&gt; object.&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;Now let's create a couple of samples to see a real code that goes behind the theory.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 1: Searching text fields.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;// Next samples will skip lines with getting the index instance and creating the search context.&lt;/div&gt;&lt;div&gt;// Get an index object&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;Index indx = SearchManager.GetIndex("my_index");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;// Create a search context&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;using (IndexSearchContext searchContext = indx.CreateSearchContext())&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   // In following examples I will be using QueryBase class to create search queries.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   FullTextQuery ftQuery = new FullTextQuery("welcome");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   SearchHits results = searchContext.Search(ftQuery);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 2: Searching item fields&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Let's say we want to find items classified by some category. There is a trick searching by GUIDs so let's say our category is just a string name.&lt;/div&gt;&lt;div&gt;.....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   // FieldQuery ctor accepts two parambers. First is a field name. The other one is a value we're looking for.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   QueryBase query = FieldQuery("category", "slr");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   SearchHits results = searchContext.Search(query);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;.....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 3: Searching by multiple conditions&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Turned out that your category parameter is not enough to get required results. You client is screaming that there are too many items and business users cannot find ones they are looking for (is there anything they can find?).&lt;/div&gt;&lt;div&gt;Obviously you have some additional fields that can help to find more strict results. Let's say there is a rating field with values from 1 to 5.&lt;/div&gt;&lt;div&gt;That's where CombinedQuery gets into the game.&lt;/div&gt;&lt;div&gt;.....&lt;/div&gt;&lt;div&gt;   // CombinedQuery object has Add method that should be used to add search queries to it. That's why we cannot use base class variable here.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0); "&gt;   CombinedQuery query = new CombinedQuery();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   QueryBase catQuery = new FieldQuery("category", "slr");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   QueryBase ratQuery = new FieldQuery("rating", "5");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   query.Add(catQuery, QueryOccurance.Must);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   query.Add(ratQuery, QueryOccurance.Must);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;   var hits = searchContext.Search(query);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;.....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All results are presented as &lt;span class="Apple-style-span"  style="color:#009900;"&gt;SearchHits&lt;/span&gt; object. Now you should use of following methods of SearchHits object to get the results as Sitecore items:&lt;/div&gt;&lt;div&gt; - FetchResults(int, int) - returns search results as SearchResultCollection. First parameter is a start position of an item you want to start fetching results from. Second one is count of items you want to fetch. By calling this function as mentioned below, you can get all results at once:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;var results = hits.FetchResults(0, hits.Length);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Slice(int) - returns all results as &lt;span class="Apple-style-span"  style="color:#009900;"&gt;IEnumerable&lt;searchhit&gt;&lt;/searchhit&gt;&lt;/span&gt; collection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Slice(int, int) - this method has similar signature to FetchResults but returns results as &lt;span class="Apple-style-span"  style="color:#009900;"&gt;IEnumerable&lt;searchhit&gt;&lt;/searchhit&gt;&lt;/span&gt; collection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are a couple of examples the way you can transform SearchHits object into Sitecore items.&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 4: using FetchResults&lt;/b&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  SearchResultCollection results = hits.FetchResults(0, hits.Length);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  IEnumerable&lt;item&gt; searchItems = from hit in results&lt;/item&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;                                                                   select hit.GetObject&lt;item&gt;();&lt;/item&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 5: using Slice&lt;/b&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  IList&lt;item&gt; searchItems = List&lt;item&gt;();&lt;/item&gt;&lt;/item&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  foreach(var hit in hits.Slice(0))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;     ItemUri itemUri = new ItemUri(hit.Url);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;     if (itemUri != null)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;     {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;        Item item = ItemManager.GetItem(itemUri.ItemID, itemUri.Language, itemUri.Version, Factory.GetDatabase(itemUri.DatabaseName));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;        if (item != null)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;        {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;           searchItems.Add(item);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;        }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;     }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's worth to mention that some variations of Search method of IndexSearchContext class can accept Lucene.Net.Search.Query as a search query parameter. It becomes very useful when you need to create a complex query which cannot be built with Sitecore query types.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Searching GUIDs&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;New search index has lots of useful built-in fields that help to build strict queries.&lt;/div&gt;&lt;div&gt;Besides standard fields it has the following fields that contain GUIDs in ShortID format:&lt;/div&gt;&lt;div&gt; - _links - contains all references to current item&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; - _path - contains ShortIDs for every parent item in the path relative to current item&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; - _template - contains GUID of item's tempalte. &lt;/div&gt;&lt;div&gt;&lt;b&gt;    NOTE&lt;/b&gt;: this field is supposed to have ShortID value instead of GUID one. This field should not be used in combined queries prior to Sitecore 6.2 releases.&lt;/div&gt;&lt;div&gt;If you decide to add custom fields to your search index and they should have GUID values, you need to store them as ShortID in lower case format. Otherwise search will not be able to find any results. The reason why it happens is because Lucene recognizes GUIDs and applies special parsing for them. It works fine if search query has only one field to look into. If it's combined/complex query then it fails to find anything even if it's correct.&lt;/div&gt;&lt;div&gt;So, remember if you need to filter search results by template, you will have to customize DatabaseCrawler to add another field (e.g. _shorttemplateid) to store item template id in ShortID format.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 1: Find all item references&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0); "&gt;    QueryBase query = FieldQuery("_links", ShortID.Encode(item.ID).ToLowerInvariant());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;    SearchHits results = searchContext.Search(query);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 6: Find all items based on specified template&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;    // Prior to Sitecore 6.2 release, you will need to add and use _shorttemplateid field&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0); "&gt;    QueryBase query = FieldQuery("_template", ShortID.Encode(item.ID).ToLowerInvariant());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;    SearchHits results = searchContext.Search(query);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 7: Find items that are descendants of a specified one&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0); "&gt;    QueryBase query = FieldQuery("_path", ShortID.Encode(item.ID).ToLowerInvariant());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;    SearchHits results = searchContext.Search(query);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample 8: Find items of a parent and belong to a specific template&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 153, 0); "&gt;    CombinedQuery query = new CombinedQuery();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;div&gt;    query.Add(new FieldQuery("_shorttemplateid", ShortID.Encode(templateId).ToLowerInvariant()), QueryOccurance.Must);&lt;/div&gt;&lt;div&gt;    query.Add(new FieldQuery("_path", ShortID.Encode(parent.ID).ToLowerInvariant())), QueryOccurance.Must);&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;  .....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That's all I wanted to tell about Lucene search index in Sitecore 6. I hope it will help Lucene beginners to better understand the concept and get up to speed with Lucene search index abilities.&lt;/div&gt;&lt;div&gt;Enjoy!&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/5251195438749660493-7431877801576788621?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/7431877801576788621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=7431877801576788621' title='28 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7431877801576788621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7431877801576788621'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html' title='Working with Lucene Search Index in Sitecore 6. Part III - Code examples'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>28</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2781154286092118419</id><published>2009-11-02T08:00:00.000-08:00</published><updated>2009-11-05T15:57:36.789-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lucene'/><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore 6'/><category scheme='http://www.blogger.com/atom/ns#' term='index'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='sitecore'/><title type='text'>Working with Lucene Search Index in Sitecore 6. Part II - How it works</title><content type='html'>Here is second part of the Lucene search index overview for Sitecore 6. In this part we'll take a look at configuration settings and talk about how it works.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sitecore 5 has Lucene engine as well. Let's step one Sitecore version back and see how Lucene works there.  In web.config file there is a section &lt;span class="Apple-style-span"  style="color:#009900;"&gt;/sitecore/indexes&lt;/span&gt; that contains Lucene index configuration. When index is configured, it should be added to &lt;span class="Apple-style-span"  style="color:#009900;"&gt;/sitecore/databases/database/indexes&lt;/span&gt; section.&lt;/div&gt;&lt;div&gt;&lt;div&gt;The &lt;i&gt;web&lt;/i&gt; database does not have a search index by default. Even if you add it to aforementioned section, it won't work. Why? Because index configuration relies on &lt;i&gt;HistoryEngine&lt;/i&gt; functionality. By default the &lt;i&gt;web&lt;/i&gt; database does not have it. It's easy to add it though. Just add the &lt;i&gt;HistoryEngine&lt;/i&gt; configuration section to the database.&lt;/div&gt;&lt;div&gt;You can find more configuration details from &lt;a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx"&gt;this article&lt;/a&gt; on &lt;a href="http://sdn.sitecore.net/"&gt;SDN&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;This index has the same configuration in Sitecore 6. &lt;/div&gt;&lt;div&gt;In addition to it, Sitecore 6 has a new Lucene index functionality. Which is more reliable and has Sitecore level API on top of Lucene one. In some cases you will still have to use Lucene API. For instance to create &lt;i&gt;range&lt;/i&gt; queries.&lt;/div&gt;&lt;div&gt;Configuration settings for &lt;i&gt;new&lt;/i&gt; search index located under &lt;span class="Apple-style-span"  style="color:#009900;"&gt;/sitecore/search&lt;/span&gt; section. &lt;/div&gt;&lt;div&gt;The &lt;span class="Apple-style-span"  style="color:#009900;"&gt;analyzer&lt;/span&gt; section defines a Lucene analyzer that is used to analyze and index content. &lt;/div&gt;&lt;div&gt;The &lt;span class="Apple-style-span"  style="color:#009900;"&gt;categories&lt;/span&gt; section is used to categories search results. It's used for content tree search introduced in Sitecore 6. The search box is located right above the content tree in content editor.&lt;/div&gt;&lt;div&gt;The &lt;span class="Apple-style-span"  style="color:#009900;"&gt;configuration&lt;/span&gt; section has indexes definitions with their configurations. An index definition should be created under &lt;span class="Apple-style-span"  style="color:#009900;"&gt;/sitecore/search/configuration/indexes&lt;/span&gt; node.&lt;/div&gt;&lt;div&gt;First two parameters describe the index name and folder name where it should be stored:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;param desc="name"&amp;gt;$(id)&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;param desc="folder"&amp;gt;my_index_folderName&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Next setting is the analyzer that should be used for the index:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;Analyzer ref="search/analyzer" /&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Lucene StandardAnalyzer covers most of the case scenarios. But it's possible to use any other analyzer if it's needed.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Following setting defines locations for the index:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;locations hint="list:AddCrawler"&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;It's possible to have multiple locations for one index. Moreover it's even possible to have content from different databases in the same index. Every child of the &lt;i&gt;locations&lt;/i&gt; node has its own configuration for a particular part of the content. A name of &lt;i&gt;location&lt;/i&gt; node is not predefined. You're welcome to name it the way you want. For example:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;locations hint="list:AddCrawler"&amp;gt;  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style=" color: rgb(0, 153, 0); font-size:small;"&gt; &lt;span class="Apple-style-span"  style="color: rgb(0, 0, 0);  font-size:16px;"&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;sdn-site&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; type="Sitecore.Search.Crawlers.DatabaseCrawler, Sitecore.Kernel"&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;    ...&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style=" color: rgb(0, 153, 0); font-size:small;"&gt;  &lt;span class="Apple-style-span"  style="color: rgb(0, 0, 0);  font-size:16px;"&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#000099;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;sdn-site&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;/locations&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Every location has a &lt;span class="Apple-style-span"  style="color:#009900;"&gt;database&lt;/span&gt; section. It defines indexing database for the location.&lt;/div&gt;&lt;div&gt;Then &lt;span class="Apple-style-span"  style="color:#009900;"&gt;root&lt;/span&gt; section. The database crawler will index content beneath this path.&lt;/div&gt;&lt;div&gt;Next sibling node is the &lt;span class="Apple-style-span"  style="color:#009900;"&gt;include&lt;/span&gt; section. Here it's possible to add templates items of which should be included to the index or excluded from it.&lt;/div&gt;&lt;div&gt;Example:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;include hint="list:IncludeTemplate"&amp;gt;  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style=" color: rgb(0, 153, 0); font-size:small;"&gt;  &amp;lt;sampleItem&amp;gt;{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}&amp;lt;/sampleItem&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;/include&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;include hint="list:ExcludeTemplate"&amp;gt;  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style=" color: rgb(0, 153, 0); font-size:small;"&gt;  &amp;lt;layout&amp;gt;{3A45A723-64EE-4919-9D41-02FD40FD1466}&amp;lt;/layout&amp;gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&amp;lt;/include&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;It does not make sense to use both of these settings for the one location. Use only one of them.&lt;/div&gt;&lt;div&gt;Next location setting is &lt;span class="Apple-style-span"  style="color:#009900;"&gt;tags&lt;/span&gt; section. Here you can tag indexed content and use it during the search procedure.&lt;/div&gt;&lt;div&gt;Last setting is &lt;span class="Apple-style-span"  style="color:#009900;"&gt;boost&lt;/span&gt; section. Here you have an ability to boost indexed content among other content that belongs to other locations.&lt;/div&gt;&lt;div&gt;And last but not the least, this search index uses the same &lt;i&gt;HistoryEngine&lt;/i&gt; mechanism as old one. So, don't forget to copy configuration section from master database to a database where you want to add search index facilities to.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How it all works?&lt;/div&gt;&lt;div&gt;When an action performed on the item, database crawler updates entries in search index for the item. So that information in index is in sync with the one in database. How does it happen if "&lt;i&gt;item:saved&lt;/i&gt;", "&lt;i&gt;item:deleted&lt;/i&gt;", "&lt;i&gt;item:renamed&lt;/i&gt;", "&lt;i&gt;item:copied&lt;/i&gt;", "&lt;i&gt;item:moved&lt;/i&gt;" do not have event handlers that trigger search index update? Thank to &lt;i&gt;HistoryEngine&lt;/i&gt; that was mentioned several times already.&lt;/div&gt;&lt;div&gt;It is &lt;i&gt;HistoryEngine&lt;/i&gt; that tracks any changes made to the item and fires appropriate event handler to process it.&lt;/div&gt;&lt;div&gt;&lt;i&gt;IndexingManager&lt;/i&gt; is responsible for all operations to the search index. It subscribes to &lt;i&gt;AddEntry&lt;/i&gt; event of &lt;i&gt;HistoryEngine&lt;/i&gt; and as soon as an entry added to the &lt;i&gt;History&lt;/i&gt; table, it triggers a job that updates the search index(es).&lt;/div&gt;&lt;div&gt;In web.config file there are a few settings that belong to indexing functionality.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Indexing.UpdateInterval&lt;/b&gt; - sets the interval between the IndexingManager checking its queue for pending actions. Default value is 5 minutes.&lt;br /&gt;What does it mean? If for whatever reason pending job was not executed, the IndexingManager will re-run it if it finds it in pending state after 5 minutes pass.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Indexing.UpdateJobThrottle&lt;/b&gt; - sets the minimum time to wait between individual index update jobs. Default value 1 second.&lt;br /&gt;When some operation is performed on the item, you can see this entry in Sitecore log file:&lt;br /&gt;&lt;i&gt;INFO  Starting update of index for the database '&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;databaseName&lt;/span&gt;' (&lt;items_number&gt; pending).&lt;br /&gt;&lt;span class="Apple-style-span" style="font-style: normal;"&gt;This setting sets the interval between jobs like this. So that it does not overwhelm all CPU time if you're doing massive change to the items.&lt;/span&gt;&lt;/items_number&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Indexing.ServerSpecificProperties&lt;/b&gt; - Indicates if server specific keys should be used for property values (such as 'last updated'). It's off by default.&lt;br /&gt;This setting is designed for content delivery environments in web farms. As &lt;i&gt;web&lt;/i&gt; database is shared, there could be a situation when one server has updated its search indexes and changed &lt;i&gt;History&lt;/i&gt; table in the database. Other servers won't update their indexes because &lt;i&gt;HistoryEngine&lt;/i&gt; wouldn't indicate there was a change. This setting prevents situations like this.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Well... this is it for now. In next part we will take a look at Sitecore Lucene API and create some search queries with it.&lt;/div&gt;&lt;div&gt;Enjoy!&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/5251195438749660493-2781154286092118419?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/2781154286092118419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=2781154286092118419' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2781154286092118419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2781154286092118419'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in.html' title='Working with Lucene Search Index in Sitecore 6. Part II - How it works'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-1388752313222715085</id><published>2009-10-02T08:48:00.001-07:00</published><updated>2009-10-31T14:59:18.167-07:00</updated><title type='text'>Working with Lucene Search Index in Sitecore 6. Part I - Why/When to use</title><content type='html'>How often did you stress yourself thinking on the question "What's the most efficient way to retrieve Sitecore items?"? &lt;div&gt;Here are possible ways to do it:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Sitecore API&lt;/li&gt;&lt;li&gt;Sitecore Query&lt;/li&gt;&lt;li&gt;SQL custom stored procedures&lt;/li&gt;&lt;li&gt;Lucene index&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Let's take a look at each option briefly.&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sitecore API&lt;/b&gt; - the most popular way to get an item. All you need is an item ID and simple call of GetItem(&lt;id&gt;) method of database instance will get you the latest item version in current language. If you want an item in specific language, not a problem: GetItem(&lt;id&gt;, &lt;language&gt;). Want specify version, not a problem either: GetItem(&lt;id&gt;, &lt;language&gt;, &lt;version&gt;). There are many ways to get an item through Sitecore API. My point is that it's the most easiest way to do it.&lt;/version&gt;&lt;/language&gt;&lt;/id&gt;&lt;/language&gt;&lt;/id&gt;&lt;/id&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sitecore Query&lt;/b&gt; - easy way to get a bunch of items filtered by some criteria. Build a string query, which kinda look like XPath query, and run it on a database instance. Read more about &lt;a href="http://sdn.sitecore.net/Reference/Using%20Sitecore%20Query.aspx"&gt;Sitecore Query&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;b&gt;SQL custom stored procedures&lt;/b&gt; - we all know how to create a SQL stored procedure. Connections strings already exist in Sitecore solution. All you need is to use some SQL management studio to create a stored procedure for the database. The question is why would you do it if API already exists? It makes sense only if you run complex query with lots of filtering conditions so that SQL will return you only items that you're searching for.&lt;/div&gt;&lt;div&gt;&lt;b&gt;Lucene index&lt;/b&gt; - why would I use separate data storage/data index to get an item from Sitecore database? It does not make sense. Agree, for an item it does not but for a collection of items it has a perfect sense to do it. Why? Maybe because performance is much better when you are working with big amount of data. Moreover that's a search index. Which means that data are perfectly organized to be searched.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let's talk about performance characteristics for each of these options and compare them.&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;Sitecore API&lt;/span&gt;&lt;/i&gt; - uses Sitecore data provider to pull out information from the database. If item that we're looking for is cached the call to SQL database is avoided and item gets retrieved from one of Sitecore caches. Using Sitecore caches gives you huge performance benefit. That's why we always worried about caches configuration in Sitecore solution. What if you need to get a number of items by some criteria, let's say template ID and belonging to some category (from here on I'm gonna use this condition for all item retrieval options). You run foreach or for or any other logic that goes through the content tree and checks for a TemplateID property and category field of every single item. If item resides in cache, it will be quick enough but still the code will have to request every single item from the content tree.&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;Sitecore Query&lt;/span&gt;&lt;/i&gt; - the picture with Sitecore Query is very similar to Sitecore API but it get's more slower when number of items is growing. Kim has a good article that explains &lt;a href="http://sitecorekh.blogspot.com/2007_08_01_archive.html"&gt;Sitecore Query performance&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;NOTE: I'm not talking about &lt;i&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;fast&lt;/span&gt;&lt;/i&gt; Sitecore Query introduced in Sitecore 6.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;SQL stored procedures&lt;/span&gt; - it seems to be a good approach to go with if you're searching for items through the content tree. The thing is there will be only one stored procedure that executes query by specified criteria. Also you will have to consider caching option for retrieved items if you have very deep content tree and items of some specific time are not gathered under one branch. My point is that it can cost you more then the benefits that you will get. I would go with this approach only if I cannot do it with Lucene resources.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#3366FF;"&gt;Lucene index&lt;/span&gt; - again it's search index. It perfectly fits searching options. When you search for items with specified criteria it neither requests an item instance nor runs query over database tables. It goes through the fields that you have in your index and compares their values to your search conditions. The only thing if search query uses custom fields to filter data by, the fields must be added to your index. Otherwise you will get zero results. It's very easy to do though. I will describe it in the next part of the article.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Conclusion: Let's answer those questions in the topic of this part.&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;Why to use lucene index?&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;The approach is one of the most (maybe event the best) efficient ones. Search is quick enough that in most cases you don't even need to implement custom caching for the retrieved data.&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;When to use lucene index?&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;When you need to run search queries with specific criteria on huge number of data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Don't forget the rule - the more complex search query gets the slower it works ;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In next part we will look into Lucene search index introduced in Sitecore 6. &lt;/div&gt;&lt;div&gt;Information about "old" Lucene index (it was introduced in Sitecore 5) you can find &lt;a href="http://sdn.sitecore.net/Articles/Administration/Lucene%20Search%20Engine.aspx"&gt;here&lt;/a&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/5251195438749660493-1388752313222715085?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/1388752313222715085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=1388752313222715085' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1388752313222715085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/1388752313222715085'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/10/working-with-lucene-search-index-part-i.html' title='Working with Lucene Search Index in Sitecore 6. Part I - Why/When to use'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2860592728484151655</id><published>2009-07-30T15:20:00.000-07:00</published><updated>2009-10-02T10:54:20.510-07:00</updated><title type='text'>Restrict access to advanced media upload options</title><content type='html'>Sometimes you want to give an access to Advanced Media Upload for editors. When you do it, they get access to all the advanced options that you might not want to share with them.&lt;div&gt;This package allows you to configure access to advanced media upload options by tighten security on Sitecore items.&lt;/div&gt;&lt;div&gt;After installing the package, you can configure advanced options access for presets items at /sitecore/System/Settings/Media/Presets path.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gDIVYhqZmFo/Sl0Jb5G2tII/AAAAAAAAHDA/SvpsQPtewtw/s1600-h/MediaUploadPresets.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 214px;" src="http://1.bp.blogspot.com/_gDIVYhqZmFo/Sl0Jb5G2tII/AAAAAAAAHDA/SvpsQPtewtw/s400/MediaUploadPresets.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5358449506431448194" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Download &lt;a href="http://scusainc.com/SupportResources/ivan/Media/AdvancedMediaUploadPresets/AdvancedMediaUploadPresets-1.0.0.zip"&gt;the package&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-2860592728484151655?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2860592728484151655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2860592728484151655'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/07/restrict-access-to-advanced-media.html' title='Restrict access to advanced media upload options'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gDIVYhqZmFo/Sl0Jb5G2tII/AAAAAAAAHDA/SvpsQPtewtw/s72-c/MediaUploadPresets.png' height='72' width='72'/></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-7816610006555396181</id><published>2009-03-19T08:56:00.000-07:00</published><updated>2009-03-19T08:58:34.108-07:00</updated><title type='text'>YouTube Integration source code</title><content type='html'>For those who's interested, the source code for YouTube data provider is available on &lt;a href="http://trac.sitecore.net/YouTubeIntegration"&gt;Sitecore Trac system&lt;/a&gt;. &lt;div&gt;Enjoy!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-7816610006555396181?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/7816610006555396181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=7816610006555396181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7816610006555396181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7816610006555396181'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/03/youtube-integration-source-code.html' title='YouTube Integration source code'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-3639775371328573870</id><published>2009-03-06T09:46:00.000-08:00</published><updated>2009-03-19T08:59:22.331-07:00</updated><title type='text'>YouTube Integration with Sitecore 6.0</title><content type='html'>Recently I got a quite interesting task to build an integration between Sitecore CMS and YouTube repository. I finished that task and I'm willing to share my experience with public. I will describe code only partially. Only those parts I consider the most interesting.&lt;br /&gt;&lt;br /&gt;We've been thinking about different approaches and have chosen Sitecore Data Provider approach. We decided to have items in CMS that would represent YouTube videos. One of the challenges was to integrate YouTube videos on the fly when an editor wants to add videos from one or other YouTube author.&lt;br /&gt;This data provider works in read-only mode. If you want to extend this solution, you're welcome to do so.&lt;br /&gt;So let's begin....&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Templates&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I created two templates that will represent root item for YouTube videos and YouTube video item itself. First one is called "YouTube branch" and the other one is "YouTube video".&lt;br /&gt;YouTube branch is going to be a folder for YouTube video items. Unlike usual folders it has a field that determinates videos of what YouTube author to show beneath it.&lt;br /&gt;YouTube video template extends Flash media template and adds two additional fields: Url and Preview. Url is obviously intended for a YouTube video url. Preview is an iframe field that will show us the preview of YouTube video.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Implementation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is a required list of methods you must implement to get data provider working. Here are those methods:&lt;br /&gt;&lt;br /&gt;- GetItemDefinition&lt;br /&gt;- GetItemFields&lt;br /&gt;- GetChildIDs&lt;br /&gt;- GetParentID&lt;br /&gt;- GetItemVersions&lt;br /&gt;&lt;br /&gt;I'm not going to describe what they are for. You can find a &lt;a href="http://sdn5.sitecore.net/developer/integrating%20external%20data%20sources/implementation/read-only%20sources.aspx"&gt;detailed explanation&lt;/a&gt; on SDN.&lt;br /&gt;One method is missing in this list. It's "GetTemplates" method. We can avoid implementing this method if required templates already exist in our data source.&lt;br /&gt;I'm going to use master database as a source for YouTube video items. I created a couple of templates for this approach so that we can skip implementation of the "GetTemplates" method.&lt;br /&gt;Also I made this data provider publish its items by implementing one publishing method:&lt;br /&gt;&lt;br /&gt;- GetPublishQueue&lt;br /&gt;&lt;br /&gt;This is how constructor looks for the data provider:&lt;br /&gt;    public YouTubeDataProvider(string rootTID, string resourceTID, string videoOwnerField, string contentDB)&lt;br /&gt;    {&lt;br /&gt;  prefix = ToString();&lt;br /&gt;  rootTemplateID = rootTID;&lt;br /&gt;  resourceTemplateID = resourceTID;&lt;br /&gt;  contentDatabase = contentDB;&lt;br /&gt;  videoOwnerFieldName = videoOwnerField;&lt;br /&gt;  _items = new Hashtable();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;rootTemplateID&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;contains an ID of YouTube branch template&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;resourceTemplateID &lt;/span&gt;contains an ID of YouTube video template&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;contentDatabase &lt;/span&gt;is a source database for our YouTube provider (it's master database)&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;videoOwnerFieldName &lt;/span&gt;is a field name of YouTube branch template where you specify an owner of YouTube videos.&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;_items&lt;/span&gt; is a temporary cache for our YouTube videos.&lt;br /&gt;Since we need to use some sort of mapping between YouTube videos and Sitecore items, I'm going to use existing functionality of IDTable. That's what we need "&lt;span style="font-style: italic; font-weight: bold;"&gt;prefix&lt;/span&gt;" variable for.&lt;br /&gt;&lt;br /&gt;Now let's look at implementation of first method:&lt;br /&gt;    public override ItemDefinition GetItemDefinition(ID itemId, CallContext context)&lt;br /&gt;    {&lt;br /&gt;  ItemDefinition itemDef = null;&lt;br /&gt;  string itemName = string.Empty;&lt;br /&gt;  if (CanProcessYouTubeItem(itemId, context))&lt;br /&gt;  {&lt;br /&gt;     // method body&lt;br /&gt;  }&lt;br /&gt;  return itemDef;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;The first thing we need to think of is how to determine if the item we are getting from data provider is our YouTube item. That's what CanProcessYouTubeItem method for. This method uses IDTable API to find out if an item comes from YouTube rather than SQL database. Here is the code for the method:&lt;br /&gt;    bool CanProcessYouTubeItem(ID id, CallContext context)&lt;br /&gt;    {&lt;br /&gt;           if (IDTable.GetKeys(prefix, id).Length &gt; 0)&lt;br /&gt;  {&lt;br /&gt;     return true;&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;The same technic is used for GetItemFields, GetParentID and GetItemVersions methods. For GetChildIDs we had to use different code because we had to work with parent item. Here is a code for the method:&lt;br /&gt;    public override Sitecore.Collections.IDList GetChildIDs(ItemDefinition itemDefinition, CallContext context)&lt;br /&gt;    {&lt;br /&gt;  if (CanProcessParent(itemDefinition.ID, context))&lt;br /&gt;  {&lt;br /&gt;     // method body&lt;br /&gt;  }&lt;br /&gt;  return null;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;CanProcessParent method checks if the item is our YouTube branch item. If it indicates that it is then we start processing our child items that are YouTube videos.&lt;br /&gt;This is the code of the method:&lt;br /&gt;    bool CanProcessParent(ID id, CallContext context)&lt;br /&gt;    {&lt;br /&gt;  Item item = ContentDB.Items[id];&lt;br /&gt;  bool canProduce = false;&lt;br /&gt;  if (item != null &amp;amp;&amp;amp; (ID.Parse(rootTemplateID) == item.TemplateID))&lt;br /&gt;  {&lt;br /&gt;     canProduce = true;&lt;br /&gt;  }&lt;br /&gt;  return canProduce;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;After we get our items, we have to fill out their fields to finish our integration process. Information from YouTube video is mapped in GetItemFields method. This is the code:&lt;br /&gt;    public override FieldList GetItemFields(ItemDefinition itemDefinition, VersionUri versionUri, CallContext context)&lt;br /&gt;    {&lt;br /&gt;  FieldList fields = new FieldList();&lt;br /&gt;  if (CanProcessYouTubeItem(itemDefinition.ID, context))&lt;br /&gt;  {&lt;br /&gt;     string originalID = GetOriginalRecordID(itemDefinition.ID);&lt;br /&gt;     TemplateItem templateItem = ContentDB.Templates[resourceTemplateID];&lt;br /&gt;     if (templateItem != null)&lt;br /&gt;     {&lt;br /&gt;        YTItemInfo ytItemInfo = GetYTItemInfo(itemDefinition.ID);&lt;br /&gt;        if (ytItemInfo != null)&lt;br /&gt;        {&lt;br /&gt;           foreach (var field in templateItem.Fields)&lt;br /&gt;           {&lt;br /&gt;              fields.Add(field.ID, GetFieldValue(field, ytItemInfo));&lt;br /&gt;           }&lt;br /&gt;        }&lt;br /&gt;     }&lt;br /&gt;  }&lt;br /&gt;  return fields;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;As you can see it's simply iterates through template fields and maps data from YouTube Entry to Sitecore YouTube video item.&lt;br /&gt;We got YouTube video items in our content tree. But we cannot do anything with them on front-end. One option is to add our data provider to web database to get it working on front-end. But what if we make main data provider know about our items and just publish them as a real items. All I need to do is to get list of IDs of our items in GetPublishQueue method.&lt;br /&gt;This is how the code looks:&lt;br /&gt;    public override IDList GetPublishQueue(DateTime from, DateTime to, CallContext context)&lt;br /&gt;    {&lt;br /&gt;  IDList list = new IDList();&lt;br /&gt;  foreach (var item in _items)&lt;br /&gt;  {&lt;br /&gt;     YTItemInfo ytItemInfo = (YTItemInfo) item;&lt;br /&gt;     list.Add(ytItemInfo.ItemID);&lt;br /&gt;  }&lt;br /&gt;  return list;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;Since I did not use a publish queue table, YouTube items are going to be published every time to run publish operation on them. You can avoid this if you implement AddToPublishQueue and CleanupPublishQueue methods.&lt;br /&gt;&lt;br /&gt;Here is a screen dump the way YouTube item looks in Sitecore media library:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gDIVYhqZmFo/SbF6uUTzGwI/AAAAAAAAE4I/FW7BuTnIMp4/s1600-h/YouTubeVideoItem.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 239px;" src="http://4.bp.blogspot.com/_gDIVYhqZmFo/SbF6uUTzGwI/AAAAAAAAE4I/FW7BuTnIMp4/s400/YouTubeVideoItem.png" alt="" id="BLOGGER_PHOTO_ID_5310160371790846722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;This is a &lt;a href="http://scusainc.com/SupportResources/ivan/DataProviders/YouTube/YouTubeDataProvider-1.0.0.zip"&gt;sitecore package&lt;/a&gt; that will install data provider on your Sitecore 6.0 CMS. I do not described provider configuration in this article. You can find it in /App_Config/Include folder after installing the package.&lt;br /&gt;NOTE: if installation fails, that means that you run into a known issue. Reinstalling the package should solve it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-3639775371328573870?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/3639775371328573870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=3639775371328573870' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/3639775371328573870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/3639775371328573870'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2009/03/youtube-integration-with-sitecore-60.html' title='YouTube Integration with Sitecore 6.0'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_gDIVYhqZmFo/SbF6uUTzGwI/AAAAAAAAE4I/FW7BuTnIMp4/s72-c/YouTubeVideoItem.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-6874743838317502114</id><published>2008-12-19T10:51:00.000-08:00</published><updated>2011-09-10T15:49:39.237-07:00</updated><title type='text'>Adding buttons to inline-editing frame</title><content type='html'>Today's post is dedicated to Sitecore inline-editor and some customization you can put into it. The question I'm going to address is:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"Is it possible to add custom buttons to inline-editor frame?"&lt;/span&gt;&lt;br /&gt;The answer is simple as is: "Yes, it is" :). Wait... don't go away. Read further to find out the solution.&lt;br /&gt;&lt;br /&gt;Our challenge is to add a button to inline-editor. Let's do that for Rich Text field.&lt;br /&gt;I put this approach into the steps to outline this process. Let's start:&lt;br /&gt;&lt;br /&gt;1) Open Sitecore Client and go to the Core database.&lt;br /&gt;As you know (or maybe you're going to find out right away) Rich Text field has several profiles to give different sets of functionality to logged in users. Let's go to default profile and check its configuration, here is the path in content tree: "&lt;span style="font-size: 85%;"&gt;&lt;span style="font-weight: bold;"&gt;/sitecore/system/Settings/Html Editor Profiles/Rich Text Default&lt;/span&gt;&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;2) The configuration node we're interested in is "WebEdit Buttons". Go ahead and expand it.&lt;br /&gt;Beneath the node you can see all available buttons which are going to show up as soon as you put mouse cursor over the rich text data in Page Editor.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-DIBilfdGQmc/TmvpSXEjhZI/AAAAAAAAITU/sTwpnBCURrY/s1600/RichTextDefaultProfileButtons.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/-DIBilfdGQmc/TmvpSXEjhZI/AAAAAAAAITU/sTwpnBCURrY/s400/RichTextDefaultProfileButtons.PNG" width="260" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3) Since we're already here let's add our own button to the current set. A button should be created from "/sitecore/templates/System/WebEdit/WebEdit  Button" template.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-jLDaP81yz5g/Tmvpatf4l5I/AAAAAAAAITY/LFr2au-c3Pg/s1600/MyButton.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="265" src="http://3.bp.blogspot.com/-jLDaP81yz5g/Tmvpatf4l5I/AAAAAAAAITY/LFr2au-c3Pg/s640/MyButton.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Header&lt;/span&gt; field contains the name of the button in inline-editor frame.&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Icon&lt;/span&gt; field has the icon for the button&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Click&lt;/span&gt; field is the most important part. It has command message that should be sent when you hit the button.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;a)&lt;/span&gt; Here is the format of this field for the custom command: "javascript:return Sitecore.WebEdit.editControl($JavascriptParameters, "webedit:mybutton:message")"&lt;br /&gt;Javascript command is required to set you command message that is passed as second parameter for the "&lt;span style="font-style: italic; font-weight: bold;"&gt;editControl&lt;/span&gt;" function.&lt;br /&gt;"webedit:mybutton:message" is command message. Don't be concerned about the format of this message. It can have any format you want. For instance: "webedit:mymessage" or "webedit:mybutton:mymessage". It's good when the first part of the message describes an area the message belongs to, e.g. "webedit:".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;b)&lt;/span&gt; Here is another example to run JavaScript function through the button.&lt;br /&gt;Click field should look like this: javascript:Sitecore.WebEdit.execute("&lt;span style="font-style: italic; font-weight: bold;"&gt;js_function_name&lt;/span&gt;", true, "&lt;span style="font-style: italic; font-weight: bold;"&gt;parameter_for_js_function&lt;/span&gt;");&lt;br /&gt;This example changes the font size:&lt;br /&gt;javascript:Sitecore.WebEdit.execute("fontsize", true, "20");&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;NOTE&lt;/span&gt;: if you use javascript function, the Header field for the button item should be left &lt;span style="font-style: italic; font-weight: bold;"&gt;empty&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Tooltip&lt;/span&gt; field describes itself :).&lt;br /&gt;&lt;br /&gt;4) This is the final step. You have to create a command handler that will do action you want.&lt;br /&gt;I'm not going to touch command creation process here. You can find sample in John's article &lt;a href="http://sitecorejohn.spaces.live.com/Blog/cns%21960125F1D4A59952%21135.entry"&gt;here&lt;/a&gt;.&lt;br /&gt;NOTE: webedit command handler class must be inherited from Sitecore.Shell.Applications.WebEdit.Commands.WebEditCommand one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-6874743838317502114?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/6874743838317502114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=6874743838317502114' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/6874743838317502114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/6874743838317502114'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/12/adding-buttons-to-inline-editing-frame.html' title='Adding buttons to inline-editing frame'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-DIBilfdGQmc/TmvpSXEjhZI/AAAAAAAAITU/sTwpnBCURrY/s72-c/RichTextDefaultProfileButtons.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-6871101349828636119</id><published>2008-07-25T16:40:00.000-07:00</published><updated>2008-07-25T17:15:50.933-07:00</updated><title type='text'>Migrate from 5.3 to 6.0 (alpha)</title><content type='html'>Today was my first experience with "alpha" version of Sitecore migration from 5.3 to 6.0.&lt;br /&gt;What I can say, that was not so bad :-). Anyways, I have to say that my site was pretty simple and did not have heavy customization (no custom fields, default devices, no proxies).&lt;br /&gt;I migrated only master database because I had only default security objects in my solution.&lt;br /&gt;I followed all steps from documentation and did not face any problems. Altogether it took about 3 hours to migrate my content and clean up my solution from migration tool. Not bad! Again that was the first time when I saw this tool.&lt;br /&gt;In addition I spent about 2+ hours to adjust my code to spin it in Sitecore 6.0.&lt;br /&gt;The most common issue for my renderings was related to pulling out media url using "sc:fld()" function and media item variable.&lt;br /&gt;I had to substitute "sc:fld()" for "sc:GetMediaUrl()".&lt;br /&gt;&lt;br /&gt;I thought I would have to do some modifications to get in-line editing working in V6. I was surprised that old buddy "sc:dot" represented this opportunity.&lt;br /&gt;So, as a result it is not so bad as it sounds at the first glance ;-).&lt;br /&gt;You should try it out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-6871101349828636119?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/6871101349828636119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=6871101349828636119' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/6871101349828636119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/6871101349828636119'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/07/migrate-from-53-to-60-alpha.html' title='Migrate from 5.3 to 6.0 (alpha)'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-8476121396196702973</id><published>2008-04-17T08:27:00.000-07:00</published><updated>2008-04-25T15:49:31.491-07:00</updated><title type='text'>Share site resources among several sites</title><content type='html'>If you have lots of sites with similar structure and presentation layer you can make them use resources of one Sitecore site from web.config file. To do this you can create custom SiteResolver and insert it in &amp;lt;httprequestbegin&amp;gt; pipeline just after the native SiteResolver processor.&lt;br /&gt;Using this approach you should have custom SiteResolver processor and special config file where you can map your sites to the same instance of Sitecore site from web.config file. It shows you how you can set several host names for the same Sitecore site in web.config file.&lt;br /&gt;NOTE:  This approach is supposed to have “website” site in your web.config file.&lt;br /&gt;Using this idea you can set not only host names but the whole site configuration for the same Sitecore site. In that case you will be able to share cache and other resources among several sites.&lt;br /&gt;Below are the steps how to apply this approach:&lt;br /&gt;1)    Create custom SiteResolver and set add it in web.config file just after the native SiteResolver processor, as shown below:&lt;br /&gt;&amp;lt;httprequestbegin&amp;gt;&lt;br /&gt; ………………&lt;br /&gt; &amp;lt;processor type="Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel" /&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  &amp;lt;processor type="SiteMapper.Pipelines.HttpRequest. SimilarSitesResolver, SiteMapper" /&amp;gt;&lt;/span&gt;&lt;br /&gt; ………………&lt;br /&gt;&amp;lt;/httprequestbegin&amp;gt;&lt;br /&gt;&lt;br /&gt;2)    Create special config file (similar.sites.config) to map your sites with the following structure:&lt;br /&gt;&amp;lt;sites&amp;gt;&lt;br /&gt;&amp;lt;site mode="on" name="&lt;span style="font-weight: bold;"&gt;www.mysite&lt;/span&gt;" hostname="www.mysite.dk" language="da-DK" /&amp;gt;&lt;br /&gt;&amp;lt;site mode="on" name="&lt;span style="font-weight: bold;"&gt;www.mysite&lt;/span&gt;" hostname="www.mysite.uk" language="en-GB" /&amp;gt;&lt;br /&gt;&amp;lt;site mode="on" name="&lt;span style="font-weight: bold;"&gt;www.mysite&lt;/span&gt;" hostname="www.mysite.com" language="en" /&amp;gt;&lt;br /&gt;&amp;lt;/sites&amp;gt;&lt;br /&gt;&lt;br /&gt;As you can see all three sites have the same “name”. This name determine which site from web.config file should be used when you request any of these sites.&lt;br /&gt;Example of web.config file:&lt;br /&gt;&amp;lt;!-- ***** &lt;span style="font-weight: bold;"&gt;www.mysite&lt;/span&gt; group ***** --&amp;gt;&lt;br /&gt;&amp;lt;site mode="on" name="&lt;span style="font-weight: bold;"&gt;www.mysite&lt;/span&gt;" hostname=" www.mysite.com" language="en" virtualfolder="/" physicalfolder="/" rootpath="/sitecore/content" startitem="/www.mysite/home" database="web" domain="extranet" allowdebug="true" cachehtml="true" htmlcachesize="10MB" enablepreview="true" enablewebedit="true" enabledebugger="true" disableclientdata="false" /&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;!-- “website” is compulsory for this solution --&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;site name="website" virtualfolder="/" physicalfolder="/" rootpath="/sitecore/content" startitem="/flugger/home" database="master" domain="extranet" allowdebug="true" cachehtml="true" htmlcachesize="10MB" enablepreview="true" enablewebedit="true" enabledebugger="true" disableclientdata="false" /&amp;gt;&lt;br /&gt;&lt;br /&gt;NOTE: each Sitecore site in web.config file &lt;span style="font-weight: bold;"&gt;must have hostName&lt;/span&gt; attribute. Otherwise Sitecore will classify this site as a default website and you won’t get required results.&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://scusainc.com/supportresources/ivan/Tools/SiteMapper/SiteMapper-1.0.0.zip"&gt;Sitecore package&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://scusainc.com/supportresources/ivan/Tools/SiteMapper/SiteMapper-1.0.0_source.zip"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-8476121396196702973?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/8476121396196702973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=8476121396196702973' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8476121396196702973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/8476121396196702973'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/04/share-site-resources-among-several.html' title='Share site resources among several sites'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-7172034758671800984</id><published>2008-03-31T13:03:00.000-07:00</published><updated>2008-12-09T07:09:29.137-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore Client Tools'/><title type='text'>Convert unversioned media to versioned</title><content type='html'>This tool is intended to make a work with media be smoothly. By default Sitecore uploads media as unversioned data. In order to have different media data for different languages we need to upload media as versioned. Otherwise you won't be able to have different data for the same media item. Even if you change unversioned template to versioned.&lt;br /&gt;After installing the package a "Make versioned" button will be available on Media tab.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gDIVYhqZmFo/R_FH2u8nGEI/AAAAAAAAA4Y/o1NsLUhgfWc/s1600-h/MakeVerRibbon.PNG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_gDIVYhqZmFo/R_FH2u8nGEI/AAAAAAAAA4Y/o1NsLUhgfWc/s320/MakeVerRibbon.PNG" alt="" id="BLOGGER_PHOTO_ID_5184003651720910914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can convert media item as well as the whole media folder.&lt;br /&gt;&lt;br /&gt;You can download sitecore package from &lt;a href="http://scusainc.com/supportresources/ivan/Tools/UnversionedToVersionedMedia/VersionableMedia-1.0.0.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-7172034758671800984?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/7172034758671800984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=7172034758671800984' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7172034758671800984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/7172034758671800984'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/03/convert-unversioned-media-to-versioned.html' title='Convert unversioned media to versioned'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gDIVYhqZmFo/R_FH2u8nGEI/AAAAAAAAA4Y/o1NsLUhgfWc/s72-c/MakeVerRibbon.PNG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-2985454665225596319</id><published>2008-03-03T10:40:00.000-08:00</published><updated>2008-12-09T07:09:29.338-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore Fields'/><title type='text'>Cross Database TreeList Field</title><content type='html'>Sometimes we would like to have an opportunity to get data from another database in sitecore field. Since we already have &lt;a href="http://sdn5.sitecore.net/Resources/Shared%20Source/Shell%20Extensions/TreeList/Downloads.aspx"&gt;source code of TreeList field on SDN&lt;/a&gt;, I decided to adjust it a little bit to have such opportunity.&lt;br /&gt;To allow cross db usage I had to add one parameter to the source query of TreeList field.&lt;br /&gt;It's SourceDatabaseName parameter.&lt;br /&gt;Here is example how to get users from security database in TreeList field.&lt;br /&gt;&lt;div style="font-weight: bold;"&gt;DataSource=/sitecore/users&amp;amp;SourceDatabaseName=security&lt;/div&gt;&lt;br /&gt;Here is the way it looks:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gDIVYhqZmFo/R8xPTm5Hr_I/AAAAAAAAA3Q/WEZGGMPKJ5g/s1600-h/HowItLooks.PNG"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_gDIVYhqZmFo/R8xPTm5Hr_I/AAAAAAAAA3Q/WEZGGMPKJ5g/s320/HowItLooks.PNG" alt="" id="BLOGGER_PHOTO_ID_5173597270218092530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To get rid of broken links in this field I had to MultilistCrossDbField which is intended to validate links correctly in LinkDatabase. So, don't forget to add the line below into &lt;span style="font-weight: bold;"&gt;/App_Config/FieldTypes.config&lt;/span&gt; file:&lt;br /&gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;............&lt;br /&gt;&amp;lt;!-- Custom fields --&amp;gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;fieldtype name="tree list cross db" type="Custom.Data.Fields.MultilistCrossDbField,TreeListCrossDB"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;/fieldtype&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;br /&gt;I added support for "query:" definition into this field. Now you can use either "/sitecore/content" or "query:/sitecore/content/*" as a data source for the field.&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://scusainc.com/supportresources/ivan/fields/treelistcrossdb/TreeList-CrossDB-1.1.zip"&gt;Sitecore Package&lt;/a&gt; for the field.&lt;br /&gt;Here is &lt;a href="http://scusainc.com/supportresources/ivan/fields/treelistcrossdb/TreeListCrossDB_Source-1.1.zip"&gt;source code&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-2985454665225596319?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/2985454665225596319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=2985454665225596319' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2985454665225596319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/2985454665225596319'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/03/cross-database-treelist-field.html' title='Cross Database TreeList Field'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_gDIVYhqZmFo/R8xPTm5Hr_I/AAAAAAAAA3Q/WEZGGMPKJ5g/s72-c/HowItLooks.PNG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5251195438749660493.post-5466243657731018652</id><published>2008-02-29T11:20:00.000-08:00</published><updated>2008-12-09T07:09:29.757-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sitecore Client Tools'/><title type='text'>Go To Item tool</title><content type='html'>Sometimes you have item ID or somebody provides you with pretty long item path and you want to navigate to the item as fast as you can. Of course you can use DBBrowser tool but it's not very convenient switching between several browser windows, isn't it.&lt;br /&gt;So, I created a "Go To Item" tool and I like to share it with Sitecore lovers :).&lt;br /&gt;To get it working you have to install the attached Sitecore package on your Sitecore.&lt;br /&gt;After installation you can see the "Go To Item" button on Developer tab.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gDIVYhqZmFo/R8hbOG5Hr4I/AAAAAAAAA10/7shYpoUki4Y/s1600-h/DeveloperTab.PNG"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_gDIVYhqZmFo/R8hbOG5Hr4I/AAAAAAAAA10/7shYpoUki4Y/s320/DeveloperTab.PNG" alt="" id="BLOGGER_PHOTO_ID_5172484469961502594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After clicking the button you get dialog window where you should input item path/ID. Since /sitecore item is a root of any sitecore trees you can avoid it in item path.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gDIVYhqZmFo/R8hbV25Hr5I/AAAAAAAAA18/UOsvOiEsIMM/s1600-h/GoToItemDialog.PNG"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_gDIVYhqZmFo/R8hbV25Hr5I/AAAAAAAAA18/UOsvOiEsIMM/s320/GoToItemDialog.PNG" alt="" id="BLOGGER_PHOTO_ID_5172484603105488786" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://scusainc.com/supportresources/ivan/tools/gotoitem/gotoitem-1.0.zip"&gt;Sitecore package&lt;/a&gt; (follow readme instruction during installation).&lt;br /&gt;Here is &lt;a href="http://scusainc.com/supportresources/ivan/tools/gotoitem/gotoitem_sources.zip"&gt;GoToItem sources&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5251195438749660493-5466243657731018652?l=sitecoregadgets.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sitecoregadgets.blogspot.com/feeds/5466243657731018652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5251195438749660493&amp;postID=5466243657731018652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/5466243657731018652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5251195438749660493/posts/default/5466243657731018652'/><link rel='alternate' type='text/html' href='http://sitecoregadgets.blogspot.com/2008/02/go-to-item-tool.html' title='Go To Item tool'/><author><name>Ivan</name><uri>http://www.blogger.com/profile/09998430037866709466</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_gDIVYhqZmFo/R8hbOG5Hr4I/AAAAAAAAA10/7shYpoUki4Y/s72-c/DeveloperTab.PNG' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
