Рейтинг:2

Я открыт для любых указаний и предложений. Я очень ценю это.

флаг cn

Как я могу загрузить шаблон из пользовательского модуля на определенной странице?

Мы предоставляем наш контент через API. Иногда мы используем подход Views Restful, а иногда — JSONAPI.

Нам нужно добавить поле API на узлах, которое представляет собой полный HTML-рендеринг страницы этого узла в соответствии с темой (технически мне просто нужно... но я возьму весь документ, если смогу его получить).

Я пробовал несколько подходов:

Я попытался использовать службу рендеринга. Он отображает полный HTML-код из шаблона html.html.twig, но такие элементы, как блоки на странице, отсутствуют. Я предполагаю, что у него нет всего контекста, в котором он нуждается.
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$content = $view_builder->представление($node);
$ построить = [
  '#тип' => 'html',
  'страница' => [
    '#тип' => 'страница',
    '#theme' => 'страница',
    '#title' => $node->get("title")->значение,
    'контент' => $контент,
  ],
];
$page = \Drupal::service('рендерер')->renderPlain($build);

Точно так же я пытался использовать twig_render_template. Точно так же он отображает полный html, но такие элементы, как блоки на странице, отсутствуют.
$markup = twig_render_template(drupal_get_path('theme', 'neato'). '/templates/base/html.html.twig', array(
  'страница' => [
    '#тип' => 'страница',
    '#theme' => 'страница',
    '#title' => $node->get("title")->значение,
    'контент' => $контент,
  ],
  // Необходимо для предотвращения уведомлений, когда включена отладка Twig.
  'theme_hook_original' => 'не применимо',
));
$body = (строка) $разметка;

В качестве отдельного подхода я попытался сделать «подзапрос». При таком подходе я получаю визуализированный HTML-код, но это вызывает фатальные ошибки раннего рендеринга, такие как «Блуждающий вызов renderRoot() приводит к разрыву всплытия прикрепленных ресурсов».
$kernel = \Drupal::service('http_kernel.basic');
$sub_request = \Symfony\Component\HttpFoundation\Request::create("/node/".$value->_entity->id(), 'GET');
$subResponse = $kernel->handle($sub_request, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
$html = $subResponse->getContent();

Я даже пытался имитировать полную загрузку Drupal.
$autoloader = требуется '/app/web/autoload.php';
$sub_request = Request::create("/node/".$node->id(), 'GET');
$site_path = DrupalKernel::findSitePath($sub_request);
$kernel = DrupalKernel::createFromRequest($sub_request, $autoloader, 'prod');
$sub_response = $kernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST);
$html = $sub_response->getContent();

john Smith avatar
флаг gr
так же, как, вероятно, «не очень эффективный» и не-друпаловый способ, используйте file_get_contents в URL-адресе страницы...
john Smith avatar
флаг gr
PS: я только что наткнулся на `\Drupal::service('renderer')->renderRoot(` в каком-то моем коде, возможно, это поможет вместо этого использовать `renderPlain`
4uk4 avatar
флаг cn
Обычно вам вообще не нужно визуализировать переменные. Но если вам нужно, используйте `\Drupal::service('renderer')->render()`. Два приведенных выше метода предназначены только для конкретных случаев использования, а не для обычного рендеринга страниц.
флаг cn
Согласовано. Это не то, как обычно отображаются страницы. Это крайний случай для моей спецификации. Я пробовал \Drupal::service('renderer')->renderRoot и render() разными способами. У него никогда не было всего контекста. Я получил HTML-скелет страницы, но блоки и тому подобное все еще отсутствовали. Я обнаружил, что вам придется имитировать полный запрос Drupal, который является сложным, и начал чувствовать себя как худшее направление. Мы пошли по тому же пути, что и запись @johnSmith, используя file_get_contents(). Когда узлы сохранены, мы используем httpClient, чтобы сделать второй запрос к сайту.Этот ответ сохраняется в поле и включается в API. Спасибо!!
Рейтинг:1
флаг cn

Мы пошли по тому же пути, что и запись @johnSmith, используя file_get_contents(). Спасибо!

TL;ДР; Когда узлы сохранены, мы используем httpClient, чтобы сделать второй запрос к сайту. Этот ответ сохраняется в поле и включается в API. Спасибо!!

Подробности

  • К связанным типам контента было добавлено новое поле. Это поле будет использоваться для хранения отображаемого HTML-кода страницы.

  • Был написан специальный модуль. Когда узлы связанных типов контента создаются или обновляются, последующий запрос выполняется с использованием httpClient. Этот запрос делается на странице узла. Этот HTML-ответ сохраняется в новом поле.

    // Мы сохранили настроенное доменное имя, в котором будет выполняться этот запрос на рендеринг, в конфигурации Drupal.

    $config = \Drupal::service('config.factory')->getEditable('myApi.static_server_settings');

    $domain = $config->get('myApi.theme_domain');

    // Запросить отображаемую страницу этого узла

    $nid = $node->id();

    $client = \Drupal::httpClient();

    $request = $client->get($domain.'/node/'.$nid);

    $render = (строка) $request->getBody();

  • Наш API был расширен, чтобы включить это поле.В качестве запасного варианта при запуске API, если новое поле пусто, тот же самый последующий запрос httpClient выполняется на лету.

  • Мы создали пакетный процесс, который обновляет поле «отображаемая страница» для всего контента. Это можно запустить, если тема обновлена. В конечном итоге мы можем запустить его из наших скриптов для создания тем / gulp / CI.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.