Our big problem is that there are paths like node/12345/edit
. To handle these and others, we use a wildcard: the percent sign. So, when the system tries to find which {menu_router} entry specifies node/12345/edit
it will look at the menu definitions of the following paths:
node/12345/edit
node/12345/%
node/%/edit
node/%/%
node/12345
node/%
node
These we call the ancestors of node/12345/edit
.
Fit
As a wildcard is less specific than the path itself -- for example, if we defined a {menu_router} entry for node/12345/edit
it will only deal with this one node only but node/%/edit
deals with all nodes. We can say that node/12345/edit
is a better fit than node/%/edit
.
So let's add fitness number to these paths:
Path | Fitness | Fitness in binary |
---|---|---|
node/12345/edit |
7 | 111 |
node/12345/% |
6 | 110 |
node/%/edit |
5 | 101 |
node/%/% |
4 | 100 |
node/12345 |
3 | 11 |
node/% |
2 | 10 |
node |
1 | 1 |
I think it's quite visible that if we replace the % wildcard with 0 and the specific part with 1 then we get the binary number. We will use this both ways: we can calculate the value fitness of any path easily and also we can generate the ancestors of any given path by generating these binary numbers and replacing backwards.
CSS designers will recognise fitness as being analogous with specifity in CSS selectors.
Ancestors and fitness are used only on run time, not on build time.
Note
An additional optimization has been implemented, so that only the ancestors which correspond to the binary patterns of paths that actually exist in {menu_router} are checked. This is important because the number of possible ancestors increases exponentially with the number of parts in the path. The patterns that are known to exist are called the "masks".
Wildcard vs. Fitness
The right wildcard in these examples can also be %node, rather than %. Using %node gets you a node_load() for free passed into your page callback. However, it does not help calculate fitness.