[ Index ]

PHP Cross Reference of Wordpress 2.7.1

title

Body

[close]

/wp-includes/ -> theme.php (source)

   1  <?php
   2  /**
   3   * Theme, template, and stylesheet functions.
   4   *
   5   * @package WordPress
   6   * @subpackage Template
   7   */
   8  
   9  /**
  10   * Retrieve name of the current stylesheet.
  11   *
  12   * The theme name that the administrator has currently set the front end theme
  13   * as.
  14   *
  15   * For all extensive purposes, the template name and the stylesheet name are
  16   * going to be the same for most cases.
  17   *
  18   * @since 1.5.0
  19   * @uses apply_filters() Calls 'stylesheet' filter on stylesheet name.
  20   *
  21   * @return string Stylesheet name.
  22   */
  23  function get_stylesheet() {
  24      return apply_filters('stylesheet', get_option('stylesheet'));
  25  }
  26  
  27  /**
  28   * Retrieve stylesheet directory path for current theme.
  29   *
  30   * @since 1.5.0
  31   * @uses apply_filters() Calls 'stylesheet_directory' filter on stylesheet directory and theme name.
  32   *
  33   * @return string Path to current theme directory.
  34   */
  35  function get_stylesheet_directory() {
  36      $stylesheet = get_stylesheet();
  37      $stylesheet_dir = get_theme_root() . "/$stylesheet";
  38      return apply_filters('stylesheet_directory', $stylesheet_dir, $stylesheet);
  39  }
  40  
  41  /**
  42   * Retrieve stylesheet directory URI.
  43   *
  44   * @since 1.5.0
  45   *
  46   * @return string
  47   */
  48  function get_stylesheet_directory_uri() {
  49      $stylesheet = get_stylesheet();
  50      $stylesheet_dir_uri = get_theme_root_uri() . "/$stylesheet";
  51      return apply_filters('stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet);
  52  }
  53  
  54  /**
  55   * Retrieve URI of current theme stylesheet.
  56   *
  57   * The stylesheet file name is 'style.css' which is appended to {@link
  58   * get_stylesheet_directory_uri() stylesheet directory URI} path.
  59   *
  60   * @since 1.5.0
  61   * @uses apply_filters() Calls 'stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI.
  62   *
  63   * @return string
  64   */
  65  function get_stylesheet_uri() {
  66      $stylesheet_dir_uri = get_stylesheet_directory_uri();
  67      $stylesheet_uri = $stylesheet_dir_uri . "/style.css";
  68      return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
  69  }
  70  
  71  /**
  72   * Retrieve localized stylesheet URI.
  73   *
  74   * The stylesheet directory for the localized stylesheet files are located, by
  75   * default, in the base theme directory. The name of the locale file will be the
  76   * locale followed by '.css'. If that does not exist, then the text direction
  77   * stylesheet will be checked for existence, for example 'ltr.css'.
  78   *
  79   * The theme may change the location of the stylesheet directory by either using
  80   * the 'stylesheet_directory_uri' filter or the 'locale_stylesheet_uri' filter.
  81   * If you want to change the location of the stylesheet files for the entire
  82   * WordPress workflow, then change the former. If you just have the locale in a
  83   * separate folder, then change the latter.
  84   *
  85   * @since 2.1.0
  86   * @uses apply_filters() Calls 'locale_stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI.
  87   *
  88   * @return string
  89   */
  90  function get_locale_stylesheet_uri() {
  91      global $wp_locale;
  92      $stylesheet_dir_uri = get_stylesheet_directory_uri();
  93      $dir = get_stylesheet_directory();
  94      $locale = get_locale();
  95      if ( file_exists("$dir/$locale.css") )
  96          $stylesheet_uri = "$stylesheet_dir_uri/$locale.css";
  97      elseif ( !empty($wp_locale->text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") )
  98          $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css";
  99      else
 100          $stylesheet_uri = '';
 101      return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri);
 102  }
 103  
 104  /**
 105   * Retrieve name of the current theme.
 106   *
 107   * @since 1.5.0
 108   * @uses apply_filters() Calls 'template' filter on template option.
 109   *
 110   * @return string Template name.
 111   */
 112  function get_template() {
 113      return apply_filters('template', get_option('template'));
 114  }
 115  
 116  /**
 117   * Retrieve current theme directory.
 118   *
 119   * @since 1.5.0
 120   * @uses apply_filters() Calls 'template_directory' filter on template directory path and template name.
 121   *
 122   * @return string Template directory path.
 123   */
 124  function get_template_directory() {
 125      $template = get_template();
 126      $template_dir = get_theme_root() . "/$template";
 127      return apply_filters('template_directory', $template_dir, $template);
 128  }
 129  
 130  /**
 131   * Retrieve theme directory URI.
 132   *
 133   * @since 1.5.0
 134   * @uses apply_filters() Calls 'template_directory_uri' filter on template directory URI path and template name.
 135   *
 136   * @return string Template directory URI.
 137   */
 138  function get_template_directory_uri() {
 139      $template = get_template();
 140      $template_dir_uri = get_theme_root_uri() . "/$template";
 141      return apply_filters('template_directory_uri', $template_dir_uri, $template);
 142  }
 143  
 144  /**
 145   * Retrieve theme data from parsed theme file.
 146   *
 147   * The description will have the tags filtered with the following HTML elements
 148   * whitelisted. The <b>'a'</b> element with the <em>href</em> and <em>title</em>
 149   * attributes. The <b>abbr</b> element with the <em>title</em> attribute. The
 150   * <b>acronym<b> element with the <em>title</em> attribute allowed. The
 151   * <b>code</b>, <b>em</b>, and <b>strong</b> elements also allowed.
 152   *
 153   * The style.css file must contain theme name, theme URI, and description. The
 154   * data can also contain author URI, author, template (parent template),
 155   * version, status, and finally tags. Some of these are not used by WordPress
 156   * administration panels, but are used by theme directory web sites which list
 157   * the theme.
 158   *
 159   * @since 1.5.0
 160   *
 161   * @param string $theme_file Theme file path.
 162   * @return array Theme data.
 163   */
 164  function get_theme_data( $theme_file ) {
 165      $themes_allowed_tags = array(
 166          'a' => array(
 167              'href' => array(),'title' => array()
 168              ),
 169          'abbr' => array(
 170              'title' => array()
 171              ),
 172          'acronym' => array(
 173              'title' => array()
 174              ),
 175          'code' => array(),
 176          'em' => array(),
 177          'strong' => array()
 178      );
 179  
 180      $theme_data = implode( '', file( $theme_file ) );
 181      $theme_data = str_replace ( '\r', '\n', $theme_data );
 182      preg_match( '|Theme Name:(.*)$|mi', $theme_data, $theme_name );
 183      preg_match( '|Theme URI:(.*)$|mi', $theme_data, $theme_uri );
 184      preg_match( '|Description:(.*)$|mi', $theme_data, $description );
 185  
 186      if ( preg_match( '|Author URI:(.*)$|mi', $theme_data, $author_uri ) )
 187          $author_uri = clean_url( trim( $author_uri[1]) );
 188      else
 189          $author_uri = '';
 190  
 191      if ( preg_match( '|Template:(.*)$|mi', $theme_data, $template ) )
 192          $template = wp_kses( trim( $template[1] ), $themes_allowed_tags );
 193      else
 194          $template = '';
 195  
 196      if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) )
 197          $version = wp_kses( trim( $version[1] ), $themes_allowed_tags );
 198      else
 199          $version = '';
 200  
 201      if ( preg_match('|Status:(.*)|i', $theme_data, $status) )
 202          $status = wp_kses( trim( $status[1] ), $themes_allowed_tags );
 203      else
 204          $status = 'publish';
 205  
 206      if ( preg_match('|Tags:(.*)|i', $theme_data, $tags) )
 207          $tags = array_map( 'trim', explode( ',', wp_kses( trim( $tags[1] ), array() ) ) );
 208      else
 209          $tags = array();
 210  
 211      $name = $theme = wp_kses( trim( $theme_name[1] ), $themes_allowed_tags );
 212      $theme_uri = clean_url( trim( $theme_uri[1] ) );
 213      $description = wptexturize( wp_kses( trim( $description[1] ), $themes_allowed_tags ) );
 214  
 215      if ( preg_match( '|Author:(.*)$|mi', $theme_data, $author_name ) ) {
 216          if ( empty( $author_uri ) ) {
 217              $author = wp_kses( trim( $author_name[1] ), $themes_allowed_tags );
 218          } else {
 219              $author = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $author_uri, __( 'Visit author homepage' ), wp_kses( trim( $author_name[1] ), $themes_allowed_tags ) );
 220          }
 221      } else {
 222          $author = __('Anonymous');
 223      }
 224  
 225      return array( 'Name' => $name, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Status' => $status, 'Tags' => $tags );
 226  }
 227  
 228  /**
 229   * Retrieve list of themes with theme data in theme directory.
 230   *
 231   * The theme is broken, if it doesn't have a parent theme and is missing either
 232   * style.css and, or index.php. If the theme has a parent theme then it is
 233   * broken, if it is missing style.css; index.php is optional. The broken theme
 234   * list is saved in the {@link $wp_broken_themes} global, which is displayed on
 235   * the theme list in the administration panels.
 236   *
 237   * @since 1.5.0
 238   * @global array $wp_broken_themes Stores the broken themes.
 239   * @global array $wp_themes Stores the working themes.
 240   *
 241   * @return array Theme list with theme data.
 242   */
 243  function get_themes() {
 244      global $wp_themes, $wp_broken_themes;
 245  
 246      if ( isset($wp_themes) )
 247          return $wp_themes;
 248  
 249      $themes = array();
 250      $wp_broken_themes = array();
 251      $theme_loc = $theme_root = get_theme_root();
 252      if ( '/' != WP_CONTENT_DIR ) // don't want to replace all forward slashes, see Trac #4541
 253          $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root);
 254  
 255      // Files in wp-content/themes directory and one subdir down
 256      $themes_dir = @ opendir($theme_root);
 257      if ( !$themes_dir )
 258          return false;
 259  
 260      while ( ($theme_dir = readdir($themes_dir)) !== false ) {
 261          if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
 262              if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
 263                  continue;
 264              $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
 265              $found_stylesheet = false;
 266              while ( ($theme_file = readdir($stylish_dir)) !== false ) {
 267                  if ( $theme_file == 'style.css' ) {
 268                      $theme_files[] = $theme_dir . '/' . $theme_file;
 269                      $found_stylesheet = true;
 270                      break;
 271                  }
 272              }
 273              @closedir($stylish_dir);
 274              if ( !$found_stylesheet ) { // look for themes in that dir
 275                  $subdir = "$theme_root/$theme_dir";
 276                  $subdir_name = $theme_dir;
 277                  $theme_subdir = @ opendir( $subdir );
 278                  while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
 279                      if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
 280                          if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
 281                              continue;
 282                          $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
 283                          $found_stylesheet = false;
 284                          while ( ($theme_file = readdir($stylish_dir)) !== false ) {
 285                              if ( $theme_file == 'style.css' ) {
 286                                  $theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
 287                                  $found_stylesheet = true;
 288                                  break;
 289                              }
 290                          }
 291                          @closedir($stylish_dir);
 292                      }
 293                  }
 294                  @closedir($theme_subdir);
 295                  $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
 296              }
 297          }
 298      }
 299      if ( is_dir( $theme_dir ) )
 300          @closedir( $theme_dir );
 301  
 302      if ( !$themes_dir || !$theme_files )
 303          return $themes;
 304  
 305      sort($theme_files);
 306  
 307      foreach ( (array) $theme_files as $theme_file ) {
 308          if ( !is_readable("$theme_root/$theme_file") ) {
 309              $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.'));
 310              continue;
 311          }
 312  
 313          $theme_data = get_theme_data("$theme_root/$theme_file");
 314  
 315          $name        = $theme_data['Name'];
 316          $title       = $theme_data['Title'];
 317          $description = wptexturize($theme_data['Description']);
 318          $version     = $theme_data['Version'];
 319          $author      = $theme_data['Author'];
 320          $template    = $theme_data['Template'];
 321          $stylesheet  = dirname($theme_file);
 322  
 323          $screenshot = false;
 324          foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) {
 325              if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) {
 326                  $screenshot = "screenshot.$ext";
 327                  break;
 328              }
 329          }
 330  
 331          if ( empty($name) ) {
 332              $name = dirname($theme_file);
 333              $title = $name;
 334          }
 335  
 336          if ( empty($template) ) {
 337              if ( file_exists(dirname("$theme_root/$theme_file/index.php")) )
 338                  $template = dirname($theme_file);
 339              else
 340                  continue;
 341          }
 342  
 343          $template = trim($template);
 344  
 345          if ( !file_exists("$theme_root/$template/index.php") ) {
 346              $parent_dir = dirname(dirname($theme_file));
 347              if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
 348                  $template = "$parent_dir/$template";
 349              } else {
 350                  $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
 351                  continue;
 352              }
 353          }
 354  
 355          $stylesheet_files = array();
 356          $template_files = array();
 357  
 358          $stylesheet_dir = @ dir("$theme_root/$stylesheet");
 359          if ( $stylesheet_dir ) {
 360              while ( ($file = $stylesheet_dir->read()) !== false ) {
 361                  if ( !preg_match('|^\.+$|', $file) ) {
 362                      if ( preg_match('|\.css$|', $file) )
 363                          $stylesheet_files[] = "$theme_loc/$stylesheet/$file";
 364                      elseif ( preg_match('|\.php$|', $file) )
 365                          $template_files[] = "$theme_loc/$stylesheet/$file";
 366                  }
 367              }
 368          }
 369  
 370          $template_dir = @ dir("$theme_root/$template");
 371          if ( $template_dir ) {
 372              while(($file = $template_dir->read()) !== false) {
 373                  if ( !preg_match('|^\.+$|', $file) && preg_match('|\.php$|', $file) )
 374                      $template_files[] = "$theme_loc/$template/$file";
 375              }
 376          }
 377  
 378          $template_dir = dirname($template_files[0]);
 379          $stylesheet_dir = dirname($stylesheet_files[0]);
 380  
 381          if ( empty($template_dir) )
 382              $template_dir = '/';
 383          if ( empty($stylesheet_dir) )
 384              $stylesheet_dir = '/';
 385  
 386          // Check for theme name collision.  This occurs if a theme is copied to
 387          // a new theme directory and the theme header is not updated.  Whichever
 388          // theme is first keeps the name.  Subsequent themes get a suffix applied.
 389          // The Default and Classic themes always trump their pretenders.
 390          if ( isset($themes[$name]) ) {
 391              if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) &&
 392                       ('default' == $stylesheet || 'classic' == $stylesheet) ) {
 393                  // If another theme has claimed to be one of our default themes, move
 394                  // them aside.
 395                  $suffix = $themes[$name]['Stylesheet'];
 396                  $new_name = "$name/$suffix";
 397                  $themes[$new_name] = $themes[$name];
 398                  $themes[$new_name]['Name'] = $new_name;
 399              } else {
 400                  $name = "$name/$stylesheet";
 401              }
 402          }
 403  
 404          $themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Stylesheet' => $stylesheet, 'Template Files' => $template_files, 'Stylesheet Files' => $stylesheet_files, 'Template Dir' => $template_dir, 'Stylesheet Dir' => $stylesheet_dir, 'Status' => $theme_data['Status'], 'Screenshot' => $screenshot, 'Tags' => $theme_data['Tags']);
 405      }
 406  
 407      // Resolve theme dependencies.
 408      $theme_names = array_keys($themes);
 409  
 410      foreach ( (array) $theme_names as $theme_name ) {
 411          $themes[$theme_name]['Parent Theme'] = '';
 412          if ( $themes[$theme_name]['Stylesheet'] != $themes[$theme_name]['Template'] ) {
 413              foreach ( (array) $theme_names as $parent_theme_name ) {
 414                  if ( ($themes[$parent_theme_name]['Stylesheet'] == $themes[$parent_theme_name]['Template']) && ($themes[$parent_theme_name]['Template'] == $themes[$theme_name]['Template']) ) {
 415                      $themes[$theme_name]['Parent Theme'] = $themes[$parent_theme_name]['Name'];
 416                      break;
 417                  }
 418              }
 419          }
 420      }
 421  
 422      $wp_themes = $themes;
 423  
 424      return $themes;
 425  }
 426  
 427  /**
 428   * Retrieve theme data.
 429   *
 430   * @since 1.5.0
 431   *
 432   * @param string $theme Theme name.
 433   * @return array|null Null, if theme name does not exist. Theme data, if exists.
 434   */
 435  function get_theme($theme) {
 436      $themes = get_themes();
 437  
 438      if ( array_key_exists($theme, $themes) )
 439          return $themes[$theme];
 440  
 441      return null;
 442  }
 443  
 444  /**
 445   * Retrieve current theme display name.
 446   *
 447   * If the 'current_theme' option has already been set, then it will be returned
 448   * instead. If it is not set, then each theme will be iterated over until both
 449   * the current stylesheet and current template name.
 450   *
 451   * @since 1.5.0
 452   *
 453   * @return string
 454   */
 455  function get_current_theme() {
 456      if ( $theme = get_option('current_theme') )
 457          return $theme;
 458  
 459      $themes = get_themes();
 460      $theme_names = array_keys($themes);
 461      $current_template = get_option('template');
 462      $current_stylesheet = get_option('stylesheet');
 463      $current_theme = 'WordPress Default';
 464  
 465      if ( $themes ) {
 466          foreach ( (array) $theme_names as $theme_name ) {
 467              if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet &&
 468                      $themes[$theme_name]['Template'] == $current_template ) {
 469                  $current_theme = $themes[$theme_name]['Name'];
 470                  break;
 471              }
 472          }
 473      }
 474  
 475      update_option('current_theme', $current_theme);
 476  
 477      return $current_theme;
 478  }
 479  
 480  /**
 481   * Retrieve path to themes directory.
 482   *
 483   * Does not have trailing slash.
 484   *
 485   * @since 1.5.0
 486   * @uses apply_filters() Calls 'theme_root' filter on path.
 487   *
 488   * @return string Theme path.
 489   */
 490  function get_theme_root() {
 491      return apply_filters('theme_root', WP_CONTENT_DIR . "/themes");
 492  }
 493  
 494  /**
 495   * Retrieve URI for themes directory.
 496   *
 497   * Does not have trailing slash.
 498   *
 499   * @since 1.5.0
 500   *
 501   * @return string Themes URI.
 502   */
 503  function get_theme_root_uri() {
 504      return apply_filters('theme_root_uri', content_url('themes'), get_option('siteurl'));
 505  }
 506  
 507  /**
 508   * Retrieve path to file without the use of extension.
 509   *
 510   * Used to quickly retrieve the path of file without including the file
 511   * extension. It will also check the parent template, if the file exists, with
 512   * the use of {@link locate_template()}. Allows for more generic file location
 513   * without the use of the other get_*_template() functions.
 514   *
 515   * Can be used with include() or require() to retrieve path.
 516   * <code>
 517   * if( '' != get_query_template( '404' ) )
 518   *     include( get_query_template( '404' ) );
 519   * </code>
 520   * or the same can be accomplished with
 521   * <code>
 522   * if( '' != get_404_template() )
 523   *     include( get_404_template() );
 524   * </code>
 525   *
 526   * @since 1.5.0
 527   *
 528   * @param string $type Filename without extension.
 529   * @return string Full path to file.
 530   */
 531  function get_query_template($type) {
 532      $type = preg_replace( '|[^a-z0-9-]+|', '', $type );
 533      return apply_filters("{$type}_template", locate_template(array("{$type}.php")));
 534  }
 535  
 536  /**
 537   * Retrieve path of 404 template in current or parent template.
 538   *
 539   * @since 1.5.0
 540   *
 541   * @return string
 542   */
 543  function get_404_template() {
 544      return get_query_template('404');
 545  }
 546  
 547  /**
 548   * Retrieve path of archive template in current or parent template.
 549   *
 550   * @since 1.5.0
 551   *
 552   * @return string
 553   */
 554  function get_archive_template() {
 555      return get_query_template('archive');
 556  }
 557  
 558  /**
 559   * Retrieve path of author template in current or parent template.
 560   *
 561   * @since 1.5.0
 562   *
 563   * @return string
 564   */
 565  function get_author_template() {
 566      return get_query_template('author');
 567  }
 568  
 569  /**
 570   * Retrieve path of category template in current or parent template.
 571   *
 572   * Works by retrieving the current category ID, for example 'category-1.php' and
 573   * will fallback to category.php template, if the ID category file doesn't
 574   * exist.
 575   *
 576   * @since 1.5.0
 577   * @uses apply_filters() Calls 'category_template' on file path of category template.
 578   *
 579   * @return string
 580   */
 581  function get_category_template() {
 582      $template = locate_template(array("category-" . absint( get_query_var('cat') ) . '.php', 'category.php'));
 583      return apply_filters('category_template', $template);
 584  }
 585  
 586  /**
 587   * Retrieve path of tag template in current or parent template.
 588   *
 589   * Works by retrieving the current tag name, for example 'tag-wordpress.php' and will
 590   * fallback to tag.php template, if the name tag file doesn't exist.
 591   *
 592   * @since 2.3.0
 593   * @uses apply_filters() Calls 'tag_template' on file path of tag template.
 594   *
 595   * @return string
 596   */
 597  function get_tag_template() {
 598      $template = locate_template(array("tag-" . get_query_var('tag') . '.php', 'tag.php'));
 599      return apply_filters('tag_template', $template);
 600  }
 601  
 602  /**
 603   * Retrieve path of taxonomy template in current or parent template.
 604   *
 605   * Retrieves the taxonomy and term, if term is available. The template is
 606   * prepended with 'taxonomy-' and followed by both the taxonomy string and
 607   * the taxonomy string followed by a dash and then followed by the term.
 608   *
 609   * The taxonomy and term template is checked and used first, if it exists.
 610   * Second, just the taxonomy template is checked, and then finally, taxonomy.php
 611   * template is used. If none of the files exist, then it will fall back on to
 612   * index.php.
 613   *
 614   * @since unknown (2.6.0 most likely)
 615   * @uses apply_filters() Calls 'taxonomy_template' filter on found path.
 616   *
 617   * @return string
 618   */
 619  function get_taxonomy_template() {
 620      $taxonomy = get_query_var('taxonomy');
 621      $term = get_query_var('term');
 622  
 623      $templates = array();
 624      if ( $taxonomy && $term )
 625          $templates[] = "taxonomy-$taxonomy-$term.php";
 626      if ( $taxonomy )
 627          $templates[] = "taxonomy-$taxonomy.php";
 628  
 629      $templates[] = "taxonomy.php";
 630  
 631      $template = locate_template($templates);
 632      return apply_filters('taxonomy_template', $template);
 633  }
 634  
 635  /**
 636   * Retrieve path of date template in current or parent template.
 637   *
 638   * @since 1.5.0
 639   *
 640   * @return string
 641   */
 642  function get_date_template() {
 643      return get_query_template('date');
 644  }
 645  
 646  /**
 647   * Retrieve path of home template in current or parent template.
 648   *
 649   * Attempts to locate 'home.php' first before falling back to 'index.php'.
 650   *
 651   * @since 1.5.0
 652   * @uses apply_filters() Calls 'home_template' on file path of home template.
 653   *
 654   * @return string
 655   */
 656  function get_home_template() {
 657      $template = locate_template(array('home.php', 'index.php'));
 658      return apply_filters('home_template', $template);
 659  }
 660  
 661  /**
 662   * Retrieve path of page template in current or parent template.
 663   *
 664   * First attempt is to look for the file in the '_wp_page_template' page meta
 665   * data. The second attempt, if the first has a file and is not empty, is to
 666   * look for 'page.php'.
 667   *
 668   * @since 1.5.0
 669   *
 670   * @return string
 671   */
 672  function get_page_template() {
 673      global $wp_query;
 674  
 675      $id = (int) $wp_query->post->ID;
 676      $template = get_post_meta($id, '_wp_page_template', true);
 677  
 678      if ( 'default' == $template )
 679          $template = '';
 680  
 681      $templates = array();
 682      if ( !empty($template) && !validate_file($template) )
 683          $templates[] = $template;
 684  
 685      $templates[] = "page.php";
 686  
 687      return apply_filters('page_template', locate_template($templates));
 688  }
 689  
 690  /**
 691   * Retrieve path of paged template in current or parent template.
 692   *
 693   * @since 1.5.0
 694   *
 695   * @return string
 696   */
 697  function get_paged_template() {
 698      return get_query_template('paged');
 699  }
 700  
 701  /**
 702   * Retrieve path of search template in current or parent template.
 703   *
 704   * @since 1.5.0
 705   *
 706   * @return string
 707   */
 708  function get_search_template() {
 709      return get_query_template('search');
 710  }
 711  
 712  /**
 713   * Retrieve path of single template in current or parent template.
 714   *
 715   * @since 1.5.0
 716   *
 717   * @return string
 718   */
 719  function get_single_template() {
 720      return get_query_template('single');
 721  }
 722  
 723  /**
 724   * Retrieve path of attachment template in current or parent template.
 725   *
 726   * The attachment path first checks if the first part of the mime type exists.
 727   * The second check is for the second part of the mime type. The last check is
 728   * for both types separated by an underscore. If neither are found then the file
 729   * 'attachment.php' is checked and returned.
 730   *
 731   * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
 732   * finally 'text_plain.php'.
 733   *
 734   * @since 2.0.0
 735   *
 736   * @return string
 737   */
 738  function get_attachment_template() {
 739      global $posts;
 740      $type = explode('/', $posts[0]->post_mime_type);
 741      if ( $template = get_query_template($type[0]) )
 742          return $template;
 743      elseif ( $template = get_query_template($type[1]) )
 744          return $template;
 745      elseif ( $template = get_query_template("$type[0]_$type[1]") )
 746          return $template;
 747      else
 748          return get_query_template('attachment');
 749  }
 750  
 751  /**
 752   * Retrieve path of comment popup template in current or parent template.
 753   *
 754   * Checks for comment popup template in current template, if it exists or in the
 755   * parent template. If it doesn't exist, then it retrieves the comment-popup.php
 756   * file from the default theme. The default theme must then exist for it to
 757   * work.
 758   *
 759   * @since 1.5.0
 760   * @uses apply_filters() Calls 'comments_popup_template' filter on path.
 761   *
 762   * @return string
 763   */
 764  function get_comments_popup_template() {
 765      $template = locate_template(array("comments-popup.php"));
 766      if ('' == $template)
 767          $template = get_theme_root() . '/default/comments-popup.php';
 768  
 769      return apply_filters('comments_popup_template', $template);
 770  }
 771  
 772  /**
 773   * Retrieve the name of the highest priority template file that exists.
 774   *
 775   * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
 776   * inherit from a parent theme can just overload one file.
 777   *
 778   * @since 2.7.0
 779   *
 780   * @param array $template_names Array of template files to search for in priority order.
 781   * @param bool $load If true the template file will be loaded if it is found.
 782   * @return string The template filename if one is located.
 783   */
 784  function locate_template($template_names, $load = false) {
 785      if (!is_array($template_names))
 786          return '';
 787  
 788      $located = '';
 789      foreach($template_names as $template_name) {
 790          if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
 791              $located = STYLESHEETPATH . '/' . $template_name;
 792              break;
 793          } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
 794              $located = TEMPLATEPATH . '/' . $template_name;
 795              break;
 796          }
 797      }
 798  
 799      if ($load && '' != $located)
 800          load_template($located);
 801  
 802      return $located;
 803  }
 804  
 805  /**
 806   * Require once the template file with WordPress environment.
 807   *
 808   * The globals are set up for the template file to ensure that the WordPress
 809   * environment is available from within the function. The query variables are
 810   * also available.
 811   *
 812   * @since 1.5.0
 813   *
 814   * @param string $_template_file Path to template file.
 815   */
 816  function load_template($_template_file) {
 817      global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
 818  
 819      if ( is_array($wp_query->query_vars) )
 820          extract($wp_query->query_vars, EXTR_SKIP);
 821  
 822      require_once($_template_file);
 823  }
 824  
 825  /**
 826   * Display localized stylesheet link element.
 827   *
 828   * @since 2.1.0
 829   */
 830  function locale_stylesheet() {
 831      $stylesheet = get_locale_stylesheet_uri();
 832      if ( empty($stylesheet) )
 833          return;
 834      echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />';
 835  }
 836  
 837  /**
 838   * Start preview theme output buffer.
 839   *
 840   * Will only preform task if the user has permissions and template and preview
 841   * query variables exist.
 842   *
 843   * @since 2.5.0
 844   */
 845  function preview_theme() {
 846      if ( ! (isset($_GET['template']) && isset($_GET['preview'])) )
 847          return;
 848  
 849      if ( !current_user_can( 'switch_themes' ) )
 850          return;
 851  
 852      $_GET['template'] = preg_replace('|[^a-z0-9_.-/]|i', '', $_GET['template']);
 853  
 854      if ( validate_file($_GET['template']) )
 855          return;
 856  
 857      add_filter('template', create_function('', "return '{$_GET['template']}';") );
 858  
 859      if ( isset($_GET['stylesheet']) ) {
 860          $_GET['stylesheet'] = preg_replace('|[^a-z0-9_.-/]|i', '', $_GET['stylesheet']);
 861          if ( validate_file($_GET['stylesheet']) )
 862              return;
 863          add_filter('stylesheet', create_function('', "return '{$_GET['stylesheet']}';") );
 864      }
 865  
 866      ob_start( 'preview_theme_ob_filter' );
 867  }
 868  add_action('setup_theme', 'preview_theme');
 869  
 870  /**
 871   * Callback function for ob_start() to capture all links in the theme.
 872   *
 873   * @since unknown
 874   * @access private
 875   *
 876   * @param string $content
 877   * @return string
 878   */
 879  function preview_theme_ob_filter( $content ) {
 880      return preg_replace_callback( "|(<a.*?href=([\"']))(.*?)([\"'].*?>)|", 'preview_theme_ob_filter_callback', $content );
 881  }
 882  
 883  /**
 884   * Manipulates preview theme links in order to control and maintain location.
 885   *
 886   * Callback function for preg_replace_callback() to accept and filter matches.
 887   *
 888   * @since unknown
 889   * @access private
 890   *
 891   * @param array $matches
 892   * @return string
 893   */
 894  function preview_theme_ob_filter_callback( $matches ) {
 895      if ( strpos($matches[4], 'onclick') !== false )
 896          $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.
 897      if (
 898          ( false !== strpos($matches[3], '/wp-admin/') )
 899      ||
 900          ( false !== strpos($matches[3], '://') && 0 !== strpos($matches[3], get_option('home')) )
 901      ||
 902          ( false !== strpos($matches[3], '/feed/') )
 903      ||
 904          ( false !== strpos($matches[3], '/trackback/') )
 905      )
 906          return $matches[1] . "#$matches[2] onclick=$matches[2]return false;" . $matches[4];
 907  
 908      $link = add_query_arg( array('preview' => 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'] ), $matches[3] );
 909      if ( 0 === strpos($link, 'preview=1') )
 910          $link = "?$link";
 911      return $matches[1] . attribute_escape( $link ) . $matches[4];
 912  }
 913  
 914  /**
 915   * Switches current theme to new template and stylesheet names.
 916   *
 917   * @since unknown
 918   * @uses do_action() Calls 'switch_theme' action on updated theme display name.
 919   *
 920   * @param string $template Template name
 921   * @param string $stylesheet Stylesheet name.
 922   */
 923  function switch_theme($template, $stylesheet) {
 924      update_option('template', $template);
 925      update_option('stylesheet', $stylesheet);
 926      delete_option('current_theme');
 927      $theme = get_current_theme();
 928      do_action('switch_theme', $theme);
 929  }
 930  
 931  /**
 932   * Checks that current theme files 'index.php' and 'style.css' exists.
 933   *
 934   * Does not check the 'default' theme. The 'default' theme should always exist
 935   * or should have another theme renamed to that template name and directory
 936   * path. Will switch theme to default if current theme does not validate.
 937   * You can use the 'validate_current_theme' filter to return FALSE to
 938   * disable this functionality.
 939   *
 940   * @since 1.5.0
 941   *
 942   * @return bool
 943   */
 944  function validate_current_theme() {
 945      // Don't validate during an install/upgrade.
 946      if ( defined('WP_INSTALLING') || !apply_filters( 'validate_current_theme', true ) )
 947          return true;
 948  
 949      if ( get_template() != 'default' && !file_exists(get_template_directory() . '/index.php') ) {
 950          switch_theme('default', 'default');
 951          return false;
 952      }
 953  
 954      if ( get_stylesheet() != 'default' && !file_exists(get_template_directory() . '/style.css') ) {
 955          switch_theme('default', 'default');
 956          return false;
 957      }
 958  
 959      return true;
 960  }
 961  
 962  /**
 963   * Retrieve theme modification value for the current theme.
 964   *
 965   * If the modification name does not exist, then the $default will be passed
 966   * through {@link http://php.net/sprintf sprintf()} PHP function with the first
 967   * string the template directory URI and the second string the stylesheet
 968   * directory URI.
 969   *
 970   * @since 2.1.0
 971   * @uses apply_filters() Calls 'theme_mod_$name' filter on the value.
 972   *
 973   * @param string $name Theme modification name.
 974   * @param bool|string $default
 975   * @return string
 976   */
 977  function get_theme_mod($name, $default = false) {
 978      $theme = get_current_theme();
 979  
 980      $mods = get_option("mods_$theme");
 981  
 982      if ( isset($mods[$name]) )
 983          return apply_filters( "theme_mod_$name", $mods[$name] );
 984  
 985      return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri(), get_stylesheet_directory_uri()) );
 986  }
 987  
 988  /**
 989   * Update theme modification value for the current theme.
 990   *
 991   * @since 2.1.0
 992   *
 993   * @param string $name Theme modification name.
 994   * @param string $value theme modification value.
 995   */
 996  function set_theme_mod($name, $value) {
 997      $theme = get_current_theme();
 998  
 999      $mods = get_option("mods_$theme");
1000  
1001      $mods[$name] = $value;
1002  
1003      update_option("mods_$theme", $mods);
1004      wp_cache_delete("mods_$theme", 'options');
1005  }
1006  
1007  /**
1008   * Remove theme modification name from current theme list.
1009   *
1010   * If removing the name also removes all elements, then the entire option will
1011   * be removed.
1012   *
1013   * @since 2.1.0
1014   *
1015   * @param string $name Theme modification name.
1016   * @return null
1017   */
1018  function remove_theme_mod( $name ) {
1019      $theme = get_current_theme();
1020  
1021      $mods = get_option("mods_$theme");
1022  
1023      if ( !isset($mods[$name]) )
1024          return;
1025  
1026      unset($mods[$name]);
1027  
1028      if ( empty($mods) )
1029          return remove_theme_mods();
1030  
1031      update_option("mods_$theme", $mods);
1032      wp_cache_delete("mods_$theme", 'options');
1033  }
1034  
1035  /**
1036   * Remove theme modifications option for current theme.
1037   *
1038   * @since 2.1.0
1039   */
1040  function remove_theme_mods() {
1041      $theme = get_current_theme();
1042  
1043      delete_option("mods_$theme");
1044  }
1045  
1046  /**
1047   * Retrieve text color for custom header.
1048   *
1049   * @since 2.1.0
1050   * @uses HEADER_TEXTCOLOR
1051   *
1052   * @return string
1053   */
1054  function get_header_textcolor() {
1055      return get_theme_mod('header_textcolor', HEADER_TEXTCOLOR);
1056  }
1057  
1058  /**
1059   * Display text color for custom header.
1060   *
1061   * @since 2.1.0
1062   */
1063  function header_textcolor() {
1064      echo get_header_textcolor();
1065  }
1066  
1067  /**
1068   * Retrieve header image for custom header.
1069   *
1070   * @since 2.1.0
1071   * @uses HEADER_IMAGE
1072   *
1073   * @return string
1074   */
1075  function get_header_image() {
1076      return get_theme_mod('header_image', HEADER_IMAGE);
1077  }
1078  
1079  /**
1080   * Display header image path.
1081   *
1082   * @since 2.1.0
1083   */
1084  function header_image() {
1085      echo get_header_image();
1086  }
1087  
1088  /**
1089   * Add callbacks for image header display.
1090   *
1091   * The parameter $header_callback callback will be required to display the
1092   * content for the 'wp_head' action. The parameter $admin_header_callback
1093   * callback will be added to Custom_Image_Header class and that will be added
1094   * to the 'admin_menu' action.
1095   *
1096   * @since 2.1.0
1097   * @uses Custom_Image_Header Sets up for $admin_header_callback for administration panel display.
1098   *
1099   * @param callback $header_callback Call on 'wp_head' action.
1100   * @param callback $admin_header_callback Call on administration panels.
1101   */
1102  function add_custom_image_header($header_callback, $admin_header_callback) {
1103      if ( ! empty($header_callback) )
1104          add_action('wp_head', $header_callback);
1105  
1106      if ( ! is_admin() )
1107          return;
1108      require_once (ABSPATH . 'wp-admin/custom-header.php');
1109      $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback);
1110      add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init'));
1111  }
1112  
1113  ?>


Generated: Mon Mar 23 16:23:02 2009 Cross-referenced by PHPXref 0.7