Archive

Posts Tagged ‘tutorial’

Implementing the XSLT Mediator – Part 1

July 11, 2009 4 comments

Contents

Introduction

In the next series of articles I plan on showing how to use the XSLT Mediator which Im currently maintaining as an eXtension available on SDLTridion World.

The Mediator can be downloaded from the XSLT Mediator Page

An explanation why should you use the XSLT Mediator can be found at the aforementioned download page, so I won’t go into that, ill simply show how it can be used.

This is the first part in a series of at least 3 articles; in following articles I will mainly be discussing how to extend the XSLT transformation with .NET code.

This article assumes basic knowledge of XSLT and basic Tridion experience in templating.

Setting up the Mediator

In the Mediator zip file you will find the assembly DLL which can be used as is as well as the source code of the mediator project.

You should be able to simply drop the DLL somewhere on the Content Manager Server to begin using it but you may choose to first use the source code either to build it against a different version of Tridion (currently that’s 5.3GA) or if you wish to add extension objects to the assembly (will be discussed on the next article in this series).

The simple setup requires an edit to the Tridion configuration file, which is located in the Config folder under the Tridion installation folder (i.e.: C:\Program Files\Tridion\Config) and the file name is Tridion.ContentManager.config.

Open the file for editing and insert the following XML fragment in the <mediators> element:

<mediator matchMIMEType="text/xml" type="Tridion.Extensions.Mediators.XsltMediator" assemblyPath="C:\Program Files\Tridion\bin\Tridion.Extensions.Mediators.dll"/>

If you’re using the binary as it is supplied then there is no need to change the ‘type’ attribute but make sure the ‘assemblyPath’ attribute is pointing to the right location of where you placed the DLL file.

To begin using the Mediator you should restart the following: Tridion COM+ package (Component Services), IIS, Tridion Publisher service and any open Template Builder instance.

Next step is to create the parameters schema which will be used with the XSLT TBBs we will be creating.

In the zip file you will find XSLT_Transformation_Parameters.xsd, In Tridion create a new parameters schema and use the upload button in the source tab to load the contents of the included XSD file:

XSLT transformation parameters schema

XSLT transformation parameters schema

That’s it. This is all the setting-up needed for now.

Creating an XSLT Component Template

Now you’re ready to create your first XSLT TBB which can be used in a compound template.

Note: For a long time it was possible to create XSLT component templates in Tridion, this has not changed. XSLT page templates however are not supported so in order to create these, the Mediator is required. The Mediator has another advantage of being able to incorporate managed (.NET) code into XSLT templates (will be discussed in a later article).

Lets create a simple schema which you will be able to use to test your new XSLT template with.
(The schema is included in the downloadable for this article)

Simple Schema

Simple Schema

The schema contains a title text field, a body rich text field, a date field and a multimedia link for an image.

Create a new component based on this schema and populate its fields with some values.
Based on this schema we will start with a simple XSLT TBB which we can extend later on:


<?xml version="1.0" encoding="utf-8"?>


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:simple="uuid:3CC625ED-34E6-4B51-BDD8-72BBD0D71469" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
exclude-result-prefixes="msxsl simple">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

<xsl:template match="/">
<xsl:element name="p">

<xsl:apply-templates select="tcm:Component/tcm:Data/tcm:Content/simple:Content"/>
</xsl:element>
</xsl:template>

<xsl:template match="simple:Content">

<xsl:element name="h3">

<xsl:value-of select="simple:title"/>

</xsl:element>

<xsl:element name="div">

<xsl:copy-of select="simple:body"/>

</xsl:element>

<xsl:element name="div">

Publish Date: <xsl:value-of select="simple:pubDate" />

</xsl:element>

<xsl:element name="img">

<xsl:attribute name="src">

<xsl:value-of select="simple:image/@xlink:href"/>

</xsl:attribute>

</xsl:element>

</xsl:template>

</xsl:stylesheet>

If you’re familiar with doing normal XSLT component templates you will notice the declaration of the “simple” namespace prefix at the top, this is necessary to be able to output the component’s content. The uuid:3CC625ED-34E6-4B51-BDD8-72BBD0D71469 namespace is copied from the schema we’ve just created (notice that each new schema receives a new target namespace by default which is in this long string format).

The rest of the template is very straight forward and just outputs the field values from the component.

In Tridion create a new TBB and copy the above code into the source tab. In the general tab make sure to add the parameters schema created before then save & close the template:

