Skip to content

Instantly share code, notes, and snippets.

@sonnykt
Last active May 21, 2021 02:51
Show Gist options
  • Save sonnykt/aaaff8f620c717194446547739ac77b9 to your computer and use it in GitHub Desktop.
Save sonnykt/aaaff8f620c717194446547739ac77b9 to your computer and use it in GitHub Desktop.
Drupal 8 - module vs theme

Alter hooks

In 7.x, themes were allowed to participate in any alter hook because the code that invoked theme alters lived in drupal_alter(). In 8.x, there has been a clear and distinct separation between ModuleHandler::alter and ThemeManager::alter. So now, in 8.x, themes can only participate in an alter hook if it is explicitly invoked for themes as well. An example of this can be seen in ElementInfoManager::buildInfo:

$this->moduleHandler->alter('element_info', $info);
$this->themeManager->alter('element_info', $info);

As far as a "list" of what alter hooks themes are allowed to participate in... I really don't know of any. This base theme implements the majority/common alters hooks found in themes and you can see what it implements in bootstrap.theme. The only other suggestion I would have towards this subject is to see what code implements the module alter and see if there's a theme alter along with it.

Services/container

This is a no go. Themes are not allowed to participate in services, primarily due to the fact that themes are not stored in container or allowed to have dependency injected classes. This is partially why I created the "Plugin System" (@Bootstrap... plugins) in this base theme. It allows to garner some of this type of "functionality". You can read more about a lot of this topic in the related issues.

Controllers/Plugins

Similar to above, these are module implementations and cannot be stored in a theme. These are similar to module_invoke_all() for a particular "hook" in 7.x. In 8.x, they've just been converted to "plugins" for annotated discovery.

Module dependency

You already listed this one, but it's worth noting that a lot of the "limitations" in themes could be greatly mitigated by simply allowing this. Granted that issue has brought up some concerns whether or not this should be allowed, but in general I think there is a lot of support for it.

Namespacing/Autoloading

Generally this works just fine for themes since anything in {system} will automatically add the namespaces to the autoloader. That being said there is a small caveat, generally when dealing with cross-request/ajax theme class based callbacks, that prevent the namespaces from being registered in themes when logic is being processed too early in a low level bootstrapped request. This is why I added the Bootstrap::autoloadFixInclude helper method so autoload-fix.php can be included as a "file" for certain callbacks where it's necessary.

References: https://www.drupal.org/project/bootstrap/issues/2770001#comment-11423341

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment