Forums / Setup & design / Dynamic right column

Dynamic right column

Author Message

Yngve Bergheim

Tuesday 04 October 2005 4:39:27 am

My goal: I want to show dynamic content in the right column (where Latest News now is shown), which can be unique to each folder. Let's say you have a "home/Sports" folder, and you want to display sport articles in both the main area and the right column. In a "home/Science" folder you want to display just science articles in main and right column. In folder "home/Sports/Soccer" you don't have a soccer right column, so you display the parent's right column, Sports.

Ok, still with me?

I'm a looser in the eZ template language so I'm not near any solution jet, but I guess this might be a good start:

In every folder look for a child folder called "RightColumn". If not found, look for, the "RightColumn" folder in parent folder, if not found, look in grand parent folder etc. When found, get all the children in that folder and display them.

Can someone please help me in the right direction in the template language?

Yngve Bergheim

Tuesday 04 October 2005 4:43:56 am

And I was thinking of setting the "RightColumn" folder to be hidden, so it doesn't show in the main content.

Matt Reston

Tuesday 04 October 2005 10:32:58 am

Excellent. Unfortunately i can't help you with this, but i was about to post the very same question and also await any information people can provide.

Yngve Bergheim

Wednesday 05 October 2005 2:45:19 am

Okey, my first try:

{* set children variable *}
{let children=fetch('content',tree,hash(parent_node_id,$module_result.node_id,
	                     class_filter_type,  include,
                           class_filter_array, array( 'folder' ),
	))}

{* loop children *}
{section name=Child loop=$children}
	
	{* If we find folder RightColumn *}
	{if eq( $Child:item.name, 'RightColumn' )}
		
		Test: {$Child:item.name}<br>			

		{let thischildren=fetch('content',tree,hash(parent_node_id,$Child:item.node_id))}
		Test: thischildren{$thischildren:item|attribute(show)}	
			<h1>{$Child:item.node_id}{$Child:item.name}</h1>
					
			{* Loop trough content inside RightColumn folder *}
			{section name=subchild loop=$thischildren}
			Test: subchild
					{$subchild:item|attribute(show)}	
					{$subchild:item.name}<br>
			{/section}
		
		{/let}		
		
	{/if}
{/section}

{/let}

It produce:

Test: RightColumn
Test: thischildren
Attribute	Type	Value	
116RightColumn

So $thischildren is never set. Why? I have content inside mye RightColumn folder. Is it not possible to have a nested loop?

Roy Bøhmer

Thursday 06 October 2005 3:15:33 am

I've once done a similar task. The way I solved it was to make a seperate class (named 'sidebox' or something). The template logic is pretty much the same you describe. The main advantage (i think) is that by doing this
- you can add additional features to the content presented, by adding optional attributes to the class.
- its esier to fetch nodes from a spesific class, rather than match the name.
- you dont have to hide the node, but just assure that none of the class-attributes is searchable, and that there are no useful template to view its content for the user.

Instead of making a brand new class you can add an attribute to the folder-class, determing if dynamic right column content is to be shown for this folder. The point is: I would not recomend making a folder-node with more or less "dummy-content" to add funcionality.

To comment on your code-sample:
First: It looks like you first looks for 'RightColumn'-folders in parent-node. Then, if it finds one, try to fetch children to the 'RightColumn'-folder. If I have understood the consept of 'RightColumn'-folders, it probably dont have any children.
Seccond:

Test: thischildren{$thischildren:item|attribute(show)}

should be

Test: thischildren{$thischildren.0|attribute(show)}

$thischildren is an array (since you used fetch,tree). It's only when you do a loop (section) you need the .item.

Hope it helps!
Roy

 

Yngve Bergheim

Thursday 06 October 2005 6:07:04 am

Thank you very much. Your answer is appreciated!

Your idea is very good.

I can just make a sidebar class (copy the folder class), and then the sidebar-folder will display all the children nodes in the right column. I'll definitively go for that. Thanks!

Your code

Test: thischildren{$thischildren.0|attribute(show)}

Didn't work for me.

Any idea of how I can go reverse in the nodes? If I don't find a sidebar class in the current folder I would like to fetch a sidebar in parent node, grandparent... etc.

Roy Bøhmer

Thursday 06 October 2005 2:44:59 pm

At least in pagelayout you have $module_result.path which is an array containing (among other) node_id. You find something similar in $node.'something'. When you know each node_id in the path, you can do some fetching and tests to find the latest folder with a sidebar-class child.

It's late, and I already should have gone to bed, so sorry for not posting any code.

Roy

Yngve Bergheim

Friday 14 October 2005 2:17:21 am

Wow. It works!

This is how you can make dynamic right column;

1. Make a sidebar class (copy the folder class)
2. Put the sidebar code below in your right column template file (to try it quick and dirty, add it in design/standard/templates/toolbar/full/node_list.tpl
3. The sidebar-folder will display all the children nodes in the right column.
4. Modify your folder.tpl so it does not show sidebar classes: Add the following code in &#8220;set list_items=fetch_alias(&#8230;&#8221;

class_filter_type, exclude,
class_filter_array, array( 'sidebar' ),

Sidebar code:

{def $thisNode=$node}
{def $thisParent=$thisNode.node_id}
{def $isSidebar=false() }
{def $i=0 }

{* Loop untill we find a sidebar *}
{while ne($isSidebar,true() )  }

	{* Make sure we don't walk up the node tree more then 4 times *}
	{if ne($i,4)}	
		
		{* Fetch current node and make sure sidebar is a children *}	
		{let Children=fetch('content', 'list', 
					hash('parent_node_id', $thisParent,
					'depth', 1,
					class_filter_type, include,
					class_filter_array, array( 'sidebar' ),
				))}
				
			{* If this node got a sidebar, print it *}
			{if eq($:Children.0.name,'Sidebar') }
				{section var=childrenList loop=$Children}
					{node_view_gui view=full content_node=$childrenList}
					{set $isSidebar=true() }
			    {/section}
			{else}
			    {set $thisParent=$thisNode.node_id}
			    {* If this node not is the root node, get parent node *}
			    {if ne($thisNode.node_id,1) }
   			    	{set $thisNode=fetch('content','node',hash('node_id',$thisNode.parent_node_id))}
   			    {else}
   			    	{set $isSidebar=true()}
   			    {/if}
		    {/if}
		{/let}
		
		{set i=$i|inc}
	{else}
		{set $isSidebar=true()}
	{/if}
{/while}			
		
{undef $thisNode}
{undef $isSidebar}	
{undef $thisParent}