Take the 2-minute tour ×
Tridion Stack Exchange is a question and answer site for Tridion developers and administrators. It's 100% free, no registration required.

I need to build header/footer in a DD4T based website using Tridion 2011 SP1.

My proposed approach is to

  • publish the header Component dynamically
  • In the controller/action, write the broker API to query the Component using ItemTitleCriteria (as I don't have any metadata associated)
  • to get the TCMID of the Component,
  • fetching it's content and
  • build the header

I have two questions -

  1. Can we write broker queries in the DD4T controller/action.
  2. Is the above approach advisable or there is a better way to achieve the same?
share|improve this question
add comment

2 Answers 2

I'd say that your approach is solid as the headers and footers are in a single item, which means they can be published once and changed globally.

I typically have a configuration file where I store 'global components' by TCM ID, this means you can get the item from the broker via the following:

var componentFactory = DependencyResolver.Current.GetService<IComponentFactory>();    
IComponent component = componentFactory.GetComponent("tcm:123-45678");

But this does mean that the TCM ID must be changed in the event the ID is different from one environment to another.

I suspect the issue with the ItemTitleCriteria is that your users can change the component title in the CMS which would break your code. Other alternatives are:

  1. Use taxonomies - create a 'Global Components' taxonomy and in there have keywords for 'Header' and 'Footer' - but ensure this is a 1-1 relationship in the CMS

  2. Use the schema - If your header is based on a 'header' footer and again is a 1-1 relationship with the component you could do down this route.

Hope this helps.

share|improve this answer
2  
FWIW, I tend to publish these TCM configuration items from Tridion, and have a configuration component where I store the webdav URLs of the items, and the template that publishes it resolves the URL to a URI, solving your "different per environment" issue. –  Nuno Linhares Mar 26 at 10:22
2  
the problem with webdav urls, is that they can be changed by users. –  johnwinter Mar 26 at 11:06
3  
I dont think there is any silver bullet, you either have TCM URIs (which are environment dependent) or Webdav URLs (which are subject to changing titles). I typically have a set of system component folders (config, resources, header/footer etc.) and use a .NET TBB to publish info about the items in them. The folder webdav url(s) are parameters passed to the .NET TBB –  Will Price Mar 26 at 11:10
    
+1 for "the problem with webdav urls, is that they can be changed by users" ... I've always seen WebDAV URLs as better than TCMIDs but more and more I see editors break this by renaming a Tridion {organizational} item (and they will not correlate the sudden break with renaming - simply exclaiming - "I did't do anything") - it's much less likely they will delete and (re)create a new version of the same thing. –  Dylan .. Mark Saunders Mar 26 at 12:38
add comment

I've had some success with this approach (example used is for a footer but could easily be applied to a header):

  1. Create a Generic DD4T XML Page Template that Publishes a DD4T page with an XML extension (the extension itself is actually fairly arbitrary).
  2. Create a Generic DD4T Component Template with no specific view/controller/action.
  3. Create a Page for the footer in Tridion, add Component Presentations for the relevant parts of the footer. Define a convention for where this Page will be published (e.g. \Root\_system\Footer).
  4. Create a LayoutController in your application and a Footer action.

Inject an IPageFactory into this controller and use this to resolve your page:

[ChildActionOnly]
public ActionResult Footer()
{
    var model = new FooterViewModel();    
    IPage page;

    if (_pageFactory.TryFindPage("/_system/footer.xml", out page)
        && page.ComponentPresentations.Any())
    {
        // map page to model
    }

    return PartialView("_Footer", model);
}

Then, in your layout, you just need to do this:

@Html.Action("Footer", "Layout");

Obviously this will need adapting to your specific scenario (e.g. to make the footer page path configurable); but this gives you exactly the same setup for your footer view as for your Component Presentation views, with the exception being that the Page URL is preconfigured.

This is particularly convenient if you're using some kind of mapping framework to map Component Presentations to view models as your mapping code doesn't have to change.

It's generally best if you wrap everything up in one Component Presentation on this Page as you can then just map the first CP on the Page and treat the view like any other Component Presentation view.

If, however, you need more flexibility in terms of different Component Templates on the header/footer, you can pass page to the view directly and then use RenderComponentPresentations as if it was a normal Page Template. If you go down this route, you'll need to swap the Generic DD4T Component Template for "proper" CTs with associated views/actions.

I find that this is also quite intuitive for content editors as they can just treat the footer as "another page."

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.