Retrieving values of a linked component in Dreamweaver TBB - and making it SiteEditable
Asked Answered
E

4

6

I am working on Dreamweaver TBBs in SDL Tridion 2011 SP1.

I am unaware of handling component links in Dreamweaver TBBs.

Consider my Component name is "A" which has link to another component "B".

Component A source looks like this:

<Content xmlns="Some UUID">
    <Name xlink:type="simple" xlink:href="tcm:184-1897" 
          xmlns:xlink="http://www.w3.org/1999/xlink" xlink:title="B"></Name>
</Content>

Component B source is:

<Content xmlns="Some other UUID">
    <first>first field</first>
    <second>second field</second>
</Content>

I want to write a DWT TBB which can access the fields in the linked component B from Component A.

I want to use RenderComponentField rendition method.

Do I need to add any extentions to it, will I be able apply SiteEdit on it.

Please share your views on it.

Thank you.

Erminois answered 21/4, 2012 at 6:13 Comment(0)
H
6

There are two separate questions in this topic:

  1. How to access fields from a linked Component in DWT?
  2. How to make fields from a linked Component editable in SiteEdit 2009?

This is the answer to question 1. I will provide a separate answer for question 2.

In Tridion's default handling of expressions in DWT templates you only have access to fields of Components that are in the package. So if you want to access the fields of Component B, you will have to write a C# TBB that pushes that Component into the Package.

A sample C# fragment:

var componentA = (Component) engine.GetObject(package.GetValue("Component.ID"));
var fieldsA = new ItemFields(componentA.Content, componentA.Schema);
var linkField = (ComponentLinkField) fieldsA["Name"];
var componentB = linkField.Value;
var itemB = package.CreateTridionItem(ContentType.Component, componentB);
package.PushItem("ComponentB", itemB);

If you put this in a C# fragment TBB and drop it into your CT before the DWT, you can do this in your DWT:

@@ComponentB.Fields.first@@

Alternatively you can use Nuno's Dreamweaver Get eXtension (DGX) to access such fields without writing a TBB:

@@Get("Fields.Name.first")@@"/>

The only downside to using the DGX is that you will need to install it on every Tridion server. After that, a heap of extended functionality is available in your DWTs.

Homogenize answered 21/4, 2012 at 12:18 Comment(0)
H
5

Allowing fields of a linked Component to be editable has been introduced in SiteEdit 2009 SP2. The SiteEdit front-end works based on the SiteEdit command language that is embedded into the HTML it gets back from the staging server.

So let's say you have a single Component in there:

<div class="cp">
    <!-- Start SiteEdit Component Presentation: {"ID" : "cp_1", 
         "ComponentID" : "tcm:12-549", "ComponentTemplateID" : "tcm:12-568-32",
         "ComponentVersion" : 5, "IsQueryBased" : false  } -->
    <label>Title: </label>
    <span>
        <!-- Start SiteEdit Component Field: {"ID": "cf_1", 
             "XPath": "tcm:Content/custom:Content/custom:Title", 
             "IsMultiValued":false} -->
        Tips for getting insurance when you have a pre-existing condition
    </span>
</div>

Those Start SiteEdit comments in there are commands that your HTML gives to SiteEdit and you can see how they mark the Component Presentation and the title field.

If you render fields of a linked Component, you need to also have a corresponding Component Presentation command like this:

<div class="cp">
    <!-- Start SiteEdit Component Presentation: {"ID" : "cp_1", 
         "ComponentID": "tcm:12-54", "ComponentTemplateID": "tcm:12-56-32",
         "ComponentVersion" : 5, "IsQueryBased" : false  } -->
    <label>Title: </label>
    <span>
        <!-- Start SiteEdit Component Field: {"ID": "cf_1", 
             "XPath": "tcm:Content/custom:Content/custom:Title", 
             "IsMultiValued":false} -->
        Tips for getting insurance when you have a pre-existing condition
    </span>
    <br />
    <div class="cp">
        <!-- Start SiteEdit Component Presentation: {"ID" : "cp_2", 
            "ComponentID": "tcm:12-85", "ComponentTemplateID": "tcm:12-60-32", 
            "ComponentVersion" : 2, "IsQueryBased" : true  } -->
        <label>Byline: </label>
        <span>
            <!-- Start SiteEdit Component Field: {"ID": "cf_2", 
                 "XPath": "tcm:Metadata/custom:Metadata/custom:ByLine", 
                 "IsMultiValued":false} -->
            "It's a huge problem, because ..." says one expert.
        </span>
        <br />
        <label>Copyright: </label>
        <span>
            <!-- Start SiteEdit Component Field: {"ID": "cf_3", 
                 "XPath": "tcm:Metadata/custom:Metadata/custom:Copyright", 
                 "IsMultiValued":false} -->
            Getty Images
        </span>
    </div>
