Skip to main content

Posts

Showing posts with the label DD4T .NET Implementation

A DD4T.net Implementation - IIS URL Rewrite

I have used IIS's URL Rewrite module in several of my .net projects. It is a very neat module that gives a lot of URL rewrite/redirect functionality out-of-the-box. Namely, the module can do: URL rewrite -- rewrite the URL path before request processing starts (similar to a server transfer); URL redirect -- redirects the client browser to a modified URL by sending back redirect HTTP status codes; Rewrite outgoing URLs in the response body; My requirements have so far involved using URL rewrite together with the outgoing URLs rewrite in the response. For example, I had recently the following use case -- my client has legacy .aspx pages under location /devices . There are new DD4T .html pages in the system, but because of some routing restrictions they had to be placed under a temporary location /device (notice the difference from /devices). The .html pages should, however, be exposed to the internet as if they belonged to folder /devices . Example: /device/page.html  sh...

A DD4T.net Implementation - Extending the LinkFactory

In my current DD4T .net implementation, I encountered the requirement of having Rich Text Format fields resolved in a custom way. Namely, I had to check whether the type of a RTF Component link is of a wrapper around the actual Component to link to, and if so, resolve the link to the wrapped Component. An elegant way of doing to is to extend the default DD4T.ContentModel.Factories.LinkFactory and create a new method ResolveRTFLink(string componentUri) : public interface IMyLinkFactory : ILinkFactory { string ResolveRTFLink ( string componentUri); } The implementing class would extend DD4T LinkFactory and implement IMyLinkFactory : public class MyLinkFactory : LinkFactory, IMyLinkFactory { [Inject] public virtual IComponentFactory ComponentFactory { get ; set ; } [Inject] public virtual IModelFactory ModelFactory { get ; set ; } At the same time the class must provide an implementation for  ResolveRTFLink  method: public strin...

A DD4T.net Implementation - Custom Binary Publisher (part 2)

In previous post Custom Binary Publisher , I presented the main logic needed to publish our Multimedia Components using custom code in DD4T .net. In this post, I present the Template Building Blocks (TBB) that call the custom binary publisher. If you take a closer look at the code, you will notice it is basically the same code as the existing TBBs PublishBinariesComponent and PublishBinariesPage . I just created a separate PublishBinariesHelper class that uses the CustomBinaryPublisher described earlier. Calling methods PublishMultimediaComponent and PublishBinariesInRichTextField will call the overridden method PublishItem . public class PublishBinariesHelper { private readonly CustomBinaryPublisher binaryPublisher; public PublishBinariesHelper (Package package, Engine engine) { binaryPublisher = new CustomBinaryPublisher(package, engine); } public void PublishAllBinaries (Component component) { if (component.ComponentType =...

A DD4T.net Implementation - Custom Binary Publisher

The default way to publish binaries in DD4T is implemented in class DD4T.Templates.Base.Utils.BinaryPublisher and uses method RenderedItem.AddBinary(Component) . This produces binaries that have their TCM URI as suffix in their filename. In my recent project, we had a requirement that binary file names should be clean (without the TCM URI suffix). Therefore, it was time to modify the way DD4T was publishing binaries. The method in charge with publishing binaries is called PublishItem and is defined in class BinaryPublisher . I therefore extended the BinaryPublisher and overrode method PublishItem. public class CustomBinaryPublisher : BinaryPublisher { private Template currentTemplate; private TcmUri structureGroupUri; In its simplest form, method PublishItem just takes the item and passes it to the AddBinary. In order to accomplish the requirement, we must specify a filename while publishing. This is the file name part of the binary path of Component.BinaryConten...

A DD4T.net Implementation - A Dynamic Publication Resolver

In the previous post Simple Publication Resolver , I presented a simplistic way of putting generic pages into Publication context by identifying the Publication URL by just applying a regular expression to the URL path. In this post, I present a proper Publication Resolver algorithm, for DD4T.net, that dynamically maps Publication IDs to Publication URLs and vice versa. The interface of a Publication Resolver defines 2 methods: GetPublicationUrl and GetPublicationId , which provide retrieval functionality for mapped Publication ID and URL. public interface IPublicationResolver { string GetPublicationUrl ( int publicationId); int GetPublicationId ( string publicationUrl); } The implementing class, PublicationResolver , defines an algorithm that dynamically discovers the mapped ID for a given Publication URL and the other way around. It makes use of the Tridion Content Delivery API PublicationMetaFactory to retrieve the PublicationMeta object containing informat...

A DD4T.net Implementation - A Simple Publication Resolver

In previous posts I referred to a utility method GetPublicationUrl . This method simply looks up the current request path and returns the first two levels under the root. In my current implementation it is these two levels that identify the Publication. For example, for URL path /zh/cn/products/abc.html , method GetPublicationUrl returns " /zh/ch/ ". In different implementations, it could be that only the first level of the URL path represents the Publication URL, but that is a matter of choice and URL design. The code below show casts the simple GetPublicationUrl method, which applies a regular expression pattern to the given (current) URL path. The regular expression pattern matches only if the path starts with slash and is followed by two characters, followed by slash, followed by two characters, followed by slash. In this case, it extracts the 2 level nested folders and returns them. public static class UriHelper { private static readonly Regex Publica...

A DD4T.net Implementation - Pagination (AJAX)

This is the third and last post on the topic of implementing a pagination solution for lists of Dynamic Component Presentations retrieved by a query. If you haven't already done so, please read the first two posts to put things in context: Pagination - Models Pagination - Views This post deals with client-side Javascript code performing the AJAX call to the server-side code and displaying the returned HTML. In the current architecture, the server-side components render a snippet of HTML (i.e. the only piece of markup that changes between two page iterations). I use Javascript (JQuery) to replace the content of a container DIV with the HTML returned by the DD4T server-side partials. Since we receive rendered HTML back, it is quite simple to perform the DIV content replacement. No other rendering, parsing or processing is necessary as if we had received JSON back from the server. I chose this approach because it fits better with the Tridion and DD4T architecture. I can easi...

A DD4T.net Implementation - Pagination (Views)

In previous post Pagination (Models) , I presented a way of modeling the server-side code to display dynamic lists of Dynamic Component Presentations (DCP) using AJAX. In this post, I present the server-side view logic in context of MVC .net architecture and using Razor CSHTML views. As presented in the previous post, the Controller creates a model class that contains the paginated list, and it then attaches this model to the ViewBag. In the example it was DeviceController, that created model DocumentPartial which contained a paginated list of documents. We now need to display this list of paginated items in a Razor view. In order to make the logic reusable and succinct, I implemented the paginated view as partial view. The Component view corresponding to the controller includes the partial view and passes to it the model previously saved in the ViewBag. This makes the partial view generic and reusable from other contexts. To continue our earlier example, the view corresponding...

A DD4T.net Implementation - Pagination (Models)

This post adds pagination capabilities to an AJAX Dynamic Component Presentation (DCP) presented in an earlier post Rendering Only a Partial for AJAX . The use case is the following: we have a controller that displays a list of DCPs in a paginated way. Due to the dynamic nature of this list, the list of DCPs should be rendered as a partial using AJAX. This implies that an actual AJAX request is made to the controller, which triggers only the list of DCPs be recalculated and served back. The paginated AJAX URL produces HTML directly, therefore the Javascript logic can simply replace the container div 'innerHTML' with the markup received from pagination. A whole page reload is thus not necessary. Additionally the list of DCPs can be sorted before being paginated, but about that in a later post. This post descries the server-side model builder that generated the paginated list of models. In a subsequent post I will present the server-side views that render the same and the cli...

A DD4T.net Implementation - Navigtion Utils

In the previous posts Navigation and Navigation (part 2) , I presented the NavigationFactory class and the object model obtained by deserializing the navigation XML. In this post, I will present simple examples of creating breadcrumb and navigation structures. Breadcrumb When rendering a breadcrumb trail, we start by locating the NavigationItem in the navigation object model corresponding to the current page, and then we follow the "ParentItem" relation to go up until the navigation root. We retain each NavigationItem that we encounter in this traversal. Finally, the breadcrumb trail is the reversed list of these NavigationItems. The following code is part of the NavigationFactory and returns an array of NavigationItem objects corresponding to the breadcrumb trail. public NavigationItem[] GetBreadcrumb (NavigationItem page) { IList<NavigationItem> result = new List<NavigationItem>(); if (page != null ) { do { ...

A DD4T.net Implementation - Navigation (part 3)

Check out the previous posts about the NavigationFactory: Navigation and Navigation (part 2) . I presented a way to deserialize the navigation XML into an object model and then serve it through a factory class that uses caching. In this post, I will present a simple way of locating a certain node in the navigation object model. Locating a NavigationItem is done by comparing it in some way to a given identifier. The most natural way is to retrieve an item by its TcmUri. In order to do so, I defined the following method on the INavigationFactory interface: NavigationItem GetItemById (Navigation navigation, string tcmUri); The implementation of this method traverses the Navigation object passed as parameter and applies a Comparator to it, hoping to identify the given tcmUri. The method calls helper method FindItem that performs the recursive traversal of the Navigation object model. public NavigationItem GetItemById (Navigation navigation, string pageUri) { if...

A DD4T.net Implementation - Navigation (part 2)

In previous post, Navigation , I presented the foundation for deserializing the navigation XML into an object model. In this post, I'll continue presenting the NavigationFactory class and the integration with caching. The NavigationFactory class is a singleton wired through dependency injection (such as Ninject) that uses caching to serve navigation object model for a given Publication. [Inject] public virtual ICacheWrapper CacheWrapper { get ; set ; } public Navigation GetNavigation () { string publicationUrl = UriHelper.GetPublicationUrl(HttpContext.Current); string key = GetKey(publicationUrl); Navigation navigation; object cacheElement; if (!CacheWrapper.TryGet(key, out cacheElement)) { string virtualPath = publicationUrl + "system/navigation.xml" ; string filePath = HttpContext.Current.Request.MapPath(virtualPath); navigation = ParseXml<Navigation>(filePath); SetParent(navigation); ...