web/wp-includes/post-template.php
changeset 136 bde1974c263b
child 194 32102edaa81b
equal deleted inserted replaced
135:53cff4b4a802 136:bde1974c263b
       
     1 <?php
       
     2 /**
       
     3  * WordPress Post Template Functions.
       
     4  *
       
     5  * Gets content for the current post in the loop.
       
     6  *
       
     7  * @package WordPress
       
     8  * @subpackage Template
       
     9  */
       
    10 
       
    11 /**
       
    12  * Display the ID of the current item in the WordPress Loop.
       
    13  *
       
    14  * @since 0.71
       
    15  * @uses $id
       
    16  */
       
    17 function the_ID() {
       
    18 	global $id;
       
    19 	echo $id;
       
    20 }
       
    21 
       
    22 /**
       
    23  * Retrieve the ID of the current item in the WordPress Loop.
       
    24  *
       
    25  * @since 2.1.0
       
    26  * @uses $id
       
    27  *
       
    28  * @return unknown
       
    29  */
       
    30 function get_the_ID() {
       
    31 	global $id;
       
    32 	return $id;
       
    33 }
       
    34 
       
    35 /**
       
    36  * Display or retrieve the current post title with optional content.
       
    37  *
       
    38  * @since 0.71
       
    39  *
       
    40  * @param string $before Optional. Content to prepend to the title.
       
    41  * @param string $after Optional. Content to append to the title.
       
    42  * @param bool $echo Optional, default to true.Whether to display or return.
       
    43  * @return null|string Null on no title. String if $echo parameter is false.
       
    44  */
       
    45 function the_title($before = '', $after = '', $echo = true) {
       
    46 	$title = get_the_title();
       
    47 
       
    48 	if ( strlen($title) == 0 )
       
    49 		return;
       
    50 
       
    51 	$title = $before . $title . $after;
       
    52 
       
    53 	if ( $echo )
       
    54 		echo $title;
       
    55 	else
       
    56 		return $title;
       
    57 }
       
    58 
       
    59 /**
       
    60  * Sanitize the current title when retrieving or displaying.
       
    61  *
       
    62  * Works like {@link the_title()}, except the parameters can be in a string or
       
    63  * an array. See the function for what can be override in the $args parameter.
       
    64  *
       
    65  * The title before it is displayed will have the tags stripped and {@link
       
    66  * esc_attr()} before it is passed to the user or displayed. The default
       
    67  * as with {@link the_title()}, is to display the title.
       
    68  *
       
    69  * @since 2.3.0
       
    70  *
       
    71  * @param string|array $args Optional. Override the defaults.
       
    72  * @return string|null Null on failure or display. String when echo is false.
       
    73  */
       
    74 function the_title_attribute( $args = '' ) {
       
    75 	$title = get_the_title();
       
    76 
       
    77 	if ( strlen($title) == 0 )
       
    78 		return;
       
    79 
       
    80 	$defaults = array('before' => '', 'after' =>  '', 'echo' => true);
       
    81 	$r = wp_parse_args($args, $defaults);
       
    82 	extract( $r, EXTR_SKIP );
       
    83 
       
    84 
       
    85 	$title = $before . $title . $after;
       
    86 	$title = esc_attr(strip_tags($title));
       
    87 
       
    88 	if ( $echo )
       
    89 		echo $title;
       
    90 	else
       
    91 		return $title;
       
    92 }
       
    93 
       
    94 /**
       
    95  * Retrieve post title.
       
    96  *
       
    97  * If the post is protected and the visitor is not an admin, then "Protected"
       
    98  * will be displayed before the post title. If the post is private, then
       
    99  * "Private" will be located before the post title.
       
   100  *
       
   101  * @since 0.71
       
   102  *
       
   103  * @param int $id Optional. Post ID.
       
   104  * @return string
       
   105  */
       
   106 function get_the_title( $id = 0 ) {
       
   107 	$post = &get_post($id);
       
   108 
       
   109 	$title = $post->post_title;
       
   110 
       
   111 	if ( !is_admin() ) {
       
   112 		if ( !empty($post->post_password) ) {
       
   113 			$protected_title_format = apply_filters('protected_title_format', __('Protected: %s'));
       
   114 			$title = sprintf($protected_title_format, $title);
       
   115 		} else if ( isset($post->post_status) && 'private' == $post->post_status ) {
       
   116 			$private_title_format = apply_filters('private_title_format', __('Private: %s'));
       
   117 			$title = sprintf($private_title_format, $title);
       
   118 		}
       
   119 	}
       
   120 	return apply_filters( 'the_title', $title, $post->ID );
       
   121 }
       
   122 
       
   123 /**
       
   124  * Display the Post Global Unique Identifier (guid).
       
   125  *
       
   126  * The guid will appear to be a link, but should not be used as an link to the
       
   127  * post. The reason you should not use it as a link, is because of moving the
       
   128  * blog across domains.
       
   129  *
       
   130  * @since 1.5.0
       
   131  *
       
   132  * @param int $id Optional. Post ID.
       
   133  */
       
   134 function the_guid( $id = 0 ) {
       
   135 	echo get_the_guid($id);
       
   136 }
       
   137 
       
   138 /**
       
   139  * Retrieve the Post Global Unique Identifier (guid).
       
   140  *
       
   141  * The guid will appear to be a link, but should not be used as an link to the
       
   142  * post. The reason you should not use it as a link, is because of moving the
       
   143  * blog across domains.
       
   144  *
       
   145  * @since 1.5.0
       
   146  *
       
   147  * @param int $id Optional. Post ID.
       
   148  * @return string
       
   149  */
       
   150 function get_the_guid( $id = 0 ) {
       
   151 	$post = &get_post($id);
       
   152 
       
   153 	return apply_filters('get_the_guid', $post->guid);
       
   154 }
       
   155 
       
   156 /**
       
   157  * Display the post content.
       
   158  *
       
   159  * @since 0.71
       
   160  *
       
   161  * @param string $more_link_text Optional. Content for when there is more text.
       
   162  * @param string $stripteaser Optional. Teaser content before the more text.
       
   163  */
       
   164 function the_content($more_link_text = null, $stripteaser = 0) {
       
   165 	$content = get_the_content($more_link_text, $stripteaser);
       
   166 	$content = apply_filters('the_content', $content);
       
   167 	$content = str_replace(']]>', ']]&gt;', $content);
       
   168 	echo $content;
       
   169 }
       
   170 
       
   171 /**
       
   172  * Retrieve the post content.
       
   173  *
       
   174  * @since 0.71
       
   175  *
       
   176  * @param string $more_link_text Optional. Content for when there is more text.
       
   177  * @param string $stripteaser Optional. Teaser content before the more text.
       
   178  * @return string
       
   179  */
       
   180 function get_the_content($more_link_text = null, $stripteaser = 0) {
       
   181 	global $id, $post, $more, $page, $pages, $multipage, $preview, $pagenow;
       
   182 
       
   183 	if ( null === $more_link_text )
       
   184 		$more_link_text = __( '(more...)' );
       
   185 
       
   186 	$output = '';
       
   187 	$hasTeaser = false;
       
   188 
       
   189 	// If post password required and it doesn't match the cookie.
       
   190 	if ( post_password_required($post) ) {
       
   191 		$output = get_the_password_form();
       
   192 		return $output;
       
   193 	}
       
   194 
       
   195 	if ( $page > count($pages) ) // if the requested page doesn't exist
       
   196 		$page = count($pages); // give them the highest numbered page that DOES exist
       
   197 
       
   198 	$content = $pages[$page-1];
       
   199 	if ( preg_match('/<!--more(.*?)?-->/', $content, $matches) ) {
       
   200 		$content = explode($matches[0], $content, 2);
       
   201 		if ( !empty($matches[1]) && !empty($more_link_text) )
       
   202 			$more_link_text = strip_tags(wp_kses_no_null(trim($matches[1])));
       
   203 
       
   204 		$hasTeaser = true;
       
   205 	} else {
       
   206 		$content = array($content);
       
   207 	}
       
   208 	if ( (false !== strpos($post->post_content, '<!--noteaser-->') && ((!$multipage) || ($page==1))) )
       
   209 		$stripteaser = 1;
       
   210 	$teaser = $content[0];
       
   211 	if ( ($more) && ($stripteaser) && ($hasTeaser) )
       
   212 		$teaser = '';
       
   213 	$output .= $teaser;
       
   214 	if ( count($content) > 1 ) {
       
   215 		if ( $more ) {
       
   216 			$output .= '<span id="more-' . $id . '"></span>' . $content[1];
       
   217 		} else {
       
   218 			if ( ! empty($more_link_text) )
       
   219 				$output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-$id\" class=\"more-link\">$more_link_text</a>", $more_link_text );
       
   220 			$output = force_balance_tags($output);
       
   221 		}
       
   222 
       
   223 	}
       
   224 	if ( $preview ) // preview fix for javascript bug with foreign languages
       
   225 		$output =	preg_replace_callback('/\%u([0-9A-F]{4})/', create_function('$match', 'return "&#" . base_convert($match[1], 16, 10) . ";";'), $output);
       
   226 
       
   227 	return $output;
       
   228 }
       
   229 
       
   230 /**
       
   231  * Display the post excerpt.
       
   232  *
       
   233  * @since 0.71
       
   234  * @uses apply_filters() Calls 'the_excerpt' hook on post excerpt.
       
   235  */
       
   236 function the_excerpt() {
       
   237 	echo apply_filters('the_excerpt', get_the_excerpt());
       
   238 }
       
   239 
       
   240 /**
       
   241  * Retrieve the post excerpt.
       
   242  *
       
   243  * @since 0.71
       
   244  *
       
   245  * @param mixed $deprecated Not used.
       
   246  * @return string
       
   247  */
       
   248 function get_the_excerpt($deprecated = '') {
       
   249 	global $post;
       
   250 	$output = $post->post_excerpt;
       
   251 	if ( post_password_required($post) ) {
       
   252 		$output = __('There is no excerpt because this is a protected post.');
       
   253 		return $output;
       
   254 	}
       
   255 
       
   256 	return apply_filters('get_the_excerpt', $output);
       
   257 }
       
   258 
       
   259 /**
       
   260  * Whether post has excerpt.
       
   261  *
       
   262  * @since 2.3.0
       
   263  *
       
   264  * @param int $id Optional. Post ID.
       
   265  * @return bool
       
   266  */
       
   267 function has_excerpt( $id = 0 ) {
       
   268 	$post = &get_post( $id );
       
   269 	return ( !empty( $post->post_excerpt ) );
       
   270 }
       
   271 
       
   272 /**
       
   273  * Display the classes for the post div.
       
   274  *
       
   275  * @since 2.7.0
       
   276  *
       
   277  * @param string|array $class One or more classes to add to the class list.
       
   278  * @param int $post_id An optional post ID.
       
   279  */
       
   280 function post_class( $class = '', $post_id = null ) {
       
   281 	// Separates classes with a single space, collates classes for post DIV
       
   282 	echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
       
   283 }
       
   284 
       
   285 /**
       
   286  * Retrieve the classes for the post div as an array.
       
   287  *
       
   288  * The class names are add are many. If the post is a sticky, then the 'sticky'
       
   289  * class name. The class 'hentry' is always added to each post. For each
       
   290  * category, the class will be added with 'category-' with category slug is
       
   291  * added. The tags are the same way as the categories with 'tag-' before the tag
       
   292  * slug. All classes are passed through the filter, 'post_class' with the list
       
   293  * of classes, followed by $class parameter value, with the post ID as the last
       
   294  * parameter.
       
   295  *
       
   296  * @since 2.7.0
       
   297  *
       
   298  * @param string|array $class One or more classes to add to the class list.
       
   299  * @param int $post_id An optional post ID.
       
   300  * @return array Array of classes.
       
   301  */
       
   302 function get_post_class( $class = '', $post_id = null ) {
       
   303 	$post = get_post($post_id);
       
   304 
       
   305 	$classes = array();
       
   306 
       
   307 	if ( empty($post) )
       
   308 		return $classes;
       
   309 
       
   310 	$classes[] = 'post-' . $post->ID;
       
   311 	$classes[] = $post->post_type;
       
   312 
       
   313 	// sticky for Sticky Posts
       
   314 	if ( is_sticky($post->ID) && is_home())
       
   315 		$classes[] = 'sticky';
       
   316 
       
   317 	// hentry for hAtom compliace
       
   318 	$classes[] = 'hentry';
       
   319 
       
   320 	// Categories
       
   321 	foreach ( (array) get_the_category($post->ID) as $cat ) {
       
   322 		if ( empty($cat->slug ) )
       
   323 			continue;
       
   324 		$classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->cat_ID);
       
   325 	}
       
   326 
       
   327 	// Tags
       
   328 	foreach ( (array) get_the_tags($post->ID) as $tag ) {
       
   329 		if ( empty($tag->slug ) )
       
   330 			continue;
       
   331 		$classes[] = 'tag-' . sanitize_html_class($tag->slug, $tag->term_id);
       
   332 	}
       
   333 
       
   334 	if ( !empty($class) ) {
       
   335 		if ( !is_array( $class ) )
       
   336 			$class = preg_split('#\s+#', $class);
       
   337 		$classes = array_merge($classes, $class);
       
   338 	}
       
   339 
       
   340 	$classes = array_map('esc_attr', $classes);
       
   341 
       
   342 	return apply_filters('post_class', $classes, $class, $post_id);
       
   343 }
       
   344 
       
   345 /**
       
   346  * Display the classes for the body element.
       
   347  *
       
   348  * @since 2.8.0
       
   349  *
       
   350  * @param string|array $class One or more classes to add to the class list.
       
   351  */
       
   352 function body_class( $class = '' ) {
       
   353 	// Separates classes with a single space, collates classes for body element
       
   354 	echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
       
   355 }
       
   356 
       
   357 /**
       
   358  * Retrieve the classes for the body element as an array.
       
   359  *
       
   360  * @since 2.8.0
       
   361  *
       
   362  * @param string|array $class One or more classes to add to the class list.
       
   363  * @return array Array of classes.
       
   364  */
       
   365 function get_body_class( $class = '' ) {
       
   366 	global $wp_query, $wpdb, $current_user;
       
   367 
       
   368 	$classes = array();
       
   369 
       
   370 	if ( 'rtl' == get_bloginfo('text_direction') )
       
   371 		$classes[] = 'rtl';
       
   372 
       
   373 	if ( is_front_page() )
       
   374 		$classes[] = 'home';
       
   375 	if ( is_home() )
       
   376 		$classes[] = 'blog';
       
   377 	if ( is_archive() )
       
   378 		$classes[] = 'archive';
       
   379 	if ( is_date() )
       
   380 		$classes[] = 'date';
       
   381 	if ( is_search() )
       
   382 		$classes[] = 'search';
       
   383 	if ( is_paged() )
       
   384 		$classes[] = 'paged';
       
   385 	if ( is_attachment() )
       
   386 		$classes[] = 'attachment';
       
   387 	if ( is_404() )
       
   388 		$classes[] = 'error404';
       
   389 
       
   390 	if ( is_single() ) {
       
   391 		$wp_query->post = $wp_query->posts[0];
       
   392 		setup_postdata($wp_query->post);
       
   393 
       
   394 		$postID = $wp_query->post->ID;
       
   395 		$classes[] = 'single postid-' . $postID;
       
   396 
       
   397 		if ( is_attachment() ) {
       
   398 			$mime_type = get_post_mime_type();
       
   399 			$mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
       
   400 			$classes[] = 'attachmentid-' . $postID;
       
   401 			$classes[] = 'attachment-' . str_replace($mime_prefix, '', $mime_type);
       
   402 		}
       
   403 	} elseif ( is_archive() ) {
       
   404 		if ( is_author() ) {
       
   405 			$author = $wp_query->get_queried_object();
       
   406 			$classes[] = 'author';
       
   407 			$classes[] = 'author-' . sanitize_html_class($author->user_nicename , $author->ID);
       
   408 		} elseif ( is_category() ) {
       
   409 			$cat = $wp_query->get_queried_object();
       
   410 			$classes[] = 'category';
       
   411 			$classes[] = 'category-' . sanitize_html_class($cat->slug, $cat->cat_ID);
       
   412 		} elseif ( is_tag() ) {
       
   413 			$tags = $wp_query->get_queried_object();
       
   414 			$classes[] = 'tag';
       
   415 			$classes[] = 'tag-' . sanitize_html_class($tags->slug, $tags->term_id);
       
   416 		}
       
   417 	} elseif ( is_page() ) {
       
   418 		$classes[] = 'page';
       
   419 
       
   420 		$wp_query->post = $wp_query->posts[0];
       
   421 		setup_postdata($wp_query->post);
       
   422 
       
   423 		$pageID = $wp_query->post->ID;
       
   424 
       
   425 		$classes[] = 'page-id-' . $pageID;
       
   426 
       
   427 		if ( $wpdb->get_var( $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'page' LIMIT 1", $pageID) ) )
       
   428 			$classes[] = 'page-parent';
       
   429 
       
   430 		if ( $wp_query->post->post_parent ) {
       
   431 			$classes[] = 'page-child';
       
   432 			$classes[] = 'parent-pageid-' . $wp_query->post->post_parent;
       
   433 		}
       
   434 		if ( is_page_template() ) {
       
   435 			$classes[] = 'page-template';
       
   436 			$classes[] = 'page-template-' . str_replace( '.php', '-php', get_post_meta( $pageID, '_wp_page_template', true ) );
       
   437 		}
       
   438 	} elseif ( is_search() ) {
       
   439 		if ( !empty($wp_query->posts) )
       
   440 			$classes[] = 'search-results';
       
   441 		else
       
   442 			$classes[] = 'search-no-results';
       
   443 	}
       
   444 
       
   445 	if ( is_user_logged_in() )
       
   446 		$classes[] = 'logged-in';
       
   447 
       
   448 	$page = $wp_query->get('page');
       
   449 
       
   450 	if ( !$page || $page < 2)
       
   451 		$page = $wp_query->get('paged');
       
   452 
       
   453 	if ( $page && $page > 1 ) {
       
   454 		$classes[] = 'paged-' . $page;
       
   455 
       
   456 		if ( is_single() )
       
   457 			$classes[] = 'single-paged-' . $page;
       
   458 		elseif ( is_page() )
       
   459 			$classes[] = 'page-paged-' . $page;
       
   460 		elseif ( is_category() )
       
   461 			$classes[] = 'category-paged-' . $page;
       
   462 		elseif ( is_tag() )
       
   463 			$classes[] = 'tag-paged-' . $page;
       
   464 		elseif ( is_date() )
       
   465 			$classes[] = 'date-paged-' . $page;
       
   466 		elseif ( is_author() )
       
   467 			$classes[] = 'author-paged-' . $page;
       
   468 		elseif ( is_search() )
       
   469 			$classes[] = 'search-paged-' . $page;
       
   470 	}
       
   471 
       
   472 	if ( !empty($class) ) {
       
   473 		if ( !is_array( $class ) )
       
   474 			$class = preg_split('#\s+#', $class);
       
   475 		$classes = array_merge($classes, $class);
       
   476 	}
       
   477 
       
   478 	$classes = array_map('esc_attr', $classes);
       
   479 
       
   480 	return apply_filters('body_class', $classes, $class);
       
   481 }
       
   482 
       
   483 /**
       
   484  * Whether post requires password and correct password has been provided.
       
   485  *
       
   486  * @since 2.7.0
       
   487  *
       
   488  * @param int|object $post An optional post.  Global $post used if not provided.
       
   489  * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
       
   490  */
       
   491 function post_password_required( $post = null ) {
       
   492 	$post = get_post($post);
       
   493 
       
   494 	if ( empty($post->post_password) )
       
   495 		return false;
       
   496 
       
   497 	if ( !isset($_COOKIE['wp-postpass_' . COOKIEHASH]) )
       
   498 		return true;
       
   499 
       
   500 	if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password )
       
   501 		return true;
       
   502 
       
   503 	return false;
       
   504 }
       
   505 
       
   506 /**
       
   507  * Display "sticky" CSS class, if a post is sticky.
       
   508  *
       
   509  * @since 2.7.0
       
   510  *
       
   511  * @param int $post_id An optional post ID.
       
   512  */
       
   513 function sticky_class( $post_id = null ) {
       
   514 	if ( !is_sticky($post_id) )
       
   515 		return;
       
   516 
       
   517 	echo " sticky";
       
   518 }
       
   519 
       
   520 /**
       
   521  * Page Template Functions for usage in Themes
       
   522  *
       
   523  * @package WordPress
       
   524  * @subpackage Template
       
   525  */
       
   526 
       
   527 /**
       
   528  * The formatted output of a list of pages.
       
   529  *
       
   530  * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
       
   531  * Quicktag one or more times). This tag must be within The Loop.
       
   532  *
       
   533  * The defaults for overwriting are:
       
   534  * 'next_or_number' - Default is 'number' (string). Indicates whether page
       
   535  *      numbers should be used. Valid values are number and next.
       
   536  * 'nextpagelink' - Default is 'Next Page' (string). Text for link to next page.
       
   537  *      of the bookmark.
       
   538  * 'previouspagelink' - Default is 'Previous Page' (string). Text for link to
       
   539  *      previous page, if available.
       
   540  * 'pagelink' - Default is '%' (String).Format string for page numbers. The % in
       
   541  *      the parameter string will be replaced with the page number, so Page %
       
   542  *      generates "Page 1", "Page 2", etc. Defaults to %, just the page number.
       
   543  * 'before' - Default is '<p> Pages:' (string). The html or text to prepend to
       
   544  *      each bookmarks.
       
   545  * 'after' - Default is '</p>' (string). The html or text to append to each
       
   546  *      bookmarks.
       
   547  * 'link_before' - Default is '' (string). The html or text to prepend to each
       
   548  *      Pages link inside the <a> tag.
       
   549  * 'link_after' - Default is '' (string). The html or text to append to each
       
   550  *      Pages link inside the <a> tag.
       
   551  *
       
   552  * @since 1.2.0
       
   553  * @access private
       
   554  *
       
   555  * @param string|array $args Optional. Overwrite the defaults.
       
   556  * @return string Formatted output in HTML.
       
   557  */
       
   558 function wp_link_pages($args = '') {
       
   559 	$defaults = array(
       
   560 		'before' => '<p>' . __('Pages:'), 'after' => '</p>',
       
   561 		'link_before' => '', 'link_after' => '',
       
   562 		'next_or_number' => 'number', 'nextpagelink' => __('Next page'),
       
   563 		'previouspagelink' => __('Previous page'), 'pagelink' => '%',
       
   564 		'echo' => 1
       
   565 	);
       
   566 
       
   567 	$r = wp_parse_args( $args, $defaults );
       
   568 	extract( $r, EXTR_SKIP );
       
   569 
       
   570 	global $post, $page, $numpages, $multipage, $more, $pagenow;
       
   571 
       
   572 	$output = '';
       
   573 	if ( $multipage ) {
       
   574 		if ( 'number' == $next_or_number ) {
       
   575 			$output .= $before;
       
   576 			for ( $i = 1; $i < ($numpages+1); $i = $i + 1 ) {
       
   577 				$j = str_replace('%',"$i",$pagelink);
       
   578 				$output .= ' ';
       
   579 				if ( ($i != $page) || ((!$more) && ($page==1)) ) {
       
   580 					if ( 1 == $i ) {
       
   581 						$output .= '<a href="' . get_permalink() . '">';
       
   582 					} else {
       
   583 						if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
       
   584 							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">';
       
   585 						else
       
   586 							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">';
       
   587 					}
       
   588 
       
   589 				}
       
   590 				$output .= $link_before;
       
   591 				$output .= $j;
       
   592 				$output .= $link_after;
       
   593 				if ( ($i != $page) || ((!$more) && ($page==1)) )
       
   594 					$output .= '</a>';
       
   595 			}
       
   596 			$output .= $after;
       
   597 		} else {
       
   598 			if ( $more ) {
       
   599 				$output .= $before;
       
   600 				$i = $page - 1;
       
   601 				if ( $i && $more ) {
       
   602 					if ( 1 == $i ) {
       
   603 						$output .= '<a href="' . get_permalink() . '">' . $link_before. $previouspagelink . $link_after . '</a>';
       
   604 					} else {
       
   605 						if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
       
   606 							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">' . $link_before. $previouspagelink . $link_after . '</a>';
       
   607 						else
       
   608 							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">' . $link_before. $previouspagelink . $link_after . '</a>';
       
   609 					}
       
   610 				}
       
   611 				$i = $page + 1;
       
   612 				if ( $i <= $numpages && $more ) {
       
   613 					if ( 1 == $i ) {
       
   614 						$output .= '<a href="' . get_permalink() . '">' . $link_before. $nextpagelink . $link_after . '</a>';
       
   615 					} else {
       
   616 						if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
       
   617 							$output .= '<a href="' . get_permalink() . '&amp;page=' . $i . '">' . $link_before. $nextpagelink . $link_after . '</a>';
       
   618 						else
       
   619 							$output .= '<a href="' . trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged') . '">' . $link_before. $nextpagelink . $link_after . '</a>';
       
   620 					}
       
   621 				}
       
   622 				$output .= $after;
       
   623 			}
       
   624 		}
       
   625 	}
       
   626 
       
   627 	if ( $echo )
       
   628 		echo $output;
       
   629 
       
   630 	return $output;
       
   631 }
       
   632 
       
   633 
       
   634 //
       
   635 // Post-meta: Custom per-post fields.
       
   636 //
       
   637 
       
   638 /**
       
   639  * Retrieve post custom meta data field.
       
   640  *
       
   641  * @since 1.5.0
       
   642  *
       
   643  * @param string $key Meta data key name.
       
   644  * @return string|array Array of values or single value, if only one element exists.
       
   645  */
       
   646 function post_custom( $key = '' ) {
       
   647 	$custom = get_post_custom();
       
   648 
       
   649 	if ( 1 == count($custom[$key]) )
       
   650 		return $custom[$key][0];
       
   651 	else
       
   652 		return $custom[$key];
       
   653 }
       
   654 
       
   655 /**
       
   656  * Display list of post custom fields.
       
   657  *
       
   658  * @internal This will probably change at some point...
       
   659  * @since 1.2.0
       
   660  * @uses apply_filters() Calls 'the_meta_key' on list item HTML content, with key and value as separate parameters.
       
   661  */
       
   662 function the_meta() {
       
   663 	if ( $keys = get_post_custom_keys() ) {
       
   664 		echo "<ul class='post-meta'>\n";
       
   665 		foreach ( (array) $keys as $key ) {
       
   666 			$keyt = trim($key);
       
   667 			if ( '_' == $keyt{0} )
       
   668 				continue;
       
   669 			$values = array_map('trim', get_post_custom_values($key));
       
   670 			$value = implode($values,', ');
       
   671 			echo apply_filters('the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value);
       
   672 		}
       
   673 		echo "</ul>\n";
       
   674 	}
       
   675 }
       
   676 
       
   677 //
       
   678 // Pages
       
   679 //
       
   680 
       
   681 /**
       
   682  * Retrieve or display list of pages as a dropdown (select list).
       
   683  *
       
   684  * @since 2.1.0
       
   685  *
       
   686  * @param array|string $args Optional. Override default arguments.
       
   687  * @return string HTML content, if not displaying.
       
   688  */
       
   689 function wp_dropdown_pages($args = '') {
       
   690 	$defaults = array(
       
   691 		'depth' => 0, 'child_of' => 0,
       
   692 		'selected' => 0, 'echo' => 1,
       
   693 		'name' => 'page_id', 'show_option_none' => '', 'show_option_no_change' => '',
       
   694 		'option_none_value' => ''
       
   695 	);
       
   696 
       
   697 	$r = wp_parse_args( $args, $defaults );
       
   698 	extract( $r, EXTR_SKIP );
       
   699 
       
   700 	$pages = get_pages($r);
       
   701 	$output = '';
       
   702 	$name = esc_attr($name);
       
   703 
       
   704 	if ( ! empty($pages) ) {
       
   705 		$output = "<select name=\"$name\" id=\"$name\">\n";
       
   706 		if ( $show_option_no_change )
       
   707 			$output .= "\t<option value=\"-1\">$show_option_no_change</option>";
       
   708 		if ( $show_option_none )
       
   709 			$output .= "\t<option value=\"" . esc_attr($option_none_value) . "\">$show_option_none</option>\n";
       
   710 		$output .= walk_page_dropdown_tree($pages, $depth, $r);
       
   711 		$output .= "</select>\n";
       
   712 	}
       
   713 
       
   714 	$output = apply_filters('wp_dropdown_pages', $output);
       
   715 
       
   716 	if ( $echo )
       
   717 		echo $output;
       
   718 
       
   719 	return $output;
       
   720 }
       
   721 
       
   722 /**
       
   723  * Retrieve or display list of pages in list (li) format.
       
   724  *
       
   725  * @since 1.5.0
       
   726  *
       
   727  * @param array|string $args Optional. Override default arguments.
       
   728  * @return string HTML content, if not displaying.
       
   729  */
       
   730 function wp_list_pages($args = '') {
       
   731 	$defaults = array(
       
   732 		'depth' => 0, 'show_date' => '',
       
   733 		'date_format' => get_option('date_format'),
       
   734 		'child_of' => 0, 'exclude' => '',
       
   735 		'title_li' => __('Pages'), 'echo' => 1,
       
   736 		'authors' => '', 'sort_column' => 'menu_order, post_title',
       
   737 		'link_before' => '', 'link_after' => '', 'walker' => '',
       
   738 	);
       
   739 
       
   740 	$r = wp_parse_args( $args, $defaults );
       
   741 	extract( $r, EXTR_SKIP );
       
   742 
       
   743 	$output = '';
       
   744 	$current_page = 0;
       
   745 
       
   746 	// sanitize, mostly to keep spaces out
       
   747 	$r['exclude'] = preg_replace('/[^0-9,]/', '', $r['exclude']);
       
   748 
       
   749 	// Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
       
   750 	$exclude_array = ( $r['exclude'] ) ? explode(',', $r['exclude']) : array();
       
   751 	$r['exclude'] = implode( ',', apply_filters('wp_list_pages_excludes', $exclude_array) );
       
   752 
       
   753 	// Query pages.
       
   754 	$r['hierarchical'] = 0;
       
   755 	$pages = get_pages($r);
       
   756 
       
   757 	if ( !empty($pages) ) {
       
   758 		if ( $r['title_li'] )
       
   759 			$output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
       
   760 
       
   761 		global $wp_query;
       
   762 		if ( is_page() || is_attachment() || $wp_query->is_posts_page )
       
   763 			$current_page = $wp_query->get_queried_object_id();
       
   764 		$output .= walk_page_tree($pages, $r['depth'], $current_page, $r);
       
   765 
       
   766 		if ( $r['title_li'] )
       
   767 			$output .= '</ul></li>';
       
   768 	}
       
   769 
       
   770 	$output = apply_filters('wp_list_pages', $output, $r);
       
   771 
       
   772 	if ( $r['echo'] )
       
   773 		echo $output;
       
   774 	else
       
   775 		return $output;
       
   776 }
       
   777 
       
   778 /**
       
   779  * Display or retrieve list of pages with optional home link.
       
   780  *
       
   781  * The arguments are listed below and part of the arguments are for {@link
       
   782  * wp_list_pages()} function. Check that function for more info on those
       
   783  * arguments.
       
   784  *
       
   785  * <ul>
       
   786  * <li><strong>sort_column</strong> - How to sort the list of pages. Defaults
       
   787  * to page title. Use column for posts table.</li>
       
   788  * <li><strong>menu_class</strong> - Class to use for the div ID which contains
       
   789  * the page list. Defaults to 'menu'.</li>
       
   790  * <li><strong>echo</strong> - Whether to echo list or return it. Defaults to
       
   791  * echo.</li>
       
   792  * <li><strong>link_before</strong> - Text before show_home argument text.</li>
       
   793  * <li><strong>link_after</strong> - Text after show_home argument text.</li>
       
   794  * <li><strong>show_home</strong> - If you set this argument, then it will
       
   795  * display the link to the home page. The show_home argument really just needs
       
   796  * to be set to the value of the text of the link.</li>
       
   797  * </ul>
       
   798  *
       
   799  * @since 2.7.0
       
   800  *
       
   801  * @param array|string $args
       
   802  */
       
   803 function wp_page_menu( $args = array() ) {
       
   804 	$defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
       
   805 	$args = wp_parse_args( $args, $defaults );
       
   806 	$args = apply_filters( 'wp_page_menu_args', $args );
       
   807 
       
   808 	$menu = '';
       
   809 
       
   810 	$list_args = $args;
       
   811 
       
   812 	// Show Home in the menu
       
   813 	if ( isset($args['show_home']) && ! empty($args['show_home']) ) {
       
   814 		if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
       
   815 			$text = __('Home');
       
   816 		else
       
   817 			$text = $args['show_home'];
       
   818 		$class = '';
       
   819 		if ( is_front_page() && !is_paged() )
       
   820 			$class = 'class="current_page_item"';
       
   821 		$menu .= '<li ' . $class . '><a href="' . get_option('home') . '" title="' . esc_attr($text) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
       
   822 		// If the front page is a page, add it to the exclude list
       
   823 		if (get_option('show_on_front') == 'page') {
       
   824 			if ( !empty( $list_args['exclude'] ) ) {
       
   825 				$list_args['exclude'] .= ',';
       
   826 			} else {
       
   827 				$list_args['exclude'] = '';
       
   828 			}
       
   829 			$list_args['exclude'] .= get_option('page_on_front');
       
   830 		}
       
   831 	}
       
   832 
       
   833 	$list_args['echo'] = false;
       
   834 	$list_args['title_li'] = '';
       
   835 	$menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
       
   836 
       
   837 	if ( $menu )
       
   838 		$menu = '<ul>' . $menu . '</ul>';
       
   839 
       
   840 	$menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
       
   841 	$menu = apply_filters( 'wp_page_menu', $menu, $args );
       
   842 	if ( $args['echo'] )
       
   843 		echo $menu;
       
   844 	else
       
   845 		return $menu;
       
   846 }
       
   847 
       
   848 //
       
   849 // Page helpers
       
   850 //
       
   851 
       
   852 /**
       
   853  * Retrieve HTML list content for page list.
       
   854  *
       
   855  * @uses Walker_Page to create HTML list content.
       
   856  * @since 2.1.0
       
   857  * @see Walker_Page::walk() for parameters and return description.
       
   858  */
       
   859 function walk_page_tree($pages, $depth, $current_page, $r) {
       
   860 	if ( empty($r['walker']) )
       
   861 		$walker = new Walker_Page;
       
   862 	else
       
   863 		$walker = $r['walker'];
       
   864 
       
   865 	$args = array($pages, $depth, $r, $current_page);
       
   866 	return call_user_func_array(array(&$walker, 'walk'), $args);
       
   867 }
       
   868 
       
   869 /**
       
   870  * Retrieve HTML dropdown (select) content for page list.
       
   871  *
       
   872  * @uses Walker_PageDropdown to create HTML dropdown content.
       
   873  * @since 2.1.0
       
   874  * @see Walker_PageDropdown::walk() for parameters and return description.
       
   875  */
       
   876 function walk_page_dropdown_tree() {
       
   877 	$args = func_get_args();
       
   878 	if ( empty($args[2]['walker']) ) // the user's options are the third parameter
       
   879 		$walker = new Walker_PageDropdown;
       
   880 	else
       
   881 		$walker = $args[2]['walker'];
       
   882 
       
   883 	return call_user_func_array(array(&$walker, 'walk'), $args);
       
   884 }
       
   885 
       
   886 //
       
   887 // Attachments
       
   888 //
       
   889 
       
   890 /**
       
   891  * Display an attachment page link using an image or icon.
       
   892  *
       
   893  * @since 2.0.0
       
   894  *
       
   895  * @param int $id Optional. Post ID.
       
   896  * @param bool $fullsize Optional, default is false. Whether to use full size.
       
   897  * @param bool $deprecated Deprecated. Not used.
       
   898  * @param bool $permalink Optional, default is false. Whether to include permalink.
       
   899  */
       
   900 function the_attachment_link($id = 0, $fullsize = false, $deprecated = false, $permalink = false) {
       
   901 	if ( $fullsize )
       
   902 		echo wp_get_attachment_link($id, 'full', $permalink);
       
   903 	else
       
   904 		echo wp_get_attachment_link($id, 'thumbnail', $permalink);
       
   905 }
       
   906 
       
   907 /**
       
   908  * Retrieve an attachment page link using an image or icon, if possible.
       
   909  *
       
   910  * @since 2.5.0
       
   911  * @uses apply_filters() Calls 'wp_get_attachment_link' filter on HTML content with same parameters as function.
       
   912  *
       
   913  * @param int $id Optional. Post ID.
       
   914  * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string.
       
   915  * @param bool $permalink Optional, default is false. Whether to add permalink to image.
       
   916  * @param bool $icon Optional, default is false. Whether to include icon.
       
   917  * @param string $text Optional, default is false. If string, then will be link text.
       
   918  * @return string HTML content.
       
   919  */
       
   920 function wp_get_attachment_link($id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false) {
       
   921 	$id = intval($id);
       
   922 	$_post = & get_post( $id );
       
   923 
       
   924 	if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
       
   925 		return __('Missing Attachment');
       
   926 
       
   927 	if ( $permalink )
       
   928 		$url = get_attachment_link($_post->ID);
       
   929 
       
   930 	$post_title = esc_attr($_post->post_title);
       
   931 
       
   932 	if ( $text ) {
       
   933 		$link_text = esc_attr($text);
       
   934 	} elseif ( ( is_int($size) && $size != 0 ) or ( is_string($size) && $size != 'none' ) or $size != false ) {
       
   935 		$link_text = wp_get_attachment_image($id, $size, $icon);
       
   936 	}
       
   937 
       
   938 	if( trim($link_text) == '' )
       
   939 		$link_text = $_post->post_title;
       
   940 
       
   941 	return apply_filters( 'wp_get_attachment_link', "<a href='$url' title='$post_title'>$link_text</a>", $id, $size, $permalink, $icon, $text );
       
   942 }
       
   943 
       
   944 /**
       
   945  * Retrieve HTML content of attachment image with link.
       
   946  *
       
   947  * @since 2.0.0
       
   948  * @deprecated Use {@link wp_get_attachment_link()}
       
   949  * @see wp_get_attachment_link() Use instead.
       
   950  *
       
   951  * @param int $id Optional. Post ID.
       
   952  * @param bool $fullsize Optional, default is false. Whether to use full size image.
       
   953  * @param array $max_dims Optional. Max image dimensions.
       
   954  * @param bool $permalink Optional, default is false. Whether to include permalink to image.
       
   955  * @return string
       
   956  */
       
   957 function get_the_attachment_link($id = 0, $fullsize = false, $max_dims = false, $permalink = false) {
       
   958 	$id = (int) $id;
       
   959 	$_post = & get_post($id);
       
   960 
       
   961 	if ( ('attachment' != $_post->post_type) || !$url = wp_get_attachment_url($_post->ID) )
       
   962 		return __('Missing Attachment');
       
   963 
       
   964 	if ( $permalink )
       
   965 		$url = get_attachment_link($_post->ID);
       
   966 
       
   967 	$post_title = esc_attr($_post->post_title);
       
   968 
       
   969 	$innerHTML = get_attachment_innerHTML($_post->ID, $fullsize, $max_dims);
       
   970 	return "<a href='$url' title='$post_title'>$innerHTML</a>";
       
   971 }
       
   972 
       
   973 /**
       
   974  * Retrieve icon URL and Path.
       
   975  *
       
   976  * @since 2.1.0
       
   977  * @deprecated Use {@link wp_get_attachment_image_src()}
       
   978  * @see wp_get_attachment_image_src() Use instead.
       
   979  *
       
   980  * @param int $id Optional. Post ID.
       
   981  * @param bool $fullsize Optional, default to false. Whether to have full image.
       
   982  * @return array Icon URL and full path to file, respectively.
       
   983  */
       
   984 function get_attachment_icon_src( $id = 0, $fullsize = false ) {
       
   985 	$id = (int) $id;
       
   986 	if ( !$post = & get_post($id) )
       
   987 		return false;
       
   988 
       
   989 	$file = get_attached_file( $post->ID );
       
   990 
       
   991 	if ( !$fullsize && $src = wp_get_attachment_thumb_url( $post->ID ) ) {
       
   992 		// We have a thumbnail desired, specified and existing
       
   993 
       
   994 		$src_file = basename($src);
       
   995 		$class = 'attachmentthumb';
       
   996 	} elseif ( wp_attachment_is_image( $post->ID ) ) {
       
   997 		// We have an image without a thumbnail
       
   998 
       
   999 		$src = wp_get_attachment_url( $post->ID );
       
  1000 		$src_file = & $file;
       
  1001 		$class = 'attachmentimage';
       
  1002 	} elseif ( $src = wp_mime_type_icon( $post->ID ) ) {
       
  1003 		// No thumb, no image. We'll look for a mime-related icon instead.
       
  1004 
       
  1005 		$icon_dir = apply_filters( 'icon_dir', get_template_directory() . '/images' );
       
  1006 		$src_file = $icon_dir . '/' . basename($src);
       
  1007 	}
       
  1008 
       
  1009 	if ( !isset($src) || !$src )
       
  1010 		return false;
       
  1011 
       
  1012 	return array($src, $src_file);
       
  1013 }
       
  1014 
       
  1015 /**
       
  1016  * Retrieve HTML content of icon attachment image element.
       
  1017  *
       
  1018  * @since 2.0.0
       
  1019  * @deprecated Use {@link wp_get_attachment_image()}
       
  1020  * @see wp_get_attachment_image() Use instead of.
       
  1021  *
       
  1022  * @param int $id Optional. Post ID.
       
  1023  * @param bool $fullsize Optional, default to false. Whether to have full size image.
       
  1024  * @param array $max_dims Optional. Dimensions of image.
       
  1025  * @return string HTML content.
       
  1026  */
       
  1027 function get_attachment_icon( $id = 0, $fullsize = false, $max_dims = false ) {
       
  1028 	$id = (int) $id;
       
  1029 	if ( !$post = & get_post($id) )
       
  1030 		return false;
       
  1031 
       
  1032 	if ( !$src = get_attachment_icon_src( $post->ID, $fullsize ) )
       
  1033 		return false;
       
  1034 
       
  1035 	list($src, $src_file) = $src;
       
  1036 
       
  1037 	// Do we need to constrain the image?
       
  1038 	if ( ($max_dims = apply_filters('attachment_max_dims', $max_dims)) && file_exists($src_file) ) {
       
  1039 
       
  1040 		$imagesize = getimagesize($src_file);
       
  1041 
       
  1042 		if (($imagesize[0] > $max_dims[0]) || $imagesize[1] > $max_dims[1] ) {
       
  1043 			$actual_aspect = $imagesize[0] / $imagesize[1];
       
  1044 			$desired_aspect = $max_dims[0] / $max_dims[1];
       
  1045 
       
  1046 			if ( $actual_aspect >= $desired_aspect ) {
       
  1047 				$height = $actual_aspect * $max_dims[0];
       
  1048 				$constraint = "width='{$max_dims[0]}' ";
       
  1049 				$post->iconsize = array($max_dims[0], $height);
       
  1050 			} else {
       
  1051 				$width = $max_dims[1] / $actual_aspect;
       
  1052 				$constraint = "height='{$max_dims[1]}' ";
       
  1053 				$post->iconsize = array($width, $max_dims[1]);
       
  1054 			}
       
  1055 		} else {
       
  1056 			$post->iconsize = array($imagesize[0], $imagesize[1]);
       
  1057 			$constraint = '';
       
  1058 		}
       
  1059 	} else {
       
  1060 		$constraint = '';
       
  1061 	}
       
  1062 
       
  1063 	$post_title = esc_attr($post->post_title);
       
  1064 
       
  1065 	$icon = "<img src='$src' title='$post_title' alt='$post_title' $constraint/>";
       
  1066 
       
  1067 	return apply_filters( 'attachment_icon', $icon, $post->ID );
       
  1068 }
       
  1069 
       
  1070 /**
       
  1071  * Retrieve HTML content of image element.
       
  1072  *
       
  1073  * @since 2.0.0
       
  1074  * @deprecated Use {@link wp_get_attachment_image()}
       
  1075  * @see wp_get_attachment_image() Use instead.
       
  1076  *
       
  1077  * @param int $id Optional. Post ID.
       
  1078  * @param bool $fullsize Optional, default to false. Whether to have full size image.
       
  1079  * @param array $max_dims Optional. Dimensions of image.
       
  1080  * @return string
       
  1081  */
       
  1082 function get_attachment_innerHTML($id = 0, $fullsize = false, $max_dims = false) {
       
  1083 	$id = (int) $id;
       
  1084 	if ( !$post = & get_post($id) )
       
  1085 		return false;
       
  1086 
       
  1087 	if ( $innerHTML = get_attachment_icon($post->ID, $fullsize, $max_dims))
       
  1088 		return $innerHTML;
       
  1089 
       
  1090 
       
  1091 	$innerHTML = esc_attr($post->post_title);
       
  1092 
       
  1093 	return apply_filters('attachment_innerHTML', $innerHTML, $post->ID);
       
  1094 }
       
  1095 
       
  1096 /**
       
  1097  * Wrap attachment in <<p>> element before content.
       
  1098  *
       
  1099  * @since 2.0.0
       
  1100  * @uses apply_filters() Calls 'prepend_attachment' hook on HTML content.
       
  1101  *
       
  1102  * @param string $content
       
  1103  * @return string
       
  1104  */
       
  1105 function prepend_attachment($content) {
       
  1106 	global $post;
       
  1107 
       
  1108 	if ( empty($post->post_type) || $post->post_type != 'attachment' )
       
  1109 		return $content;
       
  1110 
       
  1111 	$p = '<p class="attachment">';
       
  1112 	// show the medium sized image representation of the attachment if available, and link to the raw file
       
  1113 	$p .= wp_get_attachment_link(0, 'medium', false);
       
  1114 	$p .= '</p>';
       
  1115 	$p = apply_filters('prepend_attachment', $p);
       
  1116 
       
  1117 	return "$p\n$content";
       
  1118 }
       
  1119 
       
  1120 //
       
  1121 // Misc
       
  1122 //
       
  1123 
       
  1124 /**
       
  1125  * Retrieve protected post password form content.
       
  1126  *
       
  1127  * @since 1.0.0
       
  1128  * @uses apply_filters() Calls 'the_password_form' filter on output.
       
  1129  *
       
  1130  * @return string HTML content for password form for password protected post.
       
  1131  */
       
  1132 function get_the_password_form() {
       
  1133 	global $post;
       
  1134 	$label = 'pwbox-'.(empty($post->ID) ? rand() : $post->ID);
       
  1135 	$output = '<form action="' . get_option('siteurl') . '/wp-pass.php" method="post">
       
  1136 	<p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
       
  1137 	<p><label for="' . $label . '">' . __("Password:") . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr__("Submit") . '" /></p>
       
  1138 	</form>
       
  1139 	';
       
  1140 	return apply_filters('the_password_form', $output);
       
  1141 }
       
  1142 
       
  1143 /**
       
  1144  * Whether currently in a page template.
       
  1145  *
       
  1146  * This template tag allows you to determine whether or not you are in a page
       
  1147  * template. You can optional provide a template name and then the check will be
       
  1148  * specific to that template.
       
  1149  *
       
  1150  * @since 2.5.0
       
  1151  * @uses $wp_query
       
  1152  *
       
  1153  * @param string $template The specific template name if specific matching is required.
       
  1154  * @return bool False on failure, true if success.
       
  1155  */
       
  1156 function is_page_template($template = '') {
       
  1157 	if (!is_page()) {
       
  1158 		return false;
       
  1159 	}
       
  1160 
       
  1161 	global $wp_query;
       
  1162 
       
  1163 	$page = $wp_query->get_queried_object();
       
  1164 	$custom_fields = get_post_custom_values('_wp_page_template',$page->ID);
       
  1165 	$page_template = $custom_fields[0];
       
  1166 
       
  1167 	// We have no argument passed so just see if a page_template has been specified
       
  1168 	if ( empty( $template ) ) {
       
  1169 		if (!empty( $page_template ) ) {
       
  1170 			return true;
       
  1171 		}
       
  1172 	} elseif ( $template == $page_template) {
       
  1173 		return true;
       
  1174 	}
       
  1175 
       
  1176 	return false;
       
  1177 }
       
  1178 
       
  1179 /**
       
  1180  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
       
  1181  *
       
  1182  * @package WordPress
       
  1183  * @subpackage Post_Revisions
       
  1184  * @since 2.6.0
       
  1185  *
       
  1186  * @uses date_i18n()
       
  1187  *
       
  1188  * @param int|object $revision Revision ID or revision object.
       
  1189  * @param bool $link Optional, default is true. Link to revisions's page?
       
  1190  * @return string i18n formatted datetimestamp or localized 'Current Revision'.
       
  1191  */
       
  1192 function wp_post_revision_title( $revision, $link = true ) {
       
  1193 	if ( !$revision = get_post( $revision ) )
       
  1194 		return $revision;
       
  1195 
       
  1196 	if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
       
  1197 		return false;
       
  1198 
       
  1199 	/* translators: revision date format, see http://php.net/date */
       
  1200 	$datef = _x( 'j F, Y @ G:i', 'revision date format');
       
  1201 	/* translators: 1: date */
       
  1202 	$autosavef = __( '%1$s [Autosave]' );
       
  1203 	/* translators: 1: date */
       
  1204 	$currentf  = __( '%1$s [Current Revision]' );
       
  1205 
       
  1206 	$date = date_i18n( $datef, strtotime( $revision->post_modified_gmt . ' +0000' ) );
       
  1207 	if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
       
  1208 		$date = "<a href='$link'>$date</a>";
       
  1209 
       
  1210 	if ( !wp_is_post_revision( $revision ) )
       
  1211 		$date = sprintf( $currentf, $date );
       
  1212 	elseif ( wp_is_post_autosave( $revision ) )
       
  1213 		$date = sprintf( $autosavef, $date );
       
  1214 
       
  1215 	return $date;
       
  1216 }
       
  1217 
       
  1218 /**
       
  1219  * Display list of a post's revisions.
       
  1220  *
       
  1221  * Can output either a UL with edit links or a TABLE with diff interface, and
       
  1222  * restore action links.
       
  1223  *
       
  1224  * Second argument controls parameters:
       
  1225  *   (bool)   parent : include the parent (the "Current Revision") in the list.
       
  1226  *   (string) format : 'list' or 'form-table'.  'list' outputs UL, 'form-table'
       
  1227  *                     outputs TABLE with UI.
       
  1228  *   (int)    right  : what revision is currently being viewed - used in
       
  1229  *                     form-table format.
       
  1230  *   (int)    left   : what revision is currently being diffed against right -
       
  1231  *                     used in form-table format.
       
  1232  *
       
  1233  * @package WordPress
       
  1234  * @subpackage Post_Revisions
       
  1235  * @since 2.6.0
       
  1236  *
       
  1237  * @uses wp_get_post_revisions()
       
  1238  * @uses wp_post_revision_title()
       
  1239  * @uses get_edit_post_link()
       
  1240  * @uses get_the_author_meta()
       
  1241  *
       
  1242  * @todo split into two functions (list, form-table) ?
       
  1243  *
       
  1244  * @param int|object $post_id Post ID or post object.
       
  1245  * @param string|array $args See description {@link wp_parse_args()}.
       
  1246  * @return null
       
  1247  */
       
  1248 function wp_list_post_revisions( $post_id = 0, $args = null ) {
       
  1249 	if ( !$post = get_post( $post_id ) )
       
  1250 		return;
       
  1251 
       
  1252 	$defaults = array( 'parent' => false, 'right' => false, 'left' => false, 'format' => 'list', 'type' => 'all' );
       
  1253 	extract( wp_parse_args( $args, $defaults ), EXTR_SKIP );
       
  1254 
       
  1255 	switch ( $type ) {
       
  1256 	case 'autosave' :
       
  1257 		if ( !$autosave = wp_get_post_autosave( $post->ID ) )
       
  1258 			return;
       
  1259 		$revisions = array( $autosave );
       
  1260 		break;
       
  1261 	case 'revision' : // just revisions - remove autosave later
       
  1262 	case 'all' :
       
  1263 	default :
       
  1264 		if ( !$revisions = wp_get_post_revisions( $post->ID ) )
       
  1265 			return;
       
  1266 		break;
       
  1267 	}
       
  1268 
       
  1269 	/* translators: post revision: 1: when, 2: author name */
       
  1270 	$titlef = _x( '%1$s by %2$s', 'post revision' );
       
  1271 
       
  1272 	if ( $parent )
       
  1273 		array_unshift( $revisions, $post );
       
  1274 
       
  1275 	$rows = '';
       
  1276 	$class = false;
       
  1277 	$can_edit_post = current_user_can( 'edit_post', $post->ID );
       
  1278 	foreach ( $revisions as $revision ) {
       
  1279 		if ( !current_user_can( 'read_post', $revision->ID ) )
       
  1280 			continue;
       
  1281 		if ( 'revision' === $type && wp_is_post_autosave( $revision ) )
       
  1282 			continue;
       
  1283 
       
  1284 		$date = wp_post_revision_title( $revision );
       
  1285 		$name = get_the_author_meta( 'display_name', $revision->post_author );
       
  1286 
       
  1287 		if ( 'form-table' == $format ) {
       
  1288 			if ( $left )
       
  1289 				$left_checked = $left == $revision->ID ? ' checked="checked"' : '';
       
  1290 			else
       
  1291 				$left_checked = $right_checked ? ' checked="checked"' : ''; // [sic] (the next one)
       
  1292 			$right_checked = $right == $revision->ID ? ' checked="checked"' : '';
       
  1293 
       
  1294 			$class = $class ? '' : " class='alternate'";
       
  1295 
       
  1296 			if ( $post->ID != $revision->ID && $can_edit_post )
       
  1297 				$actions = '<a href="' . wp_nonce_url( add_query_arg( array( 'revision' => $revision->ID, 'diff' => false, 'action' => 'restore' ) ), "restore-post_$post->ID|$revision->ID" ) . '">' . __( 'Restore' ) . '</a>';
       
  1298 			else
       
  1299 				$actions = '';
       
  1300 
       
  1301 			$rows .= "<tr$class>\n";
       
  1302 			$rows .= "\t<th style='white-space: nowrap' scope='row'><input type='radio' name='left' value='$revision->ID'$left_checked /><input type='radio' name='right' value='$revision->ID'$right_checked /></th>\n";
       
  1303 			$rows .= "\t<td>$date</td>\n";
       
  1304 			$rows .= "\t<td>$name</td>\n";
       
  1305 			$rows .= "\t<td class='action-links'>$actions</td>\n";
       
  1306 			$rows .= "</tr>\n";
       
  1307 		} else {
       
  1308 			$title = sprintf( $titlef, $date, $name );
       
  1309 			$rows .= "\t<li>$title</li>\n";
       
  1310 		}
       
  1311 	}
       
  1312 
       
  1313 	if ( 'form-table' == $format ) : ?>
       
  1314 
       
  1315 <form action="revision.php" method="get">
       
  1316 
       
  1317 <div class="tablenav">
       
  1318 	<div class="alignleft">
       
  1319 		<input type="submit" class="button-secondary" value="<?php esc_attr_e( 'Compare Revisions' ); ?>" />
       
  1320 		<input type="hidden" name="action" value="diff" />
       
  1321 	</div>
       
  1322 </div>
       
  1323 
       
  1324 <br class="clear" />
       
  1325 
       
  1326 <table class="widefat post-revisions" cellspacing="0">
       
  1327 	<col />
       
  1328 	<col style="width: 33%" />
       
  1329 	<col style="width: 33%" />
       
  1330 	<col style="width: 33%" />
       
  1331 <thead>
       
  1332 <tr>
       
  1333 	<th scope="col"></th>
       
  1334 	<th scope="col"><?php _e( 'Date Created' ); ?></th>
       
  1335 	<th scope="col"><?php _e( 'Author' ); ?></th>
       
  1336 	<th scope="col" class="action-links"><?php _e( 'Actions' ); ?></th>
       
  1337 </tr>
       
  1338 </thead>
       
  1339 <tbody>
       
  1340 
       
  1341 <?php echo $rows; ?>
       
  1342 
       
  1343 </tbody>
       
  1344 </table>
       
  1345 
       
  1346 </form>
       
  1347 
       
  1348 <?php
       
  1349 	else :
       
  1350 		echo "<ul class='post-revisions'>\n";
       
  1351 		echo $rows;
       
  1352 		echo "</ul>";
       
  1353 	endif;
       
  1354 
       
  1355 }