Make WordPress Core

Changeset 63507


Ignore:
Timestamp:
09/06/2026 05:16:12 AM (13 hours ago)
Author:
westonruter
Message:

Themes: Set the template property when a theme is its own parent.

When a theme's Template header names the theme's own directory, WP_Theme::__construct() recorded the theme_child_invalid error and returned before assigning $this->template, leaving the property unset. As a result WP_Theme::get_template() returned null despite being documented as returning a string. That error scenario now assigns the stylesheet to $this->template and stores it in the theme cache, matching how the theme_no_stylesheet and theme_no_parent errors are already handled. The invalid-theme error itself is unchanged, and tests cover both the fresh and the cached construction paths.

Developed in https://github.com/WordPress/wordpress-develop/pull/10837.
Follow-up to r41601.

Props marian1, westonruter.
See #40820.
Fixes #64582.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme.php

    r63494 r63507  
    362362
    363363                if ( ! $this->template && $this->stylesheet === $this->headers['Template'] ) {
    364                         $this->errors = new WP_Error(
     364                        $this->errors   = new WP_Error(
    365365                                'theme_child_invalid',
    366366                                sprintf(
     
    370370                                )
    371371                        );
     372                        $this->template = $this->stylesheet;
    372373                        $this->cache_add(
    373374                                'theme',
     
    378379                                        'errors'                 => $this->errors,
    379380                                        'stylesheet'             => $this->stylesheet,
     381                                        'template'               => $this->template,
    380382                                )
    381383                        );
  • trunk/tests/phpunit/tests/theme/wpTheme.php

    r60729 r63507  
    184184        }
    185185
     186        /**
     187         * Tests that a theme declaring itself as its own parent still has a template.
     188         *
     189         * The `theme_child_invalid` error must not leave `WP_Theme::$template` unset, as
     190         * that makes `get_template()` return `null` and makes the template directory and
     191         * its URI resolve to the theme root instead of the theme's own directory.
     192         *
     193         * @ticket 64582
     194         *
     195         * @covers WP_Theme::get_template
     196         * @covers WP_Theme::get_template_directory
     197         * @covers WP_Theme::get_template_directory_uri
     198         */
     199        public function test_child_theme_with_itself_as_parent_should_have_template_set() {
     200                $theme = new WP_Theme( 'child-parent-itself', $this->theme_root );
     201
     202                $this->assertSame( 'child-parent-itself', $theme->get_template(), 'The template was not set to the stylesheet.' );
     203                $this->assertSame(
     204                        $this->theme_root . '/child-parent-itself',
     205                        $theme->get_template_directory(),
     206                        'The template directory did not resolve to the theme directory.'
     207                );
     208                $this->assertSame(
     209                        $theme->get_theme_root_uri() . '/child-parent-itself',
     210                        $theme->get_template_directory_uri(),
     211                        'The template directory URI did not resolve to the theme directory.'
     212                );
     213        }
     214
     215        /**
     216         * Tests that the template of a theme declaring itself as its own parent is cached.
     217         *
     218         * @ticket 64582
     219         *
     220         * @covers WP_Theme::__construct
     221         * @covers WP_Theme::get_template
     222         */
     223        public function test_child_theme_with_itself_as_parent_should_have_template_set_when_read_from_cache() {
     224                // Prime the theme cache.
     225                new WP_Theme( 'child-parent-itself', $this->theme_root );
     226
     227                $theme = new WP_Theme( 'child-parent-itself', $this->theme_root );
     228
     229                $errors = $theme->errors();
     230                $this->assertInstanceOf( WP_Error::class, $errors, 'The theme was not read back from the cache in an error state.' );
     231                $this->assertSame( 'theme_child_invalid', $errors->get_error_code(), 'The theme was not read back from the cache with the expected error.' );
     232                $this->assertSame( 'child-parent-itself', $theme->get_template(), 'The template was not restored from the cache.' );
     233        }
    186234
    187235        /**
Note: See TracChangeset for help on using the changeset viewer.