0

I'm trying to use the Background Image module, but there seems to be a problem with the dynamic route it registers for generating CSS. I've been debugging it, but I have run into a wall. It's basically a duplicate of the core Image module's routing setup, so I'm not sure what's wrong, but the controller method never fires; the controller isn't even instantiated. Here's the config file:

route_callbacks:
  - '\Drupal\background_image\Routing\BackgroundImageRoutes::routes'

Here's the routes method:

  public function routes() {
    error_log('Router::routes');
    $routes = [];
    // Generate background image CSS files. If clean URLs are disabled the
    // files will always be served through the menu system. If clean URLs are
    // enabled and the file already exists, PHP will be bypassed.
    $directory_path = $this->streamWrapperManager->getViaScheme('public')->getDirectoryPath();

    $routes['background_image.css'] = new Route(
      '/' . $directory_path . '/background_image/css/{background_image}/{scheme}/{file}',
      [
        '_controller' => '\Drupal\background_image\Controller\BackgroundImageCssController::deliver',
      ],
      [
        '_access' => 'TRUE',
      ]
    );
    error_log(print_r($routes, true));
    return $routes;
  }

Here's the $routes object:

Array
(
    [background_image.css] => Symfony\Component\Routing\Route Object
        (
            [path:Symfony\Component\Routing\Route:private] => /sites/default/files/background_image/css/{background_image}/{scheme}/{file}
            [host:Symfony\Component\Routing\Route:private] => 
            [schemes:Symfony\Component\Routing\Route:private] => Array
                (
                )
            [methods:Symfony\Component\Routing\Route:private] => Array
                (
                )
            [defaults:Symfony\Component\Routing\Route:private] => Array
                (
                    [_controller] => \Drupal\background_image\Controller\BackgroundImageCssController::deliver
                )
            [requirements:Symfony\Component\Routing\Route:private] => Array
                (
                    [_access] => TRUE
                )
            [options:Symfony\Component\Routing\Route:private] => Array
                (
                    [compiler_class] => Symfony\Component\Routing\RouteCompiler
                )
            [compiled:Symfony\Component\Routing\Route:private] => 
            [condition:Symfony\Component\Routing\Route:private] => 
        )
)

If I try to hit a URL such as /sites/default/files/background_image/css/3/public/dq5DbF1hqHxkHXGiHSl9yuXubPox08bOX6nE12gX2h0.css?p2aptq (which the module correctly generates when I've got a background image set up on the site) I get a 404 error and nothing in the error log.

I'm using docker4drupal and have checked the nginx config and am 99% sure that's not the issue (there are no rules for /sites/default/files/ and I do see the 404 in the nginx log.)

Why doesn't the dynamic route work as it should, and as it doesn't for the Image module?

  • 1
    Welcome to Drupal Answers! I am not sure I understand what you mean by implementing the Background Image module: That module already has a Drupal 8 version. Do you mean you are trying to use the module in a site? – kiamlaluno Jan 9 '18 at 17:29
  • 1
    Yes, I'm just trying to get the module working and this routing issue appears to be the culprit. Sorry if that wasn't clear. The question is about Drupal's routing system (I didn't want to post a module-specific question here.) – ken.dunnington Jan 9 '18 at 21:03
0

Well, I'm an idiot. The problem was nginx after all. There actually was a block to handle CSS/JS assets that was preventing the dynamic route from executing because of a lack of physical files. I had to place the following above that rule:

location ~ ^/sites/.*/files/background_image/ {
    try_files $uri @drupal;
}

Here's the offending rule:

location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|xml|otf|ttf|eot|woff|woff2|svg|svgz)$ {
    expires 30d;
    tcp_nodelay off;
    open_file_cache off;
    open_file_cache_valid 45s;
    open_file_cache_min_uses 2;
    open_file_cache_errors off;

    location ~* ^.+\.svgz$ {
        gzip off;
        add_header Content-Encoding gzip;
    }
}

I found the solution after searching for relevant issues on other modules that generate dynamic files, such as imagecache, which led me to the official nginx Drupal guide. Definitely a learning exercise.

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.