Sorting items in foreach

Just recently a user in #cms IRC chanel was aksing if there is a way to sort MenuManager items (Navigation) by name.
The answer is yes, with a simple UDT you can sort your MenuManager by anything.

What you need for this is knowing how MenuManager Object is built and what can be accessed there. To see that we can simply use print_r Smarty modifier inside MenuManager template.

<pre>{$nodelist|print_r}</pre>

This would give us a result like following

stdClass Object
(
    [id] => 15
    [pagetitle] => Home
    [url] => http://domain.com
    [accesskey] => 1
    [type] => content
    [tabindex] => 
    [titleattribute] => 
    [modified] => 1333265577
    [created] => 1153855351
    [hierarchy] => 1
    [depth] => 1
    [prevdepth] => 1
    [children_exist] => 
    [haschildren] => 
    [menutext] => Home
    [raw_menutext] => Home
    [target] => 
    [index] => 0
    [alias] => home
    [parent] => 
    [extra1] => 
    [extra2] => 
    [extra3] => 
    [image] => 
    [thumbnail] =>
    [current] => 
)

As we have this information, we know that we want to sort our items by value of "menutext". So let's create our UDT.
Go to "Extensions » User Defined Tags" and klick on "Add User Defined Tag". Name it "sort" for example and add following PHP code.

if (!function_exists('do_sort')) {
    function do_sort($a, $b) {
        return $a->menutext > $b->menutext;
    }
}

$data = $params['data'];
usort($data, 'do_sort');
$smarty->assign('sorted', $data);

As we have our UDT ready now, which will sort our Array, we can add this UDT to our MenuManager template.
In your MenuManager template, before {foreach} simply call the UDT with {sort data=$nodelist} then change parameter from= from $nodelist to $sorted.

{sort data=$nodelist}
{foreach from=$sorted item='node'}

Now our Menu will be sorted in Alphabetical order.

You are not only limited to sorting of MenuManager, my main purpose for this UDT was when working with Uploads Module template. Uploads Module already has "sortorder" parameter but my issue was that i had to fake Subfolders and sort the Summary of Module by category and subfolder.
So to achieve this i used "extra field" of Type "dropdown" and named it "Subfolders" in Uploads module and the above mentioned UDT. Nice thing about this UDT is that you can also sort Mutilevel Arrays. So my UDT in that case looked like this.

if (!function_exists('do_sort')) {
    function do_sort($a, $b) {
        return $a->fieldvals[Subfolders] > $b->fieldvals[Subfolders];
    }
}

$data = $params['data'];
usort($data, 'do_sort');
$smarty->assign('sorted', $data);

With this method and some funky Template logic i was able to create nicely sorted summary Template in Uploads module, which was sorted by Category and fake Subfolders.

Uploads Template with two sorting options

Comments