<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sitecore &#8211; blog.boro2g .co.uk</title>
	<atom:link href="https://blog.boro2g.co.uk/tag/sitecore-2/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.boro2g.co.uk</link>
	<description>Some ideas about coding, dev and all things online.</description>
	<lastBuildDate>Mon, 24 Jun 2019 09:34:27 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.8</generator>
	<item>
		<title>JSS Blog post series</title>
		<link>https://blog.boro2g.co.uk/jss-blog-post-series/</link>
					<comments>https://blog.boro2g.co.uk/jss-blog-post-series/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Mon, 24 Jun 2019 09:34:25 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">https://blog.boro2g.co.uk/?p=1081</guid>

					<description><![CDATA[<p>I&#8217;ve recently been working with the Marketing team within Valtech to get a series of JSS Blog posts published onto the Valtech site. If anyone is interested you can access them via https://www.valtech.com/en-gb/insights/going-live-with-jss/ The topics cover things like what it’s like to move from being a traditional Sitecore dev to a JSS dev, how to [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/jss-blog-post-series/">JSS Blog post series</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve recently been working with the Marketing team within Valtech to get a series of JSS Blog posts published onto the Valtech site.</p>



<p>If anyone is interested you can access them via  <a href="https://www.valtech.com/en-gb/insights/going-live-with-jss/">https://www.valtech.com/en-gb/insights/going-live-with-jss/</a> </p>



<p><em>The topics cover things like what it’s like to move from being a traditional Sitecore dev to a JSS dev, how to get everything deployed, any gotchas we didn&#8217;t estimate for when we started and some key design decisions we made along the way. </em></p>



<p>I hope you find them useful <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/jss-blog-post-series/">JSS Blog post series</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/jss-blog-post-series/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Setting up JSS with Vue, Typescript and dependency injection</title>
		<link>https://blog.boro2g.co.uk/setting-up-jss-with-vue-typescript-and-dependency-injection/</link>
					<comments>https://blog.boro2g.co.uk/setting-up-jss-with-vue-typescript-and-dependency-injection/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Mon, 04 Feb 2019 11:23:03 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[jss]]></category>
		<category><![CDATA[sitecore]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[vue]]></category>
		<guid isPermaLink="false">https://blog.boro2g.co.uk/?p=991</guid>

					<description><![CDATA[<p>If JSS is a new term for you, I&#8217;d seriously recommend checking our the documentation that Sitecore have provided: https://jss.sitecore.com/ . By the end of this post we&#8217;ll have run through how you can get JSS up and running locally, with dependencies all wired together using a DI container and any functional aspects written in [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/setting-up-jss-with-vue-typescript-and-dependency-injection/">Setting up JSS with Vue, Typescript and dependency injection</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>If JSS is a new term for you, I&#8217;d seriously recommend checking our the documentation that Sitecore have provided: <a rel="noreferrer noopener" aria-label="https://jss.sitecore.com/ (opens in a new tab)" href="https://jss.sitecore.com/" target="_blank">https://jss.sitecore.com/</a> . </p>



<p>By the end of this post we&#8217;ll have run through how you can get JSS up and running locally, with dependencies all wired together using a DI container and any functional aspects written in TypeScript. For us this is a key set of requirements &#8211; we&#8217;ve worked with many projects that have grown over several years. By putting in some key rules and requirements up front should mean with good discipline that the codebase can scale over time.</p>



<p><strong>Why&nbsp;JSS?</strong></p>



<p>Imagine a standard Sitecore development team, typically based around C# developers and some front end devs. In the default approach to building a site you&#8217;d need everyone to contribute Razor files with the markup and associated styling and functionality. This is the approach you would probably have seen for several years until more recently with the demand for richer front end technologies. Think Vue, Angular, React and so on. </p>



<p>This is what JSS facilitates.</p>



<p><strong>Is this right for everyone?</strong></p>



<p>Just because technologies exist, it doesn&#8217;t always make them the right platform to jump on. E.g. if you have a very established Sitecore development team that doesn&#8217;t have the appetite for these front end technologies, then JSS might not be the thing for you.</p>



<p><strong>Getting started</strong></p>



<p>The quick start from the docs site provides 4 tasks to get you started:</p>



<pre class="crayon-plain-tag">npm install -g @sitecore-jss/sitecore-jss-cli
jss create my-first-jss-app vue
cd my-first-jss-app
jss start</pre>



<p>Provided you have node installed, once you run ^ you should then see <a href="http://localhost:3000" target="_blank" rel="noreferrer noopener" aria-label="http://localhost:3000 (opens in a new tab)">http://localhost:3000</a> fire up.</p>



<p><strong>Why TypeScript?</strong></p>



<p>I wouldn&#8217;t consider starting a new web project now without TypeScript as it provides so many useful features for a codebase. Refactoring is just like if you were using C#, variables have types, classes can implement other abstract classes or interfaces. If you&#8217;ve not used it before, I&#8217;d highly recommend it.</p>



<p>In terms of designing your application, another key factor to consider is the coupling between the different layers. Core functionality being one layer, your UI framework being another. If you structure things so that e.g. you can peel out Vue without too much trouble, moving up through different technologies or versions will be a breeze.</p>



<p><strong>Changes to the default app</strong></p>



<p>Here we&#8217;ll add things like some demo services, some DI registrations and a few other bits we&#8217;ll need.</p>



<p>1.First up lets include some extra dependencies:</p>



<pre class="crayon-plain-tag">npm install -d inversify-inject-decorators, vue-class-component, inversify, vue-property-decorator, reflect-metadata, ts-loader, typescript</pre>



<p>2. In src/AppRoot.vue, before the <code>export default</code> line add <code>import "reflect-metadata"</code><br></p>



<p>3. Add a tsconfig.json file to the root folder (a level above src):</p>



<pre class="crayon-plain-tag">{
    &quot;compilerOptions&quot;: {
        &quot;outDir&quot;: &quot;./built/&quot;,
        &quot;sourceMap&quot;: true,
        &quot;strict&quot;: true,
        &quot;module&quot;: &quot;es2015&quot;,
        &quot;moduleResolution&quot;: &quot;node&quot;,
        &quot;target&quot;: &quot;es5&quot;,       
        &quot;lib&quot;: [
            &quot;es6&quot;,
            &quot;dom&quot;
        ],
        &quot;types&quot;: [
            &quot;reflect-metadata&quot;
        ],
        &quot;experimentalDecorators&quot;: true,
        &quot;emitDecoratorMetadata&quot;: true,
        &quot;baseUrl&quot;: &quot;./src&quot;,
        &quot;paths&quot;: {            
            &quot;@di_ids&quot;: [&quot;DependencyInjection/Identifiers&quot;]
        }
    },
    &quot;include&quot;: [
        &quot;./src/**/*&quot;
    ]
}</pre>



<p>4. Update the webpack config, in the Vue world this is done in <code>vue.config.js</code></p>



<pre class="crayon-plain-tag">//at the top of the file:
let path= require('path');

//alongside the graphql includes:
config.module.rules.push({
    test: /\.tsx?$/,
    loader: 'ts-loader',
    exclude: /node_modules/,
    options: {
      appendTsSuffixTo: [/\.vue$/],
    }
  });

config.resolve.extensions.push('.ts');

//note, this is required for alias'ing to work for your references - a nice way to avoid crazy import statements. Same change exists in tsconfig

config.resolve.alias[&quot;@di_ids&quot;] = path.resolve(__dirname, 'src/DependencyInjection/Identifiers')</pre>



<p>5. Now add a <code>vue-shim.d.ts</code> (in the src folder)</p>



<pre class="crayon-plain-tag">declare module &quot;*.vue&quot; {
    import Vue from &quot;vue&quot;;
    export default Vue;
}</pre>



<p>6. Next, some dummy TypeScript dependencies:</p>



<pre class="crayon-plain-tag">// /src/scripts/processors/TestProcessor.ts

import { IService } from &quot;../services/TestService&quot;;
import { inject, injectable } from 'inversify';
import {SERVICE_IDENTIFIER} from &quot;@di_ids&quot;;

@injectable()
export default class TestProcessor
{    
    constructor(@inject(SERVICE_IDENTIFIER.IService) private service:IService) {        
        
    }

    public DoSomething() : string {
        return this.service.DoIt();
    }
}

// /src/scripts/services/TestServices.ts

import { injectable } from 'inversify';

@injectable()
export class ServiceA implements IService {
    DoIt(): string {
        return &quot;ServiceA&quot;;
    }

}
@injectable()
export class ServiceB implements IService {
    DoIt(): string {
        return &quot;ServiceB&quot;;
    }

}

export interface IService {
    DoIt(): string;
}</pre>



<p>7. And the DI  container and keys:</p>



<pre class="crayon-plain-tag">// /src/DependencyInjection/ContainerRoot.ts

import { Container } from &quot;inversify&quot;;
import getDecorators from 'inversify-inject-decorators';
import TestModule from './Modules/TestModule'

let container = new Container();

container.load(TestModule);

const { lazyInject } = getDecorators(container);

export { container, lazyInject }

// /src/DependencyInjection/Identifiers.ts

const SERVICE_IDENTIFIER = {
    IService: Symbol(&quot;IService&quot;),
    Container: Symbol(&quot;Container&quot;),
    TestProcessor: Symbol(&quot;TestProcessor&quot;)
};

export {SERVICE_IDENTIFIER}

// /src/DependencyInjection/Modules/TestModule.ts

import { ContainerModule, interfaces } from &quot;inversify&quot;;
import { SERVICE_IDENTIFIER } from &quot;../Identifiers&quot;;
import { IService, ServiceA, ServiceB } from &quot;../../scripts/services/TestService&quot;;
import TestProcessor from &quot;../../scripts/processors/TestProcessor&quot;;

const testServices = new ContainerModule(
    (
        bind: interfaces.Bind
    ) =&gt; {
        bind&lt;IService&gt;(SERVICE_IDENTIFIER.IService).to(ServiceA);
        bind&lt;TestProcessor&gt;(SERVICE_IDENTIFIER.TestProcessor).to(TestProcessor);
    }
);

export default testServices;</pre>



<p>8. Now a TypeScript enabled Vue component: <code>/src/components/Hello.vue</code></p>



<pre class="crayon-plain-tag">&lt;template&gt;
    &lt;div&gt;
        &lt;div class=&quot;greeting&quot;&gt;Hello {{name}}{{exclamationMarks}}&lt;/div&gt;
        &lt;button @click=&quot;decrement&quot;&gt;-&lt;/button&gt;
        &lt;button @click=&quot;increment&quot;&gt;+&lt;/button&gt;       
    &lt;/div&gt;
&lt;/template&gt;

&lt;script lang=&quot;ts&quot;&gt;
import { Vue, Component, Prop, Inject } from 'vue-property-decorator'
import { Container } from &quot;inversify&quot;;
import TestProcessor from '../scripts/processors/TestProcessor';
import { SERVICE_IDENTIFIER } from &quot;@di_ids&quot;;
import { inject, injectable } from 'inversify';
import { lazyInject } from '../DependencyInjection/ContainerRoot';


@Component({
    //components: { SubComponent }
})
export default class Hello extends Vue
{      
    @lazyInject(SERVICE_IDENTIFIER.TestProcessor)
    private _testProcessor!: TestProcessor;

// // If you want to use Vue's OTB Inject/Provide you can
    // @Inject(SERVICE_IDENTIFIER.Container)
    // private _container!: Container;

    created (): void {
        //console.log(this._container.resolve&lt;TestProcessor&gt;(TestProcessor).DoSomething());

        console.log(this._testProcessor.DoSomething());
    }

    @Prop() name!: string;
    @Prop() initialEnthusiasm!: number;    

    enthusiasm = this.initialEnthusiasm;

    increment() {
        this.enthusiasm++;
    }
    decrement() {
        if (this.enthusiasm &gt; 1) {
            this.enthusiasm--;
        }
    }

    get exclamationMarks(): string {
        return Array(this.enthusiasm + 1).join('!');
    }    
}
&lt;/script&gt;

&lt;style&gt;
.greeting {
    font-size: 20px;
}
&lt;/style&gt;</pre>



<p>9. And to finally get it showing on a page, edit layout.vue to include your component:</p>



<pre class="crayon-plain-tag">&lt;div class=&quot;container&quot;&gt;
      &lt;!-- &lt;placeholder name=&quot;jss-main&quot; :rendering=&quot;route&quot; /&gt; --&gt;
      &lt;Hello :initialEnthusiasm=&quot;5&quot; /&gt;
&lt;/div&gt;

//...
import Hello from './components/Hello'

//...
components: {
    //...,
    Hello
},</pre>



<p>After all that, you should see the homepage load up and &#8220;ServiceA&#8221; getting logged to the console. Not the most impressive output but shows the full flow of dependencies getting configured and resolved, with all the code written in TypeScript <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>If you are using SSR Renderings, you&#8217;ll also need to add <code>|ts</code> into the list of rules that get &#8216;unshift&#8217;ed in <code>/server/server.vue.config.js</code></p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/setting-up-jss-with-vue-typescript-and-dependency-injection/">Setting up JSS with Vue, Typescript and dependency injection</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/setting-up-jss-with-vue-typescript-and-dependency-injection/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Debugging Sitecore Marketing Automation UI</title>
		<link>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation-ui/</link>
					<comments>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation-ui/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Wed, 24 Oct 2018 13:13:53 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[marketing automation]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">https://blog.boro2g.co.uk/?p=965</guid>

					<description><![CDATA[<p>The previous post detailed how you can debug the server side aspects of the Marketing Automation agent. If you start experimenting with richer functionality, I&#8217;m sure you&#8217;ll soon want to create your own custom activities and UI&#8217;s. Sitecore provide a good description of doing this in their documentation. Adding custom fields to the UI In [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation-ui/">Debugging Sitecore Marketing Automation UI</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The <a href="https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/">previous post</a> detailed how you can debug the server side aspects of the Marketing Automation agent. If you start experimenting with richer functionality, I&#8217;m sure you&#8217;ll soon want to create your own custom activities and UI&#8217;s.</p>



<p>Sitecore provide a good description of doing this in their <a href="https://doc.sitecore.net/developers/xp/marketing-automation/activities/activity-types/add-activity-type-to-ui.html" target="_blank">documentation</a>.</p>



<p><strong>Adding custom fields to the UI</strong></p>



<p>In my demo activity, I needed to include a MessageKey that would be passed through to the backend engine. Getting the field to show was relatively easy if you follow the example. I&#8217;d also recommend checking out <a href="https://github.com/avershalovich/Demo9.Features/tree/master/Demo9.Features.UI/SendPromoEmailAction-UI" target="_blank">this repo</a>.</p>



<p>The problem I hit was getting the MessageKey value to render correctly in the UI when I opened a plan for the second time &#8211; rather than seeing the Key displayed as expected, you&#8217;d see an empty block.</p>



<figure class="wp-block-image"><img decoding="async" width="93" height="264" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-no-data.png" alt="" class="wp-image-967"/><figcaption>Missing key value</figcaption></figure>



<figure class="wp-block-image"><img fetchpriority="high" decoding="async" width="243" height="256" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-with-data.png" alt="" class="wp-image-968"/><figcaption>Showing the key value</figcaption></figure>



<p><strong>Why was this?</strong></p>



<p>Well, it turns out the <strong>MessageKey != messageKey</strong> . For some reason, when you write your custom typescript activity, you need to reference &#8216;this.editorParams.messageKey&#8217;, not &#8216;this.editorParams.MessageKey&#8217;. Note the capital, or lack of, <strong>M</strong>.</p>



<p><strong>Missing bits of Sitecore</strong></p>



<p>One thing the docs doesn&#8217;t mention is when you create your custom parameter within the Sitecore tree, you need to set a couple additional fields (Editor ID, Editor Parameters). Have a look at some existing ones for more details.</p>



<figure class="wp-block-image"><img decoding="async" width="770" height="289" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-params.png" alt="" class="wp-image-969" srcset="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-params.png 770w, https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-params-300x113.png 300w, https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-params-768x288.png 768w" sizes="(max-width: 770px) 100vw, 770px" /></figure>



<p><strong>Debugging the UI</strong></p>



<p>How did I spot the issue with the <strong>M</strong>? Once you&#8217;ve built your plugin js (npm run dev) you get a minified js file to deploy. Alongside this you will also get a sourcemap file:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="238" height="81" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-sourcemap.png" alt="" class="wp-image-970"/></figure>



<p>If you copy this to the same folder as your deployed plugin, you can then do some clever things in chrome:</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="922" height="352" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-sourcemaps.png" alt="" class="wp-image-971" srcset="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-sourcemaps.png 922w, https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-sourcemaps-300x115.png 300w, https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-sourcemaps-768x293.png 768w" sizes="(max-width: 922px) 100vw, 922px" /></figure>



<p>In order for this to work you need to:</p>



<ul><li>Deploy the sourcemap file as per above</li><li>Add the folder where the original TS files live into chrome<ul><li>In the diagram above => Filesystem => Add folder to workspace </li></ul></li></ul>



<p>Happy debugging <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation-ui/">Debugging Sitecore Marketing Automation UI</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation-ui/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Debugging Sitecore Marketing automation</title>
		<link>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/</link>
					<comments>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Tue, 23 Oct 2018 11:51:28 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[marketing automation]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">https://blog.boro2g.co.uk/?p=962</guid>

					<description><![CDATA[<p>Here are a few tips and tricks that should help if you want to start developing custom activities within the new Sitecore Marketing automation engine. The docs There is a pretty extensive guide on the Sitecore docs site: https://doc.sitecore.net/developers/xp/marketing-automation/activities/activity-types/create-an-activity-type.html Alternatively have a look at these really useful 4 blog posts: https://www.brimit.com/blog/sitecore-9-custom-marketing-automation-action Debugging your code There are a [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/">Debugging Sitecore Marketing automation</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Here are a few tips and tricks that should help if you want to start developing custom activities within the new Sitecore Marketing automation engine.</p>



<p><strong>The docs</strong></p>



<p>There is a pretty extensive guide on the Sitecore docs site: <a href="https://doc.sitecore.net/developers/xp/marketing-automation/activities/activity-types/create-an-activity-type.html" target="_blank">https://doc.sitecore.net/developers/xp/marketing-automation/activities/activity-types/create-an-activity-type.html</a></p>



<p>Alternatively have a look at these really useful 4 blog posts: <a href="https://www.brimit.com/blog/sitecore-9-custom-marketing-automation-action" target="_blank">https://www.brimit.com/blog/sitecore-9-custom-marketing-automation-action</a></p>



<p><strong>Debugging your code</strong></p>



<p>There are a few ways to run the engine &#8211; by default it gets installed as a windows service however if you navigate to:</p>



<p><strong>{xconnectdeployment}\App_data\jobs\continuous\AutomationEngine</strong> there is an exe (maengine.exe) you can run instead. Your code deployment will involve copying dll&#8217;s from your solution into that same folder.</p>



<p>To debug, run the console app and then attach to the <strong>maengine</strong> process within visual studio. When the plans run, and your activity is triggered, you should see breakpoints kick in. </p>



<p>If you want to make attaching to the engine simpler, in Visual Studio &#8216;<strong>Add existing project</strong>&#8216; => Select the <strong>maengine.exe</strong> on disk => Right click &#8216;<strong>Debug => Start new instance</strong>&#8216;</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="493" height="95" src="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-debug.png" alt="" class="wp-image-975" srcset="https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-debug.png 493w, https://blog.boro2g.co.uk/wp-content/uploads/2018/10/ma-debug-300x58.png 300w" sizes="(max-width: 493px) 100vw, 493px" /></figure>



<p><strong>Some developer tips</strong></p>



<p>If you are getting started and can&#8217;t seem to get your code to run, try setting up a very simple plan with a loose trigger. An example trigger, <strong>where the month is October</strong>. </p>



<p>Also, check the custom config is in place to link your custom code with the GUID of the new activity within Sitecore. This needs to live in  <br/><strong>{xconnectdeployment}</strong><strong>\App_data\jobs\continuous \AutomationEngine\App_Data\Config\sitecore\PatchFolder</strong>  &#8211; you can call the PatchFolder what you need.</p>



<p>And finally, if you want to see what Sitecore is storing under the hood when you save a plan, they live in <strong>/sitecore/system/Marketing Control Panel/Automation Plans</strong>. You can always un-bucket the folder to see each plan.</p>



<p></p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/">Debugging Sitecore Marketing automation</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/debugging-sitecore-marketing-automation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>$name in your Sitecore content</title>
		<link>https://blog.boro2g.co.uk/name-in-your-sitecore-content/</link>
					<comments>https://blog.boro2g.co.uk/name-in-your-sitecore-content/#comments</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Mon, 12 Mar 2012 12:05:33 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[$name]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=166</guid>

					<description><![CDATA[<p>One issue that seems to regularly occur in Sitecore builds is pages showing $name in the content. Its the sort of problem that seems to creep into projects the further through you get. Why does it happen? When you setup Sitecore templates they are typically built up from several other templates eg: A content page [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/name-in-your-sitecore-content/">$name in your Sitecore content</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>One issue that seems to regularly occur in Sitecore builds is pages showing $name in the content. Its the sort of problem that seems to creep into projects the further through you get.</p>
<p><strong>Why does it happen?</strong></p>
<p>When you setup Sitecore templates they are typically built up from several other templates eg:</p>
<ul>
<li>A content page is comprised from:</li>
<ul>
<li><em>Page Title</em> field section</li>
<li><em>Meta Data</em> field section</li>
<li>etc</li>
</ul>
</ul>
<p>Down the line you decide you want to add <em>&#8216;Page Content &#8211; (Header and Body fields)&#8217;</em> to all pages so you setup a new Field Section template along with corresponding fields and <em>__standard values</em>. So that new pages automatically push the item name to the Header field, you set the <em>__standard values</em> to contain $name.</p>
<p>All this gets published and you then come to check the front end of the site &#8211; pages created before adding the Page Content field section now have the new header and body fields but the header field shows $name <img src="https://s.w.org/images/core/emoji/15.0.3/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The reason being these fields are inheriting their value from <em>__standard values</em> &#8211; variables such as $name are processed when items are created. See <a title="http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/" href="http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/" target="_blank">http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/</a> for info on how to create custom replacement tokens. There is also more information on <a title="http://learnsitecore.cmsuniverse.net/en/Developers/Articles/2010/08/Standard-values-in-sitecore.aspx" href="http://learnsitecore.cmsuniverse.net/en/Developers/Articles/2010/08/Standard-values-in-sitecore.aspx" target="_blank">http://learnsitecore.cmsuniverse.net/en/Developers/Articles/2010/08/Standard-values-in-sitecore.aspx</a></p>
<p><strong>How to solve the problem?</strong></p>
<p>When items are created they are processed by a set of pipelines. An example of this is <em>expandInitialFieldValue </em>pipeline<em>.</em> Out the box, this makes use of  the <em>MasterVariablesReplacer. </em></p>
<p>You now have a couple options, either you can call the <em>MasterVariablesReplacer</em> for the problematic items or you could manually script the same functionality. The following code demonstrates the manual approach:</p><pre class="crayon-plain-tag">&amp;lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; %&amp;gt;

&amp;lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&amp;gt;

&amp;lt;%@ Import Namespace=&quot;Sitecore.Data.Items&quot; %&amp;gt;
&amp;lt;%@ Import Namespace=&quot;Sitecore.Data.Fields&quot; %&amp;gt;
&amp;lt;%@ Import Namespace=&quot;Sitecore.Data&quot; %&amp;gt;

&amp;lt;script runat=&quot;server&quot;&amp;gt;    

    public void FixNames_Click(object sender, EventArgs e)
    {
        //note, this doesn't error check the root guid is valid item
        Item root = Database.GetDatabase(&quot;master&quot;).GetItem(new ID(new Guid(RootIdTextBox.Text)));
        int fixes = 0;

        using (new Sitecore.SecurityModel.SecurityDisabler())
        {
            fixes = RecurseAndFix(root);
        }

        ResultsLiteral.Text = String.Format(&quot;&amp;lt;hr /&amp;gt;Fixed {0} cases of '$name'&quot;, fixes);
    }

    private int RecurseAndFix(Item root)
    {
        int fixes = 0;

        if (root.Template != null)
        {
            foreach (TemplateFieldItem field in root.Template.Fields)
            {
                Field existingField = root.Fields[field.ID];

                if (existingField != null)
                {
                    bool fixMe = false;

                    if (existingField.Value.Equals(&quot;$name&quot;))
                    {
                        fixMe = true;
                    }

                    if (existingField.ContainsStandardValue &amp;amp;&amp;amp; existingField.GetStandardValue().Equals(&quot;$name&quot;))
                    {
                        fixMe = true;
                    }

                    if (fixMe)
                    {
                        using (new EditContext(root))
                        {
                            existingField.Value = root.Name;
                            fixes++;
                        }
                    }
                }
                else
                {
                    if (root.Template.StandardValues[field.ID].Equals(&quot;$name&quot;))
                    {
                        using (new EditContext(root))
                        {
                            root[field.ID] = root.Name;
                            fixes++;
                        }
                    }
                }
            }
        }

        foreach (Item child in root.Children)
        {
            fixes += RecurseAndFix(child);
        }

        return fixes;
    }

&amp;lt;/script&amp;gt;

&amp;lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &amp;gt;
&amp;lt;head id=&quot;Head1&quot; runat=&quot;server&quot;&amp;gt;
    &amp;lt;title&amp;gt;'$name' Fixer &amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;form id=&quot;form1&quot; runat=&quot;server&quot;&amp;gt;
        &amp;lt;p&amp;gt;'$name' Fixer &amp;lt;/p&amp;gt;
        &amp;lt;p&amp;gt;
            Running the code on this page searches through all the content in the tree and replaces
            any '$name' values with the item's name.
        &amp;lt;/p&amp;gt;
        &amp;lt;h2&amp;gt;Note: Be careful, only run on content nodes and children and not templates!&amp;lt;/h2&amp;gt;
        &amp;lt;hr /&amp;gt;
        &amp;lt;div&amp;gt;
            Root id: &amp;lt;asp:TextBox runat=&quot;server&quot; ID=&quot;RootIdTextBox&quot; Width=&quot;600&quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;
            &amp;lt;asp:Button runat=&quot;server&quot; OnClick=&quot;FixNames_Click&quot; Text=&quot;Fix '$name'&quot; /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;asp:Literal runat=&quot;server&quot; ID=&quot;ResultsLiteral&quot; /&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;</pre><p>Its worth noting this can introduce some interesting challenges if Language Fallback is used on your site. The script above works fine for content items on a single language site. If you need similar functionality when language fallback is in place it may actually be meaningful to set $name = &#8221; for non-primary languages. This will ensure the fallback will occur correctly, rather than finding $name and thinking it is valid content.</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/name-in-your-sitecore-content/">$name in your Sitecore content</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/name-in-your-sitecore-content/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Common mistakes when programming with Sitecore pt1</title>
		<link>https://blog.boro2g.co.uk/common-mistakes-when-programming-with-sitecore-pt1/</link>
					<comments>https://blog.boro2g.co.uk/common-mistakes-when-programming-with-sitecore-pt1/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Thu, 23 Jun 2011 13:22:09 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[common mistakes]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=95</guid>

					<description><![CDATA[<p>The aim of this post is to highlight some pitfalls I have run into in the past when working with the Sitecore API. Hopefully some ideas demonstrated here will help people avoid some common mistakes when programming with Sitecore. Over time I&#8217;d like this list to grow so if anyone has any feedback or suggestions [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/common-mistakes-when-programming-with-sitecore-pt1/">Common mistakes when programming with Sitecore pt1</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The aim of this post is to highlight some pitfalls I have run into in the past when working with the Sitecore API. Hopefully some ideas demonstrated here will help people avoid some common mistakes when programming with Sitecore.</p>
<p>Over time I&#8217;d like this list to grow so if anyone has any feedback or suggestions for more items, please let me know.</p>
<p>For each item I will highlight some examples of where I have seen the mistakes and how they can best be avoided.</p>
<ol>
<li>Direct database access</li>
<li>Expensive content queries</li>
</ol>
<p><strong>1. Direct database access</strong><br />
There are several ways to get a reference to a Sitecore database. Note, these are defined within the config (&lt;databases&gt;). In the following example, the first 2 items get a specific database, the last the context database.</p><pre class="crayon-plain-tag">Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase(&quot;master&quot;);
Sitecore.Data.Database web = Sitecore.Configuration.Factory.GetDatabase(&quot;web&quot;);

Sitecore.Data.Database contextDatabase = Sitecore.Context.Database;</pre><p><strong><em>Why is this bad?</em></strong><br />
In larger Sitecore builds one of the common tasks is to run through the ideas stored in the following guides on the sdn: <a href="http://sdn.sitecore.net/reference/sitecore%206/security%20hardening%20guide.aspx">security hardening</a> and <a href="http://sdn.sitecore.net/developer/configuring%20production%20environments.aspx">configuring production environments</a>.</p>
<p>One of key steps in these documents is that the content delivery site only has a reference to the web database. Typically you would have an independent content authoring environment which has references to core, master and web. In this setup, if your code has a direct reference to master, you will get an exception since master doesnt exist.</p>
<p><strong><em>When might you want to do this?</em></strong><br />
It may be that in certain circumstances you do want to target a specific database. Consider an import routine. In this example you would want to ensure that new items are only added to master &#8211; note you would need to ensure the import routine is run from an environment which can access the master database.</p>
<p><strong>2. Expensive content queries</strong><br />
Sitecore.Data.Items.ItemAxes exposes a set of methods which can be used to drill up and down through the content tree. Some examples of this are:</p><pre class="crayon-plain-tag">namespace Sitecore.Data.Items
{
    // Summary:
    //     Provides access to other items relative to a source item.
    //
    // Remarks:
    //     Implements the Sitecore.Data.Items.Item.Axes property.
    //     You should never instantiate this class.
    public class ItemAxes
    {
        ...

        // Summary:
        //     Gets an ancestor item.
        //
        // Parameters:
        //   itemID:
        //     The item ID.
        //
        //   includeSelf:
        //     if set to true this instance is include self.
        //
        // Returns:
        //     The ancestor.
        public Item GetAncestor(ID itemID, bool includeSelf);
        
        // Summary:
        //     Gets all ancestors.
        //
        // Returns:
        //     The ancestors.
        public Item[] GetAncestors();
        //
        // Summary:
        //     Gets a child item.

        ...

        //
        // Summary:
        //     Gets a list of items that is in descendant axis of the source item.
        //
        // Returns:
        //     The descendants.
        public Item[] GetDescendants();            
    }
}</pre><p>Within your sublayouts you could then call eg:</p><pre class="crayon-plain-tag">Sitecore.Data.Items.Item[] descendants = Sitecore.Context.Item.Axes.GetDescendants();</pre><p><strong><em>Why is this bad?</em></strong><br />
If your content tree contains thousands of content items and you call GetDescendants from the root node &#8211; you will effectively be loading every single item in the tree &#8211; I can guarantee the bigger the tree, the slower this will go!</p>
<p><strong><em>When might you want to do this?</em></strong><br />
If you are comfortable that the result of a descendants call will expose a controlled set of nodes then you may find them more useful than querying direct children. An example of this is if folders are used in the structure you are querying.</p>
<p><strong><em>Where might you make this mistake?</em></strong><br />
A typical place I have seen this implemented is building footer navigation. Consider the following: &#8216;<em>A developer understands your template structure and sees there is a common base template for each page so adds a new checkbox &#8216;Show in footer navigation&#8217;. In the footer control they then start at the home node calling GetDescendants, checking each item for the new checkbox.</em>&#8216;</p>
<p><strong><em>What can I do instead?</em></strong><br />
In the footer example, try to consider alternative solutions for defining which items should be shown in the footer. How about a configuration area of the content tree where the footer navigation is defined as its own  node (and children if needed). Your descendants call could then target these specific items.</p>
<p>Other alternatives are using shallower axes for your queries for example: direct children or siblings.</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/common-mistakes-when-programming-with-sitecore-pt1/">Common mistakes when programming with Sitecore pt1</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/common-mistakes-when-programming-with-sitecore-pt1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Create a version of an item in all languages in the Sitecore client</title>
		<link>https://blog.boro2g.co.uk/create-a-version-of-an-item-in-all-languages-in-the-sitecore-client/</link>
					<comments>https://blog.boro2g.co.uk/create-a-version-of-an-item-in-all-languages-in-the-sitecore-client/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Fri, 17 Jun 2011 12:46:21 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=88</guid>

					<description><![CDATA[<p>This post aims to demonstrate how to add new versions for all languages if they dont exist in the cms. When you click buttons within the Sitecore client, typically Sitecore commands are used to map these actions to c# code. This link is defined in /App_Config/Commands.config. Some sample entries here are: [crayon-69b25614a7deb564143179/] If you want [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/create-a-version-of-an-item-in-all-languages-in-the-sitecore-client/">Create a version of an item in all languages in the Sitecore client</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This post aims to demonstrate how to add new versions for all languages if they dont exist in the cms.</p>
<p>When you click buttons within the Sitecore client, typically Sitecore commands are used to map these actions to c# code. This link is defined in /App_Config/Commands.config. Some sample entries here are:</p><pre class="crayon-plain-tag">&amp;lt;command name=&quot;item:addversion&quot; type=&quot;Sitecore.Shell.Framework.Commands.AddVersion,Sitecore.Kernel&quot; /&amp;gt;
&amp;lt;command name=&quot;item:archive&quot; type=&quot;Sitecore.Shell.Framework.Commands.Archive,Sitecore.Kernel&quot; /&amp;gt;</pre><p>If you want to add your own commands you can either edit this file or setup a patch file in /App_Config/Include. Note the patch file is the preferable option.</p>
<p>The code used for this example is:</p><pre class="crayon-plain-tag">using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Shell.Framework.Commands;
using Sitecore.Web.UI.Sheer;

namespace ###.Domain.Cms.Specialization.Shell.Framework.Commands
{
    /// &amp;lt;summary&amp;gt;
    /// Create a version of the current item in all languages
    /// &amp;lt;/summary&amp;gt;
    public class CreateVersionInAllLanguages : Command
    {
        public override void Execute(CommandContext context)
        {
            Assert.ArgumentNotNull(context, &quot;context&quot;);

            if (context.Items.Length == 1)
            {
                NameValueCollection parameters = new NameValueCollection();

                parameters[&quot;items&quot;] = base.SerializeItems(context.Items);

                Context.ClientPage.Start(this, &quot;Run&quot;, parameters);
            }
        }

        protected void Run(ClientPipelineArgs args)
        {
            Item item = base.DeserializeItems(args.Parameters[&quot;items&quot;])[0];

            if (item == null)
            {
                return;
            }

            IEnumerable&amp;lt;Language&amp;gt; languages = LanguageManager.GetLanguages(item.Database).Where(a =&amp;gt; a != item.Language);

            if (SheerResponse.CheckModified())
            {
                //prompt user they want to add versions
                if (args.IsPostBack)
                {
                    if (args.Result == &quot;yes&quot;)
                    {
                        foreach (Language language in languages)
                        {
                            Item localizedItem = item.Database.GetItem(item.ID, language);

                            //if Versions.Count == 0 then no entries exist in the given language
                            if (localizedItem.Versions.Count == 0)
                            {
                                localizedItem.Editing.BeginEdit();

                                localizedItem.Versions.AddVersion();

                                localizedItem.Editing.EndEdit();
                            }

                            Sitecore.Web.UI.HtmlControls.DataContext contentEditorDataContext = Sitecore.Context.ClientPage.FindControl(&quot;ContentEditorDataContext&quot;) as Sitecore.Web.UI.HtmlControls.DataContext;

                            contentEditorDataContext.SetFolder(item.Uri);
                        }
                    }
                }
                else
                {
                    StringBuilder builder = new StringBuilder();

                    builder.Append(&quot;Create version for each language?&quot;);                    

                    SheerResponse.Confirm(builder.ToString());

                    args.WaitForPostBack();
                }
            }
        }
    }
}</pre><p>This then needs to be added into the commands section of the config with the following patch file:</p><pre class="crayon-plain-tag">&amp;lt;configuration xmlns:patch=&quot;http://www.sitecore.net/xmlconfig/&quot;&amp;gt;
    &amp;lt;sitecore&amp;gt;
        &amp;lt;commands&amp;gt;
            &amp;lt;command name=&quot;item:addversiontoalllanguages&quot; type=&quot;###.Domain.Cms.Specialization.Shell.Framework.Commands.CreateVersionInAllLanguages,###.Domain.Cms&quot; /&amp;gt;
        &amp;lt;/commands&amp;gt;
    &amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;</pre><p>If you want this functionality available from a cms button, you need to wire up the button to the command. To do this, switch to the core database. </p>
<p>In this example we will add to the Language chunk of the ribbon (<em>/sitecore/content/Applications/Content Editor/Ribbons/Chunks/Language</em>). You need to create a new button and then setup the data section paying close attention to the Command field. This wants to be the same value as set in the patch file (item:addversiontoalllanguages).</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/create-a-version-of-an-item-in-all-languages-in-the-sitecore-client/">Create a version of an item in all languages in the Sitecore client</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/create-a-version-of-an-item-in-all-languages-in-the-sitecore-client/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Debugging Sitecore pipelines</title>
		<link>https://blog.boro2g.co.uk/debugging-sitecore-pipelines/</link>
					<comments>https://blog.boro2g.co.uk/debugging-sitecore-pipelines/#respond</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Thu, 16 Jun 2011 16:09:07 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[pipelines]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=84</guid>

					<description><![CDATA[<p>A quick tip for checking data flowing through the Sitecore pipelines is to setup empty processors and then move them sequentially through the required pipeline. An example for the pipeline: [crayon-69b25614a81af308352683/] Then add your debug point and dig into the args. Some example usage for checking which site has been resolved: [crayon-69b25614a81b5683873927/]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-pipelines/">Debugging Sitecore pipelines</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>A quick tip for checking data flowing through the Sitecore pipelines is to setup empty processors and then move them sequentially through the required pipeline.</p>
<p>An example for the <httpRequestBegin> pipeline:</p><pre class="crayon-plain-tag">using Sitecore.Pipelines.HttpRequest;

namespace ###.Domain.Cms.Specialization.Pipelines.HttpRequest
{
    public class PipelineDebugger : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            
        }
    }
}</pre><p>Then add your debug point and dig into the args.</p>
<p>Some example usage for checking which site has been resolved:</p><pre class="crayon-plain-tag">&amp;lt;processor type=&amp;quot;Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel&amp;quot; /&amp;gt;
&amp;lt;processor type=&amp;quot;###.Domain.Cms.Specialization.Pipelines.HttpRequest.PipelineDebugger, ###.Domain.Cms&amp;quot; /&amp;gt;
&amp;lt;processor type=&amp;quot;Sitecore.Pipelines.HttpRequest.UserResolver, Sitecore.Kernel&amp;quot; /&amp;gt;</pre><p></p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/debugging-sitecore-pipelines/">Debugging Sitecore pipelines</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/debugging-sitecore-pipelines/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Sitecore Gutters for updated presentation</title>
		<link>https://blog.boro2g.co.uk/sitecore-gutters-for-updated-presentation/</link>
					<comments>https://blog.boro2g.co.uk/sitecore-gutters-for-updated-presentation/#comments</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Thu, 16 Jun 2011 13:07:17 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[gutters]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=77</guid>

					<description><![CDATA[<p>Sitecore gutters are a great way of seeing quick summaries of content within the tree. Some existing gutter options include Locked Items, Workflow State, Missing Versions and more. These can be toggled by right clicking in the left column of the content editor. Its easy to build custom gutters &#8211; in the example above we [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/sitecore-gutters-for-updated-presentation/">Sitecore Gutters for updated presentation</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Sitecore gutters are a great way of seeing quick summaries of content within the tree. Some existing gutter options include Locked Items, Workflow State, Missing Versions and more. These can be toggled by right clicking in the left column of the content editor.</p>
<p><a href="http://blog.boro2g.co.uk/wp-content/uploads/2011/06/gutter-options.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-78" title="gutter-options" src="http://blog.boro2g.co.uk/wp-content/uploads/2011/06/gutter-options.png" alt="" width="139" height="205" /></a>Its easy to build custom gutters &#8211; in the example above we have a new item available &#8211; &#8216;Custom Presentation&#8217;. When this is active on an item it shows:</p>
<p><a href="http://blog.boro2g.co.uk/wp-content/uploads/2011/06/gutters.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-79" title="gutters" src="http://blog.boro2g.co.uk/wp-content/uploads/2011/06/gutters.jpg" alt="" width="284" height="64" /></a>Behind the scenes there is very little code to achieve this:</p><pre class="crayon-plain-tag">using System;
using System.Linq;
using ###.DataSource.Cms;
using Sitecore;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor.Gutters;

namespace ###.Domain.Cms.Specialization.Shell.Applications.ContentEditor.Gutters
{
    /// &lt;summary&gt;
    /// Shows icon if layout field on item doesnt use presentation value set on __StandardValues
    /// &lt;/summary&gt;
    public class PresentationGutter : GutterRenderer
    {
        protected override GutterIconDescriptor GetIconDescriptor(Item item)
        {
            Assert.ArgumentNotNull(item, &quot;item&quot;);

            Field layoutField = item.Fields[FieldIDs.LayoutField];

            //ItemKeys.Home is a hard coded Guid elswhere in the app
            if (layoutField == null || !item.Axes.GetAncestors().Any(a =&gt; a.ID.Guid == ItemKeys.Home))
            {
                return null;
            }

            if (!String.IsNullOrEmpty(layoutField.Value) &amp;&amp; !layoutField.ContainsStandardValue)
            {
                GutterIconDescriptor descriptor = new GutterIconDescriptor();

                descriptor.Icon = &quot;applications/16x16/document_into.png&quot;;

                descriptor.Tooltip = Translate.Text(&quot;Item doesn't have same presentation as standard values&quot;);

                return descriptor;
            }

            return null;
        }
    }
}</pre><p>Gutters then need to be added to the core database at &#8216;<em>/sitecore/content/Applications/Content Editor/Gutters</em>&#8216;</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/sitecore-gutters-for-updated-presentation/">Sitecore Gutters for updated presentation</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/sitecore-gutters-for-updated-presentation/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Setup custom Sitecore MediaProvider</title>
		<link>https://blog.boro2g.co.uk/setup-custom-sitecore-mediaprovider/</link>
					<comments>https://blog.boro2g.co.uk/setup-custom-sitecore-mediaprovider/#comments</comments>
		
		<dc:creator><![CDATA[boro]]></dc:creator>
		<pubDate>Thu, 16 Jun 2011 12:48:06 +0000</pubDate>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[MediaProvider]]></category>
		<category><![CDATA[sitecore]]></category>
		<guid isPermaLink="false">http://blog.boro2g.co.uk/?p=73</guid>

					<description><![CDATA[<p>One of Sitecore&#8217;s most useful features is the plug-ability of functionality via the configuration factory. Its very easy to add or update custom implementations where necessary. A typical programming model used throughout this is the Provider model &#8211; Membership, Roles, Item, Proxy&#8230; the list is endless. Unfortunately one provider thats not exposed in the config [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/setup-custom-sitecore-mediaprovider/">Setup custom Sitecore MediaProvider</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>One of Sitecore&#8217;s most useful features is the plug-ability of functionality via the configuration factory. Its very easy to add or update custom implementations where necessary.</p>
<p>A typical programming model used throughout this is the Provider model &#8211; Membership, Roles, Item, Proxy&#8230; the list is endless. Unfortunately one provider thats not exposed in the config factory is the MediaProvider.</p>
<p>No problem, thanks to some help from support they suggested a way to get around this, you can tap into the initialise pipeline. Here is the patch file to enable this:</p><pre class="crayon-plain-tag">&amp;lt;configuration xmlns:patch=&amp;quot;http://www.sitecore.net/xmlconfig/&amp;quot;&amp;gt;
  &amp;lt;sitecore&amp;gt;
    &amp;lt;pipelines&amp;gt;
      &amp;lt;initialize&amp;gt;
        &amp;lt;processor patch:after=&amp;quot;processor[@type='Sitecore.Pipelines.Loader.EnsureAnonymousUsers, Sitecore.Kernel']&amp;quot; type=&amp;quot;###.Domain.Cms.Specialization.Pipelines.Loader.InitializeMediaProvider, ###.Domain.Cms&amp;quot; /&amp;gt;
      &amp;lt;/initialize&amp;gt;
    &amp;lt;/pipelines&amp;gt;   
  &amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;</pre><p>This pipeline runs as the application intializes. Next you need the implementation of the pipeline processor:</p><pre class="crayon-plain-tag">using Sitecore.Diagnostics;
using Sitecore.Pipelines;
using Sitecore.Resources.Media;

namespace ###.Domain.Cms.Specialization.Pipelines.Loader
{
    /// &amp;lt;summary&amp;gt;
    /// Sets the Provider for Sitecore's MediaManager to a custom version.
    /// &amp;lt;/summary&amp;gt;
    public class InitializeMediaProvider
    {
        public void Process(PipelineArgs args)
        {
            Assert.IsNotNull(args, &amp;quot;args&amp;quot;);

            MediaManager.Provider = new ###.Domain.Cms.Specialization.Resources.Media.MediaProvider();
        }
    }
}</pre><p>And finally the custom implementation:</p><pre class="crayon-plain-tag">namespace ###.Domain.Cms.Specialization.Resources.Media
{
    public class MediaProvider : Sitecore.Resources.Media.MediaProvider
    {
        public override string GetMediaUrl(MediaItem item, MediaUrlOptions options)
        {
            ...
        }
    }
}</pre><p>Our customization allowed us to push certain media extensions to known file types.</p>
<p>The post <a rel="nofollow" href="https://blog.boro2g.co.uk/setup-custom-sitecore-mediaprovider/">Setup custom Sitecore MediaProvider</a> appeared first on <a rel="nofollow" href="https://blog.boro2g.co.uk">blog.boro2g .co.uk</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.boro2g.co.uk/setup-custom-sitecore-mediaprovider/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