</div>

The there are now two Start SiteEdit Component Presentation commands, one for the outer Component and one for the linked Component. One important thing to note here is that the IsQueryBased property of the nested Component Presentation must be set to true. This tells the SiteEdit front-end that the Component Presentation is indeed not supposed to be present in the Page XML it retrieves from Tridion.

To the SiteEdit front-end it doesn't matter how the commands are put into the HTML.

Most common is for people to call RenderComponentPresentation and RenderComponentField, which marks the corresponding parts. But unfortunately the RenderComponentField function can only be used to render fields from the so-called "context Component", which it looks up like this:

Item component = _package.GetByType(ContentType.Component);

This means that in a single DWT all calls to RenderComponentField will work on the same context Component. So you can never call RenderComponentField in a single DWT to render fields from two different Components.

You have two options to solve this:

  1. Call RenderComponentPresentation for the linked Component
  2. Render the Start SiteEdit Component Presentation and Start SiteEdit Component Field commands yourself in the DWT

Option 1 is the cleanest separation you can get: since you are rendering fields from another Component, you are essentially rendering another Component Presentation. If you split out the layout for the linked fields into a separate DWT and build a CT around that, you can render it like this in your main DWT:

@@RenderComponentPresentation(Component.Fields.Name, "tcm:1-2-32")@@

Walter explained this best in his article on Tridion templating:

Since the scope of this Dreamweaver template is limited to displaying the current component fields, an extra step is necessary by using the RenderComponentPresentation function. We need to pass the TCM URI of the multimedia component to this function, together with the TCM URI of another Dreamweaver template.

Although it does lead to more CTs and DWTs, those DWTs will be a lot simpler since you can now use RenderComponentField in them as usual.

Option 2 really just means that you're outputting the HTML comments with the SiteEdit commands in your DWT. Since the command language is documented as part of the API (see link above) there is little chance that it will change in future versions of SiteEdit 2009.

Sorry for the long story, you happened to trigger a tricky use-case here. I hope it makes sense.

Homogenize answered 21/4, 2012 at 14:28 Comment(2)
Frank, you've mentioned "so-called context component", was that a definition of it: _package.GetByType(ContentType.Component); ? In another words: is the top-most package item of type Component called "context component"? (..and as a result is subject to mentioned behaviour)Autonomy
The name "context component" is just something I used here to make the behavior clear. It is not a term that SDL codified anywhere to mean specifically what I used here.Homogenize
A
2

If you are using SiteEdit 2009 it is possible, just a bit more difficult than it would be with the main component fields. SiteEdit works by wrapping the content fields with JSON markup. There's no reason why you can't detect if the publication target is staging and write this JSON out yourself.

Alternatively Will Price has developed some Template Building Blocks to help with SiteEdit which are available here.

These are accompanied by a guide here, specifically the section on embedded components will be of use to you.

Autoharp answered 21/4, 2012 at 11:47 Comment(0)
P
-2

You cannot read the fields from B using standard Dreamweaver templates. You will need to write a C# TBB to extract the linked Component and place it in the package as type Component. You then can use DWT syntax to read the fields from that component. Eg: @@linkedComponent.Fields.first@@

Siteedit is problematic on this one and different versions use different syntaxes and capabilities. I'm afraid with the latest version you cannot edit such fields...

Patriapatriarch answered 21/4, 2012 at 8:20 Comment(1)
SiteEdit 2009 SP2 (and later) CAN edit fields form linked Components as long as you mark them up correctly. I'll provide an example in a separate answer.Homogenize

© 2022 - 2024 — McMap. All rights reserved.