Contents / Dynamic server-side generation of menus

With the professional edition of DHTML Menu Studio you can insert items into the menu dynamically, from a server-side script such as ASP or PHP. This is very useful if you want to reflect a structure stored in a database or enable/disable items based on user's permissions. You can enable dynamic generation in options / output / dynamic creation of menu structure. NOTE: If using a bitmap scheme (and the top-level menu generation method is not set to HTML code) you will only be able to dynamically create popups. You will not be able to modify top-level menu items. The reason for this is that in such case, the program creates the top-level menu in form of image files containing fixed texts chosen at the design time.

Note: when using the variable-size "vertical menu without popups" style, the dynamic creation is slightly different, you will find the details here and here.

Adding items to menu

When dynamic creation is enabled, in the ouput page created by DHTML Menu Studio you will notice PHP / ASP / JavaScript functions which should be called to dynamically add items to the menu. Please note that when creating the menus, you don't specify the position of items -- all items are always inserted at the end of a given menu (top-level menu bar or popup). The code for dynamic menu creation should be inserted just after the Add items to the menu here comment (the program will also create default code at this location -- this code will create a menu designed inside the program's UI). Below is the description of the functions you'll need to use:

function SSAddTopLevelMenu -- call this function to add a popup menu to the top-level menu bar (use SSAddMenuItem to add items which do not expand into a popup, instead). The function returns the id of the created menu (this id can be used as the parentMenu parameter when adding child items to the menu). This function accepts the following parameters:

function SSAddSubMenu -- call this function to add a popup menu as a child of another popup menu (to add popup menus to the top-level menu bar, use SSAddTopLevelMenu). The function returns the id of the created menu (this id can be used as the parentMenu parameter when adding child items to the menu). This function accepts the following parameters:

function SSAddMenuItem -- call this function to add a menu item which does not expand a popup (if you want to create an item which expands into a popup, use SSAddTopLevelMenu or SSAddSubMenu). This function accepts the following parameters:

function SSGetTopLevelMenu -- this function returns the id of a top-level menu created statically by DHTML Menu Studio at design time (the top-level menu bar is created statically when top-level items are created as images). You can use the id returned by this function in subsequent calls to SSAddSubMenu.

Here's a sample code (PHP version) which creates the whole menu (top-level bar and popups):

...

// --------------------------
// Add items to the menu here
// --------------------------

// adding top-level items
$e_1=SSAddTopLevelMenu("Sample folder 1","", "");
$e_2=SSAddTopLevelMenu("Sample folder 2","http://www.xtreeme.com/", "");

// adding first popup items (and a sub-popup)
SSAddMenuItem ("Item","http://www.google.com/", "",$e_1);
$e_1_1=SSAddSubMenu("Subfolder","http://www.yahoo.com/", "",$e_1);
SSAddMenuItem ("Item opened in a new window","http://www.msn.com/", "_blank",$e_1_1);

// adding item to second popup
SSAddMenuItem ("Item","http://www.websmill.com/", "",$e_2);

...

Here's a sample code (PHP version) which creates popups only (top-level menu created at images):

...

// --------------------------
// Add items to the menu here
// --------------------------

// getting IDs of top-level items
$e_1=SSGetTopLevelMenu(1);
$e_2=SSGetTopLevelMenu(2);

// adding first popup items (and a sub-popup)
SSAddMenuItem ("Item","http://www.google.com/", "",$e_1);
$e_1_1=SSAddSubMenu("Subfolder","http://www.yahoo.com/", "",$e_1);
SSAddMenuItem ("Item opened in a new window","http://www.msn.com/", "_blank",$e_1_1);

// adding item to second popup
SSAddMenuItem ("Item","http://www.websmill.com/", "",$e_2);

...

The above samples will result in the following structure being created:

Sample folder 1
	Item
	Subfolder
		Item opened in a new window
Sample folder 2
	Item

 

Reusable (typical-use) sample

The remaining part of this document provides a sample code which dynamically creates menus based on a structure saved in a database on server. In our sample the whole structure is kept in a single database table with the following fields:
field namefield typedescription
idintunique item identifier (cannot be zero)
parent_idintparent item (or zero for top-level items)
node_namevarchartext of menu item
node_urlvarchartarget URL

The above table is called sample_structure in the sample code. Please note that if you're using a different format for storing the structure, all you need to do is change the SQL queries in the sample code.

Implementation using PHP + MySQL

The following PHP code should be inserted just after the following comments generated by DHTML Menu Studio:

// --------------------------
// Add items to the menu here
// --------------------------

Please note that in order to get the menu to work with PHP dynamic creation code you have to:

The sample code below is very simple. You will need to modify it in places which are preceeded by the comment: // MODIFICATION REQUIRED.

// --------------------------
// Add items to the menu here
// --------------------------

function getFindChildrenQuery ($db_id)
{
	// MODIFICATION REQUIRED
	// You might need to modify the query below
	// Its goal is to fetch all entries whose parent is identified by $db_id
	return "select * from sample_structure where parent_id=$db_id";
}

// The function hasChildren returns true if item identified by $db_id 
// has children or false otherwise
function hasChildren ($db_id)
{
	$query = getFindChildrenQuery ($db_id);
	$result = mysql_query ($query) or die ("SQL Query Failed: $query");
	return (mysql_num_rows ($result) > 0);
}

function createMenuLevel ($db_parentId, $menu_parentId)
{
	$query = getFindChildrenQuery ($db_parentId);
	$result = mysql_query ($query) or die ("SQL Query Failed: $query");
	while($row = mysql_fetch_array ($result))
	{
		// MODIFICATION REQUIRED
		// Adjust the following three lines so that the proper fields 
		// of the result rows get referenced
		$text = $row ['node_name'];
		$url = $row ['node_url'];
		$id = $row ['id'];
		if (hasChildren ($id))
		{
			if ($menu_parentId == null)
			{
				$menu_id = SSAddTopLevelMenu ($text, $url);
			}
			else
			{
				$menu_id = SSAddSubMenu ($text, $url, NULL, $menu_parentId);
			}
			createMenuLevel ($id, $menu_id);
		}
		else
		{
			SSAddMenuItem ($text, $url, NULL, $menu_parentId);
		}
	}
}

function createMenu ()
{
	// MODIFICATION REQUIRED
	// Open database
	// You'll need to change the values of server, user name, password
	// and database name below.
	// Note: very often the server should often be set to localhost
	mysql_pconnect ("your_server","your_login","your_password") or die ("Unable to connect to SQL server"); 
	mysql_select_db ("database_name") or die ("Unable to select database");

	createMenuLevel (0, null);
}

createMenu ();

Implementation using ASP + ODBC

The following ASP code should be inserted just after the following comments generated by DHTML Menu Studio:

' --------------------------
' Add items to the menu here
' --------------------------

Please note that in order to get the menu to work with ASP dynamic creation code you have to:

The sample code below is very simple. You will need to modify it in places which are preceeded by the comment: ' MODIFICATION REQUIRED.

' --------------------------
' Add items to the menu here
' --------------------------

Function getFindChildrenQuery (db_id)
	' MODIFICATION REQUIRED
	' You might need to modify the query below
	' Its goal is to fetch all entries whose parent is identified by db_id
	getFindChildrenQuery = "select * from sample_structure where parent_id=" & db_id
End Function

' The function hasChildren returns true if item identified by db_id 
' has children or false otherwise
Function hasChildren (db_id, connection)
	query = getFindChildrenQuery (db_id)
	Set result = connection.Execute (query)
	If result.EOF = True Then
		hasChildren = False
	Else
		hasChildren = True
	End If
End Function

Function createMenuLevel (db_parentId, menu_parentId, connection)
	query = getFindChildrenQuery (db_parentId)
	Set result = connection.Execute (query)
	Do While Not result.EOF
		' MODIFICATION REQUIRED
		' Adjust the following three lines so that the proper fields 
		' of the result rows get referenced
		text = result.Fields ("node_name")
		url = result.Fields ("node_url")
		id = result.Fields ("id")
		bFolder = hasChildren (id, connection)
		If bFolder = True Then
			If menu_parentId = Null Then
				menu_id = SSAddTopLevelMenu (text, url, Null, Null, Null)
			Else
				menu_id = SSAddSubMenu (text, url, Null, menu_parentId, Null, Null)
			End If
			createMenuLevel id, menu_id, connection
		Else
			SSAddMenuItem text, url, Null, menu_parentId, Null, Null
		End If
		result.MoveNext
	Loop
End Function

Function createMenu ()
	' MODIFICATION REQUIRED
	' Open database
	' You'll need to change the values of server, user name, password
	' and database name below.
	' Note: very often the server should often be set to localhost

	Dim connection
	Set connection = Server.CreateObject("ADODB.Connection")
	connection.Open "DSN=database_name; UID=your_user; PWD=your_password;"
	createMenuLevel 0, null, connection
	connection.Close
End Function

createMenu

In case of the other server-side creation methods supported by the program (ASP.NET, JSP) you should have no problem with appropriate changes in the code syntax as the general algorithm is the same.