[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Link Template Functions 4 * 5 * @package WordPress 6 * @subpackage Template 7 */ 8 9 /** 10 * Display the permalink for the current post. 11 * 12 * @since 1.2.0 13 * @uses apply_filters() Calls 'the_permalink' filter on the permalink string. 14 */ 15 function the_permalink() { 16 echo esc_url( apply_filters( 'the_permalink', get_permalink() ) ); 17 } 18 19 /** 20 * Retrieve trailing slash string, if blog set for adding trailing slashes. 21 * 22 * Conditionally adds a trailing slash if the permalink structure has a trailing 23 * slash, strips the trailing slash if not. The string is passed through the 24 * 'user_trailingslashit' filter. Will remove trailing slash from string, if 25 * blog is not set to have them. 26 * 27 * @since 2.2.0 28 * @uses $wp_rewrite 29 * 30 * @param string $string URL with or without a trailing slash. 31 * @param string $type_of_url The type of URL being considered (e.g. single, category, etc) for use in the filter. 32 * @return string 33 */ 34 function user_trailingslashit($string, $type_of_url = '') { 35 global $wp_rewrite; 36 if ( $wp_rewrite->use_trailing_slashes ) 37 $string = trailingslashit($string); 38 else 39 $string = untrailingslashit($string); 40 41 // Note that $type_of_url can be one of following: 42 // single, single_trackback, single_feed, single_paged, feed, category, page, year, month, day, paged, post_type_archive 43 $string = apply_filters('user_trailingslashit', $string, $type_of_url); 44 return $string; 45 } 46 47 /** 48 * Display permalink anchor for current post. 49 * 50 * The permalink mode title will use the post title for the 'a' element 'id' 51 * attribute. The id mode uses 'post-' with the post ID for the 'id' attribute. 52 * 53 * @since 0.71 54 * 55 * @param string $mode Permalink mode can be either 'title', 'id', or default, which is 'id'. 56 */ 57 function permalink_anchor( $mode = 'id' ) { 58 $post = get_post(); 59 switch ( strtolower( $mode ) ) { 60 case 'title': 61 $title = sanitize_title( $post->post_title ) . '-' . $post->ID; 62 echo '<a id="'.$title.'"></a>'; 63 break; 64 case 'id': 65 default: 66 echo '<a id="post-' . $post->ID . '"></a>'; 67 break; 68 } 69 } 70 71 /** 72 * Retrieve full permalink for current post or post ID. 73 * 74 * @since 1.0.0 75 * 76 * @param int|WP_Post $id Optional. Post ID or post object, defaults to the current post. 77 * @param bool $leavename Optional. Whether to keep post name or page name, defaults to false. 78 * @return string|bool The permalink URL or false if post does not exist. 79 */ 80 function get_permalink( $id = 0, $leavename = false ) { 81 $rewritecode = array( 82 '%year%', 83 '%monthnum%', 84 '%day%', 85 '%hour%', 86 '%minute%', 87 '%second%', 88 $leavename? '' : '%postname%', 89 '%post_id%', 90 '%category%', 91 '%author%', 92 $leavename? '' : '%pagename%', 93 ); 94 95 if ( is_object($id) && isset($id->filter) && 'sample' == $id->filter ) { 96 $post = $id; 97 $sample = true; 98 } else { 99 $post = get_post($id); 100 $sample = false; 101 } 102 103 if ( empty($post->ID) ) 104 return false; 105 106 if ( $post->post_type == 'page' ) 107 return get_page_link($post->ID, $leavename, $sample); 108 elseif ( $post->post_type == 'attachment' ) 109 return get_attachment_link( $post->ID, $leavename ); 110 elseif ( in_array($post->post_type, get_post_types( array('_builtin' => false) ) ) ) 111 return get_post_permalink($post->ID, $leavename, $sample); 112 113 $permalink = get_option('permalink_structure'); 114 115 $permalink = apply_filters('pre_post_link', $permalink, $post, $leavename); 116 117 if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) { 118 $unixtime = strtotime($post->post_date); 119 120 $category = ''; 121 if ( strpos($permalink, '%category%') !== false ) { 122 $cats = get_the_category($post->ID); 123 if ( $cats ) { 124 usort($cats, '_usort_terms_by_ID'); // order by ID 125 $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post ); 126 $category_object = get_term( $category_object, 'category' ); 127 $category = $category_object->slug; 128 if ( $parent = $category_object->parent ) 129 $category = get_category_parents($parent, false, '/', true) . $category; 130 } 131 // show default category in permalinks, without 132 // having to assign it explicitly 133 if ( empty($category) ) { 134 $default_category = get_term( get_option( 'default_category' ), 'category' ); 135 $category = is_wp_error( $default_category ) ? '' : $default_category->slug; 136 } 137 } 138 139 $author = ''; 140 if ( strpos($permalink, '%author%') !== false ) { 141 $authordata = get_userdata($post->post_author); 142 $author = $authordata->user_nicename; 143 } 144 145 $date = explode(" ",date('Y m d H i s', $unixtime)); 146 $rewritereplace = 147 array( 148 $date[0], 149 $date[1], 150 $date[2], 151 $date[3], 152 $date[4], 153 $date[5], 154 $post->post_name, 155 $post->ID, 156 $category, 157 $author, 158 $post->post_name, 159 ); 160 $permalink = home_url( str_replace($rewritecode, $rewritereplace, $permalink) ); 161 $permalink = user_trailingslashit($permalink, 'single'); 162 } else { // if they're not using the fancy permalink option 163 $permalink = home_url('?p=' . $post->ID); 164 } 165 return apply_filters('post_link', $permalink, $post, $leavename); 166 } 167 168 /** 169 * Retrieve the permalink for a post with a custom post type. 170 * 171 * @since 3.0.0 172 * 173 * @param int $id Optional. Post ID. 174 * @param bool $leavename Optional, defaults to false. Whether to keep post name. 175 * @param bool $sample Optional, defaults to false. Is it a sample permalink. 176 * @return string 177 */ 178 function get_post_permalink( $id = 0, $leavename = false, $sample = false ) { 179 global $wp_rewrite; 180 181 $post = get_post($id); 182 183 if ( is_wp_error( $post ) ) 184 return $post; 185 186 $post_link = $wp_rewrite->get_extra_permastruct($post->post_type); 187 188 $slug = $post->post_name; 189 190 $draft_or_pending = isset($post->post_status) && in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ); 191 192 $post_type = get_post_type_object($post->post_type); 193 194 if ( !empty($post_link) && ( !$draft_or_pending || $sample ) ) { 195 if ( ! $leavename ) { 196 if ( $post_type->hierarchical ) 197 $slug = get_page_uri($id); 198 $post_link = str_replace("%$post->post_type%", $slug, $post_link); 199 } 200 $post_link = home_url( user_trailingslashit($post_link) ); 201 } else { 202 if ( $post_type->query_var && ( isset($post->post_status) && !$draft_or_pending ) ) 203 $post_link = add_query_arg($post_type->query_var, $slug, ''); 204 else 205 $post_link = add_query_arg(array('post_type' => $post->post_type, 'p' => $post->ID), ''); 206 $post_link = home_url($post_link); 207 } 208 209 return apply_filters('post_type_link', $post_link, $post, $leavename, $sample); 210 } 211 212 /** 213 * Retrieve permalink from post ID. 214 * 215 * @since 1.0.0 216 * 217 * @param int $post_id Optional. Post ID. 218 * @param mixed $deprecated Not used. 219 * @return string 220 */ 221 function post_permalink( $post_id = 0, $deprecated = '' ) { 222 if ( !empty( $deprecated ) ) 223 _deprecated_argument( __FUNCTION__, '1.3' ); 224 225 return get_permalink($post_id); 226 } 227 228 /** 229 * Retrieve the permalink for current page or page ID. 230 * 231 * Respects page_on_front. Use this one. 232 * 233 * @since 1.5.0 234 * 235 * @param int|object $post Optional. Post ID or object. 236 * @param bool $leavename Optional, defaults to false. Whether to keep page name. 237 * @param bool $sample Optional, defaults to false. Is it a sample permalink. 238 * @return string 239 */ 240 function get_page_link( $post = false, $leavename = false, $sample = false ) { 241 $post = get_post( $post ); 242 243 if ( 'page' == get_option( 'show_on_front' ) && $post->ID == get_option( 'page_on_front' ) ) 244 $link = home_url('/'); 245 else 246 $link = _get_page_link( $post, $leavename, $sample ); 247 248 return apply_filters( 'page_link', $link, $post->ID, $sample ); 249 } 250 251 /** 252 * Retrieve the page permalink. 253 * 254 * Ignores page_on_front. Internal use only. 255 * 256 * @since 2.1.0 257 * @access private 258 * 259 * @param int|object $post Optional. Post ID or object. 260 * @param bool $leavename Optional. Leave name. 261 * @param bool $sample Optional. Sample permalink. 262 * @return string 263 */ 264 function _get_page_link( $post = false, $leavename = false, $sample = false ) { 265 global $wp_rewrite; 266 267 $post = get_post( $post ); 268 269 $draft_or_pending = in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ); 270 271 $link = $wp_rewrite->get_page_permastruct(); 272 273 if ( !empty($link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) { 274 if ( ! $leavename ) { 275 $link = str_replace('%pagename%', get_page_uri( $post ), $link); 276 } 277 278 $link = home_url($link); 279 $link = user_trailingslashit($link, 'page'); 280 } else { 281 $link = home_url( '?page_id=' . $post->ID ); 282 } 283 284 return apply_filters( '_get_page_link', $link, $post->ID ); 285 } 286 287 /** 288 * Retrieve permalink for attachment. 289 * 290 * This can be used in the WordPress Loop or outside of it. 291 * 292 * @since 2.0.0 293 * 294 * @param int|object $post Optional. Post ID or object. 295 * @param bool $leavename Optional. Leave name. 296 * @return string 297 */ 298 function get_attachment_link( $post = null, $leavename = false ) { 299 global $wp_rewrite; 300 301 $link = false; 302 303 $post = get_post( $post ); 304 $parent = ( $post->post_parent > 0 && $post->post_parent != $post->ID ) ? get_post( $post->post_parent ) : false; 305 306 if ( $wp_rewrite->using_permalinks() && $parent ) { 307 if ( 'page' == $parent->post_type ) 308 $parentlink = _get_page_link( $post->post_parent ); // Ignores page_on_front 309 else 310 $parentlink = get_permalink( $post->post_parent ); 311 312 if ( is_numeric($post->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') ) 313 $name = 'attachment/' . $post->post_name; // <permalink>/<int>/ is paged so we use the explicit attachment marker 314 else 315 $name = $post->post_name; 316 317 if ( strpos($parentlink, '?') === false ) 318 $link = user_trailingslashit( trailingslashit($parentlink) . '%postname%' ); 319 320 if ( ! $leavename ) 321 $link = str_replace( '%postname%', $name, $link ); 322 } 323 324 if ( ! $link ) 325 $link = home_url( '/?attachment_id=' . $post->ID ); 326 327 return apply_filters( 'attachment_link', $link, $post->ID ); 328 } 329 330 /** 331 * Retrieve the permalink for the year archives. 332 * 333 * @since 1.5.0 334 * 335 * @param int|bool $year False for current year or year for permalink. 336 * @return string 337 */ 338 function get_year_link($year) { 339 global $wp_rewrite; 340 if ( !$year ) 341 $year = gmdate('Y', current_time('timestamp')); 342 $yearlink = $wp_rewrite->get_year_permastruct(); 343 if ( !empty($yearlink) ) { 344 $yearlink = str_replace('%year%', $year, $yearlink); 345 return apply_filters('year_link', home_url( user_trailingslashit($yearlink, 'year') ), $year); 346 } else { 347 return apply_filters('year_link', home_url('?m=' . $year), $year); 348 } 349 } 350 351 /** 352 * Retrieve the permalink for the month archives with year. 353 * 354 * @since 1.0.0 355 * 356 * @param bool|int $year False for current year. Integer of year. 357 * @param bool|int $month False for current month. Integer of month. 358 * @return string 359 */ 360 function get_month_link($year, $month) { 361 global $wp_rewrite; 362 if ( !$year ) 363 $year = gmdate('Y', current_time('timestamp')); 364 if ( !$month ) 365 $month = gmdate('m', current_time('timestamp')); 366 $monthlink = $wp_rewrite->get_month_permastruct(); 367 if ( !empty($monthlink) ) { 368 $monthlink = str_replace('%year%', $year, $monthlink); 369 $monthlink = str_replace('%monthnum%', zeroise(intval($month), 2), $monthlink); 370 return apply_filters('month_link', home_url( user_trailingslashit($monthlink, 'month') ), $year, $month); 371 } else { 372 return apply_filters('month_link', home_url( '?m=' . $year . zeroise($month, 2) ), $year, $month); 373 } 374 } 375 376 /** 377 * Retrieve the permalink for the day archives with year and month. 378 * 379 * @since 1.0.0 380 * 381 * @param bool|int $year False for current year. Integer of year. 382 * @param bool|int $month False for current month. Integer of month. 383 * @param bool|int $day False for current day. Integer of day. 384 * @return string 385 */ 386 function get_day_link($year, $month, $day) { 387 global $wp_rewrite; 388 if ( !$year ) 389 $year = gmdate('Y', current_time('timestamp')); 390 if ( !$month ) 391 $month = gmdate('m', current_time('timestamp')); 392 if ( !$day ) 393 $day = gmdate('j', current_time('timestamp')); 394 395 $daylink = $wp_rewrite->get_day_permastruct(); 396 if ( !empty($daylink) ) { 397 $daylink = str_replace('%year%', $year, $daylink); 398 $daylink = str_replace('%monthnum%', zeroise(intval($month), 2), $daylink); 399 $daylink = str_replace('%day%', zeroise(intval($day), 2), $daylink); 400 return apply_filters('day_link', home_url( user_trailingslashit($daylink, 'day') ), $year, $month, $day); 401 } else { 402 return apply_filters('day_link', home_url( '?m=' . $year . zeroise($month, 2) . zeroise($day, 2) ), $year, $month, $day); 403 } 404 } 405 406 /** 407 * Display the permalink for the feed type. 408 * 409 * @since 3.0.0 410 * 411 * @param string $anchor The link's anchor text. 412 * @param string $feed Optional, defaults to default feed. Feed type. 413 */ 414 function the_feed_link( $anchor, $feed = '' ) { 415 $link = '<a href="' . esc_url( get_feed_link( $feed ) ) . '">' . $anchor . '</a>'; 416 echo apply_filters( 'the_feed_link', $link, $feed ); 417 } 418 419 /** 420 * Retrieve the permalink for the feed type. 421 * 422 * @since 1.5.0 423 * 424 * @param string $feed Optional, defaults to default feed. Feed type. 425 * @return string 426 */ 427 function get_feed_link($feed = '') { 428 global $wp_rewrite; 429 430 $permalink = $wp_rewrite->get_feed_permastruct(); 431 if ( '' != $permalink ) { 432 if ( false !== strpos($feed, 'comments_') ) { 433 $feed = str_replace('comments_', '', $feed); 434 $permalink = $wp_rewrite->get_comment_feed_permastruct(); 435 } 436 437 if ( get_default_feed() == $feed ) 438 $feed = ''; 439 440 $permalink = str_replace('%feed%', $feed, $permalink); 441 $permalink = preg_replace('#/+#', '/', "/$permalink"); 442 $output = home_url( user_trailingslashit($permalink, 'feed') ); 443 } else { 444 if ( empty($feed) ) 445 $feed = get_default_feed(); 446 447 if ( false !== strpos($feed, 'comments_') ) 448 $feed = str_replace('comments_', 'comments-', $feed); 449 450 $output = home_url("?feed={$feed}"); 451 } 452 453 return apply_filters('feed_link', $output, $feed); 454 } 455 456 /** 457 * Retrieve the permalink for the post comments feed. 458 * 459 * @since 2.2.0 460 * 461 * @param int $post_id Optional. Post ID. 462 * @param string $feed Optional. Feed type. 463 * @return string 464 */ 465 function get_post_comments_feed_link($post_id = 0, $feed = '') { 466 $post_id = absint( $post_id ); 467 468 if ( ! $post_id ) 469 $post_id = get_the_ID(); 470 471 if ( empty( $feed ) ) 472 $feed = get_default_feed(); 473 474 if ( '' != get_option('permalink_structure') ) { 475 if ( 'page' == get_option('show_on_front') && $post_id == get_option('page_on_front') ) 476 $url = _get_page_link( $post_id ); 477 else 478 $url = get_permalink($post_id); 479 480 $url = trailingslashit($url) . 'feed'; 481 if ( $feed != get_default_feed() ) 482 $url .= "/$feed"; 483 $url = user_trailingslashit($url, 'single_feed'); 484 } else { 485 $type = get_post_field('post_type', $post_id); 486 if ( 'page' == $type ) 487 $url = add_query_arg( array( 'feed' => $feed, 'page_id' => $post_id ), home_url( '/' ) ); 488 else 489 $url = add_query_arg( array( 'feed' => $feed, 'p' => $post_id ), home_url( '/' ) ); 490 } 491 492 return apply_filters('post_comments_feed_link', $url); 493 } 494 495 /** 496 * Display the comment feed link for a post. 497 * 498 * Prints out the comment feed link for a post. Link text is placed in the 499 * anchor. If no link text is specified, default text is used. If no post ID is 500 * specified, the current post is used. 501 * 502 * @package WordPress 503 * @subpackage Feed 504 * @since 2.5.0 505 * 506 * @param string $link_text Descriptive text. 507 * @param int $post_id Optional post ID. Default to current post. 508 * @param string $feed Optional. Feed format. 509 * @return string Link to the comment feed for the current post. 510 */ 511 function post_comments_feed_link( $link_text = '', $post_id = '', $feed = '' ) { 512 $url = esc_url( get_post_comments_feed_link( $post_id, $feed ) ); 513 if ( empty($link_text) ) 514 $link_text = __('Comments Feed'); 515 516 echo apply_filters( 'post_comments_feed_link_html', "<a href='$url'>$link_text</a>", $post_id, $feed ); 517 } 518 519 /** 520 * Retrieve the feed link for a given author. 521 * 522 * Returns a link to the feed for all posts by a given author. A specific feed 523 * can be requested or left blank to get the default feed. 524 * 525 * @package WordPress 526 * @subpackage Feed 527 * @since 2.5.0 528 * 529 * @param int $author_id ID of an author. 530 * @param string $feed Optional. Feed type. 531 * @return string Link to the feed for the author specified by $author_id. 532 */ 533 function get_author_feed_link( $author_id, $feed = '' ) { 534 $author_id = (int) $author_id; 535 $permalink_structure = get_option('permalink_structure'); 536 537 if ( empty($feed) ) 538 $feed = get_default_feed(); 539 540 if ( '' == $permalink_structure ) { 541 $link = home_url("?feed=$feed&author=" . $author_id); 542 } else { 543 $link = get_author_posts_url($author_id); 544 if ( $feed == get_default_feed() ) 545 $feed_link = 'feed'; 546 else 547 $feed_link = "feed/$feed"; 548 549 $link = trailingslashit($link) . user_trailingslashit($feed_link, 'feed'); 550 } 551 552 $link = apply_filters('author_feed_link', $link, $feed); 553 554 return $link; 555 } 556 557 /** 558 * Retrieve the feed link for a category. 559 * 560 * Returns a link to the feed for all posts in a given category. A specific feed 561 * can be requested or left blank to get the default feed. 562 * 563 * @package WordPress 564 * @subpackage Feed 565 * @since 2.5.0 566 * 567 * @param int $cat_id ID of a category. 568 * @param string $feed Optional. Feed type. 569 * @return string Link to the feed for the category specified by $cat_id. 570 */ 571 function get_category_feed_link($cat_id, $feed = '') { 572 return get_term_feed_link($cat_id, 'category', $feed); 573 } 574 575 /** 576 * Retrieve the feed link for a term. 577 * 578 * Returns a link to the feed for all posts in a given term. A specific feed 579 * can be requested or left blank to get the default feed. 580 * 581 * @since 3.0 582 * 583 * @param int $term_id ID of a category. 584 * @param string $taxonomy Optional. Taxonomy of $term_id 585 * @param string $feed Optional. Feed type. 586 * @return string Link to the feed for the term specified by $term_id and $taxonomy. 587 */ 588 function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { 589 $term_id = ( int ) $term_id; 590 591 $term = get_term( $term_id, $taxonomy ); 592 593 if ( empty( $term ) || is_wp_error( $term ) ) 594 return false; 595 596 if ( empty( $feed ) ) 597 $feed = get_default_feed(); 598 599 $permalink_structure = get_option( 'permalink_structure' ); 600 601 if ( '' == $permalink_structure ) { 602 if ( 'category' == $taxonomy ) { 603 $link = home_url("?feed=$feed&cat=$term_id"); 604 } 605 elseif ( 'post_tag' == $taxonomy ) { 606 $link = home_url("?feed=$feed&tag=$term->slug"); 607 } else { 608 $t = get_taxonomy( $taxonomy ); 609 $link = home_url("?feed=$feed&$t->query_var=$term->slug"); 610 } 611 } else { 612 $link = get_term_link( $term_id, $term->taxonomy ); 613 if ( $feed == get_default_feed() ) 614 $feed_link = 'feed'; 615 else 616 $feed_link = "feed/$feed"; 617 618 $link = trailingslashit( $link ) . user_trailingslashit( $feed_link, 'feed' ); 619 } 620 621 if ( 'category' == $taxonomy ) 622 $link = apply_filters( 'category_feed_link', $link, $feed ); 623 elseif ( 'post_tag' == $taxonomy ) 624 $link = apply_filters( 'tag_feed_link', $link, $feed ); 625 else 626 $link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy ); 627 628 return $link; 629 } 630 631 /** 632 * Retrieve permalink for feed of tag. 633 * 634 * @since 2.3.0 635 * 636 * @param int $tag_id Tag ID. 637 * @param string $feed Optional. Feed type. 638 * @return string 639 */ 640 function get_tag_feed_link($tag_id, $feed = '') { 641 return get_term_feed_link($tag_id, 'post_tag', $feed); 642 } 643 644 /** 645 * Retrieve edit tag link. 646 * 647 * @since 2.7.0 648 * 649 * @param int $tag_id Tag ID 650 * @param string $taxonomy Taxonomy 651 * @return string 652 */ 653 function get_edit_tag_link( $tag_id, $taxonomy = 'post_tag' ) { 654 return apply_filters( 'get_edit_tag_link', get_edit_term_link( $tag_id, $taxonomy ) ); 655 } 656 657 /** 658 * Display or retrieve edit tag link with formatting. 659 * 660 * @since 2.7.0 661 * 662 * @param string $link Optional. Anchor text. 663 * @param string $before Optional. Display before edit link. 664 * @param string $after Optional. Display after edit link. 665 * @param object $tag Tag object. 666 * @return string HTML content. 667 */ 668 function edit_tag_link( $link = '', $before = '', $after = '', $tag = null ) { 669 $link = edit_term_link( $link, '', '', $tag, false ); 670 echo $before . apply_filters( 'edit_tag_link', $link ) . $after; 671 } 672 673 /** 674 * Retrieve edit term url. 675 * 676 * @since 3.1.0 677 * 678 * @param int $term_id Term ID 679 * @param string $taxonomy Taxonomy 680 * @param string $object_type The object type 681 * @return string 682 */ 683 function get_edit_term_link( $term_id, $taxonomy, $object_type = '' ) { 684 $tax = get_taxonomy( $taxonomy ); 685 if ( !current_user_can( $tax->cap->edit_terms ) ) 686 return; 687 688 $term = get_term( $term_id, $taxonomy ); 689 690 $args = array( 691 'action' => 'edit', 692 'taxonomy' => $taxonomy, 693 'tag_ID' => $term->term_id, 694 ); 695 696 if ( $object_type ) 697 $args['post_type'] = $object_type; 698 699 $location = add_query_arg( $args, admin_url( 'edit-tags.php' ) ); 700 701 return apply_filters( 'get_edit_term_link', $location, $term_id, $taxonomy, $object_type ); 702 } 703 704 /** 705 * Display or retrieve edit term link with formatting. 706 * 707 * @since 3.1.0 708 * 709 * @param string $link Optional. Anchor text. 710 * @param string $before Optional. Display before edit link. 711 * @param string $after Optional. Display after edit link. 712 * @param object $term Term object. 713 * @return string HTML content. 714 */ 715 function edit_term_link( $link = '', $before = '', $after = '', $term = null, $echo = true ) { 716 if ( is_null( $term ) ) 717 $term = get_queried_object(); 718 719 if ( ! $term ) 720 return; 721 722 $tax = get_taxonomy( $term->taxonomy ); 723 if ( ! current_user_can( $tax->cap->edit_terms ) ) 724 return; 725 726 if ( empty( $link ) ) 727 $link = __('Edit This'); 728 729 $link = '<a href="' . get_edit_term_link( $term->term_id, $term->taxonomy ) . '">' . $link . '</a>'; 730 $link = $before . apply_filters( 'edit_term_link', $link, $term->term_id ) . $after; 731 732 if ( $echo ) 733 echo $link; 734 else 735 return $link; 736 } 737 738 /** 739 * Retrieve permalink for search. 740 * 741 * @since 3.0.0 742 * 743 * @param string $query Optional. The query string to use. If empty the current query is used. 744 * @return string 745 */ 746 function get_search_link( $query = '' ) { 747 global $wp_rewrite; 748 749 if ( empty($query) ) 750 $search = get_search_query( false ); 751 else 752 $search = stripslashes($query); 753 754 $permastruct = $wp_rewrite->get_search_permastruct(); 755 756 if ( empty( $permastruct ) ) { 757 $link = home_url('?s=' . urlencode($search) ); 758 } else { 759 $search = urlencode($search); 760 $search = str_replace('%2F', '/', $search); // %2F(/) is not valid within a URL, send it unencoded. 761 $link = str_replace( '%search%', $search, $permastruct ); 762 $link = home_url( user_trailingslashit( $link, 'search' ) ); 763 } 764 765 return apply_filters( 'search_link', $link, $search ); 766 } 767 768 /** 769 * Retrieve the permalink for the feed of the search results. 770 * 771 * @since 2.5.0 772 * 773 * @param string $search_query Optional. Search query. 774 * @param string $feed Optional. Feed type. 775 * @return string 776 */ 777 function get_search_feed_link($search_query = '', $feed = '') { 778 global $wp_rewrite; 779 $link = get_search_link($search_query); 780 781 if ( empty($feed) ) 782 $feed = get_default_feed(); 783 784 $permastruct = $wp_rewrite->get_search_permastruct(); 785 786 if ( empty($permastruct) ) { 787 $link = add_query_arg('feed', $feed, $link); 788 } else { 789 $link = trailingslashit($link); 790 $link .= "feed/$feed/"; 791 } 792 793 $link = apply_filters('search_feed_link', $link, $feed, 'posts'); 794 795 return $link; 796 } 797 798 /** 799 * Retrieve the permalink for the comments feed of the search results. 800 * 801 * @since 2.5.0 802 * 803 * @param string $search_query Optional. Search query. 804 * @param string $feed Optional. Feed type. 805 * @return string 806 */ 807 function get_search_comments_feed_link($search_query = '', $feed = '') { 808 global $wp_rewrite; 809 810 if ( empty($feed) ) 811 $feed = get_default_feed(); 812 813 $link = get_search_feed_link($search_query, $feed); 814 815 $permastruct = $wp_rewrite->get_search_permastruct(); 816 817 if ( empty($permastruct) ) 818 $link = add_query_arg('feed', 'comments-' . $feed, $link); 819 else 820 $link = add_query_arg('withcomments', 1, $link); 821 822 $link = apply_filters('search_feed_link', $link, $feed, 'comments'); 823 824 return $link; 825 } 826 827 /** 828 * Retrieve the permalink for a post type archive. 829 * 830 * @since 3.1.0 831 * 832 * @param string $post_type Post type 833 * @return string 834 */ 835 function get_post_type_archive_link( $post_type ) { 836 global $wp_rewrite; 837 if ( ! $post_type_obj = get_post_type_object( $post_type ) ) 838 return false; 839 840 if ( ! $post_type_obj->has_archive ) 841 return false; 842 843 if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) ) { 844 $struct = ( true === $post_type_obj->has_archive ) ? $post_type_obj->rewrite['slug'] : $post_type_obj->has_archive; 845 if ( $post_type_obj->rewrite['with_front'] ) 846 $struct = $wp_rewrite->front . $struct; 847 else 848 $struct = $wp_rewrite->root . $struct; 849 $link = home_url( user_trailingslashit( $struct, 'post_type_archive' ) ); 850 } else { 851 $link = home_url( '?post_type=' . $post_type ); 852 } 853 854 return apply_filters( 'post_type_archive_link', $link, $post_type ); 855 } 856 857 /** 858 * Retrieve the permalink for a post type archive feed. 859 * 860 * @since 3.1.0 861 * 862 * @param string $post_type Post type 863 * @param string $feed Optional. Feed type 864 * @return string 865 */ 866 function get_post_type_archive_feed_link( $post_type, $feed = '' ) { 867 $default_feed = get_default_feed(); 868 if ( empty( $feed ) ) 869 $feed = $default_feed; 870 871 if ( ! $link = get_post_type_archive_link( $post_type ) ) 872 return false; 873 874 $post_type_obj = get_post_type_object( $post_type ); 875 if ( get_option( 'permalink_structure' ) && is_array( $post_type_obj->rewrite ) && $post_type_obj->rewrite['feeds'] ) { 876 $link = trailingslashit( $link ); 877 $link .= 'feed/'; 878 if ( $feed != $default_feed ) 879 $link .= "$feed/"; 880 } else { 881 $link = add_query_arg( 'feed', $feed, $link ); 882 } 883 884 return apply_filters( 'post_type_archive_feed_link', $link, $feed ); 885 } 886 887 /** 888 * Retrieve edit posts link for post. 889 * 890 * Can be used within the WordPress loop or outside of it. Can be used with 891 * pages, posts, attachments, and revisions. 892 * 893 * @since 2.3.0 894 * 895 * @param int $id Optional. Post ID. 896 * @param string $context Optional, defaults to display. How to write the '&', defaults to '&'. 897 * @return string 898 */ 899 function get_edit_post_link( $id = 0, $context = 'display' ) { 900 if ( ! $post = get_post( $id ) ) 901 return; 902 903 if ( 'revision' === $post->post_type ) 904 $action = ''; 905 elseif ( 'display' == $context ) 906 $action = '&action=edit'; 907 else 908 $action = '&action=edit'; 909 910 $post_type_object = get_post_type_object( $post->post_type ); 911 if ( !$post_type_object ) 912 return; 913 914 if ( !current_user_can( 'edit_post', $post->ID ) ) 915 return; 916 917 return apply_filters( 'get_edit_post_link', admin_url( sprintf($post_type_object->_edit_link . $action, $post->ID) ), $post->ID, $context ); 918 } 919 920 /** 921 * Display edit post link for post. 922 * 923 * @since 1.0.0 924 * 925 * @param string $link Optional. Anchor text. 926 * @param string $before Optional. Display before edit link. 927 * @param string $after Optional. Display after edit link. 928 * @param int $id Optional. Post ID. 929 */ 930 function edit_post_link( $link = null, $before = '', $after = '', $id = 0 ) { 931 if ( !$post = get_post( $id ) ) 932 return; 933 934 if ( !$url = get_edit_post_link( $post->ID ) ) 935 return; 936 937 if ( null === $link ) 938 $link = __('Edit This'); 939 940 $post_type_obj = get_post_type_object( $post->post_type ); 941 $link = '<a class="post-edit-link" href="' . $url . '">' . $link . '</a>'; 942 echo $before . apply_filters( 'edit_post_link', $link, $post->ID ) . $after; 943 } 944 945 /** 946 * Retrieve delete posts link for post. 947 * 948 * Can be used within the WordPress loop or outside of it, with any post type. 949 * 950 * @since 2.9.0 951 * 952 * @param int $id Optional. Post ID. 953 * @param string $deprecated Not used. 954 * @param bool $force_delete Whether to bypass trash and force deletion. Default is false. 955 * @return string 956 */ 957 function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false ) { 958 if ( ! empty( $deprecated ) ) 959 _deprecated_argument( __FUNCTION__, '3.0' ); 960 961 if ( !$post = get_post( $id ) ) 962 return; 963 964 $post_type_object = get_post_type_object( $post->post_type ); 965 if ( !$post_type_object ) 966 return; 967 968 if ( !current_user_can( 'delete_post', $post->ID ) ) 969 return; 970 971 $action = ( $force_delete || !EMPTY_TRASH_DAYS ) ? 'delete' : 'trash'; 972 973 $delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) ); 974 975 return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-post_{$post->ID}" ), $post->ID, $force_delete ); 976 } 977 978 /** 979 * Retrieve edit comment link. 980 * 981 * @since 2.3.0 982 * 983 * @param int $comment_id Optional. Comment ID. 984 * @return string 985 */ 986 function get_edit_comment_link( $comment_id = 0 ) { 987 $comment = get_comment( $comment_id ); 988 989 if ( !current_user_can( 'edit_comment', $comment->comment_ID ) ) 990 return; 991 992 $location = admin_url('comment.php?action=editcomment&c=') . $comment->comment_ID; 993 return apply_filters( 'get_edit_comment_link', $location ); 994 } 995 996 /** 997 * Display or retrieve edit comment link with formatting. 998 * 999 * @since 1.0.0 1000 * 1001 * @param string $link Optional. Anchor text. 1002 * @param string $before Optional. Display before edit link. 1003 * @param string $after Optional. Display after edit link. 1004 * @return string|null HTML content, if $echo is set to false. 1005 */ 1006 function edit_comment_link( $link = null, $before = '', $after = '' ) { 1007 global $comment; 1008 1009 if ( !current_user_can( 'edit_comment', $comment->comment_ID ) ) 1010 return; 1011 1012 if ( null === $link ) 1013 $link = __('Edit This'); 1014 1015 $link = '<a class="comment-edit-link" href="' . get_edit_comment_link( $comment->comment_ID ) . '">' . $link . '</a>'; 1016 echo $before . apply_filters( 'edit_comment_link', $link, $comment->comment_ID ) . $after; 1017 } 1018 1019 /** 1020 * Display edit bookmark (literally a URL external to blog) link. 1021 * 1022 * @since 2.7.0 1023 * 1024 * @param int $link Optional. Bookmark ID. 1025 * @return string 1026 */ 1027 function get_edit_bookmark_link( $link = 0 ) { 1028 $link = get_bookmark( $link ); 1029 1030 if ( !current_user_can('manage_links') ) 1031 return; 1032 1033 $location = admin_url('link.php?action=edit&link_id=') . $link->link_id; 1034 return apply_filters( 'get_edit_bookmark_link', $location, $link->link_id ); 1035 } 1036 1037 /** 1038 * Display edit bookmark (literally a URL external to blog) link anchor content. 1039 * 1040 * @since 2.7.0 1041 * 1042 * @param string $link Optional. Anchor text. 1043 * @param string $before Optional. Display before edit link. 1044 * @param string $after Optional. Display after edit link. 1045 * @param int $bookmark Optional. Bookmark ID. 1046 */ 1047 function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = null ) { 1048 $bookmark = get_bookmark($bookmark); 1049 1050 if ( !current_user_can('manage_links') ) 1051 return; 1052 1053 if ( empty($link) ) 1054 $link = __('Edit This'); 1055 1056 $link = '<a href="' . get_edit_bookmark_link( $bookmark ) . '">' . $link . '</a>'; 1057 echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after; 1058 } 1059 1060 /** 1061 * Retrieve edit user link 1062 * 1063 * @since 3.5.0 1064 * 1065 * @param int $user_id Optional. User ID. Defaults to the current user. 1066 * @return string URL to edit user page or empty string. 1067 */ 1068 function get_edit_user_link( $user_id = null ) { 1069 if ( ! $user_id ) 1070 $user_id = get_current_user_id(); 1071 1072 if ( empty( $user_id ) || ! current_user_can( 'edit_user', $user_id ) ) 1073 return ''; 1074 1075 $user = get_userdata( $user_id ); 1076 1077 if ( ! $user ) 1078 return ''; 1079 1080 if ( get_current_user_id() == $user->ID ) 1081 $link = get_edit_profile_url( $user->ID ); 1082 else 1083 $link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) ); 1084 1085 return apply_filters( 'get_edit_user_link', $link, $user->ID ); 1086 } 1087 1088 // Navigation links 1089 1090 /** 1091 * Retrieve previous post that is adjacent to current post. 1092 * 1093 * @since 1.5.0 1094 * 1095 * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term. 1096 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1097 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1098 * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists. 1099 */ 1100 function get_previous_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { 1101 return get_adjacent_post( $in_same_term, $excluded_terms, true, $taxonomy ); 1102 } 1103 1104 /** 1105 * Retrieve next post that is adjacent to current post. 1106 * 1107 * @since 1.5.0 1108 * 1109 * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term. 1110 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1111 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1112 * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists. 1113 */ 1114 function get_next_post( $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { 1115 return get_adjacent_post( $in_same_term, $excluded_terms, false, $taxonomy ); 1116 } 1117 1118 /** 1119 * Retrieve adjacent post. 1120 * 1121 * Can either be next or previous post. 1122 * 1123 * @since 2.5.0 1124 * 1125 * @param bool $in_same_term Optional. Whether post should be in a same taxonomy term. 1126 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1127 * @param bool $previous Optional. Whether to retrieve previous post. 1128 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1129 * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists. 1130 */ 1131 function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { 1132 global $wpdb; 1133 1134 if ( ( ! $post = get_post() ) || ! taxonomy_exists( $taxonomy ) ) 1135 return null; 1136 1137 $current_post_date = $post->post_date; 1138 1139 $join = ''; 1140 $posts_in_ex_terms_sql = ''; 1141 if ( $in_same_term || ! empty( $excluded_terms ) ) { 1142 $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"; 1143 1144 if ( $in_same_term ) { 1145 if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) ) 1146 return ''; 1147 $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ); 1148 if ( ! $term_array || is_wp_error( $term_array ) ) 1149 return ''; 1150 $join .= $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id IN (" . implode( ',', array_map( 'intval', $term_array ) ) . ")", $taxonomy ); 1151 } 1152 1153 $posts_in_ex_terms_sql = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy ); 1154 if ( ! empty( $excluded_terms ) ) { 1155 if ( ! is_array( $excluded_terms ) ) { 1156 // back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and " 1157 if ( false !== strpos( $excluded_terms, ' and ' ) ) { 1158 _deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded terms.' ), "'and'" ) ); 1159 $excluded_terms = explode( ' and ', $excluded_terms ); 1160 } else { 1161 $excluded_terms = explode( ',', $excluded_terms ); 1162 } 1163 } 1164 1165 $excluded_terms = array_map( 'intval', $excluded_terms ); 1166 1167 if ( ! empty( $term_array ) ) { 1168 $excluded_terms = array_diff( $excluded_terms, $term_array ); 1169 $posts_in_ex_terms_sql = ''; 1170 } 1171 1172 if ( ! empty( $excluded_terms ) ) { 1173 $posts_in_ex_terms_sql = $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id NOT IN (" . implode( $excluded_terms, ',' ) . ')', $taxonomy ); 1174 } 1175 } 1176 } 1177 1178 $adjacent = $previous ? 'previous' : 'next'; 1179 $op = $previous ? '<' : '>'; 1180 $order = $previous ? 'DESC' : 'ASC'; 1181 1182 $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms ); 1183 $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_terms_sql", $current_post_date, $post->post_type), $in_same_term, $excluded_terms ); 1184 $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" ); 1185 1186 $query = "SELECT p.ID FROM $wpdb->posts AS p $join $where $sort"; 1187 $query_key = 'adjacent_post_' . md5( $query ); 1188 $result = wp_cache_get( $query_key, 'counts' ); 1189 if ( false !== $result ) { 1190 if ( $result ) 1191 $result = get_post( $result ); 1192 return $result; 1193 } 1194 1195 $result = $wpdb->get_var( $query ); 1196 if ( null === $result ) 1197 $result = ''; 1198 1199 wp_cache_set( $query_key, $result, 'counts' ); 1200 1201 if ( $result ) 1202 $result = get_post( $result ); 1203 1204 return $result; 1205 } 1206 1207 /** 1208 * Get adjacent post relational link. 1209 * 1210 * Can either be next or previous post relational link. 1211 * 1212 * @since 2.8.0 1213 * 1214 * @param string $title Optional. Link title format. 1215 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1216 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1217 * @param bool $previous Optional. Whether to display link to previous or next post. Default true. 1218 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1219 * @return string 1220 */ 1221 function get_adjacent_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { 1222 if ( $previous && is_attachment() && $post = get_post() ) 1223 $post = get_post( $post->post_parent ); 1224 else 1225 $post = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy ); 1226 1227 if ( empty( $post ) ) 1228 return; 1229 1230 $post_title = the_title_attribute( array( 'echo' => false, 'post' => $post ) ); 1231 1232 if ( empty( $post_title ) ) 1233 $post_title = $previous ? __( 'Previous Post' ) : __( 'Next Post' ); 1234 1235 $date = mysql2date( get_option( 'date_format' ), $post->post_date ); 1236 1237 $title = str_replace( '%title', $post_title, $title ); 1238 $title = str_replace( '%date', $date, $title ); 1239 1240 $link = $previous ? "<link rel='prev' title='" : "<link rel='next' title='"; 1241 $link .= esc_attr( $title ); 1242 $link .= "' href='" . get_permalink( $post ) . "' />\n"; 1243 1244 $adjacent = $previous ? 'previous' : 'next'; 1245 return apply_filters( "{$adjacent}_post_rel_link", $link ); 1246 } 1247 1248 /** 1249 * Display relational links for the posts adjacent to the current post. 1250 * 1251 * @since 2.8.0 1252 * 1253 * @param string $title Optional. Link title format. 1254 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1255 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1256 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1257 */ 1258 function adjacent_posts_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { 1259 echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', true, $taxonomy ); 1260 echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', false, $taxonomy ); 1261 } 1262 1263 /** 1264 * Display relational links for the posts adjacent to the current post for single post pages. 1265 * 1266 * This is meant to be attached to actions like 'wp_head'. Do not call this directly in plugins or theme templates. 1267 * @since 3.0.0 1268 * 1269 */ 1270 function adjacent_posts_rel_link_wp_head() { 1271 if ( !is_singular() || is_attachment() ) 1272 return; 1273 adjacent_posts_rel_link(); 1274 } 1275 1276 /** 1277 * Display relational link for the next post adjacent to the current post. 1278 * 1279 * @since 2.8.0 1280 * 1281 * @param string $title Optional. Link title format. 1282 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1283 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1284 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1285 */ 1286 function next_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { 1287 echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', false, $taxonomy ); 1288 } 1289 1290 /** 1291 * Display relational link for the previous post adjacent to the current post. 1292 * 1293 * @since 2.8.0 1294 * 1295 * @param string $title Optional. Link title format. 1296 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1297 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. Default true. 1298 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1299 */ 1300 function prev_post_rel_link( $title = '%title', $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) { 1301 echo get_adjacent_post_rel_link( $title, $in_same_term, $excluded_terms = '', true, $taxonomy ); 1302 } 1303 1304 /** 1305 * Retrieve boundary post. 1306 * 1307 * Boundary being either the first or last post by publish date within the constraints specified 1308 * by $in_same_term or $excluded_terms. 1309 * 1310 * @since 2.8.0 1311 * 1312 * @param bool $in_same_term Optional. Whether returned post should be in a same taxonomy term. 1313 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1314 * @param bool $start Optional. Whether to retrieve first or last post. 1315 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1316 * @return object 1317 */ 1318 function get_boundary_post( $in_same_term = false, $excluded_terms = '', $start = true, $taxonomy = 'category' ) { 1319 $post = get_post(); 1320 if ( ! $post || ! is_single() || is_attachment() || ! taxonomy_exists( $taxonomy ) ) 1321 return null; 1322 1323 $query_args = array( 1324 'posts_per_page' => 1, 1325 'order' => $start ? 'ASC' : 'DESC', 1326 'update_post_term_cache' => false, 1327 'update_post_meta_cache' => false 1328 ); 1329 1330 $term_array = array(); 1331 1332 if ( ! is_array( $excluded_terms ) ) { 1333 if ( ! empty( $excluded_terms ) ) 1334 $excluded_terms = explode( ',', $excluded_terms ); 1335 else 1336 $excluded_terms = array(); 1337 } 1338 1339 if ( $in_same_term || ! empty( $excluded_terms ) ) { 1340 if ( $in_same_term ) 1341 $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) ); 1342 1343 if ( ! empty( $excluded_terms ) ) { 1344 $excluded_terms = array_map( 'intval', $excluded_terms ); 1345 $excluded_terms = array_diff( $excluded_terms, $term_array ); 1346 1347 $inverse_terms = array(); 1348 foreach ( $excluded_terms as $excluded_term ) 1349 $inverse_terms[] = $excluded_term * -1; 1350 $excluded_terms = $inverse_terms; 1351 } 1352 1353 $query_args[ 'tax_query' ] = array( array( 1354 'taxonomy' => $taxonomy, 1355 'terms' => array_merge( $term_array, $excluded_terms ) 1356 ) ); 1357 } 1358 1359 return get_posts( $query_args ); 1360 } 1361 1362 /* 1363 * Get previous post link that is adjacent to the current post. 1364 * 1365 * @since 3.7.0 1366 * 1367 * @param string $format Optional. Link anchor format. 1368 * @param string $link Optional. Link permalink format. 1369 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1370 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1371 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1372 * @return string 1373 */ 1374 function get_previous_post_link( $format = '« %link', $link = '%title', $in_same_cat = false, $excluded_terms = '', $taxonomy = 'category' ) { 1375 return get_adjacent_post_link( $format, $link, $in_same_cat, $excluded_terms, true, $taxonomy ); 1376 } 1377 1378 /** 1379 * Display previous post link that is adjacent to the current post. 1380 * 1381 * @since 1.5.0 1382 * @see get_previous_post_link() 1383 * 1384 * @param string $format Optional. Link anchor format. 1385 * @param string $link Optional. Link permalink format. 1386 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1387 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1388 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1389 */ 1390 function previous_post_link( $format = '« %link', $link = '%title', $in_same_cat = false, $excluded_terms = '', $taxonomy = 'category' ) { 1391 echo get_previous_post_link( $format, $link, $in_same_cat, $excluded_terms, $taxonomy ); 1392 } 1393 1394 /** 1395 * Get next post link that is adjacent to the current post. 1396 * 1397 * @since 3.7.0 1398 * 1399 * @param string $format Optional. Link anchor format. 1400 * @param string $link Optional. Link permalink format. 1401 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1402 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1403 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1404 * @return string 1405 */ 1406 function get_next_post_link( $format = '%link »', $link = '%title', $in_same_cat = false, $excluded_terms = '', $taxonomy = 'category' ) { 1407 return get_adjacent_post_link( $format, $link, $in_same_cat, $excluded_terms, false, $taxonomy ); 1408 } 1409 1410 /** 1411 * Display next post link that is adjacent to the current post. 1412 * 1413 * @since 1.5.0 1414 * @see get_next_post_link() 1415 * 1416 * @param string $format Optional. Link anchor format. 1417 * @param string $link Optional. Link permalink format. 1418 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1419 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded term IDs. 1420 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1421 */ 1422 function next_post_link( $format = '%link »', $link = '%title', $in_same_cat = false, $excluded_terms = '', $taxonomy = 'category' ) { 1423 echo get_next_post_link( $format, $link, $in_same_cat, $excluded_terms, $taxonomy ); 1424 } 1425 1426 /** 1427 * Get adjacent post link. 1428 * 1429 * Can be either next post link or previous. 1430 * 1431 * @since 3.7.0 1432 * 1433 * @param string $format Link anchor format. 1434 * @param string $link Link permalink format. 1435 * @param bool $in_same_term Optional. Whether link should be in a same taxonomy term. 1436 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded terms IDs. 1437 * @param bool $previous Optional. Whether to display link to previous or next post. Default true. 1438 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1439 * @return string 1440 */ 1441 function get_adjacent_post_link( $format, $link, $in_same_cat = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { 1442 if ( $previous && is_attachment() ) 1443 $post = get_post( get_post()->post_parent ); 1444 else 1445 $post = get_adjacent_post( $in_same_cat, $excluded_terms, $previous, $taxonomy ); 1446 1447 if ( ! $post ) { 1448 $output = ''; 1449 } else { 1450 $title = $post->post_title; 1451 1452 if ( empty( $post->post_title ) ) 1453 $title = $previous ? __( 'Previous Post' ) : __( 'Next Post' ); 1454 1455 /** This filter is documented in wp-includes/post-template.php */ 1456 $title = apply_filters( 'the_title', $title, $post->ID ); 1457 $date = mysql2date( get_option( 'date_format' ), $post->post_date ); 1458 $rel = $previous ? 'prev' : 'next'; 1459 1460 $string = '<a href="' . get_permalink( $post ) . '" rel="'.$rel.'">'; 1461 $inlink = str_replace( '%title', $title, $link ); 1462 $inlink = str_replace( '%date', $date, $inlink ); 1463 $inlink = $string . $inlink . '</a>'; 1464 1465 $output = str_replace( '%link', $inlink, $format ); 1466 } 1467 1468 $adjacent = $previous ? 'previous' : 'next'; 1469 1470 return apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post ); 1471 } 1472 1473 /** 1474 * Display adjacent post link. 1475 * 1476 * Can be either next post link or previous. 1477 * 1478 * @since 2.5.0 1479 * @uses get_adjacent_post_link() 1480 * 1481 * @param string $format Link anchor format. 1482 * @param string $link Link permalink format. 1483 * @param bool $in_same_cat Optional. Whether link should be in a same category. 1484 * @param array|string $excluded_terms Optional. Array or comma-separated list of excluded category IDs. 1485 * @param bool $previous Optional. Whether to display link to previous or next post. Default true. 1486 * @param string $taxonomy Optional. Taxonomy, if $in_same_term is true. Default 'category'. 1487 * @return string 1488 */ 1489 function adjacent_post_link( $format, $link, $in_same_cat = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) { 1490 echo get_adjacent_post_link( $format, $link, $in_same_cat, $excluded_terms, $previous, $taxonomy ); 1491 } 1492 1493 /** 1494 * Retrieve links for page numbers. 1495 * 1496 * @since 1.5.0 1497 * 1498 * @param int $pagenum Optional. Page ID. 1499 * @param bool $escape Optional. Whether to escape the URL for display, with esc_url(). Defaults to true. 1500 * Otherwise, prepares the URL with esc_url_raw(). 1501 * @return string 1502 */ 1503 function get_pagenum_link($pagenum = 1, $escape = true ) { 1504 global $wp_rewrite; 1505 1506 $pagenum = (int) $pagenum; 1507 1508 $request = remove_query_arg( 'paged' ); 1509 1510 $home_root = parse_url(home_url()); 1511 $home_root = ( isset($home_root['path']) ) ? $home_root['path'] : ''; 1512 $home_root = preg_quote( $home_root, '|' ); 1513 1514 $request = preg_replace('|^'. $home_root . '|i', '', $request); 1515 $request = preg_replace('|^/+|', '', $request); 1516 1517 if ( !$wp_rewrite->using_permalinks() || is_admin() ) { 1518 $base = trailingslashit( get_bloginfo( 'url' ) ); 1519 1520 if ( $pagenum > 1 ) { 1521 $result = add_query_arg( 'paged', $pagenum, $base . $request ); 1522 } else { 1523 $result = $base . $request; 1524 } 1525 } else { 1526 $qs_regex = '|\?.*?$|'; 1527 preg_match( $qs_regex, $request, $qs_match ); 1528 1529 if ( !empty( $qs_match[0] ) ) { 1530 $query_string = $qs_match[0]; 1531 $request = preg_replace( $qs_regex, '', $request ); 1532 } else { 1533 $query_string = ''; 1534 } 1535 1536 $request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request); 1537 $request = preg_replace( '|^' . preg_quote( $wp_rewrite->index, '|' ) . '|i', '', $request); 1538 $request = ltrim($request, '/'); 1539 1540 $base = trailingslashit( get_bloginfo( 'url' ) ); 1541 1542 if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) ) 1543 $base .= $wp_rewrite->index . '/'; 1544 1545 if ( $pagenum > 1 ) { 1546 $request = ( ( !empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( $wp_rewrite->pagination_base . "/" . $pagenum, 'paged' ); 1547 } 1548 1549 $result = $base . $request . $query_string; 1550 } 1551 1552 $result = apply_filters('get_pagenum_link', $result); 1553 1554 if ( $escape ) 1555 return esc_url( $result ); 1556 else 1557 return esc_url_raw( $result ); 1558 } 1559 1560 /** 1561 * Retrieve next posts page link. 1562 * 1563 * Backported from 2.1.3 to 2.0.10. 1564 * 1565 * @since 2.0.10 1566 * 1567 * @param int $max_page Optional. Max pages. 1568 * @return string 1569 */ 1570 function get_next_posts_page_link($max_page = 0) { 1571 global $paged; 1572 1573 if ( !is_single() ) { 1574 if ( !$paged ) 1575 $paged = 1; 1576 $nextpage = intval($paged) + 1; 1577 if ( !$max_page || $max_page >= $nextpage ) 1578 return get_pagenum_link($nextpage); 1579 } 1580 } 1581 1582 /** 1583 * Display or return the next posts page link. 1584 * 1585 * @since 0.71 1586 * 1587 * @param int $max_page Optional. Max pages. 1588 * @param boolean $echo Optional. Echo or return; 1589 */ 1590 function next_posts( $max_page = 0, $echo = true ) { 1591 $output = esc_url( get_next_posts_page_link( $max_page ) ); 1592 1593 if ( $echo ) 1594 echo $output; 1595 else 1596 return $output; 1597 } 1598 1599 /** 1600 * Return the next posts page link. 1601 * 1602 * @since 2.7.0 1603 * 1604 * @param string $label Content for link text. 1605 * @param int $max_page Optional. Max pages. 1606 * @return string|null 1607 */ 1608 function get_next_posts_link( $label = null, $max_page = 0 ) { 1609 global $paged, $wp_query; 1610 1611 if ( !$max_page ) 1612 $max_page = $wp_query->max_num_pages; 1613 1614 if ( !$paged ) 1615 $paged = 1; 1616 1617 $nextpage = intval($paged) + 1; 1618 1619 if ( null === $label ) 1620 $label = __( 'Next Page »' ); 1621 1622 if ( !is_single() && ( $nextpage <= $max_page ) ) { 1623 $attr = apply_filters( 'next_posts_link_attributes', '' ); 1624 return '<a href="' . next_posts( $max_page, false ) . "\" $attr>" . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) . '</a>'; 1625 } 1626 } 1627 1628 /** 1629 * Display the next posts page link. 1630 * 1631 * @since 0.71 1632 * @uses get_next_posts_link() 1633 * 1634 * @param string $label Content for link text. 1635 * @param int $max_page Optional. Max pages. 1636 */ 1637 function next_posts_link( $label = null, $max_page = 0 ) { 1638 echo get_next_posts_link( $label, $max_page ); 1639 } 1640 1641 /** 1642 * Retrieve previous posts page link. 1643 * 1644 * Will only return string, if not on a single page or post. 1645 * 1646 * Backported to 2.0.10 from 2.1.3. 1647 * 1648 * @since 2.0.10 1649 * 1650 * @return string|null 1651 */ 1652 function get_previous_posts_page_link() { 1653 global $paged; 1654 1655 if ( !is_single() ) { 1656 $nextpage = intval($paged) - 1; 1657 if ( $nextpage < 1 ) 1658 $nextpage = 1; 1659 return get_pagenum_link($nextpage); 1660 } 1661 } 1662 1663 /** 1664 * Display or return the previous posts page link. 1665 * 1666 * @since 0.71 1667 * 1668 * @param boolean $echo Optional. Echo or return; 1669 */ 1670 function previous_posts( $echo = true ) { 1671 $output = esc_url( get_previous_posts_page_link() ); 1672 1673 if ( $echo ) 1674 echo $output; 1675 else 1676 return $output; 1677 } 1678 1679 /** 1680 * Return the previous posts page link. 1681 * 1682 * @since 2.7.0 1683 * 1684 * @param string $label Optional. Previous page link text. 1685 * @return string|null 1686 */ 1687 function get_previous_posts_link( $label = null ) { 1688 global $paged; 1689 1690 if ( null === $label ) 1691 $label = __( '« Previous Page' ); 1692 1693 if ( !is_single() && $paged > 1 ) { 1694 $attr = apply_filters( 'previous_posts_link_attributes', '' ); 1695 return '<a href="' . previous_posts( false ) . "\" $attr>". preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label ) .'</a>'; 1696 } 1697 } 1698 1699 /** 1700 * Display the previous posts page link. 1701 * 1702 * @since 0.71 1703 * @uses get_previous_posts_link() 1704 * 1705 * @param string $label Optional. Previous page link text. 1706 */ 1707 function previous_posts_link( $label = null ) { 1708 echo get_previous_posts_link( $label ); 1709 } 1710 1711 /** 1712 * Return post pages link navigation for previous and next pages. 1713 * 1714 * @since 2.8 1715 * 1716 * @param string|array $args Optional args. 1717 * @return string The posts link navigation. 1718 */ 1719 function get_posts_nav_link( $args = array() ) { 1720 global $wp_query; 1721 1722 $return = ''; 1723 1724 if ( !is_singular() ) { 1725 $defaults = array( 1726 'sep' => ' — ', 1727 'prelabel' => __('« Previous Page'), 1728 'nxtlabel' => __('Next Page »'), 1729 ); 1730 $args = wp_parse_args( $args, $defaults ); 1731 1732 $max_num_pages = $wp_query->max_num_pages; 1733 $paged = get_query_var('paged'); 1734 1735 //only have sep if there's both prev and next results 1736 if ($paged < 2 || $paged >= $max_num_pages) { 1737 $args['sep'] = ''; 1738 } 1739 1740 if ( $max_num_pages > 1 ) { 1741 $return = get_previous_posts_link($args['prelabel']); 1742 $return .= preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $args['sep']); 1743 $return .= get_next_posts_link($args['nxtlabel']); 1744 } 1745 } 1746 return $return; 1747 1748 } 1749 1750 /** 1751 * Display post pages link navigation for previous and next pages. 1752 * 1753 * @since 0.71 1754 * 1755 * @param string $sep Optional. Separator for posts navigation links. 1756 * @param string $prelabel Optional. Label for previous pages. 1757 * @param string $nxtlabel Optional Label for next pages. 1758 */ 1759 function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) { 1760 $args = array_filter( compact('sep', 'prelabel', 'nxtlabel') ); 1761 echo get_posts_nav_link($args); 1762 } 1763 1764 /** 1765 * Retrieve comments page number link. 1766 * 1767 * @since 2.7.0 1768 * 1769 * @param int $pagenum Optional. Page number. 1770 * @return string 1771 */ 1772 function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) { 1773 global $wp_rewrite; 1774 1775 $pagenum = (int) $pagenum; 1776 1777 $result = get_permalink(); 1778 1779 if ( 'newest' == get_option('default_comments_page') ) { 1780 if ( $pagenum != $max_page ) { 1781 if ( $wp_rewrite->using_permalinks() ) 1782 $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged'); 1783 else 1784 $result = add_query_arg( 'cpage', $pagenum, $result ); 1785 } 1786 } elseif ( $pagenum > 1 ) { 1787 if ( $wp_rewrite->using_permalinks() ) 1788 $result = user_trailingslashit( trailingslashit($result) . 'comment-page-' . $pagenum, 'commentpaged'); 1789 else 1790 $result = add_query_arg( 'cpage', $pagenum, $result ); 1791 } 1792 1793 $result .= '#comments'; 1794 1795 $result = apply_filters('get_comments_pagenum_link', $result); 1796 1797 return $result; 1798 } 1799 1800 /** 1801 * Return the link to next comments page. 1802 * 1803 * @since 2.7.1 1804 * 1805 * @param string $label Optional. Label for link text. 1806 * @param int $max_page Optional. Max page. 1807 * @return string|null 1808 */ 1809 function get_next_comments_link( $label = '', $max_page = 0 ) { 1810 global $wp_query; 1811 1812 if ( !is_singular() || !get_option('page_comments') ) 1813 return; 1814 1815 $page = get_query_var('cpage'); 1816 1817 $nextpage = intval($page) + 1; 1818 1819 if ( empty($max_page) ) 1820 $max_page = $wp_query->max_num_comment_pages; 1821 1822 if ( empty($max_page) ) 1823 $max_page = get_comment_pages_count(); 1824 1825 if ( $nextpage > $max_page ) 1826 return; 1827 1828 if ( empty($label) ) 1829 $label = __('Newer Comments »'); 1830 1831 return '<a href="' . esc_url( get_comments_pagenum_link( $nextpage, $max_page ) ) . '" ' . apply_filters( 'next_comments_link_attributes', '' ) . '>'. preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) .'</a>'; 1832 } 1833 1834 /** 1835 * Display the link to next comments page. 1836 * 1837 * @since 2.7.0 1838 * 1839 * @param string $label Optional. Label for link text. 1840 * @param int $max_page Optional. Max page. 1841 */ 1842 function next_comments_link( $label = '', $max_page = 0 ) { 1843 echo get_next_comments_link( $label, $max_page ); 1844 } 1845 1846 /** 1847 * Return the previous comments page link. 1848 * 1849 * @since 2.7.1 1850 * 1851 * @param string $label Optional. Label for comments link text. 1852 * @return string|null 1853 */ 1854 function get_previous_comments_link( $label = '' ) { 1855 if ( !is_singular() || !get_option('page_comments') ) 1856 return; 1857 1858 $page = get_query_var('cpage'); 1859 1860 if ( intval($page) <= 1 ) 1861 return; 1862 1863 $prevpage = intval($page) - 1; 1864 1865 if ( empty($label) ) 1866 $label = __('« Older Comments'); 1867 1868 return '<a href="' . esc_url( get_comments_pagenum_link( $prevpage ) ) . '" ' . apply_filters( 'previous_comments_link_attributes', '' ) . '>' . preg_replace('/&([^#])(?![a-z]{1,8};)/i', '&$1', $label) .'</a>'; 1869 } 1870 1871 /** 1872 * Display the previous comments page link. 1873 * 1874 * @since 2.7.0 1875 * 1876 * @param string $label Optional. Label for comments link text. 1877 */ 1878 function previous_comments_link( $label = '' ) { 1879 echo get_previous_comments_link( $label ); 1880 } 1881 1882 /** 1883 * Create pagination links for the comments on the current post. 1884 * 1885 * @see paginate_links() 1886 * @since 2.7.0 1887 * 1888 * @param string|array $args Optional args. See paginate_links(). 1889 * @return string Markup for pagination links. 1890 */ 1891 function paginate_comments_links($args = array()) { 1892 global $wp_rewrite; 1893 1894 if ( !is_singular() || !get_option('page_comments') ) 1895 return; 1896 1897 $page = get_query_var('cpage'); 1898 if ( !$page ) 1899 $page = 1; 1900 $max_page = get_comment_pages_count(); 1901 $defaults = array( 1902 'base' => add_query_arg( 'cpage', '%#%' ), 1903 'format' => '', 1904 'total' => $max_page, 1905 'current' => $page, 1906 'echo' => true, 1907 'add_fragment' => '#comments' 1908 ); 1909 if ( $wp_rewrite->using_permalinks() ) 1910 $defaults['base'] = user_trailingslashit(trailingslashit(get_permalink()) . 'comment-page-%#%', 'commentpaged'); 1911 1912 $args = wp_parse_args( $args, $defaults ); 1913 $page_links = paginate_links( $args ); 1914 1915 if ( $args['echo'] ) 1916 echo $page_links; 1917 else 1918 return $page_links; 1919 } 1920 1921 /** 1922 * Retrieve the Press This bookmarklet link. 1923 * 1924 * Use this in 'a' element 'href' attribute. 1925 * 1926 * @since 2.6.0 1927 * 1928 * @return string 1929 */ 1930 function get_shortcut_link() { 1931 // In case of breaking changes, version this. #WP20071 1932 $link = "javascript: 1933 var d=document, 1934 w=window, 1935 e=w.getSelection, 1936 k=d.getSelection, 1937 x=d.selection, 1938 s=(e?e():(k)?k():(x?x.createRange().text:0)), 1939 f='" . admin_url('press-this.php') . "', 1940 l=d.location, 1941 e=encodeURIComponent, 1942 u=f+'?u='+e(l.href)+'&t='+e(d.title)+'&s='+e(s)+'&v=4'; 1943 a=function(){if(!w.open(u,'t','toolbar=0,resizable=1,scrollbars=1,status=1,width=720,height=570'))l.href=u;}; 1944 if (/Firefox/.test(navigator.userAgent)) setTimeout(a, 0); else a(); 1945 void(0)"; 1946 1947 $link = str_replace(array("\r", "\n", "\t"), '', $link); 1948 1949 return apply_filters('shortcut_link', $link); 1950 } 1951 1952 /** 1953 * Retrieve the home url for the current site. 1954 * 1955 * Returns the 'home' option with the appropriate protocol, 'https' if 1956 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 1957 * overridden. 1958 * 1959 * @package WordPress 1960 * @since 3.0.0 1961 * 1962 * @uses get_home_url() 1963 * 1964 * @param string $path (optional) Path relative to the home url. 1965 * @param string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https', or 'relative'. 1966 * @return string Home url link with optional path appended. 1967 */ 1968 function home_url( $path = '', $scheme = null ) { 1969 return get_home_url( null, $path, $scheme ); 1970 } 1971 1972 /** 1973 * Retrieve the home url for a given site. 1974 * 1975 * Returns the 'home' option with the appropriate protocol, 'https' if 1976 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 1977 * overridden. 1978 * 1979 * @package WordPress 1980 * @since 3.0.0 1981 * 1982 * @param int $blog_id (optional) Blog ID. Defaults to current blog. 1983 * @param string $path (optional) Path relative to the home url. 1984 * @param string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https', or 'relative'. 1985 * @return string Home url link with optional path appended. 1986 */ 1987 function get_home_url( $blog_id = null, $path = '', $scheme = null ) { 1988 $orig_scheme = $scheme; 1989 1990 if ( empty( $blog_id ) || !is_multisite() ) { 1991 $url = get_option( 'home' ); 1992 } else { 1993 switch_to_blog( $blog_id ); 1994 $url = get_option( 'home' ); 1995 restore_current_blog(); 1996 } 1997 1998 if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) { 1999 if ( is_ssl() && ! is_admin() && 'wp-login.php' !== $GLOBALS['pagenow'] ) 2000 $scheme = 'https'; 2001 else 2002 $scheme = parse_url( $url, PHP_URL_SCHEME ); 2003 } 2004 2005 $url = set_url_scheme( $url, $scheme ); 2006 2007 if ( $path && is_string( $path ) ) 2008 $url .= '/' . ltrim( $path, '/' ); 2009 2010 return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id ); 2011 } 2012 2013 /** 2014 * Retrieve the site url for the current site. 2015 * 2016 * Returns the 'site_url' option with the appropriate protocol, 'https' if 2017 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 2018 * overridden. 2019 * 2020 * @package WordPress 2021 * @since 2.6.0 2022 * 2023 * @uses get_site_url() 2024 * 2025 * @param string $path Optional. Path relative to the site url. 2026 * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme(). 2027 * @return string Site url link with optional path appended. 2028 */ 2029 function site_url( $path = '', $scheme = null ) { 2030 return get_site_url( null, $path, $scheme ); 2031 } 2032 2033 /** 2034 * Retrieve the site url for a given site. 2035 * 2036 * Returns the 'site_url' option with the appropriate protocol, 'https' if 2037 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 2038 * overridden. 2039 * 2040 * @package WordPress 2041 * @since 3.0.0 2042 * 2043 * @param int $blog_id (optional) Blog ID. Defaults to current blog. 2044 * @param string $path Optional. Path relative to the site url. 2045 * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', 'admin', or 'relative'. 2046 * @return string Site url link with optional path appended. 2047 */ 2048 function get_site_url( $blog_id = null, $path = '', $scheme = null ) { 2049 if ( empty( $blog_id ) || !is_multisite() ) { 2050 $url = get_option( 'siteurl' ); 2051 } else { 2052 switch_to_blog( $blog_id ); 2053 $url = get_option( 'siteurl' ); 2054 restore_current_blog(); 2055 } 2056 2057 $url = set_url_scheme( $url, $scheme ); 2058 2059 if ( $path && is_string( $path ) ) 2060 $url .= '/' . ltrim( $path, '/' ); 2061 2062 return apply_filters( 'site_url', $url, $path, $scheme, $blog_id ); 2063 } 2064 2065 /** 2066 * Retrieve the url to the admin area for the current site. 2067 * 2068 * @package WordPress 2069 * @since 2.6.0 2070 * 2071 * @param string $path Optional path relative to the admin url. 2072 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2073 * @return string Admin url link with optional path appended. 2074 */ 2075 function admin_url( $path = '', $scheme = 'admin' ) { 2076 return get_admin_url( null, $path, $scheme ); 2077 } 2078 2079 /** 2080 * Retrieve the url to the admin area for a given site. 2081 * 2082 * @package WordPress 2083 * @since 3.0.0 2084 * 2085 * @param int $blog_id (optional) Blog ID. Defaults to current blog. 2086 * @param string $path Optional path relative to the admin url. 2087 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2088 * @return string Admin url link with optional path appended. 2089 */ 2090 function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) { 2091 $url = get_site_url($blog_id, 'wp-admin/', $scheme); 2092 2093 if ( $path && is_string( $path ) ) 2094 $url .= ltrim( $path, '/' ); 2095 2096 return apply_filters( 'admin_url', $url, $path, $blog_id ); 2097 } 2098 2099 /** 2100 * Retrieve the url to the includes directory. 2101 * 2102 * @package WordPress 2103 * @since 2.6.0 2104 * 2105 * @param string $path Optional. Path relative to the includes url. 2106 * @param string $scheme Optional. Scheme to give the includes url context. 2107 * @return string Includes url link with optional path appended. 2108 */ 2109 function includes_url( $path = '', $scheme = null ) { 2110 $url = site_url( '/' . WPINC . '/', $scheme ); 2111 2112 if ( $path && is_string( $path ) ) 2113 $url .= ltrim($path, '/'); 2114 2115 return apply_filters('includes_url', $url, $path); 2116 } 2117 2118 /** 2119 * Retrieve the url to the content directory. 2120 * 2121 * @package WordPress 2122 * @since 2.6.0 2123 * 2124 * @param string $path Optional. Path relative to the content url. 2125 * @return string Content url link with optional path appended. 2126 */ 2127 function content_url($path = '') { 2128 $url = set_url_scheme( WP_CONTENT_URL ); 2129 2130 if ( $path && is_string( $path ) ) 2131 $url .= '/' . ltrim($path, '/'); 2132 2133 return apply_filters('content_url', $url, $path); 2134 } 2135 2136 /** 2137 * Retrieve the url to the plugins directory or to a specific file within that directory. 2138 * You can hardcode the plugin slug in $path or pass __FILE__ as a second argument to get the correct folder name. 2139 * 2140 * @package WordPress 2141 * @since 2.6.0 2142 * 2143 * @param string $path Optional. Path relative to the plugins url. 2144 * @param string $plugin Optional. The plugin file that you want to be relative to - i.e. pass in __FILE__ 2145 * @return string Plugins url link with optional path appended. 2146 */ 2147 function plugins_url($path = '', $plugin = '') { 2148 2149 $mu_plugin_dir = WPMU_PLUGIN_DIR; 2150 foreach ( array('path', 'plugin', 'mu_plugin_dir') as $var ) { 2151 $$var = str_replace('\\' ,'/', $$var); // sanitize for Win32 installs 2152 $$var = preg_replace('|/+|', '/', $$var); 2153 } 2154 2155 if ( !empty($plugin) && 0 === strpos($plugin, $mu_plugin_dir) ) 2156 $url = WPMU_PLUGIN_URL; 2157 else 2158 $url = WP_PLUGIN_URL; 2159 2160 2161 $url = set_url_scheme( $url ); 2162 2163 if ( !empty($plugin) && is_string($plugin) ) { 2164 $folder = dirname(plugin_basename($plugin)); 2165 if ( '.' != $folder ) 2166 $url .= '/' . ltrim($folder, '/'); 2167 } 2168 2169 if ( $path && is_string( $path ) ) 2170 $url .= '/' . ltrim($path, '/'); 2171 2172 return apply_filters('plugins_url', $url, $path, $plugin); 2173 } 2174 2175 /** 2176 * Retrieve the site url for the current network. 2177 * 2178 * Returns the site url with the appropriate protocol, 'https' if 2179 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 2180 * overridden. 2181 * 2182 * @package WordPress 2183 * @since 3.0.0 2184 * 2185 * @param string $path Optional. Path relative to the site url. 2186 * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme(). 2187 * @return string Site url link with optional path appended. 2188 */ 2189 function network_site_url( $path = '', $scheme = null ) { 2190 if ( ! is_multisite() ) 2191 return site_url($path, $scheme); 2192 2193 $current_site = get_current_site(); 2194 2195 if ( 'relative' == $scheme ) 2196 $url = $current_site->path; 2197 else 2198 $url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme ); 2199 2200 if ( $path && is_string( $path ) ) 2201 $url .= ltrim( $path, '/' ); 2202 2203 return apply_filters( 'network_site_url', $url, $path, $scheme ); 2204 } 2205 2206 /** 2207 * Retrieve the home url for the current network. 2208 * 2209 * Returns the home url with the appropriate protocol, 'https' if 2210 * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is 2211 * overridden. 2212 * 2213 * @package WordPress 2214 * @since 3.0.0 2215 * 2216 * @param string $path (optional) Path relative to the home url. 2217 * @param string $scheme (optional) Scheme to give the home url context. Currently 'http', 'https', or 'relative'. 2218 * @return string Home url link with optional path appended. 2219 */ 2220 function network_home_url( $path = '', $scheme = null ) { 2221 if ( ! is_multisite() ) 2222 return home_url($path, $scheme); 2223 2224 $current_site = get_current_site(); 2225 $orig_scheme = $scheme; 2226 2227 if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) 2228 $scheme = is_ssl() && ! is_admin() ? 'https' : 'http'; 2229 2230 if ( 'relative' == $scheme ) 2231 $url = $current_site->path; 2232 else 2233 $url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme ); 2234 2235 if ( $path && is_string( $path ) ) 2236 $url .= ltrim( $path, '/' ); 2237 2238 return apply_filters( 'network_home_url', $url, $path, $orig_scheme); 2239 } 2240 2241 /** 2242 * Retrieve the url to the admin area for the network. 2243 * 2244 * @package WordPress 2245 * @since 3.0.0 2246 * 2247 * @param string $path Optional path relative to the admin url. 2248 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2249 * @return string Admin url link with optional path appended. 2250 */ 2251 function network_admin_url( $path = '', $scheme = 'admin' ) { 2252 if ( ! is_multisite() ) 2253 return admin_url( $path, $scheme ); 2254 2255 $url = network_site_url('wp-admin/network/', $scheme); 2256 2257 if ( $path && is_string( $path ) ) 2258 $url .= ltrim($path, '/'); 2259 2260 return apply_filters('network_admin_url', $url, $path); 2261 } 2262 2263 /** 2264 * Retrieve the url to the admin area for the current user. 2265 * 2266 * @package WordPress 2267 * @since 3.0.0 2268 * 2269 * @param string $path Optional path relative to the admin url. 2270 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2271 * @return string Admin url link with optional path appended. 2272 */ 2273 function user_admin_url( $path = '', $scheme = 'admin' ) { 2274 $url = network_site_url('wp-admin/user/', $scheme); 2275 2276 if ( $path && is_string( $path ) ) 2277 $url .= ltrim($path, '/'); 2278 2279 return apply_filters('user_admin_url', $url, $path); 2280 } 2281 2282 /** 2283 * Retrieve the url to the admin area for either the current blog or the network depending on context. 2284 * 2285 * @package WordPress 2286 * @since 3.1.0 2287 * 2288 * @param string $path Optional path relative to the admin url. 2289 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2290 * @return string Admin url link with optional path appended. 2291 */ 2292 function self_admin_url($path = '', $scheme = 'admin') { 2293 if ( is_network_admin() ) 2294 return network_admin_url($path, $scheme); 2295 elseif ( is_user_admin() ) 2296 return user_admin_url($path, $scheme); 2297 else 2298 return admin_url($path, $scheme); 2299 } 2300 2301 /** 2302 * Set the scheme for a URL 2303 * 2304 * @since 3.4.0 2305 * 2306 * @param string $url Absolute url that includes a scheme 2307 * @param string $scheme Optional. Scheme to give $url. Currently 'http', 'https', 'login', 'login_post', 'admin', or 'relative'. 2308 * @return string $url URL with chosen scheme. 2309 */ 2310 function set_url_scheme( $url, $scheme = null ) { 2311 $orig_scheme = $scheme; 2312 if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) { 2313 if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) ) 2314 $scheme = 'https'; 2315 elseif ( ( 'login' == $scheme ) && force_ssl_admin() ) 2316 $scheme = 'https'; 2317 elseif ( ( 'admin' == $scheme ) && force_ssl_admin() ) 2318 $scheme = 'https'; 2319 else 2320 $scheme = ( is_ssl() ? 'https' : 'http' ); 2321 } 2322 2323 $url = trim( $url ); 2324 if ( substr( $url, 0, 2 ) === '//' ) 2325 $url = 'http:' . $url; 2326 2327 if ( 'relative' == $scheme ) { 2328 $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) ); 2329 if ( $url !== '' && $url[0] === '/' ) 2330 $url = '/' . ltrim($url , "/ \t\n\r\0\x0B" ); 2331 } else { 2332 $url = preg_replace( '#^\w+://#', $scheme . '://', $url ); 2333 } 2334 2335 return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme ); 2336 } 2337 2338 /** 2339 * Get the URL to the user's dashboard. 2340 * 2341 * If a user does not belong to any site, the global user dashboard is used. If the user belongs to the current site, 2342 * the dashboard for the current site is returned. If the user cannot edit the current site, the dashboard to the user's 2343 * primary blog is returned. 2344 * 2345 * @since 3.1.0 2346 * 2347 * @param int $user_id User ID 2348 * @param string $path Optional path relative to the dashboard. Use only paths known to both blog and user admins. 2349 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2350 * @return string Dashboard url link with optional path appended. 2351 */ 2352 function get_dashboard_url( $user_id, $path = '', $scheme = 'admin' ) { 2353 $user_id = (int) $user_id; 2354 2355 $blogs = get_blogs_of_user( $user_id ); 2356 if ( ! is_super_admin() && empty($blogs) ) { 2357 $url = user_admin_url( $path, $scheme ); 2358 } elseif ( ! is_multisite() ) { 2359 $url = admin_url( $path, $scheme ); 2360 } else { 2361 $current_blog = get_current_blog_id(); 2362 if ( $current_blog && ( is_super_admin( $user_id ) || in_array( $current_blog, array_keys( $blogs ) ) ) ) { 2363 $url = admin_url( $path, $scheme ); 2364 } else { 2365 $active = get_active_blog_for_user( $user_id ); 2366 if ( $active ) 2367 $url = get_admin_url( $active->blog_id, $path, $scheme ); 2368 else 2369 $url = user_admin_url( $path, $scheme ); 2370 } 2371 } 2372 2373 return apply_filters( 'user_dashboard_url', $url, $user_id, $path, $scheme); 2374 } 2375 2376 /** 2377 * Get the URL to the user's profile editor. 2378 * 2379 * @since 3.1.0 2380 * 2381 * @param int $user User ID 2382 * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). 'http' or 'https' can be passed to force those schemes. 2383 * @return string Dashboard url link with optional path appended. 2384 */ 2385 function get_edit_profile_url( $user, $scheme = 'admin' ) { 2386 $user = (int) $user; 2387 2388 if ( is_user_admin() ) 2389 $url = user_admin_url( 'profile.php', $scheme ); 2390 elseif ( is_network_admin() ) 2391 $url = network_admin_url( 'profile.php', $scheme ); 2392 else 2393 $url = get_dashboard_url( $user, 'profile.php', $scheme ); 2394 2395 return apply_filters( 'edit_profile_url', $url, $user, $scheme); 2396 } 2397 2398 /** 2399 * Output rel=canonical for singular queries. 2400 * 2401 * @package WordPress 2402 * @since 2.9.0 2403 */ 2404 function rel_canonical() { 2405 if ( !is_singular() ) 2406 return; 2407 2408 global $wp_the_query; 2409 if ( !$id = $wp_the_query->get_queried_object_id() ) 2410 return; 2411 2412 $link = get_permalink( $id ); 2413 2414 if ( $page = get_query_var('cpage') ) 2415 $link = get_comments_pagenum_link( $page ); 2416 2417 echo "<link rel='canonical' href='$link' />\n"; 2418 } 2419 2420 /** 2421 * Return a shortlink for a post, page, attachment, or blog. 2422 * 2423 * This function exists to provide a shortlink tag that all themes and plugins can target. A plugin must hook in to 2424 * provide the actual shortlinks. Default shortlink support is limited to providing ?p= style links for posts. 2425 * Plugins can short-circuit this function via the pre_get_shortlink filter or filter the output 2426 * via the get_shortlink filter. 2427 * 2428 * @since 3.0.0. 2429 * 2430 * @param int $id A post or blog id. Default is 0, which means the current post or blog. 2431 * @param string $context Whether the id is a 'blog' id, 'post' id, or 'media' id. If 'post', the post_type of the post is consulted. If 'query', the current query is consulted to determine the id and context. Default is 'post'. 2432 * @param bool $allow_slugs Whether to allow post slugs in the shortlink. It is up to the plugin how and whether to honor this. 2433 * @return string A shortlink or an empty string if no shortlink exists for the requested resource or if shortlinks are not enabled. 2434 */ 2435 function wp_get_shortlink($id = 0, $context = 'post', $allow_slugs = true) { 2436 // Allow plugins to short-circuit this function. 2437 $shortlink = apply_filters('pre_get_shortlink', false, $id, $context, $allow_slugs); 2438 if ( false !== $shortlink ) 2439 return $shortlink; 2440 2441 global $wp_query; 2442 $post_id = 0; 2443 if ( 'query' == $context && is_singular() ) { 2444 $post_id = $wp_query->get_queried_object_id(); 2445 $post = get_post( $post_id ); 2446 } elseif ( 'post' == $context ) { 2447 $post = get_post( $id ); 2448 if ( ! empty( $post->ID ) ) 2449 $post_id = $post->ID; 2450 } 2451 2452 $shortlink = ''; 2453 2454 // Return p= link for all public post types. 2455 if ( ! empty( $post_id ) ) { 2456 $post_type = get_post_type_object( $post->post_type ); 2457 if ( $post_type->public ) 2458 $shortlink = home_url('?p=' . $post_id); 2459 } 2460 2461 return apply_filters('get_shortlink', $shortlink, $id, $context, $allow_slugs); 2462 } 2463 2464 /** 2465 * Inject rel=shortlink into head if a shortlink is defined for the current page. 2466 * 2467 * Attached to the wp_head action. 2468 * 2469 * @since 3.0.0 2470 * 2471 * @uses wp_get_shortlink() 2472 */ 2473 function wp_shortlink_wp_head() { 2474 $shortlink = wp_get_shortlink( 0, 'query' ); 2475 2476 if ( empty( $shortlink ) ) 2477 return; 2478 2479 echo "<link rel='shortlink' href='" . esc_url( $shortlink ) . "' />\n"; 2480 } 2481 2482 /** 2483 * Send a Link: rel=shortlink header if a shortlink is defined for the current page. 2484 * 2485 * Attached to the wp action. 2486 * 2487 * @since 3.0.0 2488 * 2489 * @uses wp_get_shortlink() 2490 */ 2491 function wp_shortlink_header() { 2492 if ( headers_sent() ) 2493 return; 2494 2495 $shortlink = wp_get_shortlink(0, 'query'); 2496 2497 if ( empty($shortlink) ) 2498 return; 2499 2500 header('Link: <' . $shortlink . '>; rel=shortlink', false); 2501 } 2502 2503 /** 2504 * Display the Short Link for a Post 2505 * 2506 * Must be called from inside "The Loop" 2507 * 2508 * Call like the_shortlink(__('Shortlinkage FTW')) 2509 * 2510 * @since 3.0.0 2511 * 2512 * @param string $text Optional The link text or HTML to be displayed. Defaults to 'This is the short link.' 2513 * @param string $title Optional The tooltip for the link. Must be sanitized. Defaults to the sanitized post title. 2514 * @param string $before Optional HTML to display before the link. 2515 * @param string $after Optional HTML to display after the link. 2516 */ 2517 function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) { 2518 $post = get_post(); 2519 2520 if ( empty( $text ) ) 2521 $text = __('This is the short link.'); 2522 2523 if ( empty( $title ) ) 2524 $title = the_title_attribute( array( 'echo' => false ) ); 2525 2526 $shortlink = wp_get_shortlink( $post->ID ); 2527 2528 if ( !empty( $shortlink ) ) { 2529 $link = '<a rel="shortlink" href="' . esc_url( $shortlink ) . '" title="' . $title . '">' . $text . '</a>'; 2530 $link = apply_filters( 'the_shortlink', $link, $shortlink, $text, $title ); 2531 echo $before, $link, $after; 2532 } 2533 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |