Realname vs ctools(page manager)

Доброго времени суток!
Есть небольшой трабл: при установке модуля Realname и установленном Page Manager от CTools выключается страница типа:
Система blog_user User blog /blog/%user In code

и фиг ее включишь, выдает предупреждение:
файл blog_user.inc
Page manager module is unable to enable blog/%user because some other module already has overridden with %callback.

Код, откуда ноги растут имеет вид:

/**
* Callback defined by page_manager_blog_user_page_manager_tasks().
*
* Alter the user view input so that user view comes to us rather than the
* normal user view process.
*/
function page_manager_blog_user_menu_alter(&$items, $task) {
if (variable_get('page_manager_blog_user_disabled', TRUE)) {
return;
}

// Override the user view handler for our purpose.
if ($items['blog/%user_uid_optional']['page callback'] == 'blog_page_user' || variable_get('page_manager_override_anyway', FALSE)) {
$items['blog/%user_uid_optional']['page callback'] = 'page_manager_blog_user';
$items['blog/%user_uid_optional']['file path'] = $task['path'];
$items['blog/%user_uid_optional']['file'] = $task['file'];
}
else {
// automatically disable this task if it cannot be enabled.
variable_set('page_manager_blog_user_disabled', TRUE);
if (!empty($GLOBALS['page_manager_enabling_blog_user'])) {
drupal_set_message(t('Page manager module is unable to enable blog/%user because some other module already has overridden with %callback.', array('%callback' => $items['blog/%user']['page callback'])), 'error');
}
}
}

легкая отладка дает повод предположить, что во втором условии не выполняется ни первый вариант ни второй, и нам выключают "disable this task".

в то же время в файле realname.module происходит следующее:

/**
* Implements hook_menu_alter().
*/
function realname_menu_alter(&$callbacks) {
$callbacks['user/%user_uid_optional']['title callback'] = 'realname_user_page_title';

// Adjust menu page callbacks to the real name alternatives.
foreach ($callbacks as $path => $callback) {
if (isset($callback['page callback'])) {
switch ($callback['page callback']) {
case 'user_view':
// Skip if the Page manager module is installed, which needs to
// override
if ($path == 'user/%user_uid_optional' && module_exists('page_manager') && !variable_get('page_manager_user_view_disabled', TRUE)) {
continue;
}
case 'user_edit':
case 'tracker_page':
case 'statistics_user_tracker':
case 'content_profile_page_edit':
$callbacks[$path]['page callback'] = 'realname_' . $callback['page callback'];
break;
case 'contact_user_page':
$callbacks[$path]['page callback'] = 'realname_contact_user';
break;
case 'blog_page_user':
$callbacks[$path]['page callback'] = 'realname_blog_page';
break;
}
}
}

// Remove the core user_search, if requested.
if (variable_get('realname_user_disable', FALSE) && isset($callbacks['search/user/%menu_tail'])) {
unset($callbacks['search/user/%menu_tail']);
}
}

где меняется page callback 'blog_page_user' на 'realname_blog_page'

сама функция реализована так:

/**
* Intercept the user blog page.
*/
function realname_blog_page($account) {
if (module_exists('blogtitle')) {
$output = blogtitle_blog_page_user($account);
} else {
$output = blog_page_user($account);
drupal_set_title(t("@name's blog", array('@name' => $account->realname)));
}

return $output;
}

модуль blogtitle у меня не установлен, поэтому условие идет по второй ветке и возвращает blog_page_user($account) и устанавливает drupal_set_title(...), отключая при этом мне страницу в Page Manager.

Сам вопрос, зачем весь этот механизм, если он не дает нормально юзать страницы вида /blog/%user через Page Manager? И как было бы правильнее его исправить?

Коментарів:

4

Коментувати

Увійдіть або зареєструйтесь, щоб додати коментар

Коментарі

Выглядит все логично, нужно более детально подебажить и issues написать.
— realname_menu_alter — ставит вывод страницы блогов на себя и вывод заголовка то же на себя, потмоу что нужно везде поменять имена.
— realname_blog_page — тоже все логично

А вот с этим page_manager_blog_user_menu_alter мутно, интересно в какой последовательности включать модули нужно.
если сначала включить page_manager, она сама себя заблочит получается. Как-то мутно, нужно дебажить дальше и глубже.

если сначала включить page_manager, она сама себя заблочит получается. Как-то мутно, нужно дебажить дальше и глубже.
пока не вижу, где она сама себя заблочит.
Сейчас realname вызывает ф-цию blog_page_user и меняет title на том все и заканчивается.

$output = blog_page_user($account);
drupal_set_title(t("@name's blog", array('@name' => $account->realname)));

Сам же ctools если выключить realname установит функцию вызова в page_manager_blog_user а вот в самой функции(ниже), есть интересные моменты...

$items['blog/%user_uid_optional']['page callback'] = 'page_manager_blog_user';
$items['blog/%user_uid_optional']['file path'] = $task['path'];
$items['blog/%user_uid_optional']['file'] = $task['file'];

если условно разделить page_manager_blog_user на две части, первая часть вернет ctools_context_handler_render, и если не получится отрисовать контент панели, запустится механизм, который либо дефолтную функцию blog_page_user вызовет(как в realname только там напрямую), либо если есть в каком-либо модуле хук page_manager_override запустит его.

/**
* Entry point for our overridden user view.
*
* This function asks its assigned handlers who, if anyone, would like
* to run with it. If no one does, it passes through to Drupal core's
* user view, which is user_page_view().
*/
function page_manager_blog_user($account) {
// Load my task plugin:
$task = page_manager_get_task('blog_user');

// Load the account into a context.
ctools_include('context');
ctools_include('context-task-handler');
$contexts = ctools_context_handler_get_task_contexts($task, '', array($account));

$output = ctools_context_handler_render($task, '', $contexts, array($account->uid));
if ($output !== FALSE) {
return $output;
}

module_load_include('inc', 'blog', 'blog.pages');
$function = 'blog_page_user';
foreach (module_implements('page_manager_override') as $module) {
$call = $module . '_page_manager_override';
if (($rc = $call('blog_user')) && function_exists($rc)) {
$function = $rc;
break;
}
}

// Otherwise, fall back.
return $function($account);
}

В таком случае, думаю есть смысл "поправить" модуль realname? Или все таки нет?

Сложно сказать, нужно сначала хорошо дебажить эту связку модулей.
Насчет где заблочит сама себя:
function page_manager_blog_user_menu_alter(&$items, $task) {
if (variable_get('page_manager_blog_user_disabled', TRUE)) {
return;
}

этот флажок выставляется если в нижнем условии процесс пойдет по второй ветке, а в случае, если page_manager идет первым, выполняется равенство $items['blog/%user_uid_optional']['page callback'] == 'blog_page_user' и меняется вызов page callback на page_manager_blog_user, таким образом флажок останется в FALSE-неактивным. Как то так. Попробую написать issue на орге.