WordPress 3.0 beta 1 documentation kindly provided to you by Hay Kranen
| [ Index ] |
PHP Cross Reference of WordPress 3.0 beta 1 |
|
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[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 $parent_template = $template; 301 302 if ( empty($template) ) { 303 if ( file_exists("$theme_root/$stylesheet/index.php") ) 304 $template = $stylesheet; 305 else 306 continue; 307 } 308 309 $template = trim( $template ); 310 311 if ( !file_exists("$theme_root/$template/index.php") ) { 312 $parent_dir = dirname(dirname($theme_file)); 313 if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) { 314 $template = "$parent_dir/$template"; 315 $template_directory = "$theme_root/$template"; 316 } else { 317 /** 318 * The parent theme doesn't exist in the current theme's folder or sub folder 319 * so lets use the theme root for the parent template. 320 */ 321 if ( isset($theme_files[$template]) && file_exists( $theme_files[$template]['theme_root'] . "/$template/index.php" ) ) { 322 $template_directory = $theme_files[$template]['theme_root'] . "/$template"; 323 } else { 324 if ( empty( $parent_template) ) 325 $wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'), 'error' => 'no_template'); 326 else 327 $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 ); 328 continue; 329 } 330 331 } 332 } else { 333 $template_directory = trim( $theme_root . '/' . $template ); 334 } 335 336 $stylesheet_files = array(); 337 $template_files = array(); 338 339 $stylesheet_dir = @ dir("$theme_root/$stylesheet"); 340 if ( $stylesheet_dir ) { 341 while ( ($file = $stylesheet_dir->read()) !== false ) { 342 if ( !preg_match('|^\.+$|', $file) ) { 343 if ( preg_match('|\.css$|', $file) ) 344 $stylesheet_files[] = "$theme_root/$stylesheet/$file"; 345 elseif ( preg_match('|\.php$|', $file) ) 346 $template_files[] = "$theme_root/$stylesheet/$file"; 347 } 348 } 349 @ $stylesheet_dir->close(); 350 } 351 352 $template_dir = @ dir("$template_directory"); 353 if ( $template_dir ) { 354 while ( ($file = $template_dir->read()) !== false ) { 355 if ( preg_match('|^\.+$|', $file) ) 356 continue; 357 if ( preg_match('|\.php$|', $file) ) { 358 $template_files[] = "$template_directory/$file"; 359 } elseif ( is_dir("$template_directory/$file") ) { 360 $template_subdir = @ dir("$template_directory/$file"); 361 if ( !$template_subdir ) 362 continue; 363 while ( ($subfile = $template_subdir->read()) !== false ) { 364 if ( preg_match('|^\.+$|', $subfile) ) 365 continue; 366 if ( preg_match('|\.php$|', $subfile) ) 367 $template_files[] = "$template_directory/$file/$subfile"; 368 } 369 @ $template_subdir->close(); 370 } 371 } 372 @ $template_dir->close(); 373 } 374 375 //Make unique and remove duplicates when stylesheet and template are the same i.e. most themes 376 $template_files = array_unique($template_files); 377 $stylesheet_files = array_unique($stylesheet_files); 378 379 $template_dir = dirname($template_files[0]); 380 $stylesheet_dir = dirname($stylesheet_files[0]); 381 382 if ( empty($template_dir) ) 383 $template_dir = '/'; 384 if ( empty($stylesheet_dir) ) 385 $stylesheet_dir = '/'; 386 387 // Check for theme name collision. This occurs if a theme is copied to 388 // a new theme directory and the theme header is not updated. Whichever 389 // theme is first keeps the name. Subsequent themes get a suffix applied. 390 // The Default and Classic themes always trump their pretenders. 391 if ( isset($wp_themes[$name]) ) { 392 if ( ('WordPress Default' == $name || 'WordPress Classic' == $name) && 393 ('default' == $stylesheet || 'classic' == $stylesheet) ) { 394 // If another theme has claimed to be one of our default themes, move 395 // them aside. 396 $suffix = $wp_themes[$name]['Stylesheet']; 397 $new_name = "$name/$suffix"; 398 $wp_themes[$new_name] = $wp_themes[$name]; 399 $wp_themes[$new_name]['Name'] = $new_name; 400 } else { 401 $name = "$name/$stylesheet"; 402 } 403 } 404 405 $theme_roots[$stylesheet] = str_replace( WP_CONTENT_DIR, '', $theme_root ); 406 $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 ) ); 407 } 408 409 unset($theme_files); 410 411 /* Store theme roots in the DB */ 412 if ( get_site_transient( 'theme_roots' ) != $theme_roots ) 413 set_site_transient( 'theme_roots', $theme_roots, 7200 ); // cache for two hours 414 unset($theme_roots); 415 416 /* Resolve theme dependencies. */ 417 $theme_names = array_keys( $wp_themes ); 418 foreach ( (array) $theme_names as $theme_name ) { 419 $wp_themes[$theme_name]['Parent Theme'] = ''; 420 if ( $wp_themes[$theme_name]['Stylesheet'] != $wp_themes[$theme_name]['Template'] ) { 421 foreach ( (array) $theme_names as $parent_theme_name ) { 422 if ( ($wp_themes[$parent_theme_name]['Stylesheet'] == $wp_themes[$parent_theme_name]['Template']) && ($wp_themes[$parent_theme_name]['Template'] == $wp_themes[$theme_name]['Template']) ) { 423 $wp_themes[$theme_name]['Parent Theme'] = $wp_themes[$parent_theme_name]['Name']; 424 break; 425 } 426 } 427 } 428 } 429 430 return $wp_themes; 431 } 432 433 /** 434 * Retrieve theme roots. 435 * 436 * @since 2.9.0 437 * 438 * @return array Theme roots 439 */ 440 function get_theme_roots() { 441 $theme_roots = get_site_transient( 'theme_roots' ); 442 if ( false === $theme_roots ) { 443 get_themes(); 444 $theme_roots = get_site_transient( 'theme_roots' ); // this is set in get_theme() 445 } 446 return $theme_roots; 447 } 448 449 /** 450 * Retrieve theme data. 451 * 452 * @since 1.5.0 453 * 454 * @param string $theme Theme name. 455 * @return array|null Null, if theme name does not exist. Theme data, if exists. 456 */ 457 function get_theme($theme) { 458 $themes = get_themes(); 459 460 if ( array_key_exists($theme, $themes) ) 461 return $themes[$theme]; 462 463 return null; 464 } 465 466 /** 467 * Retrieve current theme display name. 468 * 469 * If the 'current_theme' option has already been set, then it will be returned 470 * instead. If it is not set, then each theme will be iterated over until both 471 * the current stylesheet and current template name. 472 * 473 * @since 1.5.0 474 * 475 * @return string 476 */ 477 function get_current_theme() { 478 if ( $theme = get_option('current_theme') ) 479 return $theme; 480 481 $themes = get_themes(); 482 $theme_names = array_keys($themes); 483 $current_template = get_option('template'); 484 $current_stylesheet = get_option('stylesheet'); 485 $current_theme = 'WordPress Default'; 486 487 if ( $themes ) { 488 foreach ( (array) $theme_names as $theme_name ) { 489 if ( $themes[$theme_name]['Stylesheet'] == $current_stylesheet && 490 $themes[$theme_name]['Template'] == $current_template ) { 491 $current_theme = $themes[$theme_name]['Name']; 492 break; 493 } 494 } 495 } 496 497 update_option('current_theme', $current_theme); 498 499 return $current_theme; 500 } 501 502 /** 503 * Register a directory that contains themes. 504 * 505 * @since 2.9.0 506 * 507 * @param string $directory Either the full filesystem path to a theme folder or a folder within WP_CONTENT_DIR 508 * @return bool 509 */ 510 function register_theme_directory( $directory) { 511 global $wp_theme_directories; 512 513 /* If this folder does not exist, return and do not register */ 514 if ( !file_exists( $directory ) ) 515 /* Try prepending as the theme directory could be relative to the content directory */ 516 $registered_directory = WP_CONTENT_DIR . '/' . $directory; 517 else 518 $registered_directory = $directory; 519 520 /* If this folder does not exist, return and do not register */ 521 if ( !file_exists( $registered_directory ) ) 522 return false; 523 524 $wp_theme_directories[] = $registered_directory; 525 526 return true; 527 } 528 529 /** 530 * Search all registered theme directories for complete and valid themes. 531 * 532 * @since 2.9.0 533 * 534 * @return array Valid themes found 535 */ 536 function search_theme_directories() { 537 global $wp_theme_directories, $wp_broken_themes; 538 if ( empty( $wp_theme_directories ) ) 539 return false; 540 541 $theme_files = array(); 542 $wp_broken_themes = array(); 543 544 /* Loop the registered theme directories and extract all themes */ 545 foreach ( (array) $wp_theme_directories as $theme_root ) { 546 $theme_loc = $theme_root; 547 548 /* We don't want to replace all forward slashes, see Trac #4541 */ 549 if ( '/' != WP_CONTENT_DIR ) 550 $theme_loc = str_replace(WP_CONTENT_DIR, '', $theme_root); 551 552 /* Files in the root of the current theme directory and one subdir down */ 553 $themes_dir = @ opendir($theme_root); 554 555 if ( !$themes_dir ) 556 return false; 557 558 while ( ($theme_dir = readdir($themes_dir)) !== false ) { 559 if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) { 560 if ( $theme_dir{0} == '.' || $theme_dir == 'CVS' ) 561 continue; 562 563 $stylish_dir = @opendir($theme_root . '/' . $theme_dir); 564 $found_stylesheet = false; 565 566 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 567 if ( $theme_file == 'style.css' ) { 568 $theme_files[$theme_dir] = array( 'theme_file' => $theme_dir . '/' . $theme_file, 'theme_root' => $theme_root ); 569 $found_stylesheet = true; 570 break; 571 } 572 } 573 @closedir($stylish_dir); 574 575 if ( !$found_stylesheet ) { // look for themes in that dir 576 $subdir = "$theme_root/$theme_dir"; 577 $subdir_name = $theme_dir; 578 $theme_subdirs = @opendir( $subdir ); 579 580 $found_subdir_themes = false; 581 while ( ($theme_subdir = readdir($theme_subdirs)) !== false ) { 582 if ( is_dir( $subdir . '/' . $theme_subdir) && is_readable($subdir . '/' . $theme_subdir) ) { 583 if ( $theme_subdir{0} == '.' || $theme_subdir == 'CVS' ) 584 continue; 585 586 $stylish_dir = @opendir($subdir . '/' . $theme_subdir); 587 $found_stylesheet = false; 588 589 while ( ($theme_file = readdir($stylish_dir)) !== false ) { 590 if ( $theme_file == 'style.css' ) { 591 $theme_files["$theme_dir/$theme_subdir"] = array( 'theme_file' => $subdir_name . '/' . $theme_subdir . '/' . $theme_file, 'theme_root' => $theme_root ); 592 $found_stylesheet = true; 593 $found_subdir_themes = true; 594 break; 595 } 596 } 597 @closedir($stylish_dir); 598 } 599 } 600 @closedir($theme_subdir); 601 if ( !$found_subdir_themes ) 602 $wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.')); 603 } 604 } 605 } 606 if ( is_dir( $theme_dir ) ) 607 @closedir( $theme_dir ); 608 } 609 return $theme_files; 610 } 611 612 /** 613 * Retrieve path to themes directory. 614 * 615 * Does not have trailing slash. 616 * 617 * @since 1.5.0 618 * @param $stylesheet_or_template The stylesheet or template name of the theme 619 * @uses apply_filters() Calls 'theme_root' filter on path. 620 * 621 * @return string Theme path. 622 */ 623 function get_theme_root( $stylesheet_or_template = false ) { 624 if ($stylesheet_or_template) { 625 $theme_roots = get_theme_roots(); 626 627 if ( ! empty( $theme_roots[$stylesheet_or_template] ) ) 628 $theme_root = WP_CONTENT_DIR . $theme_roots[$stylesheet_or_template]; 629 else 630 $theme_root = WP_CONTENT_DIR . '/themes'; 631 } else { 632 $theme_root = WP_CONTENT_DIR . '/themes'; 633 } 634 635 return apply_filters( 'theme_root', $theme_root ); 636 } 637 638 /** 639 * Retrieve URI for themes directory. 640 * 641 * Does not have trailing slash. 642 * 643 * @since 1.5.0 644 * @param $stylesheet_or_template The stylesheet or template name of the theme 645 * 646 * @return string Themes URI. 647 */ 648 function get_theme_root_uri( $stylesheet_or_template = false ) { 649 $theme_roots = get_theme_roots(); 650 651 if ( isset( $theme_roots[$stylesheet_or_template] ) && $theme_roots[$stylesheet_or_template] ) 652 $theme_root_uri = content_url( $theme_roots[$stylesheet_or_template] ); 653 else 654 $theme_root_uri = content_url( 'themes' ); 655 656 return apply_filters( 'theme_root_uri', $theme_root_uri, get_option('siteurl'), $stylesheet_or_template ); 657 } 658 659 /** 660 * Retrieve path to file without the use of extension. 661 * 662 * Used to quickly retrieve the path of file without including the file 663 * extension. It will also check the parent template, if the file exists, with 664 * the use of {@link locate_template()}. Allows for more generic file location 665 * without the use of the other get_*_template() functions. 666 * 667 * Can be used with include() or require() to retrieve path. 668 * <code> 669 * if( '' != get_query_template( '404' ) ) 670 * include( get_query_template( '404' ) ); 671 * </code> 672 * or the same can be accomplished with 673 * <code> 674 * if( '' != get_404_template() ) 675 * include( get_404_template() ); 676 * </code> 677 * 678 * @since 1.5.0 679 * 680 * @param string $type Filename without extension. 681 * @return string Full path to file. 682 */ 683 function get_query_template($type) { 684 $type = preg_replace( '|[^a-z0-9-]+|', '', $type ); 685 return apply_filters("{$type}_template", locate_template(array("{$type}.php"))); 686 } 687 688 /** 689 * Retrieve path of index template in current or parent template. 690 * 691 * @since 3.0.0 692 * 693 * @return string 694 */ 695 function get_index_template() { 696 return get_query_template('index'); 697 } 698 699 /** 700 * Retrieve path of 404 template in current or parent template. 701 * 702 * @since 1.5.0 703 * 704 * @return string 705 */ 706 function get_404_template() { 707 return get_query_template('404'); 708 } 709 710 /** 711 * Retrieve path of archive template in current or parent template. 712 * 713 * @since 1.5.0 714 * 715 * @return string 716 */ 717 function get_archive_template() { 718 return get_query_template('archive'); 719 } 720 721 /** 722 * Retrieve path of author template in current or parent template. 723 * 724 * @since 1.5.0 725 * 726 * @return string 727 */ 728 function get_author_template() { 729 $author_id = absint( get_query_var( 'author' ) ); 730 $author = get_user_by( 'id', $author_id ); 731 $author = $author->user_nicename; 732 733 $templates = array(); 734 735 if ( $author ) 736 $templates[] = "author-{$author}.php"; 737 if ( $author_id ) 738 $templates[] = "author-{$author_id}.php"; 739 $templates[] = 'author.php'; 740 741 $template = locate_template( $templates ); 742 return apply_filters( 'author_template', $template ); 743 } 744 745 /** 746 * Retrieve path of category template in current or parent template. 747 * 748 * Works by first retrieving the current slug for example 'category-default.php' and then 749 * trying category ID, for example 'category-1.php' and will finally fallback to category.php 750 * template, if those files don't exist. 751 * 752 * @since 1.5.0 753 * @uses apply_filters() Calls 'category_template' on file path of category template. 754 * 755 * @return string 756 */ 757 function get_category_template() { 758 $cat_ID = absint( get_query_var('cat') ); 759 $category = get_category( $cat_ID ); 760 761 $templates = array(); 762 763 if ( !is_wp_error($category) ) 764 $templates[] = "category-{$category->slug}.php"; 765 766 $templates[] = "category-$cat_ID.php"; 767 $templates[] = "category.php"; 768 769 $template = locate_template($templates); 770 return apply_filters('category_template', $template); 771 } 772 773 /** 774 * Retrieve path of tag template in current or parent template. 775 * 776 * Works by first retrieving the current tag name, for example 'tag-wordpress.php' and then 777 * trying tag ID, for example 'tag-1.php' and will finally fallback to tag.php 778 * template, if those files don't exist. 779 * 780 * @since 2.3.0 781 * @uses apply_filters() Calls 'tag_template' on file path of tag template. 782 * 783 * @return string 784 */ 785 function get_tag_template() { 786 $tag_id = absint( get_query_var('tag_id') ); 787 $tag_name = get_query_var('tag'); 788 789 $templates = array(); 790 791 if ( $tag_name ) 792 $templates[] = "tag-$tag_name.php"; 793 if ( $tag_id ) 794 $templates[] = "tag-$tag_id.php"; 795 $templates[] = "tag.php"; 796 797 $template = locate_template($templates); 798 return apply_filters('tag_template', $template); 799 } 800 801 /** 802 * Retrieve path of taxonomy template in current or parent template. 803 * 804 * Retrieves the taxonomy and term, if term is available. The template is 805 * prepended with 'taxonomy-' and followed by both the taxonomy string and 806 * the taxonomy string followed by a dash and then followed by the term. 807 * 808 * The taxonomy and term template is checked and used first, if it exists. 809 * Second, just the taxonomy template is checked, and then finally, taxonomy.php 810 * template is used. If none of the files exist, then it will fall back on to 811 * index.php. 812 * 813 * @since unknown (2.6.0 most likely) 814 * @uses apply_filters() Calls 'taxonomy_template' filter on found path. 815 * 816 * @return string 817 */ 818 function get_taxonomy_template() { 819 $taxonomy = get_query_var('taxonomy'); 820 $term = get_query_var('term'); 821 822 $templates = array(); 823 if ( $taxonomy && $term ) 824 $templates[] = "taxonomy-$taxonomy-$term.php"; 825 if ( $taxonomy ) 826 $templates[] = "taxonomy-$taxonomy.php"; 827 828 $templates[] = "taxonomy.php"; 829 830 $template = locate_template($templates); 831 return apply_filters('taxonomy_template', $template); 832 } 833 834 /** 835 * Retrieve path of date template in current or parent template. 836 * 837 * @since 1.5.0 838 * 839 * @return string 840 */ 841 function get_date_template() { 842 return get_query_template('date'); 843 } 844 845 /** 846 * Retrieve path of home template in current or parent template. 847 * 848 * Attempts to locate 'home.php' first before falling back to 'index.php'. 849 * 850 * @since 1.5.0 851 * @uses apply_filters() Calls 'home_template' on file path of home template. 852 * 853 * @return string 854 */ 855 function get_home_template() { 856 $template = locate_template(array('home.php', 'index.php')); 857 return apply_filters('home_template', $template); 858 } 859 860 /** 861 * Retrieve path of page template in current or parent template. 862 * 863 * Will first look for the specifically assigned page template 864 * The will search for 'page-{slug}.php' followed by 'page-id.php' 865 * and finally 'page.php' 866 * 867 * @since 1.5.0 868 * 869 * @return string 870 */ 871 function get_page_template() { 872 global $wp_query; 873 874 $id = (int) $wp_query->get_queried_object_id(); 875 $template = get_post_meta($id, '_wp_page_template', true); 876 $pagename = get_query_var('pagename'); 877 878 if ( 'default' == $template ) 879 $template = ''; 880 881 $templates = array(); 882 if ( !empty($template) && !validate_file($template) ) 883 $templates[] = $template; 884 if ( $pagename ) 885 $templates[] = "page-$pagename.php"; 886 if ( $id ) 887 $templates[] = "page-$id.php"; 888 $templates[] = "page.php"; 889 890 return apply_filters('page_template', locate_template($templates)); 891 } 892 893 /** 894 * Retrieve path of paged template in current or parent template. 895 * 896 * @since 1.5.0 897 * 898 * @return string 899 */ 900 function get_paged_template() { 901 return get_query_template('paged'); 902 } 903 904 /** 905 * Retrieve path of search template in current or parent template. 906 * 907 * @since 1.5.0 908 * 909 * @return string 910 */ 911 function get_search_template() { 912 return get_query_template('search'); 913 } 914 915 /** 916 * Retrieve path of single template in current or parent template. 917 * 918 * @since 1.5.0 919 * 920 * @return string 921 */ 922 function get_single_template() { 923 global $wp_query; 924 925 $object = $wp_query->get_queried_object(); 926 $templates = array('single-' . $object->post_type . '.php', 'single.php'); 927 return apply_filters('single_template', locate_template($templates)); 928 } 929 930 /** 931 * Retrieve path of attachment template in current or parent template. 932 * 933 * The attachment path first checks if the first part of the mime type exists. 934 * The second check is for the second part of the mime type. The last check is 935 * for both types separated by an underscore. If neither are found then the file 936 * 'attachment.php' is checked and returned. 937 * 938 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and 939 * finally 'text_plain.php'. 940 * 941 * @since 2.0.0 942 * 943 * @return string 944 */ 945 function get_attachment_template() { 946 global $posts; 947 $type = explode('/', $posts[0]->post_mime_type); 948 if ( $template = get_query_template($type[0]) ) 949 return $template; 950 elseif ( $template = get_query_template($type[1]) ) 951 return $template; 952 elseif ( $template = get_query_template("$type[0]_$type[1]") ) 953 return $template; 954 else 955 return get_query_template('attachment'); 956 } 957 958 /** 959 * Retrieve path of comment popup template in current or parent template. 960 * 961 * Checks for comment popup template in current template, if it exists or in the 962 * parent template. If it doesn't exist, then it retrieves the comment-popup.php 963 * file from the WP_FALLBACK_THEME theme. The WP_FALLBACK_THEME theme must then exist for it to 964 * work. 965 * 966 * @since 1.5.0 967 * @uses apply_filters() Calls 'comments_popup_template' filter on path. 968 * 969 * @return string 970 */ 971 function get_comments_popup_template() { 972 $template = locate_template(array("comments-popup.php")); 973 if ('' == $template) 974 $template = get_theme_root() . '/' . WP_FALLBACK_THEME . '/comments-popup.php'; 975 976 return apply_filters('comments_popup_template', $template); 977 } 978 979 /** 980 * Retrieve the name of the highest priority template file that exists. 981 * 982 * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which 983 * inherit from a parent theme can just overload one file. 984 * 985 * @since 2.7.0 986 * 987 * @param array $template_names Array of template files to search for in priority order. 988 * @param bool $load If true the template file will be loaded if it is found. 989 * @return string The template filename if one is located. 990 */ 991 function locate_template($template_names, $load = false) { 992 if ( !is_array($template_names) ) 993 return ''; 994 995 $located = ''; 996 foreach ( $template_names as $template_name ) { 997 if ( file_exists(STYLESHEETPATH . '/' . $template_name)) { 998 $located = STYLESHEETPATH . '/' . $template_name; 999 break; 1000 } else if ( file_exists(TEMPLATEPATH . '/' . $template_name) ) { 1001 $located = TEMPLATEPATH . '/' . $template_name; 1002 break; 1003 } 1004 } 1005 1006 if ( $load && '' != $located ) 1007 load_template($located); 1008 1009 return $located; 1010 } 1011 1012 /** 1013 * Require once the template file with WordPress environment. 1014 * 1015 * The globals are set up for the template file to ensure that the WordPress 1016 * environment is available from within the function. The query variables are 1017 * also available. 1018 * 1019 * @since 1.5.0 1020 * 1021 * @param string $_template_file Path to template file. 1022 */ 1023 function load_template($_template_file) { 1024 global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID; 1025 1026 if ( is_array($wp_query->query_vars) ) 1027 extract($wp_query->query_vars, EXTR_SKIP); 1028 1029 require_once($_template_file); 1030 } 1031 1032 /** 1033 * Display localized stylesheet link element. 1034 * 1035 * @since 2.1.0 1036 */ 1037 function locale_stylesheet() { 1038 $stylesheet = get_locale_stylesheet_uri(); 1039 if ( empty($stylesheet) ) 1040 return; 1041 echo '<link rel="stylesheet" href="' . $stylesheet . '" type="text/css" media="screen" />'; 1042 } 1043 1044 /** 1045 * Start preview theme output buffer. 1046 * 1047 * Will only preform task if the user has permissions and template and preview 1048 * query variables exist. 1049 * 1050 * @since 2.6.0 1051 */ 1052 function preview_theme() { 1053 if ( ! (isset($_GET['template']) && isset($_GET['preview'])) ) 1054 return; 1055 1056 if ( !current_user_can( 'switch_themes' ) ) 1057 return; 1058 1059 $_GET['template'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['template']); 1060 1061 if ( validate_file($_GET['template']) ) 1062 return; 1063 1064 add_filter( 'template', '_preview_theme_template_filter' ); 1065 1066 if ( isset($_GET['stylesheet']) ) { 1067 $_GET['stylesheet'] = preg_replace('|[^a-z0-9_./-]|i', '', $_GET['stylesheet']); 1068 if ( validate_file($_GET['stylesheet']) ) 1069 return; 1070 add_filter( 'stylesheet', '_preview_theme_stylesheet_filter' ); 1071 } 1072 1073 // Prevent theme mods to current theme being used on theme being previewed 1074 add_filter( 'pre_option_mods_' . get_current_theme(), create_function( '', "return array();" ) ); 1075 1076 ob_start( 'preview_theme_ob_filter' ); 1077 } 1078 add_action('setup_theme', 'preview_theme'); 1079 1080 /** 1081 * Private function to modify the current template when previewing a theme 1082 * 1083 * @since 2.9.0 1084 * @access private 1085 * 1086 * @return string 1087 */ 1088 function _preview_theme_template_filter() { 1089 return isset($_GET['template']) ? $_GET['template'] : ''; 1090 } 1091 1092 /** 1093 * Private function to modify the current stylesheet when previewing a theme 1094 * 1095 * @since 2.9.0 1096 * @access private 1097 * 1098 * @return string 1099 */ 1100 function _preview_theme_stylesheet_filter() { 1101 return isset($_GET['stylesheet']) ? $_GET['stylesheet'] : ''; 1102 } 1103 1104 /** 1105 * Callback function for ob_start() to capture all links in the theme. 1106 * 1107 * @since 2.6.0 1108 * @access private 1109 * 1110 * @param string $content 1111 * @return string 1112 */ 1113 function preview_theme_ob_filter( $content ) { 1114 return preg_replace_callback( "|(<a.*?href=([\"']))(.*?)([\"'].*?>)|", 'preview_theme_ob_filter_callback', $content ); 1115 } 1116 1117 /** 1118 * Manipulates preview theme links in order to control and maintain location. 1119 * 1120 * Callback function for preg_replace_callback() to accept and filter matches. 1121 * 1122 * @since 2.6.0 1123 * @access private 1124 * 1125 * @param array $matches 1126 * @return string 1127 */ 1128 function preview_theme_ob_filter_callback( $matches ) { 1129 if ( strpos($matches[4], 'onclick') !== false ) 1130 $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. 1131 if ( 1132 ( false !== strpos($matches[3], '/wp-admin/') ) 1133 || 1134 ( false !== strpos( $matches[3], '://' ) && 0 !== strpos( $matches[3], home_url() ) ) 1135 || 1136 ( false !== strpos($matches[3], '/feed/') ) 1137 || 1138 ( false !== strpos($matches[3], '/trackback/') ) 1139 ) 1140 return $matches[1] . "#$matches[2] onclick=$matches[2]return false;" . $matches[4]; 1141 1142 $link = add_query_arg( array('preview' => 1, 'template' => $_GET['template'], 'stylesheet' => @$_GET['stylesheet'] ), $matches[3] ); 1143 if ( 0 === strpos($link, 'preview=1') ) 1144 $link = "?$link"; 1145 return $matches[1] . esc_attr( $link ) . $matches[4]; 1146 } 1147 1148 /** 1149 * Switches current theme to new template and stylesheet names. 1150 * 1151 * @since unknown 1152 * @uses do_action() Calls 'switch_theme' action on updated theme display name. 1153 * 1154 * @param string $template Template name 1155 * @param string $stylesheet Stylesheet name. 1156 */ 1157 function switch_theme($template, $stylesheet) { 1158 update_option('template', $template); 1159 update_option('stylesheet', $stylesheet); 1160 delete_option('current_theme'); 1161 $theme = get_current_theme(); 1162 do_action('switch_theme', $theme); 1163 } 1164 1165 /** 1166 * Checks that current theme files 'index.php' and 'style.css' exists. 1167 * 1168 * Does not check the 'default' theme. The 'default' theme should always exist 1169 * or should have another theme renamed to that template name and directory 1170 * path. Will switch theme to default if current theme does not validate. 1171 * You can use the 'validate_current_theme' filter to return FALSE to 1172 * disable this functionality. 1173 * 1174 * @since 1.5.0 1175 * 1176 * @return bool 1177 */ 1178 function validate_current_theme() { 1179 // Don't validate during an install/upgrade. 1180 if ( defined('WP_INSTALLING') || !apply_filters( 'validate_current_theme', true ) ) 1181 return true; 1182 1183 if ( get_template() != WP_FALLBACK_THEME && !file_exists(get_template_directory() . '/index.php') ) { 1184 switch_theme( WP_FALLBACK_THEME, WP_FALLBACK_THEME ); 1185 return false; 1186 } 1187 1188 if ( get_stylesheet() != WP_FALLBACK_THEME && !file_exists(get_template_directory() . '/style.css') ) { 1189 switch_theme( WP_FALLBACK_THEME, WP_FALLBACK_THEME ); 1190 return false; 1191 } 1192 1193 return true; 1194 } 1195 1196 /** 1197 * Retrieve theme modification value for the current theme. 1198 * 1199 * If the modification name does not exist, then the $default will be passed 1200 * through {@link http://php.net/sprintf sprintf()} PHP function with the first 1201 * string the template directory URI and the second string the stylesheet 1202 * directory URI. 1203 * 1204 * @since 2.1.0 1205 * @uses apply_filters() Calls 'theme_mod_$name' filter on the value. 1206 * 1207 * @param string $name Theme modification name. 1208 * @param bool|string $default 1209 * @return string 1210 */ 1211 function get_theme_mod($name, $default = false) { 1212 $theme = get_current_theme(); 1213 1214 $mods = get_option( "mods_$theme" ); 1215 1216 if ( isset($mods[$name]) ) 1217 return apply_filters( "theme_mod_$name", $mods[$name] ); 1218 1219 return apply_filters( "theme_mod_$name", sprintf($default, get_template_directory_uri(), get_stylesheet_directory_uri()) ); 1220 } 1221 1222 /** 1223 * Update theme modification value for the current theme. 1224 * 1225 * @since 2.1.0 1226 * 1227 * @param string $name Theme modification name. 1228 * @param string $value theme modification value. 1229 */ 1230 function set_theme_mod($name, $value) { 1231 $theme = get_current_theme(); 1232 1233 $mods = get_option("mods_$theme"); 1234 1235 $mods[$name] = $value; 1236 1237 update_option("mods_$theme", $mods); 1238 wp_cache_delete("mods_$theme", 'options'); 1239 } 1240 1241 /** 1242 * Remove theme modification name from current theme list. 1243 * 1244 * If removing the name also removes all elements, then the entire option will 1245 * be removed. 1246 * 1247 * @since 2.1.0 1248 * 1249 * @param string $name Theme modification name. 1250 * @return null 1251 */ 1252 function remove_theme_mod( $name ) { 1253 $theme = get_current_theme(); 1254 1255 $mods = get_option("mods_$theme"); 1256 1257 if ( !isset($mods[$name]) ) 1258 return; 1259 1260 unset($mods[$name]); 1261 1262 if ( empty($mods) ) 1263 return remove_theme_mods(); 1264 1265 update_option("mods_$theme", $mods); 1266 wp_cache_delete("mods_$theme", 'options'); 1267 } 1268 1269 /** 1270 * Remove theme modifications option for current theme. 1271 * 1272 * @since 2.1.0 1273 */ 1274 function remove_theme_mods() { 1275 $theme = get_current_theme(); 1276 1277 delete_option("mods_$theme"); 1278 } 1279 1280 /** 1281 * Retrieve text color for custom header. 1282 * 1283 * @since 2.1.0 1284 * @uses HEADER_TEXTCOLOR 1285 * 1286 * @return string 1287 */ 1288 function get_header_textcolor() { 1289 return get_theme_mod('header_textcolor', HEADER_TEXTCOLOR); 1290 } 1291 1292 /** 1293 * Display text color for custom header. 1294 * 1295 * @since 2.1.0 1296 */ 1297 function header_textcolor() { 1298 echo get_header_textcolor(); 1299 } 1300 1301 /** 1302 * Retrieve header image for custom header. 1303 * 1304 * @since 2.1.0 1305 * @uses HEADER_IMAGE 1306 * 1307 * @return string 1308 */ 1309 function get_header_image() { 1310 return get_theme_mod('header_image', HEADER_IMAGE); 1311 } 1312 1313 /** 1314 * Display header image path. 1315 * 1316 * @since 2.1.0 1317 */ 1318 function header_image() { 1319 echo get_header_image(); 1320 } 1321 1322 /** 1323 * Add callbacks for image header display. 1324 * 1325 * The parameter $header_callback callback will be required to display the 1326 * content for the 'wp_head' action. The parameter $admin_header_callback 1327 * callback will be added to Custom_Image_Header class and that will be added 1328 * to the 'admin_menu' action. 1329 * 1330 * @since 2.1.0 1331 * @uses Custom_Image_Header Sets up for $admin_header_callback for administration panel display. 1332 * 1333 * @param callback $header_callback Call on 'wp_head' action. 1334 * @param callback $admin_header_callback Call on custom header administration screen. 1335 * @param callback $admin_image_div_callback Output a custom header image div on the custom header administration screen. Optional. 1336 */ 1337 function add_custom_image_header($header_callback, $admin_header_callback, $admin_image_div_callback = '') { 1338 if ( ! empty($header_callback) ) 1339 add_action('wp_head', $header_callback); 1340 1341 add_theme_support( 'custom-header' ); 1342 1343 if ( ! is_admin() ) 1344 return; 1345 require_once (ABSPATH . 'wp-admin/custom-header.php'); 1346 $GLOBALS['custom_image_header'] =& new Custom_Image_Header($admin_header_callback, $admin_image_div_callback); 1347 add_action('admin_menu', array(&$GLOBALS['custom_image_header'], 'init')); 1348 } 1349 1350 /** 1351 * Register a selection of default headers to be displayed by the custom header admin UI. 1352 * 1353 * @since 3.0.0 1354 * 1355 * @param array $headers Array of headers keyed by a string id. The ids point to arrays containing 'url', 'thumbnail_url', and 'description' keys. 1356 */ 1357 function register_default_headers( $headers ) { 1358 global $_wp_default_headers; 1359 1360 $_wp_default_headers = array_merge( (array) $_wp_default_headers, (array) $headers ); 1361 } 1362 1363 /** 1364 * Unregister default headers. 1365 * 1366 * This function must be called after register_default_headers() has already added the 1367 * header you want to remove. 1368 * 1369 * @see register_default_headers() 1370 * @since 3.0.0 1371 * 1372 * @param string|array The header string id (key of array) to remove, or an array thereof. 1373 * @return True on success, false on failure. 1374 */ 1375 function unregister_default_headers( $header ) { 1376 global $_wp_default_headers; 1377 if ( is_array( $header ) ) { 1378 array_map( 'unregister_default_headers', $header ); 1379 } elseif ( isset( $_wp_default_headers[ $header ] ) ) { 1380 unset( $_wp_default_headers[ $header ] ); 1381 return true; 1382 } else { 1383 return false; 1384 } 1385 } 1386 1387 /** 1388 * Retrieve background image for custom background. 1389 * 1390 * @since 3.0.0 1391 * 1392 * @return string 1393 */ 1394 function get_background_image() { 1395 $default = defined('BACKGROUND_IMAGE') ? BACKGROUND_IMAGE : ''; 1396 1397 return get_theme_mod('background_image', $default); 1398 } 1399 1400 /** 1401 * Display background image path. 1402 * 1403 * @since 3.0.0 1404 */ 1405 function background_image() { 1406 echo get_background_image(); 1407 } 1408 1409 /** 1410 * Retrieve value for custom background color. 1411 * 1412 * @since 3.0.0 1413 * @uses BACKGROUND_COLOR 1414 * 1415 * @return string 1416 */ 1417 function get_background_color() { 1418 $default = defined('BACKGROUND_COLOR') ? BACKGROUND_COLOR : ''; 1419 1420 return get_theme_mod('background_color', $default); 1421 } 1422 1423 /** 1424 * Display background color value. 1425 * 1426 * @since 3.0.0 1427 */ 1428 function background_color() { 1429 echo get_background_color(); 1430 } 1431 1432 /** 1433 * Add callbacks for background image display. 1434 * 1435 * The parameter $header_callback callback will be required to display the 1436 * content for the 'wp_head' action. The parameter $admin_header_callback 1437 * callback will be added to Custom_Background class and that will be added 1438 * to the 'admin_menu' action. 1439 * 1440 * @since 3.0.0 1441 * @uses Custom_Background Sets up for $admin_header_callback for administration panel display. 1442 * 1443 * @param callback $header_callback Call on 'wp_head' action. 1444 * @param callback $admin_header_callback Call on custom background administration screen. 1445 * @param callback $admin_image_div_callback Output a custom background image div on the custom background administration screen. Optional. 1446 */ 1447 function add_custom_background($header_callback = '', $admin_header_callback = '', $admin_image_div_callback = '') { 1448 if ( isset($GLOBALS['custom_background']) ) 1449 return; 1450 1451 if ( empty($header_callback) ) 1452 $header_callback = '_custom_background_cb'; 1453 1454 add_action('wp_head', $header_callback); 1455 1456 add_theme_support( 'custom-background' ); 1457 1458 if ( ! is_admin() ) 1459 return; 1460 require_once (ABSPATH . 'wp-admin/custom-background.php'); 1461 $GLOBALS['custom_background'] =& new Custom_Background($admin_header_callback, $admin_image_div_callback); 1462 add_action('admin_menu', array(&$GLOBALS['custom_background'], 'init')); 1463 } 1464 1465 /** 1466 * Default custom background callback. 1467 * 1468 * @since 3.0.0 1469 * @see add_custom_background() 1470 * @access protected 1471 */ 1472 function _custom_background_cb() { 1473 $background = get_background_image(); 1474 $color = get_background_color(); 1475 if ( !$background && !$color ) 1476 return; 1477 1478 switch ( get_theme_mod('background_repeat', 'repeat') ) { 1479 case 'no-repeat': 1480 $repeat = 'background-repeat: no-repeat;'; 1481 break; 1482 case 'repeat-x': 1483 $repeat = 'background-repeat: repeat-x;'; 1484 break; 1485 case 'repeat-y': 1486 $repeat = 'background-repeat: repeat-y;'; 1487 break; 1488 default: 1489 $repeat = 'background-repeat: repeat;'; 1490 } 1491 1492 switch ( get_theme_mod('background_position', 'left') ) { 1493 case 'center': 1494 $position = 'background-position: top center;'; 1495 break; 1496 case 'right': 1497 $position = 'background-position: top right;'; 1498 break; 1499 default: 1500 $position = 'background-position: top left;'; 1501 } 1502 1503 if ( 'scroll' == get_theme_mod('background_attachment', 'fixed') ) 1504 $attachment = 'background-attachment: scroll;'; 1505 else 1506 $attachment = 'background-attachment: fixed;'; 1507 1508 if ( !empty($background ) ) 1509 $image = "background-image: url('$background');"; 1510 else 1511 $image = ''; 1512 1513 if ( !empty($color) ) 1514 $color = "background-color: #$color;"; 1515 else 1516 $color = ''; 1517 ?> 1518 <style type="text/css"> 1519 body { 1520 <?php echo $image; ?> 1521 <?php echo $color; ?> 1522 <?php echo $repeat; ?> 1523 <?php echo $position; ?> 1524 <?php echo $attachment; ?> 1525 } 1526 </style> 1527 <?php 1528 } 1529 1530 /** 1531 * Add callback for custom TinyMCE editor stylesheets. 1532 * 1533 * The parameter $stylesheet is the name of the stylesheet, relative to 1534 * the theme root. It also accepts an array of stylesheets. 1535 * It is optional and defaults to 'editor-style.css'. 1536 * 1537 * @since 3.0.0 1538 * 1539 * @param mixed $stylesheet Optional. Stylesheet name or array thereof, relative to theme root. 1540 * Defaults to 'editor-style.css' 1541 */ 1542 function add_editor_style( $stylesheet = 'editor-style.css' ) { 1543 1544 add_theme_support( 'editor-style' ); 1545 1546 if ( ! is_admin() ) 1547 return; 1548 1549 global $editor_styles; 1550 $editor_styles = (array) $editor_styles; 1551 $stylesheet = (array) $stylesheet; 1552 $editor_styles = array_merge( $editor_styles, $stylesheet ); 1553 } 1554 1555 /** 1556 * Allows a theme to register its support of a certain feature 1557 * 1558 * Must be called in the theme's functions.php file to work. 1559 * If attached to a hook, it must be after_setup_theme. 1560 * The init hook may be too late for some features. 1561 * 1562 * @since 2.9.0 1563 * @param string $feature the feature being added 1564 */ 1565 function add_theme_support( $feature ) { 1566 global $_wp_theme_features; 1567 1568 if ( func_num_args() == 1 ) 1569 $_wp_theme_features[$feature] = true; 1570 else 1571 $_wp_theme_features[$feature] = array_slice( func_get_args(), 1 ); 1572 } 1573 1574 /** 1575 * Allows a theme to de-register its support of a certain feature 1576 * 1577 * Should be called in the theme's functions.php file. Generally would 1578 * be used for child themes to override support from the parent theme. 1579 * 1580 * @since 3.0.0 1581 * @see add_theme_support() 1582 * @param string $feature the feature being added 1583 * @return bool Whether feature was removed. 1584 */ 1585 function remove_theme_support( $feature ) { 1586 // Blacklist: for internal registrations not used directly by themes. 1587 if ( in_array( $feature, array( 'custom-background', 'custom-header', 'editor-style', 'widgets' ) ) ) 1588 return false; 1589 1590 global $_wp_theme_features; 1591 1592 if ( ! isset( $_wp_theme_features[$feature] ) ) 1593 return false; 1594 unset( $_wp_theme_features[$feature] ); 1595 return true; 1596 } 1597 1598 /** 1599 * Checks a theme's support for a given feature 1600 * 1601 * @since 2.9.0 1602 * @param string $feature the feature being checked 1603 * @return boolean 1604 */ 1605 function current_theme_supports( $feature ) { 1606 global $_wp_theme_features; 1607 1608 if ( !isset( $_wp_theme_features[$feature] ) ) 1609 return false; 1610 1611 // If no args passed then no extra checks need be performed 1612 if ( func_num_args() <= 1 ) 1613 return true; 1614 1615 $args = array_slice( func_get_args(), 1 ); 1616 1617 // @todo Allow pluggable arg checking 1618 switch ( $feature ) { 1619 case 'post-thumbnails': 1620 // post-thumbnails can be registered for only certain content/post types by passing 1621 // an array of types to add_theme_support(). If no array was passed, then 1622 // any type is accepted 1623 if ( true === $_wp_theme_features[$feature] ) // Registered for all types 1624 return true; 1625 $content_type = $args[0]; 1626 if ( in_array($content_type, $_wp_theme_features[$feature][0]) ) 1627 return true; 1628 else 1629 return false; 1630 break; 1631 } 1632 1633 return true; 1634 } 1635 1636 /** 1637 * Checks a theme's support for a given feature before loading the functions which implement it. 1638 * 1639 * @since 2.9.0 1640 * @param string $feature the feature being checked 1641 * @param string $include the file containing the functions that implement the feature 1642 */ 1643 function require_if_theme_supports( $feature, $include) { 1644 if ( current_theme_supports( $feature ) ) 1645 require ( $include ); 1646 } 1647 1648 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Apr 5 14:26:09 2010 | Cross-referenced by PHPXref 0.7 |