Page 1 of 1

Sort Menu Items Alphabetically

Posted: Sat Aug 23, 2008 10:09 am
by Alex53
How can I re-order all my menu items alphabetically without having to manually move them up and down?

Please tell me this is possible, there are some big menus in the site I need this for! :)

Re: Sort Menu Items Alphabetically

Posted: Sun Aug 24, 2008 5:16 pm
by almooj-craig
Hello Alex53,

Since you want "ALL" of your menu items to be displayed alphabetically I would just change the query that loads the menus.

First make a backup copy of includes/menu.php, then in the load() function of the real file, change the ORDER BY clause to:
ORDER BY m.sublevel, m.parent, m.alias

You can also use m.title, but I think m.alias is a little more flexible because you can easily tweak the order if necessary.

I actually use a couple of functions and params that make changing the order of individual menus fairly easy, but they are more complicated to install. I'll post my other solution if you are interested.

Craig

Re: Sort Menu Items Alphabetically

Posted: Mon Aug 25, 2008 7:45 pm
by Alex53
Thanks for your reply. I will try to do this shortly and let you know how it goes.

To be honest although all the menus will be alphabetical, there are some exceptions where the top item in the menu breaks that order because its called something like 'Index', 'Home' or the name of the area of the site.

Re: Sort Menu Items Alphabetically

Posted: Thu Jul 22, 2010 4:13 pm
by asynctea
worked well for me, thanks!

Re: Sort Menu Items Alphabetically

Posted: Mon Jan 10, 2011 5:46 am
by ghost999
Hi Craig,

thanks for this hack, it perfectly work for all menu items.
as you wrote, your solution will change also main menu items. It works great, but I would like to order only subcategories. Could you pls post your full solution? I want to avoid re-naming of alias.

Thanks.
Pavol

Re: Sort Menu Items Alphabetically

Posted: Fri Jan 14, 2011 3:51 pm
by almooj-craig
Pavol,

Since I wrote this a couple of years ago, I scanned through the code changes. Hopefully I included all of the changes. First backup your files and tables. Then restore the original query in the includes/menu.php file.

I prefer to just sort the order of the menu items when you save a menu item or by saving the order when you are viewing the menu items table. The parameters are passed from the module that uses the menu. This is a one to many relationship so it gets the parameters from the first matching module.

These changes can be used two ways.
(1) Automatically when you edit or create a new menu item it will sort the menu if necessary.
(2) You can manually sort the menu when you are viewing it's table.
Top level or children of a parent can be eliminated from the sort order and save.

In the modules/mod_mainmenu/mod_mainmenu.xml add these parameters.

Code: Select all

		<param name="@spacer" type="spacer" default="" label="" description="" />
		<param name="filter_order" type="list" default="" label="Order by on Save" description="Sort the menu using this order when you save a menu item.">
			<option value="None">None</option>
			<option value="m.name">Title</option>
			<option value="m.alias">Alias</option>
			<option value="m.id">ID number</option>
			<option value="Table">Table Order</option>
		</param>
		<param name="filter_order_Dir" type="radio" default="asc" label="Order Direction on Save" description="Ascending or Descending Order">
			<option value="asc">Ascending</option>
			<option value="desc">Descending</option>
		</param>
		<param name="excludeParents" type="text" default="" size="40" label="Exclude Parents" description="Enter the Parent IDs of the Children that you want to excluded from the saved sort. 0 will exclude all top level menu items. Format as a mysql set. For example, to exclude all top level menu items and the children of parents 19 and 44 enter: 0,19,44" />
Then in the administrator/components/cm_menus/controller.php file change these functions;

