<?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 Per Nergård</title> <link>https://world.optimizely.com/blogs/Per-Nergard/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>Scheduled job for deleting content types and all related content</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-for-deleting-content-types-and-all-related-content/</link>            <description>&lt;p&gt;In my previous blog post which was about getting an overview of your sites content &lt;a href=&quot;/link/e89ad1059bc047499d1ed92fe36b1726.aspx&quot;&gt;https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-for-getting-overview-of-site-content-usage/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I actually found a couple of content types that was related to decomission functionality that actually hade quite a lot of created content. So what to do? ContentTypeObliteratorScheduledJob to the rescue.&lt;br /&gt;&lt;br /&gt;It&#39;s very simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get the contenttype ids you want to remove all content for and deleting the actual content type as well.&lt;/li&gt;
&lt;li&gt;Take a database backup&lt;/li&gt;
&lt;li&gt;Add the contenttype ids into a comma separated list&lt;/li&gt;
&lt;li&gt;Run the job and enjoy less code and a less bloated content tree.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have only done a test run on one content type but for that it worked.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Link to my Gist: &lt;a title=&quot;Gist link to the ContenttypeObliteratorScheduledJob&quot; href=&quot;https://gist.github.com/PNergard/818677955ae0e2c933f30a3186e0fe37&quot;&gt;ContentTypeObliteratorScheduledJob&lt;/a&gt;.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-for-deleting-content-types-and-all-related-content/</guid>            <pubDate>Fri, 30 Jan 2026 13:09:03 GMT</pubDate>           <category>Blog post</category></item><item> <title>ScheduledJob for getting overview of site content usage</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-for-getting-overview-of-site-content-usage/</link>            <description>&lt;p&gt;In one of my current project which we are going to upgrade from Optimizely 11 I needed to get an overview of the content and which content types we have, are some unused etc.&lt;/p&gt;
&lt;p&gt;In order to do that I did a scheduled job that will go through the sites content types, check for usage and if a content type id is specified render links to edit mode for all content instances for that type.&lt;/p&gt;
&lt;p&gt;Everything is wrapped up into a CSV file that are easily imported into excell for easy filtering and send that as an attached file via SMTP.&lt;br /&gt;&lt;br /&gt;In the code you can change sender, recipients and after an initial run and you also want to get the links to the content instances for one or more content types that can be set as well.&lt;br /&gt;&lt;br /&gt;The collumns you get is the following:&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;/link/2d7cd960b8a64d3b87e165ef09d482bd.aspx&quot; alt=&quot;&quot; width=&quot;1731&quot; height=&quot;36&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I expected some content types with zero content instances but to my suprise the number was bigger than I expected.&lt;br /&gt;&lt;br /&gt;Nothing advanced but a simple way to identify content types that could be removed or find all instances of a content type that you might be able to remove after you actually check the content.&lt;br /&gt;&lt;br /&gt;You can find the content over at my gist. &lt;a title=&quot;Link to tool gist&quot; href=&quot;https://gist.github.com/PNergard/f3e2e363bbee0e9c1781348de1550b8a&quot;&gt;ScheduledJob content usage Gist&lt;/a&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-for-getting-overview-of-site-content-usage/</guid>            <pubDate>Tue, 27 Jan 2026 22:47:29 GMT</pubDate>           <category>Blog post</category></item><item> <title>ScheduledJob overview Blazor component</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-overview-blazor-component/</link>            <description>&lt;p&gt;I have always felt that the admin UI for scheduled jobs in Optimizely is harder to use than it needs to be. To check a job you have to go into admin, filter to find the right job, click to see the history, and then click again to view status messages. When you are troubleshooting, this quickly becomes frustrating.&lt;/p&gt;
&lt;p&gt;Back in 2017 I tried to improve this by creating a small plugin for viewing scheduled job run history. I wrote about it here:&lt;br /&gt;&lt;a class=&quot;decorated-link&quot; href=&quot;/link/1bd5f39a76cf4152b8bd1054b27f99e9.aspx&quot;&gt;https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/9/plugin-for-viewing-scheduled-job-run-history/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;During the Christmas break I decided to revisit the idea. The result is a Blazor component that gives a better overview of scheduled jobs and their status messages, with fewer clicks and faster access to the information you usually care about. I am using MudBlazor for UI components.&amp;nbsp; It&#39;s a Razor Class Library so you need to configure Blazor in you CMS solution and see that the MudBlazor css and js are loaded.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The component includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Separate tabs for custom jobs and built-in jobs, since custom jobs are often the ones causing issues&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Filtering on job names&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Direct access to the latest run and status message when selecting a job&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A list view of up to 1000 status message excerpts with keyword filtering&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Drill-down into a specific status message with additional filtering&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Image 1: Overview of the component.&lt;br /&gt;&lt;img src=&quot;/link/6e9aa90e7cdb4d389a044d29889ae04a.aspx&quot; alt=&quot;&quot; width=&quot;1242&quot; height=&quot;418&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Image 2: A selected job showing all status messages.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/61d90647a4e04383ab98a2c5cf4c4181.aspx&quot; alt=&quot;&quot; width=&quot;1248&quot; height=&quot;565&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Image 3: Drill-down view of a single status message with filtering.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/91173c34077645e6ac19714cc1eca483.aspx&quot; alt=&quot;&quot; width=&quot;1255&quot; height=&quot;565&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The full source code is available in a public GitHub repository:&lt;/p&gt;
&lt;p&gt;https://github.com/PNergard/ScheduledJob-overview-Blazor-component&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/scheduledjob-overview-blazor-component/</guid>            <pubDate>Thu, 15 Jan 2026 15:21:39 GMT</pubDate>           <category>Blog post</category></item><item> <title>PageCriteriaQueryService builder with Blazor and MudBlazor</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/2/dynamic-pagecriteriaqueryservice-builder-with-blazor-and-mudblazor/</link>            <description>&lt;p&gt;This might be a stupid idea but my new years resolution was to do / test more stuff so here goes. This razor component allows users to build and execute queries against your CMS site, providing a semi user-friendly interface for searching for pages based on content type, properties.&lt;br /&gt;&lt;br /&gt;You do need to have knowledge about your content types and the data but the thought is that when the need arises to identify what pages / how many pages you have with a certain combination of data you should be able to find those without any coding. If the results are not that many maybe manually editing them and adjusting what is needed is enough. If the number is to high or more complex changes needs to be performed a action-button can be added to do the work instead of possible doing a scheduled job or something.&lt;br /&gt;&lt;br /&gt;You can find the code over at my &lt;a href=&quot;https://gist.github.com/PNergard/31e8ab4ad39ddb2bfc123fc4d540ad64&quot;&gt;Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Criteria:&lt;/strong&gt;&lt;br /&gt;So you can create criteria parameters based on content type , propertes and condition and make them required or not. Required parameters will be shown in green.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Search:&lt;/strong&gt;&lt;br /&gt;When youre happy with your criterias you select a startnode (Root or any of the defined sites) and hit search. If you are not happy with the results you can delete individual parameters or all.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Results:&lt;/strong&gt;&lt;br /&gt;Simple list with a link to edit mode for each content that opens in a new tab.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Actions:&lt;/strong&gt;&lt;br /&gt;I actually haven&#39;t implemented any actions. But the idea is that it&#39;s easy to add any action need to perform actions on the search result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Looks like this:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;img src=&quot;/link/fd7c2b688d67403eba3c505ce978a8dd.aspx&quot; alt=&quot;&quot; width=&quot;1018&quot; height=&quot;449&quot; /&gt;&lt;/strong&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/2/dynamic-pagecriteriaqueryservice-builder-with-blazor-and-mudblazor/</guid>            <pubDate>Mon, 10 Feb 2025 09:59:23 GMT</pubDate>           <category>Blog post</category></item><item> <title>Content statistics Blazor component</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/content-statistics-blazor-components/</link>            <description>&lt;p&gt;Another week and another MudBlazor component to explore. I wanted to test the charts components so I created a small Blazor component that displays som charts based on information we can get from the pages of a site.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How many pages are created / updated on a monthly basis&lt;/li&gt;
&lt;li&gt;Whats the most used content type&lt;/li&gt;
&lt;li&gt;When are pages created during the day&lt;/li&gt;
&lt;li&gt;When are pages being updated during the day&lt;/li&gt;
&lt;li&gt;Who is the most productive content creator&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not life changing stuff but could be a bit fun to get an overview. Code over at my &lt;a href=&quot;https://gist.github.com/PNergard/85b2417ecf3b64c069623b340edae10a&quot;&gt;Gist&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Looks like this in a Alloy solution:&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;/link/f0dedefc578a476eb6aea1a73faa58f1.aspx&quot; alt=&quot;&quot; width=&quot;609&quot; height=&quot;303&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/content-statistics-blazor-components/</guid>            <pubDate>Tue, 28 Jan 2025 13:54:43 GMT</pubDate>           <category>Blog post</category></item><item> <title>Find and delete non used media and blocks</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/find-and-delete-non-used-media-and-blocks/</link>            <description>&lt;p&gt;On my new quest to play around with Blazor and MudBlazor I&#39;m going back memory lane and porting some previously plugins. So this time up is my plugin for finding non used images in the global assets folder and you can read the old blog post from 2017 over &lt;a href=&quot;/link/127945d0edab4aa2aeafde6581e907e6.aspx&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I decided I wanted to update it a bit so it could look for blocks as well. It&#39;s not that much to tell about it but you can choose if you want to look for media and / or blocks and look for orphans and then optionally delete selected or all.&lt;/p&gt;
&lt;p&gt;You can grab the code over at my &lt;a href=&quot;https://gist.github.com/PNergard/704913111bed24b6a9fdc11fe18f4567&quot;&gt;Gist.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have in my tests used the component in a page type I have setup for Blazor testing but if you want to have it as a plugin have a look at Ove Lartelius excellent post about how to run you components in different areas of the Optimizely UI &lt;a href=&quot;https://www.epinova.se/en/blog/2024/use-blazor-components-in-optimizely-cms-adminedit-interface/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And it looks like this&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/1185ebe3f615426cb749edf4a98b8432.aspx&quot; alt=&quot;&quot; width=&quot;878&quot; height=&quot;490&quot; /&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/find-and-delete-non-used-media-and-blocks/</guid>            <pubDate>Tue, 21 Jan 2025 07:43:26 GMT</pubDate>           <category>Blog post</category></item><item> <title>Order tabs with drag and drop - Blazor</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/order-tabs-with-drag-and-drop---revisited/</link>            <description>&lt;p&gt;I have started to play around a little with Blazor and the best way to learn is to reimplement some old stuff for CMS12.&lt;/p&gt;
&lt;p&gt;So I took a look at my old blog posts and decided to redo my plugin for drag and drop sorting of tabs since I still don&#39;t like that using the [GroupDefinition] attribute forces you do manage the index order in code. &lt;a href=&quot;/link/5a6818bd02074b9ea8473dd0ef5711f3.aspx&quot;&gt;Old blog post here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My thought with this Blazor component is to have a tools content type with it&#39;s own layout which is only for tools and stuff done with Blazor. If feels easier than doing menuproviders or plugins in admin mode.&lt;/p&gt;
&lt;p&gt;It&#39;s very simple, just a list of the tabs which you can reorder with drang and drop and then save or reset (only currently unsaved order). In the example it&#39;s wrapped into another component for a header and navigation but it&#39;s not included in the component.&lt;/p&gt;
&lt;p&gt;You can find the code and a small readme over at my&lt;a href=&quot;https://gist.github.com/PNergard/865a402c0fb41fdc04bac8f67e79e66f&quot;&gt; Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/4537b6d723bf4814870f44eb822bab25.aspx&quot; alt=&quot;&quot; width=&quot;738&quot; height=&quot;493&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/order-tabs-with-drag-and-drop---revisited/</guid>            <pubDate>Tue, 14 Jan 2025 12:56:20 GMT</pubDate>           <category>Blog post</category></item><item> <title>ImageFile alt-description validation attribute</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/imagefile-alt-text-validation-attribute/</link>            <description>&lt;p&gt;A customer wanted to improve their quality of having meta descriptive texts on all their published images but it was ok that it could take some time to get it into place (they are forced to review and republish pages on a regular basis) so thought that a validation attribute would do the trick.&lt;br /&gt;&lt;br /&gt;I vaguely remebered that I did something like this a long time a go which I had (&lt;a href=&quot;/link/0c07f80212834b7ab46f0180ee181c8c.aspx&quot;&gt;nov 2015&lt;/a&gt;) but that didn&#39;t handle images added in Xhtml-properties which was needed in this case. I found a solution that had solved a similiar problem but did handle it on actual rendering which used HtmlAgilitypack to handle the check for xthml-editors.&lt;br /&gt;&lt;br /&gt;So I updated my validation attribute and I have published it as a Gist. &lt;a href=&quot;https://gist.github.com/PNergard/d0accbbc46cc756b04c309257b69c902&quot;&gt;ImageValidatorGis&lt;/a&gt;t.&lt;br /&gt;&lt;br /&gt;The validation attribute checks contentreference, ContentArea and XhtmlEditor properties for images and check if they have a description property with value and if not returns an error. Since a image-file added to a XhtmlEditor gets the filename name as alt-text we need to compare the alt-text to the file-name and if equal we interpret that as not set even if the image file it self might have a descripton set.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2025/1/imagefile-alt-text-validation-attribute/</guid>            <pubDate>Tue, 07 Jan 2025 14:13:03 GMT</pubDate>           <category>Blog post</category></item><item> <title>Developer meetup i G&#246;teborg</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/2/developer-meetup-in-gothenburg/</link>            <description>&lt;p&gt;Knowit och Episervers meetup i Malm&amp;ouml; var en succ&amp;eacute; s&amp;aring; nu k&amp;ouml;r vi den &amp;auml;ven i G&amp;ouml;teborg den 3e mars. S&amp;aring; om man &amp;auml;r intresserad av att h&amp;ouml;ra mer om vad som &amp;auml;r p&amp;aring; g&amp;aring;ng inom .Net core eller l&amp;auml;ra sig mer om Episervers nya referens arkitektur &quot;Foundation&quot; ska man genast klicka sig vidare till meetup sidan och anm&amp;auml;la sig. Kan ni inte g&amp;aring; just detta tillf&amp;auml;lle passa p&amp;aring; att g&amp;aring; med i gruppen s&amp;aring; att ni inte missar kommande events!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.meetup.com/EPiServer-utvecklare-Goteborg/events/268705786/&quot;&gt;https://www.meetup.com/EPiServer-utvecklare-Goteborg/events/268705786/&lt;/a&gt;&lt;/p&gt;
</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/2/developer-meetup-in-gothenburg/</guid>            <pubDate>Fri, 14 Feb 2020 14:14:42 GMT</pubDate>           <category>Blog post</category></item><item> <title>Developer meetup in Malm&#246;</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/1/developer-meetup-in-malmo/</link>            <description>&lt;p&gt;After a long slumber in the Episerver Developers &amp;Ouml;resund group Knowit and Episerver is kicking off 2020 with a developer meetup in Malm&amp;ouml; february 6.&lt;/p&gt;
&lt;p&gt;Episerver .Net Core and the new reference project Episerver Foundation is the topics of the evening.&lt;/p&gt;
&lt;p&gt;So if you are in the &amp;Ouml;resund area come and join us.&lt;/p&gt;
&lt;p&gt;See below link to sign up!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.meetup.com/EPiServer-utvecklare-Oresund/events/267933749/&quot;&gt;https://www.meetup.com/EPiServer-utvecklare-Oresund/events/267933749/&lt;/a&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/1/developer-meetup-in-malmo/</guid>            <pubDate>Mon, 27 Jan 2020 12:45:35 GMT</pubDate>           <category>Blog post</category></item><item> <title>Use a page type as a  scheduledjob</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/1/scheduledjobs-ish-with-input-parameters/</link>            <description>&lt;p&gt;Scheduledjobs have evolved a bit over the years but they still lack a nice way to have input parameters. If you don&#39;t hard code everything I see the following alternatives.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Appsettings&lt;br /&gt;Works but can only be done by a developer with access to the server environment. Causes a restart of the website.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Properties on a page&lt;br /&gt;I really like using a builtuin way to get a nice editorial experience when setting parameters. But having to view logs / status in admin mode and change settings in edit mode feels a bit disconnected. And I think that admin-mode access for non developers should be kept to an absolute minimum.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Extending the builtin views in admin mode&lt;br /&gt;Mathias Kunto did a nice implemantation where you can extend the builtin views with the help of control adapters. You can read his blog post &lt;a href=&quot;https://blog.mathiaskunto.com/2014/03/21/scheduled-jobs-with-input-parameters-in-episerver-7-5/&quot;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So hardcoding and using appsettings is out of questions but I really like using builtin editorial features for a smooth experience but mixing edit and admin mode together makes is hard to understand. Mathias way is for sure the most &quot;integrated&quot; way of doing it, but is in admin mode which is still in webforms and for some jobs I would like a more granular control over who can handle specific jobs without giving access to everything in admin mode.&lt;/p&gt;
&lt;p&gt;So here is a proof of concept of the solution I came up with: A page type that after initial publish it automatically sets it self for scheduled publishing according to the preffered interval and all work is done during the publishing event.&lt;/p&gt;
&lt;p&gt;To get everything up and running we need a specific page type which have all the settings we want and the model will contain all code that do the actual scheduledwork and handling logging. We also need an initalizationmodule hooking up to&amp;nbsp; the PublishingContent and PublishedContent events. And of course the schedulejob handling future publishing of content must be up and running.&lt;/p&gt;
&lt;p&gt;The page type is lika any normal page type but it contains one method that will perform all work and log a status message to a IList property:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public void DoTheMagic()
{
  if (this.HistoryLog == null) this.HistoryLog = new List&amp;lt;Log&amp;gt;();

     var message = new Log
     {
       Date = DateTime.Now.ToString(),
       Message = &quot;We did som magic!&quot;,
       ExecutedBy = &quot;The logged in user&quot;
      };

      this.HistoryLog.Add(message);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the initaliziationmodule PublishingContent event if the content is of the correct type we call the DoTheMagic method. We need to do it in the publishing event because we are creating a log message and adds it to the logging IList property and we need to have the object in a writable state.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;private void ToolPageInitializationModule1_PublishingContent(object sender, EPiServer.ContentEventArgs e)
{
    var page = e.Content as ToolPage;

    if (page != null)
    {
        page.DoTheMagic();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To hande setting the new scheduled publish date we need to to it in the PublishedContent event. Trying to change the date in the same event as the DoTheMagic don&#39;t work.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;private void ToolPageInitializationModule1_PublishedContent(object sender, ContentEventArgs e)
{
    var page = e.Content as ToolPage;
    var writable = page.CreateWritableClone() as ToolPage;

    if (page != null)
    {
        if (page.Interval == &quot;Minute&quot;)
        {
            var date = writable.StartTime = page.StartTime.AddMinutes(page.IntervalValue);
            writable.StartPublish = date;

            ServiceLocator.Current.GetInstance&amp;lt;IContentRepository&amp;gt;().Save(writable, SaveAction.CheckIn | SaveAction.Schedule, EPiServer.Security.AccessLevel.NoAccess);
        }

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So in the editorial interface it looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/fc72859129bc49a4ae9a90764f2feb2e.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/ae02845bb3474216b1e6f1ef7b62b407.aspx&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So this is only a simple proof of concept but it does what I set up to do so at this stage Im happy :)&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2020/1/scheduledjobs-ish-with-input-parameters/</guid>            <pubDate>Tue, 21 Jan 2020 09:55:36 GMT</pubDate>           <category>Blog post</category></item><item> <title>Find and delete content based on type</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/6/find-and-delete-content-based-on-type/</link>            <description>&lt;p&gt;Another blog post and another admin mode plugin..&lt;/p&gt;
&lt;p&gt;From time to time I have had the need to delete content for specific types. It could be a cleanup case before using a dev database as UAT or maybe we wan&#39;t to discard some content type.&lt;/p&gt;
&lt;p&gt;In general content of a specific types tend to be all over the place especially with images and blocks so this can be a tedious process. So I whipped together a small admin mode plugin that lets you select a type and get a list of all content-instances and lets you delete all or selected instances of that type. Nothing fancy but it does it&#39;t job.&lt;/p&gt;
&lt;p&gt;You can find the code over at my &lt;a href=&quot;https://gist.github.com/PNergard/8a1037dcea6918dfc558676bded4e7b9&quot;&gt;Gist&lt;/a&gt; and it looks lite this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/def33cea04e64ea2add53e51da715fb8.aspx&quot; /&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/6/find-and-delete-content-based-on-type/</guid>            <pubDate>Mon, 17 Jun 2019 15:47:46 GMT</pubDate>           <category>Blog post</category></item><item> <title>Episerver CMS  11 certification - tips and comments</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/4/episerver-cms-certification---tips-and-comments/</link>            <description>&lt;p&gt;This week it what that time again where I needed to renew my Episerver CMS certificate. So here is a post with some thoughts, comments and tips that hopefully is to some use&amp;nbsp; for others preparing for the exam.&lt;/p&gt;
&lt;p&gt;A lot of things have happened in the Episerver world the last couple of years both with the CMS and other products and not least going into the cloud with the DXC.I think this is reflected in the exam. You really need to have a broad knowledge about Episerver both from a developer perspective but also general product knowledge and editorial skills sprinkled with some Find and DXC to pass the exam.&lt;/p&gt;
&lt;p&gt;I&#39;ve been working with Episerver for a long time (maybe too long) and I&#39;m certified in all versions since CMS 5, and although I try to keep myself updated&amp;nbsp; my professional career has drifted away to doing other stuff than coding so I thought that some reading in the development guide probably was a good idea.&lt;/p&gt;
&lt;p&gt;I was pleasently suprised that the &lt;a href=&quot;/link/f3882e248540406fa3bc4a6858a3b244.aspx&quot;&gt;development guide&lt;/a&gt; has been updated and include more code examples than before.Also a big improvement is that new features now are clearly marked from which version that feature is available which is great for seasoned developers that really only need to brush up their knowledge on new stuff. The new improved looks on world also really made reading more easy on the eyes.&lt;/p&gt;
&lt;p&gt;I&#39;d say that the development guide is the main place to go for information but the &lt;a href=&quot;/link/3aa770bc7f0044fb9175c18048c0d2e7.aspx&quot;&gt;user guide&lt;/a&gt; is a great place&amp;nbsp; to gain knowledge about ie personalization of blocks, and you can learn som useful stuff around environments, deployment, optional extras and service and health continuity in the &lt;a href=&quot;https://www.episerver.com/services/descriptions/episerver-dxc-service-description/&quot;&gt;DXC service description&lt;/a&gt;. And if you haven&#39; used Episerver Find it can be well spent time to play around with how to do searches using different Find features like best bets, stemming, filtering etc. And don&#39;t forget to use the Visual Studio extension creating an Alloy sample project and have a look in the code and maybe try out some of the newer features like projects and notifications.&lt;/p&gt;
&lt;p&gt;It&#39;s alot of material to read through but if you have the time I would really recomend going through it all since the documentation is quite good and even super experienced Episerver proffessionals will learn something new.&lt;/p&gt;
&lt;p&gt;Anders G Nordbys &lt;a href=&quot;https://andersnordby.wordpress.com/2018/01/09/knowledge-areas-for-the-episerver-cms-certification/&quot;&gt;blog post&lt;/a&gt; from 2018 is still a very good writeup with general information and hints.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So with this post and Anders blog posts, in combination with putting in some effort I&#39;m sure that pass you will pass the exam.&lt;/p&gt;
&lt;p&gt;Oh and the exam I took was for CMS version 11.&lt;/p&gt;
&lt;p&gt;Happy certification!&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/4/episerver-cms-certification---tips-and-comments/</guid>            <pubDate>Sat, 13 Apr 2019 14:44:20 GMT</pubDate>           <category>Blog post</category></item><item> <title>AllowedTypes for LinkItem collection</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/3/allowedtypes-for-linkitem-collection/</link>            <description>&lt;p&gt;The other day I heard a discussion about a possible requirement for only allowing specific pages in a LinkItem collection.&amp;nbsp; My first thought was to use a ContentArea property in combination with the AllowedTypes attribute but for some reason the possiblity to have external links was needed.&lt;/p&gt;
&lt;p&gt;I googled a bit but I only found a post where a custom validation class handled validation of max number of items in a LinkItemCollection, you can read Allan Thraens blog post &lt;a href=&quot;/link/e7723a75c6a24c6a8c5b952386265817.aspx&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It seemed like a clean and simple approach so I decided to do a variant that is similiar to AllowedTypes for ContentArea and ContentReference properties.&lt;/p&gt;
&lt;p&gt;My solution is a simple validation attribute that takes an array of types that should be allowed to add to a LinkItemCollection property. The attribute ignores linkitems that are not Episerver content.If an Epierver content (page,image) is added to the LinkItemCollection and the underlying type is not inte the allowed types array a error message is displayed and publishing of the page is blocked.&lt;/p&gt;
&lt;p&gt;You can find the coder over at my &lt;a href=&quot;https://gist.github.com/PNergard/7df2636b45753a5b9a654447cf64461a&quot;&gt;gist&lt;/a&gt;.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/3/allowedtypes-for-linkitem-collection/</guid>            <pubDate>Tue, 02 Apr 2019 17:29:30 GMT</pubDate>           <category>Blog post</category></item><item> <title>Automatically create pages for ContentReference properties</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/2/automatically-create-pages-for-contentreference-properties/</link>            <description>&lt;p&gt;If you like me have tried to take an existing solution but wanted to start from scratch, maybe for a demo and you just gave up due to the amount of required properties on for example a settings page? Most of them are probably strings and ints that should be pretty easy to fix (or really should have had good defaults). But what about those pesky properties of type ContentReference which excpects a page of a certain type? And I bet those new pages have more pesky required properties as well! Gaah my blood pressure!&lt;/p&gt;
&lt;p&gt;So to come closer to my (pipe?) dream of super easy site site setup even from scratch and using a &quot;mature&quot; solution that has developed over some years I decided to go with an attribute and initmodule approach.&lt;/p&gt;
&lt;p&gt;Ok so the attribute is very simple it just takes one parameter with the type we want to get automatically created. So in my example here I have three page types: A startpage that needs a reference to a settingspage which have two references to a searchpage and a newsarchivepage.&lt;/p&gt;
&lt;p&gt;So my page type looks like this (RequiredDependec is my custom attribute)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;         [RequiredDependency(typeof(Settings))]&lt;br /&gt;         [AllowedTypes(typeof(Settings))]&lt;br /&gt;        public virtual ContentReference SettingsPage {get; set;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The settingspage looks like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;        [RequiredDependency(typeof(NewsArchive))]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;        public virtual ContentReference NewsArchive { get; set; }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;        [RequiredDependency(typeof(ContactCards))]&lt;/code&gt;&lt;br /&gt;&lt;code&gt;        public virtual ContentReference ContactCards { get; set; }&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To fix the automagic creating and setting or properties I did a initmodule that on the onpublish event scans the underlying type with reflection for properties decorated with the new attribute, creates a new page of that type and sets the property to that reference. The created pages are not automatically published since I name them &quot;Automatically created - &amp;lt;pagetypename&amp;gt;&quot; so I guess atleast the name should be changed before they are published. The new pages are created below the ContentReference.StartPage so the startpage need to be created and a site and start page needs to be configured in admin mode.&lt;/p&gt;
&lt;p&gt;Ok so what does it look like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here we have a unpublished startpage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/ceb6e48cd10844ff8d49f30e7d835939.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
&lt;p&gt;&lt;strong&gt;Here we have the automatically created settingspage&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/20c9e74d5de941c9bfe2681681983b1c.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;img src=&quot;/link/8ba9a5de715044929895224bbb7439ab.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;strong&gt;After publishing the settingspage we have a newsarchive and searchpage created&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/5190bbc3968345be88f1ef2aba4d4c13.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The code is what it is and you use it at your own risk but you can find a complete project over at my Pnergard &lt;a href=&quot;https://github.com/PNergard/AutoCreateDependency&quot;&gt;GitHub&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/2/automatically-create-pages-for-contentreference-properties/</guid>            <pubDate>Sun, 24 Feb 2019 10:56:22 GMT</pubDate>           <category>Blog post</category></item><item> <title>Warning before deleting a page that is used in a property decorated with a SelectOne or SelectMany attribute</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/2/warning-before-deleting-a-page-that-is-used-in-a-property-decorated-with-a-selectone-or-selectmany-attribute/</link>            <description>&lt;p&gt;Long title and I hope it made some sense.&lt;/p&gt;
&lt;p&gt;The case is that it&#39;s quite common that the underlying data for SelectionFactories which is then used with SelectOne and SelectMany attributes is normal Episerver pages. For example this is used to handle contact-cards in the Alloy site.&lt;/p&gt;
&lt;p&gt;But since it&#39;s pages there is always a risk that someone by mistake deletes such a page causing problems. We would really like to have Episervers built in is this page used somewhere check.&lt;/p&gt;
&lt;p&gt;The fix for a SelectOne attribute is as easy as having the underlying property to be of type ContentReference instead of a string. But if you have a SelectMany the underlying property needs to be a string and the chosen values is just added as a comma separated string.&lt;/p&gt;
&lt;p&gt;To fix this for SelectMany I have created a custom attribute and a validation attribute class. When you add a SelectMany attribute where the SelectionFactory returns ContentReferences as id&#39;s you also add the new custom attribute which specifies an IList&amp;lt;ContentReference&amp;gt; property. The validation attribute then adds / removes references to the IList property automatically. With this when we try to delete a referenced page we get the builtin reference check functionality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pseudo code:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SelectMany(typeof(factoryclass))&lt;br /&gt;SelectManyListProperty(&quot;ListPropertyName&quot;)&lt;br /&gt;public virtual string SelectManyProp { get; set; }&lt;/p&gt;
&lt;p&gt;public virtual IList ListPropertyName {get; set;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/744223f60a83448f8f45485b136a6dc7.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/b85e3e6027c4481081a50e69849ca8e6.aspx&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Note that the ContentReference property isn&#39;t updated until page is published (values are there) and ofcourse it should be hidden under an other tab or atleast disabled for editors.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/PNergard/41d38a7daeb0c92845454d55c630f6f3&quot;&gt;Code over at my Gist.&lt;/a&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2019/2/warning-before-deleting-a-page-that-is-used-in-a-property-decorated-with-a-selectone-or-selectmany-attribute/</guid>            <pubDate>Tue, 19 Feb 2019 16:02:14 GMT</pubDate>           <category>Blog post</category></item><item> <title>Plugin for viewing / filtering wastebasket content and delete single content items</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/11/plugin-for-viewing--filtering-wastebasket-content-and-delete-single-content-items/</link>            <description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;From time to time we have the need to delete single content from the waste basket in Episerver. Saddly there is no built in support for this. A year ago &lt;a href=&quot;https://gregwiechec.com/2016/06/deleting-single-file-from-trash/&quot;&gt;Grzegorz modified&lt;/a&gt; the built in waste basket. It&#39;s great but I wanted to see some more information about the content and doing a Dojo solution is out of my comfort zone I decided to create yet another admin mode plugin.&lt;/p&gt;
&lt;p&gt;It&#39;s very simple and uses datatables.js for search / filtering functionality. You can delete all or selected items. See below for what it looks like. Code over at my &lt;a href=&quot;https://gist.github.com/PNergard/eba36f8c585419f1b65e27c0bd5f43fe&quot;&gt;Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/b5890876a6c142c3b6c4b706adb44cfa.aspx&quot; alt=&quot;Image wastebasket.jpg&quot; /&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/11/plugin-for-viewing--filtering-wastebasket-content-and-delete-single-content-items/</guid>            <pubDate>Thu, 09 Nov 2017 13:47:53 GMT</pubDate>           <category>Blog post</category></item><item> <title>Plugin for viewing scheduled job run history</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/9/plugin-for-viewing-scheduled-job-run-history/</link>            <description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;A couple of times during the years I have had the need to view the scheduled job history log. In all these cases it has been jobs that are running frequently and therefor I need to use the paging since the default view doesn&#39;t display that many rows.&lt;/p&gt;
&lt;p&gt;So I did a small plugin that let you choose between all scheduled jobs and display all the history in one table. Might not be the oste useful plugin but since I built it can as wll share it. You can find it over at my &lt;a href=&quot;https://gist.github.com/PNergard/743e5cb4e0480be7994789b49490cfea&quot;&gt;Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/2a817b35c4c4458f9c0d2c5020fb933a.aspx&quot; alt=&quot;Image logviewer.jpg&quot; /&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/9/plugin-for-viewing-scheduled-job-run-history/</guid>            <pubDate>Thu, 14 Sep 2017 22:21:44 GMT</pubDate>           <category>Blog post</category></item><item> <title>Plugin for deleting unreferenced media</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/9/plugin-for-deleting-unreferenced-media/</link>            <description>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Sometimes you need to synch a dev-environment with production database and media and the blob-storage is huge with likely a lot of unreferenced media or perphaps want to clean up a test-environment.&lt;/p&gt;
&lt;p&gt;To help in those two scenarios I threw togheter a small plugin that lets you delete all or just selected unreferenced media. Really nothing to say about the code than it can be found over at my &lt;a href=&quot;https://gist.github.com/PNergard/952e4225563a27a79b4671ad4dee0412&quot;&gt;Gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/0a4c82a652fb4defa1cd87926ad2ffd7.aspx&quot; alt=&quot;Image cleaner.jpg&quot; /&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/9/plugin-for-deleting-unreferenced-media/</guid>            <pubDate>Tue, 05 Sep 2017 23:12:05 GMT</pubDate>           <category>Blog post</category></item><item> <title>MenuProvider for easy display of key settings in a site</title>            <link>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/2/menuprovider-for-easy-display-of-important-information/</link>            <description>&lt;h2&gt;The problem (perceived at least)&lt;/h2&gt;
&lt;p&gt;How many times have you got a question about something or just had the need to do a quick check of some setting or status of something in a site? I guess that it happens more often that you would like.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My experience is that most of the times you can find the answers by loggin in to the site but that you need to click around a bit to find what you are looking for. If unlucky we need to log on to the actual server and check an appsetting or something like that. Not really that hard but wouldn&#39;t it be great to have key information about a site in one place?&lt;/p&gt;
&lt;p&gt;Atleast I think so, so here comes Overview dashboard to the rescue. (Failed to think of a better name so it will have to do).&lt;/p&gt;
&lt;h2&gt;My solution&lt;/h2&gt;
&lt;p&gt;So what is it? Overview dashboard is implemented as a menu provider that only has one view. The view uses reflection to look for classes that implements a specific interface and supplies the information. My initial thought with this was that the dashboard should only provide the means to easy display what ever you want and leave that to each project using it. So to have it this way it should be dead easy to have the dashboard included in your projects and if the need arise just implement a class with the correct interface to get a new menu option into the dashboard.&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;What does it look like&lt;/h2&gt;
&lt;p&gt;Each menu option to the left is equal to a class implementing the specific interface. The dashboard only supports two different rendering layouts for now: table and bootstrap alerts.&lt;/p&gt;
&lt;p&gt;All options can consist of a list of settings to display and the different layouts can be combined. It&#39;s also possible to display a badge in the menu option if something need to be highlighted.&lt;/p&gt;
&lt;h3&gt;Table example&lt;em&gt;&amp;nbsp;&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/link/da195848229c468e8a5437de301d5c00.aspx&quot; alt=&quot;Image 2 menu and appsetting.jpg&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;&lt;em&gt;Bootsrap alert example&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/link/f077770f03a44a08938a3e45e841cf50.aspx&quot; alt=&quot;Image 3 general example.jpg&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Mixed example&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/link/d99f2fb9871b4763a83666f9fcee5211.aspx&quot; alt=&quot;Image 4 mixed.jpg&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;Just create a class and implement the&amp;nbsp;IDashboardInformation interface see below.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;public interface IDashboardInformation&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;{&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;string Heading { get; } // The heading in the menu&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;List&amp;lt;DashboardData&amp;gt; Data(); // Data to display&lt;/em&gt;&lt;br /&gt;&lt;em&gt; string Badge { get; set; } //Badge in menu option&lt;/em&gt;&lt;br /&gt;&lt;em&gt; }&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The DashboardData class looks like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;public class DashboardData&lt;/strong&gt;&lt;br /&gt; {&lt;br /&gt; public string RenderType { get; set; } //View to render data&lt;br /&gt; public Object Data { get; set; } // The data&lt;br /&gt; }&lt;/p&gt;
&lt;h3&gt;Appsetting example&lt;/h3&gt;
&lt;p&gt;One thing to note about the two different now existing render types is that Dictionary expects the data to be a generic Dictionary&amp;lt;string,string&amp;gt; and the general render type to be of the General model which contains three properties: Heading, Text and Alert type. Alert type is the boostrap alert style wanted if any.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;public class AppsettingsInformation : IDashboardInformation&lt;/strong&gt;&lt;br /&gt; {&lt;/p&gt;
&lt;p&gt;public string Heading&lt;br /&gt; {&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt; return &quot;AppSettings&quot;;&lt;br /&gt; }&lt;br /&gt; }&lt;/p&gt;
&lt;p&gt;public List&amp;lt;DashboardData&amp;gt; Data()&lt;br /&gt; {&lt;br /&gt; var retList = new List&amp;lt;DashboardData&amp;gt;();&lt;/p&gt;
&lt;p&gt;var dict =first ConfigurationManager.AppSettings.AllKeys&lt;br /&gt; .ToDictionary(k =&amp;gt; k, v =&amp;gt; ConfigurationManager.AppSettings[v]);&lt;br /&gt; var dbData = new DashboardData&lt;br /&gt; {&lt;br /&gt; RenderType = RenderTypes.Dictionary,&lt;br /&gt; Data = dict,&lt;/p&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;retList.Add(dbData);&lt;/p&gt;
&lt;p&gt;return retList;&lt;br /&gt; }&lt;/p&gt;
&lt;p&gt;public string Badge { get; set; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;h2&gt;What is&amp;nbsp;missing&lt;/h2&gt;
&lt;p&gt;It still needs a bit work on the looks since I&#39;m no frontend guy at all. Maybe som more rendertypes as well but as a first check in I think it does the trick, atleast for my needs.&lt;/p&gt;
&lt;h2&gt;Where to get it&lt;/h2&gt;
&lt;p&gt;You can get the code over at my &lt;a href=&quot;https://github.com/PNergard/OverviewDashboard&quot;&gt;GitHub&lt;/a&gt;. Been thinking of doing it as a Nuget package but maybe it needs to be polished a bit more.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Per-Nergard/Dates/2017/2/menuprovider-for-easy-display-of-important-information/</guid>            <pubDate>Sun, 26 Feb 2017 11:25:07 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>