<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Tahir Naveed</title><link href="http://world.optimizely.com" /><updated>2020-02-14T09:29:34.0000000Z</updated><id>https://world.optimizely.com/blogs/Tahir-Naveed/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Using Microsoft cognitive services to improve content sentiments</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2020/2/using-microsoft-cognitive-services-to-improve-content-sentiments/" /><id>&lt;p&gt;In this blog post, I will describe how we have utilised Microsoft cognitive services (Text Analytics API) to analyse content before a content author publishes it so it can be rewritten in a more positive tone.&amp;nbsp;The Text Analytics API uses a machine learning classification algorithm to generate a sentiment score between 0 and 1. Scores closer to 1 indicate positive sentiment, while scores closer to 0 indicate negative sentiment.&lt;/p&gt;
&lt;p&gt;Content author will be encourged to rewrite content if a score closer to zero is returned - the idea is to make sure our content conveys the message in a postive manner.&lt;/p&gt;
&lt;p&gt;A working example can be seen below and all the code is in &lt;a href=&quot;https://github.com/tahirnaveed/sentiment-analysis&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/4-tr9h8r5slzVXhrZJ76r6qlTpM_bC8vNbsdypQv1h3v3vSbXZE04i7De2kXni1uYupCjovsCq6wr519I0Ga0NTU-p9O2CzVlmfNuXjsWCGGmDz9ovHjw-RhEF9UhezCLil9iByr=w2400&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;The basic steps are as follows&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create a Microsoft azure account and subscribe to Microsoft cognitive services. You will need the end point and a key. A detail documentation can be found &lt;a href=&quot;https://azure.microsoft.com/en-us/services/cognitive-services/&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a plugin (button) in tinymce
&lt;ol&gt;
&lt;li&gt;The button when clicked will call a server side web api and pass the tinymce content alongwith via an ajax call.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Create a server side web api controller to process content
&lt;ol&gt;
&lt;li&gt;This controller will receive the content from tinymce and will call microsoft cognitive services to analyse sentiments of the content&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Visual studio solution architecture:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Use visual studio extension to create basic episerver alloy vinealla website.&lt;/li&gt;
&lt;li&gt;Install the following nuget packages
&lt;ol&gt;
&lt;li&gt;install-package Microsoft.AspNet.WebApi
&lt;ol&gt;
&lt;li&gt;You will need to configure some basic routes ( see the working example)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;install-package Microsoft.Azure.CognitiveServices.Language.TextAnalytics
&lt;ol&gt;
&lt;li&gt;You will need to configure Cognitive services in Azure portal and then copy/paste the key in the sample&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once it is configured, the backend code is all setup.&lt;/p&gt;
&lt;p&gt;For front end code, I have utilised yomen TinyMCE Plugin Generator to generate a tinymce plugin. More documentation can found &lt;a href=&quot;https://www.tiny.cloud/docs/advanced/yeoman-generator/&quot;&gt;here&lt;/a&gt;. Simple code to add a button to tinymce editor which when clicked will made an ajax call to backend web api and show the result to end use.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;(Please note the code share is a basic example of making it all work together and it is not production ready code)&lt;/p&gt;</id><updated>2020-02-14T09:29:34.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Set display options for content area item via code</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2019/10/set-display-options-for-content-area-item-via-code/" /><id>&lt;p&gt;On the subject of &amp;ldquo;note to self&amp;rdquo; &amp;amp; &amp;ldquo;for future reference&amp;rdquo;, when required to setup display options programmatically for a given content area item&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ContentAreaItem newContentAreaItem = new ContentAreaItem() { ContentLink = &amp;ldquo;ID of your content&amp;rdquo;};&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;newContentAreaItem.RenderSettings = new Dictionary&amp;lt;string, object&amp;gt;();&lt;/code&gt;&lt;br /&gt;&lt;code&gt;newContentAreaItem.RenderSettings.Add(&quot;data-epi-content-display-option&quot;,&amp;rdquo;Id of display option&amp;rdquo;);&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And to get all the registered displayoptions&lt;/p&gt;
&lt;p&gt;&lt;code&gt;var options = ServiceLocator.Current.GetInstance&amp;lt;DisplayOptions&amp;gt;();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Hope this might be useful for someone&lt;/p&gt;</id><updated>2019-10-11T13:46:11.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Adding a menu item into Context Menu - EPiServer 10.1 way</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2016/11/adding-a-menu-item-into-context-menu---episerver-10-1-way/" /><id>&lt;p&gt;A while back, I &lt;a href=&quot;/link/be858eba9b4540e4ba5ace135c438a17.aspx&quot;&gt;blogged&lt;/a&gt; about how to customise the context menu in EPiServer 7. The code used to extend the context menu was not an approach supported by EPiServer and it was not guaranteed to work with any future releases.&lt;/p&gt;
&lt;p&gt;I was looking at the EPiServer documentation and came accross plugin areas &lt;a href=&quot;/link/54b2ad595a1340ada5f37300957b7934.aspx&quot;&gt;document&lt;/a&gt;&amp;nbsp;in which EPiServer explains the introduction of &quot;Plug-in areas&quot; for EPiServer 10.1 and higher which can be utilised to customise context menu both for commerce and cms.&lt;/p&gt;
&lt;p&gt;The end result will be same and will look like&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/ccd18442ec864e9a839ab57bfc0d3371.aspx&quot; alt=&quot;Image Blog_1.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The VS project looks like&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/9f91d7bf06f74b6c8d018fe689a3c747.aspx&quot; alt=&quot;Image VS.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The gist for the code is &lt;a href=&quot;https://gist.github.com/tahirnaveed/c9d0efc9f68475ee858aeb18bdddc17c&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please note that this code will only work for EPiServer.CMS.UI version 10.1 and higher.&lt;/p&gt;
&lt;p&gt;It is a very simple code but if you have any questions please feel free to ask.&lt;/p&gt;</id><updated>2016-11-17T17:59:09.5530000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>EPiServer model object browser</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2016/2/episerver-model-object-browser/" /><id>&lt;p&gt;The Object Browser lets you examine the .net models available for use in EPiServer solution. It is a simple admin plugin in MVC that displays the EPiServer Model Inhertiance&amp;nbsp;Hierarchy. It can&amp;nbsp;also (eventually but not currently :) ) be used to delete the orphan properties (properties with no codebase) &amp;amp; their assosiated content.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All the code needed for this object browser is in &lt;a href=&quot;https://gist.github.com/tahirnaveed/62162bfd5c40e1302aa5&quot;&gt;this &lt;/a&gt;gist. The code is self explainatory, it just gets all the page types using EPiServer API and then using Reflection get the C# class&amp;nbsp;hierarchy.&lt;/p&gt;
&lt;p&gt;If you deploy this plugin into&amp;nbsp;AlloyTech and browse the url &quot;/ObjectBrowser/Index&quot;, you will see all the models (blocks/PageData/MediaData) available within solution and their corresponding properties. The properties with no codebase will be highlighted in red.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Example for one of the page type is shown below.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/c4815dab1d384af3be1f02c8bac2ba0d.aspx&quot; alt=&quot;Image Model2.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hope this will be useful to someone :)&lt;/p&gt;</id><updated>2016-02-23T15:30:52.6330000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Code snippet to get Available Page Types for a specific page type</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2015/9/code-snippet-to-get-available-content-types-for-a-specific-content-type/" /><id>&lt;p&gt;Couple of days back, I have to write some code to produce&amp;nbsp;an excel sheet&amp;nbsp;listing&amp;nbsp;all the page&amp;nbsp;types and the corresponding page types that are allowed to be&amp;nbsp;created under the page type.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;for each page type in the solution,

