We provide our content via APIs. At times we use the Views Restful approach, and at times the JSONAPI.
We need to add an API field on nodes that is a full HTML rendering of that node's page according to the theme (technically I just need ... but I'll take the whole doc if I can get it).
I have tried a number of approaches:
I tried using the renderer service. It renders full html from the html.html.twig template but items such as blocks on the page are missing. I guess it doesn't have all the context it needs.
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$content = $view_builder->view($node);
$build = [
'#type' => 'html',
'page' => [
'#type' => 'page',
'#theme' => 'page',
'#title' => $node->get("title")->value,
'content' => $content,
],
];
$page = \Drupal::service('renderer')->renderPlain($build);
Very similarly I tried using twig_render_template. It similarly renders full html but items such as blocks on the page are missing.
$markup = twig_render_template(drupal_get_path('theme', 'neato') . '/templates/base/html.html.twig', array(
'page' => [
'#type' => 'page',
'#theme' => 'page',
'#title' => $node->get("title")->value,
'content' => $content,
],
// Needed to prevent notices when Twig debugging is enabled.
'theme_hook_original' => 'not-applicable',
));
$body = (string) $markup;
As a separate approach, I tried to make a 'subrequest'. With this approach, I get the rendered HTML but it causes fatal early rendering errors such as "A stray renderRoot() invocation is causing bubbling of attached assets to break."
$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();
I even tried to mimic the full drupal 'bootstrap'
$autoloader = require '/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();
I am open to any and all pointers and suggestions. I really appreciate it.