wp/wp-includes/post-template.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    20 /**
    20 /**
    21  * Retrieve the ID of the current item in the WordPress Loop.
    21  * Retrieve the ID of the current item in the WordPress Loop.
    22  *
    22  *
    23  * @since 2.1.0
    23  * @since 2.1.0
    24  *
    24  *
    25  * @return int|bool The ID of the current item in the WordPress Loop. False if $post is not set.
    25  * @return int|false The ID of the current item in the WordPress Loop. False if $post is not set.
    26  */
    26  */
    27 function get_the_ID() {
    27 function get_the_ID() {
    28 	$post = get_post();
    28 	$post = get_post();
    29 	return ! empty( $post ) ? $post->ID : false;
    29 	return ! empty( $post ) ? $post->ID : false;
    30 }
    30 }
    31 
    31 
    32 /**
    32 /**
    33  * Display or retrieve the current post title with optional content.
    33  * Display or retrieve the current post title with optional markup.
    34  *
    34  *
    35  * @since 0.71
    35  * @since 0.71
    36  *
    36  *
    37  * @param string $before Optional. Content to prepend to the title.
    37  * @param string $before Optional. Markup to prepend to the title. Default empty.
    38  * @param string $after Optional. Content to append to the title.
    38  * @param string $after  Optional. Markup to append to the title. Default empty.
    39  * @param bool $echo Optional, default to true.Whether to display or return.
    39  * @param bool   $echo   Optional. Whether to echo or return the title. Default true for echo.
    40  * @return null|string Null on no title. String if $echo parameter is false.
    40  * @return string|void Current post title if $echo is false.
    41  */
    41  */
    42 function the_title($before = '', $after = '', $echo = true) {
    42 function the_title( $before = '', $after = '', $echo = true ) {
    43 	$title = get_the_title();
    43 	$title = get_the_title();
    44 
    44 
    45 	if ( strlen($title) == 0 )
    45 	if ( strlen($title) == 0 )
    46 		return;
    46 		return;
    47 
    47 
    54 }
    54 }
    55 
    55 
    56 /**
    56 /**
    57  * Sanitize the current title when retrieving or displaying.
    57  * Sanitize the current title when retrieving or displaying.
    58  *
    58  *
    59  * Works like {@link the_title()}, except the parameters can be in a string or
    59  * Works like the_title(), except the parameters can be in a string or
    60  * an array. See the function for what can be override in the $args parameter.
    60  * an array. See the function for what can be override in the $args parameter.
    61  *
    61  *
    62  * The title before it is displayed will have the tags stripped and {@link
    62  * The title before it is displayed will have the tags stripped and esc_attr()
    63  * esc_attr()} before it is passed to the user or displayed. The default
    63  * before it is passed to the user or displayed. The default as with the_title(),
    64  * as with {@link the_title()}, is to display the title.
    64  * is to display the title.
    65  *
    65  *
    66  * @since 2.3.0
    66  * @since 2.3.0
    67  *
    67  *
    68  * @param string|array $args {
    68  * @param string|array $args {
    69  *     Title attribute arguments. Optional.
    69  *     Title attribute arguments. Optional.
    71  *     @type string  $before Markup to prepend to the title. Default empty.
    71  *     @type string  $before Markup to prepend to the title. Default empty.
    72  *     @type string  $after  Markup to append to the title. Default empty.
    72  *     @type string  $after  Markup to append to the title. Default empty.
    73  *     @type bool    $echo   Whether to echo or return the title. Default true for echo.
    73  *     @type bool    $echo   Whether to echo or return the title. Default true for echo.
    74  *     @type WP_Post $post   Current post object to retrieve the title for.
    74  *     @type WP_Post $post   Current post object to retrieve the title for.
    75  * }
    75  * }
    76  * @return string|null Null on failure or display. String when echo is false.
    76  * @return string|void String when echo is false.
    77  */
    77  */
    78 function the_title_attribute( $args = '' ) {
    78 function the_title_attribute( $args = '' ) {
    79 	$defaults = array( 'before' => '', 'after' =>  '', 'echo' => true, 'post' => get_post() );
    79 	$defaults = array( 'before' => '', 'after' =>  '', 'echo' => true, 'post' => get_post() );
    80 	$r = wp_parse_args( $args, $defaults );
    80 	$r = wp_parse_args( $args, $defaults );
    81 
    81 
   115 
   115 
   116 	if ( ! is_admin() ) {
   116 	if ( ! is_admin() ) {
   117 		if ( ! empty( $post->post_password ) ) {
   117 		if ( ! empty( $post->post_password ) ) {
   118 
   118 
   119 			/**
   119 			/**
   120 			 * Filter the text prepended to the post title for protected posts.
   120 			 * Filters the text prepended to the post title for protected posts.
   121 			 *
   121 			 *
   122 			 * The filter is only applied on the front end.
   122 			 * The filter is only applied on the front end.
   123 			 *
   123 			 *
   124 			 * @since 2.8.0
   124 			 * @since 2.8.0
   125 			 *
   125 			 *
   130 			$protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
   130 			$protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
   131 			$title = sprintf( $protected_title_format, $title );
   131 			$title = sprintf( $protected_title_format, $title );
   132 		} elseif ( isset( $post->post_status ) && 'private' == $post->post_status ) {
   132 		} elseif ( isset( $post->post_status ) && 'private' == $post->post_status ) {
   133 
   133 
   134 			/**
   134 			/**
   135 			 * Filter the text prepended to the post title of private posts.
   135 			 * Filters the text prepended to the post title of private posts.
   136 			 *
   136 			 *
   137 			 * The filter is only applied on the front end.
   137 			 * The filter is only applied on the front end.
   138 			 *
   138 			 *
   139 			 * @since 2.8.0
   139 			 * @since 2.8.0
   140 			 *
   140 			 *
   146 			$title = sprintf( $private_title_format, $title );
   146 			$title = sprintf( $private_title_format, $title );
   147 		}
   147 		}
   148 	}
   148 	}
   149 
   149 
   150 	/**
   150 	/**
   151 	 * Filter the post title.
   151 	 * Filters the post title.
   152 	 *
   152 	 *
   153 	 * @since 0.71
   153 	 * @since 0.71
   154 	 *
   154 	 *
   155 	 * @param string $title The post title.
   155 	 * @param string $title The post title.
   156 	 * @param int    $id    The post ID.
   156 	 * @param int    $id    The post ID.
   159 }
   159 }
   160 
   160 
   161 /**
   161 /**
   162  * Display the Post Global Unique Identifier (guid).
   162  * Display the Post Global Unique Identifier (guid).
   163  *
   163  *
       
   164  * The guid will appear to be a link, but should not be used as a link to the
       
   165  * post. The reason you should not use it as a link, is because of moving the
       
   166  * blog across domains.
       
   167  *
       
   168  * URL is escaped to make it XML-safe.
       
   169  *
       
   170  * @since 1.5.0
       
   171  *
       
   172  * @param int|WP_Post $post Optional. Post ID or post object. Default is global $post.
       
   173  */
       
   174 function the_guid( $post = 0 ) {
       
   175 	$post = get_post( $post );
       
   176 
       
   177 	$guid = isset( $post->guid ) ? get_the_guid( $post ) : '';
       
   178 	$id   = isset( $post->ID ) ? $post->ID : 0;
       
   179 
       
   180 	/**
       
   181 	 * Filters the escaped Global Unique Identifier (guid) of the post.
       
   182 	 *
       
   183 	 * @since 4.2.0
       
   184 	 *
       
   185 	 * @see get_the_guid()
       
   186 	 *
       
   187 	 * @param string $guid Escaped Global Unique Identifier (guid) of the post.
       
   188 	 * @param int    $id   The post ID.
       
   189 	 */
       
   190 	echo apply_filters( 'the_guid', $guid, $id );
       
   191 }
       
   192 
       
   193 /**
       
   194  * Retrieve the Post Global Unique Identifier (guid).
       
   195  *
   164  * The guid will appear to be a link, but should not be used as an link to the
   196  * The guid will appear to be a link, but should not be used as an link to the
   165  * post. The reason you should not use it as a link, is because of moving the
   197  * post. The reason you should not use it as a link, is because of moving the
   166  * blog across domains.
   198  * blog across domains.
   167  *
   199  *
   168  * Url is escaped to make it xml safe
       
   169  *
       
   170  * @since 1.5.0
   200  * @since 1.5.0
   171  *
   201  *
   172  * @param int|WP_Post $id Optional. Post ID or post object.
   202  * @param int|WP_Post $post Optional. Post ID or post object. Default is global $post.
   173  */
   203  * @return string
   174 function the_guid( $id = 0 ) {
   204  */
   175 	/**
   205 function get_the_guid( $post = 0 ) {
   176 	 * Filter the escaped Global Unique Identifier (guid) of the post.
   206 	$post = get_post( $post );
   177 	 *
   207 
   178 	 * @since 4.2.0
   208 	$guid = isset( $post->guid ) ? $post->guid : '';
   179 	 *
   209 	$id   = isset( $post->ID ) ? $post->ID : 0;
   180 	 * @see get_the_guid()
   210 
   181 	 *
   211 	/**
   182 	 * @param string $post_guid Escaped Global Unique Identifier (guid) of the post.
   212 	 * Filters the Global Unique Identifier (guid) of the post.
       
   213 	 *
       
   214 	 * @since 1.5.0
       
   215 	 *
       
   216 	 * @param string $guid Global Unique Identifier (guid) of the post.
       
   217 	 * @param int    $id   The post ID.
   183 	 */
   218 	 */
   184 	echo apply_filters( 'the_guid', get_the_guid( $id ) );
   219 	return apply_filters( 'get_the_guid', $guid, $id );
   185 }
       
   186 
       
   187 /**
       
   188  * Retrieve the Post Global Unique Identifier (guid).
       
   189  *
       
   190  * The guid will appear to be a link, but should not be used as an link to the
       
   191  * post. The reason you should not use it as a link, is because of moving the
       
   192  * blog across domains.
       
   193  *
       
   194  * @since 1.5.0
       
   195  *
       
   196  * @param int|WP_Post $id Optional. Post ID or post object.
       
   197  * @return string
       
   198  */
       
   199 function get_the_guid( $id = 0 ) {
       
   200 	$post = get_post($id);
       
   201 
       
   202 	/**
       
   203 	 * Filter the Global Unique Identifier (guid) of the post.
       
   204 	 *
       
   205 	 * @since 1.5.0
       
   206 	 *
       
   207 	 * @param string $post_guid Global Unique Identifier (guid) of the post.
       
   208 	 */
       
   209 	return apply_filters( 'get_the_guid', $post->guid );
       
   210 }
   220 }
   211 
   221 
   212 /**
   222 /**
   213  * Display the post content.
   223  * Display the post content.
   214  *
   224  *
   219  */
   229  */
   220 function the_content( $more_link_text = null, $strip_teaser = false) {
   230 function the_content( $more_link_text = null, $strip_teaser = false) {
   221 	$content = get_the_content( $more_link_text, $strip_teaser );
   231 	$content = get_the_content( $more_link_text, $strip_teaser );
   222 
   232 
   223 	/**
   233 	/**
   224 	 * Filter the post content.
   234 	 * Filters the post content.
   225 	 *
   235 	 *
   226 	 * @since 0.71
   236 	 * @since 0.71
   227 	 *
   237 	 *
   228 	 * @param string $content Content of the current post.
   238 	 * @param string $content Content of the current post.
   229 	 */
   239 	 */
   235 /**
   245 /**
   236  * Retrieve the post content.
   246  * Retrieve the post content.
   237  *
   247  *
   238  * @since 0.71
   248  * @since 0.71
   239  *
   249  *
       
   250  * @global int   $page      Page number of a single post/page.
       
   251  * @global int   $more      Boolean indicator for whether single post/page is being viewed.
       
   252  * @global bool  $preview   Whether post/page is in preview mode.
       
   253  * @global array $pages     Array of all pages in post/page. Each array element contains part of the content separated by the <!--nextpage--> tag.
       
   254  * @global int   $multipage Boolean indicator for whether multiple pages are in play.
       
   255  *
   240  * @param string $more_link_text Optional. Content for when there is more text.
   256  * @param string $more_link_text Optional. Content for when there is more text.
   241  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
   257  * @param bool   $strip_teaser   Optional. Strip teaser content before the more text. Default is false.
   242  * @return string
   258  * @return string
   243  */
   259  */
   244 function get_the_content( $more_link_text = null, $strip_teaser = false ) {
   260 function get_the_content( $more_link_text = null, $strip_teaser = false ) {
   245 	global $page, $more, $preview, $pages, $multipage;
   261 	global $page, $more, $preview, $pages, $multipage;
   246 
   262 
   247 	$post = get_post();
   263 	$post = get_post();
   248 
   264 
   249 	if ( null === $more_link_text )
   265 	if ( null === $more_link_text ) {
   250 		$more_link_text = __( '(more&hellip;)' );
   266 		$more_link_text = sprintf(
       
   267 			'<span aria-label="%1$s">%2$s</span>',
       
   268 			sprintf(
       
   269 				/* translators: %s: Name of current post */
       
   270 				__( 'Continue reading %s' ),
       
   271 				the_title_attribute( array( 'echo' => false ) )
       
   272 			),
       
   273 			__( '(more&hellip;)' )
       
   274 		);
       
   275 	}
   251 
   276 
   252 	$output = '';
   277 	$output = '';
   253 	$has_teaser = false;
   278 	$has_teaser = false;
   254 
   279 
   255 	// If post password required and it doesn't match the cookie.
   280 	// If post password required and it doesn't match the cookie.
   285 			$output .= '<span id="more-' . $post->ID . '"></span>' . $content[1];
   310 			$output .= '<span id="more-' . $post->ID . '"></span>' . $content[1];
   286 		} else {
   311 		} else {
   287 			if ( ! empty( $more_link_text ) )
   312 			if ( ! empty( $more_link_text ) )
   288 
   313 
   289 				/**
   314 				/**
   290 				 * Filter the Read More link text.
   315 				 * Filters the Read More link text.
   291 				 *
   316 				 *
   292 				 * @since 2.8.0
   317 				 * @since 2.8.0
   293 				 *
   318 				 *
   294 				 * @param string $more_link_element Read More link element.
   319 				 * @param string $more_link_element Read More link element.
   295 				 * @param string $more_link_text    Read More text.
   320 				 * @param string $more_link_text    Read More text.
   308 /**
   333 /**
   309  * Preview fix for JavaScript bug with foreign languages.
   334  * Preview fix for JavaScript bug with foreign languages.
   310  *
   335  *
   311  * @since 3.1.0
   336  * @since 3.1.0
   312  * @access private
   337  * @access private
   313  * @param array $match Match array from preg_replace_callback
   338  *
       
   339  * @param array $match Match array from preg_replace_callback.
   314  * @return string
   340  * @return string
   315  */
   341  */
   316 function _convert_urlencoded_to_entities( $match ) {
   342 function _convert_urlencoded_to_entities( $match ) {
   317 	return '&#' . base_convert( $match[1], 16, 10 ) . ';';
   343 	return '&#' . base_convert( $match[1], 16, 10 ) . ';';
   318 }
   344 }
   323  * @since 0.71
   349  * @since 0.71
   324  */
   350  */
   325 function the_excerpt() {
   351 function the_excerpt() {
   326 
   352 
   327 	/**
   353 	/**
   328 	 * Filter the displayed post excerpt.
   354 	 * Filters the displayed post excerpt.
   329 	 *
   355 	 *
   330 	 * @since 0.71
   356 	 * @since 0.71
   331 	 *
   357 	 *
   332 	 * @see get_the_excerpt()
   358 	 * @see get_the_excerpt()
   333 	 *
   359 	 *
   335 	 */
   361 	 */
   336 	echo apply_filters( 'the_excerpt', get_the_excerpt() );
   362 	echo apply_filters( 'the_excerpt', get_the_excerpt() );
   337 }
   363 }
   338 
   364 
   339 /**
   365 /**
   340  * Retrieve the post excerpt.
   366  * Retrieves the post excerpt.
   341  *
   367  *
   342  * @since 0.71
   368  * @since 0.71
   343  *
   369  * @since 4.5.0 Introduced the `$post` parameter.
   344  * @param mixed $deprecated Not used.
   370  *
   345  * @return string
   371  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
   346  */
   372  * @return string Post excerpt.
   347 function get_the_excerpt( $deprecated = '' ) {
   373  */
   348 	if ( !empty( $deprecated ) )
   374 function get_the_excerpt( $post = null ) {
   349 		_deprecated_argument( __FUNCTION__, '2.3' );
   375 	if ( is_bool( $post ) ) {
   350 
   376 		_deprecated_argument( __FUNCTION__, '2.3.0' );
   351 	$post = get_post();
   377 	}
       
   378 
       
   379 	$post = get_post( $post );
   352 	if ( empty( $post ) ) {
   380 	if ( empty( $post ) ) {
   353 		return '';
   381 		return '';
   354 	}
   382 	}
   355 
   383 
   356 	if ( post_password_required() ) {
   384 	if ( post_password_required( $post ) ) {
   357 		return __( 'There is no excerpt because this is a protected post.' );
   385 		return __( 'There is no excerpt because this is a protected post.' );
   358 	}
   386 	}
   359 
   387 
   360 	/**
   388 	/**
   361 	 * Filter the retrieved post excerpt.
   389 	 * Filters the retrieved post excerpt.
   362 	 *
   390 	 *
   363 	 * @since 1.2.0
   391 	 * @since 1.2.0
       
   392 	 * @since 4.5.0 Introduced the `$post` parameter.
   364 	 *
   393 	 *
   365 	 * @param string $post_excerpt The post excerpt.
   394 	 * @param string $post_excerpt The post excerpt.
       
   395 	 * @param WP_Post $post Post object.
   366 	 */
   396 	 */
   367 	return apply_filters( 'get_the_excerpt', $post->post_excerpt );
   397 	return apply_filters( 'get_the_excerpt', $post->post_excerpt, $post );
   368 }
   398 }
   369 
   399 
   370 /**
   400 /**
   371  * Whether post has excerpt.
   401  * Whether the post has a custom excerpt.
   372  *
   402  *
   373  * @since 2.3.0
   403  * @since 2.3.0
   374  *
   404  *
   375  * @param int|WP_Post $id Optional. Post ID or post object.
   405  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
   376  * @return bool
   406  * @return bool True if the post has a custom excerpt, false otherwise.
   377  */
   407  */
   378 function has_excerpt( $id = 0 ) {
   408 function has_excerpt( $post = 0 ) {
   379 	$post = get_post( $id );
   409 	$post = get_post( $post );
   380 	return ( !empty( $post->post_excerpt ) );
   410 	return ( !empty( $post->post_excerpt ) );
   381 }
   411 }
   382 
   412 
   383 /**
   413 /**
   384  * Display the classes for the post div.
   414  * Display the classes for the post div.
   385  *
   415  *
   386  * @since 2.7.0
   416  * @since 2.7.0
   387  *
   417  *
   388  * @param string|array $class One or more classes to add to the class list.
   418  * @param string|array $class   One or more classes to add to the class list.
   389  * @param int|WP_Post $post_id Optional. Post ID or post object.
   419  * @param int|WP_Post  $post_id Optional. Post ID or post object. Defaults to the global `$post`.
   390  */
   420  */
   391 function post_class( $class = '', $post_id = null ) {
   421 function post_class( $class = '', $post_id = null ) {
   392 	// Separates classes with a single space, collates classes for post DIV
   422 	// Separates classes with a single space, collates classes for post DIV
   393 	echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
   423 	echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
   394 }
   424 }
   395 
   425 
   396 /**
   426 /**
   397  * Retrieve the classes for the post div as an array.
   427  * Retrieves the classes for the post div as an array.
   398  *
   428  *
   399  * The class names are many. If the post is a sticky, then the 'sticky'
   429  * The class names are many. If the post is a sticky, then the 'sticky'
   400  * class name. The class 'hentry' is always added to each post. If the post has a
   430  * class name. The class 'hentry' is always added to each post. If the post has a
   401  * post thumbnail, 'has-post-thumbnail' is added as a class. For each taxonomy that
   431  * post thumbnail, 'has-post-thumbnail' is added as a class. For each taxonomy that
   402  * the post belongs to, a class will be added of the format '{$taxonomy}-{$slug}' -
   432  * the post belongs to, a class will be added of the format '{$taxonomy}-{$slug}' -
   403  * eg 'category-foo' or 'my_custom_taxonomy-bar'. The 'post_tag' taxonomy is a special
   433  * eg 'category-foo' or 'my_custom_taxonomy-bar'.
       
   434  *
       
   435  * The 'post_tag' taxonomy is a special
   404  * case; the class has the 'tag-' prefix instead of 'post_tag-'. All classes are
   436  * case; the class has the 'tag-' prefix instead of 'post_tag-'. All classes are
   405  * passed through the filter, 'post_class' with the list of classes, followed by
   437  * passed through the filter, {@see 'post_class'}, with the list of classes, followed by
   406  * $class parameter value, with the post ID as the last parameter.
   438  * $class parameter value, with the post ID as the last parameter.
   407  *
   439  *
   408  * @since 2.7.0
   440  * @since 2.7.0
   409  * @since 4.2.0 Custom taxonomy classes were added.
   441  * @since 4.2.0 Custom taxonomy classes were added.
   410  *
   442  *
   420 	if ( $class ) {
   452 	if ( $class ) {
   421 		if ( ! is_array( $class ) ) {
   453 		if ( ! is_array( $class ) ) {
   422 			$class = preg_split( '#\s+#', $class );
   454 			$class = preg_split( '#\s+#', $class );
   423 		}
   455 		}
   424 		$classes = array_map( 'esc_attr', $class );
   456 		$classes = array_map( 'esc_attr', $class );
       
   457 	} else {
       
   458 		// Ensure that we always coerce class to being an array.
       
   459 		$class = array();
   425 	}
   460 	}
   426 
   461 
   427 	if ( ! $post ) {
   462 	if ( ! $post ) {
   428 		return $classes;
   463 		return $classes;
   429 	}
   464 	}
   442 			$classes[] = 'format-' . sanitize_html_class( $post_format );
   477 			$classes[] = 'format-' . sanitize_html_class( $post_format );
   443 		else
   478 		else
   444 			$classes[] = 'format-standard';
   479 			$classes[] = 'format-standard';
   445 	}
   480 	}
   446 
   481 
   447 	// Post requires password
   482 	$post_password_required = post_password_required( $post->ID );
   448 	if ( post_password_required( $post->ID ) ) {
   483 
       
   484 	// Post requires password.
       
   485 	if ( $post_password_required ) {
   449 		$classes[] = 'post-password-required';
   486 		$classes[] = 'post-password-required';
   450 	// Post thumbnails
   487 	} elseif ( ! empty( $post->post_password ) ) {
   451 	} elseif ( ! is_attachment( $post ) && current_theme_supports( 'post-thumbnails' ) && has_post_thumbnail( $post->ID ) ) {
   488 		$classes[] = 'post-password-protected';
       
   489 	}
       
   490 
       
   491 	// Post thumbnails.
       
   492 	if ( current_theme_supports( 'post-thumbnails' ) && has_post_thumbnail( $post->ID ) && ! is_attachment( $post ) && ! $post_password_required ) {
   452 		$classes[] = 'has-post-thumbnail';
   493 		$classes[] = 'has-post-thumbnail';
   453 	}
   494 	}
   454 
   495 
   455 	// sticky for Sticky Posts
   496 	// sticky for Sticky Posts
   456 	if ( is_sticky( $post->ID ) ) {
   497 	if ( is_sticky( $post->ID ) ) {
   489 	}
   530 	}
   490 
   531 
   491 	$classes = array_map( 'esc_attr', $classes );
   532 	$classes = array_map( 'esc_attr', $classes );
   492 
   533 
   493 	/**
   534 	/**
   494 	 * Filter the list of CSS classes for the current post.
   535 	 * Filters the list of CSS classes for the current post.
   495 	 *
   536 	 *
   496 	 * @since 2.7.0
   537 	 * @since 2.7.0
   497 	 *
   538 	 *
   498 	 * @param array  $classes An array of post classes.
   539 	 * @param array $classes An array of post classes.
   499 	 * @param string $class   A comma-separated list of additional classes added to the post.
   540 	 * @param array $class   An array of additional classes added to the post.
   500 	 * @param int    $post_id The post ID.
   541 	 * @param int   $post_id The post ID.
   501 	 */
   542 	 */
   502 	$classes = apply_filters( 'post_class', $classes, $class, $post->ID );
   543 	$classes = apply_filters( 'post_class', $classes, $class, $post->ID );
   503 
   544 
   504 	return array_unique( $classes );
   545 	return array_unique( $classes );
   505 }
   546 }
   519 /**
   560 /**
   520  * Retrieve the classes for the body element as an array.
   561  * Retrieve the classes for the body element as an array.
   521  *
   562  *
   522  * @since 2.8.0
   563  * @since 2.8.0
   523  *
   564  *
       
   565  * @global WP_Query $wp_query
       
   566  *
   524  * @param string|array $class One or more classes to add to the class list.
   567  * @param string|array $class One or more classes to add to the class list.
   525  * @return array Array of classes.
   568  * @return array Array of classes.
   526  */
   569  */
   527 function get_body_class( $class = '' ) {
   570 function get_body_class( $class = '' ) {
   528 	global $wp_query, $wpdb;
   571 	global $wp_query;
   529 
   572 
   530 	$classes = array();
   573 	$classes = array();
   531 
   574 
   532 	if ( is_rtl() )
   575 	if ( is_rtl() )
   533 		$classes[] = 'rtl';
   576 		$classes[] = 'rtl';
   549 	if ( is_attachment() )
   592 	if ( is_attachment() )
   550 		$classes[] = 'attachment';
   593 		$classes[] = 'attachment';
   551 	if ( is_404() )
   594 	if ( is_404() )
   552 		$classes[] = 'error404';
   595 		$classes[] = 'error404';
   553 
   596 
   554 	if ( is_single() ) {
   597 	if ( is_singular() ) {
   555 		$post_id = $wp_query->get_queried_object_id();
   598 		$post_id = $wp_query->get_queried_object_id();
   556 		$post = $wp_query->get_queried_object();
   599 		$post = $wp_query->get_queried_object();
   557 
   600 		$post_type = $post->post_type;
   558 		$classes[] = 'single';
   601 
   559 		if ( isset( $post->post_type ) ) {
   602 		if ( is_page_template() ) {
   560 			$classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id);
   603 			$classes[] = "{$post_type}-template";
   561 			$classes[] = 'postid-' . $post_id;
   604 
   562 
   605 			$template_slug  = get_page_template_slug( $post_id );
   563 			// Post Format
   606 			$template_parts = explode( '/', $template_slug );
   564 			if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
   607 
   565 				$post_format = get_post_format( $post->ID );
   608 			foreach ( $template_parts as $part ) {
   566 
   609 				$classes[] = "{$post_type}-template-" . sanitize_html_class( str_replace( array( '.', '/' ), '-', basename( $part, '.php' ) ) );
   567 				if ( $post_format && !is_wp_error($post_format) )
   610 			}
   568 					$classes[] = 'single-format-' . sanitize_html_class( $post_format );
   611 			$classes[] = "{$post_type}-template-" . sanitize_html_class( str_replace( '.', '-', $template_slug ) );
   569 				else
   612 		} else {
   570 					$classes[] = 'single-format-standard';
   613 			$classes[] = "{$post_type}-template-default";
       
   614 		}
       
   615 
       
   616 		if ( is_single() ) {
       
   617 			$classes[] = 'single';
       
   618 			if ( isset( $post->post_type ) ) {
       
   619 				$classes[] = 'single-' . sanitize_html_class( $post->post_type, $post_id );
       
   620 				$classes[] = 'postid-' . $post_id;
       
   621 
       
   622 				// Post Format
       
   623 				if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
       
   624 					$post_format = get_post_format( $post->ID );
       
   625 
       
   626 					if ( $post_format && !is_wp_error($post_format) )
       
   627 						$classes[] = 'single-format-' . sanitize_html_class( $post_format );
       
   628 					else
       
   629 						$classes[] = 'single-format-standard';
       
   630 				}
   571 			}
   631 			}
   572 		}
   632 		}
   573 
   633 
   574 		if ( is_attachment() ) {
   634 		if ( is_attachment() ) {
   575 			$mime_type = get_post_mime_type($post_id);
   635 			$mime_type = get_post_mime_type($post_id);
   576 			$mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
   636 			$mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
   577 			$classes[] = 'attachmentid-' . $post_id;
   637 			$classes[] = 'attachmentid-' . $post_id;
   578 			$classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
   638 			$classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
       
   639 		} elseif ( is_page() ) {
       
   640 			$classes[] = 'page';
       
   641 
       
   642 			$page_id = $wp_query->get_queried_object_id();
       
   643 
       
   644 			$post = get_post($page_id);
       
   645 
       
   646 			$classes[] = 'page-id-' . $page_id;
       
   647 
       
   648 			if ( get_pages( array( 'parent' => $page_id, 'number' => 1 ) ) ) {
       
   649 				$classes[] = 'page-parent';
       
   650 			}
       
   651 
       
   652 			if ( $post->post_parent ) {
       
   653 				$classes[] = 'page-child';
       
   654 				$classes[] = 'parent-pageid-' . $post->post_parent;
       
   655 			}
   579 		}
   656 		}
   580 	} elseif ( is_archive() ) {
   657 	} elseif ( is_archive() ) {
   581 		if ( is_post_type_archive() ) {
   658 		if ( is_post_type_archive() ) {
   582 			$classes[] = 'post-type-archive';
   659 			$classes[] = 'post-type-archive';
   583 			$post_type = get_query_var( 'post_type' );
   660 			$post_type = get_query_var( 'post_type' );
   626 				$classes[] = 'tax-' . sanitize_html_class( $term->taxonomy );
   703 				$classes[] = 'tax-' . sanitize_html_class( $term->taxonomy );
   627 				$classes[] = 'term-' . $term_class;
   704 				$classes[] = 'term-' . $term_class;
   628 				$classes[] = 'term-' . $term->term_id;
   705 				$classes[] = 'term-' . $term->term_id;
   629 			}
   706 			}
   630 		}
   707 		}
   631 	} elseif ( is_page() ) {
       
   632 		$classes[] = 'page';
       
   633 
       
   634 		$page_id = $wp_query->get_queried_object_id();
       
   635 
       
   636 		$post = get_post($page_id);
       
   637 
       
   638 		$classes[] = 'page-id-' . $page_id;
       
   639 
       
   640 		if ( get_pages( array( 'parent' => $page_id, 'number' => 1 ) ) ) {
       
   641 			$classes[] = 'page-parent';
       
   642 		}
       
   643 
       
   644 		if ( $post->post_parent ) {
       
   645 			$classes[] = 'page-child';
       
   646 			$classes[] = 'parent-pageid-' . $post->post_parent;
       
   647 		}
       
   648 		if ( is_page_template() ) {
       
   649 			$classes[] = 'page-template';
       
   650 
       
   651 			$template_slug  = get_page_template_slug( $page_id );
       
   652 			$template_parts = explode( '/', $template_slug );
       
   653 
       
   654 			foreach ( $template_parts as $part ) {
       
   655 				$classes[] = 'page-template-' . sanitize_html_class( str_replace( array( '.', '/' ), '-', basename( $part, '.php' ) ) );
       
   656 			}
       
   657 			$classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', $template_slug ) );
       
   658 		} else {
       
   659 			$classes[] = 'page-template-default';
       
   660 		}
       
   661 	}
   708 	}
   662 
   709 
   663 	if ( is_user_logged_in() )
   710 	if ( is_user_logged_in() )
   664 		$classes[] = 'logged-in';
   711 		$classes[] = 'logged-in';
   665 
   712 
   668 		$classes[] = 'no-customize-support';
   715 		$classes[] = 'no-customize-support';
   669 	}
   716 	}
   670 
   717 
   671 	if ( get_background_color() !== get_theme_support( 'custom-background', 'default-color' ) || get_background_image() )
   718 	if ( get_background_color() !== get_theme_support( 'custom-background', 'default-color' ) || get_background_image() )
   672 		$classes[] = 'custom-background';
   719 		$classes[] = 'custom-background';
       
   720 
       
   721 	if ( has_custom_logo() ) {
       
   722 		$classes[] = 'wp-custom-logo';
       
   723 	}
   673 
   724 
   674 	$page = $wp_query->get( 'page' );
   725 	$page = $wp_query->get( 'page' );
   675 
   726 
   676 	if ( ! $page || $page < 2 )
   727 	if ( ! $page || $page < 2 )
   677 		$page = $wp_query->get( 'paged' );
   728 		$page = $wp_query->get( 'paged' );
   707 	}
   758 	}
   708 
   759 
   709 	$classes = array_map( 'esc_attr', $classes );
   760 	$classes = array_map( 'esc_attr', $classes );
   710 
   761 
   711 	/**
   762 	/**
   712 	 * Filter the list of CSS body classes for the current post or page.
   763 	 * Filters the list of CSS body classes for the current post or page.
   713 	 *
   764 	 *
   714 	 * @since 2.8.0
   765 	 * @since 2.8.0
   715 	 *
   766 	 *
   716 	 * @param array  $classes An array of body classes.
   767 	 * @param array $classes An array of body classes.
   717 	 * @param string $class   A comma-separated list of additional classes added to the body.
   768 	 * @param array $class   An array of additional classes added to the body.
   718 	 */
   769 	 */
   719 	$classes = apply_filters( 'body_class', $classes, $class );
   770 	$classes = apply_filters( 'body_class', $classes, $class );
   720 
   771 
   721 	return array_unique( $classes );
   772 	return array_unique( $classes );
   722 }
   773 }
   724 /**
   775 /**
   725  * Whether post requires password and correct password has been provided.
   776  * Whether post requires password and correct password has been provided.
   726  *
   777  *
   727  * @since 2.7.0
   778  * @since 2.7.0
   728  *
   779  *
   729  * @param int|WP_Post $post An optional post. Global $post used if not provided.
   780  * @param int|WP_Post|null $post An optional post. Global $post used if not provided.
   730  * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
   781  * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
   731  */
   782  */
   732 function post_password_required( $post = null ) {
   783 function post_password_required( $post = null ) {
   733 	$post = get_post($post);
   784 	$post = get_post($post);
   734 
   785 
   735 	if ( empty( $post->post_password ) )
   786 	if ( empty( $post->post_password ) ) {
   736 		return false;
   787 		/** This filter is documented in wp-includes/post-template.php */
   737 
   788 		return apply_filters( 'post_password_required', false, $post );
   738 	if ( ! isset( $_COOKIE['wp-postpass_' . COOKIEHASH] ) )
   789 	}
   739 		return true;
   790 
       
   791 	if ( ! isset( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) ) {
       
   792 		/** This filter is documented in wp-includes/post-template.php */
       
   793 		return apply_filters( 'post_password_required', true, $post );
       
   794 	}
   740 
   795 
   741 	require_once ABSPATH . WPINC . '/class-phpass.php';
   796 	require_once ABSPATH . WPINC . '/class-phpass.php';
   742 	$hasher = new PasswordHash( 8, true );
   797 	$hasher = new PasswordHash( 8, true );
   743 
   798 
   744 	$hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] );
   799 	$hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] );
   745 	if ( 0 !== strpos( $hash, '$P$B' ) )
   800 	if ( 0 !== strpos( $hash, '$P$B' ) ) {
   746 		return true;
   801 		$required = true;
   747 
   802 	} else {
   748 	return ! $hasher->CheckPassword( $post->post_password, $hash );
   803 		$required = ! $hasher->CheckPassword( $post->post_password, $hash );
       
   804 	}
       
   805 
       
   806 	/**
       
   807 	 * Filters whether a post requires the user to supply a password.
       
   808 	 *
       
   809 	 * @since 4.7.0
       
   810 	 *
       
   811 	 * @param bool    $required Whether the user needs to supply a password. True if password has not been
       
   812 	 *                          provided or is incorrect, false if password has been supplied or is not required.
       
   813 	 * @param WP_Post $post     Post data.
       
   814 	 */
       
   815 	return apply_filters( 'post_password_required', $required, $post );
   749 }
   816 }
   750 
   817 
   751 //
   818 //
   752 // Page Template Functions for usage in Themes
   819 // Page Template Functions for usage in Themes
   753 //
   820 //
   757  *
   824  *
   758  * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
   825  * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
   759  * Quicktag one or more times). This tag must be within The Loop.
   826  * Quicktag one or more times). This tag must be within The Loop.
   760  *
   827  *
   761  * @since 1.2.0
   828  * @since 1.2.0
       
   829  *
       
   830  * @global int $page
       
   831  * @global int $numpages
       
   832  * @global int $multipage
       
   833  * @global int $more
   762  *
   834  *
   763  * @param string|array $args {
   835  * @param string|array $args {
   764  *     Optional. Array or string of default arguments.
   836  *     Optional. Array or string of default arguments.
   765  *
   837  *
   766  *     @type string       $before           HTML or text to prepend to each link. Default is `<p> Pages:`.
   838  *     @type string       $before           HTML or text to prepend to each link. Default is `<p> Pages:`.
   780  *     @type int|bool     $echo             Whether to echo or not. Accepts 1|true or 0|false. Default 1|true.
   852  *     @type int|bool     $echo             Whether to echo or not. Accepts 1|true or 0|false. Default 1|true.
   781  * }
   853  * }
   782  * @return string Formatted output in HTML.
   854  * @return string Formatted output in HTML.
   783  */
   855  */
   784 function wp_link_pages( $args = '' ) {
   856 function wp_link_pages( $args = '' ) {
       
   857 	global $page, $numpages, $multipage, $more;
       
   858 
   785 	$defaults = array(
   859 	$defaults = array(
   786 		'before'           => '<p>' . __( 'Pages:' ),
   860 		'before'           => '<p>' . __( 'Pages:' ),
   787 		'after'            => '</p>',
   861 		'after'            => '</p>',
   788 		'link_before'      => '',
   862 		'link_before'      => '',
   789 		'link_after'       => '',
   863 		'link_after'       => '',
   796 	);
   870 	);
   797 
   871 
   798 	$params = wp_parse_args( $args, $defaults );
   872 	$params = wp_parse_args( $args, $defaults );
   799 
   873 
   800 	/**
   874 	/**
   801 	 * Filter the arguments used in retrieving page links for paginated posts.
   875 	 * Filters the arguments used in retrieving page links for paginated posts.
   802 	 *
   876 	 *
   803 	 * @since 3.0.0
   877 	 * @since 3.0.0
   804 	 *
   878 	 *
   805 	 * @param array $params An array of arguments for page links for paginated posts.
   879 	 * @param array $params An array of arguments for page links for paginated posts.
   806 	 */
   880 	 */
   807 	$r = apply_filters( 'wp_link_pages_args', $params );
   881 	$r = apply_filters( 'wp_link_pages_args', $params );
   808 
       
   809 	global $page, $numpages, $multipage, $more;
       
   810 
   882 
   811 	$output = '';
   883 	$output = '';
   812 	if ( $multipage ) {
   884 	if ( $multipage ) {
   813 		if ( 'number' == $r['next_or_number'] ) {
   885 		if ( 'number' == $r['next_or_number'] ) {
   814 			$output .= $r['before'];
   886 			$output .= $r['before'];
   816 				$link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
   888 				$link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
   817 				if ( $i != $page || ! $more && 1 == $page ) {
   889 				if ( $i != $page || ! $more && 1 == $page ) {
   818 					$link = _wp_link_page( $i ) . $link . '</a>';
   890 					$link = _wp_link_page( $i ) . $link . '</a>';
   819 				}
   891 				}
   820 				/**
   892 				/**
   821 				 * Filter the HTML output of individual page number links.
   893 				 * Filters the HTML output of individual page number links.
   822 				 *
   894 				 *
   823 				 * @since 3.6.0
   895 				 * @since 3.6.0
   824 				 *
   896 				 *
   825 				 * @param string $link The page number HTML output.
   897 				 * @param string $link The page number HTML output.
   826 				 * @param int    $i    Page number for paginated posts' page links.
   898 				 * @param int    $i    Page number for paginated posts' page links.
   833 			}
   905 			}
   834 			$output .= $r['after'];
   906 			$output .= $r['after'];
   835 		} elseif ( $more ) {
   907 		} elseif ( $more ) {
   836 			$output .= $r['before'];
   908 			$output .= $r['before'];
   837 			$prev = $page - 1;
   909 			$prev = $page - 1;
   838 			if ( $prev ) {
   910 			if ( $prev > 0 ) {
   839 				$link = _wp_link_page( $prev ) . $r['link_before'] . $r['previouspagelink'] . $r['link_after'] . '</a>';
   911 				$link = _wp_link_page( $prev ) . $r['link_before'] . $r['previouspagelink'] . $r['link_after'] . '</a>';
   840 
   912 
   841 				/** This filter is documented in wp-includes/post-template.php */
   913 				/** This filter is documented in wp-includes/post-template.php */
   842 				$output .= apply_filters( 'wp_link_pages_link', $link, $prev );
   914 				$output .= apply_filters( 'wp_link_pages_link', $link, $prev );
   843 			}
   915 			}
   854 			$output .= $r['after'];
   926 			$output .= $r['after'];
   855 		}
   927 		}
   856 	}
   928 	}
   857 
   929 
   858 	/**
   930 	/**
   859 	 * Filter the HTML output of page links for paginated posts.
   931 	 * Filters the HTML output of page links for paginated posts.
   860 	 *
   932 	 *
   861 	 * @since 3.6.0
   933 	 * @since 3.6.0
   862 	 *
   934 	 *
   863 	 * @param string $output HTML output of paginated posts' page links.
   935 	 * @param string $output HTML output of paginated posts' page links.
   864 	 * @param array  $args   An array of arguments.
   936 	 * @param array  $args   An array of arguments.
   875  * Helper function for wp_link_pages().
   947  * Helper function for wp_link_pages().
   876  *
   948  *
   877  * @since 3.1.0
   949  * @since 3.1.0
   878  * @access private
   950  * @access private
   879  *
   951  *
       
   952  * @global WP_Rewrite $wp_rewrite
       
   953  *
   880  * @param int $i Page number.
   954  * @param int $i Page number.
   881  * @return string Link.
   955  * @return string Link.
   882  */
   956  */
   883 function _wp_link_page( $i ) {
   957 function _wp_link_page( $i ) {
   884 	global $wp_rewrite;
   958 	global $wp_rewrite;
   885 	$post = get_post();
   959 	$post = get_post();
       
   960 	$query_args = array();
   886 
   961 
   887 	if ( 1 == $i ) {
   962 	if ( 1 == $i ) {
   888 		$url = get_permalink();
   963 		$url = get_permalink();
   889 	} else {
   964 	} else {
   890 		if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
   965 		if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
   894 		else
   969 		else
   895 			$url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
   970 			$url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
   896 	}
   971 	}
   897 
   972 
   898 	if ( is_preview() ) {
   973 	if ( is_preview() ) {
   899 		$url = add_query_arg( array(
       
   900 			'preview' => 'true'
       
   901 		), $url );
       
   902 
   974 
   903 		if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) {
   975 		if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) {
   904 			$url = add_query_arg( array(
   976 			$query_args['preview_id'] = wp_unslash( $_GET['preview_id'] );
   905 				'preview_id'    => wp_unslash( $_GET['preview_id'] ),
   977 			$query_args['preview_nonce'] = wp_unslash( $_GET['preview_nonce'] );
   906 				'preview_nonce' => wp_unslash( $_GET['preview_nonce'] )
   978 		}
   907 			), $url );
   979 
   908 		}
   980 		$url = get_preview_post_link( $post, $query_args, $url );
   909 	}
   981 	}
   910 
   982 
   911 	return '<a href="' . esc_url( $url ) . '">';
   983 	return '<a href="' . esc_url( $url ) . '">';
   912 }
   984 }
   913 
   985 
   919  * Retrieve post custom meta data field.
   991  * Retrieve post custom meta data field.
   920  *
   992  *
   921  * @since 1.5.0
   993  * @since 1.5.0
   922  *
   994  *
   923  * @param string $key Meta data key name.
   995  * @param string $key Meta data key name.
   924  * @return bool|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
   996  * @return false|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
   925  */
   997  */
   926 function post_custom( $key = '' ) {
   998 function post_custom( $key = '' ) {
   927 	$custom = get_post_custom();
   999 	$custom = get_post_custom();
   928 
  1000 
   929 	if ( !isset( $custom[$key] ) )
  1001 	if ( !isset( $custom[$key] ) )
   935 }
  1007 }
   936 
  1008 
   937 /**
  1009 /**
   938  * Display list of post custom fields.
  1010  * Display list of post custom fields.
   939  *
  1011  *
       
  1012  * @since 1.2.0
       
  1013  *
   940  * @internal This will probably change at some point...
  1014  * @internal This will probably change at some point...
   941  * @since 1.2.0
  1015  *
   942  */
  1016  */
   943 function the_meta() {
  1017 function the_meta() {
   944 	if ( $keys = get_post_custom_keys() ) {
  1018 	if ( $keys = get_post_custom_keys() ) {
   945 		echo "<ul class='post-meta'>\n";
  1019 		echo "<ul class='post-meta'>\n";
   946 		foreach ( (array) $keys as $key ) {
  1020 		foreach ( (array) $keys as $key ) {
   947 			$keyt = trim($key);
  1021 			$keyt = trim( $key );
   948 			if ( is_protected_meta( $keyt, 'post' ) )
  1022 			if ( is_protected_meta( $keyt, 'post' ) ) {
   949 				continue;
  1023 				continue;
   950 			$values = array_map('trim', get_post_custom_values($key));
  1024 			}
   951 			$value = implode($values,', ');
  1025 
       
  1026 			$values = array_map( 'trim', get_post_custom_values( $key ) );
       
  1027 			$value = implode( $values, ', ' );
       
  1028 
       
  1029 			$html = sprintf( "<li><span class='post-meta-key'>%s</span> %s</li>\n",
       
  1030 				/* translators: %s: Post custom field name */
       
  1031 				sprintf( _x( '%s:', 'Post custom field name' ), $key ),
       
  1032 				$value
       
  1033 			);
   952 
  1034 
   953 			/**
  1035 			/**
   954 			 * Filter the HTML output of the li element in the post custom fields list.
  1036 			 * Filters the HTML output of the li element in the post custom fields list.
   955 			 *
  1037 			 *
   956 			 * @since 2.2.0
  1038 			 * @since 2.2.0
   957 			 *
  1039 			 *
   958 			 * @param string $html  The HTML output for the li element.
  1040 			 * @param string $html  The HTML output for the li element.
   959 			 * @param string $key   Meta key.
  1041 			 * @param string $key   Meta key.
   960 			 * @param string $value Meta value.
  1042 			 * @param string $value Meta value.
   961 			 */
  1043 			 */
   962 			echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value );
  1044 			echo apply_filters( 'the_meta_key', $html, $key, $value );
   963 		}
  1045 		}
   964 		echo "</ul>\n";
  1046 		echo "</ul>\n";
   965 	}
  1047 	}
   966 }
  1048 }
   967 
  1049 
   972 /**
  1054 /**
   973  * Retrieve or display list of pages as a dropdown (select list).
  1055  * Retrieve or display list of pages as a dropdown (select list).
   974  *
  1056  *
   975  * @since 2.1.0
  1057  * @since 2.1.0
   976  * @since 4.2.0 The `$value_field` argument was added.
  1058  * @since 4.2.0 The `$value_field` argument was added.
       
  1059  * @since 4.3.0 The `$class` argument was added.
   977  *
  1060  *
   978  * @param array|string $args {
  1061  * @param array|string $args {
   979  *     Optional. Array or string of arguments to generate a pages drop-down element.
  1062  *     Optional. Array or string of arguments to generate a pages drop-down element.
   980  *
  1063  *
   981  *     @type int          $depth                 Maximum depth. Default 0.
  1064  *     @type int          $depth                 Maximum depth. Default 0.
   984  *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1,
  1067  *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1,
   985  *                                               or their bool equivalents. Default 1.
  1068  *                                               or their bool equivalents. Default 1.
   986  *     @type string       $name                  Value for the 'name' attribute of the select element.
  1069  *     @type string       $name                  Value for the 'name' attribute of the select element.
   987  *                                               Default 'page_id'.
  1070  *                                               Default 'page_id'.
   988  *     @type string       $id                    Value for the 'id' attribute of the select element.
  1071  *     @type string       $id                    Value for the 'id' attribute of the select element.
       
  1072  *     @type string       $class                 Value for the 'class' attribute of the select element. Default: none.
   989  *                                               Defaults to the value of `$name`.
  1073  *                                               Defaults to the value of `$name`.
   990  *     @type string       $show_option_none      Text to display for showing no pages. Default empty (does not display).
  1074  *     @type string       $show_option_none      Text to display for showing no pages. Default empty (does not display).
   991  *     @type string       $show_option_no_change Text to display for "no change" option. Default empty (does not display).
  1075  *     @type string       $show_option_no_change Text to display for "no change" option. Default empty (does not display).
   992  *     @type string       $option_none_value     Value to use when no page is selected. Default empty.
  1076  *     @type string       $option_none_value     Value to use when no page is selected. Default empty.
   993  *     @type string       $value_field           Post field used to populate the 'value' attribute of the option
  1077  *     @type string       $value_field           Post field used to populate the 'value' attribute of the option
   998 function wp_dropdown_pages( $args = '' ) {
  1082 function wp_dropdown_pages( $args = '' ) {
   999 	$defaults = array(
  1083 	$defaults = array(
  1000 		'depth' => 0, 'child_of' => 0,
  1084 		'depth' => 0, 'child_of' => 0,
  1001 		'selected' => 0, 'echo' => 1,
  1085 		'selected' => 0, 'echo' => 1,
  1002 		'name' => 'page_id', 'id' => '',
  1086 		'name' => 'page_id', 'id' => '',
       
  1087 		'class' => '',
  1003 		'show_option_none' => '', 'show_option_no_change' => '',
  1088 		'show_option_none' => '', 'show_option_no_change' => '',
  1004 		'option_none_value' => '',
  1089 		'option_none_value' => '',
  1005 		'value_field' => 'ID',
  1090 		'value_field' => 'ID',
  1006 	);
  1091 	);
  1007 
  1092 
  1013 	if ( empty( $r['id'] ) ) {
  1098 	if ( empty( $r['id'] ) ) {
  1014 		$r['id'] = $r['name'];
  1099 		$r['id'] = $r['name'];
  1015 	}
  1100 	}
  1016 
  1101 
  1017 	if ( ! empty( $pages ) ) {
  1102 	if ( ! empty( $pages ) ) {
  1018 		$output = "<select name='" . esc_attr( $r['name'] ) . "' id='" . esc_attr( $r['id'] ) . "'>\n";
  1103 		$class = '';
       
  1104 		if ( ! empty( $r['class'] ) ) {
       
  1105 			$class = " class='" . esc_attr( $r['class'] ) . "'";
       
  1106 		}
       
  1107 
       
  1108 		$output = "<select name='" . esc_attr( $r['name'] ) . "'" . $class . " id='" . esc_attr( $r['id'] ) . "'>\n";
  1019 		if ( $r['show_option_no_change'] ) {
  1109 		if ( $r['show_option_no_change'] ) {
  1020 			$output .= "\t<option value=\"-1\">" . $r['show_option_no_change'] . "</option>\n";
  1110 			$output .= "\t<option value=\"-1\">" . $r['show_option_no_change'] . "</option>\n";
  1021 		}
  1111 		}
  1022 		if ( $r['show_option_none'] ) {
  1112 		if ( $r['show_option_none'] ) {
  1023 			$output .= "\t<option value=\"" . esc_attr( $r['option_none_value'] ) . '">' . $r['show_option_none'] . "</option>\n";
  1113 			$output .= "\t<option value=\"" . esc_attr( $r['option_none_value'] ) . '">' . $r['show_option_none'] . "</option>\n";
  1025 		$output .= walk_page_dropdown_tree( $pages, $r['depth'], $r );
  1115 		$output .= walk_page_dropdown_tree( $pages, $r['depth'], $r );
  1026 		$output .= "</select>\n";
  1116 		$output .= "</select>\n";
  1027 	}
  1117 	}
  1028 
  1118 
  1029 	/**
  1119 	/**
  1030 	 * Filter the HTML output of a list of pages as a drop down.
  1120 	 * Filters the HTML output of a list of pages as a drop down.
  1031 	 *
  1121 	 *
  1032 	 * @since 2.1.0
  1122 	 * @since 2.1.0
       
  1123 	 * @since 4.4.0 `$r` and `$pages` added as arguments.
  1033 	 *
  1124 	 *
  1034 	 * @param string $output HTML output for drop down list of pages.
  1125 	 * @param string $output HTML output for drop down list of pages.
  1035 	 */
  1126 	 * @param array  $r      The parsed arguments array.
  1036 	$html = apply_filters( 'wp_dropdown_pages', $output );
  1127 	 * @param array  $pages  List of WP_Post objects returned by `get_pages()`
       
  1128  	 */
       
  1129 	$html = apply_filters( 'wp_dropdown_pages', $output, $r, $pages );
  1037 
  1130 
  1038 	if ( $r['echo'] ) {
  1131 	if ( $r['echo'] ) {
  1039 		echo $html;
  1132 		echo $html;
  1040 	}
  1133 	}
  1041 	return $html;
  1134 	return $html;
  1042 }
  1135 }
  1043 
  1136 
  1044 /**
  1137 /**
  1045  * Retrieve or display list of pages in list (li) format.
  1138  * Retrieve or display list of pages (or hierarchical post type items) in list (li) format.
  1046  *
  1139  *
  1047  * @since 1.5.0
  1140  * @since 1.5.0
       
  1141  * @since 4.7.0 Added the `item_spacing` argument.
  1048  *
  1142  *
  1049  * @see get_pages()
  1143  * @see get_pages()
       
  1144  *
       
  1145  * @global WP_Query $wp_query
  1050  *
  1146  *
  1051  * @param array|string $args {
  1147  * @param array|string $args {
  1052  *     Array or string of arguments. Optional.
  1148  *     Array or string of arguments. Optional.
  1053  *
  1149  *
  1054  *     @type int    $child_of     Display only the sub-pages of a single page by ID. Default 0 (all pages).
  1150  *     @type int          $child_of     Display only the sub-pages of a single page by ID. Default 0 (all pages).
  1055  *     @type string $authors      Comma-separated list of author IDs. Default empty (all authors).
  1151  *     @type string       $authors      Comma-separated list of author IDs. Default empty (all authors).
  1056  *     @type string $date_format  PHP date format to use for the listed pages. Relies on the 'show_date' parameter.
  1152  *     @type string       $date_format  PHP date format to use for the listed pages. Relies on the 'show_date' parameter.
  1057  *                                Default is the value of 'date_format' option.
  1153  *                                      Default is the value of 'date_format' option.
  1058  *     @type int    $depth        Number of levels in the hierarchy of pages to include in the generated list.
  1154  *     @type int          $depth        Number of levels in the hierarchy of pages to include in the generated list.
  1059  *                                Accepts -1 (any depth), 0 (all pages), 1 (top-level pages only), and n (pages to
  1155  *                                      Accepts -1 (any depth), 0 (all pages), 1 (top-level pages only), and n (pages to
  1060  *                                the given n depth). Default 0.
  1156  *                                      the given n depth). Default 0.
  1061  *     @type bool   $echo         Whether or not to echo the list of pages. Default true.
  1157  *     @type bool         $echo         Whether or not to echo the list of pages. Default true.
  1062  *     @type string $exclude      Comma-separated list of page IDs to exclude. Default empty.
  1158  *     @type string       $exclude      Comma-separated list of page IDs to exclude. Default empty.
  1063  *     @type array  $include      Comma-separated list of page IDs to include. Default empty.
  1159  *     @type array        $include      Comma-separated list of page IDs to include. Default empty.
  1064  *     @type string $link_after   Text or HTML to follow the page link label. Default null.
  1160  *     @type string       $link_after   Text or HTML to follow the page link label. Default null.
  1065  *     @type string $link_before  Text or HTML to precede the page link label. Default null.
  1161  *     @type string       $link_before  Text or HTML to precede the page link label. Default null.
  1066  *     @type string $post_type    Post type to query for. Default 'page'.
  1162  *     @type string       $post_type    Post type to query for. Default 'page'.
  1067  *     @type string $post_status  Comma-separated list of post statuses to include. Default 'publish'.
  1163  *     @type string|array $post_status  Comma-separated list or array of post statuses to include. Default 'publish'.
  1068  *     @type string $show_date	  Whether to display the page publish or modified date for each page. Accepts
  1164  *     @type string       $show_date    Whether to display the page publish or modified date for each page. Accepts
  1069  *                                'modified' or any other value. An empty value hides the date. Default empty.
  1165  *                                      'modified' or any other value. An empty value hides the date. Default empty.
  1070  *     @type string $sort_column  Comma-separated list of column names to sort the pages by. Accepts 'post_author',
  1166  *     @type string       $sort_column  Comma-separated list of column names to sort the pages by. Accepts 'post_author',
  1071  *                                'post_date', 'post_title', 'post_name', 'post_modified', 'post_modified_gmt',
  1167  *                                      'post_date', 'post_title', 'post_name', 'post_modified', 'post_modified_gmt',
  1072  *                                'menu_order', 'post_parent', 'ID', 'rand', or 'comment_count'. Default 'post_title'.
  1168  *                                      'menu_order', 'post_parent', 'ID', 'rand', or 'comment_count'. Default 'post_title'.
  1073  *     @type string $title_li     List heading. Passing a null or empty value will result in no heading, and the list
  1169  *     @type string       $title_li     List heading. Passing a null or empty value will result in no heading, and the list
  1074  *                                will not be wrapped with unordered list `<ul>` tags. Default 'Pages'.
  1170  *                                      will not be wrapped with unordered list `<ul>` tags. Default 'Pages'.
  1075  *     @type Walker $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
  1171  *     @type string       $item_spacing Whether to preserve whitespace within the menu's HTML. Accepts 'preserve' or 'discard'.
       
  1172  *                                      Default 'preserve'.
       
  1173  *     @type Walker       $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
  1076  * }
  1174  * }
  1077  * @return string HTML list of pages.
  1175  * @return string|void HTML list of pages.
  1078  */
  1176  */
  1079 function wp_list_pages( $args = '' ) {
  1177 function wp_list_pages( $args = '' ) {
  1080 	$defaults = array(
  1178 	$defaults = array(
  1081 		'depth' => 0, 'show_date' => '',
  1179 		'depth'        => 0,
  1082 		'date_format' => get_option( 'date_format' ),
  1180 		'show_date'    => '',
  1083 		'child_of' => 0, 'exclude' => '',
  1181 		'date_format'  => get_option( 'date_format' ),
  1084 		'title_li' => __( 'Pages' ), 'echo' => 1,
  1182 		'child_of'     => 0,
  1085 		'authors' => '', 'sort_column' => 'menu_order, post_title',
  1183 		'exclude'      => '',
  1086 		'link_before' => '', 'link_after' => '', 'walker' => '',
  1184 		'title_li'     => __( 'Pages' ),
       
  1185 		'echo'         => 1,
       
  1186 		'authors'      => '',
       
  1187 		'sort_column'  => 'menu_order, post_title',
       
  1188 		'link_before'  => '',
       
  1189 		'link_after'   => '',
       
  1190 		'item_spacing' => 'preserve',
       
  1191 		'walker'       => '',
  1087 	);
  1192 	);
  1088 
  1193 
  1089 	$r = wp_parse_args( $args, $defaults );
  1194 	$r = wp_parse_args( $args, $defaults );
       
  1195 
       
  1196 	if ( ! in_array( $r['item_spacing'], array( 'preserve', 'discard' ), true ) ) {
       
  1197 		// invalid value, fall back to default.
       
  1198 		$r['item_spacing'] = $defaults['item_spacing'];
       
  1199 	}
  1090 
  1200 
  1091 	$output = '';
  1201 	$output = '';
  1092 	$current_page = 0;
  1202 	$current_page = 0;
  1093 
  1203 
  1094 	// sanitize, mostly to keep spaces out
  1204 	// sanitize, mostly to keep spaces out
  1096 
  1206 
  1097 	// Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
  1207 	// Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
  1098 	$exclude_array = ( $r['exclude'] ) ? explode( ',', $r['exclude'] ) : array();
  1208 	$exclude_array = ( $r['exclude'] ) ? explode( ',', $r['exclude'] ) : array();
  1099 
  1209 
  1100 	/**
  1210 	/**
  1101 	 * Filter the array of pages to exclude from the pages list.
  1211 	 * Filters the array of pages to exclude from the pages list.
  1102 	 *
  1212 	 *
  1103 	 * @since 2.1.0
  1213 	 * @since 2.1.0
  1104 	 *
  1214 	 *
  1105 	 * @param array $exclude_array An array of page IDs to exclude.
  1215 	 * @param array $exclude_array An array of page IDs to exclude.
  1106 	 */
  1216 	 */
  1130 			$output .= '</ul></li>';
  1240 			$output .= '</ul></li>';
  1131 		}
  1241 		}
  1132 	}
  1242 	}
  1133 
  1243 
  1134 	/**
  1244 	/**
  1135 	 * Filter the HTML output of the pages to list.
  1245 	 * Filters the HTML output of the pages to list.
  1136 	 *
  1246 	 *
  1137 	 * @since 1.5.1
  1247 	 * @since 1.5.1
       
  1248 	 * @since 4.4.0 `$pages` added as arguments.
  1138 	 *
  1249 	 *
  1139 	 * @see wp_list_pages()
  1250 	 * @see wp_list_pages()
  1140 	 *
  1251 	 *
  1141 	 * @param string $output HTML output of the pages list.
  1252 	 * @param string $output HTML output of the pages list.
  1142 	 * @param array  $r      An array of page-listing arguments.
  1253 	 * @param array  $r      An array of page-listing arguments.
       
  1254 	 * @param array  $pages  List of WP_Post objects returned by `get_pages()`
  1143 	 */
  1255 	 */
  1144 	$html = apply_filters( 'wp_list_pages', $output, $r );
  1256 	$html = apply_filters( 'wp_list_pages', $output, $r, $pages );
  1145 
  1257 
  1146 	if ( $r['echo'] ) {
  1258 	if ( $r['echo'] ) {
  1147 		echo $html;
  1259 		echo $html;
  1148 	} else {
  1260 	} else {
  1149 		return $html;
  1261 		return $html;
  1150 	}
  1262 	}
  1151 }
  1263 }
  1152 
  1264 
  1153 /**
  1265 /**
  1154  * Display or retrieve list of pages with optional home link.
  1266  * Displays or retrieves a list of pages with an optional home link.
  1155  *
  1267  *
  1156  * The arguments are listed below and part of the arguments are for {@link
  1268  * The arguments are listed below and part of the arguments are for wp_list_pages()} function.
  1157  * wp_list_pages()} function. Check that function for more info on those
  1269  * Check that function for more info on those arguments.
  1158  * arguments.
       
  1159  *
  1270  *
  1160  * @since 2.7.0
  1271  * @since 2.7.0
       
  1272  * @since 4.4.0 Added `menu_id`, `container`, `before`, `after`, and `walker` arguments.
       
  1273  * @since 4.7.0 Added the `item_spacing` argument.
  1161  *
  1274  *
  1162  * @param array|string $args {
  1275  * @param array|string $args {
  1163  *     Optional. Arguments to generate a page menu. See wp_list_pages() for additional arguments.
  1276  *     Optional. Arguments to generate a page menu. See wp_list_pages() for additional arguments.
  1164  *
  1277  *
  1165  *     @type string          $sort_column How to short the list of pages. Accepts post column names.
  1278  *     @type string          $sort_column  How to sort the list of pages. Accepts post column names.
  1166  *                                        Default 'menu_order, post_title'.
  1279  *                                         Default 'menu_order, post_title'.
  1167  *     @type string          $menu_class  Class to use for the div ID containing the page list. Default 'menu'.
  1280  *     @type string          $menu_id      ID for the div containing the page list. Default is empty string.
  1168  *     @type bool            $echo        Whether to echo the list or return it. Accepts true (echo) or false (return).
  1281  *     @type string          $menu_class   Class to use for the element containing the page list. Default 'menu'.
  1169  *                                        Default true.
  1282  *     @type string          $container    Element to use for the element containing the page list. Default 'div'.
  1170  *     @type string          $link_before The HTML or text to prepend to $show_home text. Default empty.
  1283  *     @type bool            $echo         Whether to echo the list or return it. Accepts true (echo) or false (return).
  1171  *     @type string          $link_after  The HTML or text to append to $show_home text. Default empty.
  1284  *                                         Default true.
  1172  *     @type int|bool|string $show_home   Whether to display the link to the home page. Can just enter the text
  1285  *     @type int|bool|string $show_home    Whether to display the link to the home page. Can just enter the text
  1173  *                                        you'd like shown for the home link. 1|true defaults to 'Home'.
  1286  *                                         you'd like shown for the home link. 1|true defaults to 'Home'.
       
  1287  *     @type string          $link_before  The HTML or text to prepend to $show_home text. Default empty.
       
  1288  *     @type string          $link_after   The HTML or text to append to $show_home text. Default empty.
       
  1289  *     @type string          $before       The HTML or text to prepend to the menu. Default is '<ul>'.
       
  1290  *     @type string          $after        The HTML or text to append to the menu. Default is '</ul>'.
       
  1291  *     @type string          $item_spacing Whether to preserve whitespace within the menu's HTML. Accepts 'preserve' or 'discard'. Default 'discard'.
       
  1292  *     @type Walker          $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
  1174  * }
  1293  * }
  1175  * @return string html menu
  1294  * @return string|void HTML menu
  1176  */
  1295  */
  1177 function wp_page_menu( $args = array() ) {
  1296 function wp_page_menu( $args = array() ) {
  1178 	$defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
  1297 	$defaults = array(
       
  1298 		'sort_column'  => 'menu_order, post_title',
       
  1299 		'menu_id'      => '',
       
  1300 		'menu_class'   => 'menu',
       
  1301 		'container'    => 'div',
       
  1302 		'echo'         => true,
       
  1303 		'link_before'  => '',
       
  1304 		'link_after'   => '',
       
  1305 		'before'       => '<ul>',
       
  1306 		'after'        => '</ul>',
       
  1307 		'item_spacing' => 'discard',
       
  1308 		'walker'       => '',
       
  1309 	);
  1179 	$args = wp_parse_args( $args, $defaults );
  1310 	$args = wp_parse_args( $args, $defaults );
  1180 
  1311 
  1181 	/**
  1312 	if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ) ) ) {
  1182 	 * Filter the arguments used to generate a page-based menu.
  1313 		// invalid value, fall back to default.
       
  1314 		$args['item_spacing'] = $defaults['item_spacing'];
       
  1315 	}
       
  1316 
       
  1317 	if ( 'preserve' === $args['item_spacing'] ) {
       
  1318 		$t = "\t";
       
  1319 		$n = "\n";
       
  1320 	} else {
       
  1321 		$t = '';
       
  1322 		$n = '';
       
  1323 	}
       
  1324 
       
  1325 	/**
       
  1326 	 * Filters the arguments used to generate a page-based menu.
  1183 	 *
  1327 	 *
  1184 	 * @since 2.7.0
  1328 	 * @since 2.7.0
  1185 	 *
  1329 	 *
  1186 	 * @see wp_page_menu()
  1330 	 * @see wp_page_menu()
  1187 	 *
  1331 	 *
  1214 		}
  1358 		}
  1215 	}
  1359 	}
  1216 
  1360 
  1217 	$list_args['echo'] = false;
  1361 	$list_args['echo'] = false;
  1218 	$list_args['title_li'] = '';
  1362 	$list_args['title_li'] = '';
  1219 	$menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
  1363 	$menu .= wp_list_pages( $list_args );
  1220 
  1364 
  1221 	if ( $menu )
  1365 	$container = sanitize_text_field( $args['container'] );
  1222 		$menu = '<ul>' . $menu . '</ul>';
  1366 
  1223 
  1367 	// Fallback in case `wp_nav_menu()` was called without a container.
  1224 	$menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
  1368 	if ( empty( $container ) ) {
  1225 
  1369 		$container = 'div';
  1226 	/**
  1370 	}
  1227 	 * Filter the HTML output of a page-based menu.
  1371 
       
  1372 	if ( $menu ) {
       
  1373 
       
  1374 		// wp_nav_menu doesn't set before and after
       
  1375 		if ( isset( $args['fallback_cb'] ) &&
       
  1376 			'wp_page_menu' === $args['fallback_cb'] &&
       
  1377 			'ul' !== $container ) {
       
  1378 			$args['before'] = "<ul>{$n}";
       
  1379 			$args['after'] = '</ul>';
       
  1380 		}
       
  1381 
       
  1382 		$menu = $args['before'] . $menu . $args['after'];
       
  1383 	}
       
  1384 
       
  1385 	$attrs = '';
       
  1386 	if ( ! empty( $args['menu_id'] ) ) {
       
  1387 		$attrs .= ' id="' . esc_attr( $args['menu_id'] ) . '"';
       
  1388 	}
       
  1389 
       
  1390 	if ( ! empty( $args['menu_class'] ) ) {
       
  1391 		$attrs .= ' class="' . esc_attr( $args['menu_class'] ) . '"';
       
  1392 	}
       
  1393 
       
  1394 	$menu = "<{$container}{$attrs}>" . $menu . "</{$container}>{$n}";
       
  1395 
       
  1396 	/**
       
  1397 	 * Filters the HTML output of a page-based menu.
  1228 	 *
  1398 	 *
  1229 	 * @since 2.7.0
  1399 	 * @since 2.7.0
  1230 	 *
  1400 	 *
  1231 	 * @see wp_page_menu()
  1401 	 * @see wp_page_menu()
  1232 	 *
  1402 	 *
  1247 /**
  1417 /**
  1248  * Retrieve HTML list content for page list.
  1418  * Retrieve HTML list content for page list.
  1249  *
  1419  *
  1250  * @uses Walker_Page to create HTML list content.
  1420  * @uses Walker_Page to create HTML list content.
  1251  * @since 2.1.0
  1421  * @since 2.1.0
  1252  * @see Walker_Page::walk() for parameters and return description.
  1422  *
  1253  */
  1423  * @param array $pages
  1254 function walk_page_tree($pages, $depth, $current_page, $r) {
  1424  * @param int   $depth
       
  1425  * @param int   $current_page
       
  1426  * @param array $r
       
  1427  * @return string
       
  1428  */
       
  1429 function walk_page_tree( $pages, $depth, $current_page, $r ) {
  1255 	if ( empty($r['walker']) )
  1430 	if ( empty($r['walker']) )
  1256 		$walker = new Walker_Page;
  1431 		$walker = new Walker_Page;
  1257 	else
  1432 	else
  1258 		$walker = $r['walker'];
  1433 		$walker = $r['walker'];
  1259 
  1434 
  1270  * Retrieve HTML dropdown (select) content for page list.
  1445  * Retrieve HTML dropdown (select) content for page list.
  1271  *
  1446  *
  1272  * @uses Walker_PageDropdown to create HTML dropdown content.
  1447  * @uses Walker_PageDropdown to create HTML dropdown content.
  1273  * @since 2.1.0
  1448  * @since 2.1.0
  1274  * @see Walker_PageDropdown::walk() for parameters and return description.
  1449  * @see Walker_PageDropdown::walk() for parameters and return description.
       
  1450  *
       
  1451  * @return string
  1275  */
  1452  */
  1276 function walk_page_dropdown_tree() {
  1453 function walk_page_dropdown_tree() {
  1277 	$args = func_get_args();
  1454 	$args = func_get_args();
  1278 	if ( empty($args[2]['walker']) ) // the user's options are the third parameter
  1455 	if ( empty($args[2]['walker']) ) // the user's options are the third parameter
  1279 		$walker = new Walker_PageDropdown;
  1456 		$walker = new Walker_PageDropdown;
  1281 		$walker = $args[2]['walker'];
  1458 		$walker = $args[2]['walker'];
  1282 
  1459 
  1283 	return call_user_func_array(array($walker, 'walk'), $args);
  1460 	return call_user_func_array(array($walker, 'walk'), $args);
  1284 }
  1461 }
  1285 
  1462 
  1286 /**
       
  1287  * Create HTML list of pages.
       
  1288  *
       
  1289  * @since 2.1.0
       
  1290  * @uses Walker
       
  1291  */
       
  1292 class Walker_Page extends Walker {
       
  1293 	/**
       
  1294 	 * @see Walker::$tree_type
       
  1295 	 * @since 2.1.0
       
  1296 	 * @var string
       
  1297 	 */
       
  1298 	public $tree_type = 'page';
       
  1299 
       
  1300 	/**
       
  1301 	 * @see Walker::$db_fields
       
  1302 	 * @since 2.1.0
       
  1303 	 * @todo Decouple this.
       
  1304 	 * @var array
       
  1305 	 */
       
  1306 	public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
       
  1307 
       
  1308 	/**
       
  1309 	 * @see Walker::start_lvl()
       
  1310 	 * @since 2.1.0
       
  1311 	 *
       
  1312 	 * @param string $output Passed by reference. Used to append additional content.
       
  1313 	 * @param int $depth Depth of page. Used for padding.
       
  1314 	 * @param array $args
       
  1315 	 */
       
  1316 	public function start_lvl( &$output, $depth = 0, $args = array() ) {
       
  1317 		$indent = str_repeat("\t", $depth);
       
  1318 		$output .= "\n$indent<ul class='children'>\n";
       
  1319 	}
       
  1320 
       
  1321 	/**
       
  1322 	 * @see Walker::end_lvl()
       
  1323 	 * @since 2.1.0
       
  1324 	 *
       
  1325 	 * @param string $output Passed by reference. Used to append additional content.
       
  1326 	 * @param int $depth Depth of page. Used for padding.
       
  1327 	 * @param array $args
       
  1328 	 */
       
  1329 	public function end_lvl( &$output, $depth = 0, $args = array() ) {
       
  1330 		$indent = str_repeat("\t", $depth);
       
  1331 		$output .= "$indent</ul>\n";
       
  1332 	}
       
  1333 
       
  1334 	/**
       
  1335 	 * @see Walker::start_el()
       
  1336 	 * @since 2.1.0
       
  1337 	 *
       
  1338 	 * @param string $output Passed by reference. Used to append additional content.
       
  1339 	 * @param object $page Page data object.
       
  1340 	 * @param int $depth Depth of page. Used for padding.
       
  1341 	 * @param int $current_page Page ID.
       
  1342 	 * @param array $args
       
  1343 	 */
       
  1344 	public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
       
  1345 		if ( $depth ) {
       
  1346 			$indent = str_repeat( "\t", $depth );
       
  1347 		} else {
       
  1348 			$indent = '';
       
  1349 		}
       
  1350 
       
  1351 		$css_class = array( 'page_item', 'page-item-' . $page->ID );
       
  1352 
       
  1353 		if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
       
  1354 			$css_class[] = 'page_item_has_children';
       
  1355 		}
       
  1356 
       
  1357 		if ( ! empty( $current_page ) ) {
       
  1358 			$_current_page = get_post( $current_page );
       
  1359 			if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
       
  1360 				$css_class[] = 'current_page_ancestor';
       
  1361 			}
       
  1362 			if ( $page->ID == $current_page ) {
       
  1363 				$css_class[] = 'current_page_item';
       
  1364 			} elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
       
  1365 				$css_class[] = 'current_page_parent';
       
  1366 			}
       
  1367 		} elseif ( $page->ID == get_option('page_for_posts') ) {
       
  1368 			$css_class[] = 'current_page_parent';
       
  1369 		}
       
  1370 
       
  1371 		/**
       
  1372 		 * Filter the list of CSS classes to include with each page item in the list.
       
  1373 		 *
       
  1374 		 * @since 2.8.0
       
  1375 		 *
       
  1376 		 * @see wp_list_pages()
       
  1377 		 *
       
  1378 		 * @param array   $css_class    An array of CSS classes to be applied
       
  1379 		 *                             to each list item.
       
  1380 		 * @param WP_Post $page         Page data object.
       
  1381 		 * @param int     $depth        Depth of page, used for padding.
       
  1382 		 * @param array   $args         An array of arguments.
       
  1383 		 * @param int     $current_page ID of the current page.
       
  1384 		 */
       
  1385 		$css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
       
  1386 
       
  1387 		if ( '' === $page->post_title ) {
       
  1388 			$page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
       
  1389 		}
       
  1390 
       
  1391 		$args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
       
  1392 		$args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];
       
  1393 
       
  1394 		/** This filter is documented in wp-includes/post-template.php */
       
  1395 		$output .= $indent . sprintf(
       
  1396 			'<li class="%s"><a href="%s">%s%s%s</a>',
       
  1397 			$css_classes,
       
  1398 			get_permalink( $page->ID ),
       
  1399 			$args['link_before'],
       
  1400 			apply_filters( 'the_title', $page->post_title, $page->ID ),
       
  1401 			$args['link_after']
       
  1402 		);
       
  1403 
       
  1404 		if ( ! empty( $args['show_date'] ) ) {
       
  1405 			if ( 'modified' == $args['show_date'] ) {
       
  1406 				$time = $page->post_modified;
       
  1407 			} else {
       
  1408 				$time = $page->post_date;
       
  1409 			}
       
  1410 
       
  1411 			$date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
       
  1412 			$output .= " " . mysql2date( $date_format, $time );
       
  1413 		}
       
  1414 	}
       
  1415 
       
  1416 	/**
       
  1417 	 * @see Walker::end_el()
       
  1418 	 * @since 2.1.0
       
  1419 	 *
       
  1420 	 * @param string $output Passed by reference. Used to append additional content.
       
  1421 	 * @param object $page Page data object. Not used.
       
  1422 	 * @param int $depth Depth of page. Not Used.
       
  1423 	 * @param array $args
       
  1424 	 */
       
  1425 	public function end_el( &$output, $page, $depth = 0, $args = array() ) {
       
  1426 		$output .= "</li>\n";
       
  1427 	}
       
  1428 
       
  1429 }
       
  1430 
       
  1431 /**
       
  1432  * Create HTML dropdown list of pages.
       
  1433  *
       
  1434  * @since 2.1.0
       
  1435  * @uses Walker
       
  1436  */
       
  1437 class Walker_PageDropdown extends Walker {
       
  1438 	/**
       
  1439 	 * @see Walker::$tree_type
       
  1440 	 * @since 2.1.0
       
  1441 	 * @var string
       
  1442 	 */
       
  1443 	public $tree_type = 'page';
       
  1444 
       
  1445 	/**
       
  1446 	 * @see Walker::$db_fields
       
  1447 	 * @since 2.1.0
       
  1448 	 * @todo Decouple this
       
  1449 	 * @var array
       
  1450 	 */
       
  1451 	public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
       
  1452 
       
  1453 	/**
       
  1454 	 * @see Walker::start_el()
       
  1455 	 * @since 2.1.0
       
  1456 	 *
       
  1457 	 * @param string $output Passed by reference. Used to append additional content.
       
  1458 	 * @param object $page   Page data object.
       
  1459 	 * @param int    $depth  Depth of page in reference to parent pages. Used for padding.
       
  1460 	 * @param array  $args   Uses 'selected' argument for selected page to set selected HTML attribute for option
       
  1461 	 *              element. Uses 'value_field' argument to fill "value" attribute. See {@see wp_dropdown_pages()}.
       
  1462 	 * @param int $id
       
  1463 	 */
       
  1464 	public function start_el( &$output, $page, $depth = 0, $args = array(), $id = 0 ) {
       
  1465 		$pad = str_repeat('&nbsp;', $depth * 3);
       
  1466 
       
  1467 		if ( ! isset( $args['value_field'] ) || ! isset( $page->{$args['value_field']} ) ) {
       
  1468 			$args['value_field'] = 'ID';
       
  1469 		}
       
  1470 
       
  1471 		$output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $page->{$args['value_field']} ) . "\"";
       
  1472 		if ( $page->ID == $args['selected'] )
       
  1473 			$output .= ' selected="selected"';
       
  1474 		$output .= '>';
       
  1475 
       
  1476 		$title = $page->post_title;
       
  1477 		if ( '' === $title ) {
       
  1478 			$title = sprintf( __( '#%d (no title)' ), $page->ID );
       
  1479 		}
       
  1480 
       
  1481 		/**
       
  1482 		 * Filter the page title when creating an HTML drop-down list of pages.
       
  1483 		 *
       
  1484 		 * @since 3.1.0
       
  1485 		 *
       
  1486 		 * @param string $title Page title.
       
  1487 		 * @param object $page  Page data object.
       
  1488 		 */
       
  1489 		$title = apply_filters( 'list_pages', $title, $page );
       
  1490 		$output .= $pad . esc_html( $title );
       
  1491 		$output .= "</option>\n";
       
  1492 	}
       
  1493 }
       
  1494 
       
  1495 //
  1463 //
  1496 // Attachments
  1464 // Attachments
  1497 //
  1465 //
  1498 
  1466 
  1499 /**
  1467 /**
  1506  * @param bool        $deprecated   Deprecated. Not used.
  1474  * @param bool        $deprecated   Deprecated. Not used.
  1507  * @param bool        $permalink    Optional, default is false. Whether to include permalink.
  1475  * @param bool        $permalink    Optional, default is false. Whether to include permalink.
  1508  */
  1476  */
  1509 function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
  1477 function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
  1510 	if ( !empty( $deprecated ) )
  1478 	if ( !empty( $deprecated ) )
  1511 		_deprecated_argument( __FUNCTION__, '2.5' );
  1479 		_deprecated_argument( __FUNCTION__, '2.5.0' );
  1512 
  1480 
  1513 	if ( $fullsize )
  1481 	if ( $fullsize )
  1514 		echo wp_get_attachment_link($id, 'full', $permalink);
  1482 		echo wp_get_attachment_link($id, 'full', $permalink);
  1515 	else
  1483 	else
  1516 		echo wp_get_attachment_link($id, 'thumbnail', $permalink);
  1484 		echo wp_get_attachment_link($id, 'thumbnail', $permalink);
  1518 
  1486 
  1519 /**
  1487 /**
  1520  * Retrieve an attachment page link using an image or icon, if possible.
  1488  * Retrieve an attachment page link using an image or icon, if possible.
  1521  *
  1489  *
  1522  * @since 2.5.0
  1490  * @since 2.5.0
       
  1491  * @since 4.4.0 The `$id` parameter can now accept either a post ID or `WP_Post` object.
  1523  *
  1492  *
  1524  * @param int|WP_Post  $id        Optional. Post ID or post object.
  1493  * @param int|WP_Post  $id        Optional. Post ID or post object.
  1525  * @param string       $size      Optional, default is 'thumbnail'. Size of image, either array or string.
  1494  * @param string|array $size      Optional. Image size. Accepts any valid image size, or an array
  1526  * @param bool         $permalink Optional, default is false. Whether to add permalink to image.
  1495  *                                of width and height values in pixels (in that order).
  1527  * @param bool         $icon      Optional, default is false. Whether to include icon.
  1496  *                                Default 'thumbnail'.
  1528  * @param string|bool  $text      Optional, default is false. If string, then will be link text.
  1497  * @param bool         $permalink Optional, Whether to add permalink to image. Default false.
  1529  * @param array|string $attr      Optional. Array or string of attributes.
  1498  * @param bool         $icon      Optional. Whether the attachment is an icon. Default false.
       
  1499  * @param string|false $text      Optional. Link text to use. Activated by passing a string, false otherwise.
       
  1500  *                                Default false.
       
  1501  * @param array|string $attr      Optional. Array or string of attributes. Default empty.
  1530  * @return string HTML content.
  1502  * @return string HTML content.
  1531  */
  1503  */
  1532 function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) {
  1504 function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) {
  1533 	$id = intval( $id );
       
  1534 	$_post = get_post( $id );
  1505 	$_post = get_post( $id );
  1535 
  1506 
  1536 	if ( empty( $_post ) || ( 'attachment' != $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) )
  1507 	if ( empty( $_post ) || ( 'attachment' !== $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) ) {
  1537 		return __( 'Missing Attachment' );
  1508 		return __( 'Missing Attachment' );
  1538 
  1509 	}
  1539 	if ( $permalink )
  1510 
       
  1511 	if ( $permalink ) {
  1540 		$url = get_attachment_link( $_post->ID );
  1512 		$url = get_attachment_link( $_post->ID );
       
  1513 	}
  1541 
  1514 
  1542 	if ( $text ) {
  1515 	if ( $text ) {
  1543 		$link_text = $text;
  1516 		$link_text = $text;
  1544 	} elseif ( $size && 'none' != $size ) {
  1517 	} elseif ( $size && 'none' != $size ) {
  1545 		$link_text = wp_get_attachment_image( $id, $size, $icon, $attr );
  1518 		$link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr );
  1546 	} else {
  1519 	} else {
  1547 		$link_text = '';
  1520 		$link_text = '';
  1548 	}
  1521 	}
  1549 
  1522 
  1550 	if ( trim( $link_text ) == '' )
  1523 	if ( '' === trim( $link_text ) ) {
  1551 		$link_text = $_post->post_title;
  1524 		$link_text = $_post->post_title;
  1552 
  1525 	}
  1553 	/**
  1526 
  1554 	 * Filter a retrieved attachment page link.
  1527 	if ( '' === trim( $link_text ) ) {
       
  1528 		$link_text = esc_html( pathinfo( get_attached_file( $_post->ID ), PATHINFO_FILENAME ) );
       
  1529 	}
       
  1530 	/**
       
  1531 	 * Filters a retrieved attachment page link.
  1555 	 *
  1532 	 *
  1556 	 * @since 2.7.0
  1533 	 * @since 2.7.0
  1557 	 *
  1534 	 *
  1558 	 * @param string      $link_html The page link HTML output.
  1535 	 * @param string       $link_html The page link HTML output.
  1559 	 * @param int         $id        Post ID.
  1536 	 * @param int          $id        Post ID.
  1560 	 * @param string      $size      Image size. Default 'thumbnail'.
  1537 	 * @param string|array $size      Size of the image. Image size or array of width and height values (in that order).
  1561 	 * @param bool        $permalink Whether to add permalink to image. Default false.
  1538 	 *                                Default 'thumbnail'.
  1562 	 * @param bool        $icon      Whether to include an icon. Default false.
  1539 	 * @param bool         $permalink Whether to add permalink to image. Default false.
  1563 	 * @param string|bool $text      If string, will be link text. Default false.
  1540 	 * @param bool         $icon      Whether to include an icon. Default false.
       
  1541 	 * @param string|bool  $text      If string, will be link text. Default false.
  1564 	 */
  1542 	 */
  1565 	return apply_filters( 'wp_get_attachment_link', "<a href='$url'>$link_text</a>", $id, $size, $permalink, $icon, $text );
  1543 	return apply_filters( 'wp_get_attachment_link', "<a href='" . esc_url( $url ) . "'>$link_text</a>", $id, $size, $permalink, $icon, $text );
  1566 }
  1544 }
  1567 
  1545 
  1568 /**
  1546 /**
  1569  * Wrap attachment in paragraph tag before content.
  1547  * Wrap attachment in paragraph tag before content.
  1570  *
  1548  *
  1598 		$p .= wp_get_attachment_link(0, 'medium', false);
  1576 		$p .= wp_get_attachment_link(0, 'medium', false);
  1599 		$p .= '</p>';
  1577 		$p .= '</p>';
  1600 	}
  1578 	}
  1601 
  1579 
  1602 	/**
  1580 	/**
  1603 	 * Filter the attachment markup to be prepended to the post content.
  1581 	 * Filters the attachment markup to be prepended to the post content.
  1604 	 *
  1582 	 *
  1605 	 * @since 2.0.0
  1583 	 * @since 2.0.0
  1606 	 *
  1584 	 *
  1607 	 * @see prepend_attachment()
  1585 	 * @see prepend_attachment()
  1608 	 *
  1586 	 *
  1628 function get_the_password_form( $post = 0 ) {
  1606 function get_the_password_form( $post = 0 ) {
  1629 	$post = get_post( $post );
  1607 	$post = get_post( $post );
  1630 	$label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
  1608 	$label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
  1631 	$output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
  1609 	$output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
  1632 	<p>' . __( 'This content is password protected. To view it please enter your password below:' ) . '</p>
  1610 	<p>' . __( 'This content is password protected. To view it please enter your password below:' ) . '</p>
  1633 	<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></form>
  1611 	<p><label for="' . $label . '">' . __( 'Password:' ) . ' <input name="post_password" id="' . $label . '" type="password" size="20" /></label> <input type="submit" name="Submit" value="' . esc_attr_x( 'Enter', 'post password form' ) . '" /></p></form>
  1634 	';
  1612 	';
  1635 
  1613 
  1636 	/**
  1614 	/**
  1637 	 * Filter the HTML output for the protected post password form.
  1615 	 * Filters the HTML output for the protected post password form.
  1638 	 *
  1616 	 *
  1639 	 * If modifying the password field, please note that the core database schema
  1617 	 * If modifying the password field, please note that the core database schema
  1640 	 * limits the password field to 20 characters regardless of the value of the
  1618 	 * limits the password field to 20 characters regardless of the value of the
  1641 	 * size attribute in the form input.
  1619 	 * size attribute in the form input.
  1642 	 *
  1620 	 *
  1654  * You can optionally provide a template name or array of template names
  1632  * You can optionally provide a template name or array of template names
  1655  * and then the check will be specific to that template.
  1633  * and then the check will be specific to that template.
  1656  *
  1634  *
  1657  * @since 2.5.0
  1635  * @since 2.5.0
  1658  * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates.
  1636  * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates.
       
  1637  * @since 4.7.0 Now works with any post type, not just pages.
  1659  *
  1638  *
  1660  * @param string|array $template The specific template name or array of templates to match.
  1639  * @param string|array $template The specific template name or array of templates to match.
  1661  * @return bool True on success, false on failure.
  1640  * @return bool True on success, false on failure.
  1662  */
  1641  */
  1663 function is_page_template( $template = '' ) {
  1642 function is_page_template( $template = '' ) {
  1664 	if ( ! is_page() )
  1643 	if ( ! is_singular() ) {
  1665 		return false;
  1644 		return false;
       
  1645 	}
  1666 
  1646 
  1667 	$page_template = get_page_template_slug( get_queried_object_id() );
  1647 	$page_template = get_page_template_slug( get_queried_object_id() );
  1668 
  1648 
  1669 	if ( empty( $template ) )
  1649 	if ( empty( $template ) )
  1670 		return (bool) $page_template;
  1650 		return (bool) $page_template;
  1678 		) {
  1658 		) {
  1679 			return true;
  1659 			return true;
  1680 		}
  1660 		}
  1681 	}
  1661 	}
  1682 
  1662 
  1683 	if ( 'default' == $template && ! $page_template )
  1663 	return ( 'default' === $template && ! $page_template );
  1684 		return true;
  1664 }
  1685 
  1665 
  1686 	return false;
  1666 /**
  1687 }
  1667  * Get the specific template name for a given post.
  1688 
       
  1689 /**
       
  1690  * Get the specific template name for a page.
       
  1691  *
  1668  *
  1692  * @since 3.4.0
  1669  * @since 3.4.0
  1693  *
  1670  * @since 4.7.0 Now works with any post type, not just pages.
  1694  * @param int $post_id Optional. The page ID to check. Defaults to the current post, when used in the loop.
  1671  *
  1695  * @return string|bool Page template filename. Returns an empty string when the default page template
  1672  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
  1696  * 	is in use. Returns false if the post is not a page.
  1673  * @return string|false Page template filename. Returns an empty string when the default page template
  1697  */
  1674  * 	is in use. Returns false if the post does not exist.
  1698 function get_page_template_slug( $post_id = null ) {
  1675  */
  1699 	$post = get_post( $post_id );
  1676 function get_page_template_slug( $post = null ) {
  1700 	if ( ! $post || 'page' != $post->post_type )
  1677 	$post = get_post( $post );
       
  1678 
       
  1679 	if ( ! $post ) {
  1701 		return false;
  1680 		return false;
       
  1681 	}
       
  1682 
  1702 	$template = get_post_meta( $post->ID, '_wp_page_template', true );
  1683 	$template = get_post_meta( $post->ID, '_wp_page_template', true );
  1703 	if ( ! $template || 'default' == $template )
  1684 
       
  1685 	if ( ! $template || 'default' == $template ) {
  1704 		return '';
  1686 		return '';
       
  1687 	}
       
  1688 
  1705 	return $template;
  1689 	return $template;
  1706 }
  1690 }
  1707 
  1691 
  1708 /**
  1692 /**
  1709  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  1693  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  1710  *
  1694  *
  1711  * @since 2.6.0
  1695  * @since 2.6.0
  1712  *
  1696  *
  1713  * @param int|object $revision Revision ID or revision object.
  1697  * @param int|object $revision Revision ID or revision object.
  1714  * @param bool $link Optional, default is true. Link to revisions's page?
  1698  * @param bool       $link     Optional, default is true. Link to revisions's page?
  1715  * @return string i18n formatted datetimestamp or localized 'Current Revision'.
  1699  * @return string|false i18n formatted datetimestamp or localized 'Current Revision'.
  1716  */
  1700  */
  1717 function wp_post_revision_title( $revision, $link = true ) {
  1701 function wp_post_revision_title( $revision, $link = true ) {
  1718 	if ( !$revision = get_post( $revision ) )
  1702 	if ( !$revision = get_post( $revision ) )
  1719 		return $revision;
  1703 		return $revision;
  1720 
  1704 
  1721 	if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  1705 	if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  1722 		return false;
  1706 		return false;
  1723 
  1707 
  1724 	/* translators: revision date format, see http://php.net/date */
  1708 	/* translators: revision date format, see https://secure.php.net/date */
  1725 	$datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
  1709 	$datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
  1726 	/* translators: 1: date */
  1710 	/* translators: %s: revision date */
  1727 	$autosavef = _x( '%1$s [Autosave]', 'post revision title extra' );
  1711 	$autosavef = __( '%s [Autosave]' );
  1728 	/* translators: 1: date */
  1712 	/* translators: %s: revision date */
  1729 	$currentf  = _x( '%1$s [Current Revision]', 'post revision title extra' );
  1713 	$currentf  = __( '%s [Current Revision]' );
  1730 
  1714 
  1731 	$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  1715 	$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  1732 	if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  1716 	if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  1733 		$date = "<a href='$link'>$date</a>";
  1717 		$date = "<a href='$link'>$date</a>";
  1734 
  1718 
  1744  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  1728  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
  1745  *
  1729  *
  1746  * @since 3.6.0
  1730  * @since 3.6.0
  1747  *
  1731  *
  1748  * @param int|object $revision Revision ID or revision object.
  1732  * @param int|object $revision Revision ID or revision object.
  1749  * @param bool $link Optional, default is true. Link to revisions's page?
  1733  * @param bool       $link     Optional, default is true. Link to revisions's page?
  1750  * @return string gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'.
  1734  * @return string|false gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'.
  1751  */
  1735  */
  1752 function wp_post_revision_title_expanded( $revision, $link = true ) {
  1736 function wp_post_revision_title_expanded( $revision, $link = true ) {
  1753 	if ( !$revision = get_post( $revision ) )
  1737 	if ( !$revision = get_post( $revision ) )
  1754 		return $revision;
  1738 		return $revision;
  1755 
  1739 
  1756 	if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  1740 	if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
  1757 		return false;
  1741 		return false;
  1758 
  1742 
  1759 	$author = get_the_author_meta( 'display_name', $revision->post_author );
  1743 	$author = get_the_author_meta( 'display_name', $revision->post_author );
  1760 	/* translators: revision date format, see http://php.net/date */
  1744 	/* translators: revision date format, see https://secure.php.net/date */
  1761 	$datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
  1745 	$datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
  1762 
  1746 
  1763 	$gravatar = get_avatar( $revision->post_author, 24 );
  1747 	$gravatar = get_avatar( $revision->post_author, 24 );
  1764 
  1748 
  1765 	$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  1749 	$date = date_i18n( $datef, strtotime( $revision->post_modified ) );
  1766 	if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  1750 	if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
  1767 		$date = "<a href='$link'>$date</a>";
  1751 		$date = "<a href='$link'>$date</a>";
  1768 
  1752 
  1769 	$revision_date_author = sprintf(
  1753 	$revision_date_author = sprintf(
  1770 		/* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
  1754 		/* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
  1771 		_x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
  1755 		__( '%1$s %2$s, %3$s ago (%4$s)' ),
  1772 		$gravatar,
  1756 		$gravatar,
  1773 		$author,
  1757 		$author,
  1774 		human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
  1758 		human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
  1775 		$date
  1759 		$date
  1776 	);
  1760 	);
  1777 
  1761 
  1778 	$autosavef = __( '%1$s [Autosave]' );
  1762 	/* translators: %s: revision date with author avatar */
  1779 	$currentf  = __( '%1$s [Current Revision]' );
  1763 	$autosavef = __( '%s [Autosave]' );
       
  1764 	/* translators: %s: revision date with author avatar */
       
  1765 	$currentf  = __( '%s [Current Revision]' );
  1780 
  1766 
  1781 	if ( !wp_is_post_revision( $revision ) )
  1767 	if ( !wp_is_post_revision( $revision ) )
  1782 		$revision_date_author = sprintf( $currentf, $revision_date_author );
  1768 		$revision_date_author = sprintf( $currentf, $revision_date_author );
  1783 	elseif ( wp_is_post_autosave( $revision ) )
  1769 	elseif ( wp_is_post_autosave( $revision ) )
  1784 		$revision_date_author = sprintf( $autosavef, $revision_date_author );
  1770 		$revision_date_author = sprintf( $autosavef, $revision_date_author );
  1785 
  1771 
  1786 	return $revision_date_author;
  1772 	/**
       
  1773 	 * Filters the formatted author and date for a revision.
       
  1774 	 *
       
  1775 	 * @since 4.4.0
       
  1776 	 *
       
  1777 	 * @param string  $revision_date_author The formatted string.
       
  1778 	 * @param WP_Post $revision             The revision object.
       
  1779 	 * @param bool    $link                 Whether to link to the revisions page, as passed into
       
  1780 	 *                                      wp_post_revision_title_expanded().
       
  1781 	 */
       
  1782 	return apply_filters( 'wp_post_revision_title_expanded', $revision_date_author, $revision, $link );
  1787 }
  1783 }
  1788 
  1784 
  1789 /**
  1785 /**
  1790  * Display list of a post's revisions.
  1786  * Display list of a post's revisions.
  1791  *
  1787  *
  1794  *
  1790  *
  1795  * @since 2.6.0
  1791  * @since 2.6.0
  1796  *
  1792  *
  1797  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
  1793  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
  1798  * @param string      $type    'all' (default), 'revision' or 'autosave'
  1794  * @param string      $type    'all' (default), 'revision' or 'autosave'
  1799  * @return null
       
  1800  */
  1795  */
  1801 function wp_list_post_revisions( $post_id = 0, $type = 'all' ) {
  1796 function wp_list_post_revisions( $post_id = 0, $type = 'all' ) {
  1802 	if ( ! $post = get_post( $post_id ) )
  1797 	if ( ! $post = get_post( $post_id ) )
  1803 		return;
  1798 		return;
  1804 
  1799 
  1805 	// $args array with (parent, format, right, left, type) deprecated since 3.6
  1800 	// $args array with (parent, format, right, left, type) deprecated since 3.6
  1806 	if ( is_array( $type ) ) {
  1801 	if ( is_array( $type ) ) {
  1807 		$type = ! empty( $type['type'] ) ? $type['type']  : $type;
  1802 		$type = ! empty( $type['type'] ) ? $type['type']  : $type;
  1808 		_deprecated_argument( __FUNCTION__, '3.6' );
  1803 		_deprecated_argument( __FUNCTION__, '3.6.0' );
  1809 	}
  1804 	}
  1810 
  1805 
  1811 	if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
  1806 	if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
  1812 		return;
  1807 		return;
  1813 
  1808