&amp;nbsp; &amp;nbsp; produce a list of page types that are allowed to be created under this page type.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This excel sheet will then be used by QA&amp;nbsp;&amp;nbsp;guys, as a starting point, to write some test scripts for an EPiServer 6 R2 and composer based solution to EPiServer 8 migration/upgrade project.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To start with, you need to find all the page types in the solution.&lt;/p&gt;
&lt;p&gt;Below is simple function to list all the page types&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt; private IEnumerable&amp;lt;PageType&amp;gt; GetAllPageTypes()
        {
            var contentTypeRepository = ServiceLocator.Current.GetInstance&amp;lt;IContentTypeRepository&amp;gt;();
            return contentTypeRepository.List().OfType&amp;lt;PageType&amp;gt;();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following snippet (self explanatory I think) will help you identify all the avaialable page types for a particular page type&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt; void GetAvailableContentTypes(ContentType contentType)
        {
            var contentTypeAvailablilityService = ServiceLocator.Current.GetInstance&amp;lt;ContentTypeAvailabilityService&amp;gt;();

            // Get Available settings
            AvailableSetting setting = contentTypeAvailablilityService.GetSetting(contentType.Name);
            bool allAvailable = setting.Availability == Availability.All ||
                               setting.Availability == Availability.Undefined &amp;amp;&amp;amp;
                               !setting.AllowedContentTypeNames.Any();


            var availableList = new List&amp;lt;PageType&amp;gt;();
            if (!allAvailable)
            {
                foreach (PageType pageType in this.GetAllPageTypes())
                {
                    foreach (string str in setting.AllowedContentTypeNames)
                    {
                        if (str.Equals(pageType.Name))
                        {
                            availableList.Add(pageType);
                        }
                    }
                }
            }
            if (allAvailable)
            {
                // All the page types are allowed
            }
            else
            {
                // Allowed page types are in the availableList
            }
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hope this will be useful :)&lt;/p&gt;</id><updated>2015-09-18T11:13:29.1800000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Adding menu item to page tree context menu</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2015/5/adding-menu-item-to-page-tree-context-menu/" /><id>&lt;p&gt;&lt;em&gt;Update:&amp;nbsp;For EPiServer version 10.1 and above see &lt;a href=&quot;/link/cd261a24083e42d0b9a100f033239fe7.aspx&quot;&gt;this &lt;/a&gt;link&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Recently I have migrated/upgraded an EPiServer 6 R2 composer based website to EPiServer 7.xx. In EPiServer 6 R2 website, the EPiServer right click context menu (page tree right click menu) was highly customized. This functionality, however, is totally removed in EPiServer 7.xx. EPiServer 7, however, does provide you a similar context menu to copy/cut/paste the content. My job was to customize this context menu and add menu items to it.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/834b78b3a710422da7c53267f3285091.aspx&quot; alt=&quot;Image Menu item.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;A quick Google search resulted in a great&lt;a href=&quot;/link/e1d1ece8894e4a9ba14417a80f77cc84.aspx&quot;&gt; blog post&lt;/a&gt; published by&amp;nbsp;Shamrez Iqbal to change the tooltip of the page tree&amp;nbsp;and this acted as a starting point for my investigation. For the sake of completeness, I am going to mention all the steps required to customize the context menu, however all the credit goes to Shamrez Iqbal for such a great blog. To get started, install Alloy Tech (webforms) website using visual studio extension,&amp;nbsp;and&amp;nbsp;enable the uncompressed (non-minified) version of javascript files in edit mode.&lt;/p&gt;
&lt;h2&gt;Enable client side debugging for JavaScript Files&lt;/h2&gt;
&lt;p&gt;The first thing that needs to be done is to tell EPiServer to use the uncompressed version of JavaScript files in edit mode so you can easily debug the js files. This is well explained in &amp;ldquo;Uncompressed JavaScript for EPiServer 7.6+&amp;rdquo; article &lt;a href=&quot;/link/379470be10da41ac8956b9e69cd5e16c.aspx&quot;&gt;here&lt;/a&gt;, however, in summary, you have to install the &amp;ldquo;EPiServer.CMS.UI.Sources&amp;rdquo; from nuget&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/c3adba76509e4e43a33df9b7fbe82d76.aspx&quot; alt=&quot;Image Install_package_cms_ui_sources.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and simply add the&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt;&amp;lt;clientResources debug=&quot;true&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&amp;nbsp;to the EPiServerFramework.config file underneath the episerver.framework element.&lt;/p&gt;
&lt;p&gt;Once this is installed, you should see&amp;nbsp;EPiServer.Cms.Shell.UI.zip under&amp;nbsp;modules\_protected\CMS directory&lt;/p&gt;
&lt;h2&gt;Override the Context Menu creation process&lt;/h2&gt;
&lt;p&gt;So to customize the context menu, we have to a)&amp;nbsp;identify where this menu is created and b) find out a way to override/customize the process so we can inject our own menu item.&amp;nbsp;The page tree menu is created in \epi-cms\component\ContentNavigationTree.js and this can be customized by using an InitializableModule to override PageRepositoryDescriptor. (see &lt;a href=&quot;/link/e1d1ece8894e4a9ba14417a80f77cc84.aspx&quot;&gt;this &lt;/a&gt;blog for detail description) Full code is below.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code&gt; public class OurDescriptor : PageRepositoryDescriptor
    {
        public override string CustomNavigationWidget
        {
            get
            {
                return &quot;alloy/component/ContentNavigationTree&quot;;
            }
        }
    }

    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class DescriptorInitialization : EPiServer.ServiceLocation.IConfigurableModule
    {

        public void ConfigureContainer(EPiServer.ServiceLocation.ServiceConfigurationContext context)
        {
            context.Container.Configure(ConfigureContainer);
        }

        public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {

        }

        public void Preload(string[] parameters)
        {

        }

        public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {

        }

        private static void ConfigureContainer(StructureMap.ConfigurationExpression container)
        {
            container.IfTypeMatches(type =&amp;gt; type.Equals(typeof(PageRepositoryDescriptor))).InterceptWith(i =&amp;gt; new OurDescriptor());
        }
    }



