<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Elucid Labs</title> <link>https://world.optimizely.com/blogs/elucid-labs/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>The Significance of Sustainable Web Design: Utilizing Optimizely CMS for Environmental Responsibility</title>            <link>https://blog.paulmcgann.dev/2024/03/the-significance-of-sustainable-web.html</link>            <description>&lt;p&gt;In today&#39;s digital era, where online presence holds utmost importance, the concept of sustainable web design has emerged as a crucial consideration for organisations aiming to reduce their environmental impact. With platforms such as Optimizely CMS at their disposal, businesses have powerful tools to not only create captivating digital experiences but also to prioritise sustainability. Let&#39;s delve into how Optimizely CMS can aid in sustainable web design efforts and why it&#39;s imperative for organisations to embrace these practices.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;1. Grasping Sustainable Web Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Sustainable web design revolves around minimising the environmental footprint associated with websites and digital products. This entails optimising various aspects of web development and maintenance to lessen energy consumption, resource usage, and carbon emissions. Key elements of sustainable web design include efficient coding, optimised assets, renewable energy hosting, and minimalistic design principles.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;2. The Importance to Organisations:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Embracing sustainable web design with Optimizely CMS offers several benefits for organisations:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Efficiency and Performance:&lt;/b&gt; Optimizely CMS provides robust tools for optimising website performance, including content delivery networks (CDNs), caching mechanisms, and image optimisation features. By improving page load times and reducing server load, organisations can enhance energy efficiency and deliver better user experiences.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Content Management Efficiency:&lt;/b&gt; Optimizely CMS streamlines content management workflows, allowing organisations to efficiently create, update, and publish content. This reduces the time and resources required for website maintenance, resulting in lower energy consumption and operational costs.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Scalability and Flexibility:&lt;/b&gt; Optimizely CMS offers scalability and flexibility to accommodate changing business needs and traffic fluctuations. This ensures that organisations can efficiently scale their digital infrastructure without sacrificing sustainability or incurring unnecessary environmental impact.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Data-Driven Decision Making:&lt;/b&gt; Optimizely CMS provides robust analytics and testing capabilities, enabling organisations to make data-driven decisions to optimise website performance and user engagement. By leveraging insights from A/B testing, multivariate testing, and user behaviour analytics, organisations can refine their digital strategies to minimise environmental impact while maximising effectiveness.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;3. Utilising Optimizely CMS for Sustainable Web Design:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Organisations can leverage Optimizely CMS to implement sustainable web design practices in several ways:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Optimised Content Delivery:&lt;/b&gt; Utilise Optimizely CMS&#39;s built-in CDN capabilities to deliver content efficiently and reduce server load, minimising energy consumption and carbon emissions associated with content delivery.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Image and Asset Optimisation:&lt;/b&gt; Leverage Optimizely CMS&#39;s image optimisation features to compress images and other media files, reducing page load times and data transfer, and decreasing environmental impact.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Renewable Energy Hosting:&lt;/b&gt; Choose hosting providers for Optimizely CMS deployments that prioritise renewable energy sources and carbon neutrality, ensuring that the digital infrastructure aligns with sustainability goals.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Content Performance Optimisation:&lt;/b&gt; Use Optimizely CMS&#39;s analytics and testing tools to optimise content performance, improve user engagement, and reduce bounce rates, ultimately minimising environmental impact by maximising the efficiency of digital interactions.&lt;/p&gt;&lt;p&gt;In conclusion, Optimizely CMS empowers organisations to not only create exceptional digital experiences but also to prioritise sustainability and environmental responsibility. By leveraging Optimizely CMS&#39;s robust features and capabilities for sustainable web design, organisations can minimise their environmental footprint while delivering compelling digital experiences that drive business success.&lt;/p&gt;</description>            <guid>https://blog.paulmcgann.dev/2024/03/the-significance-of-sustainable-web.html</guid>            <pubDate>Tue, 02 Apr 2024 07:16:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Moving IIS URL Rewrite Rules to .NET Core: A Practical Guide</title>            <link>https://blog.paulmcgann.dev/2024/03/moving-iis-url-rewrite-rules-to-net.html</link>            <description>&lt;br /&gt;In the fast-paced world of web development, staying up-to-date with the latest technologies is crucial. As businesses evolve, so do their digital needs. One common challenge faced by developers is migrating URL rewrite rules from IIS (Internet Information Services) to .NET Core. If you&#39;re embarking on this journey, fear not! This guide will walk you through the process in a clear and practical manner.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Understanding the Basics&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URL rewriting plays a crucial role in managing web traffic and optimizing user experience. It involves intercepting incoming requests and redirecting them to different URLs based on predefined rules. In the IIS environment, these rules are typically configured in the web.config file. However, with .NET Core, URL rewriting is handled differently, using middleware within the application itself.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 1: Assess Your Current Setup&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Before diving into migration, it&#39;s essential to understand your existing URL rewrite rules configured in the web.config file. Take stock of each rule, noting down its pattern and rewrite destination.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 2: Install the Microsoft.AspNetCore.Rewrite Package&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To handle URL rewriting in .NET Core, you&#39;ll need to install the Microsoft.AspNetCore.Rewrite package. This can be done easily using the .NET CLI or NuGet Package Manager in Visual Studio.&lt;br /&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;
dotnet add package Microsoft.AspNetCore.Rewrite
&lt;/code&gt;&lt;/pre&gt;

