[ Index ]

PHP Cross Reference of WordPress 3.0 beta 1

[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/wp-includes/ -> link-template.php (source)

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


Generated: Mon Apr 5 14:26:09 2010 Cross-referenced by PHPXref 0.7