eZ Community » Blogs » Harry Oosterveen » The Additional Nodes Pitfall

By

The Additional Nodes Pitfall

Wednesday 14 March 2012 11:51:38 pm

  • Currently 5 out of 5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Since the early versions 3.x there have been issues with the concept of additional nodes. The Technical Manual keeps mentioning it as a 'Pitfall', but nothing has happened to address the problem: in one location, content is visible with the subitems, in another location, the content is without the subitems. This article describes how the problem can be addressed.

An object may be referenced by several nodes, which means that the same object can appear at different locations within the tree. This feature can for example be used to place a specific news article at two locations: the front page and the archive. But when a new location is added to an object, eZ Publish will not go through and create replica of the node structure below the object's original location. For example, if a folder containing several sub-folders with articles, images, etc. is assigned a secondary location, the sub-folders with articles, images, etc. will not be automatically available below the new location of the folder.

The text may sound familiar, the lines are copied from the Technical Manual, http://doc.ez.no/eZ-Publish/Technical-manual/3.6/Concepts-and-basics/Content-management/The-content-node-tree. Version 3.6, that's 2005. Outdated? The same text is still in the recent version 4.6.

I refered to the 3.6 edition, as this showed up in the search results, and there are some comments complaining about not replicating the sub-structure and asking for a fix. There was even a request to address the issue back in 2003.

As far as I know, this is still an issue. Will it be addressed before it's 10th anniversary?

An attempt

To resolve the problem, the distinction of main nodes and additional nodes needs to made more sharp. Currently, there is little difference between the main node and additional nodes, and one can indeed easily switch the main node for any additional nodes, it is a standard feature of the admin site.But why would you bother, if the only reason to distinguish a main node seems to be to avoid duplicates in search results? Beats me.

At IRC's website (and all other eZ websites I have built) we have addressed the problem by using additional nodes only as links to the main location. To make this work, a number of issues have to be addressed. These are listed below, with the way we have solved it by overriding templates, or worked around it. There may be more issues, so please comment to give your additions. 

1. All additional nodes link to the main location.

To do so, override templates that show an item as a link, like in node/view/line.tpl.
You find something like

 node_url=$node.url_alias

Change this into

 node_url=$node.object.main_node.url_alias

Alternatively, wherever a list of subitems is fetched, use the main_node as parent:
Find occurences like

 children=fetch('content','list',hash(parent_node_id,$node.node_id, ...

Change this into

 children=fetch('content','list',hash(parent_node_id,$node.main_node_id, ...

2. Add items only under the main node

In the template design/admin2/templates/node/view/full.tpl, you find:

 {* Children window.*}
<div id="content-view-children">
{if $node.is_container}
    {include uri='design:children.tpl'}
{else}
    {include uri='design:no_children.tpl'}
{/if}
</div>

In the override template, change it to:

 {* Children window.*}
<div id="content-view-children">
{if $node.is_container}
    {if $node.is_main}
        {include uri='design:children.tpl'}
    {else}
           <p>Children can only exist under the <a    href={$node.object.main_node.url_alias|ezurl}>main    node</a>.</p>
    {/if}
{else}
    {include uri='design:no_children.tpl'}
{/if}
</div>

3. Disable changing the main node

In the template design/admin2/templates/locations.tpl, you find:

     {* Main node. *}
    <td>
 
    {if $assignment_node.can_edit}
 
    {if $assignment_count|gt( 1 ) }
    <input type="radio" {if $assignment_node.is_main}checked="checked" class="main-locations-radio main-locations-radio-initial"{else}class="main-locations-radio"{/if} name="MainAssignmentCheck" value="{$assignment_node.node_id}" title="{'Use these radio buttons to select the desired main location.'|i18n( 'design/admin/node/view/full' )}" />
    {else}
    <input type="radio" {if $assignment_node.is_main}checked="checked"{/if} name="MainAssignmentCheck" value="{$assignment_node.node_id}" disabled="disabled" title="{'The item being displayed has only one location, which is by default the main location.'|i18n( 'design/admin/node/view/full' )}" />
    {/if}
 
    {else}
 
    <input type="radio" {if $assignment_node.is_main}checked="checked"{/if} name="MainAssignmentCheck" value="{$assignment_node.node_id}" disabled="disabled" title="{'You cannot set the main location because you do not have permission to edit the item being displayed.'|i18n( 'design/admin/node/view/full' )}" />
 
    {/if}
 
    </td>

In the override template, change it to:

     {* Main node. *}
    <td>
 
    <input type="radio" {if $assignment_node.is_main}checked="checked"{/if} name="MainAssignmentCheck" value="{$assignment_node.node_id}" disabled="disabled" title="{'You cannot set the main location because you do not have permission to edit the item being displayed.'|i18n( 'design/admin/node/view/full' )}" />
 
    </td>

If you have to change the main node, you can still do so:

  1. Delete the additional node that should become the parent node
  2. Move the main node to this location
  3. Create an additional node in the previous location of the main node.

A bit more work, but how often do you have to do this?

4. Change behaviour when deleting a main node

Currently, if you delete a main node, and there are additional nodes, it will delete the main node and all subitems, but leave the object and make one of the additonal nodes the new main node.

In line with the idea that additional nodes are just links, deleting a main node should always delete the object and all additional nodes, after giving appropriate warnings and ask for confirmation. We have not made this change in the kernel. As a workaround, if the situation occurs, we manually delete all additional nodes first and then remove the item. If main nodes are accidentally deleted, we have to rely on the ezrestoresubtree script, described in my previous blog post.

More issues

As I mentioned, there may be more issues, so please comment to give your additions.

Proudly Developed with from