&lt;br /&gt;&lt;b&gt;Step 3: Configure URL Rewriting Middleware&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Once the package is installed, you&#39;ll configure the URL rewriting middleware in the Startup.cs file of your .NET Core application.&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt; 
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Rewrite;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add any necessary services here
    }

    public void Configure(IApplicationBuilder app)
    {
        // Other middleware configurations

        using (StreamReader iisUrlRewriteStreamReader =
            File.OpenText(&quot;IISUrlRewrite.xml&quot;))
        {
            var options = new RewriteOptions()
               .AddIISUrlRewrite(iisUrlRewriteStreamReader);

            app.UseRewriter(options);
        }

        // Additional middleware configurations
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;b&gt;Step 4: Migrate URL Rewrite Rules&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now, it&#39;s time to migrate your existing URL rewrite rules from the web.config file to the IISUrlRewrite.xml file. You can keep the exisiting rewrite element with all your current iis rewrite rules in place, see the below.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEikduDTh1GlrFsDUVcYXekicOfjHh3HdnZeZ5-emlChsyEjj3NXMffkK9kyqLHJiRrnEv7cII7Br5yj-GPCdND45Wt46NqOoOX0PRU8hyfPMzqyGK1ly-lIUOa2wiIqFSIAZiCkSvRcWf-sp6i6xSXbiWCdyPhxv4taqpupQ8KQyQ4lhkC0qPhj-mx9oyE&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;502&quot; data-original-width=&quot;1857&quot; height=&quot;157&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEikduDTh1GlrFsDUVcYXekicOfjHh3HdnZeZ5-emlChsyEjj3NXMffkK9kyqLHJiRrnEv7cII7Br5yj-GPCdND45Wt46NqOoOX0PRU8hyfPMzqyGK1ly-lIUOa2wiIqFSIAZiCkSvRcWf-sp6i6xSXbiWCdyPhxv4taqpupQ8KQyQ4lhkC0qPhj-mx9oyE=w578-h157&quot; width=&quot;578&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;

&lt;br /&gt;&lt;b&gt;Step 5: Test and Iterate&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;After migrating your rules, thorough testing is essential. Verify that all URLs are being rewritten / redirected correctly without any unexpected redirects or errors.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Migrating URL rewrite rules from IIS web.config to .NET Core as part of an CMS 12 upgrade may seem daunting, but with proper guidance, it can be a smooth transition. By following the steps outlined in this guide, you can ensure that your application&#39;s URL rewriting functionality remains intact while embracing the capabilities of .NET Core.&lt;br /&gt;&lt;br /&gt;Remember, migration is an opportunity to optimize and improve your application for the future. So, embrace the change, and happy migrating!&lt;/div&gt;</description>            <guid>https://blog.paulmcgann.dev/2024/03/moving-iis-url-rewrite-rules-to-net.html</guid>            <pubDate>Tue, 12 Mar 2024 21:56:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>HTTP/3: Fast and Secure</title>            <link>https://blog.paulmcgann.dev/2023/07/http3-fast-and-secure.html</link>            <description>&lt;h1 style=&quot;text-align: left;&quot;&gt;HTTP/3 with Optimizely DXP&lt;/h1&gt;&lt;p&gt;In the ever-evolving landscape of web technologies, HTTP/3 emerges as a significant advancement, promising faster and more secure communication between clients and servers. As a solution architect, it&#39;s essential to stay up-to-date with the latest protocols and understand their implications. In this blog post, we will explore what HTTP/3 is, why it is important, and when we can expect its widespread availability.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;What is HTTP/3?&lt;/h3&gt;&lt;p&gt;HTTP/3, also known as Hypertext Transfer Protocol version 3, is the next generation of the HTTP protocol. It is being developed to address the limitations and challenges faced by its predecessor, HTTP/2. HTTP/3 is designed to improve the efficiency of web communications by utilizing the User Datagram Protocol (UDP) instead of TCP (Transmission Control Protocol).&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;The Importance of HTTP/3:&lt;/h3&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Enhanced Performance: HTTP/3 leverages the QUIC (Quick UDP Internet Connections) transport protocol, which significantly improves performance. QUIC allows for lower latency and reduced connection setup time, leading to faster loading times for web pages and improved overall browsing experience.&lt;/li&gt;&lt;li&gt;Improved Security: HTTP/3 incorporates encryption as a fundamental part of the protocol. This means that data sent using HTTP/3 is encrypted by default, enhancing security and privacy for users. Additionally, the use of QUIC&#39;s built-in encryption makes it more resistant to certain types of attacks compared to previous versions of HTTP.&lt;/li&gt;&lt;li&gt;Network-Friendly: UDP-based communication used in HTTP/3 ensures better network utilization by reducing the head-of-line blocking problem. This issue often occurs with TCP, where a packet delay or loss can affect the delivery of subsequent packets. HTTP/3&#39;s QUIC protocol eliminates this problem, allowing for parallel request and response multiplexing.&lt;/li&gt;&lt;li&gt;Seamless Migration: HTTP/3 maintains backward compatibility with previous versions of the HTTP protocol, making it easier for developers to transition their applications. Existing websites and APIs can gradually adopt HTTP/3 without requiring significant changes to the underlying infrastructure.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;When will HTTP/3 be available?&lt;/h3&gt;&lt;p&gt;HTTP/3 is still in development and actively being deployed by several organizations. However, its widespread availability depends on multiple factors, including browser and server support. As of the time of writing, several major browsers, including Chrome, Firefox, and Edge, have experimental support for HTTP/3. Cloudflare has added support for HTTP/3 and you can easily switch it on, below are some steps on how to achieve this.&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Get started using HTTP/3&lt;/h3&gt;&lt;p&gt;HTTP/3 is set to revolutionize the web with its improved performance, enhanced security, and better network utilization. As solution architects, it&#39;s important to familiarize ourselves with this evolving protocol to leverage its benefits for our clients and users. While HTTP/3 is not widely available just yet, you can start to experiment with HTTP/3 by &lt;a href=&quot;https://caniuse.com/?search=http%2F3&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;enabling &lt;/a&gt;this in the three most major browsers.&lt;/p&gt;&lt;p&gt;Enabling HTTP/3 in Cloudflare involves a few straightforward steps. Here&#39;s a guide on how to enable HTTP/3 for your website:&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Log in to your Cloudflare account: Access your Cloudflare account by visiting the Cloudflare website and entering your credentials.&lt;/li&gt;&lt;li&gt;Select your domain: Once logged in, select the domain for which you want to enable HTTP/3. This will open the dashboard for that particular domain.&lt;/li&gt;&lt;li&gt;Go to the &quot;Network&quot; tab: In the Cloudflare dashboard, navigate to the &quot;Network&quot; tab located at the top of the page. Click on it to access the network settings for your domain.&lt;/li&gt;&lt;li&gt;Enable HTTP/3: Within the &quot;Network&quot; tab, scroll down until you find the &quot;HTTP/3&quot; section. Toggle the switch to enable HTTP/3 for your domain.&lt;/li&gt;&lt;li&gt;Save and deploy changes: After enabling HTTP/3, click on the &quot;Save&quot; or &quot;Deploy&quot; button (the exact wording may vary) to save your changes and apply them to your domain.&lt;/li&gt;&lt;li&gt;Verify HTTP/3 activation: Once you have enabled HTTP/3, you can verify its activation by visiting your website and checking the network tab in your browser&#39;s developer tools. Look for the protocol being used for your website&#39;s requests. If it shows &quot;h3&quot; or &quot;quic&quot; instead of &quot;http/1.1&quot; or &quot;http/2,&quot; it means HTTP/3 is successfully enabled.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Please note that enabling HTTP/3 in Cloudflare relies on the browser and client support for HTTP/3. While major browsers have support for HTTP/3, not all clients may be compatible at the time of implementation. Cloudflare automatically negotiates the best protocol available between the client and their servers, falling back to HTTP/2 or HTTP/1.1 if HTTP/3 is not supported.&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Optimizely DXP Support HTTP/3&lt;/h2&gt;&lt;p&gt;It is worth noting at the time of writing I reached out to Optimizely to see if it is possible to switch on / enable HTTP/3 in the DXP environment. Optimizely&amp;nbsp; have advised that currently HTTP/3 is not supported in DXP and due to this they won&#39;t activate in cloudflare.&lt;/p&gt;&lt;p&gt;They did however suggest that I raise a feature request and the team will consider this in future developments.&lt;/p&gt;&lt;p&gt;I had a quick check of the feature requests first before creating a duplicate request and I found this has already been request. If you too would like this feature implemented I would suggest you vote for &lt;a href=&quot;https://feedback.optimizely.com/ideas/DXCS-I-407&quot; target=&quot;_blank&quot;&gt;this request.&lt;/a&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Conclusion&lt;/h2&gt;&lt;p&gt;In conclusion, HTTP/3 presents a significant advancement in web communication, offering improved performance, enhanced security, and better network utilization. As solution architects, it&#39;s crucial for us to understand the implications of this evolving protocol and leverage its benefits for our clients and users. While HTTP/3 is still being developed and its widespread availability depends on browser and server support, it is possible to start experimenting with HTTP/3 in Cloudflare.&lt;/p&gt;&lt;p&gt;Enabling HTTP/3 in Cloudflare involves straightforward steps outlined in the blog post. However, it&#39;s important to note that at the time of writing, Optimizely DXP does not support HTTP/3 in its environment. The Optimizely team suggests raising a feature request and encourages users to vote for its implementation.&lt;/p&gt;&lt;p&gt;As HTTP/3 continues to gain traction and more organizations adopt it, we can anticipate a future where faster, more secure, and efficient web communications become the norm. By staying informed and actively exploring the possibilities of HTTP/3, we can position ourselves as forward-thinking solution architects ready to embrace the future of web technologies.&lt;/p&gt;</description>            <guid>https://blog.paulmcgann.dev/2023/07/http3-fast-and-secure.html</guid>            <pubDate>Sun, 09 Jul 2023 20:31:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Optimizely DXP Image Optimization</title>            <link>https://dev.to/paulmcgann/optimizely-dxp-image-optimization-2ip</link>            <description>&lt;p&gt;Optimizely DXP is a cloud-first approach to customer engagement including high availability and performance, easy connectivity with other cloud services and existing systems, ability to manage spikes in customer demand, and a platform that is ready to seamlessly adopt the latest technology updates. &lt;/p&gt;

&lt;p&gt;Optimizely DXP also includes a Content Delivery Network provided by Cloudflare for performance and security optimization.&lt;/p&gt;

&lt;p&gt;I want to focus upon the optimization side of Cloudflare, more specifically image optimization.&lt;/p&gt;

&lt;p&gt;Cloudflare has 3 products to help with image optimization, Cloudflare Image, Cloudflare Image Resizing, Cloudflare Polish. For the purpose of this post I will focus on Cloudflare Polish as this is enabled by default in Optimizely DXP, you can read more about the other products &lt;a href=&quot;https://developers.cloudflare.com/images/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cloudflare polish automatically optimizes images upon your site whenever is is fetched from you site.&lt;/p&gt;

&lt;p&gt;Whenever you make the first request to retrieve and image you will notice within the headers the &#39;cf-cache-status&#39; will be set to &#39;MISS&#39;. Cloudflare is telling us it tried to retrieve the image from cache, however it did not find it and so requested it from the origin.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--iqsh8dCJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6maq87yai5g399j4tqar.PNG&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--iqsh8dCJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6maq87yai5g399j4tqar.PNG&quot; alt=&quot;Cloudflare CF-Cache-Status MISS&quot; width=&quot;836&quot; height=&quot;422&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you were to wait a few seconds and refresh the image you will notice that the &#39;cf-cache-status&#39; is now &#39;HIT&#39;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--dFw_wBGl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mfhvfo6uqhmh2ni2siq.PNG&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--dFw_wBGl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8mfhvfo6uqhmh2ni2siq.PNG&quot; alt=&quot;Cloudflare CF-Cache-Status HIT&quot; width=&quot;839&quot; height=&quot;558&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To confirm that Polish has been applied we can check the &#39;cf-bgj&#39; header returns the image quality setting &#39;imgq&#39;. We can also check the &#39;cf-polished&#39; header to confirm Polish status and returns the image quality setting (qual) and original size (origSize). &lt;/p&gt;

&lt;p&gt;The above headers can confirm that polish is working working, however we can do better and ensure that images are being served in next generation format. To do this we can review the &#39;content-type&#39; header and ensure this is returning &#39;image/webp&#39;, comparing this to the &#39;cf-polished&#39; original format (origFmt) we can see the original format of the image was png and has been converted to webp.&lt;/p&gt;

&lt;p&gt;While Cloudflare Polish automatically optimizes images, it will only optimize the image if the webp image is smaller than the original image.&lt;/p&gt;

&lt;p&gt;If we review the below &#39;cf-polished&#39; header below. We can see the status is set to &#39;webp_bigger&#39; this is informing us that the image optimization on this image would provide no benefit.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--QddeN_83--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9lq4jzcyb0cou8shqorc.PNG&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--QddeN_83--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9lq4jzcyb0cou8shqorc.PNG&quot; alt=&quot;No Compression&quot; width=&quot;841&quot; height=&quot;494&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully someone else finds this information useful. If you have any questions please drop a comment below.&lt;/p&gt;

</description>            <guid>https://dev.to/paulmcgann/optimizely-dxp-image-optimization-2ip</guid>            <pubDate>Tue, 16 Nov 2021 21:04:51 GMT</pubDate>           <category>Blog post</category></item><item> <title>Working with Optimizely Projects</title>            <link>https://dev.to/paulmcgann/working-with-optimizely-projects-2ojn</link>            <description>&lt;p&gt;Optimizely has a featured called &lt;a href=&quot;https://world.optimizely.com/documentation/developer-guides/CMS/projects/&quot;&gt;&#39;Projects&#39;&lt;/a&gt;, which allows editors to collaborate on content before scheduling to publish.&lt;/p&gt;

&lt;h3&gt;
  &lt;a href=&quot;#problem&quot;&gt;
  &lt;/a&gt;
  Problem
&lt;/h3&gt;

&lt;p&gt;While work on a project that imports hundreds, of pieces of content. These pieces of content are added to a project for the team to review and mark the items as ready to publish.&lt;/p&gt;

&lt;p&gt;You can see the problem here in that with hundreds of pieces of content to review, marking each content piece as ready to publish could take some time.&lt;/p&gt;

&lt;h3&gt;
  &lt;a href=&quot;#solution&quot;&gt;
  &lt;/a&gt;
  Solution
&lt;/h3&gt;

&lt;p&gt;To over come the problem we decided to create a scheduled job that would loop over all items in a project and mark them as ready to publish.&lt;/p&gt;

&lt;p&gt;To retrieve the projects and their project items we can get an instance of the &#39;ProjectRepository&#39; into our scheduled job.&lt;/p&gt;

&lt;p&gt;Once we have the project and its items we can then loop over the project items and use the &#39;IContentChangeManager&#39; interface to update the status of the content items.&lt;br /&gt;
&lt;/p&gt;

&lt;div class=&quot;highlight js-code-highlight&quot;&gt;
&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projects&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_projectRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;project&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItemIds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_projectRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ListItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItemId&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItemIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ProjectItem&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItem&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetProjectItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectItemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectItem&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CommitResult&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;commitResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contentChangeManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Commit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentLink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SaveAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CheckIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProjectItem&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetProjectItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_projectRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectItemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I just wanted to share this piece of code with anyone who was trying to achieve something similiar.&lt;/p&gt;

</description>            <guid>https://dev.to/paulmcgann/working-with-optimizely-projects-2ojn</guid>            <pubDate>Fri, 05 Nov 2021 11:38:32 GMT</pubDate>           <category>Blog post</category></item><item> <title>Translate Categories in Episerver using DbLocalizationProvider</title>            <link>https://dev.to/paulmcgann/translate-categories-in-episerver-using-dblocalizationprovider-3c9d</link>            <description>&lt;p&gt;While doing some investigation into localization with Episerver I came across a useful library that helps content editors easily translate resources that are normally stored in xml, by storing them within a database.&lt;/p&gt;

&lt;p&gt;One of the areas that I investigated was translating the built in categories within Episerver. This is possible to do using a strongly-typed &lt;a href=&quot;https://github.com/valdisiljuconoks/localization-provider-epi/blob/master/docs/working-with-resources-epi.md#translating-episerver-categories&quot;&gt;category definition&lt;/a&gt;.&lt;br /&gt;
&lt;/p&gt;

&lt;div class=&quot;highlight js-code-highlight&quot;&gt;
&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocalizedCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SampleCategory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Category&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SampleCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This is sample cat. from code&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may be suitable in some cases, however in some scenarios where the categories already exist this may not be the best course of action.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/valdisiljuconoks/localization-provider-epi/blob/master/README.md&quot;&gt;DbLocalizationProvider&lt;/a&gt; has a way to &lt;a href=&quot;https://github.com/valdisiljuconoks/LocalizationProvider/blob/master/docs/sync-net.md#register-manually-resources&quot;&gt;manually create resources&lt;/a&gt;. Using this I set about creating a resource manually for each category.&lt;/p&gt;

&lt;p&gt;Each resource needs a unique resource key, the translation /value and the language the translation is for.&lt;/p&gt;

&lt;p&gt;In order to create each resource I used a stored procedure that would iterate over the categories and build out a unique resource key, whilst assigning the value and language.&lt;br /&gt;
&lt;/p&gt;

&lt;div class=&quot;highlight js-code-highlight&quot;&gt;
&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DbLocalizationProvider.Sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;EPiServer.DataAbstraction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;EPiServer.PlugIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;EPiServer.Scheduler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Globalization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Linq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;LangTransaltion.Business.Localization&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ScheduledPlugIn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DisplayName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Category Localization Scheduled Job&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CategoryLocalizationScheduledJob&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ScheduledJobBase&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CategoryRepository&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_categoryRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ISynchronizer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_synchronizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_stopSignaled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_categoryCounterTotal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ManualResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_allCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CategoryLocalizationScheduledJob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CategoryRepository&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ISynchronizer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;synchronizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IsStoppable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_categoryRepository&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_synchronizer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;synchronizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// Called when a user clicks on Stop for a manually started job, or when ASP.NET shuts down.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_stopSignaled&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// Called when a scheduled job executes&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;returns&amp;gt;A status message to be stored in the database log and visible from admin mode&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;OnStatusChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$&quot;Starting execution of &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;_allCategories&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ManualResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_categoryRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;nf&quot;&gt;IterateCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;Categories.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;_synchronizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RegisterManually&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_allCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_categoryCounterTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; categories checked&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// Iterates over categories build a unique key&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;currentParent&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;path&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IterateCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentParent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentParent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;category&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_stopSignaled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;_categoryCounterTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;

                &lt;span class=&quot;nf&quot;&gt;OnStatusChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$&quot;Working on category &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, child of: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentParent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;_allCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ManualResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CultureInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)));&lt;/span&gt;

                &lt;span class=&quot;nf&quot;&gt;IterateCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the scheduled job the new resources will be added to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--aMBDwMPl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/knqhifult9weu0oghnht.PNG&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/practicaldev/image/fetch/s--aMBDwMPl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/knqhifult9weu0oghnht.PNG&quot; alt=&quot;DbLocalizationProvider&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final piece of the puzzle was to retrieve the resource key whenever we use the category on the site. In order to do this I created an extension method to return the resource key based on the current category.&lt;br /&gt;
