Вывод стороннего контента на drupal-сайте

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

Аватар пользователя intuman intuman 1 августа 2009 в 14:29

Добрый день!
Пытаюсь разобраться с ситуацией:

1) есть основной сайт, сделанный на основе Drupal, к примеру - www.drupal_site.com
2) есть вспомогательный сайт, выдающий HTML код по запросу на нужный адрес, к примеру, по адресу - www.content_site.com/content_page.php
3) задача: вывести этот код на странице drupal-сайта, например на странице: www.drupal_site.com/node/3
4) причём, желательно, чтобы на этой странице (в области контента) не было других элементов.

Например, при создании странички "page" или "story" необходимы заголовоки, это необходимые поля.
Здесь же нужно, чтобы в области контента было только содержимое www.content_site.com/content_page.php.

То есть, в двух словах, нужно вывести сторонний контент на конкретной странице drupal-сайта. Smile
Подозреваю, что задача решается ОЧЕНЬ просто, но увы...
Я только начал изучать возможности Drupal, поэтому не очень представляю, с какой стороны лучше к этому подступиться.
К тому же, возможно уже есть давно отработанные решения.

Необходимо написать специальный модуль и выводить его только на конкретной странице?
Или возможно уже есть модули, реализующие такую функцию?
Или это вообще контент другого типа, отличный от "page", "story" и т.д.?

Буду благодарен любым рекомендациям, ссылкам на доки, модули и т.п.! Smile

P.S. Возможно имеет смысл задать этот вопрос в какой-нибудь другой ветке? Если знаете, где мне могут помочь, подскажите.
Я начинающий пользователь Drupal, поэтому и пишу здесь. Smile

Комментарии

Аватар пользователя intuman intuman 1 августа 2009 в 15:08

В качестве приемлемого (но не оптимального) варианта нашёл такое решение:
В файлах "page.tpl.php" и "node.tpl.php" для действующей темы сайта ставить проверки на "$node->nid".
В случае, если номер совпадает, вызывать собственную функцию загрузки контента и выводить его.
Соответственно, блокируя вывод всего ненужного.

Плюсы: работает уже сейчас. Smile
Минусы: вариант не очень гибкий, хе-хе. В первую очередь для владельцев drupal-сайта.

Аватар пользователя neochief neochief 1 августа 2009 в 21:56

Мне кажется, дергать другой сайт при показе это слишком затратная операция. Контент определенно надо будет кешировать. Грамотней всего, написать небольшой модуль, который

- на hook_view() на $op == 'view' проверяет загружен ли контент (попыткой чтения из кеша cache_get()) (пример)
- если не загружен, загружает его обычным file_get_contents() и сохраняет это в кеш (cache_set())
- удаляет все из $node->content и забивает в него только лишь ваш контент

Это все может показаться сложноватым, для первого раза (на сколько я понимаю), но почитав доки, вам должно в конечном счете все придти.

Аватар пользователя intuman intuman 2 августа 2009 в 19:05

to neochief:
Ок, спасибо! Похоже, что это именно то, что мне нужно. Smile
Использование модуля, конечно предпочтительнее, чем копание сайтовых темплэйтов. Ведь в перспективе можно будет вывести в друпаловскую админку меню от этого модуля, в котором связать нужные страницы с нужными контент-ссылками.

В общем, буду копать документацию...

Аватар пользователя intuman intuman 2 августа 2009 в 19:09

to PVasili:
Спасибо за помощь. Smile
Я уже решил, что лучше один раз разобраться и написать этот модуль самому.
Потом будет меньше вопросов. Smile

Аватар пользователя intuman intuman 4 августа 2009 в 12:20

to neochief:
Ещё раз здравствуйте!
Модуль написан и работает, но есть проблема с редактированием содержимого перед выводом.
Если конкретно: есть объект $node, который включает в себя $node->title и $node->content.
Content, в свою очередь, включает body и собственноручно добавленный контент.

Я использую хук hook_nodeapi() на $op == 'view', примерно вот так:

<?php
function my_module_nodeapi(&$node$op$teaser$page) { 

   if (

$op == 'view') { 
      
// Вот это не оказывает на вывод никакого влияния
      
$node->title 'Custom title';

      

// в то время, как вот это прекрасно убивает содержимое контента
      
unset($node->content);

      

// а вот эта часть прекрасно добавляется и выводится
      
$node->content['my_module_form'] = array( 
         
'#value'  => 'My custom text.'
         
'#weight' => 
      
);
   }

}

