fetching random content combined with cache

fetching random content combined with cache

Monday 04 September 2006 4:14:58 am - 6 replies

Author Message

Softriva .com

Wednesday 18 April 2007 8:41:45 am

Dear Marko

I am interested. Would you please provide me with more information.

Jorge estévez

Wednesday 24 December 2008 3:02:06 pm

Hello,

Please explain more, I am having problems when the cache is turn on, please see http://ez.no/developer/forum/developer/shuffle_and_cache_please_help

Can you post some code so I can get the whole idea!

Thanks

Diseño Web Cuba
Web Design Cuba
www.elfosdesign.com

Stéphane Couzinier

Friday 26 December 2008 2:55:15 am

Hi

To retrieve random content ypu can use a specific operator see : http://projects.ez.no/la_fetch_random

To avoid cache pb, you must disable content cache for the tpl :
in the override full add {set-block scope=root variable=cache_ttl}0{/set-block} and to reduce CPU/memory you should add some cache block in the TPL

http://www.kouz-cooking.fr

Marko Žmak

Friday 26 December 2008 5:36:49 am

Hi Jorge, I'll give you an example. The trick is to define keys for the cache-block in a smart way so that cache-bock depend on all the parameters that influence the results that should be displayed.

First here's the simpler example that uses the step of 1:

{*
Parameters given to this template are:

$search_parent_node_id - parent node for fetching
$class_filter_type - class filter type for fetching
$class_filter_array -class filter array for fetching
$attribute_filter - attribute filter for fetching
$main_node_only - whether to fetch only main nodes
$sort_by - sort criteria for fetching
$fetch_function - the function for fetching ('list', 'tree')

$max_nodes - the number of nodes to extract (at the end $max_nodes contains the number of nodes that were actually displayed)
$list_item_view - the view used for displaying fetched items (e.g. 'full', 'line'...)
$keys_prefix - this is added as a prefix to the keys parameter of the cache block so that we could use differentiate cache blocks when used in several parts of the page

*}

{* First we define the hash used for fetch operator *}
{def $fetch_hash=hash(
					'parent_node_id', $search_parent_node_id,
					'class_filter_type', $class_filter_type,
					'class_filter_array', $class_filter_array,
					'attribute_filter', $attribute_filter,
					'main_node_only', $main_node_only
				)
}

{* Now we get the number of nodes that fetch will return *}
{def $nodes_count=fetch(content, concat($fetch_function,'_count'), $fetch_hash)}

{if gt($nodes_count,0)}

	{* If $max_nodes is lower that 0 then we set it to $nodes_count so we'll fetch all the nodes *}
	{if le($max_nodes,0)}
		{set $max_nodes=$nodes_count}
	{/if}
	
	{* We get the index of the first element randomly and define the step of 1. (we could also make $step randomly but that's more complicated *}
	{def $index=rand(0, dec($nodes_count)) $step=1}

	{* We fetch the parent node so that we can use it's url_alias in subtree_expiry of the cache-block *}
	{def $parent_node=fetch(content, node, hash('node_id', $search_parent_node_id))}

	{* And here's the cache-block. The keys parameter is constructed from:
		$keys_prefix
		$search_parent_node_id
		$nodes_count
		$index
		$step
		
		(the $step is not really needed in keys parameter because is always 1, but if we create $step randomly, then it will be needed)
	 *}
	{cache-block
	keys=concat($keys_prefix,$search_parent_node_id,'_',$nodes_count,'_',$index,'_',$step) subtree_expiry=$parent_node.url_alias
	 expiry=0 ignore_content_expiry}

		{* The piece of code that is most intensive comes within this cache block. That is:
			- fetching the content
			- going through the list and displaying nodes
		*}

		{* We add the sort_by to the fetch hash *}
		{set $fetch_hash=$fetch_hash|merge( hash('sort_by', $sort_by) )}

		{* Now we fetch the content *}
		{def $nodes=fetch(content, $fetch_function, $fetch_hash)}

		{* We adjust the $max_nodes just in case if the number of fetched nodes is lower than $max_nodes *}
		{set $max_nodes=min($nodes_count,$max_nodes)}
				
		{* We go through the fetched items and display them *}
		{for 1 to $max_nodes as $count}
			{node_view_gui content_node=$nodes[$index] view=$list_item_view}
			{set $index=mod(sum($index,$step),$nodes_count)}
		{/for}
		
	{/cache-block}

{else}
	{set $max_nodes=0}
{/if}

Now, if we want to use the $step that is not 1 but created randomly we should replace this part of code:

	{* We get the index of the first element randomly and define the step of 1. (we could also make $step randomly but that's more complicated *}
	{def $index=rand(0, dec($nodes_count)) $step=1}

with this code:

{* We get the index of the first element randomly *}
{def $index=rand(0, dec($nodes_count))}

{*
Now we get the $step randomly, but with some adjustments.
The idea is to set $step to a random value and then repeat this process until
the remainder od division ($nodes_count / $step) is zero.
(because otherwise we could get some nodes displayed more than once)
*}


{* The $max_iterations parameter. If we don't get the $step that has the
remainder zero after $max_iterations, we give up and set $step to 1 *}
{def $max_iterations=10}


{* We set the initial random value for $step *}
{def $step=rand(0, dec($nodes_count))}


{* We loop until:
- mod($nodes_count / $step) = 0
- or the loop has been executed $max_iterations times
*}
{def $i=0}
{while and(lt($i,$max_iterations),eq(mod($nodes_count,$step),0))}
	{* We generate a new random $step *}
	{set $step=rand(0, dec($nodes_count))}
	{set $i=inc($i)}
{/while}


{* If we didnt find the $step that has the remainder zero after the loop, we set the $step to 1*}
{if eq(mod($nodes_count,$step),0))}
	{set $step=1}
{/if}

This is it. It works well for me. If you have any further questions, feel free to ask.

--
Nothing is impossible. Not if you can imagine it!

Hubert Farnsworth

Marko Žmak

Friday 26 December 2008 5:39:50 am

P.S. And of course, like Stéphane suggested you should set:

{set-block scope=root variable=cache_ttl}0{/set-block}

before this if you're using this in some template that is cached (e.g. node view override).

--
Nothing is impossible. Not if you can imagine it!

Hubert Farnsworth

Jorge estévez

Friday 26 December 2008 8:00:55 am

Thanks, I will try and come back later.

Diseño Web Cuba
Web Design Cuba
www.elfosdesign.com

You must be logged in to post messages in this topic!

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.