&lt;/p&gt;

&lt;div class=&quot;highlight js-code-highlight&quot;&gt;
&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;EPiServer.DataAbstraction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;LangTransaltion.Helpers&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CategoryHelper&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// Gets the category resource key.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;category&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetResourceKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

            &lt;span class=&quot;nf&quot;&gt;GetParentCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resourceKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;Categories.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resourceKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// Gets the parent categories, starting a from a root category.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;currentCategory&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;categoryList&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetParentCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;currentCategory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

                &lt;span class=&quot;nf&quot;&gt;GetParentCategories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;categoryList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when you are using a category and wish to retrieve the translation you can simply use&lt;br /&gt;
&lt;/p&gt;

&lt;div class=&quot;highlight js-code-highlight&quot;&gt;
&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DbLocalizationProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocalizationProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetResourceKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would like to thank the &lt;a href=&quot;https://twitter.com/tech_fellow&quot;&gt;Valdis Iljuconoks&lt;/a&gt; for helping me out and answering some questions I had along the way.&lt;/p&gt;

</description>            <guid>https://dev.to/paulmcgann/translate-categories-in-episerver-using-dblocalizationprovider-3c9d</guid>            <pubDate>Thu, 21 Jan 2021 20:52:53 GMT</pubDate>           <category>Blog post</category></item><item> <title>Episerver Visitor Group Configuration</title>            <link>http://spottyslug.wordpress.com/?p=2</link>            <description>Configuring episerver visitor groups geolocation criteria.</description>            <guid>http://spottyslug.wordpress.com/?p=2</guid>            <pubDate>Tue, 11 Dec 2018 11:58:22 GMT</pubDate>           <category>Blog post</category></item><item> <title>Episerver Visitor Group Configuration</title>            <link>http://spottyslug.wordpress.com/?p=2</link>            <description>Configuring episerver visitor groups geolocation criteria.</description>            <guid>http://spottyslug.wordpress.com/?p=2</guid>            <pubDate>Tue, 11 Dec 2018 10:58:22 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>