Wednesday, September 27, 2006

Atlas Example

Right, down to business then: Sitecore and "Atlas".

"Atlas" is pretty much microsofts approach to AJAX and the hype surrounding it, so it's quite obvious that it was not going to go away but instead turn into a new part of the framework (see Scott Guthrie's blog on the matter at http://weblogs.asp.net/scottgu/archive/2006/09/11/_2200_Atlas_2200_-1.0-Naming-and-Roadmap.aspx)

Downloads:

Now, there's more or less two ways of going about using "Atlas" to power your website, either you build your own custom extender, or you could go with the really easy way - use the UpdatePanel. For now, let's just go with the UpdatePanel approach. If you haven't installed "Atlas" on a already existing site that you want to enable "Atlas" on, don't worry, it's pretty easy to set up:
  1. Install "Atlas" (make sure the checkboxes are ticked to also install Visual Studio project template and to register the .asbx extension in IIS).
  2. Copy the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll) from its installation folder to your site's Bin folder.
  3. Open the Web.config file
  4. Add these elements as children to the <configuration> element <configSections> <sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup"> <section name="converters" type="Microsoft.Web.Configuration.ConvertersSection"/> </sectionGroup> </configSections> <microsoft.web> <converters> <add type="Microsoft.Web.Script.Serialization.Converters.DataSetConverter"/> <add type="Microsoft.Web.Script.Serialization.Converters.DataRowConverter"/> <add type="Microsoft.Web.Script.Serialization.Converters.DataTableConverter"/> </converters> </microsoft.web>
  5. Add/Integrate these elements as children to the <system.web> element <pages> <controls> <add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/> <add namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/> </controls> </pages> <!-- ASMX is mapped to a new handler so that proxy javascripts can also be served. --> <httpHandlers> <remove verb="*" path="*.asmx"/> <add verb="*" path="*.asmx" type="Microsoft.Web.Services.ScriptHandlerFactory" validate="false"/> </httpHandlers> <httpModules> <add name="ScriptModule" type="Microsoft.Web.Services.ScriptModule"/> </httpModules>
  6. Save the Web.config file.
  7. Add a reference to the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll).
  8. (Optional) You can now also add "Atlas" to the Toolbox in Visual Studio. Right click the Toolbox, chose "add tab", name it, then right click, "choose items..", and browse to the "Atlas" run-time assembly (Microsoft.Web.Atlas.dll).

Phew! Ok, that's about it for the installation and messing with a already existing site, now on to the fun stuff.