Code: Select all

	function save()
	{
		// Check for request forgeries
		JRequest::checkToken() or jexit( 'Invalid Token' );

		$cache = & JFactory::getCache('com_content');
		$cache->clean();

		$model	=& $this->getModel( 'Item' );
		$post	= JRequest::get('post');
		// allow name only to contain html
		$post['name'] = JRequest::getVar( 'name', '', 'post', 'string', JREQUEST_ALLOWHTML );
		$model->setState( 'request', $post );

		$menu	= JRequest::getVar( 'menutype', '', 'post', 'string' );
		
		$db 	=& JFactory::getDBO();
		$query = "SELECT params
				FROM #__modules
				WHERE published=1 AND params REGEXP 'menutype=$menu\n'
				AND params LIKE '%filter_order_Dir%' 
				ORDER BY ordering";
		$db->setQuery($query);
		if ($r = $db->loadResult())
		{
			$params = new JParameter($r);
			$filter_order = $params->get('filter_order');
			$filter_order_Dir = $params->get('filter_order_Dir');
			$excludeParents = $params->get('excludeParents');
		}
		else
		{
			$filter_order = '';
			$filter_order_Dir = '';
			$excludeParents = '';
		}
		
		$item =& $model->getItem();
		if ($model->store())
		{
			switch ( $filter_order ) 
			{
				case 'None':
					break;
				case 'Table':
					$filter_order	= JRequest::getVar( 'filter_order', '', 'post', 'string' );
					$filter_order_Dir	= JRequest::getVar( 'filter_order_Dir', '', 'post', 'string' );
					if ($filter_order)
						MenusController::sortMenu( $menu, $filter_order , $filter_order_Dir, $excludeParents );
					break;
				default:
					if ($filter_order)
						MenusController::sortMenu( $menu, $filter_order , $filter_order_Dir, $excludeParents);
					break;
			}
			$msg = JText::_( 'Menu item Saved' );
			if ($filter_order)
				$msg .= ", Saved Order Using: $filter_order $filter_order_Dir";
		
		} else {
			$msg = JText::_( 'Error Saving Menu item' );
		}
		
		switch ( $this->_task ) {
			case 'apply':
				$this->setRedirect( 'index.php?option=com_menus&menutype='.$item->menutype.'&task=edit&cid[]='.$item->id.'' , $msg );
				break;

			case 'save':
			default:
				$this->setRedirect( 'index.php?option=com_menus&task=view&menutype='.$item->menutype, $msg );
				break;
		}
	}

Code: Select all

	function saveorder()
	{
		// Check for request forgeries
		JRequest::checkToken() or jexit( 'Invalid Token' );
		
		$menu	= JRequest::getVar( 'menutype', '', 'post', 'string' );
		$filter_order	= JRequest::getVar( 'filter_order', 'alias', 'post', 'string' );
		$filter_order_Dir	= JRequest::getVar( 'filter_order_Dir', 'asc', 'post', 'string' );
		MenusController::sortMenu( $menu, $filter_order , $filter_order_Dir, $excludeParents );
		$msg = "This Menu has been sorted by $filter_order $filter_order_Dir and that Order has been saved.";
		$this->setRedirect( 'index.php?option=com_menus&task=view&menutype='.$menu, $msg );
	}
And add this function:

Code: Select all

	function sortMenu( $menu, $filter_order , $filter_order_Dir, $excludeParents='' )
	{
		$db 	=& JFactory::getDBO();
		$db2 	=& JFactory::getDBO();
		if (!$excludeParents)
		{
			$query = "SELECT params
					FROM #__modules
					WHERE published=1 AND params REGEXP 'menutype=$menu\n'
					AND params LIKE '%filter_order_Dir%' 
					ORDER BY ordering";
			$db->setQuery($query);
			if ($r = $db->loadResult())
			{
				$params = new JParameter($r);
				$excludeParents = $params->get('excludeParents');
			}	
		}
		if ($excludeParents)
		{
			global $mainframe;
			$mainframe->enqueueMessage("The menu items directly under the ( $excludeParents ) parents did not have their order number modified.");
			$excludeParents = " AND parent NOT IN ($excludeParents)";
		}	
		
		$query = "SELECT id,parent,ordering
						FROM #__menu AS m
						WHERE m.menutype='$menu' $excludeParents
						ORDER BY $filter_order $filter_order_Dir";

		$db->setQuery($query);
		if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg() ); }
		
		$rs = $db->loadObjectList();
		$c = array();
		foreach ( $rs as $r )
		{
			$c[$r->parent]++;
			if ($r->ordering != $c[$r->parent])
			{
				$query = 'UPDATE #__menu'
				. ' SET ordering = ' . $c[$r->parent]
				. ' WHERE id = ' . $r->id
				;
				$db2->setQuery( $query );
				if (!$db2->query()) { JError::raiseError(500, $db2->getErrorMsg() ); }
			}
		}
	
	}
Hopefully I didn't overlook something. ;-)

Craig

Re: Sort Menu Items Alphabetically

Posted: Fri Jan 14, 2011 5:15 pm
by ghost999
Hi Craig,

thank you so much for this :). You can not imagine how much time it will save me (when I will translate my menu items to other languages - more than 100 menu items).

I'm not sure if it will help me with translated joomfish menu, when It will be ordering only on save.

I will try it ASAP and will let you know if it works. You wrote it couple years ago? Hopefully it will work with J1.5.

Thank you once more and have great weekend :)!

Pavol

Re: Sort Menu Items Alphabetically

Posted: Fri Jan 14, 2011 5:43 pm
by almooj-craig
Pavol,

It works with J1.5 and I use it on all of my clients sites. I don't know if it will work with joomfish since I don't use it.

It will also sort menu items when you are viewing them in the Menu Item Manager table.

If Joomfish uses a different table with a similar structure that has ordering, alias and name fields you should be able to adapt my code to work with Joomfish.

Craig