XSLT TBB with parameter schema

XSLT TBB with parameter schema

To use this new template open the Template Builder and create a new compound component template:

Template Builder Compound CT with XSLT TBB

Template Builder Compound CT with XSLT TBB

You can now run the template with the component you created earlier, the result should be something like this:

Run Compound CT in Template Builder

Run Compound CT in Template Builder

Note: Above I mentioned that I wont go into the merits of using the XSLT Mediator but one very important thing to notice is how quick it is in comparison to the Dreamweaver Mediator, obviously this example cannot be taken into account but even in real life templates, XSLT ones out run their DW counterparts by hundreds or percent.

There is no need to fill in any of the parameters attached to the XSLT Template but lets take a moment to review these:

Input Item Name – This is the item in the package to use as the input xml for the transformation.The default item which will be used for a component template is the item with name ‘Component’, for a page template it will be the ‘Page’ item.

Output Item Name – This is the name of the item the Mediator will create in the package with the result of the transformation; the default is ‘Output’.

Get Parameters from Package – A true/false value determining whether the Mediator should include items in the package as parameters for the transformation. Default is ‘true’.

For performance purposes it is recommended to change this to ‘false’ unless you require all of the items to act as parameters or plan on using specific items by specifying a prefix.

Package Items Name Prefix – The value of this parameter tells the mediator to only use items in the package which have the specified prefix. Presuming, the value of the previous parameter is ‘true’.

For example all items in the package with a prefix of ‘_par’ will be used if this value is specified.
The mediator will strip the prefix from the actual parameter name when its added to the transformation.

Output Format Type – Which content type to use for the result item created by the Mediator Default is ‘XHTML’.


Getting back to our new template:

Notice the broken image in the last  screen shot, by using some of the default TBBs provided by Tridion we can easily sort this out:

Compound Template with Image

Compound Template with Image

The order in which to place these TBBs (Extract, Publish, Resolve) is critical for the image to be published and displayed correctly.

Component Linking

The XSLT Mediator supports “linking” natively in a very similar way to how it was accomplished in XSLT CTs – by use of the document() function.

To demonstrate this ability I will use a metadata field set on the multimedia component to set the alt attribute of the image element in the resulting html. First the modified XSLT TBB:


<?xml version="1.0" encoding="utf-8"?>


<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:simple="uuid:3CC625ED-34E6-4B51-BDD8-72BBD0D71469" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
xmlns:image="http://www.tridion.com/ContentManager/5.0/DefaultMultimediaSchema"
exclude-result-prefixes="msxsl simple">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

<xsl:template match="/">
<xsl:element name="p">

<xsl:apply-templates select="tcm:Component/tcm:Data/tcm:Content/simple:Content"/>
</xsl:element>
</xsl:template>

<xsl:template match="simple:Content">

<xsl:element name="h3">

<xsl:value-of select="simple:title"/>

</xsl:element>

<xsl:element name="div">

<xsl:copy-of select="simple:body"/>

</xsl:element>

<xsl:element name="div">

Publish Date: <xsl:value-of select="simple:pubDate" />

</xsl:element>

<xsl:element name="img">

<xsl:attribute name="alt">
<xsl:value-of select="document(simple:image/@xlink:href)/tcm:Component/tcm:Data/tcm:Metadata/image:Metadata/image:altText"/>
</xsl:attribute>


<xsl:attribute name="src">
<xsl:value-of select="simple:image/@xlink:href"/>

</xsl:attribute>

</xsl:element>

</xsl:template>

</xsl:stylesheet>

The interesting additions are in red, first add the namespace of the multimedia schema, in this case this is the default MM schema, We use  ‘image’ as the prefix.

