3

I have a controller that generates a custom 500 page. I have set up a route at the path: '/500'. I would like to capture this as HTML and save as a static file, so that I don't need to bootstrap Drupal and run that controller when I return a custom 500 page.

I have been using this code:

  global $base_url;

  $contents = file_get_contents($base_url . "/500");

This works for me locally, but we have a lot of restrictions on our QA site so that file_get_contents is blocked.

Is there another way to render the entire page that this controller would return? For example, with the render service?

Also, I would want it in a logged-out context. I wouldn't want the admin toolbars, etc. to show up.

I found some code about subroutines. Is that a good way? I'm sure there's a way to use the Drupal render service to render a render array with the entire page. That sounds maybe the best way to do this?

Does anyone know how I might render the entire page programmatically?

I'm thinking in order to render the metadata and page classes based on a route, you're pretty much required to make a request.

There is another question about rendering parts of the page, but not the entire page.

  • By the way, I fixed the problem for myself by updating my vhost settings on the QA server to allow access from the same IP address. Perhaps file_get_contents is the easiest way to do this. – oknate Oct 31 '17 at 16:42
  • Does the page change very often? Otherwise, I would just save it once and commit the static HTML file to the repository. – Christoph Burschka Nov 18 '17 at 10:32
  • Could you specify this file in Apache and point it to your static file for 500s? – Kevin Nov 18 '17 at 15:33
0

If you bootstrap Drupal, you can just tell it to serve a particular page. Consider the content of index.php:

<?php
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;
$autoloader = require_once 'autoload.php';

$kernel = new DrupalKernel('prod', $autoloader);

$request = Request::createFromGlobals();
$response = $kernel->handle($request);

If you replace the Request::createFromGlobals with a new Request(...), you can pass explicit values for the $_GET etc parameters. The function signature copied from Symfony is as follows:

/**
 * Constructor.
 *
 * @param array           $query      The GET parameters
 * @param array           $request    The POST parameters
 * @param array           $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
 * @param array           $cookies    The COOKIE parameters
 * @param array           $files      The FILES parameters
 * @param array           $server     The SERVER parameters
 * @param string|resource $content    The raw body data
 */
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
    $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
}

So your custom script could require the autoloader, bootstrap Drupal, create a fake Request object, tell Drupal to handle it, then save $response->getContent() to a file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.