<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Ken McAndrew</title><link href="http://world.optimizely.com" /><updated>2015-11-21T02:46:47.0000000Z</updated><id>https://world.optimizely.com/blogs/ken-mcandrew/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Exploring Episerver Part 1.5: Working Locally, Database, Source Control, and&#160;Configs</title><link href="http://kmac23va.tumblr.com/post/133627469165" /><id>&lt;p&gt;A couple of start-up thoughts I had for a Friday evening&amp;hellip;&lt;/p&gt;&lt;!-- more --&gt;&lt;p&gt;First, on working locally with the website. You can of course install Episerver via NuGet and work with it, but without a license, you can’t effectively use it outside of your local machine. Most CMSes I work with, I publish it out to a full IIS website with a hostname setting, like&#160;“local.mysite.com” - you’ll find you can’t do that with Episerver, at least not without getting a lot of annoyware all over your site. If you run the site through Visual Studio’s IIS Express, you’ll have no problems, but to keep from constantly having to start your site, you’ll want to disable the Edit and Continue function in the debugging. If you do like the publishing to IIS idea (to take advantage of config transforms&amp;hellip;coming up later), you &lt;i&gt;can&lt;/i&gt;&#160;do it, but you have to push to a site specifically using the&#160;“localhost” name to avoid the annoyware.&lt;/p&gt;&lt;p&gt;Next, the database used in our standard setup can be found in the App_Data folder. If you look for it in Visual Studio, you won’t see it unless you turn on the&#160;“show all files” function. If you’re running SQL Server Express, you can copy that database file to another location and attach to it in SQL Management Studio to bring it into SQL Server, instead of running as LocalDB. Especially if you’re using the localhost publishing above, you might want to do this to protect your content (luckily your data modeling comes from your code).&lt;/p&gt;&lt;p&gt;For source control, I’d say put everything in there except the&#160;“modules” folder. Based on my initial look at everything, since that folder contains the CMS itself and you can get that from NuGet, there’s really no need to keep it in source control. I’d also consider leaving out the “App_Data” folder; the GeoLiteCity.dat file comes from the CMS install, the database isn’t something you’d put in source control typically (and if you moved it out, it wouldn’t be here anyway), and the log files don’t need to be kept forever certainly.&lt;/p&gt;&lt;p&gt;Finally, with the config files, I always use config transforms to make changes beyond the base file. That way, if you do any upgrades in the future, you can just overwrite the base config with the new base, and your changes will fall into place. I suggest grabbing the SlowCheetah Visual Studio extension to do your transforms; once you use it, it’ll add a NuGet reference for you. Also, take advantage of having both build-level and publish-level transforms; you can make changes based on Debug and Release states for building, then modify it further based on the publish profile you use. Note that if you need to create web.config transforms based on publish profiles, you’ll need to go into the Properties menu, select the specific profile, and right-click to choose&#160;“add web.config transform” (don’t select&#160;“add transform” or you’ll get transforms based on the publish profile itself!).&lt;/p&gt;</id><updated>2015-11-21T02:46:47.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Exploring Episerver Part 1: Getting Set Up</title><link href="http://kmac23va.tumblr.com/post/133503976875" /><id>&lt;p&gt;Now that the Episerver Ascend conference is done in Vegas, and I had a good time meeting other developers and fellow EMVPs, I figured this would be a good time to start teaching myself Episerver. And since Sitecore is now my primary day job, it’ll be a night task that I’ll be fitting in as I can.&lt;/p&gt;&lt;p&gt;I’ve decided that I need a website of my own, and I was looking for a new host, so I decided to combine all this into a starting Episerver project. So here we go!&lt;/p&gt;&lt;!-- more --&gt;&lt;p&gt;The first thing you’ll need is Visual Studio, and I highly recommend getting 2015 at this point. The Community edition will work just fine, and it’s free. After that, go into the Tools &amp;gt; Extensions and Updates and search the online catalog for Episerver. You’ll find the &lt;b&gt;Episerver CMS Visual Studio Extension&lt;/b&gt;. Install this, and you’ll have the installers you’ll need for Episerver projects.&lt;/p&gt;&lt;p&gt;When you go to create a new project now, you’ll see an Episerver entry on the menu, with a single option to create Episerver projects. Once you pick that, you’ll get three options. Forget you ever saw the Alloy (WebForms) option&amp;hellip;we’re dong MVC. :) From here, I’m assuming you’re like me and new to Episerver, so here’s how I’m proceeding.&lt;/p&gt;&lt;p&gt;First, create an Episerver project off the Alloy (MVC) model, which you’ll use as a reference. There’ll be some parts of this we’ll use as a guide, and others we’ll just swipe. :) But that’s why they put it out there, to give you some ideas on where to start.&lt;/p&gt;&lt;p&gt;After that, in another Visual Studio instance, create a blank Episerver project. This will give you the best-practices structuring for a project that you can work with. The one folder I want to point your attention to straight off is the&#160;“modules” folder. See it&amp;hellip;see it&amp;hellip;now ignore it. That’s actually where the Episerver CMS UI is kept, and I’d advise not touching it or putting anything in it. One thing I’m not sure of as I write this is if you can remove it from a production environment, if you don’t want people accessing the CMS from there. There are configurations that you can change to kill access as well, and that might be your safest bet.&lt;/p&gt;&lt;p&gt;When you’re ready to create your first item, using&#160;“add new item,” you’ll see there’s an Episerver category here as well. This will give you some starting templates to work from as you put together your site. Which we’ll do next time. In the meantime, you do have one piece of homework.&lt;/p&gt;&lt;p&gt;Episerver uses a continuous release model, and pushes their updates out via NuGet. In Visual Studio, you can add their feed URL:&#160;&lt;a href=&quot;http://nuget.episerver.com/feed/packages.svc&quot; target=&quot;_blank&quot;&gt;http://nuget.episerver.com/feed/packages.svc&lt;/a&gt;. You can then go into the NuGet Package Manager and check for updates to your Episerver install; start with the Episerver CMS entry, as that will encompass most of the updates from the other packages. After the install, open the NuGet console in Visual Studio and run&#160;“update-epidatabase” to update your database schema to match (if you don’t do this, the next time you run the site you’ll get an error telling you to do it). So get your project updated with the latest version of Episerver before you start programming!&lt;/p&gt;&lt;p&gt;Meantime, if you have questions, you can ask here (I’ll do my best to answer),&#160;check out &lt;a href=&quot;/link/6c9478a8761c41d88dfc32e9ef56e714.aspx&quot; target=&quot;_blank&quot;&gt;Episerver World&lt;/a&gt;&#160;for help, or post on Twitter using the hashtag #EpiDev. That’ll usually get some attention from folks, including other EMVPs, that might be able to help you. I always recommend, if you have a longer question, to post it on the forums at World and then tweet the link out.&lt;/p&gt;</id><updated>2015-11-19T03:45:33.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Advice on Upgrading EPiServer via NuGet</title><link href="http://kmac23va.tumblr.com/post/126916681225" /><id>&lt;p&gt;This was a question I asked about, and I thought I’d share it around. I’m sure many EPiServer developers are on Twitter (if not, you should be) and see the update notices from &lt;a href=&quot;https://twitter.com/athraen&quot; target=&quot;_blank&quot;&gt;Allan Thraen&lt;/a&gt; (if you don’t follow him, you should). You can head into Visual Studio, fire up the NuGet Package Manager, and grab those updates from the &lt;a href=&quot;http://nuget.episerver.com/feed/packages.svc&quot; target=&quot;_blank&quot;&gt;EPiServer NuGet feed&lt;/a&gt;. (If you haven’t tried Visual Studio 2015 yet, I recommend it&amp;hellip;get the Community edition since it’s free and seems to have most of the power of Professional, but you’ll love the new NuGet Package Manager).&lt;/p&gt;&lt;p&gt;So I go in there, and I see those updates and grab them. But then on the nugget.org main feed, I see many other packages crying out to be updated. Entity Framework, Newtonsoft.Json, and others that want me to help them be current&amp;hellip;&lt;/p&gt;&lt;!-- more --&gt;&lt;figure data-orig-width=&quot;407&quot; data-orig-height=&quot;218&quot; class=&quot;tmblr-full&quot;&gt;&lt;img src=&quot;http://36.media.tumblr.com/4d830789d71eb44d81172b968ac5b9bc/tumblr_inline_nt8g1whBMq1r5bq6d_540.jpg&quot; alt=&quot;image&quot; data-orig-width=&quot;407&quot; data-orig-height=&quot;218&quot; /&gt;&lt;/figure&gt;&lt;p&gt;Well, it could be. :) Some of my EMVP colleagues noted that there are packages that don’t play well necessarily with EPiServer once they’re upgraded. So I think your safest bet here is to let EPiServer define the requirements in their packages. If they need Entity upgraded, they should set the minimum requirements for that, and any other package that was integrated because of their install. (Fun fact: after updating EPiServer in my Alloy project this morning, I tried to update NuGet.Core, figuring it’s safe&amp;hellip;I was actually told it was too high a version for one of the EPiServer packages.)&lt;/p&gt;&lt;p&gt;Other stuff you might use, like Bootstrap, JQuery, the Optimization Framework, etc, you’re safe to upgrade on your own. You may need to keep a log of your own as to what to upgrade and not upgrade, and if&#160;you’re in a multi-developer environment, maybe designate a developer as the upgrade&#160;“master” so they can keep the log, etc.&lt;/p&gt;&lt;p&gt;I’d also toss this advice at anyone cross-developing in Umbraco, since they’re the two .NET CMSes I know of that do NuGet-based updating. We won’t mention Sitecore’s&amp;hellip;that upgrade process can be a serious pain, especially if you’re way behind in your updates!&lt;/p&gt;</id><updated>2015-08-17T17:32:12.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Advice on Upgrading EPiServer via NuGet (Updated)</title><link href="http://kmac23va.tumblr.com/post/126916681225" /><id>&lt;p&gt;This was a question I asked about, and I thought I’d share it around. I’m sure many EPiServer developers are on Twitter (if not, you should be) and see the update notices from &lt;a href=&quot;https://twitter.com/athraen&quot; target=&quot;_blank&quot;&gt;Allan Thraen&lt;/a&gt; (if you don’t follow him, you should). You can head into Visual Studio, fire up the NuGet Package Manager, and grab those updates from the &lt;a href=&quot;http://nuget.episerver.com/feed/packages.svc&quot; target=&quot;_blank&quot;&gt;EPiServer NuGet feed&lt;/a&gt;. (If you haven’t tried Visual Studio 2015 yet, I recommend it&amp;hellip;get the Community edition since it’s free and seems to have most of the power of Professional, but you’ll love the new NuGet Package Manager).&lt;/p&gt;&lt;p&gt;So I go in there, and I see those updates and grab them. But then on the nugget.org main feed, I see many other packages crying out to be updated. Entity Framework, Newtonsoft.Json, and others that want me to help them be current&amp;hellip;&lt;/p&gt;&lt;!-- more --&gt;&lt;figure data-orig-width=&quot;407&quot; data-orig-height=&quot;218&quot; class=&quot;tmblr-full&quot;&gt;&lt;img src=&quot;http://65.media.tumblr.com/4d830789d71eb44d81172b968ac5b9bc/tumblr_inline_nt8g1whBMq1r5bq6d_540.jpg&quot; alt=&quot;image&quot; data-orig-width=&quot;407&quot; data-orig-height=&quot;218&quot; /&gt;&lt;/figure&gt;&lt;p&gt;Well, it could be. :) Some of my EMVP colleagues noted that there are packages that don’t play well necessarily with EPiServer once they’re upgraded. So I think your safest bet here is to let EPiServer define the requirements in their packages. If they need Entity upgraded, they should set the minimum requirements for that, and any other package that was integrated because of their install. (Fun fact: after updating EPiServer in my Alloy project this morning, I tried to update NuGet.Core, figuring it’s safe&amp;hellip;I was actually told it was too high a version for one of the EPiServer packages.)&lt;/p&gt;&lt;p&gt;Other stuff you might use, like Bootstrap, JQuery, the Optimization Framework, etc, you’re safe to upgrade on your own. You may need to keep a log of your own as to what to upgrade and not upgrade, and if&#160;you’re in a multi-developer environment, maybe designate a developer as the upgrade&#160;“master” so they can keep the log, etc.&lt;/p&gt;&lt;p&gt;I’d also toss this advice at anyone cross-developing in Umbraco, since they’re the two .NET CMSes I know of that do NuGet-based updating. We won’t mention Sitecore’s&amp;hellip;that upgrade process can be a serious pain, especially if you’re way behind in your updates!&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt;&#160;I had someone at EPiServer reach out to me to ask about this post, which is always cool and makes me as a developer feel valued for feedback. They noted that there should be package constraints in their own packages, so I fired up a blank MVC site and brought in EPiServer to test it out. After I upgraded EPiServer, I went to each package left over in NuGet to update them. Some I was able to do, others I could only do to a certain level. So it does look like EPiServer has limiters on working versions of certain packages.&lt;/p&gt;&lt;p&gt;I think the only thing I could think of to add is to put the maximum package level in as a equals instead, so components are upgraded as EPiServer is. That way, there’s certainty from the vendor which works with which, while keeping the project as up-to-date as possible. Since EPiServer is releasing product updates through their NuGet every two weeks, you’d never be far out of step with general updates with this method.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Glad to see EPiServer was already thinking what I was thinking, though!&lt;/p&gt;</id><updated>2015-08-17T17:32:12.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>IIS Application Pool Recycling - I Did Not Know That!</title><link href="http://kmac23va.tumblr.com/post/126510481435" /><id>&lt;p&gt;So I’m definitely classifying this in a&#160;“I did not know that” category, and after talking to one of my colleagues, he didn’t know it either. So, it makes for a good blog! (And for those who’ve followed my blog, a change of pace from the weekly weight loss report.)&lt;/p&gt;&lt;!-- more --&gt;&lt;p&gt;I was talking with someone and in passing, they mentioned that IIS has a timeout for application pool recycling. At first I’m thinking the idle timeout, which defaults to 20 minutes and which I think most .NET developers know about and alter to suit their needs (or put in a keep-alive function). But they actually meant a real full recycling of the application pool, as if you did iisreset. It’s happening by default. It might even be happening now!&lt;/p&gt;&lt;p&gt;Here’s an article about it:&#160;&lt;a href=&quot;http://blogs.iis.net/owscott/why-is-the-iis-default-app-pool-recycle-set-to-1740-minutes&quot; target=&quot;_blank&quot;&gt;http://blogs.iis.net/owscott/why-is-the-iis-default-app-pool-recycle-set-to-1740-minutes&lt;/a&gt;. Basically, every 29 hours (because Microsoft didn’t want it set to a strict 24 hours and 29 was the first prime number past 24), your application pool recycles. Great for health, but think about what this means. Every 29 hours, whether you’re in the middle of the work day or late at night, your application pool loses session state, application state, and caching state. And now, I think, you’ll see why I’m bringing this up&amp;hellip;&lt;/p&gt;&lt;p&gt;I have a client who has, at times, said the site seems slower to them at certain times of the day. I know their network isn’t the best in the world (heck, they know it too) and I chalked it up to that. But what if this was an instance of a recycle event happening? There’s a lot of cached data in play here&amp;hellip;user profiles, menus, news articles, etc&amp;hellip;and to have to go back to the server not when I told it to, but because of an arbitrary system reset, is potentially a pain in the butt. I imagine if you’re running in the cloud, or running load-balanced servers, you’re more immune to this. But we all know some projects aren’t that distributed.&lt;/p&gt;&lt;p&gt;So, what can you do? Fortunately, there is an override. Head into IIS, go to your application pool, and choose advanced settings. Scroll down to the bottom, and you’ll see that&#160;“1740″ setting that represents 29 hours. Make that a big fat 0, and your application pool won’t recycle at all due to time. However, there’s probably value in doing it periodically, so if you look a little lower, you’ll see where you can set specific times to recycle. Aim for some off-peak hours, like the middle of the night.&#160;&lt;/p&gt;&lt;p&gt;It’s really going to depend on your business model and audience, so plan accordingly!&lt;br /&gt;&lt;/p&gt;</id><updated>2015-08-12T16:52:58.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Config Transforms With SlowCheetah</title><link href="http://kmac23va.tumblr.com/post/108220315735" /><id>&lt;p&gt;Earlier today I wrote a quick blog post on config transforms outside of the web.config. After some comments on Twitter, I did some more research on SlowCheetah, and then did some playing around with a sample project. The good news is, I found a solution that works here. The bad news is, it appears the project&amp;#8217;s been mothballed at Visual Studio 2013&amp;#8230;I don&amp;#8217;t know if it&amp;#8217;ll be installable in 2015 (I haven&amp;#8217;t tried it out yet), but honestly, this is functionality that should be part of the product.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s actually two flavors of SlowCheetah out there. First, there&amp;#8217;s a Visual Studio gallery component, which you can download at&#160;&lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5&quot; target=&quot;_blank&quot;&gt;https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5&lt;/a&gt;. This installs a context menu where you can right-click on a config file and choose to &amp;#8220;Add Transform File&amp;#8221; which will put in a transform for each configuration entry you have in your project.&lt;/p&gt;
&lt;p&gt;Second, there&amp;#8217;s a NuGet package (just find the base name &amp;#8220;SlowCheetah&amp;#8221;) that installs the transformation engine into the project. You&amp;#8217;ll actually need both parts to make this work&amp;#8230;if you only install the gallery portion, you&amp;#8217;ll be able to create transform files, but when you publish they won&amp;#8217;t transform. If you only install the NuGet portion, you&amp;#8217;ll be able to transform files, but there&amp;#8217;s no built-in mechanism for creating and linking those transforms. Since the method I used in my prior blog entry transforms the in-project config as well, I think I&amp;#8217;d avoid it after thinking about it so you don&amp;#8217;t have the source control issues I mentioned.&lt;/p&gt;
&lt;p&gt;So install both parts and you should be good to go. Here&amp;#8217;s hoping there&amp;#8217;s support behind VS 2013!&lt;/p&gt;</id><updated>2015-01-16T03:36:43.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Config Transform Beyond Web.Config (Updated)</title><link href="http://kmac23va.tumblr.com/post/108188727150" /><id>&lt;p&gt;&lt;span&gt;If you&amp;#8217;ve worked with web application projects in Visual Studio lately, you know about the web.config transforms. Basically, create a new project, and you&amp;#8217;ll see your web.config expands and, by default, there&amp;#8217;s a web.config.debug and a web.config.release. This lets you change out elements based on the configuration you&amp;#8217;re using, and a good couple of samples in what you&amp;#8217;re provided are the &amp;#8220;debug=true&amp;#8221; statement and settings customErrors to RemoteOnly instead of Off in release mode.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But if you have other config files (for example, Ektron has an application.config, Sitecore has a connectionstrings.config, and Umbraco has an umbraco.config) there&amp;#8217;s no direct way to add a transform. But there is a back way that involves editing your project file. Here&amp;#8217;s what to do:&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Create the transform file by making a config file named after your base config file. So if your file is Application.config, name your transform Application.Debug.config for a Debug platform, Application.Release.config for a Release platform, etc.&lt;br /&gt;&#160;&#160;&lt;/li&gt;
&lt;li&gt;Unload the project in Visual Studio, then&#160;&lt;span&gt;open the project file (IE the .csproj file for C#) in a notepad file.&lt;br /&gt;&#160;&#160;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Search for your transform file&amp;#8230;it&amp;#8217;ll likely be listed as a &amp;lt;Content&amp;gt; entry.&lt;br /&gt;&#160;&#160;&lt;/li&gt;
&lt;li&gt;Change the entry from Content to None to match the following pattern, assuming we&amp;#8217;re creating an entry for the debug here:&lt;br /&gt;&lt;p&gt;&amp;lt;None Include=&amp;#8221;App_Config\Application.Debug.config&amp;#8221;&amp;gt;&lt;br /&gt; &amp;lt;DependentUpon&amp;gt;Application.config&amp;lt;/DependentUpon&amp;gt;&lt;br /&gt; &amp;lt;IsTransformFile&amp;gt;True&amp;lt;/IsTransformFile&amp;gt;&lt;br /&gt; &amp;lt;/None&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Save the file, then reload the project. You&amp;#8217;ll see your transform file has been folded underneath.&lt;br /&gt;&#160;&#160;&lt;/li&gt;
&lt;li&gt;Create a publish profile with your specified configuration.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;A good news/bad news caveat to this method. The web.config transform does not change the actual web.config file, it only produces the result at the destination. So the bad news is, with this methodology, a build or publish will cause the base file to change to match your transformation requests. This can be a mild headache that you may want to undo later from source control. But the good news is, this method works for both builds AND publishes, whereas the out-of-the-box web.config transforms only work on publish. So if you&amp;#8217;re just building in place and have your local IIS pointed to your project file, you can get the transform you want for your other config files.&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s a question&amp;#8230;has anyone pulled this off treating the secondary config files like web.config? That is, so it doesn&amp;#8217;t transform the file in your project (thus constantly checking it out of source control if you&amp;#8217;re using it) but publishes out the transformed file?&lt;/p&gt;
&lt;p&gt;Hope this helps some folks and others can help me out!&lt;/p&gt;
&lt;p&gt;UPDATE: I&amp;#8217;ve had folks recommend Slow Cheetah to me for this purpose. There&amp;#8217;s apparently a NuGet option and a Visual Studio Gallery option. I tried the NuGet and it didn&amp;#8217;t seem to work, but when I installed the VS Gallery it worked just like the web.config. So if you&amp;#8217;re trying to do this, give this a go:&#160;&lt;a href=&quot;https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5&quot; target=&quot;_blank&quot;&gt;https://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5&lt;/a&gt;&lt;/p&gt;</id><updated>2015-01-15T21:04:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>On Upgrading Ektron, Or Why It&#39;s A Headache Out Of The Box</title><link href="http://kmac23va.tumblr.com/post/100250879755" /><id>&lt;p&gt;Recently, we did an upgrade to an Ektron project from 8.6.1 to 9.1 SP1, as well as converting the search system from MS Search to Solr. It&amp;#8217;s set up as a pretty default Ektron deal&amp;#8230;the project was built in the web site project that comes in the site setup (CMS400Min), the database didn&amp;#8217;t have any custom tables inside it, etc. But after we ran the upgrade, we ran into performance issues, even though we&amp;#8217;d heavily cached the application.&lt;/p&gt;
&lt;p&gt;On another project that&amp;#8217;s 8.7 SP2, we&amp;#8217;ve been asked to evaluate the project for an eventual upgrade to 9.1 SP1 (or whatever the latest is at that point). Again, built off CMS400Min (as well as eIntranet, if you remember that chestnut), but they have a lot of custom tables in the Ektron database. And the project&amp;#8217;s a mess of files.&lt;/p&gt;
&lt;p&gt;After both of these, I was banging my head into the wall (sometimes not figuratively). How could this be so difficult? There&amp;#8217;s a function built into the site setup to do this, after all! So I became inspired to write this. Consider this a setup best practice guide to help make your upgrades easier, I hope.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;First things first. I&amp;#8217;m a huge proponent of using a web application project to build on top of the CMS400Min site, and to not even bother opening that min site (&lt;a href=&quot;http://kmac23va.tumblr.com/post/62434470264/visual-studio-development-configuration-thoughts&quot; target=&quot;_blank&quot;&gt;I wrote more about that topic here&lt;/a&gt;). But if you don&amp;#8217;t want to go that route, let&amp;#8217;s discuss the situation I outlined above&amp;#8230;you&amp;#8217;re going to use the web site project. (Are you sure? Last chance&amp;#8230;okay&amp;#8230;) When you build your custom code, do not put it in the site root or any of the folders that come with the project itself. Even with the App_Code folder, you&amp;#8217;ll see that Ektron ships with a CSCode and VBCode folder&amp;#8230;make your own subfolder(s) and put your custom code in there. &lt;em&gt;(Side note: why is there still a VBCode folder? It&amp;#8217;s just a text file now, no other code in there&amp;#8230;could we clean that up, Ektron?)&lt;/em&gt;&#160;&lt;/p&gt;
&lt;p&gt;Second thing, do as few changes to the web.config as you can from the baseline, and what changes you do make, note them in a separate file. The big thing I&amp;#8217;m referring to here is your custom application settings that I see clients add to the web.config. There&amp;#8217;s a nice file called application.config provided out of the box that you should use, because then you can back that file up and be good to go. Of course, if you&amp;#8217;re more enterprising, you could try storing your keys in Ektron itself so you don&amp;#8217;t need to recompile to make changes (&lt;a href=&quot;http://kmac23va.tumblr.com/post/61546692788/using-an-ektron-smart-form-for-configuration&quot; target=&quot;_blank&quot;&gt;conveniently I talk about this here&lt;/a&gt;). If you make any other config changes, like to the AssetManagement.config, be sure to back them up or source control them.&lt;/p&gt;
&lt;p&gt;Third, if you do need to use custom tables/views/stored procedures/etc for your application, don&amp;#8217;t do it inside the Ektron database. An upgrade likely won&amp;#8217;t cause any problems, but do you want to chance it? Since you&amp;#8217;ll be building your own data layer anyway, put the code in a separate database, add the connection string to your web.config, and link up that way.&lt;/p&gt;
&lt;p&gt;Finally, regarding Ektron&amp;#8217;s API calls. As much as possible, make sure you&amp;#8217;re using the Framework API. I know there&amp;#8217;s still things that the legacy APIs do that the Framework APIs don&amp;#8217;t do natively or as quick-to-write as they did, but find the workarounds. There&amp;#8217;s definitely still pieces that aren&amp;#8217;t in the new APIs (like discussion forum content types - ContentManager will get you some of the way, but not wholly there) that I hope Ektron will add on if they&amp;#8217;re going to support those types out of the box going forward.&lt;/p&gt;
&lt;p&gt;Once you&amp;#8217;re on the Framework APIs, make sure you&amp;#8217;re using the appropriate access levels for the tasks you&amp;#8217;re doing. This is where we ran into the performance issues. We were calling UserManager with no access context (so it&amp;#8217;ll default to LoggedInUser) and it was performing access checks that, for purposes of the script at hand, wasn&amp;#8217;t needed. (Although it did uncover some very inefficiently-written SQL in the functions from Ektron, so yes, the scripts in the database could use a good scrubbing as much as the workarea code could!) Point being, unless you need the logged-in user context for some reason (like private content checks or updating content to ensure it&amp;#8217;s the updater&amp;#8217;s name and not &amp;#8220;internal administrator&amp;#8221;), I&amp;#8217;d stick to using the admin context. If you do things as I specified with a web application project, in your data access class you can make your own constructors to ensure which context is called by default, and then when you&amp;#8217;re calling those more specific functions you won&amp;#8217;t need to worry about it except in rare circumstances.&lt;/p&gt;
&lt;p&gt;So this all leads into the original point, upgrading. At this point, it doesn&amp;#8217;t matter how you set your project up (web site or web app), as I&amp;#8217;m going to make the process very simple for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step One:&lt;/strong&gt; Back up your custom folders (or have them source controlled already - &lt;a href=&quot;http://kmac23va.tumblr.com/post/89356511245/ektron-tfs-and-you&quot; target=&quot;_blank&quot;&gt;yeah, I wrote about that too!&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Two:&lt;/strong&gt; Throw out your website. Yes, I said that. Throw it out. It&amp;#8217;s okay&amp;#8230;you&amp;#8217;ll be fine&amp;#8230;it&amp;#8217;s just code. And if you didn&amp;#8217;t skip Step One, you still have the good stuff!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Three:&lt;/strong&gt; Run the Ektron site setup for the upgraded version of the CMS and do the full installation - this will give you a new CMS400Min for your site. Don&amp;#8217;t bother doing the database setup part of it, that&amp;#8217;s next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Four:&lt;/strong&gt; Copy your custom code back into the CMS400Min site. The only file you should have to worry about is the web.config&amp;#8230;if you kept your customizations in a separate file, you can do a manual integration, or do a diff between your web.config and the new web.config. There&amp;#8217;ll be updated references to DLLs, etc, especially if you did a big jump in versions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Five:&lt;/strong&gt; Run the Ektron site setup again, but this time choose database upgrade. It&amp;#8217;ll get the connection information from your site and take care of the upgrade for you. (This is the one part you&#160;&lt;em&gt;want&lt;/em&gt; to do out of the box.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Six:&#160;&lt;/strong&gt;Do any other tasks you need to do, like setting up your new search environment if you went to 9+ and Solr. But the big stuff should be done, and you should be able to fire up your site!&lt;/p&gt;
&lt;p&gt;So I&amp;#8217;m sure you&amp;#8217;re now asking why I said to do it this way. If you&amp;#8217;ve ever done an upgrade out of the box, you&amp;#8217;ll see that Ektron will sometimes create a second bin directory, and then make new references to point to the correct DLLs in the web.config. This not only can be very messy, but with multiple locations for these files, you can end up in DLL Limbo (not quite DLL Hell but you&amp;#8217;ll feel it). Rather than end up with an even more complex config and more lingering files, keep it simple and clean.&lt;/p&gt;
&lt;p&gt;Also, if you read my article on setting up a web application project, you&amp;#8217;ll see that we&amp;#8217;re basically doing this every time&amp;#8230;we copy the custom code overtop a CMS400Min site and we&amp;#8217;re ready to rock. It minimizes the Ektron DLLs needed in your custom code, makes it easier to upgrade, and if there&amp;#8217;s ever a problem you can just jettison your site, drop in a new CMS400Min, and be good to go.&lt;/p&gt;
&lt;p&gt;So yes, at the end of the day it does come down to project organization. And maybe you&amp;#8217;re too far down the path to do some of these things. But if you can iteratively put some of these suggestions into practice, I think you&amp;#8217;ll find life will be easier for you when upgrade time rolls around.&lt;/p&gt;
&lt;p&gt;Any other suggestions or thoughts on this, put them in the comments!&lt;/p&gt;</id><updated>2014-10-17T19:23:09.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Ektron Smart Forms For the Marketer</title><link href="http://kmac23va.tumblr.com/post/94643463955" /><id>&lt;p&gt;&lt;em&gt;Originally posted at&#160;&lt;a href=&quot;http://www.ektron.com/Blogs/Ken-McAndrew/Smart-Forms-For-the-Marketer/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;http://www.ektron.com/Blogs/Ken-McAndrew/Smart-Forms-For-the-Marketer/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As any of my developer brethren will tell you, I’m a big proponent of Ektron’s Smart Forms. In our world, they’re a great way to structure content, to make dictionary objects for storing things like settings, and to store more data in a defined way than is natively available in the Ektron workarea. I like to call them a database inside the database.&#160;&lt;/p&gt;
&lt;p&gt;But this is geared more towards marketers and decision-makers, those that use what we developers do. So you might not be familiar with what a Smart Form is or why it’s a good idea to use it. Hopefully after this, you’ll not only understand it, but if your application isn’t making use of the concept, you’ll convince your development team to look into it.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consistency, Consistency, Consistency&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I noted, Smart Forms are a great way to structure content. Take the standard Ektron content item for example. When you create a new piece of content, you’ve got the title, a teaser/summary, and a text body to work with. In that text body, you can put anything you like, styled however you like. I’m sure at first you’re thinking this is a good thing…but what happens when you have ten, twenty, or a hundred people who all have that same idea? Then factor in that your website has standard styles for headings, text, bullet lists, etc. – &lt;strong&gt;every little formatting decision you put in there could violate those standards, and someone will make you go back over and over to fix it&lt;/strong&gt;. Sure, using the editor you could actually apply styles that are defined by your designers and implemented by your developers, but trust me, we like to use names that make technical sense and maybe not “human sense” – do you want to be asking every time you see a style called “colRtH2” as to what that is and if you should use it?&lt;/p&gt;
&lt;p&gt;Enter the Smart Form.&#160;&lt;strong&gt;Instead of that big empty text body, you’ll instead get a nice input form to work with&lt;/strong&gt;, kind of like you’re on a website signing up for something. (Don’t worry, you won’t get spam mail doing this.) You’ll find fields that will be clearly labeled with what content should go there, or an image or file selector, or even a date picker or link selector. The nice thing is that a well-developed Smart Form can also have a full set of instructions built in, so you know just what is expected and what limitations there might be on your content (for example, an image should be only 200x200 maximum or it’ll be auto-cropped).&lt;/p&gt;
&lt;p&gt;Once you fill out that information, everything will drop into place on the appropriate page of your site, all styled up without your having to worry about it. If that “colRtH2” style should be applied with Comic Sans and a bright pink color, it’s all taken care of (and then scold your designer!). It takes a lot of the guesswork out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reusable Content&lt;/strong&gt;&#160;&lt;/p&gt;
&lt;p&gt;Even better, your content can be reused throughout the site in a variety of ways. Let’s say you filled out a Smart Form for a news article. You’ll have the article page, of course. But then you’ll have some summary list of news articles. You may have a sidebar component that lists the story of the day or most popular article. You might even have a homepage that can be reconfigured based on the importance of news articles. By using Smart Forms,&#160;&lt;strong&gt;it doesn’t matter where the content is used or how, because it’ll look right in all locations&lt;/strong&gt;, and you won’t have people asking why there’s an oddball look to something in one location because of some random formatting you did.&lt;/p&gt;
&lt;p&gt;But don’t worry, even Smart Forms have a freeform textual element, where you can still do all the styling you want. But expect that to be used for the body of an article, which will likely only be displayed in one place. All the reusable components will still be well formatted.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Making Search Better&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The final advantage to Smart Forms in this world is search. Not only will the Ektron search engine crawl your title, but it can also crawl each individual field in your smart form.&#160;&lt;strong&gt;This allows for tighter targeting of content, both from a broad perspective as well as by creating facets to let end users further narrow their results&lt;/strong&gt;. If you work with your developers in the page design process, you can even find some of your fields becoming behind-the-scenes metadata to make your content stand out more to Google or Bing.&#160;&lt;/p&gt;
&lt;p&gt;If you search for “Ektron Smart Forms” you’ll find a lot of developer talk around them. Hopefully you see why now. We use them because it not only makes our world easier, but it can make yours easier, too.&lt;/p&gt;</id><updated>2014-08-13T19:27:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Ektron, TFS, and You</title><link href="http://kmac23va.tumblr.com/post/89356511245" /><id>&lt;p&gt;So this question came in from Twitter, and I&amp;#8217;ve seen it before, but to go over the nuances is difficult in 140 character chunks, so let&amp;#8217;s try this.&lt;/p&gt;
&lt;p&gt;As those of you who&amp;#8217;ve worked with Ektron know, it&amp;#8217;s a web site project at its core. (Trust me,&#160;&lt;strong&gt;many&lt;/strong&gt; of us are arguing for a web app project model&amp;#8230;and we&amp;#8217;ll keep doing it, too.) Now while this is a pain, it can also be a benefit to you, and here&amp;#8217;s how.&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;When you install Ektron, you get to the site setup and you get the CMS400Min site. This installs the workarea, the default widgets, and all the baseline goodies that make Ektron work. So you&amp;#8217;ve done that part, and here&amp;#8217;s lesson one:&#160;&lt;em&gt;You do not put any of that into TFS&lt;/em&gt;. Several reasons come to mind for this. One, it&amp;#8217;s a LOT of code that you&amp;#8217;re not likely to be touching. Two, when you have to do upgrades, that&amp;#8217;s a LOT of code you&amp;#8217;d have to check out just to make it writeable. Three, if you ever have a problem, you can pick up the site and toss it in the trash, then build a new CMS400Min out and you&amp;#8217;re back. The magic of that comes next.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll want to set up a Visual Studio solution for your Ektron project. I recommend &lt;a href=&quot;http://kmac23va.tumblr.com/post/62434470264/visual-studio-development-configuration-thoughts&quot; target=&quot;_blank&quot;&gt;this method for organizing your projects&lt;/a&gt;&amp;#8230;I think the guy who wrote it is pretty smart. (Okay, I&amp;#8217;m biased, it&amp;#8217;s me.) To give you the high-level benefits here, if you manage it right, you&amp;#8217;re constraining your Ektron DLLs to a single project (your Data class), so when you have to do upgrades, you just update those DLLs and you&amp;#8217;re good to go. The best approach I found is to add an &amp;#8220;ExternalReferences&amp;#8221; folder to your project and put the DLLs in there, then reference them from that location. That ensures they get checked into TFS, and when you use TFS&amp;#8217; build engine, it can find them. (I tried putting them external to the project structure but still in TFS but it didn&amp;#8217;t compile&amp;#8230;if you can make that work, please share!) The other thing you need to do is copy the web.config from the Ektron CMS400Min and put it in your web application project.&lt;/p&gt;
&lt;p&gt;Now you have to do a build. Let&amp;#8217;s take the local developer&amp;#8217;s environment first. You&amp;#8217;ll have set up a local Ektron site on your computer with a CMS400Min. Then, go into your web application project&amp;#8217;s properties and go to the Build Events. For the post-build event, use this:&lt;/p&gt;
&lt;p&gt;cd $(SolutionDir)&lt;br /&gt;xcopy &amp;#8220;$(ProjectDir)*.*&amp;#8221; &amp;#8220;[WEBSITE LOCATION]&amp;#8221; /E /I /R /D /C /Y /EXCLUDE:excludedfileslist.txt&lt;/p&gt;
&lt;p&gt;Where [WEBSITE LOCATION] is the file path to your site (like c:\inetpub\wwwroot). The excludedfiles.txt is used to prevent the copying of things like the .aspx.cs files, and should sit on the same folder level as your solution file; you can create a solution folder and store it in there for reference and TFS check-in. Here&amp;#8217;s what I recommend as a default, but adjust as best suits your needs:&lt;/p&gt;
&lt;p&gt;.asax.cs&lt;br /&gt;.asax.designer.cs&lt;br /&gt;.ascx.cs&lt;br /&gt;.ascx.designer.cs.aspx.cs&lt;br /&gt;.aspx.designer.cs&lt;br /&gt;.master.cs&lt;br /&gt;.master.designer.cs&lt;br /&gt;.asmx.cs&lt;br /&gt;.asmx.designer.cs&lt;br /&gt;.ashx.cs&lt;br /&gt;.ashx.designer.cs&lt;br /&gt;.svc&lt;br /&gt;.htm&lt;br /&gt;.html&lt;br /&gt;.Debug.config&lt;br /&gt;.Release.config&lt;br /&gt;.csproj&lt;br /&gt;csproj.user&lt;br /&gt;obj\&lt;br /&gt;Properties\&lt;br /&gt;ExternalReferences\&lt;br /&gt;web.config&lt;/p&gt;
&lt;p&gt;The web.config I recommend changing manually. Now this is just doing it via build, you could use the publish process and config transforms to do the job as well. Just most folks are used to using that F5 build/debug bit and that just does builds.&lt;/p&gt;
&lt;p&gt;Speaking of debugging, to set that up you&amp;#8217;ll become less reliant on F5 and more on &amp;#8220;Attach to Process&amp;#8221; which you can find in the Debug menu. First make sure your site is started in IIS (just hit the site), then launch Attach to Process. Make sure the checkbox to see all processes is on, then look for w3wp.exe. You want to attach to that. This should give you breakpoints, etc. It won&amp;#8217;t let you debug Ektron&amp;#8217;s workarea or the like, but if you really want to do that, you can always open the site as a web site project and go that route.&lt;/p&gt;
&lt;p&gt;One other caveat for development is with PageBuilder. Since PageBuilder relies on user controls that are in the workarea, you won&amp;#8217;t have them in your web application project. But you can just put the references in the file and then build your structure. You lose Intellisense, but I think you gain far more. Plus, PageBuilder keeps improving to where more of the layouts can be built via Ektron&amp;#8217;s GUI, so it may be minimal structure you have to set up for drop zones.&lt;/p&gt;
&lt;p&gt;The one other question was on versioning smart forms. The smart forms are kept in the database and don&amp;#8217;t have version control specifically there, so barring database backups you&amp;#8217;re a little out of luck. There may be some help though. First, you can copy the HTML structure of the smart form designer and store it in a text file, and if you paste it back in it&amp;#8217;ll recreate the structure. You can also use content types to strong-type your smart form calls (&lt;a href=&quot;http://kmac23va.tumblr.com/post/17579016242/enhancing-ektron-content-types-updated-link&quot; target=&quot;_blank&quot;&gt;I highly recommend it!&lt;/a&gt;) which you might be able to use to recreate your smart forms. But if you want the quick and dirty way, the first option will be your best bet if someone comes along and messes things up. (Of course, I&amp;#8217;d use role permissions to keep those who don&amp;#8217;t need to develop smart forms out of there&amp;#8230;)&lt;/p&gt;
&lt;p&gt;So to tie this all back up. You now have a web application project and library classes in a solution that&amp;#8217;s a lot more lightweight than the Ektron web site project, is more in a best practice setup (you could even add tests!), and is well organized. This makes it very easy to get into TFS. From there, you can run the build scripts in TFS to generate output, whether to a drop folder or to manually grab a zip file. Go into the _PublishedWebsites folder in that drop and you should find all of your web code ready to go. You can exclude the ExternalReferences folder, since all of the DLLs you need will now be in bin. Copy that code to your CMS400Min folder on your development server, and you&amp;#8217;re good to go. Then you can do the same for staging and production, or use eSync if you have that.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m sure there are ways to further automate these processes, and this is based on my experience not being a TFS power user. If you can take this and expand it outwards, please share. The Ektron community loves to swap ideas like this&amp;#8230;use that #Ektron hashtag and you&amp;#8217;ll usually grab attention!&lt;/p&gt;</id><updated>2014-06-20T14:59:48.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Configuring Intranet Security Within Ektron’s CMS</title><link href="http://kmac23va.tumblr.com/post/80189721322" /><id>&lt;p&gt;&lt;em&gt;Originally posted on Celerity&amp;#8217;s blog: &lt;a href=&quot;http://www.celerity.com/blog/2014/03/17/configuring-intranet-security-within-ektrons-cms-part-1/&quot; target=&quot;_blank&quot;&gt;Part 1&lt;/a&gt; and &lt;a href=&quot;http://www.celerity.com/blog/2014/03/18/configuring-intranet-security-within-ektrons-cms-part-2/&quot; target=&quot;_blank&quot;&gt;Part 2&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;When developing an intranet, one of the items to consider straight out of the gate is&#160;&lt;/span&gt;&lt;strong&gt;security&lt;/strong&gt;&lt;span&gt;. A content management system will help you get started, but there are still a number of things to think about. This three-part blog series will explore how to securely configure user setup with an intranet powered by&#160;&lt;/span&gt;&lt;strong&gt;Ektron™&lt;/strong&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;!-- more --&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understanding Ektron Users: Who Holds the Keys?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As of version 9.0, Ektron is divided between&#160;&lt;strong&gt;two user pools based on functional group.&lt;/strong&gt;&#160;The first group is&#160;&lt;strong&gt;CMS authors&lt;/strong&gt;, who have access to the Ektron workarea, PageBuilder configuration, and content. The second group is&#160;&lt;strong&gt;membership users&lt;/strong&gt;, who have no back-end access, but have options for personalization. How many or few of the features you use for each group is up to you, but when choosing your user base for intranet access (that is, the front-end system people will browse daily) you need to consider three main things:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Front-End Access&lt;br /&gt;&lt;/strong&gt;If you’re planning to use&lt;strong&gt;&#160;PageBuilder&#160;&lt;/strong&gt;on your site, you want all of your front-end access to come from the membership user base. This is easy to understand: you don’t want users, when they are just browsing (and especially if that is all they&#160;&lt;em&gt;can&lt;/em&gt;&#160;do) seeing the PageBuilder function bar. Also, when they’re logged into the CMS itself, more JQuery libraries and stylesheets are loaded than are in just “browse” mode, so why burden the user more?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Authentication Schemes&lt;/strong&gt;&lt;br /&gt;Second, and potentially more confusing, is the choice between&lt;strong&gt;&#160;Active Directory (AD) and Lightweight Directory Access Protocol (LDAP)&lt;/strong&gt;&#160;in your authentication schemes. LDAP, besides presenting the caveat of being able to bring in users and not user groups, only allows users to be hooked up to the CMS authors side of the fence. AD allows you to hook in to either membership users or CMS authors, and you can get the groups from AD.&lt;/p&gt;
&lt;p&gt;What I would suggest is&#160;&lt;em&gt;if you have AD&lt;/em&gt;, connect to the membership users so that your end users (of which you will likely have many more of than authors) will have full connectivity of their network passwords to their accounts. You can also import groups for permissions.&lt;/p&gt;
&lt;p&gt;On the other hand,&#160;&lt;em&gt;if you only have LDAP&lt;/em&gt;, I would consider leaving it off as far as the Ektron workarea is concerned. More than likely you will want your end users to keep the same usernames as their network names, although the passwords will not match their network ones. But if you integrate LDAP, those usernames essentially become “reserved” by Ektron since you cannot use the same username twice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Mixed-Mode Authentication&lt;/strong&gt;&lt;br /&gt;A final decision you have to make is if you have the need for “mixed-mode” authentication. For example, say you’re using Active Directory to authenticate users as membership users, but one of the requirements states that users might come from outside of AD. Ektron will not allow you to create users manually if you have AD hooked up. You can create users as CMS authors, but that exposes more permissions and access than you might want, and going the other way could expose the PageBuilder bar to people who don’t need to see it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to Authenticate Intranet Users with LDAP&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For one of our recent intranet clients, we were required to use LDAP for authenticating users for both front- and back-end access. LDAP had to be connected to the CMS author accounts, and we also had to account for non-LDAP users needing front-end access only. This would cause conflict between CMS author usernames and membership account usernames. Also, because membership users are not linkable to LDAP, their network passwords would not be maintainable in Ektron.&lt;/p&gt;
&lt;p&gt;The first thing we did was to connect the CMS authors to LDAP, which is easily done through the workarea. We then had to establish a strategy for handling all front-end (membership) users, allowing for both LDAP users and straight Ektron membership users to log in. Here’s what we came up with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Custom Authentication with LDAP, Ektron and ASP.NET&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What we came up with for LDAP users is using a custom LDAP authentication system for the end users to go through, checking them against the LDAP server separate from Ektron’s check, and then connecting them to an Ektron membership account.&lt;/p&gt;
&lt;p&gt;First, we created a standard ASP.NET login page with the Login control, which gave us the username/password fields as well as a “remember me” checkbox to allow users to maintain their authentication. When the user clicks the Login button, the OnAuthenticate function is triggered, and one of two paths is taken:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Ektron membership is checked directly first to see if the account matches up. This avoids the LDAP processing if it’s not needed, as well as to ensure the first authentication point is for lesser permissions.&lt;/li&gt;
&lt;li&gt;If the user is not found in Ektron membership directly, a custom LDAP authentication call is made. If the user passes that check, they are considered authenticated and they must then be logged into Ektron.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Step 2: Using Pass-Through Authentication To Create User Accounts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We now have a user that we know should be allowed into the intranet, but if this is their first visit, they have no account in Ektron. We could easily create one, of course, but two things prevent this from being a simple exercise. First, the username must be unique, and our user could potentially be a CMS author as well, so we cannot just use their entered username directly. Second, the user entered their network password, which while correct today will likely be changed someday due to network security requirements. That change will be reflected in LDAP, but not Ektron.&lt;/p&gt;
&lt;p&gt;The solution is to use a&#160;&lt;strong&gt;pass-through authentication methodology, creating a presence in the membership world that can be recognized via code&lt;/strong&gt;. We do this by adapting the username and creating a standardized password to use. In this case, we added “mbr” to the end of each username as it came in, to denote a network-based authentication that is now a membership account. For the password, we also used the username and added complex characters around it to create a common, yet hard-to-guess, password algorithm.&lt;/p&gt;
&lt;p&gt;At this point, the user experience becomes identical no matter which way the user entered the system. LDAP-authenticated users do come with other information from the network, like name and email address, which can be used to update the Ektron record and maintain synchronicity between the systems. The membership record can also be used at this point to store other information in custom properties, whether other data for tracking user activity or storing data from other third-party applications. By encapsulating all of the information in the user record, not only does the developer have a single-source location for information, but that information is also searchable in Ektron using the standard APIs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Part 3: Maintaining the Logged-In State Over Extended Periods&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Given that you have more than just basic ASP.NET involved, maintaining the appropriate states can be a bit of a juggling act.&lt;/p&gt;
&lt;p&gt;As far as ASP.NET is concerned, maintaining the login state comes down to &#160;using the Login control’s “remember me” checkbox. The logic behind what to do when this is checked is up to the developer, but typically an authentication ticket is created with an extended timeframe (say a month), so when the user returns to the site, they will continue on without having to enter their login credentials. (That being said, don’t dismiss the KISS method and overlook just usings FormsAuthentication.RedirectFromLoginPage!) This is fine for ASP.NET, and using the stored username and Ektron APIs you can retrieve information about the logged-in user to populate a session variable about them.&lt;/p&gt;
&lt;p&gt;What must be accounted for is the Ektron login. Much like a standard forms authentication ticket (when “remember me” is not checked on), the login period lasts for as long as the user session does, which by default is usually 20 minutes with a sliding expiration. If this time period expires, the user is logged out of Ektron, and if you were using their membership login to control and check permissions, for example, you will have to reauthenticate them without user intervention. And of course, you cannot retrieve their password and you would not store it in any exposed data structure like cookies.&lt;/p&gt;
&lt;p&gt;For this purpose, we actually turned to the legacy Ektron API, which has a function to allow for a user to be authenticated without their password being required. To secure this from spammers and spoofers, the username comes from the User.Identity.Name property, which is populated by the forms authentication ticket, our key to knowing this user is allowed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lessons Learned&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you’re going to use network authentication, favor Active Directory over LDAP. Using AD allows you to connect directly to the membership users without a workaround login, and passwords will be handled by the network system as well. Create any CMS authors manually, as you will likely have far fewer in that group anyway.&lt;/p&gt;
&lt;p&gt;If you are going to need “mixed-mode” membership users, however, you will not be able to use AD either. In this case, you can still maintain your regular usernames in the membership area for ease of use.&lt;/p&gt;
&lt;p&gt;We can take membership users in Ektron and use the pass-through concept to invent a password algorithm. Then, use the authentication steps noted to handle network logins with a custom check as well as manually-created membership users.&lt;/p&gt;
&lt;p&gt;Setting up both ASP.NET forms authentication and Ektron authentication properly is important, especially if you want to maintain a user’s login for an extended period, which many intranet users will likely want to do. Maintain the extended time with forms authentication, then use that information to ensure Ektron authentication is handled seamlessly.&lt;/p&gt;
&lt;p&gt;As always, good requirements gathering at the beginning of the project is the first key to a successful implementation. Understanding what the client can bring to the table for authentication as well as the types of users they’ll want to let into the system (and where), will guide you into the appropriate setup for your intranet.&lt;/p&gt;</id><updated>2014-03-20T21:12:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Road to Ektron 10 - Can We Use Template Names Already?</title><link href="http://kmac23va.tumblr.com/post/76493904398" /><id>&lt;p&gt;Really, this should be an easy one, and if someone would like to sneak it into Ektron 9.1, please feel free.&lt;/p&gt;
&lt;p&gt;For the longest time, when you set up your templates (PageBuilder or not), you give it a nice descriptive name and can even describe your template. But when you go into creating content or PageBuilder pages, the templates always use the filenames, from setting up what templates a folder can use to selecting the template in the drop down for HTML content to the labels for creating PageBuilder pages.&lt;/p&gt;
&lt;p&gt;Soooo&amp;#8230;any reason it can&amp;#8217;t use the template names we give it? And use the descriptions in tooltips?&lt;/p&gt;
&lt;p&gt;As an extra, being able to select the screenshot for the PageBuilder template to use in the add new page dialog would be nice too. I find that if you&amp;#8217;re using forms authentication, it&amp;#8217;ll bounce to the login page for the default screen capture and not give you the template shot you want. I was able to finally replace them manually by pasting what I wanted over top what the system generated, but I had to set them read-only because every so often, Ektron would replace them. Having the ability to supply my own captures (or tell it when to take a capture) would be beneficial.&lt;/p&gt;</id><updated>2014-02-13T04:55:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Road to Ektron 10 - What Developers Want</title><link href="http://kmac23va.tumblr.com/post/75611749296" /><id>&lt;p&gt;I decided to make this blog entry an open forum for developers to drop in things they&amp;#8217;d like to see added/removed/fixed in a theoretical Ektron 10. (Revisit the disclaimer from the last blog entry first!) I know the Ektron dev center has a forum devoted to this kind of thing, but it hasn&amp;#8217;t had a new post in almost a month, and I&amp;#8217;m targeting this more towards the Twitter die-hards. There&amp;#8217;s lot of Ektron developers out there, but those that are on Twitter and use the hashtag and participate in Synergy or Office Hours is a lot lower.&lt;/p&gt;
&lt;p&gt;Remember, I can&amp;#8217;t promise anything on if this stuff happens. And if it&amp;#8217;s something that&amp;#8217;s broken that you need fixed immediately, get ahold of support naturally. But if you have an idea, post it in the comments. If you like someone&amp;#8217;s idea, vote it up.&lt;/p&gt;
&lt;p&gt;Oh, and if you aren&amp;#8217;t going to Synergy, you really should. If you can&amp;#8217;t go, &lt;a href=&quot;http://joegoestosynergy.tumblr.com&quot; target=&quot;_blank&quot;&gt;maybe we can arrange for your face to travel!&lt;/a&gt;&lt;/p&gt;</id><updated>2014-02-04T21:08:58.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Road to Ektron 10: Handling Users</title><link href="http://kmac23va.tumblr.com/post/75286969828" /><id>&lt;p&gt;First off, a disclaimer: I don&amp;#8217;t work for Ektron or have any insight into what &amp;#8220;Ektron 10&amp;#8221; would be. These are just my thoughts on things that should be done.&lt;/p&gt;
&lt;p&gt;From a high-level perspective, I think the time&amp;#8217;s come to really shake up Ektron and shake the tree loose of the legacy stuff. While I used one of the old APIs just recently, it&amp;#8217;s really to the point that things need to be cleaned up, refit, and rebuilt.&lt;/p&gt;
&lt;p&gt;Over the last two weeks I&amp;#8217;ve been doing a lot of work around users in Ektron, and having talked with one of my colleagues yesterday about the processes I&amp;#8217;m using, I&amp;#8217;ve come to the conclusion that it&amp;#8217;s time to abandon the CMS users vs. membership users concept, and instead go to a single user pool.&lt;/p&gt;
&lt;p&gt;First off, there really is one user pool behind the scenes. You can&amp;#8217;t use the same username in CMS and membership users, for example. So this isn&amp;#8217;t a huge change programmatically, I don&amp;#8217;t think. But right now, you have to go to two separate locations to manage the users, and if you want a user to have an everyday membership account versus an as-needed author account, you need two accounts. Especially when you consider PageBuilder, because you don&amp;#8217;t want a person just browsing your site seeing the design bar/elements all the time.&lt;/p&gt;
&lt;p&gt;When you bring in LDAP or Active Directory, things get more complex. If you&amp;#8217;re using LDAP, you can only connect up to CMS users, and groups all have to be done manually. If you&amp;#8217;re using AD, you can connect to either CMS or membership users and bring in the groups, but again, you can only connect to one side.&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s what I&amp;#8217;d do. Go to a single pool of users with three options for the user: member, author, or admin. For the authors, you can then use the roles to give them access to just working with content or being able to use PageBuilder (perhaps even the level of PageBuilder&amp;#8230;can they make master layouts or just page layouts?). I would then expand the user groups and make part of their creation also have a role of member or author. That way, when you assign someone to a group, you can determine what access they have when they&amp;#8217;re in member mode or in author mode, as well as determining what permissions can be set on the folder/content level. To simplify permissions, only groups can be added, not individual users&amp;#8230;I think that&amp;#8217;ll make things easier to manage for admins anyway.&lt;/p&gt;
&lt;p&gt;With respect to the members versus authors, the biggest thing is whether the editing bars show up or not. There&amp;#8217;s already a slider to switch modes in Ektron 9, perhaps a similar slider to turn off edit mode, or add a member/author radio button to the standard login control. I think it should be possible for a user to browse their site as an everyday user and then switch to authoring when needed.&lt;/p&gt;
&lt;p&gt;The final piece surrounds permissions. I think it&amp;#8217;s time to switch to a SQL model of what I call &amp;#8220;negative permissions.&amp;#8221; Currently, permissions work where if you&amp;#8217;re in two groups and you have editing permissions in one group, you have editing permissions regardless if the other group doesn&amp;#8217;t. There would be a need to add a &amp;#8220;no permissions&amp;#8221; option instead of just on/off, because a checkbox off should be interpreted as it is now, which is &amp;#8220;inherit whatever other groups say&amp;#8221; but there could be a &amp;#8220;no permission&amp;#8221; option as well so that if group two is explicitly said that they can&amp;#8217;t edit, the user can&amp;#8217;t edit even if group one says they can.&lt;/p&gt;
&lt;p&gt;Feel free to add your thoughts or ideas in the comments!&lt;/p&gt;</id><updated>2014-02-01T21:42:54.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Visual Studio Development Configuration Thoughts</title><link href="http://kmac23va.tumblr.com/post/62434470264" /><id>&lt;p&gt;I went through an exercise today that made me very glad I&amp;#8217;d set my Visual Studio solution up properly. I had to make some changes to smart forms in my site, changing field types, making multiple fields that were really a &amp;#8220;pick one method&amp;#8221; and so on. After changing the smart forms, then I had to regenerate the XSD-based classes, and then I had to rework the data code. But because I layered my code nicely, that was as far as I had to go.&lt;/p&gt;
&lt;p&gt;I didn&amp;#8217;t come up with this idea myself&amp;#8230;it&amp;#8217;s actually part of an&#160;&lt;a href=&quot;http://www.ektron.com/Webinars/Details/Building-an-Extensible-and-Maintainable-Website-on-Ektron---Part-1/&quot; title=&quot;Ektron webinar by Steve Mann&quot; target=&quot;_blank&quot;&gt;Ektron webinar by Steve Mann&lt;/a&gt;. It was supposed to be focused more on dependency injection but at the end, it kind of skimps out (and I&amp;#8217;m still hoping for part 2 to really address that!). But in there, Steve describes a good method for setting up your Visual Studio solution. Of course, your project may need something else, but this is a good basic start.&lt;/p&gt;
&lt;p&gt;First off, set up a Common class project where you&amp;#8217;ll keep code that&amp;#8217;s used in all of your other classes. Realistically, this should be devoid of Ektron code, mostly containing things like the smart form XSD-generated classes and your own data classes for translating your data source to your website.&lt;/p&gt;
&lt;p&gt;Then, you&amp;#8217;ll want to set up a DataAccess class, which obviously is where you do all of your data retrieval (read: Ektron calls). You should reference the Common class here. Basically, this is where you use the Framework API to retrieve data from Ektron, then pass it off to your own classes to return just the fields and data you need. You can also do searches here against the search API, call third-party data sources, and so on.&lt;/p&gt;
&lt;p&gt;Next, set up a Business class. This is what connects your DataAccess and your website code. You&amp;#8217;ll add references to the Common and DataAccess class projects here. Now a number of your calls here might seem like they&amp;#8217;re just pass-throughs (IE, just calling the DataAccess and doing nothing else). But you should also do any custom caching here, as well as combining multiple data calls if necessary into a single product.&lt;/p&gt;
&lt;p&gt;Finally, you&amp;#8217;ve got your website, whether you&amp;#8217;re using the web site project that installs by default or using a web application project that you later combine into a CMS400Min site. This should have references to the Common and Business classes. At this point, you can see that if needed, you could change out your entire data layer and you wouldn&amp;#8217;t break your code in the website or business layer. This isolation makes it a lot easier to make adjustments as well.&lt;/p&gt;
&lt;p&gt;From there, you can add other helper classes if you want. For example, I have a common functions class that I use from project to project with very generic items, like caching and logging. I also have a common Ektron library that has more generic functions, these routed towards CMS-based items that aren&amp;#8217;t specific to my project. For example, I set up a PageBuilderBase class that holds some of the common functions you find in a PageBuilder wireframe, which I can then inherit from in my website, thus minimizing the copy/paste of code. As you develop more projects, you&amp;#8217;ll find more of these opportunities to refactor and genericize. as well as what you read other developers put out; I added&#160;&lt;a href=&quot;http://developer.ektron.com/Templates/CodeLibraryDetail.aspx?id=940&amp;amp;blogid=116&quot; title=&quot;James Stout&#39;s code to hide unused PageBuilder zones&quot; target=&quot;_blank&quot;&gt;James Stout&amp;#8217;s code to hide unused PageBuilder zones&lt;/a&gt;&#160;to my PageBuilderBase, for example.&lt;/p&gt;
&lt;p&gt;Organizing your project solutions can be a tricky thing, especially if you find yourself unhappy with how you do the initial setup, and it can be really hard to reconfigure once you get into development. I hope this helps you with a starting point at least.&lt;/p&gt;</id><updated>2013-09-27T20:35:30.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Using an Ektron Smart Form For Configuration</title><link href="http://kmac23va.tumblr.com/post/61546692788" /><id>&lt;p&gt;ASP.NET developers are very familiar with the idea of setting global configuration values for a web application. You can use either the appSettings section of your web.config, or you can use an external file like an application.config if you don&amp;#8217;t want to mix things in with your web.config. Fortunately, using Ektron gives you another option that is more flexible from both a development as well as user management perspective.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.com/egandalf&quot; target=&quot;_blank&quot;&gt;James Stout (AKA eGandalf)&lt;/a&gt; recently wrote a &lt;a href=&quot;http://developer.ektron.com/Experts/James-Stout/The-CMS-Architecture-Theory/&quot; target=&quot;_blank&quot;&gt;blog post on architecting your CMS folder structure&lt;/a&gt;. One of these folders is named &amp;#8220;Configuration&amp;#8221; and will be the home for our exercise. We&amp;#8217;ll be using a smart form for setting up the configurations, which not only gives us structure but allows us to set up multiple configuration blocks. This lets us set up one block for site-wide config, another for a specific section&amp;#8217;s config, etc, and set permissions so only certain users can affect certain configurations. (This also shows one advantage, that a developer isn&amp;#8217;t needed to change configurations like they would be with a .config file.)&lt;/p&gt;
&lt;p&gt;The smart form structure is very simple. Set it up with a multi-group-box with two fields in the box, one for Key and one for Value. We&amp;#8217;ll be using the &lt;a href=&quot;http://kmac23va.tumblr.com/post/17579016242/enhancing-ektron-content-types-updated-link&quot; target=&quot;_blank&quot;&gt;content types methodology&lt;/a&gt; for retrieving the data. We&amp;#8217;ll then use a function that returns a Dictionary object (that you should cache!) that will store all of the data; you&amp;#8217;ll find this code on the &lt;a href=&quot;http://developer.ektron.com/Templates/CodeLibraryDetail.aspx?id=1602&amp;amp;blogid=116&quot; target=&quot;_blank&quot;&gt;Ektron code library&lt;/a&gt;. The only change to make would be for the XmlConfigurationId, that should be changed to the ID of your smart form.&lt;/p&gt;
&lt;p&gt;Now that you have your dictionary of config values, you&amp;#8217;re all set to go. You can either call it as needed, or set up a manager class of public property names to retrieve the values from. If you do that, make sure you&amp;#8217;re only using the Get (no Set here), and also make sure you do a sanity check for the key, which is easy to do with a dictionary using ContainsKey.&lt;/p&gt;</id><updated>2013-09-18T03:01:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>An Ektron Taxonomy-Based Breadcrumb System</title><link href="http://kmac23va.tumblr.com/post/49641977488" /><id>&lt;p&gt;If you follow me on Twitter (and let&amp;#8217;s be honest, that&amp;#8217;s how most people know I even have a blog), you&amp;#8217;ve seen my posting about an Ektron taxonomy-based breadcrumb system. Well, here we go!&lt;/p&gt;
&lt;p&gt;&lt;!-- more --&gt;Let me start off with this note. I cobbled together information from various sources to make this work:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;span&gt;Joe Mayberry&amp;#8217;s &lt;/span&gt;&lt;a href=&quot;http://jaytem.com/2012/06/a-user-control-by-any-other-name/&quot; target=&quot;_blank&quot;&gt;blog on making a widget than can double as a user control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;James Stout&amp;#8217;s &lt;/span&gt;&lt;a href=&quot;http://www.ektron.com/Blogs/eGandalf/Reading-Assigned-Categories/&quot; target=&quot;_blank&quot;&gt;blog on reading taxonomies assigned to a content ID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;CodeProject &lt;/span&gt;&lt;a href=&quot;http://www.codeproject.com/Tips/374916/How-to-Get-the-Taxonomy-in-Ektron-CMS&quot; target=&quot;_blank&quot;&gt;article on getting taxonomy data up to the parent&lt;/a&gt;&lt;span&gt; (in the older APIs)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Ektron&amp;#8217;s OnTrek sample site&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Ektron office hours on menus and navigation which had some interesting information.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;span&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I needed a couple of things for my project. First, an alias system to manage the baseline page URLs. Second, a logical but not too deep folder structure to manage pages and content. Third, a breadcrumb system to track the path taken.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;First Thought: Folders!&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So the first thing I thought of using was the folder structure. You can assign automatic aliasing to the folder structure, and the folder properties have a breadcrumb system built into them, along with a FolderBreadcrumb server control. I started setting that up and testing it, and ran into a couple of issues.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;First off, in order to get the automatic aliases working right with folders, you need the folder structure to exactly mimic the URL structure you want to use. Then the content has to be in the correct spot for it to work. This can lead to some odd groupings, though. Let&amp;#8217;s say you have a Pages folder, and under that you have an About folder. When you set up the aliasing, you&amp;#8217;ll obscure the &amp;#8220;Pages&amp;#8221; reference, so you get foo.com/About instead of foo.com/Pages/About. The problem is to get that URL, the landing page for &amp;#8220;About&amp;#8221; has to sit in the Pages folder, not the About folder; otherwise, it&amp;#8217;s foo.com/About/About. So you don&amp;#8217;t have the best content grouping, unless you use a manual alias to override, but now you have an extra alias to manage.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Second, setting up the folder breadcrumbs is a bit of a chore. You have to set up &amp;#8220;Home&amp;#8221; on the Pages folder with the appropriate content block and URL. Then on the About folder, you go into folder properties for breadcrumbs, and it&amp;#8217;s set to inherit the parent folder by default. Of course you need to break this, and while you have the &amp;#8220;Home&amp;#8221; level already there, now you have to set up the &amp;#8220;About&amp;#8221; level. Imagine if you&amp;#8217;re going several levels deep now&amp;#8230;then imagine if you restructure your folders&amp;#8230;okay, come back from the scary place!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Finally, the FolderBreadcrumb control is a fine control that does the management you want easy enough. But you have to handle a couple of things. First, you&amp;#8217;ll likely have the breadcrumb on your master page, which means the DynamicParameter could be &amp;#8220;id&amp;#8221; or &amp;#8220;pageid&amp;#8221; depending on if this is a content template page or a PageBuilder page. Second, if you turn on the option to show the content title of the page you&amp;#8217;re on, you could get a repeat item, like &amp;#8220;Home &amp;gt; About &amp;gt; About&amp;#8221; - the first &amp;#8220;About&amp;#8221; would be hyperlinked, but go to the same page you&amp;#8217;re already on, creating a logic loop for the user. You could keep that off, of course, but most breadcrumbs I see have it on.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Assembling the Troops&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So a lot of this was already new to me because I hadn&amp;#8217;t needed to do breadcrumbs before. So I&amp;#8217;m scrambling to gather information on it early in the week. The first thing I was referred to by Derek Barka was the OnTrek sample site. If you&amp;#8217;ve never downloaded and run that, you really should, because there&amp;#8217;s a lot of cool ideas in there. (There&amp;#8217;s this trick they do with PageBuilder as a template of its own that I&amp;#8217;m going to use, but that&amp;#8217;s another discussion.) OnTrek has folder bookmarks all set up, so it&amp;#8217;s easy to see how it&amp;#8217;s supposed to be done.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The other trick OnTrek did for aliasing was to use taxonomy instead of folders. Basically, they created a taxonomy devoted to site navigation and assigned the appropriate node to a content block. This gives the advantage of the content being agnostic to a grouping folder, so if a piece of content is five levels deep in the alias, you don&amp;#8217;t need to make five levels in folders to hold it. In our case, we only wanted to go two or three levels deep for folders. Plus, it ensures that every content block that serves as a page has taxonomy assigned in some fashion, which can help your search results and other groupings.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then the Ektron office hours on menus and navigation hit, and we discussed doing breadcrumbs via taxonomy. Bill Cava brought up using custom properties to store the names and URLs you wanted to use for breadcrumbs, while Chris Osterhout mentioned using the Category Link field already built into taxonomy to store the breadcrumb URL. (It should be noted that when you look at the taxonomy properties, there&amp;#8217;s actually a breadcrumb presented&amp;#8230;this is important later on.) The Category Link field already being there appealed to me, so I went that route. The catch is, it&amp;#8217;s totally manual, so you have to type your URL carefully and hope you don&amp;#8217;t make a typo.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;All of this got me to thinking. I&amp;#8217;ve got an aliasing system with a nice tree structure. It&amp;#8217;s got a breadcrumb it&amp;#8217;s showing me. Surely there&amp;#8217;s got to be a way to put it all together.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Well there is. And don&amp;#8217;t call me Shirley. So let&amp;#8217;s walk through the steps necessary to set all this up, from soup to nuts.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Step One: Set Up a Site Navigation Taxonomy&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Go into the workarea and to the Content/Taxonomies section and create a new taxonomy. I called mine &amp;#8220;Site Navigation&amp;#8221; - original, I know. Populate this out with whatever nodes you want, but for purposes of quick setup, creating the initial node is all you need to do.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Step Two: Set Up Automatic Aliasing On the Taxonomy&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Now head over to the Settings section and get into the aliasing. Ensure taxonomy-based aliasing is turned on in the alias settings, then head into the aliasing rules to make a new automatic alias. Again, I called it &amp;#8220;Site Navigation&amp;#8221; and you&amp;#8217;ll want to be sure to choose &amp;#8220;Taxonomy&amp;#8221; for the source type. For the alias root, select the &amp;#8220;Site Navigation&amp;#8221; taxonomy node you created, then exclude that from the path in the next dropdown (you don&amp;#8217;t want foo.com/Site-Navigation, I assume!). Leave the alias format as Content Title and set the extension to &amp;#8220;/&amp;#8221; (you did read my &lt;a href=&quot;http://kmac23va.tumblr.com/post/28598731587/ektron-8-6-alias-extension-setting-cheat&quot; target=&quot;_blank&quot;&gt;blog on changing that default extension&lt;/a&gt;, right?). The only other thing you might want to do is adjust the character map, a feature added after 8.5 that lets you change out those special characters for another. I always use the dash (instead of the default underscore) for my default replacement, and the only mapping I changed was to make &amp;#8220;&amp;amp;&amp;#8221; change to &amp;#8220;and&amp;#8221; (IE &amp;#8220;News &amp;amp; Events&amp;#8221; maps to &amp;#8220;News-and-Events&amp;#8221;). Save all that, and you&amp;#8217;re ready to move on.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Before you&amp;#8217;re totally done though, do one last thing. Back on the aliasing rules page, hover over the title to your rule and look at the URL. You&amp;#8217;ll see an &amp;#8220;id&amp;#8221; property at the end of the URL&amp;#8230;note that value somewhere, we&amp;#8217;ll need it a bit later.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Step Two and a Half: Assign Site Navigation Taxonomy To Content&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Well you&amp;#8217;re going to need to test this thing when you&amp;#8217;re done, right? Don&amp;#8217;t worry, I&amp;#8217;ll wait for you to finish&amp;#8230;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step Three: Coding!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We had to get here! So as a note, I&amp;#8217;m going to post the code portions of this on the &lt;a href=&quot;http://developer.ektron.com/Templates/CodeLibraryDetail.aspx?id=1000&amp;amp;blogid=116&quot; target=&quot;_blank&quot;&gt;Ektron Developer&lt;/a&gt; site. I&amp;#8217;m also going to try and remove anything not specific to this project. One thing I want to note is error logging, though. You can either use Ektron&amp;#8217;s logging (which puts errors into the application log in Windows) or use a script called &lt;a href=&quot;http://logging.apache.org/log4net/&quot; target=&quot;_blank&quot;&gt;log4net&lt;/a&gt; that&amp;#8217;s gotten a lot of traction. We&amp;#8217;ve decided to use log4net, and I wrote a logging function around it and set it up based on &lt;a href=&quot;http://www.eyecatch.no/blog/2012/08/logging-with-log4net-in-c-sharp/&quot; target=&quot;_blank&quot;&gt;this article&lt;/a&gt;. Your mileage may vary. But if I forget to take out a logging statement, and you&amp;#8217;re wondering &amp;#8220;what is that?&amp;#8221; - now you know. (And knowing is half the battle.)&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve broken things down into several projects. A Common project that holds common, non-Ektron classes; a Common.EktronCms project that holds common, Ektron-related classes; and a web application project for my custom code (which is merged into CMS400Min via this &lt;a href=&quot;http://martinondotnet.blogspot.com/2010_03_01_archive.html&quot; target=&quot;_blank&quot;&gt;MartinOnDotNet blog&lt;/a&gt;). You&amp;#8217;ll see this in the code samples.&lt;/p&gt;
&lt;p&gt;In the Common project, I put a Conversions class that has a function for reading in the querystring and outputting the values as a dictionary. I did this for a couple of reasons. One, it let me put all of the keys in lower case to ensure matching. Two, it provides a better method via dictionary to check if a value is present than checking the querystring itself.&lt;/p&gt;
&lt;p&gt;Then in the Common.EktronCms project, I first made an EktronValues class with a function for getting the content ID based on the various types of IDs (id for content blocks, pageid for PageBuilder, etc). I check for &amp;#8220;id&amp;#8221; first in case the PageBuilder-template concept is used as specified in the OnTrek site&amp;#8230;in that case, the pageid doesn&amp;#8217;t have the data you want to investigate for the breadcrumb&amp;#8217;s purpose.&lt;/p&gt;
&lt;p&gt;I then added a Taxonomy class and included some code that James Stout wrote, which takes the content ID and returns the assigned taxonomies. We&amp;#8217;ll use this to get the assigned Site Navigation taxonomy.&lt;/p&gt;
&lt;p&gt;Finally, we create the user control in the website. When you look at the code, you&amp;#8217;ll see that it resembles a widget&amp;#8230;that&amp;#8217;s because it can work as either a user control or a widget, thanks to Joe Mayberry&amp;#8217;s blog. You can read a bit more in depth about it in his blog, but I&amp;#8217;ve modified the code a bit to isolate the parts that are common to any function and shouldn&amp;#8217;t need to be modified if you reuse it. If you use it as a user control, set the properties in the control declaration; if you use it as a widget, set the properties in PageBuilder as you do for any widget.&lt;/p&gt;
&lt;p&gt;Some of the property names are taken right from the FolderBreadcrumb control to provide a common reference. The properties are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;TaxonomyAliasId: This is the alias ID I mentioned saving earlier. We use this as a way to pull up the character map in the taxonomy alias for setting up the URLs automatically.&lt;/li&gt;
&lt;li&gt;AddContentTitleToBreadcrumb: Whether to show the content title as part of the breadcrumb.&lt;/li&gt;
&lt;li&gt;Separator: The character to put between each node in the breadcrumb.&lt;/li&gt;
&lt;li&gt;CssClass: The CSS class to wrap around the breadcrumb. The default class will bring up styling from Bootstrap.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Since the content ID is coming from the querystring, it doesn&amp;#8217;t have to be specified as a parameter. Also, the display of the breadcrumb is wrapped in a Panel control to hide the entire thing if there is no breadcrumb result (IE, the homepage).&lt;/p&gt;
&lt;p&gt;The code will loop through to find the taxonomy titled &amp;#8220;Site Navigation&amp;#8221; (so if you use a different name, you&amp;#8217;ll need to change this). The breadcrumb is built backwards, going up the tree by checking the parent ID to ensure it&amp;#8217;s greater than zero. It will convert &amp;#8220;Site Navigation&amp;#8221; to &amp;#8220;Home&amp;#8221; for display purposes. Then, it uses the Path and runs it through a parser to change the slashes and make any other changes based on your alias character map. After it gets through the tree, it&amp;#8217;ll add the title of your current content if you set that property to true.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I hope this code helps you out. It allows you to run your site navigation via taxonomy, and then without extra setup use the taxonomy in a breadcrumb system. I put the code in a user control eventually so that it could be used either as a control (like on a master page) or a widget (for PageBuilder), depending on how you want to use it.&lt;/p&gt;
&lt;p&gt;If there&amp;#8217;s any questions or problems with the code, let me know. I&amp;#8217;ve tested it on my 8.7 project in both user control and widget configurations with no problems.&lt;/p&gt;</id><updated>2013-05-05T03:47:03.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>