9

How do we add anchor links in Tridion DWT? We have a scenario where we have about 10 "teaser" type components on a page that should link to the relevant "full content" on another page.

Using:

<a tridion:href="@@Component.ID@@#@@Component.title@@">blah</a>

Breaks the link resolver, which is understandable I guess. However I can't for the life of me figure out how to get this out nicely. I did using the componentLink as below:

<tridion:ComponentLink pageURI="@@PageID@@" componentURI="@@Component.ID@@" 
    templateURI="@@GetTcmFromWebDav('/path/to/template')@@" linkAttributes="" 
    linkText="Test Link" textOnFail="true" addAnchor="true" />

which adds #1, #2, #3 to the link. Unfortunately #1, #2 and #3 doesn't seem to have any bearing on where the component is on the target page. I can add attributes that I could then later process with Javascript, but that seemed rather inelegant.

I realise I'm probably missing something obvious here.

2
  • Thanks for everything so far. I think some additional clarification may be helpful. The links are from one page to another. There are additional components on the target page (an introduction, etc.), so using addAnchor or tridion:anchor won't really work unless I create a new PT for that where I can count CPs with the required template, which I can do but again seems like it should be unnecessary. tridion:anchor would seem the obvious solution, but these are Component and not Page links and so, in 2011 at least, only takes true or false and outputs numbers. Commented May 14, 2013 at 15:07
  • the numbers are outputted by design, being the ordinal position of the Component Presentation on the Page, which was a lot easier to use in the legacy VBScript Templates, but can still be used right now (in Modular Templating you will either have to change your Page Template, or use a context variable as @Chris indicated in his answer). Commented May 14, 2013 at 15:46

4 Answers 4

9

You are doing the correct thing by adding addAnchor="true" if you want to link to a specific ComponentPresentation on the target Page. You can achieve this by adding tridion:anchor="true" to your anchor in your DWT.

I am not sure why you think that the #1, #2 or #3 are wrong. These are links to the OrdinalPosition of the target Component on the Page.

To make use of these anchors, you will need to add the <a name="3">Some Text</a> style name attributes to the output of your target CPs. Unfortunately OrdinalPosition is NOT available for non-VBScript templates, so you will need to use context variables to pass it from modular PTs to the Modular CTs as shown in the linked example above.

5

To my knowledge the Tridion provided custom controls don't support either custom anchors or query string elements for component links; you will either have to resort to using inline code to resolve component links (and add the anchor/query string there) or create your own custom controls for link resolving (which can optionally extend Tridion's; all you really want to do is split off the query string or anchor before the link is resolved and add it back on afterwards).

Note that for just linking to the target page you don't need any anchors of course and if you want to link to a specific location on a page the corresponding component presentation will have to write out the anchor itself (this is also not something Tridion will automatically do for you).

4

The documentation (requires login) describes you can use the tridion:anchor attribute in your DWT Template Building Block:

<a tridion:href="@@Component.ID@@" tridion:anchor="true">blah</a>

This will output an anchor reference to your link, for Component links it will use the index (or ordinal position) of the Component on the Page you are linking to.

I think there also was a way of getting the anchor tags added to a Component Presentation but I can't seem to find out how. So simplest way of achieving that would be using this in your Page Template DWT:

<!-- TemplateBeginRepeat name="Components" -->
    <a name="@@TemplateRepeatIndex + 1@@"></a>
    @@RenderComponentPresentation()@@
<!-- TemplateEndRepeat -->

Update

Following HTML5 rules, you can actually also use any id attribute with your ordinal position, and anchors will use that similar to the name attribute of an anchor link.

So this means you could update your Page Template to look like this:

<!-- TemplateBeginRepeat name="Components" -->
    <div id="@@GetOrdinalPosition(Component.ID, ComponentTemplate.ID)@@">
        @@RenderComponentPresentation()@@
    </div>
<!-- TemplateEndRepeat -->

Now to make it work for multiple regions, I didn't use TemplateRepeatIndex + 1 here anymore, but used a Custom Function (requires login) which gets the actual ordinal position of the Component Presentation on the Page. The code for this function would be something like this:

[TemplateCallable]
public int GetOrdinalPosition(string componentUri, string componentTemplateUri)
{
    try
    {
        // assume we are used on a Page Template
        Page page = (Page)_engine.PublishingContext.ResolvedItem.Item;

        // build a Component Presentation, so we can compare that with the CPs on the Page
        Component component = (Component)_engine.GetObject(componentUri);
        ComponentTemplate componentTemplate = (ComponentTemplate)_engine.GetObject(componentTemplateUri);
        var cp = new Tridion.ContentManager.CommunicationManagement.ComponentPresentation(component, componentTemplate);

        // determine ordinal position of the given Component URI and Template URI on this Page
        return page.ComponentPresentations.IndexOf(cp) + 1;
    }
    catch
    {
        return 0;
    }
}
5
  • he already has tridion:anchor="true" in his template, and that sample will only work if there is only one ComponentPresentations collection being output on the page. Commented May 14, 2013 at 15:21
  • the question shows he was trying to add the anchor manually in his DWT template, which doesn't work, to get anchors directly from your DWT template you have to specify the tridion:anchor="true" attribute in your link (no need to manually create the tridion:ComponentLink tag). As for the ordinal position, indeed my example only works when you are looping over the default Components array, it will require more work if you create multiple Component arrays Commented May 14, 2013 at 15:40
  • Thanks so much for posting this. I had to tweak a little as IndexOf always returned -1 for some reason, but a foreach loop seemed to return the correct position. What I can't quite get my head around is why the tridion:anchor attribute on the source page is returning #1, #2, #3, #4 when the position of the components on the target page are #5, #6, #7, #8; so I'm still scratching my head. I've reordered the components to match and dropped the +1, so the solution works for this, but not all eventualities. Commented May 15, 2013 at 12:40
  • @Dave that is interesting, I just checked and indeed I seem to get #1 for every one of my anchors where it should be #2 or #3. Sounds like a defect perhaps? Commented May 15, 2013 at 12:42
  • @Dave I checked what was in my broker database for link info, and I see things I cannot explain. I have all Component Presentations on the Page listed, but in the order they appear in my HTML, including a dynamic Component Presentation which is not actually on the Page. So the deployer does something strange here, best you can do is report this behavior to Customer Support and see if they can help getting clarification (keep us posted please). Commented May 15, 2013 at 13:24
0

Given that an or an id attribute should be unique on the page and that it isn't possible to include an anchor prefix I would suggest that you create your own convention (e.g. [prefix]_[component_template_item_id]_[component_item_id]) and use extended dynamic link resolving to append the anchor conditionally when you require it.

If using static publishing you would want to intercept links within a TBB to append the convention based anchor but the same logic can be applied at publish time or runtime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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