&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Second step is to copy the original EPiServer JS uncompressed files provided by EPiServer and modify it to customize the menu. To do this, open the EPiServer.Cms.Shell.UI.zip under&amp;nbsp;modules\_protected\CMS directory and&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Copy all the JS code from ContentNavigationTree.uncompressed.js. Create a file ContentNavigationTree.js under ClientResources\Scripts\Component directory and paste the copied content.&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;change&amp;nbsp;&quot;epi-cms/component/ContentNavigationTree&quot; to alloy/component/ContentNavigationTree&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&quot;epi-cms/component/ContentContextMenuCommandProvider&quot; to&amp;nbsp;&amp;nbsp;&quot;alloy/component/ContentContextMenuCommandProvider&quot;&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&amp;nbsp;&quot;./command/_GlobalToolbarCommandProvider&quot;, to&amp;nbsp;&amp;nbsp;&quot;epi-cms/component/command/_GlobalToolbarCommandProvider&quot;,&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&amp;nbsp;&quot;../command/CopyContent&quot;, to&amp;nbsp;&amp;nbsp;&quot;epi-cms/command/CopyContent&quot;&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&amp;nbsp;&quot;../command/CutContent&quot;, to&amp;nbsp;&amp;nbsp;&quot;epi-cms/command/CutContent&quot;&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&amp;nbsp;&quot;../command/DeleteContent&quot;, to&amp;nbsp;&amp;nbsp;&quot;epi-cms/command/DeleteContent&quot;&lt;/li&gt;
&lt;li&gt;Change&amp;nbsp;&amp;nbsp;&quot;../command/PasteContent&quot;, to&amp;nbsp;&amp;nbsp;&quot;epi-cms/command/PasteContent&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;Copy all the JS code from ContentContextMenuCommandProvider.js, create a file ContentContextMenuCommandProvider.js under ClientResources\Scripts\Component directory and paste the copied content. The full code is below (notice the newly added&amp;nbsp;RefreshTreeCommand)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;define(&quot;alloy/component/ContentContextMenuCommandProvider&quot;, [
// dojo
    &quot;dojo/_base/declare&quot;,
    &quot;dojo/_base/array&quot;,
// epi
    &quot;epi/shell/command/_CommandProviderMixin&quot;,

    &quot;epi-cms/command/CopyContent&quot;,
	&quot;alloy/component/RefreshTreeCommand&quot;,
    &quot;epi-cms/command/CutContent&quot;,
    &quot;epi-cms/command/PasteContent&quot;,
    &quot;epi-cms/command/TranslateContent&quot;,
    &quot;epi-cms/command/DeleteContent&quot;,

    &quot;epi-cms/widget/CreateCommandsMixin&quot;,

    &quot;epi/shell/selection&quot;
],

function (
// dojo
    declare,
    array,
// epi
    _CommandProviderMixin,
    CopyCommand,
	RefreshTreeCommand,
    CutCommand,
    PasteCommand,
    TranslateCommand,
    DeleteCommand,

    CreateCommandsMixin,

    Selection
) {

    return declare([_CommandProviderMixin, CreateCommandsMixin], {
        // summary:
        //      Command provider for content context menus
        // tags:
        //      internal xproduct

        // treeModel: [Object]
        //      Model use for the commands
        treeModel: null,

        clipboardManager: null,

        _settings: null,
        _newContentCommand: null,
        _translateContentCommand: null,

        constructor: function (params) {
            declare.safeMixin(this, params);
        },

        postscript: function () {
            this.inherited(arguments);

            //Create the commands
            this._settings = {
                category: &quot;context&quot;,
                model: this.treeModel,
                clipboard: this.clipboardManager,
                selection: new Selection()
            };

            this._translateContentCommand = new TranslateCommand({ category: &quot;context&quot;});

            var createCommands = this.getCreateCommands(),
                commands = [];

            for (var key in createCommands) {
                commands.push(createCommands[key].command);
            }
            
            commands.push(
                this._translateContentCommand,
				new RefreshTreeCommand(this._settings),
                new CutCommand(this._settings),
                new CopyCommand(this._settings),
                new PasteCommand(this._settings),
                new DeleteCommand(this._settings)
            );

            this.set(&quot;commands&quot;, commands);
        },

        updateCommandModel: function (model) {
            // summary:
            //      Updates the model for the commands.
            // tags:
            //      public
          
            array.forEach(this.get(&quot;commands&quot;), function(command){
                if (command.isInstanceOf(this.createCommandClass) || command.popup){
                    command.set(&quot;model&quot;, model);
                }
            }, this);

            this._translateContentCommand.set(&quot;model&quot;, model);
            this._settings.selection.set(&quot;data&quot;, [{ type: &quot;epi.cms.contentdata&quot;, data: model}]);
        }

    });

});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now under the component directory add the file&amp;nbsp;RefreshTreeCommand.js and add the following code. The below code is copied&amp;nbsp;from &quot;copy command&quot; and&amp;nbsp;modified. As an example, I am just getting the clicked page id, calling the asmx webservice and reloading the whole page.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;define(&quot;alloy/component/RefreshTreeCommand&quot;, [
    &quot;dojo/_base/declare&quot;,
    &quot;dojo/_base/array&quot;,
    &quot;epi&quot;,
    &quot;epi/shell/command/_Command&quot;,
    &quot;epi/shell/command/_ClipboardCommandMixin&quot;,
    &quot;epi/shell/command/_SelectionCommandMixin&quot;
], function (declare, array, epi, _Command, _ClipboardCommandMixin, _SelectionCommandMixin) {

    return declare([_Command, _ClipboardCommandMixin, _SelectionCommandMixin], {
        // summary:
        //      A command that starts the create new content process when executed.
        //
        // tags:
        //      public

        // label: [readonly] String
        //		The action text of the command to be used in visual elements.
        label: &quot;Refresh&quot;,

        // iconClass: [readonly] String
        //		The icon class of the command to be used in visual elements.
        iconClass: &quot;epi-iconRevert&quot;,

        _execute: function () {
            // summary:
            //		Copies the currently selected items to the clipboard and sets the clipboard copy flag.
            // tags:
            //		protected

            //this.clipboard.set(&quot;copy&quot;, true);
            //this.clipboard.set(&quot;data&quot;, this.selection.data.concat());
            //alert(&#39;Thanks for calling me&#39;);
            //debugger;
            // Standard jQuery to call an action method of our ASP.NET MVC controller
            var pageId = { &quot;id&quot;: this.selection.data[0].data.contentLink };

            dojo.rawXhrPost({
                url: &quot;/HelperService.asmx/Update&quot;,
                //handleAs: &quot;json&quot;,
                headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },
                timeout: 10000,
                postData: dojo.toJson(pageId),
                load: function (data) {
                    var result = dojo.fromJson(data);
                    if (result.d.Data != &#39;&#39;) {
                        window.location.reload();
                    }
                   
                },
                error: function (error) {
                  
                }
            });

        },

        _onModelChange: function () {
            // summary:
            //		Updates canExecute after the model has been updated.
            // tags:
            //		protected

            var model = this.model,
               selection = this.selection.data,
               canExecute = false;


            
            if (model &amp;amp;&amp;amp; selection.length) {
                canExecute = array.every(selection, function (item) {
                    return model.canCopy(item.data);
                });
            }

            this.set(&quot;canExecute&quot;, canExecute);
        }
    });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The visual studio structure should be&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/73ba928f8e7c4724ae73c1004ab739d6.aspx&quot; alt=&quot;Image VS_Structure.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now compile and run the project. You should see a new menu something like&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/14b83096684348fd83da1db0547941bb.aspx&quot; alt=&quot;Image Final.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Clicking on this menu will call a asmx webservice passing&amp;nbsp;page id as parameter. On server end, you can clear the EPiServer cache or do something else useful.&lt;/p&gt;</id><updated>2015-05-29T12:38:41.7130000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Change EPiServer file manager start folder</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2013/1/Change-EPiServer-file-manager-start-folder/" /><id>&lt;p&gt;On the subject of “for future reference” and “note to self”, when needed to setup the start-up folder within EPiServer folder manager.&lt;/p&gt;  &lt;p&gt;var cookie = new HttpCookie(&amp;quot;EPiDPCKEY&amp;quot;);&lt;/p&gt;  &lt;p&gt;cookie.Values.Add(&amp;quot;path&amp;quot;, &amp;quot;/Globals/Clients/1/&amp;quot;);&lt;/p&gt;  &lt;p&gt;this.Response.Cookies.Add(cookie);&lt;/p&gt;  &lt;p&gt;When done so, EPiServer folder manager will load the path saved in the cookie on initial load. This will be useful, if you have different business areas accessible to different users and you would like to facilitate EPiServer editors with loading the appropriate “Folder” in EPiServer Folder manager.&lt;/p&gt;</id><updated>2013-01-17T16:21:26.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Code snippet to modify EPiServer pagetype definitions programmatically.</title><link href="https://world.optimizely.com/blogs/Tahir-Naveed/Dates/2011/5/Code-snippet-to-modify-EPiServer-pagetype-definitions-programmatically/" /><id>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Few days back, I was assigned a project to amend an already created site and enable globalization on it. So I started by enabling globalization in EPiServer admin mode. Once done, the next task was to go to EPiServer edit mode and make “unique value per language” checked for all the properties. There are too many pagetypes that requires changes, so i decided to write a small code that does this for me &lt;img style=&quot;border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; alt=&quot;Smile&quot; src=&quot;/link/457c410cdc624d8aafc6f1eaa3b161f9.png&quot; /&gt;. &lt;/p&gt;  &lt;p&gt;//Get All the pageTypes&lt;/p&gt;  &lt;p&gt;PageTypeCollection pageTypeCollection = PageType.List();&lt;/p&gt;  &lt;p&gt;foreach (var pagetype in pageTypeCollection)&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;//get all the properties on pagetype&lt;/p&gt;  &lt;p&gt;PageDefinitionCollection pageDefinitionCollection = pagetype.Definitions;&lt;/p&gt;  &lt;p&gt;foreach (var pageDefinition in pageDefinitionCollection)&lt;/p&gt;  &lt;p&gt;{&lt;/p&gt;  &lt;p&gt;//Enable globalization and save&lt;/p&gt;  &lt;p&gt;pageDefinition.LanguageSpecific = true;&lt;/p&gt;  &lt;p&gt;pageDefinition.Save();&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt;}&lt;/p&gt;</id><updated>2011-05-01T22:27:27.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>