Drupal - How to output from custom module without rest of theme
The controller does not have to return a render array, it can also provide a symphony response, for example:
use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setContent('<h1>Hello world</h1>');
//$response->headers->set('Content-Type', 'text/xml');
return $response;
This will bypass the Drupal rendering and theming.
Edit:
You can use two approaches to replace your Drupal 7 code:
1) Override page.html.twig
and html.html.twig
, remove anything out of this templates and put only that in what you want.
2) Render the HTML like you are doing it now in Drupal 7 and use a Symfony response.
Rendering in Drupal 8:
use Symfony\Component\HttpFoundation\Response;
$output = \Drupal::service('renderer')->renderRoot($build);
$response = new Response();
$response->setContent($output);
return $response;
If you utilize the html_response.attachments_processor and renderer services along with BareHtmlPageRenderer
you can still get libraries to load in the head tag of an otherwise un-templated page.
use Drupal\Core\Render\BareHtmlPageRenderer;
$attachments = \Drupal::service('html_response.attachments_processor');
$renderer = \Drupal::service('renderer');
$bareHtmlPageRenderer = new BareHtmlPageRenderer($renderer, $attachments);
$response = $bareHtmlPageRenderer->renderBarePage($build, 'Page Title', 'markup');
return $response;
I do not have enough reputation to add a comment on a reply, but the anwser by @Arosboro is almost complete, except the "build variable is in the wrong spot. It must be the last variable, like so:
return $bareHtmlPageRenderer->renderBarePage([], 'Address', 'checkout_address', $build);
This way the twig variables I placed in $build were rendered correctly.
My full code:
$build = [
'#theme' => 'checkout_address',
'#content' => [],
'#edit' => FALSE,
];
...
$attachments = \Drupal::service('html_response.attachments_processor');
$bareHtmlPageRenderer = new BareHtmlPageRenderer($this->renderer, $attachments);
return $bareHtmlPageRenderer->renderBarePage([], 'Address', 'checkout_address', $build);
And the template:
{{ content }}
{% if edit == true %}
<button class="btn-edit-address">Edit Address</button>
{% endif %}
This is how I got it to work.