Thursday, February 15, 2007

Tutorial: Create your own Sitecore Wizard

This post applies to Sitecore 5.3 It's really quite logical - if you're writing your own wizards for sitecore they always look better if they are real sitecore wizards, so here's a quick tutorial on how to make your own. We're gonna go thru this in 5 steps:
  • Create a custom wizard sheer ui / xaml code
  • Create the CodeBeside class for our wizard
  • Create a Command that we can later use to launch it with
  • Edit the Web.Config and Commands.Config file
  • Create a context menu extension that launches our wizard
Still interested? well, let's start then! Step 1: Wizard XML code Create a folder somewhere beneath \sitecore modules\shell where you're going to store the code to your new wizard. The sheer ui / xaml code for the wizard is built using Sitecores WizardForm, WizardFormFirstPage, WizardFormPage & WizardFormLastPage controls so it'll look great and take advantage of all the existing features they provide, like intro & exit pages, navigation, events and so on. here's the code:
<?xml version="1.0" encoding="utf-8" ?> <control xmlns:def="Definition" xmlns=""> <ExampleWizard> <WizardForm CodeBeside="Interfolio.Examples.ExampleWizardForm,Interfolio.Examples"> <WizardFormFirstPage ID="FirstPage" Icon="People/48x48/user1.png"> <Border Class="scWizardWelcomeTitle"> <Literal Text="Example Wizard"/> </Border> <Literal Text="This wizard will help you:"/> <ul> <li> <Literal Text="Create your own wizard."/> </li> <li> <Literal Text="Understand the sitecore wizard."/> </li> </ul> </WizardFormFirstPage> <WizardFormPage ID="WizardPageOne" Header="Page 1" Text="Select one of the available options. When done, click next to continue." Icon="People/48x48/user1.png"> <WizardFormIndent> <GridPanel ID="FieldsAction" Columns="2" Width="100%" CellPadding="2"> <Literal Text="I want to.." GridPanel.NoWrap="true" Width="100%" /> <Combobox ID="SelectActions" GridPanel.Width="100%" Width="100%"> <ListItem ID="create" Header="Keep looking at this example" Value="newsite" /> <ListItem ID="edit" Header="Do something, somewhere else" Value="editsite" /> <ListItem ID="delete" Header="Yeah, you get the idea.." Value="deletesite" /> </Combobox> </GridPanel> </WizardFormIndent> </WizardFormPage> <WizardFormPage ID="WizardPageTwo" Header="Page 2" Text="Specify some information. Name needs to be set before moving on. When done, click next to continue." Icon="People/48x48/user1.png"> <WizardFormIndent> <GridPanel ID="FieldsInformation" Columns="2" Width="100%" CellPadding="2"> <Literal Text="Name:" GridPanel.NoWrap="true"/> <Edit ID="Name" Width="100%" Change="OnNameChanged" GridPanel.Width="100%"/> <Literal Text="Location:" GridPanel.NoWrap="true"/> <Edit ID="Location" Width="100%" GridPanel.Width="100%"/> <hr GridPanel.ColSpan="2" /> <Literal Text="URL:" GridPanel.NoWrap="true"/> <Edit ID="URL" Disabled="true" Width="100%" GridPanel.Width="100%"/> <hr GridPanel.ColSpan="2" /> <Literal Text="Checks:" GridPanel.NoWrap="true" /> <Checkbox ID="Check1" Header="Check one" /> <Literal Text="" GridPanel.NoWrap="true" /> <Checkbox ID="Check2" Header="Another check" /> </GridPanel> </WizardFormIndent> </WizardFormPage> <WizardFormPage ID="WizardPageThree" Header="Page 3" Text="More things to do here. When done, click next to continue." Icon="People/48x48/user1.png"> <WizardFormIndent> <GridPanel ID="FieldsOthers" Columns="2" Width="100%" CellPadding="2"> <Literal Text="Something else:" GridPanel.NoWrap="true"/> <Edit ID="SomethingElse" Width="100%" Change="OnNameChanged" GridPanel.Width="100%"/> <Literal Text="More text:" GridPanel.NoWrap="true"/> <Edit ID="MoreText" Width="100%" GridPanel.Width="100%"/> </GridPanel> </WizardFormIndent> </WizardFormPage> <WizardFormLastPage ID="LastPage" Icon="People/48x48/user1.png"> <Border> <Literal Text="The wizard has completed."/> </Border> </WizardFormLastPage> </WizardForm> </ExampleWizard> </control>
Step 2: Wizard C# code Now, for our wizard to even show and do, well, anything, we need to define it and handle some example events, like validating a Edit control and enable/disable buttons. The class is based on sitecores own WizardForm in order to get all the already-existing (and great) functionality. here's the code:
namespace Interfolio.Examples { public class ExampleWizardForm : WizardForm { // specify each control we need to access from the xml as 'protected' and it'll be available protected Edit Name; public ExampleWizardForm() { } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!Context.ClientPage.IsEvent) { // handle initial code here } } protected void OnNameChanged() { // check to make sure the name Edit is not empty (in a negative boolean style) bool IsOk = (this.Name.Value == null) (this.Name.Value.Length == 0); base.NextButton.Disabled = IsOk; if (IsOk) { Context.ClientPage.ClientResponse.Focus("Name"); } Context.ClientPage.ClientResponse.SetReturnValue(true); } protected override void ActivePageChanged(string page, string oldPage) { base.ActivePageChanged(page, oldPage); if (page == "WizardPageTwo") { // make sure next button is disabled unless the Name is entered this.OnNameChanged(); } else if (page == "LastPage") { base.BackButton.Disabled = true; } } protected override bool ActivePageChanging(string page, ref string newpage) { if (newpage == "LastPage") { // disable the back button since we've finished the wizard base.BackButton.Disabled = true; // return the boolean status of our 'commit' method return this.WhatWeWantToDo(); } return base.ActivePageChanging(page, ref newpage); } private bool WhatWeWantToDo() { // really do something else here, this is just an example.. return true; } } }
Step 3: Command C# code The purpose of this command is to make your newly created wizard launchable from pretty much anywhere you want. It is based on sitecores own Command. here's the code:
namespace Interfolio.Examples { [Serializable] public class OpenWizard : Command { public OpenWizard() { } public override void Execute(CommandContext context) { // get the uri of our wizard by finding the control using Sitecore's UIUtil string controlUrl = Sitecore.UIUtil.GetUri("control:ExampleWizard"); // broadcast the need to show the wizard to the sitecore shell Context.ClientPage.ClientResponse.Broadcast(Context.ClientPage.ClientResponse.ShowModalDialog(controlUrl), "Shell"); } public override CommandState QueryState(CommandContext context) { return base.QueryState(context); } protected void Run(Sitecore.Web.UI.Sheer.ClientPipelineArgs args) { } } }
Step 4: Config Additions Before using our code anywhere we need to tell Sitecore that it's available, which is normal since it's new code. In the Web.Config file, locate the section <controlsources> and add the source folder of your new code:
<source mode="on" namespace="Interfolio.Examples" folder="/sitecore modules/shell/interfolio/Examples" deep="true"> </source>
In the Commands.config file (located at \App_Config), add the following:
<command name="interfolio:examplewizard" type="Interfolio.Examples.OpenWizard,Interfolio.Examples" />
Save both files. As you may have noticed the example is located in interfolio\Examples, this is just where i stored it for this tutorial, you can have any folder you wish, just make sure that if you change the namespace or assembly or folders that you refactor the change onto the rest of your code. Step 5: Launching the wizard Now all the code is complete and we only need to have a way of launching it within sitecore. While this approach isn't really that durable unless your wizard is extremely generic it's still an easy way to quickly try something you've done.
  • Open Sitecore in your browser, login and switch database to 'core'
  • Navigate to Sitecore/System/Context Menus/Default and duplicate the 'New' item and name it 'ExampleWizard'
  • Change the fields DisplayName to 'ExampleWizard' and Message to 'interfolio:examplewizard(id=$Target)'
  • Save it and switch back to the 'master' database
That's it! If you've followed these steps correctly you should by now be able to right click an item in the Content Editor and click ExampleWizard which will launch your newly created wizard. Take care, P.

Friday, February 02, 2007

Sitecore 5.3 & Tablet-PC & Vista Ultimate

I guess there's something good in everything - even getting your laptop stolen, 'cause then you got a pseudo-legitimate reason to finally get a tablet-pc notebook. ok, so i've been glancing at one for quite some time, but i just could justify the change, but now i had no choice but to get a replacement for the one that was stolen.. The thing is that after (way to many hours of) installing vista and updating drivers i had to see what sitecore would look like when it's 'just a screen', and i reckon it's finally shining in it's true colors. It more or less like a part of the operating system (in some strange way even more so than on a normal laptop/pc running vista), and showing it off like this is quite neat (and really cool). Now to see if there's a way to write cool stuff that you can take advantage of the stylus with.. Oh yeah, i'm back. posts have been short and empty (i know), but i've been kinda lost without a laptop, so now hopefully things are back to normal once again.. and, it's friday, so there's really no reason to complain anymore - so gonna go for an afterwork beer today. P.

Thursday, February 01, 2007

ASP.NET 2.0 AJAX 1.0 Source Code

Ever wondered how the heck they wrote it all? well, according to Scott Guthrie they're releasing the full code for you to growl through. more info: I'm gonna blog more now since my new laptop will (hopefully) arrive today. Take care, P.