Developer's manual

Adding the scripts (PHP configuration)

There are two scripts that make up the PHP configuration - the generated stylesheet, udm-style.php, and the generated menu script, udm-dom.php. These are controlled from a configuration file called udm-custom.ini

For the head section

For the head section you need a single <link /> element to include the generated stylesheet, udm-style.php:

<!-- ULTIMATE DROP DOWN MENU Version 4.6 by Brothercake -->
<!-- -->

<!-- PHP generated stylesheet -->
<link rel="stylesheet" type="text/css" media="screen,projection"
	href="/udm-resources/udm-style.php" />

Other things being equal it can go anywhere in the head section. However since global styles can potentially affect the menus, but the menu styles are extremely unlikely to affect other rules, it's best to put it after any other style sheets.

The media attribute serves a twin purpose here - because Opera in fullscreen mode uses projection-media CSS, not screen, and because the comma-delimited syntax is not understood by primitive CSS browsers like Netscape 4, and so it won't process that stylesheet at all.

For the body section

In the body section you need a single script include for the generated menu script, udm-dom.php. It must go in the <body> - if you put it in the <head> then it won't work in Mac/IE5.

As with the script in the head section, it doesn't need a language attribute:

<!-- PHP generated menu script [any modules or extensions must come AFTER this] -->
<script type="text/javascript"

Within the body section it can go anywhere, however if you have an existing window.onload function on your page then the script should come after it, to avoid an onload conflict in Mac/IE5.

The DOM script provides core functionality, but does not include full keyboard access. For best accessibility I strongly recommend including the keyboard navigation module as well (which you already have in your udm-resources folder). This should come after the udm-dom.php script include:

<script type="text/javascript"

If you're using any other modules or extensions, these must also go in the body section and come somewhere after the udm-dom.php script include.

Specifying the configuration file

The udm-custom.ini configuration file is used by both scripts, and so both will need to know the path to it. Open the two files in your text editor and you'll see the variable you need to set near the top - the path must be server-absolute, so I've used DOCUMENT_ROOT:

//set a path to the configuration file
$config = $_SERVER['DOCUMENT_ROOT'] . '/udm-resources/udm-custom.ini';

If you need an alternative to DOCUMENT_ROOT, you can extrapolate the script's directory path using the "magic" constant __FILE__:

//set a path to the configuration file
$config = str_replace(basename(__FILE__), '', realpath(__FILE__)) . 'udm-custom.ini';

The configuration file itself doesn't need to be parsed separately by PHP, however since it has a plain-text extension it will be readable across HTTP to anyone who works out its address. I can't see how that would be a problem, but if it is you can just rename it .php

The page that the menu is on doesn't actually need to be parsed by PHP either - it's only the two included scripts that do - so you have the freedom to use this configuration language on pages built in a different one.

Using a different configuration file

If you want to use a configuration file other than the default, you can pass its path to the scripts as a query-string value. The specified value can only contain letters, numbers, dot, dash, underscore or slash. The file path must also be server-absolute:

<?php $config = $_SERVER['DOCUMENT_ROOT'] . '/path/to/config.ini'; ?>


<link rel="stylesheet" type="text/css" media="screen,projection"
	href="/udm-resources/udm-style.php?config=<?php echo($config); ?>" />


<script type="text/javascript"
	src="/udm-resources/udm-dom.php?config=<?php echo($config); ?>"></script>

Setting the character-match value for allowed filenames

The ability to specify a different configuration file exposes a potential vulnerability that could allow for malicious code injections. In order to prevent that, the input filename is validated in two passes:

  • Does it contain ONLY letters, numbers, dot, dash, colon, underscore, forward- or back-slash?
  • Does it match the regular-expression defined by the $cmatch variable?

The $cmatch expression can be defined to suit the pattern of filenames you'll be using. By default, only configuration files called "udm-custom.ini" are allowed:

//specify config file value match
$cmatch = 'udm-custom.ini';

But you could change this, for example, so that filenames like "foo-bar.php" and "foo_bar.ini" are allowed:

//specify config file value match
$cmatch = '([a-z]+[\-_]?)+[\.](ini|php)';

You should set the $cmatch expression as tight as possible, and not rely on the general regex to stop all attacks - it won't. The only way to be sure that only valid configuration files are allowed through, is to define absolutely what those files will be called.


We would like your feedback! Take the UDM4 Survey!

UDM 4 is valid XHTML, and in our judgement, meets the criteria for WAI Triple-A conformance.