Tag Archives: DD4T

DD4T is a lightweight framework on top of the Tridion APIs, aimed at facilitating the development of dynamic web sites with Tridion.

Changes in DD4T 2.1 for Java

Version 2.1 of DD4T has seen many improvements and changes with respect to the DD4T 2.0.X branch. While most changes are compatible with 2.0.X, it is recommended to upgrade your web application to the 2.1.X version. The main reason is that the 2.0.X releases will be discontinued and active development on it has stopped. Additionally, new versions of the DD4T Template Building Blocks may push new data formats or properties to the front end and these will only be incorporated in the DD4T 2.1 branch. New implementations are further encouraged to use the latest version, even if you already have published DD4T 1.0 XML or DD4T 2.0.X / 2.1.X Json in your Broker database, in order make use of the latest support for libraries, Tridion and fixed issues.

Continue reading

DD4T.Web: Publication Resolving

The next DD4T release (1.30) which will be out shortly, features a new .NET library: DD4T.Web. This library contains functionality which can be used within a .NET web application, regardless of whether you are using MVC or not. In a short series I will introduce the most important functionality in this library. This episode: Publication Resolving.

 

DD4T is all about URLs. When the request comes in, the framework looks in the Tridion broker database for pages with a matching URL. Or rather: a matching path. For example: if the URL is http://www.acme.com/products/foobar.html, the path is /products/foobar.html.

But what if there are more matches? This is entirely possible because of Tridion’s BluePrinting model. Imagine the Acme corporation decides to launch a German web site, with the base URL http://www.acme.de. They manage this site in a Tridion publication which is a child of their ‘dotcom publication’ (which manages the www.acme.com site). Given the nature of BluePrinting, the German page about their ‘Foobar’ product, will have the url http://www.acme.de/products/foobar.html, and the path of this page is /products/foobar.html.

As you see, the path is identical to the path in the English publication. So how can DD4T tell which page to serve? This is done by the PublicationResolver. This is a very simple class, whose job it is to find out which publication the current request belongs to. In the example above, the PublicationResolver could look at the host name and return the correct publication id: if the host name is ‘www.acme.de’, it should return the id of the German publication, if it’s ‘www.acme.com’ it returns the id of the DotCom publication.

Resolving the publication based on the host name is an obvious choice in many cases, but there are alternative scenarios. For example: you could look at the preferred browser language and base the publication id on that. So: if my browser language is German, I will see the German site, regardless of the host name. Technically, I wouldn’t need the www.acme.de domain at all (although I don’t think Google will like it if the same URL can return a page in different languages!)

And then there is the simplest form of all: you can simply decide that all the requests in your web application should use the same publication id. This is actually the default behavior. DD4T comes with one implementation of the PublicationResolver interface, the DefaultPublicationResolver, and it simply looks in the Web.config for an appSetting called ‘DD4T.PublicationId’. This id is then used to look up all the pages, components and binaries. The downside is of course that you need to set up a separate web application for each language that you’re supporting. Not very efficient and tough to manage!

 

Implement your own resolver

It’s very easy to write your own publication resolver.

  • First, create a class library project in Visual Studio.
  • Add a class which implements the DD4T.ContentModel.Contracts.Resolvers.IPublicationResolver.  
  • Right-click the word IPublicationResolver and select ‘implement interface’.

Your code now looks like this:

using System;
using System.Web;
using DD4T.ContentModel.Contracts.Resolvers;

namespace Trivident.DD4T.Examples.PublicationResolvers
{
   public class HostNamePublicationResolver : IPublicationResolver
   {
      public int ResolvePublicationId()
      {
      }
   }
}

As you see, this interface defines only one method: ResolvePublicationId(). In that method, we will check the host name in the URL and use it to determine the publication id. In a very simple (not to say a moronic) form, the code might look like this:

using System;
using System.Web;
using DD4T.ContentModel.Contracts.Resolvers;

namespace Trivident.DD4T.Examples.PublicationResolvers
{
   public class HostNamePublicationResolver : IPublicationResolver
   {
      public int ResolvePublicationId()
      {
         switch (HttpContext.Current.Request.Url.Host)
         {
            case "www.acme.de":
               return 17;
            case "www.acme.com":
               return 16;
         }
         throw new InvalidOperationException(string.Format("unknown hostname '{0}", HttpContext.Current.Request.Url.Host));
      }
   }
}

In a real life implementation you would probably want to get rid of the hardcoded IDs, but the point is clear, I hope.

Using  it in your application

The PublicationResolver is a property of the factories (PageFactory, ComponentFactory, BinaryFactory, LinkFactory). If you’re using a dependency injection framework (like MEF or Unity) you can simply configure it as a dependency of those factories. Otherwise, you can set it manually (in code). In your PageController for example:

 

private IPageFactory _pageFactory = null;
public override ContentModel.Factories.IPageFactory PageFactory
{
   get
   {
      if (_pageFactory == null)
      {
         _pageFactory = base.PageFactory;
         _pageFactory.PublicationResolver = new HostNamePublicationResolver();
      }
      return _pageFactory;
   }
}

 

Using DD4T without publication resolving

It’s possible to use DD4T without doing any publication resolving. In that case the publication is not used when looking up the page in the broker database. This works if all the paths in your system are unique. So in our Acme example, the URLs of the English and German ‘foobar’ pages should be:

  • http://www.acme.com/products/foobar.html (English)
  • http://www.acme.com/de/products/foobar.html (German)

In this case, DD4T can and will always find the correct page.

If ‘the business’ can live with this style of URL, then go for it. It saves you the trouble of resolving anything!

To use this approach, just use the default publication resolver (this requires no action) and remove the key ‘DD4T.PublicationId’ from the Web.config.

 

 

 

 

Inside DD4T: templates without metadata

If you’re using DD4T, you know that you have to assign metadata to your templates. It is through this metadata that DD4T knows which view to use to render a given page or component presentation.

Now, DD4T can also work without metadata on templates. How? Simple: by using a naming convention. Just give your view the same name as your template, and you’re done.  This is in line with the ‘convention over configuration’ mechanism which is embraced by the MVC world.

There is one caveat: if your template name contains spaces, these are removed before looking up the view. So if your page template is called ‘Standard Mobile’, the file containing the view should be named ‘StandardMobile.cshtml’.

Of course, the good old metadata still works, and will continue to be supported as a way to override the default.

 

Mixing content and functionality with DD4T

Today I received a question from a developer who is just starting on DD4T. He wants to have a page which consists of regular Tridion content but also contains a form. Being a .NET MVC developer he naturally wants to handle this form with a controller and various  actions to handle GET and POST and perform validation as well as sending an email on successful submission.

I call this type of web page, which combines plain content with application logic, a ‘mixed’ or ‘hybrid’ page. DD4T was designed to handle such pages (as well as the more simple content pages). To understand how DD4T does this, you need to know that the framework uses controllers and actions on two different levels:

  • The level of the page (just like in any MVC app)
  • The level of the component presentation

Let’s start by looking at a very simple page, which does NOT contain any forms or other application logic:

 

As you see, there are two views involved to build this rather simple page. The controller and action are predefined by the framework – unless you override them, which I will explain later. The controller/action for the page retrieves the page from the Tridion broker and uses that as its model. The controller/action for the component uses the component as its model. All YOU need to do is write the views.

You may wonder how DD4T knows which views to call. This is achieved by configuring the name of the view in the metadata of the page template and component template.

Now I’m coming back to the question of mixed pages. A mixed page has application logic as well as plain content. To handle application logic in MVC, you need a controller and an action. For example: you might want to display a form when the method is GET, and validate it when the method is POST.

In a diagram, this is how it will look:

The page now contains two component presentations: one that represents (and contains) just plain content and another one that represents the form. The neat thing is that your custom action will automatically be called by DD4T. All you need to do is configure your custom controller and action using metadata on the component template. So instead of just specifying a view, you will now have to specify a controller and action as well.

Advantages of this ‘mixed page’ approach:

  • Tridion stays in control of the URL
  • Editors can decide where to put a form, and which other pieces of content to put next to it
  • The placement of the form and other pieces of content is handled by the exact same view as on normal pages, so you do not have to do extra coding.
  • All MVC functionality like model binding and validation are fully supported

Happy coding!