Drupal 8 as a Static Site: Manually Add Paths

Submitted by nigel on Tuesday 13th November 2018

We established in my earlier blog Drupal 8 as a Static Site: Problems Identified that Tome isn't capable of expanding wildcards such as the taxonomy RSS subscription paths in Views at taxonomy/term/%/feed. This tutorial shows how to manually add paths so when the command drush tome:static is run they are created correctly in the static version of the website. 

Thankfully the Tome modules makes this relatively easy although we will need to develop a custom event subscriber. The subscriber will be looking for a collect paths event which is triggered when the drush tome:static command is run. At that point we can add our missing paths. In our case it will be all the taxonomy term feed paths which the Badzilla website uses. 

So the first thing to do is to create a custom module and an event subscriber within it. 

Create a skeleton custom module
Let's create a custom module
$ cd docroot/modules/custom
$ mkdir badzilla_static
$ cd badzilla_static/
$ touch badzilla_static.info.yml
And populate badzilla_static.info.yml
name: Badzilla Static
description: Custom code for facilitating the generation of a static version of Badzilla
package: Badzilla
type: module
core: 8.x
Now we need the services yml file which will hold the event subscriber namespace and parameter information.
$ touch badzilla_static.services.yml
and let's populate badzilla_static.services.yml
services:
  badzilla.route_path_subscriber:
    class: Drupal\badzilla_static\EventSubscriber\RoutePathSubscriber
    arguments: ['@router.route_provider']
    tags:
      - { name: event_subscriber }
Now we need to create the RouteEventSubscriber so let's create the directory
$ mkdir -p src/EventSubscriber
$ touch src/EventSubscriber/RoutePathSubscriber.php
Event Subscriber
The event subscriber must implement the EventSubscriberInterface. Let's have a look at the code before the commentary.

<?php

namespace Drupal\badzilla_static\EventSubscriber;

use 
Drupal\Core\Routing\RouteProviderInterface;
use 
Drupal\tome\Event\CollectPathsEvent;
use 
Symfony\Component\EventDispatcher\EventSubscriberInterface;
use 
Drupal\tome\Event\TomeEvents;



/**
 * Adds route paths to the list of paths to export.
 */
class RoutePathSubscriber implements EventSubscriberInterface
{

    
/**
     * The route provider.
     *
     * @var \Drupal\Core\Routing\RouteProviderInterface
     */
    
protected $routeProvider;


    
/**
     * Constructs the RoutePathSubscriber object.
     *
     * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
     *   The route provider.
     */
    
public function __construct(RouteProviderInterface $route_provider) {
        
$this->routeProvider $route_provider;
    }


    
/**
     * Reacts to a collect paths event - adds the taxonomy feeds paths
     *
     * @param \Drupal\tome\Event\CollectPathsEvent $event
     *   The collect paths event.
     */
    
public function collectPaths(CollectPathsEvent $event) {
        
$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree('technology');
        if (
is_array($terms) && count($terms)) {
            foreach(
$terms as $term) {
                
$event->addPath(sprintf('/taxonomy/term/%d/feed/feed.rss'$term->tid));
            }
        }
    }


    
/**
     * {@inheritdoc}
     */
    
public static function getSubscribedEvents() {
        
$events[TomeEvents::COLLECT_PATHS][] = ['collectPaths'];
        return 
$events;
    }
}
?>

The code is largely a copy / paste exercise from Tome's own event subscriber but the difference is in the method collectPaths(). My objective is to get the tids from the vocabulary called technology I use on my listing pages. To achieve this I load all the terms of that vocabulary, iterate through them, and inject the tids into the path /taxonomy/term/%/feed/feed.rss. Note how I have added feed.rss to the url? This is so Tome, seeing a file extension will not create the standard index.html file in the feed directory. 

This solution does require a configuration change at the web server level and in the Views. See the chapter Drupal 8 as a Static Site: Add feed.rss to web server config and views

Enabling and running
Now we have the coding complete. we need to enable the module the usual way:
$ drush en badzilla_static -y
 [success] Successfully enabled: badzilla_static
Now when I run the drush tome:static I see:
Generating static HTML...
 260/260 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
as opposed to the lower value of paths before my code:
Generating static HTML...
 227/227 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
Also if I ls the directory with the terms I will now see my entries correctly:
$ ls  ../static/html/taxonomy/term/          
100  102  104  106  109  111  13  20  27  36  47  53  55  78  80  82  84  86  88  9   91  93  95  97  99
101  103  105  107  110  112  18  26  32  44  49  54  57  79  81  83  85  87  89  90  92  94  96  98