Not dead yet: Overcoming fatal errors converting a theme with some override functions in template.php
Upgrading a theme from Drupal 5 to Drupal 6, Agaric ran across this lovely fatal error:
Fatal error: Call to undefined function menu_item_link() in /sites/example/www/sites/default/themes/agaric_custom_theme/template.php on line 15
And indeed, menu_item_link ends with Drupal 5: http://api.drupal.org/api/function/menu_item_link/5
There is, however, a theme_menu_item_link for Drupal 6: http://api.drupal.org/api/function/theme_menu_item_link/6
(There was for 5 also however, so it can't be a replacement for menu_item_link
Replacing
<?php
$link = menu_item_link($mid);
?>
with the theme function does NOT work:
<?php
$link = theme('menu_item_link', $mid); // main problem: it expects a path, not a menu ID
?>
Found using grep -nHR menu_item_link .
at the base of a Drupal 5 installation, let's look at a function that used menu_item_link() in Drupal 5:
<?php
function menu_get_active_breadcrumb() {
// No breadcrumb for the front page.
if (drupal_is_front_page()) {
return array();
}
// We do *not* want to use "variable_get('site_frontpage', 'node)" here
// as that will create the link '/node'. This is unsightly and creates
// a second URL for the homepage ('/' *and* '/node').
$links[] = l(t('Home'), '');
$trail = _menu_get_active_trail();
foreach ($trail as $mid) {
$item = menu_get_item($mid);
if ($item['type'] & MENU_VISIBLE_IN_BREADCRUMB) {
$links[] = menu_item_link($mid);
}
}
// The last item in the trail is the page title; don't display it here.
array_pop($links);
return
$links;
}
?>
And here's the same function in Drupal 6:
<?php
function menu_get_active_breadcrumb() {
$breadcrumb = array();
// No breadcrumb for the front page.
if (drupal_is_front_page()) {
return $breadcrumb;
}
$item = menu_get_item();
if ($item && $item['access']) {
$active_trail = menu_get_active_trail();
foreach (
$active_trail as $parent) {
$breadcrumb[] = l($parent['title'], $parent['href'], $parent['localized_options']);
}
$end = end($active_trail);
// Don't show a link to the current page in the breadcrumb trail.
if ($item['href'] == $end['href'] || ($item['type'] == MENU_DEFAULT_LOCAL_TASK && $end['href'] != '<front>')) {
array_pop($breadcrumb);
}
}
return $breadcrumb;
}
?>
Conclusion: it's quite different and after I concluded I didn't even need the function that was calling menu_item_link(), I realized the far more direct way to fix this was to look at the function that called it:
SEOposition's phptemplate_menu_item(), based on Drupal 5's theme_menu_item(), needed to be replaced with a version compatible with Drupal 6's theme_menu_item(). The main difference is that the function gets passed in a menu item, not a menu ID– so there is no need for menu_item_link() at all!
Before, Drupal 5 version:
<?php
function phptemplate_menu_item($mid, $children = '', $leaf = TRUE) {
// grab text from link
$link = menu_item_link($mid);
$textbegin = strpos($link, ">") + 1;
$textend = strpos($link, "<", 2);
$textlen = $textend - $textbegin;
$text = substr($link, $textbegin, $textlen);
$text = $text.($leaf ? '' : ($children ? ':' : '…'));
$link = substr_replace($link, $text, $textbegin, $textlen);
return
'<li class="'. ($leaf ? 'leaf' : ($children ? 'expanded' : 'collapsed')) .'">'. $link . $children ."</li>\n";
}
?>
// adds branch indicators to menu links
function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
// grab text from link
$textbegin = strpos($link, ">") + 1;
$textend = strpos($link, "<", 2);
$textlen = $textend - $textbegin;
$text = substr($link, $textbegin, $textlen);
$text = $text.($leaf ? '' : ($children ? ':' : '…'));
$link = substr_replace($link, $text, $textbegin, $textlen);
return '<li class="' . $class . '">' . $link . $menu . "</li>\n";
}
And I still don't really get what purpose it serves, heh. But it works!
Another problem: Unsupported operand types
WHAT? (I was disconcerted because the problem seemed to be coming from Drupal core!)
Fatal error: Unsupported operand types in /sites/help4computers/www/includes/common.inc on line 1445
Ah: That's the ubiquitous l() (for Link) function that takes an array of options in D6, rather than a long comma-separated list of parameters as it did previously.
The line and file sited in the error:
<?php
function l($text, $path, $options = array()) { // Merge in defaults.
$options += array( 'attributes' => array(),
'html' => FALSE,
);
//...
}
?>
Solution is simply to use the Drupal 6 style array for options, which was easy because the code in question already had all the link elements as options– just had to delete all the separate listings of each array element after href and leave the link array:
<?php
$outputbuffer .= '(' . l($link['title'], $link['href'], $link).")";
?>
Reference:
http://drupal.org/node/132442
Comments
Agaric saves the day again
or so this e-mail from Brian Dominick was titled:
That's the Agaric way... making all the stupid mistakes you're going to make... first! (Oh creator-of-life PHP, forgive Brian for his faith in Coldfusion... someday he will see the light.)
Post new comment