WordPress.org

Make WordPress Core

Changeset 12025


Ignore:
Timestamp:
10/13/2009 07:06:35 PM (10 years ago)
Author:
markjaquith
Message:

Introducing register_theme_directory() which takes a wp-content-relative path and will additionally scan it for themes. Plugins can use this to add themes without requiring copying by the user. props apeatling. fixes #10467

Location:
trunk
Files:
3 edited

Legend:

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

    r11168 r12025  
    2929    $ct->author = $themes[$current_theme]['Author'];
    3030    $ct->tags = $themes[$current_theme]['Tags'];
     31    $ct->theme_root = $themes[$current_theme]['Theme Root'];
     32    $ct->theme_root_uri = $themes[$current_theme]['Theme Root URI'];
    3133    return $ct;
    3234}
  • trunk/wp-admin/themes.php

    r11761 r12025  
    133133<div id="current-theme">
    134134<?php if ( $ct->screenshot ) : ?>
    135 <img src="<?php echo content_url($ct->stylesheet_dir . '/' . $ct->screenshot); ?>" alt="<?php _e('Current theme preview'); ?>" />
     135<img src="<?php echo $ct->theme_root_uri . '/' . $ct->stylesheet . '/' . $ct->screenshot; ?>" alt="<?php _e('Current theme preview'); ?>" />
    136136<?php endif; ?>
    137137<h4><?php
     
    140140<p class="theme-description"><?php echo $ct->description; ?></p>
    141141<?php if ($ct->parent_theme) { ?>
    142     <p><?php printf(__('The template files are located in <code>%2$s</code>.  The stylesheet files are located in <code>%3$s</code>.  <strong>%4$s</strong> uses templates from <strong>%5$s</strong>.  Changes made to the templates will affect both themes.'), $ct->title, $ct->template_dir, $ct->stylesheet_dir, $ct->title, $ct->parent_theme); ?></p>
     142    <p><?php printf(__('The template files are located in <code>%2$s</code>.  The stylesheet files are located in <code>%3$s</code>.  <strong>%4$s</strong> uses templates from <strong>%5$s</strong>.  Changes made to the templates will affect both themes.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ), $ct->title, $ct->parent_theme); ?></p>
    143143<?php } else { ?>
    144     <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $ct->title, $ct->template_dir, $ct->stylesheet_dir); ?></p>
     144    <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $ct->title, str_replace( WP_CONTENT_DIR, '', $ct->template_dir ), str_replace( WP_CONTENT_DIR, '', $ct->stylesheet_dir ) ); ?></p>
    145145<?php } ?>
    146146<?php if ( $ct->tags ) : ?>
     
    204204    $template_dir = $themes[$theme_name]['Template Dir'];
    205205    $parent_theme = $themes[$theme_name]['Parent Theme'];
     206    $theme_root = $themes[$theme_name]['Theme Root'];
     207    $theme_root_uri = $themes[$theme_name]['Theme Root URI'];
    206208    $preview_link = esc_url(get_option('home') . '/');
    207209    if ( is_ssl() )
     
    224226        <a href="<?php echo $preview_link; ?>" class="<?php echo $thickbox_class; ?> screenshot">
    225227<?php if ( $screenshot ) : ?>
    226             <img src="<?php echo content_url($stylesheet_dir . '/' . $screenshot); ?>" alt="" />
     228            <img src="<?php echo $theme_root_uri . '/' . $stylesheet . '/' . $screenshot; ?>" alt="" />
    227229<?php endif; ?>
    228230        </a>
     
    234236    <?php if ($parent_theme) {
    235237    /* translators: 1: theme title, 2:  template dir, 3: stylesheet_dir, 4: theme title, 5: parent_theme */ ?>
    236     <p><?php printf(__('The template files are located in <code>%2$s</code>.  The stylesheet files are located in <code>%3$s</code>.  <strong>%4$s</strong> uses templates from <strong>%5$s</strong>.  Changes made to the templates will affect both themes.'), $title, $template_dir, $stylesheet_dir, $title, $parent_theme); ?></p>
     238    <p><?php printf(__('The template files are located in <code>%2$s</code>.  The stylesheet files are located in <code>%3$s</code>.  <strong>%4$s</strong> uses templates from <strong>%5$s</strong>.  Changes made to the templates will affect both themes.'), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ), $title, $parent_theme); ?></p>
    237239<?php } else { ?>
    238     <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $title, $template_dir, $stylesheet_dir); ?></p>
     240    <p><?php printf(__('All of this theme&#8217;s files are located in <code>%2$s</code>.'), $title, str_replace( WP_CONTENT_DIR, '', $template_dir ), str_replace( WP_CONTENT_DIR, '', $stylesheet_dir ) ); ?></p>
    239241<?php } ?>
    240242<?php if ( $tags ) : ?>
  • trunk/wp-includes/theme.php

    r12010 r12025  
    3535function get_stylesheet_directory() {
    3636    $stylesheet = get_stylesheet();
    37     $stylesheet_dir = get_theme_root() . "/$stylesheet";
    38     return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
     37    $theme_root = get_theme_root( $stylesheet );
     38    $stylesheet_dir = "$theme_root/$stylesheet";
     39
     40    return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root );
    3941}
    4042
     
    4850function get_stylesheet_directory_uri() {
    4951    $stylesheet = get_stylesheet();
    50     $stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
    51     return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
     52    $theme_root_uri = get_theme_root_uri( $stylesheet );
     53    $stylesheet_dir_uri = "$theme_root_uri/$stylesheet";
     54
     55    return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri );
    5256}
    5357
     
    124128function get_template_directory() {
    125129    $template = get_template();
    126     $template_dir = get_theme_root() . "/$template";
    127     return apply_filters('template_directory', $template_dir, $template);
     130    $theme_root = get_theme_root( $template );
     131    $template_dir = "$theme_root/$template";
     132       
     133    return apply_filters( 'template_directory', $template_dir, $template, $theme_root );
    128134}
    129135
     
    138144function get_template_directory_uri() {
    139145    $template = get_template();
    140     $template_dir_uri = get_theme_root_uri() . "/$template";
    141     return apply_filters('template_directory_uri', $template_dir_uri, $template);
     146    $theme_root_uri = get_theme_root_uri( $template );
     147    $template_dir_uri = "$theme_root_uri/$template";
     148   
     149    return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri );
    142150}
    143151
     
    254262        return $wp_themes;
    255263
    256     $themes = array();
    257     $wp_broken_themes = array();
    258     $theme_loc = $theme_root = get_theme_root();
    259     if ( '/' != WP_CONTENT_DIR ) // don't want to replace all forward slashes, see Trac #4541
    260         $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
    261 
    262     // Files in wp-content/themes directory and one subdir down
    263     $themes_dir = @ opendir($theme_root);
    264     if ( !$themes_dir )
     264    /* Register wp-content/themes as a theme directory */
     265    register_theme_directory( 'themes' );
     266
     267    if ( !$theme_files = search_theme_directories() )
    265268        return false;
    266 
    267     while ( ($theme_dir = readdir($themes_dir)) !== false ) {
    268         if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
    269             if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
    270                 continue;
    271             $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
    272             $found_stylesheet = false;
    273             while ( ($theme_file = readdir($stylish_dir)) !== false ) {
    274                 if ( $theme_file == 'style.css' ) {
    275                     $theme_files[] = $theme_dir . '/' . $theme_file;
    276                     $found_stylesheet = true;
    277                     break;
    278                 }
    279             }
    280             @closedir($stylish_dir);
    281             if ( !$found_stylesheet ) { // look for themes in that dir
    282                 $subdir = "$theme_root/$theme_dir";
    283                 $subdir_name = $theme_dir;
    284                 $theme_subdir = @ opendir( $subdir );
    285                 while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
    286                     if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
    287                         if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
    288                             continue;
    289                         $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
    290                         $found_stylesheet = false;
    291                         while ( ($theme_file = readdir($stylish_dir)) !== false ) {
    292                             if ( $theme_file == 'style.css' ) {
    293                                 $theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
    294                                 $found_stylesheet = true;
    295                                 break;
    296                             }
    297                         }
    298                         @closedir($stylish_dir);
    299                     }
    300                 }
    301                 @closedir($theme_subdir);
    302                 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
    303             }
    304         }
    305     }
    306     if ( is_dir( $theme_dir ) )
    307         @closedir( $theme_dir );
    308 
    309     if ( !$themes_dir || !$theme_files )
    310         return $themes;
    311 
    312     sort($theme_files);
    313 
     269   
     270    asort( $theme_files );
     271   
    314272    foreach ( (array) $theme_files as $theme_file ) {
     273        $theme_root = $theme_file['theme_root'];
     274        $theme_file = $theme_file['theme_file'];
     275
    315276        if ( !is_readable("$theme_root/$theme_file") ) {
    316277            $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
     
    347308                continue;
    348309        }
    349 
    350         $template = trim($template);
     310       
     311        $template = trim( $template );
    351312
    352313        if ( !file_exists("$theme_root/$template/index.php") ) {
    353314            $parent_dir = dirname(dirname($theme_file));
    354315            if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
    355                 $template = "$parent_dir/$template";
     316                $template = "$theme_root/$parent_dir/$template";
    356317            } else {
    357                 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
    358                 continue;
     318                /** 
     319                 * The parent theme doesn't exist in the current theme's folder or sub folder
     320                 * so lets use the theme root for the parent template.
     321                 */
     322                $parent_theme_root = $theme_files[$template]['theme_root'];
     323                if ( file_exists( "$parent_theme_root/$template/index.php" ) ) {
     324                    $template = "$parent_theme_root/$template";
     325                } else {
     326                    $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
     327                    continue;
     328                }
     329               
    359330            }
     331        } else {
     332            $template = trim( $theme_root . '/' . $template );
    360333        }
    361 
     334       
    362335        $stylesheet_files = array();
    363336        $template_files = array();
     
    368341                if ( !preg_match('|^\.+$|', $file) ) {
    369342                    if ( preg_match('|\.css$|', $file) )
    370                         $stylesheet_files[] = "$theme_loc/$stylesheet/$file";
     343                        $stylesheet_files[] = "$theme_root/$stylesheet/$file";
    371344                    elseif ( preg_match('|\.php$|', $file) )
    372                         $template_files[] = "$theme_loc/$stylesheet/$file";
     345                        $template_files[] = "$theme_root/$stylesheet/$file";
    373346                }
    374347            }
     
    376349        }
    377350
    378         $template_dir = @ dir("$theme_root/$template");
     351        $template_dir = @ dir("$template");
    379352        if ( $template_dir ) {
    380353            while ( ($file = $template_dir->read()) !== false ) {
     
    382355                    continue;
    383356                if ( preg_match('|\.php$|', $file) ) {
    384                     $template_files[] = "$theme_loc/$template/$file";
    385                 } elseif ( is_dir("$theme_root/$template/$file") ) {
    386                     $template_subdir = @ dir("$theme_root/$template/$file");
     357                    $template_files[] = "$template/$file";
     358                } elseif ( is_dir("$template/$file") ) {
     359                    $template_subdir = @ dir("$template/$file");
    387360                    while ( ($subfile = $template_subdir->read()) !== false ) {
    388361                        if ( preg_match('|^\.+$|', $subfile) )
    389362                            continue;
    390363                        if ( preg_match('|\.php$|', $subfile) )
    391                             $template_files[] = "$theme_loc/$template/$file/$subfile";
     364                            $template_files[] = "$template/$file/$subfile";
    392365                    }
    393366                    @ $template_subdir->close();
     
    423396        }
    424397
    425         $themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags']);
     398        $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root );
     399        $themes[$name] = array( 'Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => basename( $template ), 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags'], 'Theme Root' => $theme_root, 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ) );
    426400    }
    427401
    428     // Resolve theme dependencies.
    429     $theme_names = array_keys($themes);
     402    /* Resolve theme dependencies. */
     403    $theme_names = array_keys( $themes );
     404
     405    /* Store theme roots in the DB */
     406    if ( get_transient( 'theme_roots' ) != $theme_roots )
     407        set_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours
    430408
    431409    foreach ( (array) $theme_names as $theme_name ) {
     
    442420
    443421    $wp_themes = $themes;
    444 
     422   
    445423    return $themes;
     424}
     425
     426/**
     427 * Retrieve theme roots.
     428 *
     429 * @since 2.9.0
     430 *
     431 * @return array Theme roots
     432 */
     433function get_theme_roots() {
     434    $theme_roots = get_transient( 'theme_roots' );
     435    if ( false === $theme_roots ) {
     436        get_themes();
     437        $theme_roots = get_transient( 'theme_roots' ); // this is set in get_theme()
     438    }
     439    return $theme_roots;
    446440}
    447441
     
    500494
    501495/**
     496 * Register a directory that contains themes relative to the content directory.
     497 *
     498 * @since 2.9.0
     499 *
     500 * @return bool
     501 */
     502function register_theme_directory( $directory ) {
     503    global $wp_theme_directories;
     504   
     505    /* The theme directory should be relative to the content directory */
     506    $registered_directory = WP_CONTENT_DIR . '/' . $directory;
     507   
     508    /* If this folder does not exist, return and do not register */
     509    if ( !file_exists( $registered_directory ) )
     510        return false;
     511   
     512    $wp_theme_directories[] = $registered_directory;
     513   
     514    return true;
     515}
     516
     517/**
     518 * Search all registered theme directories for complete and valid themes.
     519 *
     520 * @since 2.9.0
     521 *
     522 * @return array Valid themes found
     523 */
     524function search_theme_directories() {
     525    global $wp_theme_directories, $wp_broken_themes;
     526   
     527    if ( empty( $wp_theme_directories ) )
     528        return false;
     529
     530    $theme_files = array();
     531    $wp_broken_themes = array();
     532
     533    /* Loop the registered theme directories and extract all themes */
     534    foreach ( (array) $wp_theme_directories as $theme_root ) {
     535        $theme_loc = $theme_root;
     536       
     537        /* We don't want to replace all forward slashes, see Trac #4541 */
     538        if ( '/' != WP_CONTENT_DIR )
     539            $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
     540
     541        /* Files in the root of the current theme directory and one subdir down */
     542        $themes_dir = @ opendir($theme_root);
     543
     544        if ( !$themes_dir )
     545            return false;
     546
     547        while ( ($theme_dir = readdir($themes_dir)) !== false ) {
     548            if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
     549                if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
     550                    continue;
     551
     552                $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
     553                $found_stylesheet = false;
     554               
     555                while ( ($theme_file = readdir($stylish_dir)) !== false ) {
     556                    if ( $theme_file == 'style.css' ) {
     557                        $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root );
     558                        $found_stylesheet = true;
     559                        break;
     560                    }
     561                }
     562                @closedir($stylish_dir);
     563               
     564                if ( !$found_stylesheet ) { // look for themes in that dir
     565                    $subdir = "$theme_root/$theme_dir";
     566                    $subdir_name = $theme_dir;
     567                    $theme_subdir = @ opendir( $subdir );
     568                   
     569                    while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
     570                        if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
     571                            if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
     572                                continue;
     573                               
     574                            $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
     575                            $found_stylesheet = false;
     576                           
     577                            while ( ($theme_file = readdir($stylish_dir)) !== false ) {
     578                                if ( $theme_file == 'style.css' ) {
     579                                    $theme_files[$theme_dir] = array( 'theme_file' => $subdir_name . '/' . $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root );
     580                                    $found_stylesheet = true;
     581                                    break;
     582                                }
     583                            }
     584                            @closedir($stylish_dir);
     585                        }
     586                    }
     587                    @closedir($theme_subdir);
     588                   
     589                    $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
     590                }
     591            }
     592        }
     593        if ( is_dir( $theme_dir ) )
     594            @closedir( $theme_dir );
     595    }
     596   
     597    return $theme_files;
     598}
     599
     600/**
    502601 * Retrieve path to themes directory.
    503602 *
     
    505604 *
    506605 * @since 1.5.0
     606 * @param $stylesheet_or_template The stylesheet or template name of the theme
    507607 * @uses apply_filters() Calls 'theme_root' filter on path.
    508608 *
    509609 * @return string Theme path.
    510610 */
    511 function get_theme_root() {
    512     return apply_filters('theme_root', WP_CONTENT_DIR . "/themes");
     611function get_theme_root( $stylesheet_or_template = false ) {
     612    $theme_roots = get_theme_roots();
     613   
     614    if ( $theme_roots[$stylesheet_or_template] )
     615        $theme_root = WP_CONTENT_DIR . '/' . $theme_roots[$stylesheet_or_template];
     616    else
     617        $theme_root = WP_CONTENT_DIR . '/themes';
     618
     619    return apply_filters( 'theme_root', $theme_root );
    513620}
    514621
     
    519626 *
    520627 * @since 1.5.0
     628 * @param $stylesheet_or_template The stylesheet or template name of the theme
    521629 *
    522630 * @return string Themes URI.
    523631 */
    524 function get_theme_root_uri() {
    525     return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl'));
     632function get_theme_root_uri( $stylesheet_or_template = false ) {
     633    $theme_roots = get_theme_roots();
     634   
     635    if ( $theme_roots[$stylesheet_or_template] )
     636        $theme_root_uri = content_url( $theme_roots[$stylesheet_or_template] );
     637    else
     638        $theme_root_uri = content_url( 'themes' );
     639
     640    return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template );
    526641}
    527642
Note: See TracChangeset for help on using the changeset viewer.