If you've never tried it before you're going to have fun, "Atlas" is neat and easy to use (note tho that it's still not a full release, so if it for whatever reason does crash, well, sorry, not much to do then but to re-install it).

1: Adding a ScriptManager

Add this to the page you want to enable "Atlas" on.

<atlas:ScriptManager ID="MyScriptManager" runat="server" EnablePartialRendering="true"> </atlas:ScriptManager> Now, there's more stuff to add here if you want to, like automated error handling etc:

<atlas:ScriptManager ID="MyScriptManager" runat="server" EnablePartialRendering="true"> <ErrorTemplate> <div style="width: 450px; height: 300px; padding: 10px; border: solid 1px black; background: gray; text-align: left;"> <h1>Site error detected</h1> <p>An unhandled exception with the following message has occured on the server:</p> <p><span id="Span1" runat="server"></span></p> <p>We're sorry for any trouble this has caused you and will fix the problem as soon as possible.</p> <p><input id="Button1" type="button" value="OK" runat="server"/></p> </div> </ErrorTemplate> </atlas:ScriptManager>

Play around with it, you'll find more things to use i'm sure.

2: Adding a UpdatePanel

An UpdatePanel is pretty much a content-wrapper that will allow you to reload parts of the page (AJAX styled content refreshing instead of reloading an entire page) so let's look at that one. First up, we need to wrap our area with the tags.

<atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> </atlas:UpdatePanel> Next up, adding a ContentTemplate to define what within this UpdatePanel that's our actual content area.

<atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <div id="Div1"> </div> </ContentTemplate> </atlas:UpdatePanel> Now, let's add a nice looking UpdateProgress as well to show that something's going on when it loads

<atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <div id="Div1"> <atlas:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> <div id="Div2"> <asp:Image ID="Image2" runat="server" ImageUrl="/images/loading2.gif" GenerateEmptyAlternateText="True" AlternateText="Loading.." /> </div> </ProgressTemplate> </atlas:UpdateProgress> </div> </ContentTemplate> </atlas:UpdatePanel> 3: Refreshing the content

It's nice to have the possibility to update content on the page, but unless we actually activate it there's no point, so let's add an automated update of the content using a TimerControl.

<atlas:TimerControl ID="tcExample" runat="server" Interval="10000" Enabled="true" OnTick="tcExample_Tick"> </atlas:TimerControl> Next we need to add the tick event to the UpdatePanel so that it knows when to update itself. This is done using a Trigger that we'll connect to the Tick event of the newly created TimerControl. Add the following code within the UpdatePanel section:

<Triggers> <atlas:ControlEventTrigger ControlID="tcExample" EventName="Tick" /> </Triggers> 4: Defining what to refresh/update

Well, now that we have automated updating partially set up, let's add something to actually refresh/update. For this example we'll use an image (simple, i know, but it's just for example purposes). Add the following image tag within the <ContentTemplate> section of the UpdatePanel

<asp:Image id="ExampleImage" runat="server"/> 5: The code so far

Now, if you've followed the steps above somewhat down each line your page should look something like this:

<atlas:ScriptManager ID="MyScriptManager" runat="server" EnablePartialRendering="true"> <ErrorTemplate> <div style="width: 450px; height: 300px; padding: 10px; border: solid 1px black; background: gray; text-align: left;"> <h1>Site error detected</h1> <p>An unhandled exception with the following message has occured on the server:</p> <p><span id="errorMessageLabel" runat="server"></span></p> <p>We're sorry for any trouble this has caused you and will fix the problem as soon as possible.</p> <p><input id="okButton" type="button" value="OK" runat="server"/></p> </div> </ErrorTemplate> </atlas:ScriptManager> <atlas:UpdatePanel ID="UpdateExample" runat="server" Mode="Always"> <ContentTemplate> <atlas:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> <asp:Image ID="Image1" runat="server" ImageUrl="/images/loading2.gif" GenerateEmptyAlternateText="True" AlternateText="Loading.." /> </ProgressTemplate> </atlas:UpdateProgress> <asp:Image id="ExampleImage" runat="server"/> </ContentTemplate> <Triggers> <atlas:ControlEventTrigger ControlID="tcExample" EventName="Tick" /> </Triggers> </atlas:UpdatePanel> <atlas:TimerControl ID="tcExample" runat="server" Interval="10000" Enabled="true" OnTick="tcExample_Tick"> </atlas:TimerControl> 6: Adding the final code

Almost done now, just one thing left, and that's to add the actual code we use behind the scenes. For this example i've used a simple sitecore structure to attach images to an existing item Sitecore - Content -- Home --- AtlasExample ---- Image 1 ---- Image 2 ---- Image Whatever ---- ...

The template that holds the images simply holds a Image field named "image", nothing more. The reason for having them located under one item is just for easy access through sitecore.

In the code we're gonna be using a ItemCollection and IEnumerator to move through the items and get the content.

protected static System.Collections.IEnumerator images; protected static ItemCollection imageItems;

First up, load the content into the collection when the page is first loaded:

protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { InitColl(); } } protected void InitColl() { if (Sitecore.Context.Item.HasChildren) { imageItems = new ItemCollection(); Item imageFolder = Sitecore.Context.Item.Children["AtlasExample"]; if (imageFolder!=null) { foreach (Item itm in imageFolder.Children) { imageItems.Add(itm); } images = imageItems.GetEnumerator(); SelectNextImage(); } else { this.ExampleImage.Visible = false; Sitecore.Context.ClientPage.ClientResponse.Refresh(this.ExampleImage); } } } protected void SelectNextImage() { if (imageItems!=null) { if (imageItems.Count>0) { if (images != null) { if (!images.MoveNext()) { images.Reset(); images.MoveNext(); } Item next = (Item)images.Current; Sitecore.Data.Fields.ImageField image = (Sitecore.Data.Fields.ImageField)next.Fields["image"]; this.ExampleImage.ImageUrl = "~/media library/Images/" + image.Src; this.ExampleImage.AlternateText = "AtlasExample"; } } } } Next, add the tick event that we stated in the TimerControl earlier.

protected void tcExample_Tick(object sender, EventArgs e) { SelectNextImage(); }

Now go ahead and build it and watch the results on your site.

8: Moving on

As you can see extending a site, even a sitecore powered one, with "Atlas" is really a piece of cake and is there for everyone's taking. Check out the Atlas control toolkit and the samples there for more details on how to extend with "Atlas" using custom extenders.

Further reading:

Take care, and have fun!

P.

No comments: