Allow Modules and Themes to define component directories

Created on 14 March 2023, over 1 year ago

Problem/Motivation

Around the release of 1.0.0-rc1 support for defining component paths was dropped in support of using Plugins for component file discovery. While this move makes sense, the refactored code expects all component files to live specifically in `templates/components/` directories within modules/themes.

This has raised a number of issues for people using the cl_components module and the cl_server module. (see related issues).

While assuming component templates live in these specific sub-directories is OK for a default, modules and themes should have the ability to dictate where they want to store their component templates.

As a real-world example, the current architecture of my custom theme has a structure of:

my-theme/

  • - components/
    • -my-component/
      • - my-component.component.twig
  • - templates/
    • - nodes/
      • - content-type-that-uses-component.html.twig

This is a specific structure that I'd like to keep using in my theme (and all of my drupal html.twig templates, make references to my component templates based on this structure). It's unwieldily and unreasonable to expect theme/module maintainers to restructure their templates in order to fit a specific pattern for this module. Themes & modules should be able to dictate where their component templates are stored.

Proposed resolution

Adding a call to an alter hook to the `getScanDirectories` method in `ComponentPluginManager.php` would allow modules/themes to alter the array of `$directories` and define where component templates live.

A change along the lines of this:

  /**
   * Get the list of directories to scan.
   *
   * @return string[]
   *   The directories.
   */
  private function getScanDirectories(): array {
    $extension_directories = [
      ...$this->moduleHandler->getModuleDirectories(),
      ...$this->themeHandler->getThemeDirectories(),
    ];

    $directories = array_map(
      static fn(string $path) => rtrim(sprintf(
        '%s%s%s',
        rtrim($path, DIRECTORY_SEPARATOR),
        DIRECTORY_SEPARATOR,
        implode(DIRECTORY_SEPARATOR, ['templates', 'components']),
      ), DIRECTORY_SEPARATOR),
      $extension_directories
    );
    $this->moduleHandler->alter('cl_components_directories', $directories);
    $this->themeManager->alter('cl_components_directories', $directories);
    return $directories;
  }

Would then allow modules/themes to call the following alter hook:

/**
  * Implements hook_cl_components_directories_alter().
  **/
function mytheme_cl_components_directories_alter(&$directories){ 
  if (isset($directories['mytheme'])) {
    // Change component directory to location above templates directory.
    $directories['mytheme'] = str_replace('templates/components', '../components', $directories['mytheme']);
  }
}

Remaining tasks

* Add calls to an alter hook in the `getScanDirectories` method in ``ComponentPluginManager.php`

User interface changes

N/A

API changes

N/A

Data model changes

N/a

✨ Feature request
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States mikemiles86

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024