Я хотел бы отображать представление Drupal без шаблона страницы, который обычно его окружает - мне нужно только простое HTML-содержимое узлов представления.
Это представление будет включено в другой сайт, не относящийся к Drupal.
Я ожидаю, что мне придется сделать это с несколькими представлениями, поэтому решение, которое позволяет мне быстро и легко настроить их, будет лучшим - я бы предпочел не создавать файл .tpl.php каждый раз, когда мне нужно включить представление где-нибудь.






есть, вероятно, несколько способов обойти это, однако "самый простой" может заключаться в установке вашей собственной темы и пустом page.tpl.php или нескольких случайных div
// page.tpl.php
<div id = "page"><?php print $content ?></div>
этот метод в основном просто позволяет отображать node.tpl.php (или любое из представлений формы drupal и т.д.) и был бы простым способом избежать изменения ядра или необходимости изменять реестр темы, чтобы избежать отображения page.tpl .php в первую очередь.
редактировать: см. Комментарии
хорошо, я немного поигрался с представлениями, похоже, он берет на себя и создает свой собственный "node.tpl.php" (в некотором смысле) для отображения в "page.tpl.php". на первый взгляд, мне кажется, что я подключусь к theme_registry_alter().
когда вы просматриваете страницу просмотров, у вас есть доступ к куче информации, а также к путям / файлам page.tpl.php. как таковой я бы сделал что-то вроде:
function modulejustforalteration_theme_registry_alter(&$variables) {
if (isset($variables['views_ui_list_views']) ) {
// not sure if that's the best index to test for "views" but i imagine it'll work
// as well as others
$variables['page']['template'] = 'override_page';
}
}
это должно позволить вам использовать шаблон override_page.tpl.php в вашей текущей теме, в котором вы можете удалить все, что захотите (как мой первый ответ выше).
несколько вещей:
views_ui_list_views всегда доступен для проверки, но похоже, что он должен быть установлен, если мы смотрим на представлениеtheme paths массива page, если хотите (чтобы изменить местоположение, где drupal будет искать page.tpl.php, вместо того, чтобы переименовывать его полностью)template_preprocess_page() будет лучшей идеей.хм, у вас есть только определенные типы узлов, которые будут "внешним видом"? или вы можете уточнить это немного подробнее? то есть я думаю, что есть другой ответ для «узлы страницы являются внешними» и «узлы любого типа, которые я выбираю, являются внешними»
Это не узлы, это представления. Все узлы должны иногда отображаться в шаблонах страниц. Не следует ограничивать просмотры (с отображением страниц). Вроде как работает отображение ленты, но с узлом HTML вместо формата RSS.
ах хмм, я не очень много играл с видами, но я посмотрю сегодня днем и посмотрю, могу ли я дать какой-нибудь лучший совет, я не уверен, как просмотры конкретно соединяют вместе его элементы, но у меня есть чувство ответ заключается в изменении реестра тем. это друпал 6 да?
Ага, D6. Я подозреваю, что вы правы, что небольшой модуль, который настраивает реестр тем, может быть лучшим способом. Я удивлен, что никому еще не понадобилось что-то подобное для создания модуля ...
Если я понимаю ваш вопрос, вы хотите иметь узлы, содержащие весь HTML для страницы, от DOCTYPE до </HTML>. Я бы создал тип содержимого для этих узлов - "fullhtml" в качестве его машиночитаемого имени - а затем создал бы для него шаблон узла с именем node-fullhtml.tpl.php. Вы не можете просто сбросить содержимое узла, так как оно было обработано с помощью HTML. node.fullhtml.tpl.php буквально будет таким:
echo htmlspecialchars_decode($content);
Тогда вам понадобится способ переопределить стандартный page.tpl.php. Я считать то, что вы могли бы сделать, это вверху страницы. Tpl.php проверять тип содержимого $ node и спасать, если он fullhtml. Или установите глобальную переменную в node-fullhtml.tpl.php, которую будет проверять page.tpl.php.
Я не эксперт по Drupal, но я бы сделал это так. Я говорю не по манжете, так что следите за чертями в деталях.
Вы неправильно поняли мой вопрос. Мне не нужны DOCTYPE и HTML, так как на странице, на которой будет отображаться представление, все это уже есть. Мне нужно только фактическое нестилизованное содержимое узла. Создание нового типа контента не сработает, так как я зависим от типов контента для организации на сайте.
Может быть, вам стоит перефразировать или расширить вопрос.
Мне кажется, что я достаточно ясно сформулировал свой исходный вопрос, поскольку в нем явно указано, что мне не нужен шаблон страницы, окружающий содержимое узла.
Думаю, если вы посмотрите на мое решение, то оно вот что. Возможно, это не то, что вы ищете, но весь смысл того, что я здесь представляю, состоит в том, чтобы предотвратить активацию шаблона страницы.
К вашему сведению - решение Джима хорошее и имеет то преимущество, что его можно реализовать как на drupal 5, так и на 6.
Предполагая, что вы используете Drupal 6, самый простой способ сделать это - поместить вызов phptemplate_views_view_unformatted_VIEWNAME в template.php (предполагается, что ваше представление неформатировано - если это что-то еще, например список, используйте соответствующую функцию темы). Создайте тему для результатов просмотра в этом вызове темы, а затем вместо того, чтобы возвращать результаты, как обычно, распечатайте их и верните NULL. Это выведет HTML напрямую.
PS - не забудьте очистить кеш (в / admin / settings / performance), чтобы увидеть эту работу.
Мне нравится модуль Drupal. Но вот еще один способ.
скопируйте page.tpl.php из папки вашей темы в новый файл с именем page-VIEWNAME.tpl.php, где VIEWNAME - машиночитаемое имя представления.
Затем отредактируйте page-VIEWNAME.tpl.php по своему усмотрению.
Я вижу, что вы уже сделали себе модуль, так что это может больше не помогать, но довольно легко получить представление для открытия RSS-канала, что может быть более простым способом доступа к контенту, особенно если вы хотите чтобы разместить его на другом сайте.
Я искал способ извлечения данных узла через ajax и придумал следующее решение для Drupal 6. После внесения изменений ниже, если вы добавите ajax = 1 в URL-адрес (например, mysite.com/node/1?ajax= 1), вы получите только контент, а не макет страницы.
в файле template.php вашей темы:
function phptemplate_preprocess_page(&$vars) {
if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 ) {
$vars['template_file'] = 'page-ajax';
}
}
затем создайте page-ajax.tpl.php в каталоге вашей темы с этим содержимым:
<?php print $content; ?>
Это хороший простой и эффективный способ сделать это! Ух ты! Добро пожаловать в StackOverflow и спасибо!
Это кажется правильным ответом, но для меня он не работает. Я помещаю оператор печати в функцию phptemplate_preprocess_page (& $ vars) {print "Он попадает сюда"; } и ничего не происходит. Я даже не думаю, что эта функция вызывается.
Есть ли ситуации, когда это может не быть вызвано?
Брайан: имя "phptemplate" означает название вашей темы. Моя тема называется "carshop", поэтому имя функции будет carshop_preprocess_page (& $ vars).
Это просто и элегантно ... но вам все равно придется иметь дело со всем этим беспорядочным форматированием и мусором. Конечно, для этого есть хороший модуль: drupal.org/project/views_datasource
Существует также http://drupal.org/project/pagearray, который является общим решением ...
Кроме того, решение @Scott Evernden представляет собой дыру в безопасности межсайтового скриптинга (XSS). Не делай этого. Прочтите документацию на drupal.org о том, как безопасно обрабатывать текст http://drupal.org/node/28984
Для других, кто может попасть на эту страницу, если вы просто работаете со стандартными обратными вызовами (не обязательно представлениями), это легко. В вашей функции обратного вызова вместо возврата кода для рендеринга на странице используйте функцию «print».
Например:
function mymodule_do_ajax($node)
{
$rval = <<<RVAL
<table>
<th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</th>
<tr>
<td>Cool</td>
<td>Cool</td>
<td>Cool</td>
</tr>
</table>
RVAL;
//return $rval; Nope! Will render via the templating engine.
print $rval; //Much better. No wrapper.
}
Ваше здоровье!
Это, безусловно, самое простое решение. Спасибо.
Простой способ отображать контент особого типа, который вы хотите отображать, без всего, что есть на page.tpl.php:
Добавьте следующий фрагмент в свой файл template.php:
function mytheme_preprocess_page(&$vars) {
if ($vars['node'] && arg(2) != 'edit') {
$vars['template_files'][] = 'page-nodetype-'. $vars['node']->type;
}
}
Добавьте page-nodetype-examplecontenttype.tpl.php в свою тему, например page.tpl.php, но без того материала, который вы не хотите отображать, и с print $content в теле.
Эй, вот еще один способ сделать это:
1) Загрузите и установите бонусный пакет просмотров (http://drupal.org/project/views_bonus) 2) Создайте отображение «Feed» в представлении и используйте стиль «XML» (или что-то, что, по вашему мнению, лучше соответствует вашим потребностям). 3) Если вас не устраивает стандартный вывод XML, вы можете изменить его, настроив шаблон для представления. Проверьте настройки «темы», чтобы получить предложения по альтернативным именам шаблонов для этого конкретного представления (так что вы все равно будете иметь выходные данные XML по умолчанию для будущего использования).
Удачи! // Йохан Фальк, NodeOne, Швеция
Основываясь на ответе Philadelphia Web Design (спасибо) и некоторых поисковых запросах (http://drupal.org/node/957250), вот что у меня сработало в Drupal 7, чтобы отображать выбранные страницы без шаблона:
function pixture_reloaded_preprocess_page(&$vars)
{
if ( isset($_GET['vlozeno']) && $_GET['vlozeno'] == 1 ) {
$vars['theme_hook_suggestions'][] = 'page__vlozeno';
}
}
вместо phptemplate в D7 должно быть name_of_your_theme в имени функции. Кроме того, мне пришлось поставить два символа подчеркивания __ в переменной php с именем файла, но для фактического имени файла шаблона нужно два дефиса -
содержание страницы - vlozeno.tpl.php:
<?php print render($page['content']); ?>
Однако на выходе все еще есть много оберток и ссылок CSS на темы. Не уверен, как выводить совершенно незарегистрированные данные ...
Если вы хотите полностью удалить весь HTML-обертку, включая <head>, <title>, <body>, .., вы можете реализовать аналогичное предложение темы с помощью MY_THEME_preprocess_html
Основываясь на ответе Ufonion Labs, я смог полностью удалить весь HTML-вывод вокруг содержимого страницы в Drupal 7, реализовав как hook_preprocess_page, так и hook_preprocess_html в моих темах template.php, например:
function MY_THEME_preprocess_page(&$variables) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'page__embed';
}
}
function MY_THEME_preprocess_html(&$variables) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'html__embed';
}
}
Затем я добавил в свою тему два шаблона: html--embed.tpl.php:
<?php print $page; ?>
и page--embed.tpl.php:
<?php print render($page['content']); ?>
Теперь, когда я открываю страницу узла, такую как http://example.com/node/3, я вижу всю страницу как обычно, но когда я добавляю параметр response_type, такой как http://example.com/node/3?response_type=embed, я Только получаю <div> с содержимым страницы, чтобы его можно было встроить на другую страницу.
Спасибо, я потратил несколько часов на тестирование других методов, которые не работали.
Другой способ сделать это, который я считаю очень удобным, - добавить пункт меню с функцией обратного вызова страницы, которая не возвращает строку:
Пример:
/**
* Implementation of hook_menu.
*/
function test_menu(){
$items['test'] = array (
/* [...] */
'page callback' => 'test_callback',
/* [...] */
);
return $items;
}
function test_callback() {
// echo or print whatever you want
// embed views if you want
// DO NOT RETURN A STRING
return TRUE;
}
-- Обновлять
Было бы намного лучше использовать exit(); вместо return TRUE; (см. Комментарий).
Это вызовет кучу предупреждений, если вы используете ctools (ctools_page_alter будет считать, что это массив).
Я знаю, что на этот вопрос уже был дан ответ, но я хотел добавить свое собственное решение, которое использует элементы ответа Philadelphia Web Design (PWD) и использует hook_theme_registry_alter, как было предложено Оуэном. Используя это решение, вы можете загрузить шаблон прямо из настраиваемого модуля.
Сначала я добавил raw.tpl.php во вновь созданную папку «Шаблоны» внутри моего модуля. Содержимое raw.tpl.php идентично PWD page-ajax.tpl.php:
<?php print $content; ?>
Затем я реализовал hook_preprocess_page в своем модуле так же, как и PWD (за исключением того, что я изменил параметр $ _GET и обновил ссылку на файл шаблона:
function MY_MODULE_NAME_preprocess_page(&$vars) {
if ( isset($_GET['raw']) && $_GET['raw'] == 1 ) {
$vars['template_file'] = 'raw';
}
}
Наконец, я реализовал hook_theme_registry_alter, чтобы добавить каталог шаблонов моего модуля в реестр тем (на основе http://drupal.org/node/1105922#comment-4265700):
function MY_MODULE_NAME_theme_registry_alter(&$theme_registry) {
$modulepath = drupal_get_path('module','MY_MODULE_NAME');
array_unshift($theme_registry['page']['theme paths'], $modulepath.'/templates');
}
Теперь, когда я добавляю? Raw = 1 к URL-пути представления, он будет использовать указанный шаблон внутри моего модуля.
На D7 можно использовать menu_execute_active_handler
$build = menu_execute_active_handler('user', FALSE);
return render($build);
Ответ jeroen был тем, что для меня сделало для меня после игры с ним. У меня есть сайт на Drupal 7.
Прежде всего, убедитесь, что вы заменили MY_THEME названием вашей темы. Да, это очевидно, но большинство новичков упускают это из виду.
На самом деле у меня уже был function MY_THEME_preprocess_page(&$variables) {. Тогда не создавайте функцию заново, а добавьте этот код в конец функции, прежде чем закрыть ее с помощью }.
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'page__embed';
}
$vars, а не $variables, поэтому мне пришлось обновить и его. Опять же очевидно, если подумать, поищите.Мой первый ответ позволил мне отобразить узел только тогда, когда я вызвал его в веб-браузере. Однако конечная цель этого - встроить узел drupal на сторонний сайт с помощью iframe.
С момента выпуска Drupal Ядро 7.50 iframe по умолчанию заблокировано, чтобы предотвратить кликджекинг.
Чтобы успешно встроить только узел на сторонний сайт, вам также необходимо переопределить настройку x-frame по умолчанию. Все заработало после того, как я добавил в template.php следующее:
function MY_THEME_page_alter($page) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
header_remove('X-Frame-Options');
}
}
Это сработало бы, если бы я использовал этот сайт только для встраивания в другое место, но мне нужны обычные узлы для отображения с их обычными шаблонами страниц.