Dialoge box in een Sitecore Command

by Jan Bluemink Created: 8 apr 2014, last update: 20 Apr 2016

In dit artikel worden de UI opties besproken aan de hand van een voorbeeld custom Sitecore command, die kun je dan aanpassen aan je eigen wensen. Ik heb een Custom ChangeToRedirect command gemaakt een variant op het item:changetemplate command. Het changetemplate command is een typisch developers command waar je de nodige rechten voor nodig hebt. Het eigen ChangeToRedirect command is bedoel voor redacteuren om het item te converteren naar een redirect item wat gebeurd door de template te wijzigen naar een van te voren bepaald template.

Een dialoge box in Sitecore content editor

Een Command is een stukje code die je kunt aanroepen in Het CMS daarbij krijg je de context mee en kun je user interactie doe. Er zijn zo’n 500 Commands beschikbaar en je kunt ze ook zelf maken zie je commands.config. Een command aanroepen kan door bijvoorbeeld een knopje in een Ribbons te zetten of een context menu in de Sitecore content editor.

 

Knopje in ribbon en context menu

In Sitecore 7.1 is XAML / Sheer UI vervangen door SPEAK UI wat betekend dat nu als je een dialoge box wilt maken in Sitecore 6.x?

Sheer UI  word niet meer ondersteund in Sitecore 7.1 en hoger daarnaast is er weinig documentatie, geen intellisense. Beetje zonde om daar nu tijd in te gaan steken.

SPEAK  Sitecore Process Enablement & Acceleration Kit. Een HTML en JavaScript framework om de gebruikersinterface te bouwen. De opbouw werkt met  Sitecore. Lay-outs, Sublayouts en WebControls op dezelfde manier zo als je gewend bent in Sitecore.
Een belangrijk verandering t.o.v Sheer is dat de control flow is verhuisd van de server naar de client. Er is ook een client-side pipeline. SPEAK is Vanaf Sitecore 7

Eigen Applicatie In Sitecore Kun je een eigen Applicatie maken die in een Iframe getoond word. Mogelijk in Sitecore 6 en 7. Je moet dan wel goed opletten dat je code en url ook buiten het CMS toegankelijk is.  Dus enige security is meestal wel nodig. In de Core database kun je je applicatie registreren onder core:/sitecore/content/Applications.  Kies voor External link in je Application item.  Onder core: /sitecore/content/Documents and settings/All users/Start menu/Programs kun je een menu item aanmaken.

Confirm en Alert Sitecore ’s ClientResponse object heeft een Confirm en Alert en dat werkt op Sitecore 6 en 7

In onderstaande Command gaan de we de Alert en Confirm gebruiken. 

Een command overerft van Sitecore.Shell.Framework.Commands.Command override de Execute method en de QueryState method. Met de QueryState geef je terug of het command gebruikt kan worden met de huidige context en genoeg rechten e.t.c

using System.Collections.Specialized;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Shell.Framework.Commands;
/*
 * in de core database /sitecore/content/Applications/Content Editor/Ribbons/Chunks/Page Urls/Redirect
 *  en in /sitecore/content/Applications/Content Editor/Context Menues/Default/Redirect
 * in de command.config  <command name="mysite:changetoredirect" type="mywebsite.Sitecore.Commands.ContentEditor.ChangeToRedirect,mysite.Sitecore"/>
 */
using Sitecore.Web.UI.Sheer;

namespace mysite.Sitecore.Commands.ContentEditor
{
    public class ChangeToRedirect : Command
    {
        /// <summary>
        /// Executes the command in the specified context.
        /// 
        /// </summary>
        /// <param name="context">The context.</param>
        public override void Execute(CommandContext context)
        {
            var parameters = new NameValueCollection();
            if (context.Items != null && context.Items.Length == 1)
            {
                var item = context.Items[0];
                parameters["id"] = item.ID.ToString();
            }

            Context.ClientPage.Start(this, "ConfirmBeforeRun", parameters);

        }

        /// <summary>
        /// Queries the state of the command.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>
        /// The state of the command.
        /// </returns>
        public override CommandState QueryState(CommandContext context)
        {
            Error.AssertObject((object)context, "context");
            if (context.Items.Length == 0)
                return CommandState.Disabled;
            foreach (Item obj in context.Items)
            {
                if (!obj.Access.CanWrite() || obj.Appearance.ReadOnly || Command.IsLockedByOther(obj))
                    return CommandState.Disabled;
                //Dit geld alleen voor items die onder de homepage staan, (eigelijk ook alleen paginas met layout daar check ik nu niet op)
                var path = obj.Paths.FullPath.ToLower();
                if (!path.Contains("/sitecore/content/mysite") || !path.Contains("/home/"))
                {
                    return CommandState.Disabled;
                }
            }
            return base.QueryState(context);
        }

        protected new void Run(ClientPipelineArgs args)
        {
            Database database = Factory.GetDatabase("master");
            //your template id
            var template = database.GetTemplate(new ID("{AAAAAAAA-11111-1111-1111-AAAAAAAAAAAA}"));

            Item itm = database.GetItem(args.Parameters["id"]);

            if (itm != null)
            {
                itm.ChangeTemplate(template);
                Log.Info("Item converted to mywebsite redirect page "+itm.Paths.FullPath, this.GetType());
                Context.ClientPage.ClientResponse.Alert("Converted to mywebsite redirect page, fill in the Redirect url");
                
                var load = string.Concat(new object[] { "item:load(id=", itm.ID, ",language=", itm.Language, ",version=", itm.Version, ")" });
                Context.ClientPage.SendMessage(this, load);
                var refresh = string.Format("item:refreshchildren(id={0})", itm.Parent.ID);
                Context.ClientPage.ClientResponse.Timer(refresh, 2);
            }



        }

        /// <summary>
        /// Confirms before run.
        /// 
        /// </summary>
        /// <param name="args">The args.</param>
        protected void ConfirmBeforeRun(ClientPipelineArgs args)
        {
            Assert.ArgumentNotNull((object)args, "args");
            if (args.IsPostBack)
            {
                if (args.Result != "yes")
                    return;
                Context.ClientPage.Start((object)this, "Run", args.Parameters);
            }
            else
            {
                Context.ClientPage.ClientResponse.Confirm("You are about to change a item to a mywebsite redirect page. Do you want to continue?");
                args.WaitForPostBack();
            }
        }
    }
}

We hebben een ConfirmBeforeRun en Run Methode. In de Execute methode gaan we eerst de ConfirmBeforeRun aanroepen en alleen bij een Yes gaan we door naar Run.

Na het uitvoeren van de changetemplate gaan we de client nog refreshen, namelijk  het item zelf zodat we de nieuwe velden zien, en de boom vanaf de parent zodat we ook het icoontje in de boom terugzien.  Dit doen we op basis van de Example die John West hier gepost heeft http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2011/08/Load-or-Reload-an-Item-in-the-Sitecore-ASPNET-CMS.aspx

De .ClientResponse.Timer is niet nodig die staat er meer als voorbeeld. Dat kan ook met meteen met een SendMessage. De Timer gebruik je als je een Delay wilt hebben. Welke berichten je nu precies kunt sturen? Ik heb dat nergens gedocumenteerd zien staan. Al kan ik wel bevestigen dat onderstaande code werkt op Sitecore 6.5 – 7.2

Het GUID dat je in de Run Method ziet is het Id van de custom redirect Template vul daar dus een bestaand ID in voor de omgeving. Om het te kunnen gebruiken in je eigen project pas ook de QueryState aan.

Git LinkedIn Twitter