Re: Sort Menu Items Alphabetically

Posted: Mon Dec 05, 2011 11:16 pm
by ormaric
hello craig,

i am reading your post, and i am glad that there is a solution for a problem,

bat i can not make it work... i used everything you said, but it wont work.. :(

can you please check if there is something that you overlooked...


thank you!!

Re: Sort Menu Items Alphabetically

Posted: Mon Dec 05, 2011 11:41 pm
by almooj-craig
Did you open mod_mainmenu in the module manager and then for "Order by on Save" select title or alias then save it?

Re: Sort Menu Items Alphabetically

Posted: Tue Dec 06, 2011 12:09 am
by ormaric
yes I did...

and when i edit menu item, and click save i get 500 error, my admin crashes...

Re: Sort Menu Items Alphabetically

Posted: Tue Dec 06, 2011 2:18 am
by almooj-craig
Turn on error reporting and see what the error is.

Re: Sort Menu Items Alphabetically

Posted: Sat Feb 11, 2012 12:17 pm
by zonhal
Hi almooj-craig

I did all the changes, but I don't know were to find the option to sort the menu items automatically. I search in the main menu module, in the menu manager - menus. I don't see the option to save and sort.
I already have all my items created. this will sort that also?

Re: Sort Menu Items Alphabetically

Posted: Sat Feb 11, 2012 3:21 pm
by almooj-craig
I was just setting up a new clients site and wanted to exclude just the top level menu items from being sorted 0. Normally there are a couple parents that I don't sort like 0,122 so I never ran into the problem of only trying to not sort the top level. Here is the code change so that it works for 0.

/administrator/components/com_menus/controller.php

Code: Select all

function sortMenu( $menu, $filter_order , $filter_order_Dir, $excludeParents=null )
{
	$db 	=& JFactory::getDBO();
	$db2 	=& JFactory::getDBO();
	if (is_null($excludeParents))
	{
		$query = "SELECT params
				FROM #__modules
				WHERE published=1 AND params REGEXP 'menutype=$menu\n'
				AND params LIKE '%filter_order_Dir%' 
				ORDER BY ordering";
		$db->setQuery($query);
		if ($r = $db->loadResult())
		{
			$params = new JParameter($r);
			$excludeParents = $params->get('excludeParents', '');
		}
		else
			$excludeParents='';
	}
	if ($excludeParents !='')
	{
		global $mainframe;
		$mainframe->enqueueMessage("The menu items directly under the ( $excludeParents ) parents did not have their order number modified.");
		$excludeParents = " AND parent NOT IN ($excludeParents)";
	}	
	
	$query = "SELECT id,parent,ordering
					FROM #__menu AS m
					WHERE m.menutype='$menu' $excludeParents
					ORDER BY $filter_order $filter_order_Dir";

	$db->setQuery($query);
	if (!$db->query()) { JError::raiseError(500, $db->getErrorMsg() ); }
	
	$rs = $db->loadObjectList();
	$c = array();
	foreach ( $rs as $r )
	{
		$c[$r->parent]++;
		if ($r->ordering != $c[$r->parent])
		{
			$query = 'UPDATE #__menu'
			. ' SET ordering = ' . $c[$r->parent]
			. ' WHERE id = ' . $r->id
			;
			$db2->setQuery( $query );
			if (!$db2->query()) { JError::raiseError(500, $db2->getErrorMsg() ); }
		}
	}

}
There are also a couple other places in that file where you are getting the excludeParents param. Change it so that there is a default of ''.
$excludeParents = $params->get('excludeParents', '');

Re: Sort Menu Items Alphabetically

Posted: Sat Feb 11, 2012 3:32 pm
by almooj-craig
zonhal,

All menu's need to have a module of some type in order to get them to render.
If you added the parameters to:
modules/mod_mainmenu/mod_mainmenu.xml
then when you look at the associated mod_mainmenu for your menu it will have these three additional parameters.
-----
Order by on Save
Order Direction on Save Ascending Descending
Exclude Parents
-----
If you are using a module other than a mod_mainmenu to render the menu then you could create an additional mod_mainmenu for that menu and give it a module position that is not ever used. That way the sort will pick up the sorting parameters the mod_mainmenu module but your real menu module will be used to render the menu.

Re: Sort Menu Items Alphabetically

Posted: Wed Apr 03, 2013 11:17 pm
by samlf3rd
almooj-craig wrote:zonhal,

All menu's need to have a module of some type in order to get them to render.
If you added the parameters to:
modules/mod_mainmenu/mod_mainmenu.xml
then when you look at the associated mod_mainmenu for your menu it will have these three additional parameters.
-----
Order by on Save
Order Direction on Save Ascending Descending
Exclude Parents
-----
If you are using a module other than a mod_mainmenu to render the menu then you could create an additional mod_mainmenu for that menu and give it a module position that is not ever used. That way the sort will pick up the sorting parameters the mod_mainmenu module but your real menu module will be used to render the menu.
Yes thank you for that, but with the info I still can't find a solid solution for 2.5
Not sure why there isn't see a plugin for it either-would be beneficial.

But I am confident that someone knows the trick to do this, you can do this with a php script to grab the array and sort by what ever field you want. Help peoples!

Re: Sort Menu Items Alphabetically

Posted: Wed Dec 04, 2013 7:27 pm
by Cpointcc
Has anyone come up with a solution for this for version 2.5?

I am in desperate need with over 500 menu items in various modules and menus.

None of the threads I have found apply to v2.5

Re: Sort Menu Items Alphabetically

Posted: Tue Jan 14, 2014 9:41 pm
by grizzlies
Hello everyone,

I was wondering if there is a solution for this for Joomla 3.0?

I have some very large menus and I would like to show them alphabetized. Drag and drop ordering really is not an option.

Thanks!

Re: Sort Menu Items Alphabetically

Posted: Mon Oct 06, 2014 9:15 am
by bentk
I have the same problem. This is ridiculous that I can't do it with one click.

I tried to sort them in menu manager by clicking on the title, it is reordered them alphabetically, then I rebuild the menu, but nothing has changed on the front end.

How to do it?

This is the only forum topic (Joomla! 1.5) where this problem is discussed, although Joomla! 3 is the most used version.

Strange...

Re: Sort Menu Items Alphabetically

Posted: Mon Oct 06, 2014 2:39 pm
by wootx
Any news on this? I too find it strange that this hasn't been taken care of in Joomla 3.0 no less.

I would love to see a simply button for each menu with "Sort alphabetically", then taken to a confirmation page "This will sort all the items of $menu in alphebetical order. Are you sure you want to continue", click Yes and there we (should) go.

Re: Sort Menu Items Alphabetically

Posted: Sat Apr 23, 2016 8:48 am
by erick-b
same here

A sort by title and save order should be a feature in Joomla

i could solve it in that way

Code: Select all

DROP TABLE if exists  a_menu;

CREATE TABLE if not exists a_menu
SELECT  0 as `ordering` , id, title, lft AS lft_old,rgt AS rgt_old FROM `myprefix_menu` WHERE `menutype` LIKE '%menu-hk-cat%' ORDER by title;
ALTER TABLE `a_menu` CHANGE `ordering` `ordering` INT(10) NOT NULL DEFAULT '0';

ALTER TABLE `a_menu` ADD `lft` INT(11) NOT NULL DEFAULT '0' AFTER `rgt_old`, ADD `rgt` INT(11) NOT NULL DEFAULT '0' AFTER `lft`;


SET @sort := 0;
UPDATE a_menu 
SET `ordering` = @sort := @sort + 1 ORDER BY title;

UPDATE a_menu 
SET lft = 1  WHERE ordering = 1;

SET @sort := 1;
UPDATE a_menu 
SET lft = @sort := @sort + 2 WHERE ordering > 1;

UPDATE a_menu
SET rgt = lft + 1;

UPDATE sacfr_menu a INNER JOIN a_menu b USING(id)
SET a.lft = b.lft, a.rgt = b.rgt;

DROP TABLE if exists  a_menu;

Re: Sort Menu Items Alphabetically

Posted: Tue Mar 20, 2018 4:09 pm
by toineenzo
Anyone here that can help me with this code?
erick-b wrote:same here

A sort by title and save order should be a feature in Joomla

i could solve it in that way

Code: Select all

DROP TABLE if exists  a_menu;

CREATE TABLE if not exists a_menu
SELECT  0 as `ordering` , id, title, lft AS lft_old,rgt AS rgt_old FROM `myprefix_menu` WHERE `menutype` LIKE '%menu-hk-cat%' ORDER by title;
ALTER TABLE `a_menu` CHANGE `ordering` `ordering` INT(10) NOT NULL DEFAULT '0';

ALTER TABLE `a_menu` ADD `lft` INT(11) NOT NULL DEFAULT '0' AFTER `rgt_old`, ADD `rgt` INT(11) NOT NULL DEFAULT '0' AFTER `lft`;


SET @sort := 0;
UPDATE a_menu 
SET `ordering` = @sort := @sort + 1 ORDER BY title;

UPDATE a_menu 
SET lft = 1  WHERE ordering = 1;

SET @sort := 1;
UPDATE a_menu 
SET lft = @sort := @sort + 2 WHERE ordering > 1;

UPDATE a_menu
SET rgt = lft + 1;

UPDATE sacfr_menu a INNER JOIN a_menu b USING(id)
SET a.lft = b.lft, a.rgt = b.rgt;

DROP TABLE if exists  a_menu;