отображение представления Drupal без шаблона страницы вокруг него

StackOverflow https://stackoverflow.com/questions/247991

  •  05-07-2019
  •  | 
  •  

Вопрос

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

Это представление будет включено в другой сайт, не принадлежащий Drupal.

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

Это было полезно?

Решение

Я искал способ извлечения данных узла через 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; ?>

Другие советы

Основываясь на ответе 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> с содержимым страницы, чтобы его можно было вставить на другую страницу.

Я знаю, что на этот вопрос уже был дан ответ, но я хотел добавить свое собственное решение, которое использует элементы ответа Philadelphia Web Design (PWD) и использует hook_theme_registry_alter, как предложено Оуэном. Используя это решение, вы можете загрузить шаблон непосредственно из пользовательского модуля.

Сначала я добавил raw.tpl.php во вновь созданную папку 'templates' внутри моего модуля. Содержимое 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 / узел / 1105922 # комментарий-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-пути представления, он будет использовать указанный шаблон внутри моего модуля.

Для других, кто может зайти на эту страницу, если вы просто работаете со стандартными обратными вызовами (не обязательно представлениями), это легко.В вашей функции обратного вызова вместо возврата кода для рендеринга на странице используйте функцию «печать».

Например:

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.
}

Ваше здоровье!

Другой способ сделать это, который я считаю очень удобным, — добавить пункт меню с функцией обратного вызова страницы, которая не возвращает строку:

Пример:

/**
 * 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; (см. комментарий).

Эй, вот еще один способ сделать это:

1) Загрузите и установите бонусный пакет Views ( http://drupal.org/project/views_bonus) 2) Создайте отображение просмотров & Quot; Feed & Quot; и используйте стиль " XML " (или что-то, что вы думаете, соответствует вашим потребностям лучше). 3) Если вас не устраивает стандартный вывод XML, вы можете изменить его, настроив шаблон для представления. Проверьте & Quot; theme & Quot; настройки для получения предложений по альтернативным именам шаблонов для этого конкретного представления (так что у вас все еще останется вывод XML по умолчанию, оставленный для будущего использования).

Удачи! // Йохан Фальк, NodeOne, Швеция

На основании ответа веб-дизайна из Филадельфии (спасибо) и некоторого поиска в Google ( 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 и темы. Не уверен, как вывести полностью не обработанные данные ...

Предполагая, что вы находитесь в Drupal 6, самый простой способ сделать это - вставить вызов phptemplate_views_view_unformatted_VIEWNAME в template.php (предполагается, что ваше представление не отформатировано - если это что-то другое, скажем, список, используйте соответствующую функцию темы ). В этом случае представление темы приводит к вызову этой темы, а не возвращает результаты, как обычно, распечатывает их и возвращает NULL. Это выведет HTML напрямую.

PS - обязательно очистите кэш (в / admin / settings / performance), чтобы увидеть эту работу.

Вероятно, есть несколько способов обойти это, однако «самым простым» может быть просто установка собственной пользовательской темы и просто пустое 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, вместо того, чтобы переименовывать его полностью)
  • похоже, для этого конкретного представления не существует никаких идентификаторов, поэтому этот метод может представлять собой подход «все представления будут удалены».если вам нужно удалить page.tpl.php только для определенного представления, возможно, подключившись к template_preprocess_page() может быть, это лучшая идея.

Мне нравится модуль Drupal. Но вот другой способ.

скопируйте page.tpl.php в папке вашей темы в новый файл с именем page-VIEWNAME.tpl.php, где VIEWNAME - это машиночитаемое имя представления.

Затем отредактируйте страницу-VIEWNAME.tpl.php, чтобы она подходила.

Существует также http://drupal.org/project/pagearray , которое является общим решением. ...

Кроме того, решение @Scott Evernden - это дыра в безопасности межсайтовых сценариев (XSS). Не делай этого. Прочитайте документацию на drupal.org о том, как обрабатывать текст безопасным способом http://drupal.org/node/ 28984

Простой способ отображения контента специального типа, который вы хотите отобразить, без всего 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 к своей теме, например print $content, но без того, что вы не хотите отображать, и с <=> в теле.

Если я понимаю ваш вопрос, вы хотите иметь узлы, которые содержат весь HTML-код страницы, от DOCTYPE до < / HTML > ;. Я хотел бы создать тип контента для этих узлов - & Quot; fullhtml & Quot; как его машиночитаемое имя - и затем создайте для него шаблон узла с именем node-fullhtml.tpl.php. Вы не можете просто сбросить содержимое узла, так как они были продезинфицированы HTML. node.fullhtml.tpl.php будет буквально таким:

echo htmlspecialchars_decode($content);

Тогда вам понадобится способ переопределить стандартный page.tpl.php. Я думаю , что вы могли бы сделать, это в верхней части вашего page.tpl.php проверить тип содержимого $ node и выручить, если он fullhtml. Или установите глобальную переменную в node-fullhtml.tpl.php, которую будет проверять page.tpl.php.

Я не эксперт по Drupal, но я так и сделаю. Я говорю с манжетой, так что следите за дьяволами в деталях.

Я вижу, что вы уже ушли и сделали себя модулем, так что это может больше не помогать, но довольно просто получить представление об RSS-канале, который может быть более простым способом получить доступ к контенту, особенно если вы хотите включить его на другом сайте.

В D7 вы можете использовать menu_execute_active_handler

$build = menu_execute_active_handler('user', FALSE);
return render($build);

Джероен ответил, что сделал для меня после игры с ним. У меня есть сайт 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';
    }
    
    1. Моя функция использовалась $vars, а не $variables, поэтому мне пришлось обновить и ее. Снова очевидно, если вы думаете, ищите это.

    Мой первый ответ позволил мне отображать узел только тогда, когда я вызывал его в веб-браузере. Однако конечной целью этого является встраивание друпального узла в сторонний сайт с использованием iframe.

    С момента выпуска Drupal Core 7.50 iframe по умолчанию заблокирован для предотвращения Clickjacking

    Чтобы успешно внедрить только сторонний сайт в сторонний сайт, вам также необходимо изменить настройку по умолчанию для x-frame. Все начало работать после того, как я добавил следующее в template.php

    function MY_THEME_page_alter($page) {
    
     if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
       header_remove('X-Frame-Options');
     } 
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top