WordPress.org

Make WordPress Core

Changeset 20002


Ignore:
Timestamp:
02/28/12 01:49:49 (6 years ago)
Author:
nacin
Message:

Move the template loading functions from wp-includes/theme.php to wp-includes/template.php. This includes get_query_template(), locate_template(), and friends. see #20103.

Location:
trunk
Files:
2 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/template.php

    r20001 r20002  
    11<?php 
    22/** 
    3  * Theme, template, and stylesheet functions. 
     3 * Template loading functions. 
    44 * 
    55 * @package WordPress 
    66 * @subpackage Template 
    77 */ 
    8  
    9 /** 
    10  * Whether a child theme is in use. 
    11  * 
    12  * @since 3.0.0 
    13  * 
    14  * @return bool true if a child theme is in use, false otherwise. 
    15  **/ 
    16 function is_child_theme() { 
    17     return ( TEMPLATEPATH !== STYLESHEETPATH ); 
    18 } 
    19  
    20 /** 
    21  * Retrieve name of the current stylesheet. 
    22  * 
    23  * The theme name that the administrator has currently set the front end theme 
    24  * as. 
    25  * 
    26  * For all extensive purposes, the template name and the stylesheet name are 
    27  * going to be the same for most cases. 
    28  * 
    29  * @since 1.5.0 
    30  * @uses apply_filters() Calls 'stylesheet' filter on stylesheet name. 
    31  * 
    32  * @return string Stylesheet name. 
    33  */ 
    34 function get_stylesheet() { 
    35     return apply_filters('stylesheet', get_option('stylesheet')); 
    36 } 
    37  
    38 /** 
    39  * Retrieve stylesheet directory path for current theme. 
    40  * 
    41  * @since 1.5.0 
    42  * @uses apply_filters() Calls 'stylesheet_directory' filter on stylesheet directory and theme name. 
    43  * 
    44  * @return string Path to current theme directory. 
    45  */ 
    46 function get_stylesheet_directory() { 
    47     $stylesheet = get_stylesheet(); 
    48     $theme_root = get_theme_root( $stylesheet ); 
    49     $stylesheet_dir = "$theme_root/$stylesheet"; 
    50  
    51     return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); 
    52 } 
    53  
    54 /** 
    55  * Retrieve stylesheet directory URI. 
    56  * 
    57  * @since 1.5.0 
    58  * 
    59  * @return string 
    60  */ 
    61 function get_stylesheet_directory_uri() { 
    62     $stylesheet = get_stylesheet(); 
    63     $theme_root_uri = get_theme_root_uri( $stylesheet ); 
    64     $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; 
    65  
    66     return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); 
    67 } 
    68  
    69 /** 
    70  * Retrieve URI of current theme stylesheet. 
    71  * 
    72  * The stylesheet file name is 'style.css' which is appended to {@link 
    73  * get_stylesheet_directory_uri() stylesheet directory URI} path. 
    74  * 
    75  * @since 1.5.0 
    76  * @uses apply_filters() Calls 'stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI. 
    77  * 
    78  * @return string 
    79  */ 
    80 function get_stylesheet_uri() { 
    81     $stylesheet_dir_uri = get_stylesheet_directory_uri(); 
    82     $stylesheet_uri = $stylesheet_dir_uri . '/style.css'; 
    83     return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri); 
    84 } 
    85  
    86 /** 
    87  * Retrieve localized stylesheet URI. 
    88  * 
    89  * The stylesheet directory for the localized stylesheet files are located, by 
    90  * default, in the base theme directory. The name of the locale file will be the 
    91  * locale followed by '.css'. If that does not exist, then the text direction 
    92  * stylesheet will be checked for existence, for example 'ltr.css'. 
    93  * 
    94  * The theme may change the location of the stylesheet directory by either using 
    95  * the 'stylesheet_directory_uri' filter or the 'locale_stylesheet_uri' filter. 
    96  * If you want to change the location of the stylesheet files for the entire 
    97  * WordPress workflow, then change the former. If you just have the locale in a 
    98  * separate folder, then change the latter. 
    99  * 
    100  * @since 2.1.0 
    101  * @uses apply_filters() Calls 'locale_stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI. 
    102  * 
    103  * @return string 
    104  */ 
    105 function get_locale_stylesheet_uri() { 
    106     global $wp_locale; 
    107     $stylesheet_dir_uri = get_stylesheet_directory_uri(); 
    108     $dir = get_stylesheet_directory(); 
    109     $locale = get_locale(); 
    110     if ( file_exists("$dir/$locale.css") ) 
    111         $stylesheet_uri = "$stylesheet_dir_uri/$locale.css"; 
    112     elseif ( !empty($wp_locale->text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") ) 
    113         $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css"; 
    114     else 
    115         $stylesheet_uri = ''; 
    116     return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri); 
    117 } 
    118  
    119 /** 
    120  * Retrieve name of the current theme. 
    121  * 
    122  * @since 1.5.0 
    123  * @uses apply_filters() Calls 'template' filter on template option. 
    124  * 
    125  * @return string Template name. 
    126  */ 
    127 function get_template() { 
    128     return apply_filters('template', get_option('template')); 
    129 } 
    130  
    131 /** 
    132  * Retrieve current theme directory. 
    133  * 
    134  * @since 1.5.0 
    135  * @uses apply_filters() Calls 'template_directory' filter on template directory path and template name. 
    136  * 
    137  * @return string Template directory path. 
    138  */ 
    139 function get_template_directory() { 
    140     $template = get_template(); 
    141     $theme_root = get_theme_root( $template ); 
    142     $template_dir = "$theme_root/$template"; 
    143  
    144     return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); 
    145 } 
    146  
    147 /** 
    148  * Retrieve theme directory URI. 
    149  * 
    150  * @since 1.5.0 
    151  * @uses apply_filters() Calls 'template_directory_uri' filter on template directory URI path and template name. 
    152  * 
    153  * @return string Template directory URI. 
    154  */ 
    155 function get_template_directory_uri() { 
    156     $template = get_template(); 
    157     $theme_root_uri = get_theme_root_uri( $template ); 
    158     $template_dir_uri = "$theme_root_uri/$template"; 
    159  
    160     return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); 
    161 } 
    162  
    163 /** 
    164  * Retrieve theme data from parsed theme file. 
    165  * 
    166  * The description will have the tags filtered with the following HTML elements 
    167  * whitelisted. The <b>'a'</b> element with the <em>href</em> and <em>title</em> 
    168  * attributes. The <b>abbr</b> element with the <em>title</em> attribute. The 
    169  * <b>acronym</b> element with the <em>title</em> attribute allowed. The 
    170  * <b>code</b>, <b>em</b>, and <b>strong</b> elements also allowed. 
    171  * 
    172  * The style.css file must contain theme name, theme URI, and description. The 
    173  * data can also contain author URI, author, template (parent template), 
    174  * version, status, and finally tags. Some of these are not used by WordPress 
    175  * administration panels, but are used by theme directory web sites which list 
    176  * the theme. 
    177  * 
    178  * @since 1.5.0 
    179  * 
    180  * @param string $theme_file Theme file path. 
    181  * @return array Theme data. 
    182  */ 
    183 function get_theme_data( $theme_file ) { 
    184     $default_headers = array( 
    185         'Name' => 'Theme Name', 
    186         'URI' => 'Theme URI', 
    187         'Description' => 'Description', 
    188         'Author' => 'Author', 
    189         'AuthorURI' => 'Author URI', 
    190         'Version' => 'Version', 
    191         'Template' => 'Template', 
    192         'Status' => 'Status', 
    193         'Tags' => 'Tags' 
    194         ); 
    195  
    196     $themes_allowed_tags = array( 
    197         'a' => array( 
    198             'href' => array(),'title' => array() 
    199             ), 
    200         'abbr' => array( 
    201             'title' => array() 
    202             ), 
    203         'acronym' => array( 
    204             'title' => array() 
    205             ), 
    206         'code' => array(), 
    207         'em' => array(), 
    208         'strong' => array() 
    209     ); 
    210  
    211     $theme_data = get_file_data( $theme_file, $default_headers, 'theme' ); 
    212  
    213     $theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags ); 
    214  
    215     $theme_data['URI'] = esc_url( $theme_data['URI'] ); 
    216  
    217     $theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) ); 
    218  
    219     $theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] ); 
    220  
    221     $theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags ); 
    222  
    223     $theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags ); 
    224  
    225     if ( $theme_data['Status'] == '' ) 
    226         $theme_data['Status'] = 'publish'; 
    227     else 
    228         $theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags ); 
    229  
    230     if ( $theme_data['Tags'] == '' ) 
    231         $theme_data['Tags'] = array(); 
    232     else 
    233         $theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) ); 
    234  
    235     if ( $theme_data['Author'] == '' ) { 
    236         $theme_data['Author'] = $theme_data['AuthorName'] = __('Anonymous'); 
    237     } else { 
    238         $theme_data['AuthorName'] = wp_kses( $theme_data['Author'], $themes_allowed_tags ); 
    239         if ( empty( $theme_data['AuthorURI'] ) ) { 
    240             $theme_data['Author'] = $theme_data['AuthorName']; 
    241         } else { 
    242             $theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], esc_attr__( 'Visit author homepage' ), $theme_data['AuthorName'] ); 
    243         } 
    244     } 
    245  
    246     return $theme_data; 
    247 } 
    248  
    249 /** 
    250  * Retrieve list of themes with theme data in theme directory. 
    251  * 
    252  * The theme is broken, if it doesn't have a parent theme and is missing either 
    253  * style.css and, or index.php. If the theme has a parent theme then it is 
    254  * broken, if it is missing style.css; index.php is optional. The broken theme 
    255  * list is saved in the {@link $wp_broken_themes} global, which is displayed on 
    256  * the theme list in the administration panels. 
    257  * 
    258  * @since 1.5.0 
    259  * @global array $wp_broken_themes Stores the broken themes. 
    260  * @global array $wp_themes Stores the working themes. 
    261  * 
    262  * @return array Theme list with theme data. 
    263  */ 
    264 function get_themes() { 
    265     global $wp_themes, $wp_broken_themes; 
    266  
    267     if ( isset($wp_themes) ) 
    268         return $wp_themes; 
    269  
    270     if ( !$theme_files = search_theme_directories() ) 
    271         return false; 
    272  
    273     asort( $theme_files ); 
    274  
    275     $wp_themes = array(); 
    276  
    277     foreach ( (array) $theme_files as $theme_file ) { 
    278         $theme_root = $theme_file['theme_root']; 
    279         $theme_file = $theme_file['theme_file']; 
    280  
    281         if ( !is_readable("$theme_root/$theme_file") ) { 
    282             $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); 
    283             continue; 
    284         } 
    285  
    286         $theme_data = get_theme_data("$theme_root/$theme_file"); 
    287  
    288         $name        = $theme_data['Name']; 
    289         $title       = $theme_data['Title']; 
    290         $description = wptexturize($theme_data['Description']); 
    291         $version     = $theme_data['Version']; 
    292         $author      = $theme_data['Author']; 
    293         $template    = $theme_data['Template']; 
    294         $stylesheet  = dirname($theme_file); 
    295  
    296         $screenshot = false; 
    297         foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) { 
    298             if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) { 
    299                 $screenshot = "screenshot.$ext"; 
    300                 break; 
    301             } 
    302         } 
    303  
    304         if ( empty($name) ) { 
    305             $name = dirname($theme_file); 
    306             $title = $name; 
    307         } 
    308  
    309         $parent_template = $template; 
    310  
    311         if ( empty($template) ) { 
    312             if ( file_exists("$theme_root/$stylesheet/index.php") ) 
    313                 $template = $stylesheet; 
    314             else 
    315                 continue; 
    316         } 
    317  
    318         $template = trim( $template ); 
    319  
    320         if ( !file_exists("$theme_root/$template/index.php") ) { 
    321             $parent_dir = dirname(dirname($theme_file)); 
    322             if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { 
    323                 $template = "$parent_dir/$template"; 
    324                 $template_directory = "$theme_root/$template"; 
    325             } else { 
    326                 /** 
    327                  * The parent theme doesn't exist in the current theme's folder or sub folder 
    328                  * so lets use the theme root for the parent template. 
    329                  */ 
    330                 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { 
    331                     $template_directory = $theme_files[$template]['theme_root'] . "/$template"; 
    332                 } else { 
    333                     if ( empty( $parent_template) ) 
    334                         $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template'); 
    335                     else 
    336                         $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => sprintf( __('The parent theme is missing. Please install the "%s" parent theme.'),  $parent_template ), 'error' => 'no_parent', 'parent' => $parent_template ); 
    337                     continue; 
    338                 } 
    339  
    340             } 
    341         } else { 
    342             $template_directory = trim( $theme_root . '/' . $template ); 
    343         } 
    344  
    345         $stylesheet_files = array(); 
    346         $template_files = array(); 
    347  
    348         $stylesheet_dir = @ dir("$theme_root/$stylesheet"); 
    349         if ( $stylesheet_dir ) { 
    350             while ( ($file = $stylesheet_dir->read()) !== false ) { 
    351                 if ( !preg_match('|^\.+$|', $file) ) { 
    352                     if ( preg_match('|\.css$|', $file) ) 
    353                         $stylesheet_files[] = "$theme_root/$stylesheet/$file"; 
    354                     elseif ( preg_match('|\.php$|', $file) ) 
    355                         $template_files[] = "$theme_root/$stylesheet/$file"; 
    356                 } 
    357             } 
    358             @ $stylesheet_dir->close(); 
    359         } 
    360  
    361         $template_dir = @ dir("$template_directory"); 
    362         if ( $template_dir ) { 
    363             while ( ($file = $template_dir->read()) !== false ) { 
    364                 if ( preg_match('|^\.+$|', $file) ) 
    365                     continue; 
    366                 if ( preg_match('|\.php$|', $file) ) { 
    367                     $template_files[] = "$template_directory/$file"; 
    368                 } elseif ( is_dir("$template_directory/$file") ) { 
    369                     $template_subdir = @ dir("$template_directory/$file"); 
    370                     if ( !$template_subdir ) 
    371                         continue; 
    372                     while ( ($subfile = $template_subdir->read()) !== false ) { 
    373                         if ( preg_match('|^\.+$|', $subfile) ) 
    374                             continue; 
    375                         if ( preg_match('|\.php$|', $subfile) ) 
    376                             $template_files[] = "$template_directory/$file/$subfile"; 
    377                     } 
    378                     @ $template_subdir->close(); 
    379                 } 
    380             } 
    381             @ $template_dir->close(); 
    382         } 
    383  
    384         //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes 
    385         $template_files = array_unique($template_files); 
    386         $stylesheet_files = array_unique($stylesheet_files); 
    387  
    388         $template_dir = $template_directory; 
    389         $stylesheet_dir = $theme_root . '/' . $stylesheet; 
    390  
    391         if ( empty($template_dir) ) 
    392             $template_dir = '/'; 
    393         if ( empty($stylesheet_dir) ) 
    394             $stylesheet_dir = '/'; 
    395  
    396         // Check for theme name collision. This occurs if a theme is copied to 
    397         // a new theme directory and the theme header is not updated. Whichever 
    398         // theme is first keeps the name. Subsequent themes get a suffix applied. 
    399         // Default themes themes always trump their pretenders. 
    400         if ( isset($wp_themes[$name]) ) { 
    401             $trump_cards = array( 
    402                 'classic'      => 'WordPress Classic', 
    403                 'default'      => 'WordPress Default', 
    404                 'twentyten'    => 'Twenty Ten', 
    405                 'twentyeleven' => 'Twenty Eleven', 
    406                 'twentytwelve' => 'Twenty Twelve', 
    407             ); 
    408             if ( isset( $trump_cards[ $stylesheet ] ) && $name == $trump_cards[ $stylesheet ] ) { 
    409                 // If another theme has claimed to be one of our default themes, move 
    410                 // them aside. 
    411                 $suffix = $wp_themes[$name]['Stylesheet']; 
    412                 $new_name = "$name/$suffix"; 
    413                 $wp_themes[$new_name] = $wp_themes[$name]; 
    414                 $wp_themes[$new_name]['Name'] = $new_name; 
    415             } else { 
    416                 $name = "$name/$stylesheet"; 
    417             } 
    418         } 
    419  
    420         $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); 
    421         $wp_themes[$name] = array( 
    422             'Name' => $name, 
    423             'Title' => $title, 
    424             'Description' => $description, 
    425             'Author' => $author, 
    426             'Author Name' => $theme_data['AuthorName'], 
    427             'Author URI' => $theme_data['AuthorURI'], 
    428             'Version' => $version, 
    429             'Template' => $template, 
    430             'Stylesheet' => $stylesheet, 
    431             'Template Files' => $template_files, 
    432             'Stylesheet Files' => $stylesheet_files, 
    433             'Template Dir' => $template_dir, 
    434             'Stylesheet Dir' => $stylesheet_dir, 
    435             'Status' => $theme_data['Status'], 
    436             'Screenshot' => $screenshot, 
    437             'Tags' => $theme_data['Tags'], 
    438             'Theme Root' => $theme_root, 
    439             'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ), 
    440         ); 
    441     } 
    442  
    443     unset($theme_files); 
    444  
    445     /* Store theme roots in the DB */ 
    446     if ( get_site_transient( 'theme_roots' ) != $theme_roots ) 
    447         set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 
    448     unset($theme_roots); 
    449  
    450     /* Resolve theme dependencies. */ 
    451     $theme_names = array_keys( $wp_themes ); 
    452     foreach ( (array) $theme_names as $theme_name ) { 
    453         $wp_themes[$theme_name]['Parent Theme'] = ''; 
    454         if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { 
    455             foreach ( (array) $theme_names as $parent_theme_name ) { 
    456                 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { 
    457                     $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; 
    458                     break; 
    459                 } 
    460             } 
    461         } 
    462     } 
    463  
    464     return $wp_themes; 
    465 } 
    466  
    467 /** 
    468  * Retrieve theme roots. 
    469  * 
    470  * @since 2.9.0 
    471  * 
    472  * @return array|string An array of theme roots keyed by template/stylesheet or a single theme root if all themes have the same root. 
    473  */ 
    474 function get_theme_roots() { 
    475     global $wp_theme_directories; 
    476  
    477     if ( count($wp_theme_directories) <= 1 ) 
    478         return get_theme_root(); 
    479  
    480     $theme_roots = get_site_transient( 'theme_roots' ); 
    481     if ( false === $theme_roots ) { 
    482         get_themes(); 
    483         $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() 
    484     } 
    485     return $theme_roots; 
    486 } 
    487  
    488 /** 
    489  * Retrieve theme data. 
    490  * 
    491  * @since 1.5.0 
    492  * 
    493  * @param string $theme Theme name. 
    494  * @return array|null Null, if theme name does not exist. Theme data, if exists. 
    495  */ 
    496 function get_theme($theme) { 
    497     $themes = get_themes(); 
    498  
    499     if ( is_array( $themes ) && array_key_exists( $theme, $themes ) ) 
    500         return $themes[$theme]; 
    501  
    502     return null; 
    503 } 
    504  
    505 /** 
    506  * Retrieve current theme display name. 
    507  * 
    508  * If the 'current_theme' option has already been set, then it will be returned 
    509  * instead. If it is not set, then each theme will be iterated over until both 
    510  * the current stylesheet and current template name. 
    511  * 
    512  * @since 1.5.0 
    513  * 
    514  * @return string 
    515  */ 
    516 function get_current_theme() { 
    517     if ( $theme = get_option('current_theme') ) 
    518         return $theme; 
    519  
    520     $themes = get_themes(); 
    521     $current_theme = 'Twenty Eleven'; 
    522  
    523     if ( $themes ) { 
    524         $theme_names = array_keys( $themes ); 
    525         $current_template = get_option( 'template' ); 
    526         $current_stylesheet = get_option( 'stylesheet' ); 
    527  
    528         foreach ( (array) $theme_names as $theme_name ) { 
    529             if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && 
    530                     $themes[$theme_name]['Template'] == $current_template ) { 
    531                 $current_theme = $themes[$theme_name]['Name']; 
    532                 break; 
    533             } 
    534         } 
    535     } 
    536  
    537     update_option('current_theme', $current_theme); 
    538  
    539     return $current_theme; 
    540 } 
    541  
    542 /** 
    543  * Register a directory that contains themes. 
    544  * 
    545  * @since 2.9.0 
    546  * 
    547  * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR 
    548  * @return bool 
    549  */ 
    550 function register_theme_directory( $directory ) { 
    551     global $wp_theme_directories; 
    552  
    553     if ( ! file_exists( $directory ) ) { 
    554         // Try prepending as the theme directory could be relative to the content directory 
    555         $directory = WP_CONTENT_DIR . '/' . $directory; 
    556         // If this directory does not exist, return and do not register 
    557         if ( ! file_exists( $directory ) ) 
    558             return false; 
    559     } 
    560  
    561     $wp_theme_directories[] = $directory; 
    562  
    563     return true; 
    564 } 
    565  
    566 /** 
    567  * Search all registered theme directories for complete and valid themes. 
    568  * 
    569  * @since 2.9.0 
    570  * 
    571  * @return array Valid themes found 
    572  */ 
    573 function search_theme_directories() { 
    574     global $wp_theme_directories, $wp_broken_themes; 
    575     if ( empty( $wp_theme_directories ) ) 
    576         return false; 
    577  
    578     $theme_files = array(); 
    579     $wp_broken_themes = array(); 
    580  
    581     /* Loop the registered theme directories and extract all themes */ 
    582     foreach ( (array) $wp_theme_directories as $theme_root ) { 
    583         $theme_loc = $theme_root; 
    584  
    585         /* We don't want to replace all forward slashes, see Trac #4541 */ 
    586         if ( '/' != WP_CONTENT_DIR ) 
    587             $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 
    588  
    589         /* Files in the root of the current theme directory and one subdir down */ 
    590         $themes_dir = @ opendir($theme_root); 
    591  
    592         if ( !$themes_dir ) 
    593             return false; 
    594  
    595         while ( ($theme_dir = readdir($themes_dir)) !== false ) { 
    596             if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 
    597                 if ( $theme_dir[0] == '.' || $theme_dir == 'CVS' ) 
    598                     continue; 
    599  
    600                 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 
    601                 $found_stylesheet = false; 
    602  
    603                 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    604                     if ( $theme_file == 'style.css' ) { 
    605                         $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    606                         $found_stylesheet = true; 
    607                         break; 
    608                     } 
    609                 } 
    610                 @closedir($stylish_dir); 
    611  
    612                 if ( !$found_stylesheet ) { // look for themes in that dir 
    613                     $subdir = "$theme_root/$theme_dir"; 
    614                     $subdir_name = $theme_dir; 
    615                     $theme_subdirs = @opendir( $subdir ); 
    616  
    617                     $found_subdir_themes = false; 
    618                     while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 
    619                         if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 
    620                             if ( $theme_subdir[0] == '.' || $theme_subdir == 'CVS' ) 
    621                                 continue; 
    622  
    623                             $stylish_dir = @opendir($subdir . '/' . $theme_subdir); 
    624                             $found_stylesheet = false; 
    625  
    626                             while ( ($theme_file = readdir($stylish_dir)) !== false ) { 
    627                                 if ( $theme_file == 'style.css' ) { 
    628                                     $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 
    629                                     $found_stylesheet = true; 
    630                                     $found_subdir_themes = true; 
    631                                     break; 
    632                                 } 
    633                             } 
    634                             @closedir($stylish_dir); 
    635                         } 
    636                     } 
    637                     @closedir($theme_subdirs); 
    638                     if ( !$found_subdir_themes ) 
    639                         $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 
    640                 } 
    641             } 
    642         } 
    643         @closedir( $themes_dir ); 
    644     } 
    645     return $theme_files; 
    646 } 
    647  
    648 /** 
    649  * Retrieve path to themes directory. 
    650  * 
    651  * Does not have trailing slash. 
    652  * 
    653  * @since 1.5.0 
    654  * @uses apply_filters() Calls 'theme_root' filter on path. 
    655  * 
    656  * @param string $stylesheet_or_template The stylesheet or template name of the theme 
    657  * @return string Theme path. 
    658  */ 
    659 function get_theme_root( $stylesheet_or_template = false ) { 
    660     if ( $stylesheet_or_template && $theme_root = get_raw_theme_root( $stylesheet_or_template ) ) 
    661         $theme_root = $theme_root; 
    662     else 
    663         $theme_root = WP_CONTENT_DIR . '/themes'; 
    664  
    665     return apply_filters( 'theme_root', $theme_root ); 
    666 } 
    667  
    668 /** 
    669  * Retrieve URI for themes directory. 
    670  * 
    671  * Does not have trailing slash. 
    672  * 
    673  * @since 1.5.0 
    674  * 
    675  * @param string $stylesheet_or_template The stylesheet or template name of the theme 
    676  * @return string Themes URI. 
    677  */ 
    678 function get_theme_root_uri( $stylesheet_or_template = false ) { 
    679     if ( $stylesheet_or_template ) { 
    680         if ( $theme_root = get_raw_theme_root($stylesheet_or_template) ) 
    681             $theme_root_uri = content_url( str_replace( WP_CONTENT_DIR, '', $theme_root ) ); 
    682         else 
    683             $theme_root_uri = content_url( 'themes' ); 
    684     } else { 
    685         $theme_root_uri = content_url( 'themes' ); 
    686     } 
    687  
    688     return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template ); 
    689 } 
    690  
    691 /** 
    692  * Get the raw theme root with no filters applied. 
    693  * 
    694  * @since 3.1.0 
    695  * 
    696  * Before 3.4.0, this incorrectly returned a path relative to the content directory ("/themes") when 
    697  * only one theme directory was registered. Absolute paths are now always returned. 
    698  * 
    699  * @param string $stylesheet_or_template The stylesheet or template name of the theme 
    700  * @return string Theme root 
    701  */ 
    702 function get_raw_theme_root( $stylesheet_or_template, $no_cache = false ) { 
    703     global $wp_theme_directories; 
    704  
    705     if ( count($wp_theme_directories) <= 1 ) 
    706         return WP_CONTENT_DIR . '/themes'; 
    707  
    708     $theme_root = false; 
    709  
    710     // If requesting the root for the current theme, consult options to avoid calling get_theme_roots() 
    711     if ( !$no_cache ) { 
    712         if ( get_option('stylesheet') == $stylesheet_or_template ) 
    713             $theme_root = get_option('stylesheet_root'); 
    714         elseif ( get_option('template') == $stylesheet_or_template ) 
    715             $theme_root = get_option('template_root'); 
    716     } 
    717  
    718     if ( empty($theme_root) ) { 
    719         $theme_roots = get_theme_roots(); 
    720         if ( !empty($theme_roots[$stylesheet_or_template]) ) 
    721             $theme_root = $theme_roots[$stylesheet_or_template]; 
    722     } 
    723  
    724     return $theme_root; 
    725 } 
    7268 
    7279/** 
     
    1114396} 
    1115397 
    1116 /** 
    1117  * Display localized stylesheet link element. 
    1118  * 
    1119  * @since 2.1.0 
    1120  */ 
    1121 function locale_stylesheet() { 
    1122     $stylesheet = get_locale_stylesheet_uri(); 
    1123     if ( empty($stylesheet) ) 
    1124         return; 
    1125     echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />'; 
    1126 } 
    1127  
    1128 /** 
    1129  * Start preview theme output buffer. 
    1130  * 
    1131  * Will only preform task if the user has permissions and template and preview 
    1132  * query variables exist. 
    1133  * 
    1134  * @since 2.6.0 
    1135  */ 
    1136 function preview_theme() { 
    1137     if ( ! (isset($_GET['template']) && isset($_GET['preview'])) ) 
    1138         return; 
    1139  
    1140     if ( !current_user_can( 'switch_themes' ) ) 
    1141         return; 
    1142  
    1143     // Admin Thickbox requests 
    1144     if ( isset( $_GET['preview_iframe'] ) ) 
    1145         show_admin_bar( false ); 
    1146  
    1147     $_GET['template'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['template']); 
    1148  
    1149     if ( validate_file($_GET['template']) ) 
    1150         return; 
    1151  
    1152     add_filter( 'template', '_preview_theme_template_filter' ); 
    1153  
    1154     if ( isset($_GET['stylesheet']) ) { 
    1155         $_GET['stylesheet'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['stylesheet']); 
    1156         if ( validate_file($_GET['stylesheet']) ) 
    1157             return; 
    1158         add_filter( 'stylesheet', '_preview_theme_stylesheet_filter' ); 
    1159     } 
    1160  
    1161     // Prevent theme mods to current theme being used on theme being previewed 
    1162     add_filter( 'pre_option_mods_' . get_current_theme(), '__return_empty_array' ); 
    1163  
    1164     ob_start( 'preview_theme_ob_filter' ); 
    1165 } 
    1166 add_action('setup_theme', 'preview_theme'); 
    1167  
    1168 /** 
    1169  * Private function to modify the current template when previewing a theme 
    1170  * 
    1171  * @since 2.9.0 
    1172  * @access private 
    1173  * 
    1174  * @return string 
    1175  */ 
    1176 function _preview_theme_template_filter() { 
    1177     return isset($_GET['template']) ? $_GET['template'] : ''; 
    1178 } 
    1179  
    1180 /** 
    1181  * Private function to modify the current stylesheet when previewing a theme 
    1182  * 
    1183  * @since 2.9.0 
    1184  * @access private 
    1185  * 
    1186  * @return string 
    1187  */ 
    1188 function _preview_theme_stylesheet_filter() { 
    1189     return isset($_GET['stylesheet']) ? $_GET['stylesheet'] : ''; 
    1190 } 
    1191  
    1192 /** 
    1193  * Callback function for ob_start() to capture all links in the theme. 
    1194  * 
    1195  * @since 2.6.0 
    1196  * @access private 
    1197  * 
    1198  * @param string $content 
    1199  * @return string 
    1200  */ 
    1201 function preview_theme_ob_filter( $content ) { 
    1202     return preg_replace_callback( "|(<a.*?href=([\"']))(.*?)([\"'].*?>)|", 'preview_theme_ob_filter_callback', $content ); 
    1203 } 
    1204  
    1205 /** 
    1206  * Manipulates preview theme links in order to control and maintain location. 
    1207  * 
    1208  * Callback function for preg_replace_callback() to accept and filter matches. 
    1209  * 
    1210  * @since 2.6.0 
    1211  * @access private 
    1212  * 
    1213  * @param array $matches 
    1214  * @return string 
    1215  */ 
    1216 function preview_theme_ob_filter_callback( $matches ) { 
    1217     if ( strpos($matches[4], 'onclick') !== false ) 
    1218         $matches[4] = preg_replace('#onclick=([\'"]).*?(?<!\\\)\\1#i', '', $matches[4]); //Strip out any onclicks from rest of <a>. (?<!\\\) means to ignore the '" if its escaped by \  to prevent breaking mid-attribute. 
    1219     if ( 
    1220         ( false !== strpos($matches[3], '/wp-admin/') ) 
    1221     || 
    1222         ( false !== strpos( $matches[3], '://' ) && 0 !== strpos( $matches[3], home_url() ) ) 
    1223     || 
    1224         ( false !== strpos($matches[3], '/feed/') ) 
    1225     || 
    1226         ( false !== strpos($matches[3], '/trackback/') ) 
    1227     ) 
    1228         return $matches[1] . "#$matches[2] onclick=$matches[2]return false;" . $matches[4]; 
    1229  
    1230     $link = add_query_arg( array( 'preview' => 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'], 'preview_iframe' => 1 ), $matches[3] ); 
    1231     if ( 0 === strpos($link, 'preview=1') ) 
    1232         $link = "?$link"; 
    1233     return $matches[1] . esc_attr( $link ) . $matches[4]; 
    1234 } 
    1235  
    1236 /** 
    1237  * Switches current theme to new template and stylesheet names. 
    1238  * 
    1239  * @since 2.5.0 
    1240  * @uses do_action() Calls 'switch_theme' action on updated theme display name. 
    1241  * 
    1242  * @param string $template Template name 
    1243  * @param string $stylesheet Stylesheet name. 
    1244  */ 
    1245 function switch_theme($template, $stylesheet) { 
    1246     global $wp_theme_directories, $sidebars_widgets; 
    1247  
    1248     if ( is_array( $sidebars_widgets ) ) 
    1249         set_theme_mod( 'sidebars_widgets', array( 'time' => time(), 'data' => $sidebars_widgets ) ); 
    1250  
    1251     $old_theme = get_current_theme(); 
    1252  
    1253     update_option('template', $template); 
    1254     update_option('stylesheet', $stylesheet); 
    1255  
    1256     if ( count($wp_theme_directories) > 1 ) { 
    1257         update_option('template_root', get_raw_theme_root($template, true)); 
    1258         update_option('stylesheet_root', get_raw_theme_root($stylesheet, true)); 
    1259     } 
    1260  
    1261     delete_option('current_theme'); 
    1262     $theme = get_current_theme(); 
    1263  
    1264     if ( is_admin() && false === get_option( "theme_mods_$stylesheet" ) ) { 
    1265         $default_theme_mods = (array) get_option( "mods_$theme" ); 
    1266         add_option( "theme_mods_$stylesheet", $default_theme_mods ); 
    1267     } 
    1268  
    1269     update_option( 'theme_switched', $old_theme ); 
    1270     do_action( 'switch_theme', $theme ); 
    1271 } 
    1272  
    1273 /** 
    1274  * Checks that current theme files 'index.php' and 'style.css' exists. 
    1275  * 
    1276  * Does not check the default theme, which is the fallback and should always exist. 
    1277  * Will switch theme to the fallback theme if current theme does not validate. 
    1278  * You can use the 'validate_current_theme' filter to return false to 
    1279  * disable this functionality. 
    1280  * 
    1281  * @since 1.5.0 
    1282  * @see WP_DEFAULT_THEME 
    1283  * 
    1284  * @return bool 
    1285  */ 
    1286 function validate_current_theme() { 
    1287     // Don't validate during an install/upgrade. 
    1288     if ( defined('WP_INSTALLING') || !apply_filters( 'validate_current_theme', true ) ) 
    1289         return true; 
    1290  
    1291     if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { 
    1292         switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); 
    1293         return false; 
    1294     } 
    1295  
    1296     if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { 
    1297         switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); 
    1298         return false; 
    1299     } 
    1300  
    1301     if ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { 
    1302         switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); 
    1303         return false; 
    1304     } 
    1305  
    1306     return true; 
    1307 } 
    1308  
    1309 /** 
    1310  * Retrieve all theme modifications. 
    1311  * 
    1312  * @since 3.1.0 
    1313  * 
    1314  * @return array Theme modifications. 
    1315  */ 
    1316 function get_theme_mods() { 
    1317     $theme_slug = get_option( 'stylesheet' ); 
    1318     if ( false === ( $mods = get_option( "theme_mods_$theme_slug" ) ) ) { 
    1319         $theme_name = get_current_theme(); 
    1320         $mods = get_option( "mods_$theme_name" ); // Deprecated location. 
    1321         if ( is_admin() && false !== $mods ) { 
    1322             update_option( "theme_mods_$theme_slug", $mods ); 
    1323             delete_option( "mods_$theme_name" ); 
    1324         } 
    1325     } 
    1326     return $mods; 
    1327 } 
    1328  
    1329 /** 
    1330  * Retrieve theme modification value for the current theme. 
    1331  * 
    1332  * If the modification name does not exist, then the $default will be passed 
    1333  * through {@link http://php.net/sprintf sprintf()} PHP function with the first 
    1334  * string the template directory URI and the second string the stylesheet 
    1335  * directory URI. 
    1336  * 
    1337  * @since 2.1.0 
    1338  * @uses apply_filters() Calls 'theme_mod_$name' filter on the value. 
    1339  * 
    1340  * @param string $name Theme modification name. 
    1341  * @param bool|string $default 
    1342  * @return string 
    1343  */ 
    1344 function get_theme_mod( $name, $default = false ) { 
    1345     $mods = get_theme_mods(); 
    1346  
    1347     if ( isset( $mods[ $name ] ) ) 
    1348         return apply_filters( "theme_mod_$name", $mods[ $name ] ); 
    1349  
    1350     if ( is_string( $default ) ) 
    1351         $default = sprintf( $default, get_template_directory_uri(), get_stylesheet_directory_uri() ); 
    1352  
    1353     return apply_filters( "theme_mod_$name", $default ); 
    1354 } 
    1355  
    1356 /** 
    1357  * Update theme modification value for the current theme. 
    1358  * 
    1359  * @since 2.1.0 
    1360  * 
    1361  * @param string $name Theme modification name. 
    1362  * @param string $value theme modification value. 
    1363  */ 
    1364 function set_theme_mod( $name, $value ) { 
    1365     $mods = get_theme_mods(); 
    1366  
    1367     $mods[ $name ] = $value; 
    1368  
    1369     $theme = get_option( 'stylesheet' ); 
    1370     update_option( "theme_mods_$theme", $mods ); 
    1371 } 
    1372  
    1373 /** 
    1374  * Remove theme modification name from current theme list. 
    1375  * 
    1376  * If removing the name also removes all elements, then the entire option will 
    1377  * be removed. 
    1378  * 
    1379  * @since 2.1.0 
    1380  * 
    1381  * @param string $name Theme modification name. 
    1382  * @return null 
    1383  */ 
    1384 function remove_theme_mod( $name ) { 
    1385     $mods = get_theme_mods(); 
    1386  
    1387     if ( ! isset( $mods[ $name ] ) ) 
    1388         return; 
    1389  
    1390     unset( $mods[ $name ] ); 
    1391  
    1392     if ( empty( $mods ) ) 
    1393         return remove_theme_mods(); 
    1394  
    1395     $theme = get_option( 'stylesheet' ); 
    1396     update_option( "theme_mods_$theme", $mods ); 
    1397 } 
    1398  
    1399 /** 
    1400  * Remove theme modifications option for current theme. 
    1401  * 
    1402  * @since 2.1.0 
    1403  */ 
    1404 function remove_theme_mods() { 
    1405     delete_option( 'theme_mods_' . get_option( 'stylesheet' ) ); 
    1406     delete_option( 'mods_' . get_current_theme() ); 
    1407 } 
    1408  
    1409 /** 
    1410  * Retrieve text color for custom header. 
    1411  * 
    1412  * @since 2.1.0 
    1413  * @uses HEADER_TEXTCOLOR 
    1414  * 
    1415  * @return string 
    1416  */ 
    1417 function get_header_textcolor() { 
    1418     $default = defined('HEADER_TEXTCOLOR') ? HEADER_TEXTCOLOR : ''; 
    1419  
    1420     return get_theme_mod('header_textcolor', $default); 
    1421 } 
    1422  
    1423 /** 
    1424  * Display text color for custom header. 
    1425  * 
    1426  * @since 2.1.0 
    1427  */ 
    1428 function header_textcolor() { 
    1429     echo get_header_textcolor(); 
    1430 } 
    1431  
    1432 /** 
    1433  * Retrieve header image for custom header. 
    1434  * 
    1435  * @since 2.1.0 
    1436  * @uses HEADER_IMAGE 
    1437  * 
    1438  * @return string 
    1439  */ 
    1440 function get_header_image() { 
    1441     $default = defined( 'HEADER_IMAGE' ) ? HEADER_IMAGE : ''; 
    1442     $url = get_theme_mod( 'header_image', $default ); 
    1443  
    1444     if ( 'remove-header' == $url ) 
    1445         return false; 
    1446  
    1447     if ( is_random_header_image() ) 
    1448         $url = get_random_header_image(); 
    1449  
    1450     if ( is_ssl() ) 
    1451         $url = str_replace( 'http://', 'https://', $url ); 
    1452     else 
    1453         $url = str_replace( 'https://', 'http://', $url ); 
    1454  
    1455     return esc_url_raw( $url ); 
    1456 } 
    1457  
    1458 /** 
    1459  * Get random header image data from registered images in theme. 
    1460  * 
    1461  * @since 3.4.0 
    1462  * 
    1463  * @access private 
    1464  * 
    1465  * @return string Path to header image 
    1466  */ 
    1467  
    1468 function _get_random_header_data() { 
    1469     static $_wp_random_header; 
    1470  
    1471     if ( empty( $_wp_random_header ) ) { 
    1472         global $_wp_default_headers; 
    1473         $header_image_mod = get_theme_mod( 'header_image', '' ); 
    1474         $headers = array(); 
    1475  
    1476         if ( 'random-uploaded-image' == $header_image_mod ) 
    1477             $headers = get_uploaded_header_images(); 
    1478         elseif ( ! empty( $_wp_default_headers ) ) { 
    1479             if ( 'random-default-image' == $header_image_mod ) { 
    1480                 $headers = $_wp_default_headers; 
    1481             } else { 
    1482                 $is_random = get_theme_support( 'custom-header' ); 
    1483                 if ( isset( $is_random[ 0 ] ) && !empty( $is_random[ 0 ][ 'random-default' ] ) ) 
    1484                     $headers = $_wp_default_headers; 
    1485             } 
    1486         } 
    1487  
    1488         if ( empty( $headers ) ) 
    1489             return new stdClass; 
    1490  
    1491         $_wp_random_header = (object) $headers[ array_rand( $headers ) ]; 
    1492  
    1493         $_wp_random_header->url =  sprintf( $_wp_random_header->url, get_template_directory_uri(), get_stylesheet_directory_uri() ); 
    1494         $_wp_random_header->thumbnail_url =  sprintf( $_wp_random_header->thumbnail_url, get_template_directory_uri(), get_stylesheet_directory_uri() ); 
    1495     } 
    1496     return $_wp_random_header; 
    1497 } 
    1498  
    1499 /** 
    1500  * Get random header image url from registered images in theme. 
    1501  * 
    1502  * @since 3.2.0 
    1503  * 
    1504  * @return string Path to header image 
    1505  */ 
    1506  
    1507 function get_random_header_image() { 
    1508     $random_image = _get_random_header_data(); 
    1509     if ( empty( $random_image->url ) ) 
    1510         return ''; 
    1511     return $random_image->url; 
    1512 } 
    1513  
    1514 /** 
    1515  * Check if random header image is in use. 
    1516  * 
    1517  * Always true if user expressly chooses the option in Appearance > Header. 
    1518  * Also true if theme has multiple header images registered, no specific header image 
    1519  * is chosen, and theme turns on random headers with add_theme_support(). 
    1520  * 
    1521  * @since 3.2.0 
    1522  * @uses HEADER_IMAGE 
    1523  * 
    1524  * @param string $type The random pool to use. any|default|uploaded 
    1525  * @return boolean 
    1526  */ 
    1527 function is_random_header_image( $type = 'any' ) { 
    1528     $default = defined( 'HEADER_IMAGE' ) ? HEADER_IMAGE : ''; 
    1529     $header_image_mod = get_theme_mod( 'header_image', $default ); 
    1530  
    1531     if ( 'any' == $type ) { 
    1532         if ( 'random-default-image' == $header_image_mod || 'random-uploaded-image' == $header_image_mod || ( '' != get_random_header_image() && empty( $header_image_mod ) ) ) 
    1533             return true; 
    1534     } else { 
    1535         if ( "random-$type-image" == $header_image_mod ) 
    1536             return true; 
    1537         elseif ( 'default' == $type && empty( $header_image_mod ) && '' != get_random_header_image() ) 
    1538             return true; 
    1539     } 
    1540  
    1541     return false; 
    1542 } 
    1543  
    1544 /** 
    1545  * Display header image path. 
    1546  * 
    1547  * @since 2.1.0 
    1548  */ 
    1549 function header_image() { 
    1550     echo get_header_image(); 
    1551 } 
    1552  
    1553 /** 
    1554  * Get the header images uploaded for the current theme. 
    1555  * 
    1556  * @since 3.2.0 
    1557  * 
    1558  * @return array 
    1559  */ 
    1560 function get_uploaded_header_images() { 
    1561     $header_images = array(); 
    1562  
    1563     // @todo caching 
    1564     $headers = get_posts( array( 'post_type' => 'attachment', 'meta_key' => '_wp_attachment_is_custom_header', 'meta_value' => get_option('stylesheet'), 'orderby' => 'none', 'nopaging' => true ) ); 
    1565  
    1566     if ( empty( $headers ) ) 
    1567         return array(); 
    1568  
    1569     foreach ( (array) $headers as $header ) { 
    1570         $url = esc_url_raw( $header->guid ); 
    1571         $header_data = wp_get_attachment_metadata( $header->ID ); 
    1572         $header_index = basename($url); 
    1573         $header_images[$header_index] = array(); 
    1574         $header_images[$header_index]['attachment_id'] =  $header->ID; 
    1575         $header_images[$header_index]['url'] =  $url; 
    1576         $header_images[$header_index]['thumbnail_url'] =  $url; 
    1577         $header_images[$header_index]['width'] = $header_data['width']; 
    1578         $header_images[$header_index]['height'] = $header_data['height']; 
    1579     } 
    1580  
    1581     return $header_images; 
    1582 } 
    1583  
    1584 /** 
    1585  * Get the header image data. 
    1586  * 
    1587  * @since 3.4.0 
    1588  * 
    1589  * @return object 
    1590  */ 
    1591 function get_current_header_data() { 
    1592     $data = is_random_header_image()? _get_random_header_data() : get_theme_mod( 'header_image_data' ); 
    1593     $default = array( 
    1594         'url'           => '', 
    1595         'thumbnail_url' => '', 
    1596         'width'         => '', 
    1597         'height'        => '', 
    1598     ); 
    1599     return (object) wp_parse_args( $data, $default ); 
    1600 } 
    1601  
    1602 /** 
    1603  * Get the header image width. 
    1604  * 
    1605  * @since 3.4.0 
    1606  * 
    1607  * @return int 
    1608  */ 
    1609 function get_header_image_width() { 
    1610     return empty( get_current_header_data()->width )? HEADER_IMAGE_WIDTH : get_current_header_data()->width; 
    1611 } 
    1612  
    1613 /** 
    1614  * Get the header image height. 
    1615  * 
    1616  * @since 3.4.0 
    1617  * 
    1618  * @return int 
    1619  */ 
    1620 function get_header_image_height() { 
    1621     return empty( get_current_header_data()->height )? HEADER_IMAGE_HEIGHT : get_current_header_data()->height; 
    1622 } 
    1623  
    1624 /** 
    1625  * Add callbacks for image header display. 
    1626  * 
    1627  * The parameter $header_callback callback will be required to display the 
    1628  * content for the 'wp_head' action. The parameter $admin_header_callback 
    1629  * callback will be added to Custom_Image_Header class and that will be added 
    1630  * to the 'admin_menu' action. 
    1631  * 
    1632  * @since 2.1.0 
    1633  * @uses Custom_Image_Header Sets up for $admin_header_callback for administration panel display. 
    1634  * 
    1635  * @param callback $header_callback Call on 'wp_head' action. 
    1636  * @param callback $admin_header_callback Call on custom header administration screen. 
    1637  * @param callback $admin_image_div_callback Output a custom header image div on the custom header administration screen. Optional. 
    1638  */ 
    1639 function add_custom_image_header( $header_callback, $admin_header_callback, $admin_image_div_callback = '' ) { 
    1640     if ( ! empty( $header_callback ) ) 
    1641         add_action('wp_head', $header_callback); 
    1642  
    1643     $support = array( 'callback' => $header_callback ); 
    1644     $theme_support = get_theme_support( 'custom-header' ); 
    1645     if ( ! empty( $theme_support ) && is_array( $theme_support[ 0 ] ) ) 
    1646         $support = array_merge( $theme_support[ 0 ], $support ); 
    1647     add_theme_support( 'custom-header',  $support ); 
    1648     add_theme_support( 'custom-header-uploads' ); 
    1649  
    1650     if ( ! is_admin() ) 
    1651         return; 
    1652  
    1653     global $custom_image_header; 
    1654  
    1655     require_once( ABSPATH . 'wp-admin/custom-header.php' ); 
    1656     $custom_image_header = new Custom_Image_Header( $admin_header_callback, $admin_image_div_callback ); 
    1657     add_action( 'admin_menu', array( &$custom_image_header, 'init' ) ); 
    1658 } 
    1659  
    1660 /** 
    1661  * Remove image header support. 
    1662  * 
    1663  * @since 3.1.0 
    1664  * @see add_custom_image_header() 
    1665  * 
    1666  * @return bool Whether support was removed. 
    1667  */ 
    1668 function remove_custom_image_header() { 
    1669     if ( ! current_theme_supports( 'custom-header' ) ) 
    1670         return false; 
    1671  
    1672     $callback = get_theme_support( 'custom-header' ); 
    1673     remove_action( 'wp_head', $callback[0]['callback'] ); 
    1674     _remove_theme_support( 'custom-header' ); 
    1675     remove_theme_support( 'custom-header-uploads' ); 
    1676  
    1677     if ( is_admin() ) { 
    1678         remove_action( 'admin_menu', array( &$GLOBALS['custom_image_header'], 'init' ) ); 
    1679         unset( $GLOBALS['custom_image_header'] ); 
    1680     } 
    1681  
    1682     return true; 
    1683 } 
    1684  
    1685 /** 
    1686  * Register a selection of default headers to be displayed by the custom header admin UI. 
    1687  * 
    1688  * @since 3.0.0 
    1689  * 
    1690  * @param array $headers Array of headers keyed by a string id. The ids point to arrays containing 'url', 'thumbnail_url', and 'description' keys. 
    1691  */ 
    1692 function register_default_headers( $headers ) { 
    1693     global $_wp_default_headers; 
    1694  
    1695     $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); 
    1696 } 
    1697  
    1698 /** 
    1699  * Unregister default headers. 
    1700  * 
    1701  * This function must be called after register_default_headers() has already added the 
    1702  * header you want to remove. 
    1703  * 
    1704  * @see register_default_headers() 
    1705  * @since 3.0.0 
    1706  * 
    1707  * @param string|array $header The header string id (key of array) to remove, or an array thereof. 
    1708  * @return True on success, false on failure. 
    1709  */ 
    1710 function unregister_default_headers( $header ) { 
    1711     global $_wp_default_headers; 
    1712     if ( is_array( $header ) ) { 
    1713         array_map( 'unregister_default_headers', $header ); 
    1714     } elseif ( isset( $_wp_default_headers[ $header ] ) ) { 
    1715         unset( $_wp_default_headers[ $header ] ); 
    1716         return true; 
    1717     } else { 
    1718         return false; 
    1719     } 
    1720 } 
    1721  
    1722 /** 
    1723  * Retrieve background image for custom background. 
    1724  * 
    1725  * @since 3.0.0 
    1726  * 
    1727  * @return string 
    1728  */ 
    1729 function get_background_image() { 
    1730     $default = defined('BACKGROUND_IMAGE') ? BACKGROUND_IMAGE : ''; 
    1731  
    1732     return get_theme_mod('background_image', $default); 
    1733 } 
    1734  
    1735 /** 
    1736  * Display background image path. 
    1737  * 
    1738  * @since 3.0.0 
    1739  */ 
    1740 function background_image() { 
    1741     echo get_background_image(); 
    1742 } 
    1743  
    1744 /** 
    1745  * Retrieve value for custom background color. 
    1746  * 
    1747  * @since 3.0.0 
    1748  * @uses BACKGROUND_COLOR 
    1749  * 
    1750  * @return string 
    1751  */ 
    1752 function get_background_color() { 
    1753     $default = defined('BACKGROUND_COLOR') ? BACKGROUND_COLOR : ''; 
    1754  
    1755     return get_theme_mod('background_color', $default); 
    1756 } 
    1757  
    1758 /** 
    1759  * Display background color value. 
    1760  * 
    1761  * @since 3.0.0 
    1762  */ 
    1763 function background_color() { 
    1764     echo get_background_color(); 
    1765 } 
    1766  
    1767 /** 
    1768  * Add callbacks for background image display. 
    1769  * 
    1770  * The parameter $header_callback callback will be required to display the 
    1771  * content for the 'wp_head' action. The parameter $admin_header_callback 
    1772  * callback will be added to Custom_Background class and that will be added 
    1773  * to the 'admin_menu' action. 
    1774  * 
    1775  * @since 3.0.0 
    1776  * @uses Custom_Background Sets up for $admin_header_callback for administration panel display. 
    1777  * 
    1778  * @param callback $header_callback Call on 'wp_head' action. 
    1779  * @param callback $admin_header_callback Call on custom background administration screen. 
    1780  * @param callback $admin_image_div_callback Output a custom background image div on the custom background administration screen. Optional. 
    1781  */ 
    1782 function add_custom_background( $header_callback = '', $admin_header_callback = '', $admin_image_div_callback = '' ) { 
    1783     if ( isset( $GLOBALS['custom_background'] ) ) 
    1784         return; 
    1785  
    1786     if ( empty( $header_callback ) ) 
    1787         $header_callback = '_custom_background_cb'; 
    1788  
    1789     add_action( 'wp_head', $header_callback ); 
    1790  
    1791     add_theme_support( 'custom-background', array( 'callback' => $header_callback ) ); 
    1792  
    1793     if ( ! is_admin() ) 
    1794         return; 
    1795     require_once( ABSPATH . 'wp-admin/custom-background.php' ); 
    1796     $GLOBALS['custom_background'] = new Custom_Background( $admin_header_callback, $admin_image_div_callback ); 
    1797     add_action( 'admin_menu', array( &$GLOBALS['custom_background'], 'init' ) ); 
    1798 } 
    1799  
    1800 /** 
    1801  * Remove custom background support. 
    1802  * 
    1803  * @since 3.1.0 
    1804  * @see add_custom_background() 
    1805  * 
    1806  * @return bool Whether support was removed. 
    1807  */ 
    1808 function remove_custom_background() { 
    1809     if ( ! current_theme_supports( 'custom-background' ) ) 
    1810         return false; 
    1811  
    1812     $callback = get_theme_support( 'custom-background' ); 
    1813     remove_action( 'wp_head', $callback[0]['callback'] ); 
    1814     _remove_theme_support( 'custom-background' ); 
    1815  
    1816     if ( is_admin() ) { 
    1817         remove_action( 'admin_menu', array( &$GLOBALS['custom_background'], 'init' ) ); 
    1818         unset( $GLOBALS['custom_background'] ); 
    1819     } 
    1820  
    1821     return true; 
    1822 } 
    1823  
    1824 /** 
    1825  * Default custom background callback. 
    1826  * 
    1827  * @since 3.0.0 
    1828  * @see add_custom_background() 
    1829  * @access protected 
    1830  */ 
    1831 function _custom_background_cb() { 
    1832     $background = get_background_image(); 
    1833     $color = get_background_color(); 
    1834     if ( ! $background && ! $color ) 
    1835         return; 
    1836  
    1837     $style = $color ? "background-color: #$color;" : ''; 
    1838  
    1839     if ( $background ) { 
    1840         $image = " background-image: url('$background');"; 
    1841  
    1842         $repeat = get_theme_mod( 'background_repeat', 'repeat' ); 
    1843         if ( ! in_array( $repeat, array( 'no-repeat', 'repeat-x', 'repeat-y', 'repeat' ) ) ) 
    1844             $repeat = 'repeat'; 
    1845         $repeat = " background-repeat: $repeat;"; 
    1846  
    1847         $position = get_theme_mod( 'background_position_x', 'left' ); 
    1848         if ( ! in_array( $position, array( 'center', 'right', 'left' ) ) ) 
    1849             $position = 'left'; 
    1850         $position = " background-position: top $position;"; 
    1851  
    1852         $attachment = get_theme_mod( 'background_attachment', 'scroll' ); 
    1853         if ( ! in_array( $attachment, array( 'fixed', 'scroll' ) ) ) 
    1854             $attachment = 'scroll'; 
    1855         $attachment = " background-attachment: $attachment;"; 
    1856  
    1857         $style .= $image . $repeat . $position . $attachment; 
    1858     } 
    1859 ?> 
    1860 <style type="text/css"> 
    1861 body.custom-background { <?php echo trim( $style ); ?> } 
    1862 </style> 
    1863 <?php 
    1864 } 
    1865  
    1866 /** 
    1867  * Add callback for custom TinyMCE editor stylesheets. 
    1868  * 
    1869  * The parameter $stylesheet is the name of the stylesheet, relative to 
    1870  * the theme root. It also accepts an array of stylesheets. 
    1871  * It is optional and defaults to 'editor-style.css'. 
    1872  * 
    1873  * Supports RTL stylesheets automatically by searching for the -rtl prefix, e.g. 
    1874  * editor-style-rtl.css. If an array of stylesheets is passed to add_editor_style(), 
    1875  * RTL is only added for the first stylesheet. 
    1876  * 
    1877  * @since 3.0.0 
    1878  * 
    1879  * @param mixed $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. 
    1880  *  Defaults to 'editor-style.css' 
    1881  */ 
    1882 function add_editor_style( $stylesheet = 'editor-style.css' ) { 
    1883  
    1884     add_theme_support( 'editor-style' ); 
    1885  
    1886     if ( ! is_admin() ) 
    1887         return; 
    1888  
    1889     global $editor_styles; 
    1890     $editor_styles = (array) $editor_styles; 
    1891     $stylesheet    = (array) $stylesheet; 
    1892     if ( is_rtl() ) { 
    1893         $rtl_stylesheet = str_replace('.css', '-rtl.css', $stylesheet[0]); 
    1894         $stylesheet[] = $rtl_stylesheet; 
    1895     } 
    1896  
    1897     $editor_styles = array_merge( $editor_styles, $stylesheet ); 
    1898 } 
    1899  
    1900 /** 
    1901  * Removes all visual editor stylesheets. 
    1902  * 
    1903  * @since 3.1.0 
    1904  * 
    1905  * @return bool True on success, false if there were no stylesheets to remove. 
    1906  */ 
    1907 function remove_editor_styles() { 
    1908     if ( ! current_theme_supports( 'editor-style' ) ) 
    1909         return false; 
    1910     _remove_theme_support( 'editor-style' ); 
    1911     if ( is_admin() ) 
    1912         $GLOBALS['editor_styles'] = array(); 
    1913     return true; 
    1914 } 
    1915  
    1916 /** 
    1917  * Allows a theme to register its support of a certain feature 
    1918  * 
    1919  * Must be called in the theme's functions.php file to work. 
    1920  * If attached to a hook, it must be after_setup_theme. 
    1921  * The init hook may be too late for some features. 
    1922  * 
    1923  * @since 2.9.0 
    1924  * @param string $feature the feature being added 
    1925  */ 
    1926 function add_theme_support( $feature ) { 
    1927     global $_wp_theme_features; 
    1928  
    1929     if ( func_num_args() == 1 ) 
    1930         $_wp_theme_features[$feature] = true; 
    1931     else 
    1932         $_wp_theme_features[$feature] = array_slice( func_get_args(), 1 ); 
    1933  
    1934     if ( $feature == 'post-formats' && is_array( $_wp_theme_features[$feature][0] ) ) 
    1935         $_wp_theme_features[$feature][0] = array_intersect( $_wp_theme_features[$feature][0], array_keys( get_post_format_slugs() ) ); 
    1936 } 
    1937  
    1938 /** 
    1939  * Gets the theme support arguments passed when registering that support 
    1940  * 
    1941  * @since 3.1 
    1942  * @param string $feature the feature to check 
    1943  * @return array The array of extra arguments 
    1944  */ 
    1945 function get_theme_support( $feature ) { 
    1946     global $_wp_theme_features; 
    1947     if ( !isset( $_wp_theme_features[$feature] ) ) 
    1948         return false; 
    1949     else 
    1950         return $_wp_theme_features[$feature]; 
    1951 } 
    1952  
    1953 /** 
    1954  * Allows a theme to de-register its support of a certain feature 
    1955  * 
    1956  * Should be called in the theme's functions.php file. Generally would 
    1957  * be used for child themes to override support from the parent theme. 
    1958  * 
    1959  * @since 3.0.0 
    1960  * @see add_theme_support() 
    1961  * @param string $feature the feature being added 
    1962  * @return bool Whether feature was removed. 
    1963  */ 
    1964 function remove_theme_support( $feature ) { 
    1965     // Blacklist: for internal registrations not used directly by themes. 
    1966     if ( in_array( $feature, array( 'custom-background', 'custom-header', 'editor-style', 'widgets', 'menus' ) ) ) 
    1967         return false; 
    1968     return _remove_theme_support( $feature ); 
    1969 } 
    1970  
    1971 /** 
    1972  * Do not use. Removes theme support internally, ignorant of the blacklist. 
    1973  * 
    1974  * @access private 
    1975  * @since 3.1.0 
    1976  */ 
    1977 function _remove_theme_support( $feature ) { 
    1978     global $_wp_theme_features; 
    1979  
    1980     if ( ! isset( $_wp_theme_features[$feature] ) ) 
    1981         return false; 
    1982     unset( $_wp_theme_features[$feature] ); 
    1983     return true; 
    1984 } 
    1985  
    1986 /** 
    1987  * Checks a theme's support for a given feature 
    1988  * 
    1989  * @since 2.9.0 
    1990  * @param string $feature the feature being checked 
    1991  * @return boolean 
    1992  */ 
    1993 function current_theme_supports( $feature ) { 
    1994     global $_wp_theme_features; 
    1995  
    1996     if ( !isset( $_wp_theme_features[$feature] ) ) 
    1997         return false; 
    1998  
    1999     // If no args passed then no extra checks need be performed 
    2000     if ( func_num_args() <= 1 ) 
    2001         return true; 
    2002  
    2003     $args = array_slice( func_get_args(), 1 ); 
    2004  
    2005     switch ( $feature ) { 
    2006         case 'post-thumbnails': 
    2007             // post-thumbnails can be registered for only certain content/post types by passing 
    2008             // an array of types to add_theme_support(). If no array was passed, then 
    2009             // any type is accepted 
    2010             if ( true === $_wp_theme_features[$feature] )  // Registered for all types 
    2011                 return true; 
    2012             $content_type = $args[0]; 
    2013             return in_array( $content_type, $_wp_theme_features[$feature][0] ); 
    2014             break; 
    2015  
    2016         case 'post-formats': 
    2017             // specific post formats can be registered by passing an array of types to 
    2018             // add_theme_support() 
    2019             $post_format = $args[0]; 
    2020             return in_array( $post_format, $_wp_theme_features[$feature][0] ); 
    2021             break; 
    2022  
    2023         case 'custom-header': 
    2024             // specific custom header capabilities can be registered by passing 
    2025             // an array to add_theme_support() 
    2026             $header_support = $args[0]; 
    2027             return ( isset( $_wp_theme_features[$feature][0][$header_support] ) && $_wp_theme_features[$feature][0][$header_support] ); 
    2028             break; 
    2029     } 
    2030  
    2031     return apply_filters('current_theme_supports-' . $feature, true, $args, $_wp_theme_features[$feature]); 
    2032 } 
    2033  
    2034 /** 
    2035  * Checks a theme's support for a given feature before loading the functions which implement it. 
    2036  * 
    2037  * @since 2.9.0 
    2038  * @param string $feature the feature being checked 
    2039  * @param string $include the file containing the functions that implement the feature 
    2040  */ 
    2041 function require_if_theme_supports( $feature, $include) { 
    2042     if ( current_theme_supports( $feature ) ) 
    2043         require ( $include ); 
    2044 } 
    2045  
    2046 /** 
    2047  * Checks an attachment being deleted to see if it's a header or background image. 
    2048  * 
    2049  * If true it removes the theme modification which would be pointing at the deleted 
    2050  * attachment 
    2051  * 
    2052  * @access private 
    2053  * @since 3.0.0 
    2054  * @param int $id the attachment id 
    2055  */ 
    2056 function _delete_attachment_theme_mod( $id ) { 
    2057     $attachment_image = wp_get_attachment_url( $id ); 
    2058     $header_image = get_header_image(); 
    2059     $background_image = get_background_image(); 
    2060  
    2061     if ( $header_image && $header_image == $attachment_image ) 
    2062         remove_theme_mod( 'header_image' ); 
    2063  
    2064     if ( $background_image && $background_image == $attachment_image ) 
    2065         remove_theme_mod( 'background_image' ); 
    2066 } 
    2067  
    2068 add_action( 'delete_attachment', '_delete_attachment_theme_mod' ); 
    2069  
    2070 /** 
    2071  * Checks if a theme has been changed and runs 'after_switch_theme' hook on the next WP load 
    2072  * 
    2073  * @since 3.3.0 
    2074  */ 
    2075 function check_theme_switched() { 
    2076     if ( false !== ( $old_theme = get_option( 'theme_switched' ) ) && !empty( $old_theme ) ) { 
    2077         do_action( 'after_switch_theme', $old_theme ); 
    2078         update_option( 'theme_switched', false ); 
    2079     } 
    2080 } 
    2081  
    2082 function wp_customize_load() { 
    2083     // Load on themes.php or ?customize=on 
    2084     if ( ! ( isset( $_REQUEST['customize'] ) && 'on' == $_REQUEST['customize'] ) && 'themes.php' != $GLOBALS['pagenow'] ) 
    2085         return; 
    2086  
    2087     require( ABSPATH . WPINC . '/class-wp-customize.php' ); 
    2088     // Init Customize class 
    2089     // @todo Dependency injection instead 
    2090     $GLOBALS['customize'] = new WP_Customize; 
    2091 } 
    2092 add_action( 'plugins_loaded', 'wp_customize_load' ); 
  • trunk/wp-includes/theme.php

    r20001 r20002  
    44 * 
    55 * @package WordPress 
    6  * @subpackage Template 
     6 * @subpackage Theme 
    77 */ 
    88 
     
    726726 
    727727/** 
    728  * Retrieve path to a template 
    729  * 
    730  * Used to quickly retrieve the path of a template without including the file 
    731  * extension. It will also check the parent theme, if the file exists, with 
    732  * the use of {@link locate_template()}. Allows for more generic template location 
    733  * without the use of the other get_*_template() functions. 
    734  * 
    735  * @since 1.5.0 
    736  * 
    737  * @param string $type Filename without extension. 
    738  * @param array $templates An optional list of template candidates 
    739  * @return string Full path to file. 
    740  */ 
    741 function get_query_template( $type, $templates = array() ) { 
    742     $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); 
    743  
    744     if ( empty( $templates ) ) 
    745         $templates = array("{$type}.php"); 
    746  
    747     return apply_filters( "{$type}_template", locate_template( $templates ) ); 
    748 } 
    749  
    750 /** 
    751  * Retrieve path of index template in current or parent template. 
    752  * 
    753  * @since 3.0.0 
    754  * 
    755  * @return string 
    756  */ 
    757 function get_index_template() { 
    758     return get_query_template('index'); 
    759 } 
    760  
    761 /** 
    762  * Retrieve path of 404 template in current or parent template. 
    763  * 
    764  * @since 1.5.0 
    765  * 
    766  * @return string 
    767  */ 
    768 function get_404_template() { 
    769     return get_query_template('404'); 
    770 } 
    771  
    772 /** 
    773  * Retrieve path of archive template in current or parent template. 
    774  * 
    775  * @since 1.5.0 
    776  * 
    777  * @return string 
    778  */ 
    779 function get_archive_template() { 
    780     $post_type = get_query_var( 'post_type' ); 
    781  
    782     $templates = array(); 
    783  
    784     if ( $post_type ) 
    785         $templates[] = "archive-{$post_type}.php"; 
    786     $templates[] = 'archive.php'; 
    787  
    788     return get_query_template( 'archive', $templates ); 
    789 } 
    790  
    791 /** 
    792  * Retrieve path of author template in current or parent template. 
    793  * 
    794  * @since 1.5.0 
    795  * 
    796  * @return string 
    797  */ 
    798 function get_author_template() { 
    799     $author = get_queried_object(); 
    800  
    801     $templates = array(); 
    802  
    803     $templates[] = "author-{$author->user_nicename}.php"; 
    804     $templates[] = "author-{$author->ID}.php"; 
    805     $templates[] = 'author.php'; 
    806  
    807     return get_query_template( 'author', $templates ); 
    808 } 
    809  
    810 /** 
    811  * Retrieve path of category template in current or parent template. 
    812  * 
    813  * Works by first retrieving the current slug for example 'category-default.php' and then 
    814  * trying category ID, for example 'category-1.php' and will finally fallback to category.php 
    815  * template, if those files don't exist. 
    816  * 
    817  * @since 1.5.0 
    818  * @uses apply_filters() Calls 'category_template' on file path of category template. 
    819  * 
    820  * @return string 
    821  */ 
    822 function get_category_template() { 
    823     $category = get_queried_object(); 
    824  
    825     $templates = array(); 
    826  
    827     $templates[] = "category-{$category->slug}.php"; 
    828     $templates[] = "category-{$category->term_id}.php"; 
    829     $templates[] = 'category.php'; 
    830  
    831     return get_query_template( 'category', $templates ); 
    832 } 
    833  
    834 /** 
    835  * Retrieve path of tag template in current or parent template. 
    836  * 
    837  * Works by first retrieving the current tag name, for example 'tag-wordpress.php' and then 
    838  * trying tag ID, for example 'tag-1.php' and will finally fallback to tag.php 
    839  * template, if those files don't exist. 
    840  * 
    841  * @since 2.3.0 
    842  * @uses apply_filters() Calls 'tag_template' on file path of tag template. 
    843  * 
    844  * @return string 
    845  */ 
    846 function get_tag_template() { 
    847     $tag = get_queried_object(); 
    848  
    849     $templates = array(); 
    850  
    851     $templates[] = "tag-{$tag->slug}.php"; 
    852     $templates[] = "tag-{$tag->term_id}.php"; 
    853     $templates[] = 'tag.php'; 
    854  
    855     return get_query_template( 'tag', $templates ); 
    856 } 
    857  
    858 /** 
    859  * Retrieve path of taxonomy template in current or parent template. 
    860  * 
    861  * Retrieves the taxonomy and term, if term is available. The template is 
    862  * prepended with 'taxonomy-' and followed by both the taxonomy string and 
    863  * the taxonomy string followed by a dash and then followed by the term. 
    864  * 
    865  * The taxonomy and term template is checked and used first, if it exists. 
    866  * Second, just the taxonomy template is checked, and then finally, taxonomy.php 
    867  * template is used. If none of the files exist, then it will fall back on to 
    868  * index.php. 
    869  * 
    870  * @since 2.5.0 
    871  * @uses apply_filters() Calls 'taxonomy_template' filter on found path. 
    872  * 
    873  * @return string 
    874  */ 
    875 function get_taxonomy_template() { 
    876     $term = get_queried_object(); 
    877     $taxonomy = $term->taxonomy; 
    878  
    879     $templates = array(); 
    880  
    881     $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; 
    882     $templates[] = "taxonomy-$taxonomy.php"; 
    883     $templates[] = 'taxonomy.php'; 
    884  
    885     return get_query_template( 'taxonomy', $templates ); 
    886 } 
    887  
    888 /** 
    889  * Retrieve path of date template in current or parent template. 
    890  * 
    891  * @since 1.5.0 
    892  * 
    893  * @return string 
    894  */ 
    895 function get_date_template() { 
    896     return get_query_template('date'); 
    897 } 
    898  
    899 /** 
    900  * Retrieve path of home template in current or parent template. 
    901  * 
    902  * This is the template used for the page containing the blog posts 
    903  * 
    904  * Attempts to locate 'home.php' first before falling back to 'index.php'. 
    905  * 
    906  * @since 1.5.0 
    907  * @uses apply_filters() Calls 'home_template' on file path of home template. 
    908  * 
    909  * @return string 
    910  */ 
    911 function get_home_template() { 
    912     $templates = array( 'home.php', 'index.php' ); 
    913  
    914     return get_query_template( 'home', $templates ); 
    915 } 
    916  
    917 /** 
    918  * Retrieve path of front-page template in current or parent template. 
    919  * 
    920  * Looks for 'front-page.php'. 
    921  * 
    922  * @since 3.0.0 
    923  * @uses apply_filters() Calls 'front_page_template' on file path of template. 
    924  * 
    925  * @return string 
    926  */ 
    927 function get_front_page_template() { 
    928     $templates = array('front-page.php'); 
    929  
    930     return get_query_template( 'front_page', $templates ); 
    931 } 
    932  
    933 /** 
    934  * Retrieve path of page template in current or parent template. 
    935  * 
    936  * Will first look for the specifically assigned page template 
    937  * The will search for 'page-{slug}.php' followed by 'page-id.php' 
    938  * and finally 'page.php' 
    939  * 
    940  * @since 1.5.0 
    941  * 
    942  * @return string 
    943  */ 
    944 function get_page_template() { 
    945     $id = get_queried_object_id(); 
    946     $template = get_post_meta($id, '_wp_page_template', true); 
    947     $pagename = get_query_var('pagename'); 
    948  
    949     if ( !$pagename && $id > 0 ) { 
    950         // If a static page is set as the front page, $pagename will not be set. Retrieve it from the queried object 
    951         $post = get_queried_object(); 
    952         $pagename = $post->post_name; 
    953     } 
    954  
    955     if ( 'default' == $template ) 
    956         $template = ''; 
    957  
    958     $templates = array(); 
    959     if ( !empty($template) && !validate_file($template) ) 
    960         $templates[] = $template; 
    961     if ( $pagename ) 
    962         $templates[] = "page-$pagename.php"; 
    963     if ( $id ) 
    964         $templates[] = "page-$id.php"; 
    965     $templates[] = 'page.php'; 
    966  
    967     return get_query_template( 'page', $templates ); 
    968 } 
    969  
    970 /** 
    971  * Retrieve path of paged template in current or parent template. 
    972  * 
    973  * @since 1.5.0 
    974  * 
    975  * @return string 
    976  */ 
    977 function get_paged_template() { 
    978     return get_query_template('paged'); 
    979 } 
    980  
    981 /** 
    982  * Retrieve path of search template in current or parent template. 
    983  * 
    984  * @since 1.5.0 
    985  * 
    986  * @return string 
    987  */ 
    988 function get_search_template() { 
    989     return get_query_template('search'); 
    990 } 
    991  
    992 /** 
    993  * Retrieve path of single template in current or parent template. 
    994  * 
    995  * @since 1.5.0 
    996  * 
    997  * @return string 
    998  */ 
    999 function get_single_template() { 
    1000     $object = get_queried_object(); 
    1001  
    1002     $templates = array(); 
    1003  
    1004     $templates[] = "single-{$object->post_type}.php"; 
    1005     $templates[] = "single.php"; 
    1006  
    1007     return get_query_template( 'single', $templates ); 
    1008 } 
    1009  
    1010 /** 
    1011  * Retrieve path of attachment template in current or parent template. 
    1012  * 
    1013  * The attachment path first checks if the first part of the mime type exists. 
    1014  * The second check is for the second part of the mime type. The last check is 
    1015  * for both types separated by an underscore. If neither are found then the file 
    1016  * 'attachment.php' is checked and returned. 
    1017  * 
    1018  * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and 
    1019  * finally 'text_plain.php'. 
    1020  * 
    1021  * @since 2.0.0 
    1022  * 
    1023  * @return string 
    1024  */ 
    1025 function get_attachment_template() { 
    1026     global $posts; 
    1027     $type = explode('/', $posts[0]->post_mime_type); 
    1028     if ( $template = get_query_template($type[0]) ) 
    1029         return $template; 
    1030     elseif ( $template = get_query_template($type[1]) ) 
    1031         return $template; 
    1032     elseif ( $template = get_query_template("$type[0]_$type[1]") ) 
    1033         return $template; 
    1034     else 
    1035         return get_query_template('attachment'); 
    1036 } 
    1037  
    1038 /** 
    1039  * Retrieve path of comment popup template in current or parent template. 
    1040  * 
    1041  * Checks for comment popup template in current template, if it exists or in the 
    1042  * parent template. 
    1043  * 
    1044  * @since 1.5.0 
    1045  * @uses apply_filters() Calls 'comments_popup_template' filter on path. 
    1046  * 
    1047  * @return string 
    1048  */ 
    1049 function get_comments_popup_template() { 
    1050     $template = get_query_template( 'comments_popup', array( 'comments-popup.php' ) ); 
    1051  
    1052     // Backward compat code will be removed in a future release 
    1053     if ('' == $template) 
    1054         $template = ABSPATH . WPINC . '/theme-compat/comments-popup.php'; 
    1055  
    1056     return $template; 
    1057 } 
    1058  
    1059 /** 
    1060  * Retrieve the name of the highest priority template file that exists. 
    1061  * 
    1062  * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which 
    1063  * inherit from a parent theme can just overload one file. 
    1064  * 
    1065  * @since 2.7.0 
    1066  * 
    1067  * @param string|array $template_names Template file(s) to search for, in order. 
    1068  * @param bool $load If true the template file will be loaded if it is found. 
    1069  * @param bool $require_once Whether to require_once or require. Default true. Has no effect if $load is false. 
    1070  * @return string The template filename if one is located. 
    1071  */ 
    1072 function locate_template($template_names, $load = false, $require_once = true ) { 
    1073     $located = ''; 
    1074     foreach ( (array) $template_names as $template_name ) { 
    1075         if ( !$template_name ) 
    1076             continue; 
    1077         if ( file_exists(STYLESHEETPATH . '/' . $template_name)) { 
    1078             $located = STYLESHEETPATH . '/' . $template_name; 
    1079             break; 
    1080         } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) { 
    1081             $located = TEMPLATEPATH . '/' . $template_name; 
    1082             break; 
    1083         } 
    1084     } 
    1085  
    1086     if ( $load && '' != $located ) 
    1087         load_template( $located, $require_once ); 
    1088  
    1089     return $located; 
    1090 } 
    1091  
    1092 /** 
    1093  * Require the template file with WordPress environment. 
    1094  * 
    1095  * The globals are set up for the template file to ensure that the WordPress 
    1096  * environment is available from within the function. The query variables are 
    1097  * also available. 
    1098  * 
    1099  * @since 1.5.0 
    1100  * 
    1101  * @param string $_template_file Path to template file. 
    1102  * @param bool $require_once Whether to require_once or require. Default true. 
    1103  */ 
    1104 function load_template( $_template_file, $require_once = true ) { 
    1105     global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; 
    1106  
    1107     if ( is_array( $wp_query->query_vars ) ) 
    1108         extract( $wp_query->query_vars, EXTR_SKIP ); 
    1109  
    1110     if ( $require_once ) 
    1111         require_once( $_template_file ); 
    1112     else 
    1113         require( $_template_file ); 
    1114 } 
    1115  
    1116 /** 
    1117728 * Display localized stylesheet link element. 
    1118729 * 
  • trunk/wp-settings.php

    r19824 r20002  
    113113require( ABSPATH . WPINC . '/query.php' ); 
    114114require( ABSPATH . WPINC . '/theme.php' ); 
     115require( ABSPATH . WPINC . '/template.php' ); 
    115116require( ABSPATH . WPINC . '/user.php' ); 
    116117require( ABSPATH . WPINC . '/meta.php' ); 
Note: See TracChangeset for help on using the changeset viewer.