<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Henrik Nyström</title><link href="http://world.optimizely.com" /><updated>2018-06-18T23:04:49.0000000Z</updated><id>https://world.optimizely.com/blogs/Henrik-Nystrom/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Geolocation provider changes</title><link href="https://world.optimizely.com/blogs/Henrik-Nystrom/Dates/2018/6/geolocation-provider-changes/" /><id>&lt;p&gt;For quite some time Episerver CMS has come with built-in Geolocation support for MaxMind’s GeoLite database. When creating a site using the Episerver CMS Visual Studio Extension or the EPiServer.CMS NuGet package it would come with a recent version of this database included.&lt;/p&gt;
&lt;p&gt;But as of late, &lt;a href=&quot;https://support.maxmind.com/geolite-legacy-discontinuation-notice/&quot;&gt;MaxMind has announced that they are discontinuing the GeoLite database format&lt;/a&gt; effective January 2, 2019 and that the database will no longer be updated as of April 1, 2018.&lt;/p&gt;
&lt;p&gt;As a replacement, MaxMind is instead offering the free GeoLite2 or the commercial GeoIP2 database which both comes with IPv6 support. These databases do however use a different format than the legacy GeoLite database that’s not compatible with the Geolocation provider included in the current version of Episerver CMS.&lt;/p&gt;
&lt;p&gt;For a while, it has been possible to add support for GeoLite2 databases by replacing the built-in Geolocation provider with an &lt;a href=&quot;/link/227b584b1f5a418295373e5c5a338b47.aspx&quot;&gt;excellent third-party provider&lt;/a&gt; available from the &lt;a href=&quot;https://nuget.episerver.com/package?id=PixieEPiServerExtensionMaxMindGeoIP2&quot;&gt;Episerver NuGet server&lt;/a&gt;, written by Khurram Khan, one of our brilliant MVPs.&lt;/p&gt;
&lt;p&gt;With the GeoLite support officially coming to an end it no longer makes sense to continue providing the same default Geolocation support. We have therefore decided to make the following changes.&lt;/p&gt;
&lt;h2&gt;A new provider for GeoLite2 databases&lt;/h2&gt;
&lt;p&gt;A new separate NuGet package called&amp;nbsp;&lt;a href=&quot;https://nuget.episerver.com/package?id=EPiServer.Personalization.MaxMindGeolocation&quot;&gt;EPiServer.Personalization.MaxMindGeolocation&lt;/a&gt; has been released. This package includes a Geolocation provider with support for MaxMind’s GeoLite2 database and it effectively works as a direct replacement for the provider from the PixieEPiServerExtensionMaxMindGeoIP2 package but with the added support from Episerver. This support is currently limited to usage with MaxMind’s free GeoLite2 City or Country databases, but the commercial GeoIP2 databases should also work although this has not been verified.&lt;/p&gt;
&lt;p&gt;This provider needs to be installed separately as the EPiServer CMS package does &lt;b&gt;not&lt;/b&gt; have a dependency to it. The Geolocation database can be downloaded from &lt;a href=&quot;https://dev.maxmind.com/geoip/geoip2/geolite2/&quot;&gt;MaxMind’s website &lt;/a&gt;directly. To ensure that an updated list of locations is used, the provider also requires the matching CSV file which includes a list of all locations contained in the database. Make sure you specify the path of both the database and the locations file in your configuration such as:&lt;/p&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code&gt;&amp;lt;geolocation defaultProvider=&quot;maxmind2&quot;&amp;gt;
    &amp;lt;providers&amp;gt;
        &amp;lt;add name=&quot;maxmind2&quot; 
             type=&quot;EPiServer.Personalization.MaxMindGeolocationProvider, EPiServer.Personalization.MaxMindGeolocation&quot; 
             databaseFileName=&quot;path\to\GeoLite2-City.mmdb&quot; 
             locationsFileName=&quot;path\to\GeoLite2-City-Locations-en.csv&quot; /&amp;gt;
    &amp;lt;/providers&amp;gt;
&amp;lt;/geolocation&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The paths can be either relative to the website root or absolute.&lt;/p&gt;
&lt;p&gt;You can alternatively configure the provider in the ConfigureContainer method of an initialization module that implements IConfigurableModule.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public void ConfigureContainer(ServiceConfigurationContext context)
{
    context.Services.AddMaxMindGeolocationProvider(&quot;path\to\geolite2-country.mmdb&quot;, &quot;path\to\geolite2-country-locations-en.csv&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the names of some regions have changed compared to the old GeoLite database, so if you are using the Geographic Location Visitor Group Criterion down to this level, you may have to update these with the new names.&lt;/p&gt;
&lt;h2&gt;Use geolocation provided by the CDN&lt;/h2&gt;
&lt;p&gt;We have also added support for retrieving Geolocation from the current request when provided from the CDN in the form of a header with a country code. Due to its nature, it&#39;s limited to Continent and Country location and will only be used for sites that don&#39;t have a Geolocation provider configured. This support will be turned on by default for all DXC customers. See &lt;a href=&quot;/link/d2b05036c97a4128864c8c067559f1ba.aspx&quot;&gt;Content Delivery Network (CDN) Configuration&lt;/a&gt; for additional information on how to enable this option.&lt;/p&gt;
&lt;h2&gt;Phasing out the old GeoLite provider&lt;/h2&gt;
&lt;p&gt;The old Geolocation provider currently included in the EPiServer.ApplicationModules assembly inside the EPiServer.Framework package will be obsoleted immediately and removed in a future major release. The EPiServer.CMS package will still contain the legacy GeoLite database for a while longer as removing it would remove it from existing solutions when updating the NuGet package. Once the provider has been fully deprecated, we will remove the database as well.&lt;/p&gt;
&lt;p&gt;New sites created using the Episerver CMS Visual Studio Extension will be configured without a Geolocation provider going forward.&lt;/p&gt;
&lt;p&gt;If you have any questions in relation to these changes, please comment below or send your question to our support team.&lt;/p&gt;</id><updated>2018-06-18T23:04:49.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Integration testing with Episerver CMS 11</title><link href="http://thisisnothing.nystrom.co.nz/?p=221" /><id>What do you need to do to set up an Episerver CMS environment in a test environment so that you can run integration tests through the whole stack? It’s probably easier than you might believe, especially with some of the enhancements that were released in CMS 11. In this post, I will walk you through [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=221&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2017-12-05T01:46:01.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Integration testing with Episerver CMS 11</title><link href="http://thisisnothing.nystrom.co.nz/?p=221" /><id>What do you need to do to set up an Episerver CMS environment in a test environment so that you can run integration tests through the whole stack? It’s probably easier than you might believe, especially with some of the enhancements that were released in CMS 11. In this post, I will walk you through [&amp;#8230;]</id><updated>2017-12-05T00:46:01.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Improving the Save experience in CMS 10</title><link href="https://world.optimizely.com/blogs/Henrik-Nystrom/Dates/2016/10/improving-the-saving-experience/" /><id>&lt;p&gt;One of the most common task in a CMS is to save, update or publish a content item. And while not exactly complicated, the Content Repository method Save together with the SaveAction enumeration has long been a source of confusion, especially for new developers.&lt;/p&gt;
&lt;p&gt;And perhaps that is no wonder considering that you often end with calls such as:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;// Why do I need to pass Save to a Save method?
contentRepository.Save(content, SaveAction.Save);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has also been plagued with slightly inconsistent behaviour in regards to when new versions are created and how the version status is changed.&lt;/p&gt;
&lt;p&gt;An in addition it has sometimes been hard to know exactly when and which events are raised, often leading to developers attaching the same event handlers to multiple events just to be certain that the handler is executed when a content item is saved.&lt;/p&gt;
&lt;p&gt;In a previous release we made a smaller attempt to consolidate the save behaviour when publishing, but this also let to a regression in the usability when someone wanted to update an existing version as it now required a check of the current status before knowing which SaveAction flag to provide to the Save method.&lt;/p&gt;
&lt;p&gt;For CMS 10 we made a more thorough review of this behaviour and has tweaked things to work in a way that hopefully should make more sense to everyone. Not everything described in this article are behaviour that has changed in CMS 10 regardless, but I have tried to highlight new or changed functionality when not obvious.&lt;/p&gt;
&lt;p&gt;For a full list of breaking changes in CMS 10, please see the &lt;a href=&quot;/link/76974ad8d2a84c1b989ad0ac453ab663.aspx?epsremainingpath=ReleaseNote/&amp;amp;releaseNoteId=CMS-2078&quot;&gt;release notes for this feature published with the CMS 10 release&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Saving Content&lt;/h2&gt;
&lt;p&gt;When you want to save a content item it should in many scenarios be sufficient to only pass the content to the Save method.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;contentRepository.Save(content);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When no explicit SaveAction is provided to the Save method, which is the equivalent to passing in SaveAction.Default, the content version will maintain its current status. This is unless the Save results in a new version, in which case it will get a checked out status. More on new versions below.&lt;/p&gt;
&lt;h3&gt;Changing the version status&lt;/h3&gt;
&lt;p&gt;Whenever you want to publish a version you can simply call the Publish extension method, such as:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;contentRepository.Publish(content);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to transition a version to a specific status when saving you will need to provide the &lt;b&gt;SaveAction&lt;/b&gt; that corresponds to the desired version status. The save actions that control version status are sometimes referred to as the primary save action. Only one primary actions can be provided at once, but they can be combined with one or more option flags.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;CheckOut &lt;/b&gt;- Checks out a version to indicate that it is being worked on. (New in CMS 10)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RequestApproval&lt;/b&gt; – Indicate that the version is ready for an approval review.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reject&lt;/b&gt; - Rejects a version. This is normally done after a review has been done.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CheckIn &lt;/b&gt;- Checks in a version indicating that it is ready to be published&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Publish&lt;/b&gt; - Publishes a version. The currently published version will automatically transition to a previously published state.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Schedule &lt;/b&gt;– Used to schedule a version for automatic publishing at a later date. (New in CMS 10)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The previously available &lt;strong&gt;DelayedPublish&lt;/strong&gt; flag that had to be used in conjunction with CheckIn has now been deprecated in favour of the Schedule action.&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;&lt;strong&gt;Save&lt;/strong&gt; flag is still supported but no longer recommended to use as it has a somewhat irregular behaviour that doesn&#39;t conform to all of the behavior described in this article. It is expected to be deprecated in a future release.&lt;/p&gt;
&lt;h3&gt;Options to control when new versions are created&lt;/h3&gt;
&lt;p&gt;The normal behaviour of the Save method is to always update the current version unless the current status is &lt;b&gt;Published&lt;/b&gt; or &lt;b&gt;PreviouslyPublished&lt;/b&gt;. In these cases, changes are applied to a new version instead.&lt;/p&gt;
&lt;p&gt;If you want to ensure that you don’t overwrite an existing version you can provide the &lt;b&gt;ForceNewVersion&lt;/b&gt; save action flag.&lt;/p&gt;
&lt;p&gt;If you on the other hand want to ensure that no additional version is created you can provide the &lt;b&gt;ForceCurrentVersion&lt;/b&gt; action flag.&lt;/p&gt;
&lt;p&gt;It’s not possible to update the status of a Published or Previously Published version and it is therefore invalid to combine the ForceCurrentVersion flag with a status changing primary action. The Publish action is allowed when updating Published versions, but Save will behave exactly the same without it.&lt;/p&gt;
&lt;p&gt;Using both the ForceCurrentVersion and the ForceNewVersion flag at the same time is not valid and will result in an exception.&lt;/p&gt;
&lt;h3&gt;Other options&lt;/h3&gt;
&lt;p&gt;There are a couple of more options that can be provided to the Save method, neither of which has any effect on status or how new versions are created.&lt;/p&gt;
&lt;p&gt;When a new version is created by the save method it’s normally set as the “common draft”. This is the version that is selected by default when editing the content in the CMS user interface. If the &lt;b&gt;SkipSetCommonDraft&lt;/b&gt; flag is provided, this step will be omitted.&lt;/p&gt;
&lt;p&gt;Normally when you save content a set of validators are executed. To bypass this validation, simply pass in the &lt;b&gt;SkipValidation&lt;/b&gt; flag.&lt;/p&gt;
&lt;p&gt;In case where you want to updated the current version regardless if it&#39;s valid or not there is also a &lt;strong&gt;Patch&lt;/strong&gt; value that combines the ForceCurrentVersion with SkipValidation. This can be handy for when you are updating something in an event handler and want to ensure that you don&#39;t disrupt the users workflow in case there is a validation error.&lt;/p&gt;
&lt;h3&gt;Saving unversioned content&lt;/h3&gt;
&lt;p&gt;Content types that does not implement &lt;b&gt;IVersionable&lt;/b&gt; are considered “unversioned”.&lt;/p&gt;
&lt;p&gt;Saving unversioned types is normally done without providing any save action unless you want to skip validation. If an action is provided, any primary action must be &lt;b&gt;Publish&lt;/b&gt; and options flags cannot include &lt;b&gt;ForceNewVersion&lt;/b&gt;.&lt;/p&gt;
&lt;h2&gt;Events&lt;/h2&gt;
&lt;p&gt;Every time the Save method is called there are a plethora of events raised by the service implementing the &lt;b&gt;IContentEvents&lt;/b&gt; interface. The exact events raised depends on the current state of the content version and what status it will get after the save is completed.&lt;/p&gt;
&lt;p&gt;The &lt;b&gt;SavingContent&lt;/b&gt; and &lt;b&gt;SavedContent&lt;/b&gt; will always be raised whenever Save is called as long as no event handler cancels the action beforehand. This is a slight change to before CMS 10 when the save events wasn’t raised for new content or when publishing content without any modifications.&lt;/p&gt;
&lt;p&gt;The &lt;b&gt;CreatingContent&lt;/b&gt; and &lt;b&gt;CreatedContent&lt;/b&gt; will be raised before the save events if the content is new.&lt;/p&gt;
&lt;p&gt;If the saved content is a new language branch of an already existing content, it will result in the &lt;b&gt;CreatingLanguageBranch&lt;/b&gt; and &lt;b&gt;CreatedLanguageBranch&lt;/b&gt; events being raised. This event is new in CMS 10.&lt;/p&gt;
&lt;p&gt;Finally, addition status specific event are raised depending on the resulting status of the save. These can be handy if you only want to react to a specific transition such as when content is published, but if you want to respond to multiple status changes you can just listening to the save event and get additional information about any status transition from the &lt;b&gt;Transition&lt;/b&gt; property now included on the save event argument class.&lt;/p&gt;
&lt;p&gt;The status specific event are raised regardless if the status is changed or not. Saving a published version with &lt;b&gt;ForceCurrentVersion&lt;/b&gt; will thus raise the publish events again.&lt;/p&gt;
&lt;p&gt;The full list of status save events are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PublishingContent/PublishedContent&lt;/li&gt;
&lt;li&gt;CheckingOutContent/CheckedOutContent (new in CMS 10)&lt;/li&gt;
&lt;li&gt;SchedulingContent/ScheduledContent (new in CMS 10)&lt;/li&gt;
&lt;li&gt;RequestingApproval/RequestedApproval&lt;/li&gt;
&lt;li&gt;RejectingContent/RejectedContent&lt;/li&gt;
&lt;li&gt;CheckingInContent/CheckedInContent&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Access rights&lt;/h2&gt;
&lt;p&gt;The exact access rights required to perform the Save will depend on the current state of the content and what status it will get after the save is completed.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Create&lt;/b&gt; access is required if no previous version exists or if saving a new language branch.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Edit&lt;/b&gt; access is required to update properties of an existing content item. Edit access is also required to check-out, check-in, request approval or reject a version.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Publish&lt;/b&gt; access is required to publish a version or to schedule a version for publishing at a later date. Publish access is also require if you want to update a Published or Scheduled version without creating a new version.&lt;/p&gt;
&lt;p&gt;If a different access right is required it can be provided to the Save method via the AccessRights parameter. If no authentication should be performed, just pass in the &lt;strong&gt;NoAccess&lt;/strong&gt; value.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;With the changes made to status transitions and events in CMS 10 it should now be even easier to use Save than before and much more predictable.&lt;/p&gt;
&lt;p&gt;In most cases it should even be sufficient to call Save(content) or Publish(content) if you want to publish it. Or just call Save(content, SaveAction.ForceCurrentVersion) if you want to update the current version regardless of what the current status is.&lt;/p&gt;
&lt;h2&gt;Related topics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/link/5a73ec431f24465a9fe25b4560cdf272.aspx&quot;&gt;Breaking changes in CMS 10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/link/76974ad8d2a84c1b989ad0ac453ab663.aspx?epsremainingpath=ReleaseNote/&amp;amp;releaseNoteId=CMS-2078&quot;&gt;Release notes on this topic, including breaking changes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</id><updated>2016-10-30T23:30:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Introducing changes to reduce our Public API</title><link href="https://world.optimizely.com/blogs/Henrik-Nystrom/Dates/2016/10/introducing-changes-to-reduce-our-public-api/" /><id>&lt;p&gt;One of the primary considerations when building a software platform that other developers based their work on is to maintain backwards compatibility. As the platform grows larger and more complex this can become the major restraining factor when trying to sustain a high development pace.&lt;/p&gt;
&lt;p&gt;Once you start to use strict semantic versioning it becomes glaringly obvious that no API changes can be done no matter how small the change or how obscure the class is, unless releasing a new major version. And while releasing a new major version might not be as big a deal as it used to be, it does add additional work, not just internally, but also for any maintainers of third party modules trying to keep their modules up to date.&lt;/p&gt;
&lt;h2&gt;internal, &amp;lt;internal /&amp;gt; or .Internal?&lt;/h2&gt;
&lt;p&gt;The typical approach to this problem is to keep your public classes to a minimum and only expose classes that are actually useful to interact with for external developers. Limiting the API is currently done primarily by keeping classes or methods internal. And while we might be high-fiving each other at the office every time we can add the internal keyword to a class, it seems like it is making some of you platform users less happy, some more than others.&lt;/p&gt;
&lt;p&gt;Another option is to use the API documenation and explicitly call out the classes and methods that are considered internal. And while this method has been used with some success in the past, such in the case of the EPiServer.DataAccess namespace, it can sometimes be hard to keep track of which APIs are public or not if they are spread out.&lt;/p&gt;
&lt;p&gt;For quite some time now we have been discussing better ways to manage these API restrictions. But as always, while you discuss, other people do, and this is exactly what Microsoft has done. In their latest .NET Core platform they have introduced the notion of “Internal namespaces”, which is a specific namespace pattern that indicates that you are now dealing with classes that are not a part of the public API. As this was very closely aligned with our own thoughts we have decided to follow suit and use the same approach.&lt;/p&gt;
&lt;p&gt;This means that going forward any class located in a namespace named &#39;Internal&#39; will not be considered a part of our supported public API. These classes can still be used, they are just not covered by the semantic versioning promise and can therefore change between minor releases without prior warning. Any problem that arise from using it will also not be covered by our usual support.&lt;/p&gt;
&lt;p&gt;It should however mean that we can expose more classes as public in our assemblies so that they are easier to use if you really, really need to or for any non-production scenarios such as for unit testing.&lt;/p&gt;
&lt;p&gt;This does not imply that everything outside these namespaces will be a part of the public API as there will still be classes and methods that are explicitly documented as being for “internal use” but we will try to keep these to a minimal whenever possible.&lt;/p&gt;
&lt;h2&gt;When should I start to notice these changes?&lt;/h2&gt;
&lt;p&gt;There are some areas in CMS and other products where you can already find Internal namespaces, but so far the use has been relatively limited.&lt;/p&gt;
&lt;p&gt;In our next major release, Episerver CMS 10, which is just around the corner, you will notice that we have moved a lot of the classes from their current location to these Internal namespaces in an attempt to minimize the weight of our legacy backpack. This will include any classes that we do not consider important for typical use cases or implementations of public abstractions.&lt;/p&gt;
&lt;p&gt;So when you upgrade a solution, please be careful and make sure that you don’t accidentaly add any Internal namespaces to your using statements as this may cause you some problems in the future.&lt;/p&gt;
&lt;h2&gt;That should be public!&lt;/h2&gt;
&lt;p&gt;Should you find a class or interface that you believe should have remained in the public API, please contact us and tell us why you think this should be the case.&lt;/p&gt;</id><updated>2016-10-21T03:37:23.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>How to compare ContentReference instances</title><link href="http://thisisnothing.nystrom.co.nz/?p=216" /><id>I thought that I would mention a small improvement that was released with CMS 8 the other day. It’s a minor change in regards to comparisons of ContentReference instances, but as this is an area that is used a lot I thought that it would be worth mentioning. First of all we tried to make [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=216&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2015-02-25T11:07:20.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>How to compare ContentReference instances</title><link href="http://thisisnothing.nystrom.co.nz/?p=216" /><id>I thought that I would mention a small improvement that was released with CMS 8 the other day. It’s a minor change in regards to comparisons of ContentReference instances, but as this is an area that is used a lot I thought that it would be worth mentioning. First of all we tried to make [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=216&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2015-02-25T11:07:20.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Improved support for canonical URLs</title><link href="http://thisisnothing.nystrom.co.nz/?p=211" /><id>Search engines often highlights the importance of using canonical URLs to signify the preferred URL that should be used when the same content can be reached using multiple URLs. And while EPiServer has always supported the use of canonical URLs it is now easier than ever to setup multiple domains and ensure that there is [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=211&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2015-02-11T23:49:47.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Performance improvements in the PropertyDataCollection</title><link href="http://thisisnothing.nystrom.co.nz/?p=206" /><id>When we took a look at what performance improvements that we could make to the EPiServer CMS platform there was one thing that stood out like a sore thumb, namely the PropertyDataCollection. The main problem was how it&amp;#8217;s base class, NameObjectCollectionBase, was handling retrieval of items in the collection in a multi-threaded scenario. As it [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=206&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2015-02-11T23:24:03.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Performance improvements in the PropertyDataCollection</title><link href="http://thisisnothing.nystrom.co.nz/?p=206" /><id>When we took a look at what performance improvements that we could make to the EPiServer CMS platform there was one thing that stood out like a sore thumb, namely the PropertyDataCollection. The main problem was how it&amp;#8217;s base class, NameObjectCollectionBase, was handling retrieval of items in the collection in a multi-threaded scenario. As it [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=206&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2015-02-11T23:24:03.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>A new logging API in EPiServer Framework</title><link href="http://thisisnothing.nystrom.co.nz/?p=199" /><id>For as long as I can remember, the logging framework of choice for EPiServer has been log4net, but this is about to change now! Well, I say that, in reality we are only changing the way we are using the logging framework so that it is possible to change framework going forward. The main reason [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=199&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2014-11-23T23:59:42.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Deployment of EPiServer add-on modules as ZIP packages</title><link href="http://thisisnothing.nystrom.co.nz/?p=191" /><id>...we have added a virtual path provider with support for ZIP files to the EPiServer.Framework package called ZipArchiveVirtualPathProvider.&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=191&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2014-11-23T23:26:24.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Using custom forms in an EPiServer MVC block template</title><link href="http://thisisnothing.nystrom.co.nz/?p=173" /><id>With EPiServer 7 came the introduction of two new features; the ability to divide a page into blocks or smaller reusable components and support for the ASP.NET MVC framework in templates. If we want to combine these two features together and create a custom form placed in an MVC block template, there are a few [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=173&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2013-11-19T07:57:49.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Embedding EPiServer language files</title><link href="http://thisisnothing.wordpress.com/?p=144" /><id>One of the things that I&amp;#8217;m always aiming for when creating a module for EPiServer is that you should be able to install it simply by dropping a single assembly to the bin folder. There should be no or very little configuration needed (Convention over Configuration!)&#160; and you shouldn&amp;#8217;t have to place files in folders [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=144&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2010-05-18T10:30:39.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Scheduled jobs in EPiServer CMS 6</title><link href="http://thisisnothing.wordpress.com/?p=130" /><id>There are a few hidden bits in EPiServer CMS 6 that hasn&amp;#8217;t been talked much about, one of them being the enhancements to the scheduled jobs. These new features include the ability to interrupt the execution of a long running job and for these jobs to send status updates to the UI. To take advantage [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=130&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2010-05-13T10:04:03.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Modify the built-in EPiServer properties</title><link href="http://thisisnothing.wordpress.com/?p=118" /><id>When you are creating a page type in EPiServer you have a lot of configuration settings you can do. You can set the default value, hide it from the Edit interface, make it mandatory and so on. For the built in properties it&amp;#8217;s another story, you can set the default values for some of them, [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=118&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2010-04-09T03:39:46.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>EPiServer Extension methods, part 1 of many</title><link href="http://thisisnothing.wordpress.com/?p=82" /><id>So Frederik Vig started a community project around EPiServer Extensions which I believe is a great initiative. Already having a great number of extension methods that we are currently using. Rather than just dump them in the source code repository I thought I would try to get my blogging going again by posting each method [&amp;#8230;]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://pixel.wp.com/b.gif?host=thisisnothing.nystrom.co.nz&amp;#038;blog=1839794&amp;#038;post=82&amp;#038;subd=thisisnothing&amp;#038;ref=&amp;#038;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</id><updated>2009-11-07T01:10:15.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Presenting PageTreeIcons</title><link href="http://thisisnothing.wordpress.com/?p=11" /><id>Developing for EPiServer CMS 5? Ever wanted to be able to easily show all editors that a page is just a container, that the page really is a redirect to another or that a certain property is missing on a page? Or do you just want to make that page tree a little more intuative? [...]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=thisisnothing.wordpress.com&amp;amp;blog=1839794&amp;amp;post=11&amp;amp;subd=thisisnothing&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;</id><updated>2008-04-20T11:05:29.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Changing the icons in the EPiServer page tree</title><link href="http://thisisnothing.wordpress.com/2007/12/15/changing-the-icons-in-the-episerver-page-tree/" /><id>So&amp;#8230; I poked around some more in the EPiServer interface. Theming just didn&amp;#8217;t cut it. So I wrote an adapter that supports adding icons and ability to do changes to the page tree. Right now it has a cool setup where you can specify a ITreeIconHandler in the web.config and it lets you add whatever [...]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=thisisnothing.wordpress.com&amp;amp;blog=1839794&amp;amp;post=9&amp;amp;subd=thisisnothing&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;</id><updated>2007-12-14T16:28:07.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>EPiServer CMS - Intergen Style</title><link href="http://thisisnothing.wordpress.com/2007/12/14/episerver-cms-intergen-style/" /><id>Played around some with a theme for the EPiServer Edit UI. Unfortunately it’s not really as themable as you would like it to be. A lot of stuff would have to be done differently in the UI to enable easy theming. More skinned controls, no inline styles to start with. A good approach when trying [...]&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=thisisnothing.wordpress.com&amp;amp;blog=1839794&amp;amp;post=7&amp;amp;subd=thisisnothing&amp;amp;ref=&amp;amp;feed=1&quot; /&gt;</id><updated>2007-12-14T00:19:58.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>