<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Nicklas Israelsson</title><link href="http://world.optimizely.com" /><updated>2018-12-04T11:47:21.0000000Z</updated><id>https://world.optimizely.com/blogs/Nicklas-Israelsson/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Using Vuex in the MusicFestival template site</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2018/12/using-vuex-in-the-musicfestival-template-site/" /><id>&lt;p&gt;We&amp;rsquo;re rewriting &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template&quot;&gt;the music festival template site&lt;/a&gt; to use &lt;a href=&quot;https://vuex.vuejs.org/&quot;&gt;vuex&lt;/a&gt; to handle the state of the app. Previously, we&amp;rsquo;ve been using instance specific properties and mixins to handle and share state in different ways. In my opinion, moving all state handling into a centralized store is a good idea regardless of framework. It makes the code easier to understand and reason about. It&amp;rsquo;s also worth noting that the available libraries for the different frameworks using flux-like stores are similar enough to make it easy to transition between frameworks.&lt;/p&gt;
&lt;p&gt;Another positive aspect is that &lt;a href=&quot;https://github.com/vuejs/vue-devtools&quot;&gt;the available tools&lt;/a&gt; for using a state management system make debugging very convenient.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/d17f77378c974d1d8e0a076132bd96ae.aspx&quot; alt=&quot;Vuex debugging&quot; width=&quot;994&quot; height=&quot;580&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;What are the differences?&lt;/h2&gt;
&lt;p&gt;On the surface, the site should function exactly the same, so the difference only lies in the architecture of the site. We&amp;rsquo;ve moved the different states we previously had into separate &lt;a href=&quot;https://vuex.vuejs.org/guide/modules.html&quot;&gt;vuex modules&lt;/a&gt;. Modules makes it easier to separate the concerns of the different states but still use a centralized store to get the data that is needed.&lt;/p&gt;
&lt;h3&gt;Updating the model&lt;/h3&gt;
&lt;p&gt;In &lt;a href=&quot;/link/4a91824ea19e4f3a8fbfb7a953115f1e.aspx&quot;&gt;my previous blog&lt;/a&gt;, I mentioned a lot about who should own the model. This approach does not fundamentally change that concept since we will still pass the model from a parent component to child components. The difference will be that instead of using the &lt;code&gt;EpiDataModelMixin&lt;/code&gt;, the loading and updating of the model will be done in the &lt;code&gt;epiDataModel&lt;/code&gt; vuex store module. The parent components will read the model from the store and pass it to child components. Updating the model is initiated from the router. When a route has changed, the router will dispatch an action in the store telling it to update the model.&lt;/p&gt;
&lt;h3&gt;Keeping track of editing context&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;$epi&lt;/code&gt; property was used to hide and show the editing overlay in edit mode. The same functionality is now stored in the &lt;code&gt;epiContext&lt;/code&gt; module. We&amp;rsquo;ve changed the old file that defined the &lt;code&gt;$epi&lt;/code&gt; instance to something we call &lt;code&gt;epiMessages&lt;/code&gt;. The sole responsibility of &lt;code&gt;epiMessages&lt;/code&gt; is to register the event handlers for &lt;code&gt;beta/contentSaved&lt;/code&gt; and &lt;code&gt;beta/epiStart&lt;/code&gt; that will update the new &lt;code&gt;epiContext&lt;/code&gt; store module.&lt;/p&gt;
&lt;h3&gt;Keeping track of application context&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;$app&lt;/code&gt; property was mainly used on the start page to show/hide a modal window and demonstrate how turning editing on and off in on page edit could be handled in that scenario. This has also been moved into its own vuex module called &lt;code&gt;appContext&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Github repo&lt;/h2&gt;
&lt;p&gt;This rewrite was merged through a PR on github recently, so if you&amp;rsquo;re interested in looking into how a transition to using a state management system could look like you can view all commits in the PR here: &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/pull/4&quot;&gt;Use vuex&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Related links&lt;/h2&gt;
&lt;p&gt;Blog series about the template site and SPA sites in OPE: &lt;a href=&quot;/link/5ccbe4dbd38c4d76a6dc81e838c70f9d.aspx&quot;&gt;https://world.episerver.com/blogs/john-philip-johansson/dates/2018/10/introducing-a-new-template-site-for-spas-musicfestival/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Documentation on client side rendering in Episerver: &lt;a href=&quot;/link/f80257067ca542288c0b74d4db6ae0c5.aspx&quot;&gt;https://world.episerver.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering/&lt;/a&gt;&lt;/p&gt;</id><updated>2018-12-04T11:47:21.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Represent the concept of &quot;pages&quot; and &quot;blocks&quot; with matching client side components in a SPA</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2018/10/represent-the-concept-of-pages-and-blocks-with-matching-client-side-components-in-a-spa/" /><id>&lt;blockquote&gt;
&lt;p&gt;To demonstrate some concepts that are useful when creating a SPA with working OPE, we are releasing a new SPA template site on Github, called MusicFestival, together with a series of blog posts. Don&amp;rsquo;t be discouraged that the SPA is written in &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; if you&amp;rsquo;re using React, Angular, or something else, as these concepts will work in any client side framework.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/5ccbe4dbd38c4d76a6dc81e838c70f9d.aspx&quot;&gt;https://world.episerver.com/blogs/john-philip-johansson/dates/2018/10/introducing-a-new-template-site-for-spas-musicfestival/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Episerver CMS uses the concepts of pages and blocks, and this is how editors are trained and used to editing a site in the CMS UI. SPAs &lt;em&gt;could&lt;/em&gt; make up one view from multiple page models, but how should an editor know where to edit it? Pages and blocks match their thinking, and are represented in the UI, so create components that match that.&lt;/p&gt;
&lt;p&gt;An example would be that an editor of the MusicFestival site needs to update the dates for an artist&amp;rsquo;s performance. The natural way to do that would be to use the page tree to navigate to the artists page and edit it using On Page Edit (OPE).&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;edit-artist.gif&quot; src=&quot;/link/4fb65998baf542648590743d0fdec78a.aspx&quot; width=&quot;1110&quot; height=&quot;771&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As the page data is represented as one model on the server, it makes sense that it is still one model on the client. Otherwise, you might need multiple places to fetch data and patch it together to represent the view that is rendered to visitors of the site. So by having one model on the client, it can trickle down property data, allowing each child component to be developed independently of each other (i.e. &lt;a href=&quot;https://storybook.js.org/&quot;&gt;story book in React&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;Who should own the model on the client?&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;beta/contentSaved&lt;/code&gt; message tells you when the editor has edited a property in OPE, and that&amp;rsquo;s the time to re-render the view. The MusicFestival does this in only one place, and gets the full page JSON that in turn updates a model property that each page and block component takes as a &lt;code&gt;param&lt;/code&gt;. The alternative is to have components own their own data updating, which will require more work per component. Having the data update in one place while editing, just as it would update while loading data in view mode, can make your API simpler.&lt;/p&gt;
&lt;p&gt;The way pages and blocks are shown in OPE is slightly different.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;page&lt;/strong&gt; will have a &lt;em&gt;friendly URL&lt;/em&gt; in view mode; otherwise, it will have an Episerver URL that includes the content link.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;block&lt;/strong&gt; does not have any friendly URLs, but can be previewed in OPE if you implement an &lt;a href=&quot;http://ASP.NET&quot;&gt;ASP.NET&lt;/a&gt; MVC controller. They will always rely on &lt;em&gt;content links&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;beta/contentSaved&lt;/code&gt; message includes the &lt;em&gt;content link&lt;/em&gt; to the model version that is being edited, but no URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The friendly URL always gets the published model, while the content link can get any version of the model.&lt;/p&gt;
&lt;p&gt;This means that pages will initially get their data with a friendly URL, while blocks get it with a content link. Both will update in OPE using content links. So your API needs to support both cases, and it&amp;rsquo;s helpful for the client side to expose both.&lt;/p&gt;
&lt;p&gt;In MusicFestival we use a &lt;a href=&quot;https://vuejs.org/v2/guide/mixins.html&quot;&gt;Vue.js mixin&lt;/a&gt; to set up a &lt;code&gt;model&lt;/code&gt; property that represents the serialized page or block model, and automatically registers for the &lt;code&gt;beta/contentSaved&lt;/code&gt; message that in turn updates the model with &lt;code&gt;updateModelByContentLink&lt;/code&gt;. Block components initiate themselves with the same method, while page components use &lt;code&gt;updateModelByFriendlyUrl&lt;/code&gt; instead. The key point is that there is only one instance of the page or block model on the client side, and it&amp;rsquo;s updated in one place. &lt;strong&gt;This allows the client side components to be written as if they weren&amp;rsquo;t in a CMS.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An excerpt from the &lt;code&gt;EpiDataModelMixin&lt;/code&gt; shows how it registers for the &lt;code&gt;beta/contentSaved&lt;/code&gt; message, how it owns the model as data it makes available to pages and blocks, and which methods it exposes:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;export default {
    // registers for the `beta/contentSaved` message
    watch: {
        &#39;$epi.isEditable&#39;: &#39;_registerContentSavedEvent&#39;
    },

    // it owns the model as data it makes available to pages and blocks
    data: function () {
        return {
            modelLoaded: false,
            model: {}
        };
    },

    // which methods it exposes
    methods: {
        updateModelByFriendlyUrl: function (friendlyUrl) {
            /* Updating a model by friendly URL is done when routing in the SPA. */
        },

        updateModelByContentLink: function (contentLink) {
            /* Updating a model by content link is done when something is being edited (&#39;beta/contentSaved&#39;) and when previewing a block. */
        },

        _registerContentSavedEvent(isEditable) {
            if (isEditable) {
                window.epi.subscribe(&#39;beta/contentSaved&#39;, message =&amp;gt; {
                    this.updateModelByContentLink(message.contentLink);
                });
            }
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;See the full source for the &lt;code&gt;epiDataModelMixin.js&lt;/code&gt; mixin &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/Mixins/epiDataModelMixin.js&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The pages rely on friendly URLs, and are loaded by the &lt;code&gt;PageComponentSelector&lt;/code&gt;, so it owns the model through the &lt;code&gt;EpiDataModelMixin&lt;/code&gt; while getting the page URL from the router as a prop:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
export default {
    mixins: [EpiDataModelMixin],
    created() {
        this.updateModelByFriendlyUrl(this.$props.url);
    }
};
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;See the full source for the &lt;code&gt;PageComponentSelector.vue&lt;/code&gt; component &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/PageComponentSelector.vue&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The blocks rely on content links, and need a view to decide how to preview blocks. In MusicFestival, we have a &lt;code&gt;Preview&lt;/code&gt; component that loads multiple instances of &lt;code&gt;BlockComponentSelector&lt;/code&gt; in different sizes, so &lt;code&gt;Preview&lt;/code&gt; is the component owning the model through the &lt;code&gt;EpiDataModelMixin&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;&amp;lt;script&amp;gt;
export default {
    mixins: [EpiDataModelMixin],
    created() {
        this.updateModelByContentLink(this.contentLink);
    }
};
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;See the full source for the &lt;code&gt;Preview.vue&lt;/code&gt; component &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/Preview.vue&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Avoiding unnecessary Razor files&lt;/h2&gt;
&lt;p&gt;As you might have seen in our &lt;a href=&quot;https://github.com/episerver/AlloyReact/blob/master/AlloyReact/Helpers/HtmlHelpers.cs#L43-L63&quot;&gt;AlloyReact template site&lt;/a&gt;, or as we&amp;rsquo;ve seen in partner solutions, it&amp;rsquo;s common to have a client side component render helper on the server side. They make it easier to get a React, or other, component where one would usually have written HTML in the various */Index.cshtml files. This is sometimes partly because of SEO, but that requires that the client side code is rendered on the server. So usually it&amp;rsquo;s done because the frontend developer prefers to write all of the visual components separate from the CMS, and then just deliver the page as set of client side resource files. This leads to creating mostly empty &lt;a href=&quot;http://ASP.NET&quot;&gt;ASP.NET&lt;/a&gt; MVC controllers and Razor views that just include one element that is then bootstrapped by the client side:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;// There&#39;s a better way to handle this.
@using AlloyTemplates.Models.Blocks
@model ThreeKeyFactsBlock


@Html.ReactComponent(&quot;ThreeKeyFacts&quot;, Model)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;rsquo;ve seen examples where developers have pasted their entire client side code into razor views because they believe that is required to get OPE working, but that is not the case. Read more about it &lt;a href=&quot;/link/f80257067ca542288c0b74d4db6ae0c5.aspx&quot;&gt;in our developer guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you use the concepts we introduced in the previous section, such as an Episerver page having a corresponding client side component, then it&amp;rsquo;s enough to have one &lt;a href=&quot;http://ASP.NET&quot;&gt;ASP.NET&lt;/a&gt; MVC controller for all pages that will delegate the responsibility of choosing the right page or block view to the client side. The architectural overview described below will show the differences &lt;em&gt;and&lt;/em&gt; similarities between rendering blocks and pages. Note that blocks will never be rendered by themselves outside of edit mode.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;// Handling pages
DefaultPageController.cs
    DefaultPage/Index.cshtml
        DefaultPage.vue
            router-view (Vue.js)
                router.js
                    PageComponentSelector.vue (owns the model)
                        ArtistContainerPage/ArtistDetailsPage/LandingPage.vue

// Handling blocks
PreviewController.cs
    Preview/Index.cshtml
        Preview.vue (owns the model)
            BlockComponentSelector.vue
                BuyTicketBlock/ContentBlock/GenericBlock.vue
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Handling pages&lt;/h3&gt;
&lt;p&gt;If all the pages are to be rendered on the client, you can avoid having boilerplate Razor files for each page by having a default page controller that will always load the same Razor view. That view will simply bootstrap the router view used by your client side framework.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DefaultPageController.cs&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Controllers/DefaultPageController.cs&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;public class DefaultPageController : PageController&amp;lt;BasePage&amp;gt;
{
    public ViewResult Index(BasePage currentPage)
    {
        return View(&quot;~/Views/DefaultPage/Index.cshtml&quot;, currentPage);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DefaultPage/Index.cshtml&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Views/DefaultPage/Index.cshtml&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;@model MusicFestival.Template.Models.Pages.BasePage
@{ Layout = &quot;~/Views/Shared/_BaseLayout.cshtml&quot;; }

&amp;lt;default-page&amp;gt;&amp;lt;/default-page&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;BasePage&lt;/code&gt; is just an empty abstract class inheriting from &lt;code&gt;EPiServer.Core.PageData&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DefaultPage.vue&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/DefaultPage.vue&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;// example in Vue.js
&amp;lt;template&amp;gt;
    &amp;lt;router-view&amp;gt;&amp;lt;/router-view&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;router-view&lt;/code&gt; component is a part of the &lt;a href=&quot;https://router.vuejs.org/&quot;&gt;Vue.js router&lt;/a&gt; framework and will load the component that matches a route inside of it. Since the &lt;code&gt;PageComponentSelector&lt;/code&gt; can render every page component we only need to register this one simple route on the client:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;router.js&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/router.js&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;routes: [
    {
        path: &#39;*&#39;,
        component: PageComponentSelector
    }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PageComponentSelector&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/PageComponentSelector.vue&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;model&lt;/code&gt; holds a serialized version of the page data. The helper method &lt;code&gt;getComponentTypeForPage&lt;/code&gt; iterates through all globally registered Vue.js components and returns the one with the same name as the &lt;code&gt;contentType&lt;/code&gt; of the model. The &lt;code&gt;&amp;lt;component&amp;gt;&lt;/code&gt; element is &lt;a href=&quot;https://vuejs.org/v2/guide/components.html#Dynamic-Components&quot;&gt;how Vue.js handles dynamic components&lt;/a&gt; (basically just a placeholder to load a real component).&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;component :is=&quot;getComponentTypeForPage(model)&quot; :url=&quot;url&quot; :model=&quot;model&quot;&amp;gt;&amp;lt;/component&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    methods: {
        getComponentTypeForPage(model) {
            // this.$options.components will contain all globally registered components from main.js
            return getComponentTypeForContent(model, this.$options.components);
        }
    }
};
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;See the full source for the &lt;code&gt;getComponentTypeForContent.js&lt;/code&gt; &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/api/getComponentTypeForContent.js&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Handling blocks&lt;/h3&gt;
&lt;p&gt;As with pages, the CMS UI is built with the concept of blocks and it&amp;rsquo;s easier to make a coherent editing experience for your users if your client side components have an equivalent concept. It&amp;rsquo;s also recommended to have a preview for blocks so your users can still enjoy OPE.&lt;/p&gt;
&lt;p&gt;The preview page can be done similarly to the default page, and even when it&amp;rsquo;s a regular &lt;a href=&quot;http://ASP.NET&quot;&gt;ASP.NET&lt;/a&gt; MVC application, it&amp;rsquo;s only one Razor view for the block preview.&lt;/p&gt;
&lt;p&gt;To get it to work with blocks, we need a similar concept to select the block component in the SPA as we did for pages, but with some differences. First, you&amp;rsquo;ll need to figure out the content-link, as blocks don&amp;rsquo;t have a public URL, and your API will need to return the block type name. The Razor view for the Preview controller will set the content-link. The MusicFestival site uses the ContentDeliveryAPI that will include the block type name in the &lt;code&gt;JSON&lt;/code&gt; response so we can use a very similar approach as the &lt;code&gt;PageComponentSelector&lt;/code&gt; in our &lt;code&gt;BlockComponentSelector&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PreviewController.cs&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Controllers/PreviewController.cs&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Remember to use the RequireClientResourcesAttribute as described in &lt;a href=&quot;/link/4552b6ecd7504771b9f3aae5832cb3a6.aspx&quot;&gt;this blog post&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;[RequireClientResources]
public class PreviewController : ActionControllerBase, IRenderTemplate&amp;lt;BlockData&amp;gt;
{
    public ActionResult Index(IContent currentContent)
    {
        var startPage = _contentRepository.Get&amp;lt;PageData&amp;gt;(ContentReference.StartPage);
        var model = new BlockEditPageViewModel(startPage, currentContent);

        return View(model);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;PreviewBlock.cs&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Models/Preview/PreviewBlock.cs&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;public class PreviewBlock : PageData
{
    public IContent PreviewContent { get; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Preview/Index.cshtml&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Views/Preview/Index.cshtml&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For the razor view for the block preview, we need to pass the content link because the client side cannot just look at the URL to load the correct content (as the page can).&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;@model MusicFestival.Template.Models.Preview.BlockEditPageViewModel
@{ Layout = &quot;~/Views/Shared/_BaseLayout.cshtml&quot;; }

&amp;lt;Preview content-link=&quot;@Model.PreviewBlock.PreviewContent.ContentLink&quot;&amp;gt;&amp;lt;/Preview&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Preview.vue&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/Preview.vue&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;BlockComponentSelector :model=&quot;model&quot;&amp;gt;&amp;lt;/BlockComponentSelector&amp;gt;
&amp;lt;/template&amp;gt;
&amp;lt;script&amp;gt;
export default {
    props: [&#39;contentLink&#39;],
    mixins: [EpiDataModelMixin],
    components: {
        BlockComponentSelector
    }
};
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;BlockComponentSelector.vue&lt;/strong&gt; See the &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/components/BlockComponentSelector.vue&quot;&gt;whole source on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, we come to the &lt;code&gt;BlockComponentSelector&lt;/code&gt; that, as you can see, is very similar to the &lt;code&gt;PageComponentSelector&lt;/code&gt; that we have shown before. A notable difference is that the &lt;code&gt;BlockComponentSelector&lt;/code&gt; does not &amp;ldquo;own&amp;rdquo; the model. The reason for that is that the &lt;code&gt;Preview&lt;/code&gt; component will render multiple &lt;code&gt;BlockComponentSelector&lt;/code&gt; for the same model.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;component :is=&quot;getComponentTypeForBlock(model)&quot; :model=&quot;model&quot;&amp;gt;&amp;lt;/component&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    props: [&#39;model&#39;],
    methods: {
        getComponentTypeForBlock: function (block) {
            // this.$options.components will contain all globally registered components from main.js
            // Load the &quot;GenericBlock&quot; in the case that no block is found.
            return getComponentTypeForContent(block, this.$options.components) || &#39;GenericBlock&#39;;
        }
    }
};
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;See the full source for the &lt;code&gt;getComponentTypeForContent.js&lt;/code&gt; &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/api/getComponentTypeForContent.js&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I hope you can see that there are a lot of advantages to keeping to the concept of one content (page, block, or even media) representing one component on the client side in Episerver.&lt;/p&gt;
&lt;h2&gt;Related links&lt;/h2&gt;
&lt;p&gt;Blog series about the template site and SPA sites in OPE &lt;a href=&quot;/link/5ccbe4dbd38c4d76a6dc81e838c70f9d.aspx&quot;&gt;https://world.episerver.com/blogs/john-philip-johansson/dates/2018/10/introducing-a-new-template-site-for-spas-musicfestival/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Template site using the techniques discussed in this blog: &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/&quot;&gt;https://github.com/episerver/musicfestival-vue-template/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Documentation on client side rendering in Episerver: &lt;a href=&quot;/link/f80257067ca542288c0b74d4db6ae0c5.aspx&quot;&gt;https://world.episerver.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering/&lt;/a&gt;&lt;/p&gt;</id><updated>2018-11-05T07:37:07.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Routing in a SPA with a working On-Page Editing experience</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2018/10/routing-in-a-spa-with-a-working-on-page-editing-experience-cms-ui-11-11-0/" /><id>&lt;p class=&quot;informationBox&quot;&gt;Since 11.24.0 the features described in this blog post are no longer considered beta features and are available to every user. The code examples have been updated to reflect that.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To demonstrate some concepts useful when creating a SPA with working OPE we are releasing a new SPA template site on Github, called MusicFestival, together with a series of blog posts. Don&amp;rsquo;t be discouraged that the SPA is written in &lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; if you&amp;rsquo;re using React, Angular or something else, as these concepts will work in any client side framework.&lt;/p&gt;
&lt;p&gt;&lt;a title=&quot;Introducing a new SPA template site: MusicFestival&quot; href=&quot;/link/5ccbe4dbd38c4d76a6dc81e838c70f9d.aspx&quot;&gt;Introducing a new SPA template site: MusicFestival&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When creating a SPA and navigating inside the CMS UI, you might notice that the context isn&amp;rsquo;t what you expect, or that the page navigation tree isn&amp;rsquo;t updated.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Example of failing context switching&quot; src=&quot;/link/c21c5245ef4748cda3e7b5fcb00d1c5d.aspx&quot; width=&quot;970&quot; height=&quot;462&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this gif we demonstrate that the page tree does not update when clicking links inside the editing iframe. Thanks to &amp;lsquo;Andreas J&amp;rsquo; that commented on &lt;a href=&quot;/link/4552b6ecd7504771b9f3aae5832cb3a6.aspx&quot;&gt;our first OPE and client-side rendering blog post&lt;/a&gt; with this scenario.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The answer to the scenario presented above is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use regular anchor tags in edit mode with the expected URL format.&lt;/li&gt;
&lt;li&gt;Present page and block models as client side components.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This blog will go in depth on how to create the expected URL formats as there are several things you need to consider and watch out for. We will also show you how to use the new features included in the CMS UI 11.24.0 release to solve the more advanced scenarios. Those features are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New &lt;code&gt;epiReady&lt;/code&gt; message.&lt;/li&gt;
&lt;li&gt;Updated the global &lt;code&gt;epi&lt;/code&gt; object with properties &lt;code&gt;isEditable&lt;/code&gt;, &lt;code&gt;inEditMode&lt;/code&gt; and &lt;code&gt;ready&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will talk a lot about routing, so if you&amp;rsquo;re not very familiar with it see our &lt;a href=&quot;/link/8c6833b05a50458383427448e3277d4c.aspx&quot;&gt;learning path article for an introduction&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Routing table on the client&lt;/h2&gt;
&lt;p&gt;When using client side routing, you need to consider URLs on your site. If you want to use a client side routing framework, you are free to write your own routing table and take responsibility for creating URLs and matching them with your content. There are, however, a number of advantages to making sure that you use the same routes in your client side routing as Episerver does when it comes to URLs, so we strongly recommend it. We also recommend that you keep the notion that one URL represents one page model in the CMS. This is the concept that the UI is built upon and following that concept will make the editing experience nicer and easier to get right.&lt;/p&gt;
&lt;p&gt;The biggest upside to keep the default routing is probably that you can use the URL to get the content JSON that matches the path. You can use a solution similar to the one that Johan Bj&amp;ouml;rnfot created called &lt;a href=&quot;https://github.com/jbearfoot/ContentDeliveryExtendedRouting&quot;&gt;ContentDeliveryExtendedRouting&lt;/a&gt; to get content from any Episerver URL by just setting the &lt;code&gt;accept-header&lt;/code&gt; to &lt;code&gt;JSON&lt;/code&gt;. (You don&amp;rsquo;t need to use the ContentDeliveryAPI to use his code as long as your API accepts content links and you use the same URLs that Episerver does).&lt;/p&gt;
&lt;p&gt;Another upside with using the default routing that is easily overlooked, is how to deal with languages and different versions of content. This affects editing and can be complicated to get right with a custom routing implementation.&lt;/p&gt;
&lt;p&gt;Here is an example of how simple the routing table on the client becomes if the SPA uses the same URLs as Episerver. Simply route all URLs to one component that has the responsibility to load the correct SPA page-component.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;// example in Vue.js
routes: [
    {
        path: &#39;*&#39;,
        component: PageComponentSelector
    }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;The whole file can be viewed in our &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Assets/Scripts/router.js&quot;&gt;new template site on Github&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Getting the page navigation tree to match the current viewed page&lt;/h2&gt;
&lt;p&gt;As you noticed in the above GIF, the links you have in your template will look like they work when clicked in OPE, but the page tree and other widgets will not update if you use a framework like &lt;a href=&quot;https://router.vuejs.org/&quot;&gt;Vue.js router&lt;/a&gt;&amp;nbsp;&amp;nbsp;or &lt;a href=&quot;https://reacttraining.com/react-router/&quot;&gt;React router&lt;/a&gt;. This is because no page request is going to the server, so the CMS UI doesn&amp;rsquo;t change context&lt;/p&gt;
&lt;p&gt;We considered adding a communication path for templates to request a page tree update, but then the client would need to know how to map between the Episerver URLs and the sites client side URLs and it&amp;rsquo;s less work for the template to not duplicate the routing table (see previous section &lt;strong&gt;&quot;Routing table on the client&quot;&lt;/strong&gt;).&lt;/p&gt;
&lt;p&gt;There are two ways of solving this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disable all links, or make them editable, so the user can only navigate the site with the page tree.&lt;/li&gt;
&lt;li&gt;Keep them working, which we recommend as some users have very large websites.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make the second option work, you can disable client side routing and instead use regular anchor tags whenever the site is rendered in edit mode. In order for anchor tags to work, you need to make sure that the URL is the correct URL for the mode that the content is rendered in.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Links&quot; src=&quot;/link/b2bc28a55a6348c5b1e48e048cdd8ed3.aspx&quot; width=&quot;1186&quot; height=&quot;788&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Consider the different view modes: View, Edit, Preview&lt;/h2&gt;
&lt;p&gt;In Episerver, there are three modes available: Edit-, preview- and regular view-mode. A page has different URL in each mode when Episerver resolves them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;View mode: When the content is delivered to the site visitor.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;url: &quot;/en/artists/&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Edit mode: When the content is loaded in the CMS UI, and the content is editable in OPE.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;url: &quot;/EPiServer/CMS/Content/en/artists,,6_7/?epieditmode=True&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Preview mode: When the content is loaded in the CMS UI, but rendered as it would in View mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;url: &quot;/EPiServer/CMS/Content/en/artists,,6_7/?epieditmode=False&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In a standard site using regular MVC controllers, you can, for example, use something like this to get the current mode for a request:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;EPiServer.Web.IContextModeResolver contextModeResolver;

var currentMode = contextModeResolver.CurrentMode;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This option is unfortunately not available in a site using AJAX requests to an API to get the data to render since traditional Episerver routing is not used. This makes it hard to know what kinds of URLs to resolve when serializing the models.&lt;/p&gt;
&lt;p&gt;URLs resolved by Episerver use a query string parameter called &lt;code&gt;epieditmode&lt;/code&gt; to keep track of this. The value will be True if the content is in edit mode. The value will be False if the content is in preview mode. If the value does not exist, we assume that we&amp;rsquo;re in regular view mode.&lt;/p&gt;
&lt;p&gt;There are two parts that need this query string: the request from the SPA&amp;rsquo;s client code and the response from the server&amp;rsquo;s API.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Point of views&quot; src=&quot;/link/b199fc3329de4b02921508894c9070b5.aspx&quot; width=&quot;1217&quot; height=&quot;422&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Responsibilities of the client&lt;/h3&gt;
&lt;p&gt;In the SPA, you can figure out what mode it&amp;rsquo;s loaded in by looking at the &lt;code&gt;epieditmode&lt;/code&gt; query string on the &lt;code&gt;window.location&lt;/code&gt;. The client should include this information in the requests to the server API.&lt;/p&gt;
&lt;p&gt;Without regular MVC Razor views, the SPA becomes responsible for rendering the correct mode. It should not render OPE attributes (e.g. &lt;code&gt;data-epi-property-name&lt;/code&gt;) in View mode for example. To set the right editing context in CMS UI (to update the page tree, etc), the SPA site needs to have disabled the router links and use regular &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;-tags, but it also needs to set the correct URL in the &lt;code&gt;src&lt;/code&gt; attribute. To save you some work on parsing URL queries, we&amp;rsquo;re introducing some new properties, including a &lt;code&gt;isEditMode&lt;/code&gt;, and a new topic message on the injected &lt;code&gt;epi&lt;/code&gt; object. We&amp;rsquo;ll introduce the &lt;code&gt;epi&lt;/code&gt; object in the section called &lt;strong&gt;&quot;New features in CMS UI&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For the API to respond with URLs for the correct mode, the client needs to send its current mode in the request, such as including it as a query parameter. In our new template site, you can see it looks like this:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;GET /EPiServer/CMS/Content/en/artists,,6/?epieditmode=True&amp;amp;expand=* HTTP/1.1
Accept: application/json
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Responsibilities of the API&lt;/h3&gt;
&lt;p&gt;For the client to be able to render correct links, the JSON returned by your API needs to have URLs with the content link (including work id) and the right context query on it whenever serializing a page&amp;rsquo;s URL. Using the &lt;a href=&quot;/link/55fe410f4f65482cab72fb59d47c7561.aspx?documentId=cms/11/8F74D57D&quot;&gt;IUrlResolver interface&lt;/a&gt;, this will be easy.&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;_urlResolver.GetUrl(contentLink, language, new UrlResolverArguments
{
    ContextMode = contextMode
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example, a response to the request shown above (with query parameter &lt;code&gt;epieditmode=True&lt;/code&gt;) would look like this in our new template site:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content:
{
    &quot;name&quot;: &quot;Artists&quot;,
    &quot;url&quot;: &quot;/EPiServer/CMS/Content/en/artists,,6_7/?epieditmode=True&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;You can see &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/blob/master/src/MusicFestival.Vue.Template/Models/ExtendedContentModelMapper.cs&quot;&gt;how this can be implemented when using the ContentDeliveryAPI and the ContentDeliveryExtendedRouting in our new template site&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Compare mode shows two views at the same time&lt;/h3&gt;
&lt;p&gt;Compare mode is not really a mode of its own since it&amp;rsquo;s an extension of edit mode that shows two different versions at the same time, but it is still good to consider it since you might need to make some adjustments for that in your client side rendering in order for it to work properly. For instance, you will want to turn off any event handler for the &lt;code&gt;contentSaved&lt;/code&gt; topic message in the right hand side iframe so that you don&amp;rsquo;t update the version shown there when the left iframe is being edited. In version 11.24.0, we&amp;rsquo;re introducing some new properties, including an &lt;code&gt;isEditable&lt;/code&gt; on the injected &lt;code&gt;epi&lt;/code&gt; object that can be used to know when to listen to the &lt;code&gt;contentSaved&lt;/code&gt; topic message. This we&amp;rsquo;ll introduce in the section called &lt;strong&gt;&quot;New features in CMS UI&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Note that compare mode URLs looks the same as edit, which can be confusing when the loaded content version (such as &amp;ldquo;Published&amp;rdquo;) is usually rendered as in preview mode.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compare mode: When the content is loaded in the CMS UI alongside another version of the content that is also being loaded in the CMS UI. The left side view can be editable in OPE if it&amp;rsquo;s a draft version.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;left side (draft) url: &quot;/EPiServer/CMS/Content/en/artists,,6_139/?epieditmode=True&quot;

right side (published) url: &quot;/EPiServer/CMS/Content/en/artists,,6_7/?epieditmode=True&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;New features in CMS UI 11.24.0&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;re introducing a new event that we call &lt;code&gt;epiReady&lt;/code&gt;. This event will be raised as soon as the iframe inside the UI is loaded. The event will contain information regarding if the current content is editable. In addition to that event, we will also set a few properties on the global epi object that is available in edit mode. It&amp;rsquo;s the same epi object that you use to subscribe to the different events such as &lt;code&gt;contentSaved&lt;/code&gt; and the aforementioned &lt;code&gt;epiReady&lt;/code&gt;. The epi object will look like this:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;epi: {
    isEditable: true,
    inEditMode: true,
    ready: true
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The object is constructed using the info from the &lt;code&gt;epiReady&lt;/code&gt; event and will not get the correct &lt;code&gt;isEditable&lt;/code&gt; value until the event has been raised. By looking at the &lt;code&gt;ready&lt;/code&gt; property you will know if the beta object has been initialized or not. Here is a sample of how this event and object could be used:&lt;/p&gt;
&lt;pre class=&quot;hljs&quot;&gt;&lt;code&gt;const context = {
    inEditMode: false,
    isEditable: false
};

// Listen to the `epiReady` event to update the `context` property.
window.addEventListener(&#39;load&#39;, () =&amp;gt; {
    // Expect `epi` to be there after the `load` event. If it&#39;s not then we&#39;re
    // not in any editing context.
    if (!window.epi) {
        return;
    }

    function setContext() {
        // The event only has `isEditable`, but the epi object has both.
        context.inEditMode = window.epi.inEditMode;
        context.isEditable = window.epi.isEditable;
    }

    // Check for beta and that ready is an actual true value (not just truthy).
    if (window.epi.ready === true) {
        // `epiReady` already fired.
        setContext();

    // The subscribe method won&#39;t be available in View mode.
    } else if (window.epi.subscribe) {
        // Subscribe if the `epiReady` event hasn&#39;t happened yet.
        window.epi.subscribe(&#39;epiReady&#39;, () =&amp;gt; setContext());
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Related links&lt;/h2&gt;
&lt;p&gt;Template site using the techniques discussed in this blog: &lt;a href=&quot;https://github.com/episerver/musicfestival-vue-template/&quot;&gt;https://github.com/episerver/musicfestival-vue-template/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Documentation on client side rendering in Episerver: &lt;a href=&quot;/link/f80257067ca542288c0b74d4db6ae0c5.aspx&quot;&gt;https://world.episerver.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Learning path documentation on page tree and routing: &lt;a href=&quot;/link/8c6833b05a50458383427448e3277d4c.aspx&quot;&gt;https://world.episerver.com/documentation/developer-guides/CMS/learning-path/page-tree-and-routing/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Documentation on routing: &lt;a href=&quot;/link/0981d69123d04f5c9609fb22bd68e10c.aspx&quot;&gt;https://world.episerver.com/documentation/developer-guides/CMS/routing/&lt;/a&gt;&lt;/p&gt;</id><updated>2018-10-30T14:09:23.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Episerver Image Tools in TinyMCE</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2018/5/episerver-image-tools-in-tinymce/" /><id>&lt;p&gt;&lt;a href=&quot;https://nuget.episerver.com/package/?id=EPiServer.CMS.TinyMce&quot;&gt;EPiServer.CMS.TinyMce&lt;/a&gt; versions 2.3.0 and 2.4.0 bring two Image Tools features inside the XHTML editor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Go to media&amp;nbsp;&lt;span&gt;(version 2.3.0)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Image gotomedia.PNG&quot; src=&quot;/link/a61ada03ec994cad8e9348de61560f2e.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This new button will make it easier for the editors to locate and navigate to the image that is included in the HTML property.&lt;/p&gt;
&lt;p&gt;Additionally, after hovering it will show a tooltip with a full path to the image.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Drag &amp;amp; Drop from local disk&amp;nbsp;&lt;span&gt;(version 2.4.0)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is possible to drag and drop an image from a local disk directly onto the editor.&lt;/p&gt;
&lt;p&gt;An image preview will be shown immediately upon dropping while the image is being uploaded to the server.&lt;/p&gt;
&lt;p&gt;All dropped images are automatically placed in the &quot;For this page&quot; or &quot;For this block&quot; folder.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Please note that although it is technically possible to drag &amp;amp; drop multiple images at the same time, it does not work deterministically.&lt;/p&gt;
&lt;p&gt;There is a bug reported in TinyMCE &lt;a title=&quot;#4055&quot; href=&quot;https://github.com/tinymce/tinymce/issues/4055&quot; target=&quot;_blank&quot;&gt;#4055&lt;/a&gt; that EPiServer has already submitted a &lt;a title=&quot;Bugfix #4055&quot; href=&quot;https://github.com/tinymce/tinymce/pull/4406&quot; target=&quot;_blank&quot;&gt;bugfix &lt;/a&gt;&amp;nbsp;to. The bug is still pending review.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Image Tools are enabled by the default configuration, but they can be disabled.&lt;/p&gt;
&lt;p&gt;To disable or re-enable the features, you should use the EnableImageTools/DisableImageTools methods available when you are configuring your properties:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;context.Services.Configure&amp;lt;TinyMceConfiguration&amp;gt;(config =&amp;gt;
{
    ...
    // Disable the image tools
    config.For&amp;lt;ArticlePage&amp;gt;(t =&amp;gt; t.MainBody)
        .DisableImageTools()
    ...
    // Enable the image tools for a property (if the property does not have it already)
    config.For&amp;lt;ArticlePage&amp;gt;(t =&amp;gt; t.MainBody)
        .EnableImageTools();
     ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The information about enabling and disabling the features is included in the SDK - &lt;a href=&quot;/link/bd2ec65225f94701b55beb5bc5bbf70f.aspx#epiplugins&quot;&gt;Episerver Plugins&lt;/a&gt;.&lt;/p&gt;</id><updated>2018-06-18T15:47:28.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Introducing EPiCommerce.Integration.Sample</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2014/3/Introducing-EPiCommerceIntegrationSample/" /><id>&lt;p&gt;Integration testing a EPiServer Commerce site can be tricky. How would you know how to initialize everything in a way so that your tests behaves similar to how your site behaves?&lt;/p&gt;  &lt;p&gt;In an attempt at answering this question for you I’ve created a sample project for integration testing EPiServer Commerce projects. It’s posted on github.com under the MIT-license and you can find it here:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;https://github.com/nicklasisraelsson/EPiCommerce.Integration.Sample&quot; target=&quot;_blank&quot;&gt;EPiServer Commerce Integration Test Sample&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This sample project doesn’t use selenium or any other web driver to test the UI but instead it aims to initialize an EPiServer Commerce site in a test context so that you can test your business logic below your UI layer. &lt;/p&gt;  &lt;p&gt;The README for the project should help you get started but I still want to highlight the requirements. EPiServer Commerce requires the &lt;a href=&quot;http://technet.microsoft.com/en-us/library/ms142571.aspx&quot; target=&quot;_blank&quot;&gt;Full-Text Search feature&lt;/a&gt; to be enabled on your SQL server and you need a version that supports &lt;a href=&quot;http://technet.microsoft.com/en-us/library/ms175158.aspx&quot; target=&quot;_blank&quot;&gt;snapshots&lt;/a&gt;. The user running the tests also need access to the master database to be able to create databases. I’ve tried isolating most of the database specific code in the &lt;a href=&quot;https://github.com/nicklasisraelsson/EPiCommerce.Integration.Sample/blob/master/TestSupport/Database.cs&quot; target=&quot;_blank&quot;&gt;Database class&lt;/a&gt; so that if you want a different approach on how to reset state between tests you can replace that one class.&lt;/p&gt;</id><updated>2014-03-07T14:38:49.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>PageEntity for Community 4.0</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2010/11/PageEntity-for-Community-40/" /><id>&lt;p&gt;PageEntities is a custom entity that links EPiServer Community functionality (rating, visits, comments etc) to ordinary EPiServer pages. It was first introduced by Per Hemmingson in &lt;a href=&quot;http://world.episerver.com/Blogs/Per-Hemmingson/Dates/2009/6/Do-you-want-Community-features-on-your-CMS-pages-PageEntity-to-the-rescue/&quot;&gt;this blog post&lt;/a&gt; and have since then been a popular addition for several projects. We use it on this website for instance.&lt;/p&gt;
&lt;p&gt;The problem is that the code attached in his post is for Community 3.2 and doesn’t work together with the new Community 4 because of changes to the API. For details on the API changes, look for the tech note named:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-Community/EPiServer-Community-32/Migrating-EPiServer-Community-32-to-40-and-EPiServer-Mail-44-to-50/&quot;&gt;Migrating EPiServer Community 3.2 to 4.0 and EPiServer Mail 4.4 to 5.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since last week we’re running Community 4 on world and in order to do the upgrade we needed to update the code for PageEntities. And since I’m such a friendly fellow I thought I’d share the changes made to the rest of the community. Hopefully I can save time for someone looking to do the same upgrade or adding PageEntities to a new community 4 project.&lt;/p&gt;
&lt;h2&gt;Changes made&lt;/h2&gt;
&lt;p&gt;The “big” change is that I removed the usage of SiteId in the code completely. Sites have been removed in favor of the category system in Community 4 and since we used the same SiteId for all our saved PageEntities we didn’t really need it. If you need it you need to make the appropriate changes to the code.&lt;/p&gt;
&lt;p&gt;Most of the changes made were similar to this one:&lt;/p&gt;
&lt;h3&gt;From:&lt;/h3&gt;
&lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;&quot;&gt;
&lt;div id=&quot;codeSnippet&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum1&quot; style=&quot;color: #606060;&quot;&gt;   1:&lt;/span&gt; DatabaseHandler.RunInTransaction(&lt;span style=&quot;color: #0000ff;&quot;&gt;delegate&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum2&quot; style=&quot;color: #606060;&quot;&gt;   2:&lt;/span&gt;  {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum3&quot; style=&quot;color: #606060;&quot;&gt;   3:&lt;/span&gt;      DatabaseHandler.GetScalar(&lt;span style=&quot;color: #006080;&quot;&gt;&quot;spUpdatePageEntity&quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum4&quot; style=&quot;color: #606060;&quot;&gt;   4:&lt;/span&gt;                                tpr.ID, (&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;) tpr.EntityType, tpr.SiteID);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum5&quot; style=&quot;color: #606060;&quot;&gt;   5:&lt;/span&gt;      UpdateEntity(tpr);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum6&quot; style=&quot;color: #606060;&quot;&gt;   6:&lt;/span&gt;  });&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;To:&lt;/h3&gt;
&lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;&quot;&gt;
&lt;div id=&quot;codeSnippet&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum1&quot; style=&quot;color: #606060;&quot;&gt;   1:&lt;/span&gt; DatabaseHandler.Instance.RunInTransaction(&lt;span style=&quot;color: #0000ff;&quot;&gt;delegate&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum2&quot; style=&quot;color: #606060;&quot;&gt;   2:&lt;/span&gt;  {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum3&quot; style=&quot;color: #606060;&quot;&gt;   3:&lt;/span&gt;      DatabaseHandler.Instance.GetScalar(&lt;span style=&quot;color: #006080;&quot;&gt;&quot;spUpdatePageEntity&quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum4&quot; style=&quot;color: #606060;&quot;&gt;   4:&lt;/span&gt;                                tpr.ID, (&lt;span style=&quot;color: #0000ff;&quot;&gt;int&lt;/span&gt;) tpr.EntityType);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum5&quot; style=&quot;color: #606060;&quot;&gt;   5:&lt;/span&gt;      UpdateEntity(tpr);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum6&quot; style=&quot;color: #606060;&quot;&gt;   6:&lt;/span&gt;  });&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In other words, we started using the new static instances of the handlers. That was needed on several places but you get a lot of help from the compiler when doing this.&lt;/p&gt;
&lt;p&gt;Another thing that was needed was a couple of methods to the PageEntityProvider class. This is because the interface IEntityProvider had gotten a few more methods. Namely: AddEntityInstance, RemoveEntityInstance, UpdateEntityInstance and GetSupportedOperations. They were all implemented similar to this (the difference is what method to use in the return statement):&lt;/p&gt;
&lt;div id=&quot;codeSnippetWrapper&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;&quot;&gt;
&lt;div id=&quot;codeSnippet&quot; style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum1&quot; style=&quot;color: #606060;&quot;&gt;   1:&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt; IEntity AddEntityInstance(IEntity entity)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum2&quot; style=&quot;color: #606060;&quot;&gt;   2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum3&quot; style=&quot;color: #606060;&quot;&gt;   3:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;if&lt;/span&gt; (!(entity &lt;span style=&quot;color: #0000ff;&quot;&gt;is&lt;/span&gt; PageEntity))&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum4&quot; style=&quot;color: #606060;&quot;&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum5&quot; style=&quot;color: #606060;&quot;&gt;   5:&lt;/span&gt;         &lt;span style=&quot;color: #0000ff;&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt; EPiServer.Common.Exceptions.NonCommittedEntityException(entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum6&quot; style=&quot;color: #606060;&quot;&gt;   6:&lt;/span&gt;     }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum7&quot; style=&quot;color: #606060;&quot;&gt;   7:&lt;/span&gt;     &lt;span style=&quot;color: #0000ff;&quot;&gt;return&lt;/span&gt; PageEntityHandler.AddPageEntity((PageEntity)entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style=&quot;text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;&quot;&gt;&lt;span id=&quot;lnum8&quot; style=&quot;color: #606060;&quot;&gt;   8:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All changes are available in&amp;nbsp; the attached .zip file at the bottom of this post.&lt;/p&gt;
&lt;h2&gt;SQL changes&lt;/h2&gt;
&lt;p&gt;Observe that the SQL script (&lt;em&gt;PageEntityProviderSQL.sql&lt;/em&gt;) is changed so that all created stored procedures doesn’t use any SiteId any more.&lt;/p&gt;
&lt;p&gt;Also note that I included a script to move data from one database to another in the same way that the migration script for community work. That script is called: &lt;em&gt;PageEntity-MoveDataInTblPageEntityWithoutSiteId.sql&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The script moves all data in your old database to the new excluding any values in the SiteId column.&lt;/p&gt;
&lt;p&gt;There is no error handling in that script and it requires you to run the PageEntityProviderSQL script first to create the correct table in the new database. Remember to backup any database affected before attempting to run these scripts. The script don’t delete anything, but it’s better to be safe than sorry.&lt;/p&gt;
&lt;h2&gt;Files&lt;/h2&gt;
&lt;div id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:efd4e928-0617-40fb-a904-7e5cdc01ef1b&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/link/4ec0e260c9f7450d8bea5a8398e07487.zip&quot; target=&quot;_blank&quot;&gt;PageEntity for Community 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</id><updated>2010-11-15T14:01:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>EPiServer log: Excluding rows from selected namespaces</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2009/2/EPiServer-log-Excluding-rows-from-selected-namespaces/" /><id>&lt;p&gt;Whenever I encounter a problem with EPiServer I can&#39;t really figure out, usually the first thing I do is &lt;a href=&quot;http://world.episerver.com/en/FAQ/Items/How-do-I-create-a-log-in-EPiServer/&quot;&gt;create a log&lt;/a&gt; while reproducing the error. Logs are one of my best friends when it comes to troubleshooting. &lt;/p&gt;
&lt;p&gt;Often I don&#39;t know what I&#39;m looking for so I set the level to either &quot;Debug&quot; or &quot;All&quot;. This will output a lot of information and create large log files really fast. I have no problem with this since I asked for all information available. But some parts of EPiServer are chattier than others and thus create a lot of noise in my logs. I’m especially thinking of the EPiServer.Core.OptimisticCache namespace. It outputs lots of rows similar to these below:&lt;/p&gt;
&lt;div style=&quot;BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; HEIGHT: 39px; BACKGROUND-COLOR: #f4f4f4&quot;&gt;
&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, retry 1, calling CacheManager.RuntimeCacheGet for key&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, retry 1, CacheManager.RuntimeCacheGet returned null for key&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, retry 1, returning null&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, inserting a RefCountedEvent object in cache&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, calling ReadAndCacheObject delegate passed&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;2009-01-21 12:17:53,942 [1] INFO EPiServer.Core.OptimisticCache [(null)] - cacheKey=EPChildrenData:3292, ReadAndCacheObject delegate returned object of type TObject&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And even though I’m not quite sure what I’m looking for, I can often rule out if the cache might have anything to do with it or not. So to remove all rows that come from this namespace I just add the following lines to my EPiServerLog.config:&lt;/p&gt;
&lt;div style=&quot;BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BACKGROUND-COLOR: #f4f4f4&quot;&gt;
&lt;div style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;span style=&quot;COLOR: #008000&quot;&gt;&amp;lt;!-- Removing all rows coming from OptimisticCache --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;logger&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.Core.OptimisticCache&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;additivity&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;false&quot;&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;level&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Off&quot;&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;appender-ref&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;fileLogAppender&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;logger&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This helps keep the logs clean from thousands of rows like the ones above and makes it a bit easier to read through. &lt;/p&gt;
&lt;p&gt;Just remember what namespaces you exclude. At one time or another you might want one of those lines and then you’ll have to change the EPiServerLog.config again. &lt;/p&gt;</id><updated>2009-02-01T15:08:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Scheduler not active when using Extension (X3)</title><link href="https://world.optimizely.com/blogs/Nicklas-Israelsson/Dates/2009/1/Scheduler-not-active-when-using-Extension-X3/" /><id>&lt;p&gt;When using X3 on your CMS 5 sites (mainly SP2) you might find out that your scheduled jobs doesn&#39;t run. When looking at the jobs in admin mode you get this message: &quot;The EPiServer Scheduler Service does not appear to be active, it may have been stopped.&quot;&lt;/p&gt;
&lt;p&gt;On a regular site you follow &lt;a href=&quot;http://world.episerver.com/FAQ/Items/Scheduler-does-not-run-scheduled-jobs-automatically/&quot;&gt;this FAQ&lt;/a&gt; and the scheduler starts to work for your site. But when using X3 this might not work. &lt;/p&gt;
&lt;p&gt;We&#39;ve found out that the problem is caused by the installation package. It adds the extension httpmodule on the same row as the scheduler initialization module and thus removing it. Your httpmodules section in web config might look something like this:&lt;/p&gt;
&lt;div style=&quot;BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BACKGROUND-COLOR: #f4f4f4&quot;&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;httpModules&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #008000&quot;&gt;&amp;lt;!--&amp;lt;add name=&quot;BasicAuthentication&quot; type=&quot;EPiServer.Security.BasicAuthentication, EPiServer&quot; /&amp;gt;--&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Dropit.Extension&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Dropit.Extension.Handlers.HttpModule, Dropit.Extension&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;WorkflowRuntime&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.WorkflowFoundation.WorkflowSystem, EPiServer.WorkflowFoundation&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;UrlRewriteModule&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.Web.UrlRewriteModule, EPiServer&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  ...
&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;httpModules&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To fix this you&#39;ll need to manually re-add the scheduler initialization module. After adding it your httpmodules it might look something like this:&lt;/p&gt;
&lt;div style=&quot;BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BACKGROUND-COLOR: #f4f4f4&quot;&gt;&lt;pre style=&quot;PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, &#39;Courier New&#39;, courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none&quot;&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;httpModules&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #008000&quot;&gt;&amp;lt;!--&amp;lt;add name=&quot;BasicAuthentication&quot; type=&quot;EPiServer.Security.BasicAuthentication, EPiServer&quot; /&amp;gt;--&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Initializer&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.Scheduler.Initializer, EPiServer.Scheduler&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Dropit.Extension&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;Dropit.Extension.Handlers.HttpModule, Dropit.Extension&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;WorkflowRuntime&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.WorkflowFoundation.WorkflowSystem, EPiServer.WorkflowFoundation&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;add&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;UrlRewriteModule&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;=&quot;EPiServer.Web.UrlRewriteModule, EPiServer&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
  ...
&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;httpModules&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After adding this you can follow the above mentioned FAQ and your scheduler should now once again be active. &lt;/p&gt;</id><updated>2009-01-22T11:05:00.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>