Problem/Motivation

In code there is support for themes without a theme engine. I.e where the engine is defined like

engine: false

or

engine: ''

in the theme's .info.yml.

This support is done in \Drupal\Core\Theme\ThemeInitialization::loadActiveTheme()

 public function loadActiveTheme(ActiveTheme $active_theme) {
    // Initialize the theme.
    if ($theme_engine = $active_theme->getEngine()) {
      // Include the engine.
      include_once $this->root . '/' . $active_theme->getOwner();

      if (function_exists($theme_engine . '_init')) {
        foreach ($active_theme->getBaseThemes() as $base) {
          call_user_func($theme_engine . '_init', $base->getExtension());
        }
        call_user_func($theme_engine . '_init', $active_theme->getExtension());
      }
    }
    else {
      // include non-engine theme files
      foreach ($active_theme->getBaseThemes() as $base) {
        // Include the theme file or the engine.
        if ($base->getOwner()) {
          include_once $this->root . '/' . $base->getOwner();
        }
      }
      // and our theme gets one too.
      if ($active_theme->getOwner()) {
        include_once $this->root . '/' . $active_theme->getOwner();
      }
    }

    // Always include Twig as the default theme engine.
    include_once $this->root . '/core/themes/engines/twig/twig.engine';
  }

It is completely untested and if you omit the engine key in theme.info.yml file we merge in the default of 'twig' in \Drupal\Core\Extension\ThemeExtensionList

Proposed resolution

Remove the supposed support of such themes.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

alexpott created an issue. See original summary.

alexpott’s picture

StatusFileSize
new93.1 KB

I've created a theme with an info file like so:

name: Zero
type: theme
description: 'An intentionally plain theme with no base theme or theme engine.'
package: Core
version: VERSION
core: 8.x
base theme: false
engine: ''

I also did engine: false

The result in the UI was this:

However via drush...

sudo -u _www drush then zero                                              409ms  Thu 13 Dec 09:30:04 2018
 [success] Successfully enabled theme: zero

hmmm...

alexpott’s picture

So even if you use Drush to install such a theme and then use drush to set it as the default theme... then there is no engine but there also cannot be an owner because owner is set liek this:

     // Defaults to 'twig' (see self::defaults above).
      $engine = $theme->info['engine'];
      if (isset($engines[$engine])) {
        $theme->owner = $engines[$engine]->getExtensionPathname();
        $theme->prefix = $engines[$engine]->getName();
      }

And without an owner nothing is going to happen here:

      // include non-engine theme files
      foreach ($active_theme->getBaseThemes() as $base) {
        // Include the theme file or the engine.
        if ($base->getOwner()) {
          include_once $this->root . '/' . $base->getOwner();
        }
      }
      // and our theme gets one too.
      if ($active_theme->getOwner()) {
        include_once $this->root . '/' . $active_theme->getOwner();
      }

So for me this is truly dead code.

alexpott’s picture

Status: Active » Needs review
Issue tags: +Needs tests, +Needs change record
StatusFileSize
new7.82 KB

In system controller we do

        // Confirm that the theme engine is available.
        $theme->incompatible_engine = isset($theme->info['engine']) && !isset($theme->owner);

We just don't support a theme without an engine and thereby an owner.

We could add

    // Ensure we have an engine. Setting engine to FALSE or an empty string is
    // not supported.
    if (empty($info['engine'])) {
      trigger_error("Theme's with no engine are not supported");
      $info['engine'] = 'twig';
    }

to \Drupal\Core\Extension\ThemeExtensionList::createExtensionInfo() to catch the case where someone has hacked a theme with no engine to be installed. But doing that will prevent the "This theme requires the theme engine to operate correctly" message in the UI. So I'm not really a fan of that... so what I've done is to add this only if the theme is installed.

Status: Needs review » Needs work

The last submitted patch, 4: 3020248-4.patch, failed testing. View results

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new1.13 KB
new8.69 KB

Nice - of course we do have a place where we have a theme without an engine! kernel tests with no theme... so that falls back to

    // If no theme could be negotiated, or if the negotiated theme is not within
    // the list of installed themes, fall back to the default theme output of
    // core and modules (like Stark, but without a theme extension at all). This
    // is possible, because loadActiveTheme() always loads the Twig theme
    // engine. This is desired, because missing or malformed theme configuration
    // should not leave the application in a broken state. By falling back to
    // default output, the user is able to reconfigure the theme through the UI.
    // Lastly, tests are expected to operate with no theme by default, so as to
    // only assert the original theme output of modules (unless a test manually
    // installs a specific theme).
    if (empty($themes) || !$theme_name || !isset($themes[$theme_name])) {
      $theme_name = 'core';
      // /core/core.info.yml does not actually exist, but is required because
      // Extension expects a pathname.
      $active_theme = $this->getActiveTheme(new Extension($this->root, 'theme', 'core/core.info.yml'));

      // Early-return and do not set state, because the initialized $theme_name
      // differs from the original $theme_name.
      return $active_theme;
    }

We can set up the engine here.

alexpott’s picture

Issue tags: -Needs change record

Discussed with @catch in slack. We agreed that having a CR here is noise as it is very unlikely someone is running a site with a theme without a theme engine. We also agreed to trigger a real warning in ThemeExtensionList to tell sites that they are in this state. For theme the fix is to make engine: twig in their template.

Status: Needs review » Needs work

The last submitted patch, 6: 3020248-6.patch, failed testing. View results

lauriii’s picture

I'm not sure why we are assuming that this is potential support? Because of the lack of test coverage? I cannot figure out any reason for using this so I don't believe it would be common to use this feature. However, it has been added intentionally on this issue: #137211: Move discovery of theme information to .info files (and improve theme inheritance). Therefore I agree on deprecating it since there could be themes using this feature.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new1.79 KB
new9.5 KB

Now with an engine the core theme messes up the registry so we need to special case that.

Status: Needs review » Needs work

The last submitted patch, 10: 3020248-10.patch, failed testing. View results

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new923 bytes
new9.25 KB

Looks like I went one step too far...

alexpott’s picture

StatusFileSize
new938 bytes
new10.17 KB

Final fix I think. Something very very interesting going on in low level layout stuff in Kernel tests.

alexpott’s picture

StatusFileSize
new9.25 KB

Oh weird... HEAD \Drupal\Tests\layout_discovery\Kernel\LayoutTest does not pass for me. So the patch in #12 will be green. Re-uploading that one.

The last submitted patch, 13: 3020248-13.patch, failed testing. View results

alexpott’s picture

borisson_’s picture

+++ b/core/lib/Drupal/Core/Extension/ThemeExtensionList.php
@@ -120,8 +120,16 @@ protected function doList() {
+        @trigger_error('@todo', E_USER_DEPRECATED);

Since we're not adding a CR, are we linking to this issue in the trigger_error?

alexpott’s picture

@borisson_ I discussed this with @catch and we agreed to trigger a non silenced E_USER_WARNING here. Just haven't updated the patch yet.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new146 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.