Then add a definition for a second attribute to the ‘img’ element, in the example we use the document function to load the entire multimedia component’s XML by passing the xlink:href attribute of the link field, this attribute’s value is the TCM URI of the image  component. (In the content component the link is stored like this: <image xlink:type=”simple” xmlns:xlink=”http://www.w3.org/1999/xlink&#8221; xlink:title=”chrome” xlink:href=”tcm:42-15992″ />)

We then use an inline XPATH statement to get to the altText metadata field.

The result of this can be seen here:

XSLT CT - component links

XSLT CT - component links

With the document function we can successfully retrieve information from any other Tridion item as long as we know its ID (TCM URI).

Conclusion

It is very easy to set up and start using the XSLT Mediator, it provides both flexibility and speed which are not catered so well by the Dreamweaver mediator and for customers wishing to make use of an XSLT based solution it gives the possibility of using XSLT templates for components and pages alike.

However this article does not show some of these advantages, In the second part of this series I will look into:

  • Extending the XSLT transformation with extension objects
  • Using Extension objects to publish binaries, render component presentations, etc.
  • Creating an XSLT Page Template

Source Code

You can download the example XSLT and Schema here.

Tying in WCF, JSON and jTemplates

June 26, 2009 5 comments

Contents

Introduction

In this post id like to show a useful way of combining a few technologies together in a way that might not be readily apparent to everyone.

Let me start by saying that I think WCF, jQuery, MS AJAX Library and jTemplates are all great each on its own, but combining all of these together can produce some amazing results in a very short time.

I won’t be concentrating too much on explaining how to work with each of the aforementioned technologies separately or dive into each of their best practices and possible appliances but rather show a concise way of using them together, there are some great articles and tutorials which ill list by the end of this article for you to go out and learn more about these subjects on your own.

Id like to apologize for the way the code fragments on this article look like, it seems that WordPress.com doesn’t support plugins so i can’t use any syntax highlighter… I’m looking into finding a host provider that will host my blog where i could install such plugins to make my technical articles look more professional, soon, i promise.

Just before we begin, a short disclaimer, The code in this article is definitely not optimized or should be taken as is, its just the essence of how you can achieve this type of result.

This article assumes the reader has previous experience working with WCF, javascript and AJAX.

Now we can begin…

Concept

The purpose of this article is to show how to create a service end-point using WCF which can be called from the client-side using JavaScript to retrieve data in JSON format and update parts of the page without causing a full post-back to the server.

I wont go into the discussion of why you would want to use AJAX instead of post-backs, there’s plenty of articles about that. I wont go into the discussion of the merits of JSON either, you can read about it here.

For demonstration purposes I decided to build a very simple “RSS Reader” which will poll on the feed from one of my favorite podcasts: The 404, it will present a list of the articles titles in the feed and allow the user to select any from that list to view its entire information.

So lets get to some coding already…

Server Side

We’ll start with the server side where we will create the WCF service and write some methods to get the RSS content.

First thing first though, lets create our website, in Visual Studio (im using 2008 SP1) create a new ASP.NET website and then:

  • Create a new folder called “Services”.
  • Right-click the new folder and select ‘Add New Item’, Select ‘Ajax-Enabled WCF Service’ and name it “TutorialService”, then click Add.

You will notice that you now have an “App_Code” folder with one class and in the Services folder you have a svc file.

Also your web.config file has been updated with the necessary information about the service and its end-point in the <system.serviceModel> element.

Notice the behavior element with the <enableWebScript/> tag, this makes your service send and receive JSON instead of XML.

You’d want to add the following XML fragment into the behaviors element

1
2
3
4
5
6
<serviceBehaviors>
   <behavior name="TutorialServiceBehavior">
     <serviceMetadata httpGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="true" />
   </behavior>
</serviceBehaviors>

This will enable you to send GET requests to the service instead of the default POST which will make your service a bit more “REST-ful”.

It will also allow you to debug your service when an exception is being thrown on the server-side by setting the property includeExceptionDetailInFaults to ‘true’. in a production environment you will probably want to set this to false.

  • Make sure you add the following attribute to the service element like so:
1
2
<service name="TutorialService" 
behaviorConfiguration="TutorialServiceBehavior">
  • Last thing to do in the configuration is change the contract attribute of the end-point from “TutorialService” to “ITutorialService” because we are going to create an interface to behave as the contract for our service.
1
2
3
<endpoint address="" 
behaviorConfiguration="TutorialServiceAspNetAjaxBehavior" 
binding="webHttpBinding" contract="ITutorialService" />
  • Close the web.config file.
  • To the App_Code folder add an interface called: ITutorialService.
  • Decorate it with the ServiceContract attribute from the System.ServiceModel namespace.  By setting the optional  ‘Namespace’ and ‘Name’ properties we’re telling the framework how to name the proxy object that will be auto-created for us on the client side.
1
2
3
4
[ServiceContract(Namespace = "Tutorials", Name="RssService")]
public interface ITutorialService
{
}
  • Add the following method definitions to the interface:
1
2
3
4
5
[OperationContract, WebGet]
IEnumerable<TutorialArticle> GetArticles();

[OperationContract, WebGet]
TutorialArticle GetArticle(string link);

These methods will be called from the client side in order to retrieve and show the content on the page.

  • Add a class to the App_Code folder called TutorialArticle and decorate the class with the DataContract attribute from the System.Runtime.Serialization namespace. This attribute will allow this class to be serialized and de-serialized when its passed back and forth between the service and the client side.
  • Add the following code to this class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[DataContract]
public class TutorialArticle
{
  public static DateTime ParseRssItemDate(string timestamp) 
  { //quick and dirty way of parsing the date element of the RSS item
   return DateTime.Parse(timestamp.Substring(0, timestamp.Length - 4), 
      CultureInfo.InvariantCulture,   DateTimeStyles.AllowWhiteSpaces);  
  }

   [DataMember]
   public string Title { get; set; }

   [DataMember]
   public DateTime PublishDate { get; set; }

   [DataMember]
   public string PublishedBy { get; set; }

   [DataMember]
   public string Link { get; set; }

   [DataMember]
   public string Description { get; set; }

   [DataMember]
   public bool New { get; set; }
}

Notice here the DataMember attribute which is used with the properties to mark them as serializable.

  • Open the TutorialService.cs file: remove the ServiceContract attribute and the default method.
  • Make your class implement the ITutorialService interface and its methods.
  • For the GetArticles method add this code:

<

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public IEnumerable<TutorialArticle> GetArticles()
{
   XNamespace rssNS = "http://purl.org/dc/elements/1.1/";

   var rssXML = 
        XDocument.Load("http://www.cnet.com/8300-13952_1-81.xml?tag=rtcol;about");

   var q = from r in rssXML.Descendants("item")
         select new TutorialArticle()
         {
           Title = (string)r.Element("title"),
           Link = (string)r.Element("link"),
           PublishedBy = (string)r.Element(rssNS + "creator"),
           PublishDate = 
            TutorialArticle.ParseRssItemDate((string)r.Element("pubDate")),
           New = (DateTime.Now.Subtract(
            TutorialArticle.ParseRssItemDate((string)r.Element("pubDate"))).TotalDays < 3)
         };

   var articles = q.ToList();

   return articles;
}

This code is using LINQ to XML in order to load the feed’s xml and convert it into a collection of articles.

  • For the GetArticle method add this code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public TutorialArticle GetArticle(string link)
{
   XNamespace rssNS = "http://purl.org/dc/elements/1.1/";

   var rssXML = 
     XDocument.Load("http://www.cnet.com/8300-13952_1-81.xml?tag=rtcol;about");

   var q = from r in rssXML.Descendants("item")
       where (string)r.Element("link") == link
       select new TutorialArticle()
       {
        Title = (string)r.Element("title"),
        Link = (string)r.Element("link"),
        PublishedBy = (string)r.Element(rssNS + "creator"),
        PublishDate =
         TutorialArticle.ParseRssItemDate((string)r.Element("pubDate")),
        New = (DateTime.Now.Subtract(TutorialArticle.ParseRssItemDate(
                    (string)r.Element("pubDate"))).TotalDays < 3),
        Description = (string)r.Element("description")
       };

   return q.FirstOrDefault();
}

This method does roughly the same as the previous one only it selects just one item based on the link parameter which is expected to be unique, its also selecting the “description” element of the article which you’d want to display in the full view of the article.

Thats all that is needed for the server-side functionality.

Client Side

Before coding the client-side logic a few things require setting up, in the downloadable source code you will find the necessary files to get everything working, this includes:

  • The jQuery library version 1.3.2 (and the vsdoc file)
  • The jTemplates plugin
  • A CSS file to style the page a little bit
  • A couple of images

If you’re following the naming convention and locations in this article to the letter, put the javascript files and css file in a folder called “System” under the root of the website. And the images in a “Images” folder.

Open the default.aspx file (you can get rid of the aspx.cs file, its not needed) and add the <asp:ScriptManager> element with the following references:

1
2
3
4
5
6
7
8
9
10
<form id="form1" runat="server">
 <asp:ScriptManager runat="server" ID="ScriptManager1">
  <Scripts>
    <asp:ScriptReference Path="~/System/jquery.js" />
    <asp:ScriptReference Path="~/System/jquery-jtemplates.js" />
  </Scripts>
  <Services>
    <asp:ServiceReference Path="~/Services/TutorialService.svc" />
  </Services>
 </asp:ScriptManager>

The ScriptReferences simply add the javascript references to the jQuery library and the jTemplates plugin js files.

The ServiceReference pointing to our svc file will automatically create a javascript proxy for the service which can be used to call the methods of the web service from the client side. [In a second article I will look into replacing this proxy with a pure javascript solution.]

A few html elements are needed to act as containers for the content which will be loaded onto the page.

  • Add the following html to your form:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div>
  <div id="Articles">
    <div id="ArticlesList">
     Loading...
    </div>
    <div id="ArticleMain">
     <div id="ArticleInfo">
     </div>
     <img id="LoadingImg" src="Images/ajax-loader.gif"
                                        class="Hidden" />
     <div id="SingleArticle">
     </div>
   </div>
  </div>
</div> 
  • Add the following code at the bottom of the page just above the </body> tag.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script type="text/javascript">

   $(document).ready(function() //executes this code when page loading is done
   {
      Tutorials.RssService.GetArticles(articlesRetrieved,
                 serviceDefaultErrorHandler); //get articles from the web service
   });

   function articlesRetrieved(results)
   {
     if (results)
     {
       if (results.length > 0)
       {   //set the articles template on the div element
        var templateItem =
         $("#ArticlesList").setTemplateURL("Templates/Articles.htm",
          null, { filter_data: false });

            //execute the template with the data
            templateItem.processTemplate(results); 
        }
        else
        {
           alert("no articles found");
        }
     }
   }

   function serviceDefaultErrorHandler(xhr, context, method)
   {
     alert(xhr.get_message()); //show error message(only on dev)
   }
</script>

You can see that VS recognized the service reference and is giving auto-completion for the service proxy which is pretty damn cool:

javascript Intellisense

The GetArticles method on the proxy class accepts two function parameters, the first is the method that will be called on a successfull request, in this case the ‘articlesRetrieved’ method will be called, the second parameter is for the function which will be called when an error has occurred.

At this point you’re simply calling the GetArticles method on the web service when the page has finished loading in the browser and displaying the count of how many were retrieved. which looks like this:

articles result

Much more interesting would be to look at the information which was downloaded to the browser using Firebug’s capability to display the network activity related to the current page.

(If you don’t know or haven’t started using Firebug, go download it right now, seriously, stop reading this and go get it, then come back and continue reading :) )

In Firebug the raw JSON data can be viewed:

Firebug Raw JSON

This is a great tool to see the amount and type of data being passed to the client but not so easy to read, using a tool such as JSON viewer paints a clearer picture:

JSON-Viewer

Now you can see that indeed 10 items were retrieved and even see the data for each one.

Next step is to actually display the data as HTML so the viewer of the page can make some sense of it, one way would be to start injecting individual element into the page’s DOM, or start concatenating all the html into a giant string and then update the page with that, both of these approaches are very problematic for several reasons, to name a few:

  • They usually result in unreadable code.
  • The more data and properties there are the more difficult it becomes to manage the code and make modifications.
  • The designer – developer process is severely hurt since there’s no design the developer can simply employ to inject the data in the right places and a designer will usually resent having to write the javascript for this themselves.

Here is where jTemplates comes into play. jTemplates is a “template engine for javascript”. It gives you the power of defining a template in HTML and inject or bind it with your data which could come from just about anywhere.

With jTemplates you can:

  • Create reusable templates
  • Have a very clear separation between data and layout
  • Bind the layout and data in just a couple lines of code
  • Enjoy the designer-developer process where each person does what they do best, designer does the layout while the developer supplies the data to be presented.

As a side note, ASP.NET 4.0 will have a very similar feature for doing client-side templates but if you wish to start using templates now, jTemplates is already available while ASP.NET 4.0 isnt and if you plan on using such a feature in your organization it will probably be easier to convince your boss to use a jQuery plugin (especially if you’re using jQuery already) than to convince them to use a preview version of ASP.NET and it will probably be a while before your organization upgrades to .NET 4.0.

