[development] The menu - does it have to be different on each
page?
adrian rossouw
adrian at bryght.com
Thu Aug 31 01:17:05 UTC 2006
On 30 Aug 2006, at 8:25 PM, Johan Forngren wrote:
>> WWFAPID? (What would FormsAPI do?)
> $menu['menu'] = array(
> '#type' => 'menu',
> '#path' => array ('menu', 'yet', 'another', 'path', 'etc'),
> '#title' => t('Menu'),
> '#tree' => TRUE,
> '#collapsible' => TRUE,
> '#collapsed' => TRUE,
> );
> $menu['menu']['item'] = array('
> '#type' => 'node',
> '#nid' => 1337,
> '#title' => t('Node'),
> '#description' => t('A node item'),
> '#weight' => 5,
> );
> $menu['menu']['item2'] = array('
> '#type' => 'page',
> '#callback' => 1337,
> '#title' => t('A page'),
> '#path' => array(t('translatable'), t('path')),
> );
a couple of things for this.
You would still sit with the may_cache issue, in that every run would
need 2 calls, because it can't be cached.
What i plan to do is make fapi elements possibly be callbacks, which
means any property can be a function that can instead be executed,
along with variables that can be used in the call. What this would
mean is that the instruction to check the function can be cached, but
not the final value.. an example of this would be the access check,
which currently needs to be cached per role because of permissions.
. In the following case :
$menu['node']['%d'][edit'] = array('
'#type' => 'page',
'#callback' => 'drupal_get_form',
'#callback_arguments' => callback('arg', 1), // returns an array,
so you can do callback(something) + callback(something)
'#access' => callback('user_access', 'some_permission'),
'#title' => t('A page'),
'#path' => array(t('translatable'), t('path')),
)
Take for example if you had the entire menu loaded into memory (and
unserialising it is quite expensive too).
When loading up the system, is can go :
$section &= $menu;
$parts = expode('/', $_GET['q']);
foreach ($parts as $part) {
$x++;
// this if statement will almost surely be incorrect, but it has
the general idea
if (isset($section[$part]) || (is_numeric($part) && isset($section
['%d'])) || (isset($section['%s']) ) {
// finds all callback arrays, and trigger them
trigger_callbacks($section[$part]);
if (!$section['#access']) {
drupal_access_denied();
break;
}
else {
//success, we have access to this item
$section &= $section[$part];
$found_part[] = $part;
}
}
What you will have here, is :
a) the stuff stored in the database not being role specific, and one
data structure is capable of serving the entire system
b) expensive 'path index' building not needed.
c) no longer needing may_cache, as the callbacks can be stored in the
database, but the final values can't.
d) Only the required parts of the tree are touched.
You could possibly select only the part of the tree you are
interested in .. in this example :
node, node/1, node/%d, node/%s, node/1/edit, node/1/%d, node/1/%s,
node/%d/edit etc.
So you could put those all in an array, and search for just those
menu items, and also sort them that way for traversal.
Doing such a search on a textfield could be expensive, but earl
mentioned that we could possibly just do md5's of the data in
the database, and just doing a search on md5sums in (list of integers).
This is only part of the battle though, as matching paths to
callbacks is a much lighter problem than actually displaying the menu.
But I think , that if you had the md5 of each of the parent elements
of the menu items (and you have the entire path to your current
location),
you could create a single sql query to retrieve only the necessary
levels from the tree.. and each of these layers could very possibly be
cached. (ie: get all the elements directly in the root, all the
elements in node/ , all the elements in node/1 and all the elements
underneath node/1).
>>
>> Would doing a more formsapi-ish approach make the code easier to
>> read? Slower? Faster?
> Not sure
Eh. i'm not sure either, but I'm confident with the tricks I
outlined, we should be able to at least get the bootstrap
requirements lowered,
since every load of drupal loads the _ENTIRE_ menu structure with
_ALL_ the information needed to render that mammoth block.
Not to mention, that all the menu items are always loaded into drupal
(it was the same case with the paths, and made them perform quite badly)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/development/attachments/20060831/b4490bb9/attachment-0001.htm
More information about the development
mailing list