?>

Получается, что в данном конкретно случае (hook_nodeapi() и $op == 'view') какие-то части $node можно менять, а какие-то нет.
Точнее, где-то изменение влияет на вывод, а где-то нет.

В связи с этим есть несколько вопросов.
1) Есть ли возможность вносить изменения в $node->title либо в другие части объекта $node таким образом, чтобы это гарантированно отражалось при загрузке нужной страницы? Если есть, то где?
2) При чтении форума неоднократно встречал термин "сборка темплэйта". Получается, что сборка происходит до вызова hook_nodeapi() при $op == 'view'? Иначе почему изменение $node->title не оказывает влияния на результат вывода?
3) Собственно, где и как менять содержимое $node, чтобы оно менялось "до", а не "после"? Smile

Цель - по возможности убрать со страницы всё ненужное (с моей точки зрения).

Аватар пользователя neochief neochief 4 августа 2009 в 13:01

На (hook_nodeapi() и $op == 'view') происходит сборка переменной $content, которую вы можете найти у себя в шаблоне node.tpl.php. Вы можете не затрагивать чужие изменения только в случае, если ваш модуль выполняется не последним. Чтобы он выполнялся последним, ему нужно выставить большой вес в системе. Лучше всего это делать в install файле так:

function my_module_install() {
  db_query("UPDATE {system} SET weight = 100 WHERE name = 'my_module'");
}

Но т.к. у вас уже все включено, просто выполните этот запрос в вашей базе.

Если это не поможет, есть еще (hook_nodeapi() и $op == 'alter'), о чем можно прочитать в доках или банальноп посмотреть в код.

И в самом конце, есть еще функции препроцессинга шаблона ноды (phptemplate_preprocess_node() или themename_preprocess_node()), в которых также можно внести измеения.

Аватар пользователя intuman intuman 4 августа 2009 в 15:18

to neochief:
Понятно.
Я выполнил этот запрос, вес модуля увеличился (я в БД посмотрел), но title остался.
Тогда я поэкспериментировал и нашёл такой рабочий вариант:

<?php
function my_module_nodeapi(&$node$op$teaser$page) { 

  

// Номер ноды с контентом (задаётся в админке модуля)
  
$content_page_number variable_get('my_module_page_number'0);
    
  
// Вот здесь работает!
  
if ($node->nid == $content_page_number)  $node->title '';
    
  if (
$op == 'view') {
    
// А вот тут уже не очень.
    
$node->title '';
  }
}
?>

Вывод контента всё равно всегда будет связан с конкретной нодой.
А учитывая, что в данном случае ехать важнее, чем шашечки, то вполне приемлемо.
Вот осталось такое ощущение, что между ($op == 'view') и окончательным формированием контента затерялся ещё один промежуточный этап с вызовом hook_nodeapi(), где и выводится этот предательский title! Wacko
Но, самое главное, теперь всё работает как надо.

В любом случае, огромное спасибо за помощь! Smile
Сам бы я долго разбирался.

Аватар пользователя neochief neochief 4 августа 2009 в 15:27

Смотрим node_page_view(). Там внутри есть вызов, который вызывается до node_show() (который тригерит все наши хуки ноды), и выставляет тайтл страницы. Вам нужно просто дублировать этот вызов у себя.

Аватар пользователя intuman intuman 4 августа 2009 в 16:53

to neochief:
Точно!
drupal_set_title('') - прекрасно справляется отовсюду. Smile

Видимо в этом всё и дело, что я пока не до конца разобрался, в какой последовательности работает система целиком. То есть, что вызывается сначала, что потом, и т.д., хотя бы в общих чертах. Сейчас вот буду разбираться, какое место в пищевой цепочке занимает node_page_view()... До этого я и не подозревал о его существовании. Хе-хе. Wacko

Ещё раз спасибо! Smile

Аватар пользователя neochief neochief 4 августа 2009 в 17:36

Помогает хороший редактор с функцией поиска по файлам + использование http://api.drupal.ru/

node_page_view() — это коллбэк меню для адресов 'node/%', который объявляется в node_menu(). Его можно сичтать точкой отсчета, и спускаться вниз по вызовам.