| [ Index ] |
PHP Cross Reference of Wordpress 2.9.1 |
[Summary view] [Print] [Text view]
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 $theme_root = get_theme_root( $stylesheet ); 38 $stylesheet_dir = "$theme_root/$stylesheet"; 39 40 return apply_filters( 'stylesheet_directory', $stylesheet_dir, $stylesheet, $theme_root ); 41 } 42 43 /** 44 * Retrieve stylesheet directory URI. 45 * 46 * @since 1.5.0 47 * 48 * @return string 49 */ 50 function get_stylesheet_directory_uri() { 51 $stylesheet = get_stylesheet(); 52 $theme_root_uri = get_theme_root_uri( $stylesheet ); 53 $stylesheet_dir_uri = "$theme_root_uri/$stylesheet"; 54 55 return apply_filters( 'stylesheet_directory_uri', $stylesheet_dir_uri, $stylesheet, $theme_root_uri ); 56 } 57 58 /** 59 * Retrieve URI of current theme stylesheet. 60 * 61 * The stylesheet file name is 'style.css' which is appended to {@link 62 * get_stylesheet_directory_uri() stylesheet directory URI} path. 63 * 64 * @since 1.5.0 65 * @uses apply_filters() Calls 'stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI. 66 * 67 * @return string 68 */ 69 function get_stylesheet_uri() { 70 $stylesheet_dir_uri = get_stylesheet_directory_uri(); 71 $stylesheet_uri = $stylesheet_dir_uri . "/style.css"; 72 return apply_filters('stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri); 73 } 74 75 /** 76 * Retrieve localized stylesheet URI. 77 * 78 * The stylesheet directory for the localized stylesheet files are located, by 79 * default, in the base theme directory. The name of the locale file will be the 80 * locale followed by '.css'. If that does not exist, then the text direction 81 * stylesheet will be checked for existence, for example 'ltr.css'. 82 * 83 * The theme may change the location of the stylesheet directory by either using 84 * the 'stylesheet_directory_uri' filter or the 'locale_stylesheet_uri' filter. 85 * If you want to change the location of the stylesheet files for the entire 86 * WordPress workflow, then change the former. If you just have the locale in a 87 * separate folder, then change the latter. 88 * 89 * @since 2.1.0 90 * @uses apply_filters() Calls 'locale_stylesheet_uri' filter on stylesheet URI path and stylesheet directory URI. 91 * 92 * @return string 93 */ 94 function get_locale_stylesheet_uri() { 95 global $wp_locale; 96 $stylesheet_dir_uri = get_stylesheet_directory_uri(); 97 $dir = get_stylesheet_directory(); 98 $locale = get_locale(); 99 if ( file_exists("$dir/$locale.css") ) 100 $stylesheet_uri = "$stylesheet_dir_uri/$locale.css"; 101 elseif ( !empty($wp_locale->text_direction) && file_exists("$dir/{$wp_locale->text_direction}.css") ) 102 $stylesheet_uri = "$stylesheet_dir_uri/{$wp_locale->text_direction}.css"; 103 else 104 $stylesheet_uri = ''; 105 return apply_filters('locale_stylesheet_uri', $stylesheet_uri, $stylesheet_dir_uri); 106 } 107 108 /** 109 * Retrieve name of the current theme. 110 * 111 * @since 1.5.0 112 * @uses apply_filters() Calls 'template' filter on template option. 113 * 114 * @return string Template name. 115 */ 116 function get_template() { 117 return apply_filters('template', get_option('template')); 118 } 119 120 /** 121 * Retrieve current theme directory. 122 * 123 * @since 1.5.0 124 * @uses apply_filters() Calls 'template_directory' filter on template directory path and template name. 125 * 126 * @return string Template directory path. 127 */ 128 function get_template_directory() { 129 $template = get_template(); 130 $theme_root = get_theme_root( $template ); 131 $template_dir = "$theme_root/$template"; 132 133 return apply_filters( 'template_directory', $template_dir, $template, $theme_root ); 134 } 135 136 /** 137 * Retrieve theme directory URI. 138 * 139 * @since 1.5.0 140 * @uses apply_filters() Calls 'template_directory_uri' filter on template directory URI path and template name. 141 * 142 * @return string Template directory URI. 143 */ 144 function get_template_directory_uri() { 145 $template = get_template(); 146 $theme_root_uri = get_theme_root_uri( $template ); 147 $template_dir_uri = "$theme_root_uri/$template"; 148 149 return apply_filters( 'template_directory_uri', $template_dir_uri, $template, $theme_root_uri ); 150 } 151 152 /** 153 * Retrieve theme data from parsed theme file. 154 * 155 * The description will have the tags filtered with the following HTML elements 156 * whitelisted. The <b>'a'</b> element with the <em>href</em> and <em>title</em> 157 * attributes. The <b>abbr</b> element with the <em>title</em> attribute. The 158 * <b>acronym<b> element with the <em>title</em> attribute allowed. The 159 * <b>code</b>, <b>em</b>, and <b>strong</b> elements also allowed. 160 * 161 * The style.css file must contain theme name, theme URI, and description. The 162 * data can also contain author URI, author, template (parent template), 163 * version, status, and finally tags. Some of these are not used by WordPress 164 * administration panels, but are used by theme directory web sites which list 165 * the theme. 166 * 167 * @since 1.5.0 168 * 169 * @param string $theme_file Theme file path. 170 * @return array Theme data. 171 */ 172 function get_theme_data( $theme_file ) { 173 $default_headers = array( 174 'Name' => 'Theme Name', 175 'URI' => 'Theme URI', 176 'Description' => 'Description', 177 'Author' => 'Author', 178 'AuthorURI' => 'Author URI', 179 'Version' => 'Version', 180 'Template' => 'Template', 181 'Status' => 'Status', 182 'Tags' => 'Tags' 183 ); 184 185 $themes_allowed_tags = array( 186 'a' => array( 187 'href' => array(),'title' => array() 188 ), 189 'abbr' => array( 190 'title' => array() 191 ), 192 'acronym' => array( 193 'title' => array() 194 ), 195 'code' => array(), 196 'em' => array(), 197 'strong' => array() 198 ); 199 200 $theme_data = get_file_data( $theme_file, $default_headers, 'theme' ); 201 202 $theme_data['Name'] = $theme_data['Title'] = wp_kses( $theme_data['Name'], $themes_allowed_tags ); 203 204 $theme_data['URI'] = esc_url( $theme_data['URI'] ); 205 206 $theme_data['Description'] = wptexturize( wp_kses( $theme_data['Description'], $themes_allowed_tags ) ); 207 208 $theme_data['AuthorURI'] = esc_url( $theme_data['AuthorURI'] ); 209 210 $theme_data['Template'] = wp_kses( $theme_data['Template'], $themes_allowed_tags ); 211 212 $theme_data['Version'] = wp_kses( $theme_data['Version'], $themes_allowed_tags ); 213 214 if ( $theme_data['Status'] == '' ) 215 $theme_data['Status'] = 'publish'; 216 else 217 $theme_data['Status'] = wp_kses( $theme_data['Status'], $themes_allowed_tags ); 218 219 if ( $theme_data['Tags'] == '' ) 220 $theme_data['Tags'] = array(); 221 else 222 $theme_data['Tags'] = array_map( 'trim', explode( ',', wp_kses( $theme_data['Tags'], array() ) ) ); 223 224 if ( $theme_data['Author'] == '' ) { 225 $theme_data['Author'] = __('Anonymous'); 226 } else { 227 if ( empty( $theme_data['AuthorURI'] ) ) { 228 $theme_data['Author'] = wp_kses( $theme_data['Author'], $themes_allowed_tags ); 229 } else { 230 $theme_data['Author'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $theme_data['AuthorURI'], __( 'Visit author homepage' ), wp_kses( $theme_data['Author'], $themes_allowed_tags ) ); 231 } 232 } 233 234 return $theme_data; 235 } 236 237 /** 238 * Retrieve list of themes with theme data in theme directory. 239 * 240 * The theme is broken, if it doesn't have a parent theme and is missing either 241 * style.css and, or index.php. If the theme has a parent theme then it is 242 * broken, if it is missing style.css; index.php is optional. The broken theme 243 * list is saved in the {@link $wp_broken_themes} global, which is displayed on 244 * the theme list in the administration panels. 245 * 246 * @since 1.5.0 247 * @global array $wp_broken_themes Stores the broken themes. 248 * @global array $wp_themes Stores the working themes. 249 * 250 * @return array Theme list with theme data. 251 */ 252 function get_themes() { 253 global $wp_themes, $wp_broken_themes; 254 255 if ( isset($wp_themes) ) 256 return $wp_themes; 257 258 /* Register the default root as a theme directory */ 259 register_theme_directory( get_theme_root() ); 260 261 if ( !$theme_files = search_theme_directories() ) 262 return false; 263 264 asort( $theme_files ); 265 266 $wp_themes = array(); 267 268 foreach ( (array) $theme_files as $theme_file ) { 269 $theme_root = $theme_file['theme_root']; 270 $theme_file = $theme_file['theme_file']; 271 272 if ( !is_readable("$theme_root/$theme_file") ) { 273 $wp_broken_themes[$theme_file] = array('Name' => $theme_file, 'Title' => $theme_file, 'Description' => __('File not readable.')); 274 continue; 275 } 276 277 $theme_data = get_theme_data("$theme_root/$theme_file"); 278 279 $name = $theme_data['Name']; 280 $title = $theme_data['Title']; 281 $description = wptexturize($theme_data['Description']); 282 $version = $theme_data['Version']; 283 $author = $theme_data['Author']; 284 $template = $theme_data['Template']; 285 $stylesheet = dirname($theme_file); 286 287 $screenshot = false; 288 foreach ( array('png', 'gif', 'jpg', 'jpeg') as $ext ) { 289 if (file_exists("$theme_root/$stylesheet/screenshot.$ext")) { 290 $screenshot = "screenshot.$ext"; 291 break; 292 } 293 } 294 295 if ( empty($name) ) { 296 $name = dirname($theme_file); 297 $title = $name; 298 } 299 300 if ( empty($template) ) { 301 if ( file_exists("$theme_root/$stylesheet/index.php") ) 302 $template = $stylesheet; 303 else 304 continue; 305 } 306 307 $template = trim( $template ); 308 309 if ( !file_exists("$theme_root/$template/index.php") ) { 310 $parent_dir = dirname(dirname($theme_file)); 311 if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { 312 $template = "$parent_dir/$template"; 313 $template_directory = "$theme_root/$template"; 314 } else { 315 /** 316 * The parent theme doesn't exist in the current theme's folder or sub folder 317 * so lets use the theme root for the parent template. 318 */ 319 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { 320 $template_directory = $theme_files[$template]['theme_root'] . "/$template"; 321 } else { 322 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.')); 323 continue; 324 } 325 326 } 327 } else { 328 $template_directory = trim( $theme_root . '/' . $template ); 329 } 330 331 $stylesheet_files = array(); 332 $template_files = array(); 333 334 $stylesheet_dir = @ dir("$theme_root/$stylesheet"); 335 if ( $stylesheet_dir ) { 336 while ( ($file = $stylesheet_dir->read()) !== false ) { 337 if ( !preg_match('|^\.+$|', $file) ) { 338 if ( preg_match('|\.css$|', $file) ) 339 $stylesheet_files[] = "$theme_root/$stylesheet/$file"; 340 elseif ( preg_match('|\.php$|', $file) ) 341 $template_files[] = "$theme_root/$stylesheet/$file"; 342 } 343 } 344 @ $stylesheet_dir->close(); 345 } 346 347 $template_dir = @ dir("$template_directory"); 348 if ( $template_dir ) { 349 while ( ($file = $template_dir->read()) !== false ) { 350 if ( preg_match('|^\.+$|', $file) ) 351 continue; 352 if ( preg_match('|\.php$|', $file) ) { 353 $template_files[] = "$template_directory/$file"; 354 } elseif ( is_dir("$template_directory/$file") ) { 355 $template_subdir = @ dir("$template_directory/$file"); 356 if ( !$template_subdir ) 357 continue; 358 while ( ($subfile = $template_subdir->read()) !== false ) { 359 if ( preg_match('|^\.+$|', $subfile) ) 360 continue; 361 if ( preg_match('|\.php$|', $subfile) ) 362 $template_files[] = "$template_directory/$file/$subfile"; 363 } 364 @ $template_subdir->close(); 365 } 366 } 367 @ $template_dir->close(); 368 } 369 370 //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes 371 $template_files = array_unique($template_files); 372 $stylesheet_files = array_unique($stylesheet_files); 373 374 $template_dir = dirname($template_files[0]); 375 $stylesheet_dir = dirname($stylesheet_files[0]); 376 377 if ( empty($template_dir) ) 378 $template_dir = '/'; 379 if ( empty($stylesheet_dir) ) 380 $stylesheet_dir = '/'; 381 382 // Check for theme name collision. This occurs if a theme is copied to 383 // a new theme directory and the theme header is not updated. Whichever 384 // theme is first keeps the name. Subsequent themes get a suffix applied. 385 // The Default and Classic themes always trump their pretenders. 386 if ( isset($wp_themes[$name]) ) { 387 if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) && 388 ('default' == $stylesheet || 'classic' == $stylesheet) ) { 389 // If another theme has claimed to be one of our default themes, move 390 // them aside. 391 $suffix = $wp_themes[$name]['Stylesheet']; 392 $new_name = "$name/$suffix"; 393 $wp_themes[$new_name] = $wp_themes[$name]; 394 $wp_themes[$new_name]['Name'] = $new_name; 395 } else { 396 $name = "$name/$stylesheet"; 397 } 398 } 399 400 $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); 401 $wp_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'], 'Theme Root' => $theme_root, 'Theme Root URI' => str_replace( WP_CONTENT_DIR, content_url(), $theme_root ) ); 402 } 403 404 unset($theme_files); 405 406 /* Store theme roots in the DB */ 407 if ( get_site_transient( 'theme_roots' ) != $theme_roots ) 408 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 409 unset($theme_roots); 410 411 /* Resolve theme dependencies. */ 412 $theme_names = array_keys( $wp_themes ); 413 foreach ( (array) $theme_names as $theme_name ) { 414 $wp_themes[$theme_name]['Parent Theme'] = ''; 415 if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { 416 foreach ( (array) $theme_names as $parent_theme_name ) { 417 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { 418 $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; 419 break; 420 } 421 } 422 } 423 } 424 425 return $wp_themes; 426 } 427 428 /** 429 * Retrieve theme roots. 430 * 431 * @since 2.9.0 432 * 433 * @return array Theme roots 434 */ 435 function get_theme_roots() { 436 $theme_roots = get_site_transient( 'theme_roots' ); 437 if ( false === $theme_roots ) { 438 get_themes(); 439 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() 440 } 441 return $theme_roots; 442 } 443 444 /** 445 * Retrieve theme data. 446 * 447 * @since 1.5.0 448 * 449 * @param string $theme Theme name. 450 * @return array|null Null, if theme name does not exist. Theme data, if exists. 451 */ 452 function get_theme($theme) { 453 $themes = get_themes(); 454 455 if ( array_key_exists($theme, $themes) ) 456 return $themes[$theme]; 457 458 return null; 459 } 460 461 /** 462 * Retrieve current theme display name. 463 * 464 * If the 'current_theme' option has already been set, then it will be returned 465 * instead. If it is not set, then each theme will be iterated over until both 466 * the current stylesheet and current template name. 467 * 468 * @since 1.5.0 469 * 470 * @return string 471 */ 472 function get_current_theme() { 473 if ( $theme = get_option('current_theme') ) 474 return $theme; 475 476 $themes = get_themes(); 477 $theme_names = array_keys($themes); 478 $current_template = get_option('template'); 479 $current_stylesheet = get_option('stylesheet'); 480 $current_theme = 'WordPress Default'; 481 482 if ( $themes ) { 483 foreach ( (array) $theme_names as $theme_name ) { 484 if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && 485 $themes[$theme_name]['Template'] == $current_template ) { 486 $current_theme = $themes[$theme_name]['Name']; 487 break; 488 } 489 } 490 } 491 492 update_option('current_theme', $current_theme); 493 494 return $current_theme; 495 } 496 497 /** 498 * Register a directory that contains themes. 499 * 500 * @since 2.9.0 501 * 502 * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR 503 * @return bool 504 */ 505 function register_theme_directory( $directory) { 506 global $wp_theme_directories; 507 508 /* If this folder does not exist, return and do not register */ 509 if ( !file_exists( $directory ) ) 510 /* Try prepending as the theme directory could be relative to the content directory */ 511 $registered_directory = WP_CONTENT_DIR . '/' . $directory; 512 else 513 $registered_directory = $directory; 514 515 /* If this folder does not exist, return and do not register */ 516 if ( !file_exists( $registered_directory ) ) 517 return false; 518 519 $wp_theme_directories[] = $registered_directory; 520 521 return true; 522 } 523 524 /** 525 * Search all registered theme directories for complete and valid themes. 526 * 527 * @since 2.9.0 528 * 529 * @return array Valid themes found 530 */ 531 function search_theme_directories() { 532 global $wp_theme_directories, $wp_broken_themes; 533 if ( empty( $wp_theme_directories ) ) 534 return false; 535 536 $theme_files = array(); 537 $wp_broken_themes = array(); 538 539 /* Loop the registered theme directories and extract all themes */ 540 foreach ( (array) $wp_theme_directories as $theme_root ) { 541 $theme_loc = $theme_root; 542 543 /* We don't want to replace all forward slashes, see Trac #4541 */ 544 if ( '/' != WP_CONTENT_DIR ) 545 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 546 547 /* Files in the root of the current theme directory and one subdir down */ 548 $themes_dir = @ opendir($theme_root); 549 550 if ( !$themes_dir ) 551 return false; 552 553 while ( ($theme_dir = readdir($themes_dir)) !== false ) { 554 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 555 if ( $theme_dir{0} == '.' || $theme_dir == 'CVS' ) 556 continue; 557 558 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 559 $found_stylesheet = false; 560 561 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 562 if ( $theme_file == 'style.css' ) { 563 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 564 $found_stylesheet = true; 565 break; 566 } 567 } 568 @closedir($stylish_dir); 569 570 if ( !$found_stylesheet ) { // look for themes in that dir 571 $subdir = "$theme_root/$theme_dir"; 572 $subdir_name = $theme_dir; 573 $theme_subdirs = @opendir( $subdir ); 574 575 $found_subdir_themes = false; 576 while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 577 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 578 if ( $theme_subdir{0} == '.' || $theme_subdir == 'CVS' ) 579 continue; 580 581 $stylish_dir = @opendir($subdir . '/' . $theme_subdir); 582 $found_stylesheet = false; 583 584 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 585 if ( $theme_file == 'style.css' ) { 586 $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 587 $found_stylesheet = true; 588 $found_subdir_themes = true; 589 break; 590 } 591 } 592 @closedir($stylish_dir); 593 } 594 } 595 @closedir($theme_subdir); 596 if ( !$found_subdir_themes ) 597 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 598 } 599 } 600 } 601 if ( is_dir( $theme_dir ) ) 602 @closedir( $theme_dir ); 603 } 604 return $theme_files; 605 } 606 607 /** 608 * Retrieve path to themes directory. 609 * 610 * Does not have trailing slash. 611 * 612 * @since 1.5.0 613 * @param $stylesheet_or_template The stylesheet or template name of the theme 614 * @uses apply_filters() Calls 'theme_root' filter on path. 615 * 616 * @return string Theme path. 617 */ 618 function get_theme_root( $stylesheet_or_template = false ) { 619 if ($stylesheet_or_template) { 620 $theme_roots = get_theme_roots(); 621 622 if ( $theme_roots[$stylesheet_or_template] ) 623 $theme_root = WP_CONTENT_DIR . $theme_roots[$stylesheet_or_template]; 624 else 625 $theme_root = WP_CONTENT_DIR . '/themes'; 626 } else { 627 $theme_root = WP_CONTENT_DIR . '/themes'; 628 } 629 630 return apply_filters( 'theme_root', $theme_root ); 631 } 632 633 /** 634 * Retrieve URI for themes directory. 635 * 636 * Does not have trailing slash. 637 * 638 * @since 1.5.0 639 * @param $stylesheet_or_template The stylesheet or template name of the theme 640 * 641 * @return string Themes URI. 642 */ 643 function get_theme_root_uri( $stylesheet_or_template = false ) { 644 $theme_roots = get_theme_roots(); 645 646 if ( $theme_roots[$stylesheet_or_template] ) 647 $theme_root_uri = content_url( $theme_roots[$stylesheet_or_template] ); 648 else 649 $theme_root_uri = content_url( 'themes' ); 650 651 return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template ); 652 } 653 654 /** 655 * Retrieve path to file without the use of extension. 656 * 657 * Used to quickly retrieve the path of file without including the file 658 * extension. It will also check the parent template, if the file exists, with 659 * the use of {@link locate_template()}. Allows for more generic file location 660 * without the use of the other get_*_template() functions. 661 * 662 * Can be used with include() or require() to retrieve path. 663 * <code> 664 * if( '' != get_query_template( '404' ) ) 665 * include( get_query_template( '404' ) ); 666 * </code> 667 * or the same can be accomplished with 668 * <code> 669 * if( '' != get_404_template() ) 670 * include( get_404_template() ); 671 * </code> 672 * 673 * @since 1.5.0 674 * 675 * @param string $type Filename without extension. 676 * @return string Full path to file. 677 */ 678 function get_query_template($type) { 679 $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); 680 return apply_filters("{$type}_template", locate_template(array("{$type}.php"))); 681 } 682 683 /** 684 * Retrieve path of 404 template in current or parent template. 685 * 686 * @since 1.5.0 687 * 688 * @return string 689 */ 690 function get_404_template() { 691 return get_query_template('404'); 692 } 693 694 /** 695 * Retrieve path of archive template in current or parent template. 696 * 697 * @since 1.5.0 698 * 699 * @return string 700 */ 701 function get_archive_template() { 702 return get_query_template('archive'); 703 } 704 705 /** 706 * Retrieve path of author template in current or parent template. 707 * 708 * @since 1.5.0 709 * 710 * @return string 711 */ 712 function get_author_template() { 713 return get_query_template('author'); 714 } 715 716 /** 717 * Retrieve path of category template in current or parent template. 718 * 719 * Works by first retrieving the current slug for example 'category-default.php' and then 720 * trying category ID, for example 'category-1.php' and will finally fallback to category.php 721 * template, if those files don't exist. 722 * 723 * @since 1.5.0 724 * @uses apply_filters() Calls 'category_template' on file path of category template. 725 * 726 * @return string 727 */ 728 function get_category_template() { 729 $cat_ID = absint( get_query_var('cat') ); 730 $category = get_category( $cat_ID ); 731 732 $templates = array(); 733 734 if ( !is_wp_error($category) ) 735 $templates[] = "category-{$category->slug}.php"; 736 737 $templates[] = "category-$cat_ID.php"; 738 $templates[] = "category.php"; 739 740 $template = locate_template($templates); 741 return apply_filters('category_template', $template); 742 } 743 744 /** 745 * Retrieve path of tag template in current or parent template. 746 * 747 * Works by first retrieving the current tag name, for example 'tag-wordpress.php' and then 748 * trying tag ID, for example 'tag-1.php' and will finally fallback to tag.php 749 * template, if those files don't exist. 750 * 751 * @since 2.3.0 752 * @uses apply_filters() Calls 'tag_template' on file path of tag template. 753 * 754 * @return string 755 */ 756 function get_tag_template() { 757 $tag_id = absint( get_query_var('tag_id') ); 758 $tag_name = get_query_var('tag'); 759 760 $templates = array(); 761 762 if ( $tag_name ) 763 $templates[] = "tag-$tag_name.php"; 764 if ( $tag_id ) 765 $templates[] = "tag-$tag_id.php"; 766 $templates[] = "tag.php"; 767 768 $template = locate_template($templates); 769 return apply_filters('tag_template', $template); 770 } 771 772 /** 773 * Retrieve path of taxonomy template in current or parent template. 774 * 775 * Retrieves the taxonomy and term, if term is available. The template is 776 * prepended with 'taxonomy-' and followed by both the taxonomy string and 777 * the taxonomy string followed by a dash and then followed by the term. 778 * 779 * The taxonomy and term template is checked and used first, if it exists. 780 * Second, just the taxonomy template is checked, and then finally, taxonomy.php 781 * template is used. If none of the files exist, then it will fall back on to 782 * index.php. 783 * 784 * @since unknown (2.6.0 most likely) 785 * @uses apply_filters() Calls 'taxonomy_template' filter on found path. 786 * 787 * @return string 788 */ 789 function get_taxonomy_template() { 790 $taxonomy = get_query_var('taxonomy'); 791 $term = get_query_var('term'); 792 793 $templates = array(); 794 if ( $taxonomy && $term ) 795 $templates[] = "taxonomy-$taxonomy-$term.php"; 796 if ( $taxonomy ) 797 $templates[] = "taxonomy-$taxonomy.php"; 798 799 $templates[] = "taxonomy.php"; 800 801 $template = locate_template($templates); 802 return apply_filters('taxonomy_template', $template); 803 } 804 805 /** 806 * Retrieve path of date template in current or parent template. 807 * 808 * @since 1.5.0 809 * 810 * @return string 811 */ 812 function get_date_template() { 813 return get_query_template('date'); 814 } 815 816 /** 817 * Retrieve path of home template in current or parent template. 818 * 819 * Attempts to locate 'home.php' first before falling back to 'index.php'. 820 * 821 * @since 1.5.0 822 * @uses apply_filters() Calls 'home_template' on file path of home template. 823 * 824 * @return string 825 */ 826 function get_home_template() { 827 $template = locate_template(array('home.php', 'index.php')); 828 return apply_filters('home_template', $template); 829 } 830 831 /** 832 * Retrieve path of page template in current or parent template. 833 * 834 * Will first look for the specifically assigned page template 835 * The will search for 'page-{slug}.php' followed by 'page-id.php' 836 * and finally 'page.php' 837 * 838 * @since 1.5.0 839 * 840 * @return string 841 */ 842 function get_page_template() { 843 global $wp_query; 844 845 $id = (int) $wp_query->post->ID; 846 $template = get_post_meta($id, '_wp_page_template', true); 847 $pagename = get_query_var('pagename'); 848 849 if ( 'default' == $template ) 850 $template = ''; 851 852 $templates = array(); 853 if ( !empty($template) && !validate_file($template) ) 854 $templates[] = $template; 855 if ( $pagename ) 856 $templates[] = "page-$pagename.php"; 857 if ( $id ) 858 $templates[] = "page-$id.php"; 859 $templates[] = "page.php"; 860 861 return apply_filters('page_template', locate_template($templates)); 862 } 863 864 /** 865 * Retrieve path of paged template in current or parent template. 866 * 867 * @since 1.5.0 868 * 869 * @return string 870 */ 871 function get_paged_template() { 872 return get_query_template('paged'); 873 } 874 875 /** 876 * Retrieve path of search template in current or parent template. 877 * 878 * @since 1.5.0 879 * 880 * @return string 881 */ 882 function get_search_template() { 883 return get_query_template('search'); 884 } 885 886 /** 887 * Retrieve path of single template in current or parent template. 888 * 889 * @since 1.5.0 890 * 891 * @return string 892 */ 893 function get_single_template() { 894 return get_query_template('single'); 895 } 896 897 /** 898 * Retrieve path of attachment template in current or parent template. 899 * 900 * The attachment path first checks if the first part of the mime type exists. 901 * The second check is for the second part of the mime type. The last check is 902 * for both types separated by an underscore. If neither are found then the file 903 * 'attachment.php' is checked and returned. 904 * 905 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and 906 * finally 'text_plain.php'. 907 * 908 * @since 2.0.0 909 * 910 * @return string 911 */ 912 function get_attachment_template() { 913 global $posts; 914 $type = explode('/', $posts[0]->post_mime_type); 915 if ( $template = get_query_template($type[0]) ) 916 return $template; 917 elseif ( $template = get_query_template($type[1]) ) 918 return $template; 919 elseif ( $template = get_query_template("$type[0]_$type[1]") ) 920 return $template; 921 else 922 return get_query_template('attachment'); 923 } 924 925 /** 926 * Retrieve path of comment popup template in current or parent template. 927 * 928 * Checks for comment popup template in current template, if it exists or in the 929 * parent template. If it doesn't exist, then it retrieves the comment-popup.php 930 * file from the default theme. The default theme must then exist for it to 931 * work. 932 * 933 * @since 1.5.0 934 * @uses apply_filters() Calls 'comments_popup_template' filter on path. 935 * 936 * @return string 937 */ 938 function get_comments_popup_template() { 939 $template = locate_template(array("comments-popup.php")); 940 if ('' == $template) 941 $template = get_theme_root() . '/default/comments-popup.php'; 942 943 return apply_filters('comments_popup_template', $template); 944 } 945 946 /** 947 * Retrieve the name of the highest priority template file that exists. 948 * 949 * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which 950 * inherit from a parent theme can just overload one file. 951 * 952 * @since 2.7.0 953 * 954 * @param array $template_names Array of template files to search for in priority order. 955 * @param bool $load If true the template file will be loaded if it is found. 956 * @return string The template filename if one is located. 957 */ 958 function locate_template($template_names, $load = false) { 959 if (!is_array($template_names)) 960 return ''; 961 962 $located = ''; 963 foreach($template_names as $template_name) { 964 if ( file_exists(STYLESHEETPATH . '/' . $template_name)) { 965 $located = STYLESHEETPATH . '/' . $template_name; 966 break; 967 } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) { 968 $located = TEMPLATEPATH . '/' . $template_name; 969 break; 970 } 971 } 972 973 if ($load && '' != $located) 974 load_template($located); 975 976 return $located; 977 } 978 979 /** 980 * Require once the template file with WordPress environment. 981 * 982 * The globals are set up for the template file to ensure that the WordPress 983 * environment is available from within the function. The query variables are 984 * also available. 985 * 986 * @since 1.5.0 987 * 988 * @param string $_template_file Path to template file. 989 */ 990 function load_template($_template_file) { 991 global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; 992 993 if ( is_array($wp_query->query_vars) ) 994 extract($wp_query->query_vars, EXTR_SKIP); 995 996 require_once($_template_file); 997 } 998 999 /** 1000 * Display localized stylesheet link element. 1001 * 1002 * @since 2.1.0 1003 */ 1004 function locale_stylesheet() { 1005 $stylesheet = get_locale_stylesheet_uri(); 1006 if ( empty($stylesheet) ) 1007 return; 1008 echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />'; 1009 } 1010 1011 /** 1012 * Start preview theme output buffer. 1013 * 1014 * Will only preform task if the user has permissions and template and preview 1015 * query variables exist. 1016 * 1017 * @since 2.6.0 1018 */ 1019 function preview_theme() { 1020 if ( ! (isset($_GET['template']) && isset($_GET['preview'])) ) 1021 return; 1022 1023 if ( !current_user_can( 'switch_themes' ) ) 1024 return; 1025 1026 $_GET['template'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['template']); 1027 1028 if ( validate_file($_GET['template']) ) 1029 return; 1030 1031 add_filter( 'template', '_preview_theme_template_filter' ); 1032 1033 if ( isset($_GET['stylesheet']) ) { 1034 $_GET['stylesheet'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['stylesheet']); 1035 if ( validate_file($_GET['stylesheet']) ) 1036 return; 1037 add_filter( 'stylesheet', '_preview_theme_stylesheet_filter' ); 1038 } 1039 1040 // Prevent theme mods to current theme being used on theme being previewed 1041 add_filter( 'pre_option_mods_' . get_current_theme(), create_function( '', "return array();" ) ); 1042 1043 ob_start( 'preview_theme_ob_filter' ); 1044 } 1045 add_action('setup_theme', 'preview_theme'); 1046 1047 /** 1048 * Private function to modify the current template when previewing a theme 1049 * 1050 * @since 2.9.0 1051 * @access private 1052 * 1053 * @return string 1054 */ 1055 function _preview_theme_template_filter() { 1056 return isset($_GET['template']) ? $_GET['template'] : ''; 1057 } 1058 1059 /** 1060 * Private function to modify the current stylesheet when previewing a theme 1061 * 1062 * @since 2.9.0 1063 * @access private 1064 * 1065 * @return string 1066 */ 1067 function _preview_theme_stylesheet_filter() { 1068 return isset($_GET['stylesheet']) ? $_GET['stylesheet'] : ''; 1069 } 1070 1071 /** 1072 * Callback function for ob_start() to capture all links in the theme. 1073 * 1074 * @since 2.6.0 1075 * @access private 1076 * 1077 * @param string $content 1078 * @return string 1079 */ 1080 function preview_theme_ob_filter( $content ) { 1081 return preg_replace_callback( "|(<a.*?href=([\"']))(.*?)([\"'].*?>)|", 'preview_theme_ob_filter_callback', $content ); 1082 } 1083 1084 /** 1085 * Manipulates preview theme links in order to control and maintain location. 1086 * 1087 * Callback function for preg_replace_callback() to accept and filter matches. 1088 * 1089 * @since 2.6.0 1090 * @access private 1091 * 1092 * @param array $matches 1093 * @return string 1094 */ 1095 function preview_theme_ob_filter_callback( $matches ) { 1096 if ( strpos($matches[4], 'onclick') !== false ) 1097 $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. 1098 if ( 1099 ( false !== strpos($matches[3], '/wp-admin/') ) 1100 || 1101 ( false !== strpos($matches[3], '://') && 0 !== strpos($matches[3], get_option('home')) ) 1102 || 1103 ( false !== strpos($matches[3], '/feed/') ) 1104 || 1105 ( false !== strpos($matches[3], '/trackback/') ) 1106 ) 1107 return $matches[1] . "#$matches[2] onclick=$matches[2]return false;" . $matches[4]; 1108 1109 $link = add_query_arg( array('preview' => 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'] ), $matches[3] ); 1110 if ( 0 === strpos($link, 'preview=1') ) 1111 $link = "?$link"; 1112 return $matches[1] . esc_attr( $link ) . $matches[4]; 1113 } 1114 1115 /** 1116 * Switches current theme to new template and stylesheet names. 1117 * 1118 * @since unknown 1119 * @uses do_action() Calls 'switch_theme' action on updated theme display name. 1120 * 1121 * @param string $template Template name 1122 * @param string $stylesheet Stylesheet name. 1123 */ 1124 function switch_theme($template, $stylesheet) { 1125 update_option('template', $template); 1126 update_option('stylesheet', $stylesheet); 1127 delete_option('current_theme'); 1128 $theme = get_current_theme(); 1129 do_action('switch_theme', $theme); 1130 } 1131 1132 /** 1133 * Checks that current theme files 'index.php' and 'style.css' exists. 1134 * 1135 * Does not check the 'default' theme. The 'default' theme should always exist 1136 * or should have another theme renamed to that template name and directory 1137 * path. Will switch theme to default if current theme does not validate. 1138 * You can use the 'validate_current_theme' filter to return FALSE to 1139 * disable this functionality. 1140 * 1141 * @since 1.5.0 1142 * 1143 * @return bool 1144 */ 1145 function validate_current_theme() { 1146 // Don't validate during an install/upgrade. 1147 if ( defined('WP_INSTALLING') || !apply_filters( 'validate_current_theme', true ) ) 1148 return true; 1149 1150 if ( get_template() != 'default' && !file_exists(get_template_directory() . '/index.php') ) { 1151 switch_theme('default', 'default'); 1152 return false; 1153 } 1154 1155 if ( get_stylesheet() != 'default' && !file_exists(get_template_directory() . '/style.css') ) { 1156 switch_theme('default', 'default'); 1157 return false; 1158 } 1159 1160 return true; 1161 } 1162 1163 /** 1164 * Retrieve theme modification value for the current theme. 1165 * 1166 * If the modification name does not exist, then the $default will be passed 1167 * through {@link http://php.net/sprintf sprintf()} PHP function with the first 1168 * string the template directory URI and the second string the stylesheet 1169 * directory URI. 1170 * 1171 * @since 2.1.0 1172 * @uses apply_filters() Calls 'theme_mod_$name' filter on the value. 1173 * 1174 * @param string $name Theme modification name. 1175 * @param bool|string $default 1176 * @return string 1177 */ 1178 function get_theme_mod($name, $default = false) { 1179 $theme = get_current_theme(); 1180 1181 $mods = get_option("mods_$theme"); 1182 1183 if ( isset($mods[$name]) ) 1184 return apply_filters( "theme_mod_$name", $mods[$name] ); 1185 1186 return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri(), get_stylesheet_directory_uri()) ); 1187 } 1188 1189 /** 1190 * Update theme modification value for the current theme. 1191 * 1192 * @since 2.1.0 1193 * 1194 * @param string $name Theme modification name. 1195 * @param string $value theme modification value. 1196 */ 1197 function set_theme_mod($name, $value) { 1198 $theme = get_current_theme(); 1199 1200 $mods = get_option("mods_$theme"); 1201 1202 $mods[$name] = $value; 1203 1204 update_option("mods_$theme", $mods); 1205 wp_cache_delete("mods_$theme", 'options'); 1206 } 1207 1208 /** 1209 * Remove theme modification name from current theme list. 1210 * 1211 * If removing the name also removes all elements, then the entire option will 1212 * be removed. 1213 * 1214 * @since 2.1.0 1215 * 1216 * @param string $name Theme modification name. 1217 * @return null 1218 */ 1219 function remove_theme_mod( $name ) { 1220 $theme = get_current_theme(); 1221 1222 $mods = get_option("mods_$theme"); 1223 1224 if ( !isset($mods[$name]) ) 1225 return; 1226 1227 unset($mods[$name]); 1228 1229 if ( empty($mods) ) 1230 return remove_theme_mods(); 1231 1232 update_option("mods_$theme", $mods); 1233 wp_cache_delete("mods_$theme", 'options'); 1234 } 1235 1236 /** 1237 * Remove theme modifications option for current theme. 1238 * 1239 * @since 2.1.0 1240 */ 1241 function remove_theme_mods() { 1242 $theme = get_current_theme(); 1243 1244 delete_option("mods_$theme"); 1245 } 1246 1247 /** 1248 * Retrieve text color for custom header. 1249 * 1250 * @since 2.1.0 1251 * @uses HEADER_TEXTCOLOR 1252 * 1253 * @return string 1254 */ 1255 function get_header_textcolor() { 1256 return get_theme_mod('header_textcolor', HEADER_TEXTCOLOR); 1257 } 1258 1259 /** 1260 * Display text color for custom header. 1261 * 1262 * @since 2.1.0 1263 */ 1264 function header_textcolor() { 1265 echo get_header_textcolor(); 1266 } 1267 1268 /** 1269 * Retrieve header image for custom header. 1270 * 1271 * @since 2.1.0 1272 * @uses HEADER_IMAGE 1273 * 1274 * @return string 1275 */ 1276 function get_header_image() { 1277 return get_theme_mod('header_image', HEADER_IMAGE); 1278 } 1279 1280 /** 1281 * Display header image path. 1282 * 1283 * @since 2.1.0 1284 */ 1285 function header_image() { 1286 echo get_header_image(); 1287 } 1288 1289 /** 1290 * Add callbacks for image header display. 1291 * 1292 * The parameter $header_callback callback will be required to display the 1293 * content for the 'wp_head' action. The parameter $admin_header_callback 1294 * callback will be added to Custom_Image_Header class and that will be added 1295 * to the 'admin_menu' action. 1296 * 1297 * @since 2.1.0 1298 * @uses Custom_Image_Header Sets up for $admin_header_callback for administration panel display. 1299 * 1300 * @param callback $header_callback Call on 'wp_head' action. 1301 * @param callback $admin_header_callback Call on administration panels. 1302 */ 1303 function add_custom_image_header($header_callback, $admin_header_callback) { 1304 if ( ! empty($header_callback) ) 1305 add_action('wp_head', $header_callback); 1306 1307 if ( ! is_admin() ) 1308 return; 1309 require_once (ABSPATH . 'wp-admin/custom-header.php'); 1310 $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback); 1311 add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init')); 1312 } 1313 1314 /** 1315 * Allows a theme to register its support of a certain feature 1316 * 1317 * Must be called in the themes functions.php file to work. 1318 * 1319 * @author Mark Jaquith 1320 * @since 2.9 1321 * @param string $feature the feature being added 1322 */ 1323 function add_theme_support( $feature ) { 1324 global $_wp_theme_features; 1325 1326 if ( func_num_args() == 1 ) 1327 $_wp_theme_features[$feature] = true; 1328 else 1329 $_wp_theme_features[$feature] = array_slice( func_get_args(), 1 ); 1330 } 1331 1332 /** 1333 * Checks a theme's support for a given feature 1334 * 1335 * @author Mark Jaquith 1336 * @since 2.9 1337 * @param string $feature the feature being checked 1338 * @return boolean 1339 */ 1340 1341 function current_theme_supports( $feature ) { 1342 global $_wp_theme_features; 1343 1344 if ( !isset( $_wp_theme_features[$feature] ) ) 1345 return false; 1346 1347 // If no args passed then no extra checks need be performed 1348 if ( func_num_args() <= 1 ) 1349 return true; 1350 1351 $args = array_slice( func_get_args(), 1 ); 1352 1353 // @todo Allow pluggable arg checking 1354 switch ( $feature ) { 1355 case 'post-thumbnails': 1356 // post-thumbnails can be registered for only certain content/post types by passing 1357 // an array of types to add_theme_support(). If no array was passed, then 1358 // any type is accepted 1359 if ( true === $_wp_theme_features[$feature] ) // Registered for all types 1360 return true; 1361 $content_type = $args[0]; 1362 if ( in_array($content_type, $_wp_theme_features[$feature][0]) ) 1363 return true; 1364 else 1365 return false; 1366 break; 1367 } 1368 1369 return true; 1370 } 1371 1372 /** 1373 * Checks a theme's support for a given feature before loading the functions which implement it. 1374 * 1375 * @author Peter Westwood 1376 * @since 2.9 1377 * @param string $feature the feature being checked 1378 * @param string $include the file containing the functions that implement the feature 1379 */ 1380 function require_if_theme_supports( $feature, $include) { 1381 if ( current_theme_supports( $feature ) ) 1382 require ( $include ); 1383 } 1384 1385 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Fri Jan 8 00:19:48 2010 | Cross-referenced by PHPXref 0.7 |