With jTemplates you can now create a template either in-line in the javascript code or take the approach I prefer which is to create an HTML file which will only contain the template.

  • In VS create a “Templates” folder.
  • In this folder create a new file: Articles.htm.
  • Remove its content and paste in the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 16
17
<ul>
 {#foreach $T as article}
  <li>
    <a href="javascript:loadArticle('{$T.article.Link}')">
      {$T.article.Title}
    </a>

    {#if $T.article.New}
       <img src="images/new.gif" title="New Post" />
    {#/if}
    <div>
      Title: <b>{$T.article.Title}</b>
      <br />
      Date: <b>{$T.article.PublishDate}</b>
      <br />
      Published By: <b>{$T.article.PublishedBy}</b>
   </div>
  </li>
 {#/for}
</ul>

You will immediately notice the jTemplates syntax in between the html elements, this syntax conveniently includes a foreach structure, a if conditional and few more which make it perfect for iterating over a set of data and define a template for each item in the set as the above example does.

The {#foreach $T as article} statement begins the loop over the array of articles where $T is the root object we’re passing to the template engine, in this case its an array so it can easily be iterated over. The “as article” will make it easier to access the current item inside the loop.

Inside the loop you can access each item’s property which was marked as a DataMember so {$T.article.Title} will write out the title of the article.

You may have noticed the Boolean “New” property which the TutorialArticle has, this property is set to True when the article’s publish date is in the last couple of days, using the {#if $T.article.New} allows to inject html based on the conditional being set, so in the case of a new article the template will show an image marking it as new.

Hopefully the usefulness of such an approach to display data is immediately obvious, with just a few lines of HTML and a little bit of special syntax we achieved a result which would have been messy at best if we were to try to do this with just in-line javscript.

Now to actually bring the data and layout together on the page:

  • Go back to the default.aspx and replace the alert() line of code in the articlesRetrieved() method with this code:
1
2
3
4
var templateItem =
   $("#ArticlesList").setTemplateURL("Templates/Articles.htm",
                              null, { filter_data: false });
templateItem.processTemplate(results);

That’s it, two lines of code and presto, we have a list on the left side of the page with the titles of the articles in the RSS feed.

The first line of code will attach the template to the DIV element (“ArticleList“) that will contain the result of rendering the template.
The second line executes the template with the object passed as a parameter to the processTemplate method. This object is the response received from the web service’s GetArticles method, it should contain an array of JSON objects each having the properties of the TutorialArticle class defined on the server side.

  • Go ahead and add the next function to your page:
1
2
3
4
5
6
7
function loadArticle(link)
{
    $("#LoadingImg").removeClass("Hidden");
    $("#SingleArticle").html("");

    Tutorials.RssService.GetArticle(link,
        articleRetrieved, serviceDefaultErrorHandler);
}

This method will call the web service’s method GetArticle with the link property of the selected article as a parameter, based on this property the service can retrieve the single article with all of its information to be displayed in the main section of the page.

To display the article we will use a second template.

  • In the Templates folder create a new file called: Article.htm and replace its content with the following HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<h3>
  {$T.Title}
</h3>

{#if $T.New}<img src="images/new.gif" title="New Post" />{#/if}

<p>
  Date: <b>{$T.PublishDate}</b>
  <br />
  Published By: <b>{$T.PublishedBy}</b>
  <br />
  From: <a href="{$T.Link}">CNET</a>
</p>

<p>
  {$T.Description}
</p>

This time to present just one article there is no need for a loop, $T in this case will be the Article object itself.

  • To the default.aspx add the last function:
1
2
3
4
5
6
7
8
9
10
11
12
13
 14
15
function articleRetrieved(results)
{
  if (results)
  {
    var templateItem =
      $("#SingleArticle").setTemplateURL("Templates/Article.htm",
                                   null, { filter_data: false });
    templateItem.processTemplate(results);
  }
  else
  {
    alert("couldnt find the article");
  }

  $("#LoadingImg").addClass("Hidden");
}

In this case the code is attaching the Article.htm template to the SingleArticle DIV element and the next line executes it with the context of the result received from the service’s GetArticle method.

By now you should have a page that looks something along these lines:

Result

Review

Let’s review what we have accomplished so far:

  • We created a WCF web service with a couple of methods.
  • These methods poll on an RSS feed to get real information from the web.
  • Our service exposes the information it retrieves as JSON so it can easily be parsed and used on the client-side using javascript.
  • Using Microsoft’s AJAX client library we are able to call the methods of our service in a somewhat strongly-typed way.
  • Using jQuery and jTemplates we present the information we retrieve from the web service in a very structured, scalable and maintainable way using templates.
  • We do all of this without refreshing the page even once.

Hopefully I have been able to demonstrate the power and simplicity of combining all of these exciting technologies into one, elegant solution which can be used to create a more rich and friendlier experience for the user while making the life of the developer easier.

Source Code

You can download it here.

Resources

Follow

Get every new post delivered to your Inbox.

Join 315 other followers

%d bloggers like this: