I am looking at converting a module I wrote and integrating it straight into my theme so as to reduce dependencies.

At first when I wrote the module as I was under the impression that a theme was not able to use hooks such as hook_page_attachments and hook_libraries_info_alter etc. It doesn't seem that bootstrap has this problem as I am fully able to leverage those hooks.

So this got to me wondering what are the chief limitations of a Bootstrap theme as compared to a module?

I know that themes can't currently depend on modules which is being tracked here:

#474684: Allow themes to declare dependencies on modules

Just was curious as wanted to start my module port and wasn't sure if I would hit any roadblocks.

I am mostly porting some custom blocks, controllers, ckeditor plugin and a few services. The one concern I do have is I have a relatively complicated settings form coupled with a pretty big schema.yml file.

Comments

sylus created an issue. See original summary.

markhalliwell’s picture

Title: Bootstrap theme and limitations related to module functionality. » Document differences between themes and modules and their limitations
Component: Code » Documentation
Category: Support request » Task
Related issues: +#1886448: Rewrite the theme registry into a proper service, +#2002606: Allow themes to provide services.yml, +#474684: Allow themes to declare dependencies on modules, +#2070581: Themes should not register namespaces, +#2763861: Provide include to fix autoloading on cross-request class based callbacks

Actually there's quite a bit that themes cannot do, especially now in 8.x:

  • 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.

Generally speaking, you'll be hard pressed to port everything to a theme. That is why they are a different extension type and why I created the Is Drupal Bootstrap a module or a theme? question of the FAQ section.

I was going to close this issue as "works as designed", but instead changing this to a documentation issue. This topic is one that really confuses people any why people constantly refer to this project as a "module" (one of my biggest pet peeves).

Perhaps we should also keep a running list of what alters are available as well?; in the @BootstrapAlter plugin docs maybe?

sylus’s picture

Thank you so much for the through response! It definitely answered all of my questions and particularly described the intricacies / limitations with an explanation of why which I found helpful. This will save me a ton of work doing a re-write that just wouldn't have likely worked in any form.

I think this would be great information to spell out but am not sure where the correct place would be to document this. I was thinking perhaps the FAQ section, however due to verbosity maybe it would make sense to have a new page entirely? Will happily assist but for now can at least point people to this issue.

As for having a running list of the alters, I am definitely in favor of that.

markhalliwell’s picture

markhalliwell’s picture

Assigned: Unassigned » sylus

@sylus, any chance you could perhaps work on updating the documentation for this?

shelane’s picture

Status: Active » Postponed