Make WordPress Core

Changeset 20002


Ignore:
Timestamp:
02/28/2012 01:49:49 AM (14 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.