Как вернуть node без menu?

Главные вкладки

Аватар пользователя makbuk makbuk 11 марта 2017 в 10:51

Возможно, это простой вопрос, но я не могу понять, как вернуть тело node без menu . Я сделал модуль, который загружает содержимое node в пользовательскую область.

<?php
function loadnode_in_region_menu_alter(&$items) {
    
$items['load_node/%'] = array(
        
'page callback' => 'loadnode_in_region_node_page_view',
        
'page arguments' => array(1),
        
'access callback' => 'user_access',
        
'access arguments' => array('access content'),
        
'type' => MENU_CALLBACK,
    );

return 

$items;  
}

function 

loadnode_in_region_node_page_view($nid) {
    
$node node_load($nidNULLfalse);
    
$vnode node_view($node);
    return 
drupal_render($vnode);
}
?>

Javascript выглядит так:

jQuery.ajax({
    type: 'GET',
    url: Drupal.settings.basePath + 'load_node/' + id,
    dataType: 'html',
    success: function(data){
        jQuery('#ajax-result').html(data);
    },
});

Результат выглядит так, с дублирующимся меню:
https://i.stack.imgur.com/0tYxx.png

Если я меняю строку с
return drupal_render($vnode);
на
echo drupal_render($vnode); ИЛИ print drupal_render($vnode);
Результат выглядит так, как мне бы хотелось, но некоторые поля отображаются неправильно, например голосование и изображение. И изображение не открывается в Lightbox.
https://i.stack.imgur.com/yv3ts.png

Как можно вернуть тело ноды без меню?

Комментарии

Аватар пользователя bumble bumble 12 марта 2017 в 16:20
1

1. Зачем hook_menu_alter ? Должен быть обычный hook_menu.

Это:

<?php
function loadnode_in_region_menu_alter(&$items) {
    
$items['load_node/%'] = array(
        
'page callback' => 'loadnode_in_region_node_page_view',
        
'page arguments' => array(1),
        
'access callback' => 'user_access',
        
'access arguments' => array('access content'),
        
'type' => MENU_CALLBACK,
    );

return 

$items;  
}

function 

loadnode_in_region_node_page_view($nid) {
    
$node node_load($nidNULLfalse);
    
$vnode node_view($node);
    return 
drupal_render($vnode);
}
?>

правильнее так:

<?php
function loadnode_in_region_menu() {
    
$items['load_node/%node'] = array(
        
'page callback' => 'loadnode_in_region_node_page_view',
        
'page arguments' => array(1),
        
'access arguments' => array('access content'),
        
'type' => MENU_CALLBACK,
    );

return 

$items;  
}

function 

loadnode_in_region_node_page_view($node) {
    return 
node_view($node);
}
?>

Но! Это все дело нужно использовать Drupal-way'но, и Ваш Javascript тут не нужен.

Вот как можно:

<?php
/**
 * Обычный хук меню с коллбеком доставки "ajax_deliver"
 */
function loadnode_in_region_menu() {
  
$items['load_node/%node'] = array(
    
'page callback'     => 'loadnode_in_region_node_page_view',
    
'page arguments'    => array(1),
    
'access arguments'  => array('access content'),
    
'type'              => MENU_CALLBACK,
    
'delivery callback' => 'ajax_deliver',
  );

  return 

$items;
}

/**
 * Коллбек страницы с AJAX-командами
 */
function loadnode_in_region_node_page_view($node) {
  
$output node_view($node);

  

$commands = array();
  
$commands[] = ajax_command_html('#ajax-result'render($output));

  return array(
    

'#type'     => 'ajax',
    
'#commands' => $commands,
  );
}

/**
 * Подобный коллбек можно использовать для генерации ссылки
 * на загрузку ноды.
 *
 * Главная задача коллбека - вернуть ссылку, вида:
 *   <a href="/load_node/1" class="use-ajax">Load node</a>
 */
function loadnode_in_region_view_booble($nid) {
  
// Подключаем либу для правильной работы
  
drupal_add_library('system''drupal.ajax');

  

// Возвращаем ссылку
  
return l(t('Load node'), "load_node/$nid", array(
    
'attributes' => array(
      
'class' => array('use-ajax'),
    ),
  ));
}
?>

Здесь:

  • реализуется хук меню по которому грузится нода
  • коллбек страницы загружающий рендер-массив ноды и выполняющий команду для замены содержимого страницы (JQuery-метод .html())
  • создан коллбек генерации ссылок, кликнув по которой будет произведена загрузка контента в необходимую область (из примера - селектор #ajax-result)

По-хорошему, еще стоит соорудить версию для JS-disabled девайсов, но то уже таке...

Аватар пользователя makbuk makbuk 12 марта 2017 в 18:55

Спасибо за ответ. По какой-то причине код работает не так как ожидалось, если я оставляю включенным JS, то регион заполняется как на картинке.
http://www.drupal.ru/files/field/comment_node_blog/err.png
Если отключить JS, то не заполняется вообще.

Аватар пользователя bumble bumble 12 марта 2017 в 19:29
  1. Проверьте правильно ли скопировали данные
  2. Почистите кеш
  3. Не забудьте отключить "свой Javascript"
  4. Если ничего не получается - показывайте как делаете, наугад не определяем...
Аватар пользователя makbuk makbuk 12 марта 2017 в 22:33

Я отключил свой модуль, создал новый пустой.
1 Скопировал без изменений все после "Вот как можно:" (без <?php<php ?>) до "Здесь:"
2 Почистил кеш
Когда нажимаю на ссылку пишет "Не найдена страница " "/load_node/348".

Где можно почитать про хук hook_view_booble? На сайте https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7.x я его не нашел.

Аватар пользователя makbuk makbuk 12 марта 2017 в 23:21

Нашел ошибку, но не срабатывает function loadnode_in_region_view_booble($nid) , ajax возвращает данные, но не загружает в нужную область. Я так понимаю, что привязка 'use-ajax' должна происходить в момент клика, но этого не происходит.

Аватар пользователя bumble bumble 12 марта 2017 в 23:24

Еще раз повторю - или приводите полностью код, или не спрашивайте в чем у Вас ошибка.
Рассуждения у Вас, пока, не особо правильные.

Аватар пользователя makbuk makbuk 12 марта 2017 в 23:29

Код имеет следующий вид

<?php
/**
 * Обычный хук меню с коллбеком доставки "ajax_deliver"
 */
function mymodule_menu() {
  
$items['load_node/%node'] = array(
    
'page callback' => 'mymodule_node_page_view',
    
'page arguments' => array(1),
    
'access arguments' => array('access content'),
    
'type' => MENU_CALLBACK,
    
'delivery callback' => 'ajax_deliver',
  );
  return 
$items;
}

/**
 * Коллбек страницы с AJAX-командами
 */
function mymodule_node_page_view($node) {
  
$output node_view($node);
  
$commands = array();
  
$commands[] = ajax_command_html('#ajax-result'render($output));

  return array(
    

'#type'     => 'ajax',
    
'#commands' => $commands,
  );
}

/**
 * Подобный коллбек можно использовать для генерации ссылки
 * на загрузку ноды. 'attributes' => array(
      'class' => array('use-ajax'),
 *
 * Главная задача коллбека - вернуть ссылку, вида:
 *   <a href="/load_node/1" class="use-ajax">Load node</a>
 */
function mymodule_view_booble($nid) {
  
// Подключаем либу для правильной работы
  
drupal_add_library('system''drupal.ajax');

// Возвращаем ссылку
  
return l(t('Load node'), "load_node/$nid", array(
    
'attributes' => array(
        
'class' => array('use-ajax'),
    ),
  ));
}
?>
Аватар пользователя makbuk makbuk 12 марта 2017 в 23:32

Ссылка из модуля IP Geolocation Views & Maps
файл ip_geoloc_leaflet_goto_content_on_click.js

«

jQuery(document).bind('leaflet.feature', function(event, marker, feature) {
  // marker is the feature just added to the map, it could be a polygon too.
  // feature.feature_id is the node ID, as set by ip_geoloc_plugin_style_leaflet.inc
  // Need to set this up for code below.
  // The same code is used for cross-highlighting. See ip_geoloc_leaflet_sync_content.js
  if (feature.feature_id) {
    marker.feature_id = feature.feature_id;
  }
});

jQuery(document).bind('leaflet.map', function(event, map, lMap) {

  if (map.settings.gotoContentOnClick) {
    for (var leaflet_id in lMap._layers) {
      lMap._layers[leaflet_id].on('click', function(e) {
        var id = e.target ? e.target.feature_id : null;
        if (!id && e.layer) id = e.layer.feature_id;
        if (id) {

                        document.location.href = Drupal.settings.basePath + 'load_node/' + id; <<<----CCЫЛКА
        }
      });
    }
  }
  if (map.settings.openBalloonsOnHover) {
    for (var leaflet_id in lMap._layers) {
      lMap._layers[leaflet_id].on('mouseover', function(e) {
        this.openPopup();
                 Drupal.attachBehaviors();
      });
    }
  }

});

»

Аватар пользователя bumble bumble 12 марта 2017 в 23:46
1

js'ом ссылки добавляются?

Тогда вручную подключите библиотеку, и может ссылки вручную нужно будет биндить чтоб аякс подхватили.

Аватар пользователя makbuk makbuk 12 марта 2017 в 23:55

В ручную подключить библиотеку я так понимаю это следующим способом:

<?phpfunction mymodule_init() {
  drupal_add_library('system', 'drupal.ajax');
  drupal_add_library('system', 'jquery.form');
}?>

«ссылки вручную нужно будет биндить чтоб аякс подхватили.»

А как можно вручную биндить ссылки?

Аватар пользователя bumble bumble 13 марта 2017 в 0:29
1

Ну, можно и в хук инит, но на всех страницах будет грузится. И формы не нужны вроде...
Попробуйте просто ссылки сооружать с классом "use-ajax", если не прокатит - глядите "misc/ajax.js", вот тут тоже описано: http://drupalapi.attiks.com/api/drupal/misc%21ajax.js/property/Drupal.be...