WordPress.org

Make WordPress Core

Changeset 34109


Ignore:
Timestamp:
09/14/2015 02:58:40 AM (6 years ago)
Author:
wonderboymusic
Message:

Move Walker_Page and Walker_PageDropdown into their own files via svn cp. Remove them from post-template.php. Load them in post.php.

post-template.php loads after post.php in wp-settings.php. It could probably also be loaded in post.php, but avoiding that for the moment.

See #33413.

Location:
trunk/src/wp-includes
Files:
2 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-walker-page-dropdown.php

    r34108 r34109  
    11<?php
    22/**
    3  * WordPress Post Template Functions.
    4  *
    5  * Gets content for the current post in the loop.
     3 * Post API: Walker_PageDropdown class
    64 *
    75 * @package WordPress
    86 * @subpackage Template
     7 * @since 4.4.0
    98 */
    10 
    11 /**
    12  * Display the ID of the current item in the WordPress Loop.
    13  *
    14  * @since 0.71
    15  */
    16 function the_ID() {
    17     echo get_the_ID();
    18 }
    19 
    20 /**
    21  * Retrieve the ID of the current item in the WordPress Loop.
    22  *
    23  * @since 2.1.0
    24  *
    25  * @return int|false The ID of the current item in the WordPress Loop. False if $post is not set.
    26  */
    27 function get_the_ID() {
    28     $post = get_post();
    29     return ! empty( $post ) ? $post->ID : false;
    30 }
    31 
    32 /**
    33  * Display or retrieve the current post title with optional content.
    34  *
    35  * @since 0.71
    36  *
    37  * @param string $before Optional. Content to prepend to the title.
    38  * @param string $after  Optional. Content to append to the title.
    39  * @param bool   $echo   Optional, default to true.Whether to display or return.
    40  * @return string|void String if $echo parameter is false.
    41  */
    42 function the_title( $before = '', $after = '', $echo = true ) {
    43     $title = get_the_title();
    44 
    45     if ( strlen($title) == 0 )
    46         return;
    47 
    48     $title = $before . $title . $after;
    49 
    50     if ( $echo )
    51         echo $title;
    52     else
    53         return $title;
    54 }
    55 
    56 /**
    57  * Sanitize the current title when retrieving or displaying.
    58  *
    59  * Works like {@link 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.
    61  *
    62  * The title before it is displayed will have the tags stripped and {@link
    63  * esc_attr()} before it is passed to the user or displayed. The default
    64  * as with {@link the_title()}, is to display the title.
    65  *
    66  * @since 2.3.0
    67  *
    68  * @param string|array $args {
    69  *     Title attribute arguments. Optional.
    70  *
    71  *     @type string  $before Markup to prepend 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.
    74  *     @type WP_Post $post   Current post object to retrieve the title for.
    75  * }
    76  * @return string|void String when echo is false.
    77  */
    78 function the_title_attribute( $args = '' ) {
    79     $defaults = array( 'before' => '', 'after' =>  '', 'echo' => true, 'post' => get_post() );
    80     $r = wp_parse_args( $args, $defaults );
    81 
    82     $title = get_the_title( $r['post'] );
    83 
    84     if ( strlen( $title ) == 0 ) {
    85         return;
    86     }
    87 
    88     $title = $r['before'] . $title . $r['after'];
    89     $title = esc_attr( strip_tags( $title ) );
    90 
    91     if ( $r['echo'] ) {
    92         echo $title;
    93     } else {
    94         return $title;
    95     }
    96 }
    97 
    98 /**
    99  * Retrieve post title.
    100  *
    101  * If the post is protected and the visitor is not an admin, then "Protected"
    102  * will be displayed before the post title. If the post is private, then
    103  * "Private" will be located before the post title.
    104  *
    105  * @since 0.71
    106  *
    107  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
    108  * @return string
    109  */
    110 function get_the_title( $post = 0 ) {
    111     $post = get_post( $post );
    112 
    113     $title = isset( $post->post_title ) ? $post->post_title : '';
    114     $id = isset( $post->ID ) ? $post->ID : 0;
    115 
    116     if ( ! is_admin() ) {
    117         if ( ! empty( $post->post_password ) ) {
    118 
    119             /**
    120              * Filter the text prepended to the post title for protected posts.
    121              *
    122              * The filter is only applied on the front end.
    123              *
    124              * @since 2.8.0
    125              *
    126              * @param string  $prepend Text displayed before the post title.
    127              *                         Default 'Protected: %s'.
    128              * @param WP_Post $post    Current post object.
    129              */
    130             $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
    131             $title = sprintf( $protected_title_format, $title );
    132         } elseif ( isset( $post->post_status ) && 'private' == $post->post_status ) {
    133 
    134             /**
    135              * Filter the text prepended to the post title of private posts.
    136              *
    137              * The filter is only applied on the front end.
    138              *
    139              * @since 2.8.0
    140              *
    141              * @param string  $prepend Text displayed before the post title.
    142              *                         Default 'Private: %s'.
    143              * @param WP_Post $post    Current post object.
    144              */
    145             $private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ), $post );
    146             $title = sprintf( $private_title_format, $title );
    147         }
    148     }
    149 
    150     /**
    151      * Filter the post title.
    152      *
    153      * @since 0.71
    154      *
    155      * @param string $title The post title.
    156      * @param int    $id    The post ID.
    157      */
    158     return apply_filters( 'the_title', $title, $id );
    159 }
    160 
    161 /**
    162  * Display the Post Global Unique Identifier (guid).
    163  *
    164  * 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
    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 $id Optional. Post ID or post object.
    173  */
    174 function the_guid( $id = 0 ) {
    175     /**
    176      * Filter the escaped Global Unique Identifier (guid) of the post.
    177      *
    178      * @since 4.2.0
    179      *
    180      * @see get_the_guid()
    181      *
    182      * @param string $post_guid Escaped Global Unique Identifier (guid) of the post.
    183      */
    184     echo apply_filters( 'the_guid', get_the_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 }
    211 
    212 /**
    213  * Display the post content.
    214  *
    215  * @since 0.71
    216  *
    217  * @param string $more_link_text Optional. Content for when there is more text.
    218  * @param bool   $strip_teaser   Optional. Strip teaser content before the more text. Default is false.
    219  */
    220 function the_content( $more_link_text = null, $strip_teaser = false) {
    221     $content = get_the_content( $more_link_text, $strip_teaser );
    222 
    223     /**
    224      * Filter the post content.
    225      *
    226      * @since 0.71
    227      *
    228      * @param string $content Content of the current post.
    229      */
    230     $content = apply_filters( 'the_content', $content );
    231     $content = str_replace( ']]>', ']]&gt;', $content );
    232     echo $content;
    233 }
    234 
    235 /**
    236  * Retrieve the post content.
    237  *
    238  * @since 0.71
    239  *
    240  * @global int   $page
    241  * @global int   $more
    242  * @global bool  $preview
    243  * @global array $pages
    244  * @global int   $multipage
    245  *
    246  * @param string $more_link_text Optional. Content for when there is more text.
    247  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
    248  * @return string
    249  */
    250 function get_the_content( $more_link_text = null, $strip_teaser = false ) {
    251     global $page, $more, $preview, $pages, $multipage;
    252 
    253     $post = get_post();
    254 
    255     if ( null === $more_link_text )
    256         $more_link_text = __( '(more&hellip;)' );
    257 
    258     $output = '';
    259     $has_teaser = false;
    260 
    261     // If post password required and it doesn't match the cookie.
    262     if ( post_password_required( $post ) )
    263         return get_the_password_form( $post );
    264 
    265     if ( $page > count( $pages ) ) // if the requested page doesn't exist
    266         $page = count( $pages ); // give them the highest numbered page that DOES exist
    267 
    268     $content = $pages[$page - 1];
    269     if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) {
    270         $content = explode( $matches[0], $content, 2 );
    271         if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) )
    272             $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );
    273 
    274         $has_teaser = true;
    275     } else {
    276         $content = array( $content );
    277     }
    278 
    279     if ( false !== strpos( $post->post_content, '<!--noteaser-->' ) && ( ! $multipage || $page == 1 ) )
    280         $strip_teaser = true;
    281 
    282     $teaser = $content[0];
    283 
    284     if ( $more && $strip_teaser && $has_teaser )
    285         $teaser = '';
    286 
    287     $output .= $teaser;
    288 
    289     if ( count( $content ) > 1 ) {
    290         if ( $more ) {
    291             $output .= '<span id="more-' . $post->ID . '"></span>' . $content[1];
    292         } else {
    293             if ( ! empty( $more_link_text ) )
    294 
    295                 /**
    296                  * Filter the Read More link text.
    297                  *
    298                  * @since 2.8.0
    299                  *
    300                  * @param string $more_link_element Read More link element.
    301                  * @param string $more_link_text    Read More text.
    302                  */
    303                 $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-{$post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text );
    304             $output = force_balance_tags( $output );
    305         }
    306     }
    307 
    308     if ( $preview ) // Preview fix for JavaScript bug with foreign languages.
    309         $output =   preg_replace_callback( '/\%u([0-9A-F]{4})/', '_convert_urlencoded_to_entities', $output );
    310 
    311     return $output;
    312 }
    313 
    314 /**
    315  * Preview fix for JavaScript bug with foreign languages.
    316  *
    317  * @since 3.1.0
    318  * @access private
    319  * @param array $match Match array from preg_replace_callback
    320  * @return string
    321  */
    322 function _convert_urlencoded_to_entities( $match ) {
    323     return '&#' . base_convert( $match[1], 16, 10 ) . ';';
    324 }
    325 
    326 /**
    327  * Display the post excerpt.
    328  *
    329  * @since 0.71
    330  */
    331 function the_excerpt() {
    332 
    333     /**
    334      * Filter the displayed post excerpt.
    335      *
    336      * @since 0.71
    337      *
    338      * @see get_the_excerpt()
    339      *
    340      * @param string $post_excerpt The post excerpt.
    341      */
    342     echo apply_filters( 'the_excerpt', get_the_excerpt() );
    343 }
    344 
    345 /**
    346  * Retrieve the post excerpt.
    347  *
    348  * @since 0.71
    349  *
    350  * @param mixed $deprecated Not used.
    351  * @return string
    352  */
    353 function get_the_excerpt( $deprecated = '' ) {
    354     if ( !empty( $deprecated ) )
    355         _deprecated_argument( __FUNCTION__, '2.3' );
    356 
    357     $post = get_post();
    358     if ( empty( $post ) ) {
    359         return '';
    360     }
    361 
    362     if ( post_password_required() ) {
    363         return __( 'There is no excerpt because this is a protected post.' );
    364     }
    365 
    366     /**
    367      * Filter the retrieved post excerpt.
    368      *
    369      * @since 1.2.0
    370      *
    371      * @param string $post_excerpt The post excerpt.
    372      */
    373     return apply_filters( 'get_the_excerpt', $post->post_excerpt );
    374 }
    375 
    376 /**
    377  * Whether post has excerpt.
    378  *
    379  * @since 2.3.0
    380  *
    381  * @param int|WP_Post $id Optional. Post ID or post object.
    382  * @return bool
    383  */
    384 function has_excerpt( $id = 0 ) {
    385     $post = get_post( $id );
    386     return ( !empty( $post->post_excerpt ) );
    387 }
    388 
    389 /**
    390  * Display the classes for the post div.
    391  *
    392  * @since 2.7.0
    393  *
    394  * @param string|array $class One or more classes to add to the class list.
    395  * @param int|WP_Post $post_id Optional. Post ID or post object.
    396  */
    397 function post_class( $class = '', $post_id = null ) {
    398     // Separates classes with a single space, collates classes for post DIV
    399     echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
    400 }
    401 
    402 /**
    403  * Retrieve the classes for the post div as an array.
    404  *
    405  * The class names are many. If the post is a sticky, then the 'sticky'
    406  * class name. The class 'hentry' is always added to each post. If the post has a
    407  * post thumbnail, 'has-post-thumbnail' is added as a class. For each taxonomy that
    408  * the post belongs to, a class will be added of the format '{$taxonomy}-{$slug}' -
    409  * eg 'category-foo' or 'my_custom_taxonomy-bar'. The 'post_tag' taxonomy is a special
    410  * case; the class has the 'tag-' prefix instead of 'post_tag-'. All classes are
    411  * passed through the filter, 'post_class' with the list of classes, followed by
    412  * $class parameter value, with the post ID as the last parameter.
    413  *
    414  * @since 2.7.0
    415  * @since 4.2.0 Custom taxonomy classes were added.
    416  *
    417  * @param string|array $class   One or more classes to add to the class list.
    418  * @param int|WP_Post  $post_id Optional. Post ID or post object.
    419  * @return array Array of classes.
    420  */
    421 function get_post_class( $class = '', $post_id = null ) {
    422     $post = get_post( $post_id );
    423 
    424     $classes = array();
    425 
    426     if ( $class ) {
    427         if ( ! is_array( $class ) ) {
    428             $class = preg_split( '#\s+#', $class );
    429         }
    430         $classes = array_map( 'esc_attr', $class );
    431     }
    432 
    433     if ( ! $post ) {
    434         return $classes;
    435     }
    436 
    437     $classes[] = 'post-' . $post->ID;
    438     if ( ! is_admin() )
    439         $classes[] = $post->post_type;
    440     $classes[] = 'type-' . $post->post_type;
    441     $classes[] = 'status-' . $post->post_status;
    442 
    443     // Post Format
    444     if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
    445         $post_format = get_post_format( $post->ID );
    446 
    447         if ( $post_format && !is_wp_error($post_format) )
    448             $classes[] = 'format-' . sanitize_html_class( $post_format );
    449         else
    450             $classes[] = 'format-standard';
    451     }
    452 
    453     // Post requires password
    454     if ( post_password_required( $post->ID ) ) {
    455         $classes[] = 'post-password-required';
    456     // Post thumbnails
    457     } elseif ( ! is_attachment( $post ) && current_theme_supports( 'post-thumbnails' ) && has_post_thumbnail( $post->ID ) ) {
    458         $classes[] = 'has-post-thumbnail';
    459     }
    460 
    461     // sticky for Sticky Posts
    462     if ( is_sticky( $post->ID ) ) {
    463         if ( is_home() && ! is_paged() ) {
    464             $classes[] = 'sticky';
    465         } elseif ( is_admin() ) {
    466             $classes[] = 'status-sticky';
    467         }
    468     }
    469 
    470     // hentry for hAtom compliance
    471     $classes[] = 'hentry';
    472 
    473     // All public taxonomies
    474     $taxonomies = get_taxonomies( array( 'public' => true ) );
    475     foreach ( (array) $taxonomies as $taxonomy ) {
    476         if ( is_object_in_taxonomy( $post->post_type, $taxonomy ) ) {
    477             foreach ( (array) get_the_terms( $post->ID, $taxonomy ) as $term ) {
    478                 if ( empty( $term->slug ) ) {
    479                     continue;
    480                 }
    481 
    482                 $term_class = sanitize_html_class( $term->slug, $term->term_id );
    483                 if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) {
    484                     $term_class = $term->term_id;
    485                 }
    486 
    487                 // 'post_tag' uses the 'tag' prefix for backward compatibility.
    488                 if ( 'post_tag' == $taxonomy ) {
    489                     $classes[] = 'tag-' . $term_class;
    490                 } else {
    491                     $classes[] = sanitize_html_class( $taxonomy . '-' . $term_class, $taxonomy . '-' . $term->term_id );
    492                 }
    493             }
    494         }
    495     }
    496 
    497     $classes = array_map( 'esc_attr', $classes );
    498 
    499     /**
    500      * Filter the list of CSS classes for the current post.
    501      *
    502      * @since 2.7.0
    503      *
    504      * @param array  $classes An array of post classes.
    505      * @param string $class   A comma-separated list of additional classes added to the post.
    506      * @param int    $post_id The post ID.
    507      */
    508     $classes = apply_filters( 'post_class', $classes, $class, $post->ID );
    509 
    510     return array_unique( $classes );
    511 }
    512 
    513 /**
    514  * Display the classes for the body element.
    515  *
    516  * @since 2.8.0
    517  *
    518  * @param string|array $class One or more classes to add to the class list.
    519  */
    520 function body_class( $class = '' ) {
    521     // Separates classes with a single space, collates classes for body element
    522     echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
    523 }
    524 
    525 /**
    526  * Retrieve the classes for the body element as an array.
    527  *
    528  * @since 2.8.0
    529  *
    530  * @global WP_Query $wp_query
    531  * @global wpdb     $wpdb
    532  *
    533  * @param string|array $class One or more classes to add to the class list.
    534  * @return array Array of classes.
    535  */
    536 function get_body_class( $class = '' ) {
    537     global $wp_query, $wpdb;
    538 
    539     $classes = array();
    540 
    541     if ( is_rtl() )
    542         $classes[] = 'rtl';
    543 
    544     if ( is_front_page() )
    545         $classes[] = 'home';
    546     if ( is_home() )
    547         $classes[] = 'blog';
    548     if ( is_archive() )
    549         $classes[] = 'archive';
    550     if ( is_date() )
    551         $classes[] = 'date';
    552     if ( is_search() ) {
    553         $classes[] = 'search';
    554         $classes[] = $wp_query->posts ? 'search-results' : 'search-no-results';
    555     }
    556     if ( is_paged() )
    557         $classes[] = 'paged';
    558     if ( is_attachment() )
    559         $classes[] = 'attachment';
    560     if ( is_404() )
    561         $classes[] = 'error404';
    562 
    563     if ( is_single() ) {
    564         $post_id = $wp_query->get_queried_object_id();
    565         $post = $wp_query->get_queried_object();
    566 
    567         $classes[] = 'single';
    568         if ( isset( $post->post_type ) ) {
    569             $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id);
    570             $classes[] = 'postid-' . $post_id;
    571 
    572             // Post Format
    573             if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
    574                 $post_format = get_post_format( $post->ID );
    575 
    576                 if ( $post_format && !is_wp_error($post_format) )
    577                     $classes[] = 'single-format-' . sanitize_html_class( $post_format );
    578                 else
    579                     $classes[] = 'single-format-standard';
    580             }
    581         }
    582 
    583         if ( is_attachment() ) {
    584             $mime_type = get_post_mime_type($post_id);
    585             $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
    586             $classes[] = 'attachmentid-' . $post_id;
    587             $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
    588         }
    589     } elseif ( is_archive() ) {
    590         if ( is_post_type_archive() ) {
    591             $classes[] = 'post-type-archive';
    592             $post_type = get_query_var( 'post_type' );
    593             if ( is_array( $post_type ) )
    594                 $post_type = reset( $post_type );
    595             $classes[] = 'post-type-archive-' . sanitize_html_class( $post_type );
    596         } elseif ( is_author() ) {
    597             $author = $wp_query->get_queried_object();
    598             $classes[] = 'author';
    599             if ( isset( $author->user_nicename ) ) {
    600                 $classes[] = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID );
    601                 $classes[] = 'author-' . $author->ID;
    602             }
    603         } elseif ( is_category() ) {
    604             $cat = $wp_query->get_queried_object();
    605             $classes[] = 'category';
    606             if ( isset( $cat->term_id ) ) {
    607                 $cat_class = sanitize_html_class( $cat->slug, $cat->term_id );
    608                 if ( is_numeric( $cat_class ) || ! trim( $cat_class, '-' ) ) {
    609                     $cat_class = $cat->term_id;
    610                 }
    611 
    612                 $classes[] = 'category-' . $cat_class;
    613                 $classes[] = 'category-' . $cat->term_id;
    614             }
    615         } elseif ( is_tag() ) {
    616             $tag = $wp_query->get_queried_object();
    617             $classes[] = 'tag';
    618             if ( isset( $tag->term_id ) ) {
    619                 $tag_class = sanitize_html_class( $tag->slug, $tag->term_id );
    620                 if ( is_numeric( $tag_class ) || ! trim( $tag_class, '-' ) ) {
    621                     $tag_class = $tag->term_id;
    622                 }
    623 
    624                 $classes[] = 'tag-' . $tag_class;
    625                 $classes[] = 'tag-' . $tag->term_id;
    626             }
    627         } elseif ( is_tax() ) {
    628             $term = $wp_query->get_queried_object();
    629             if ( isset( $term->term_id ) ) {
    630                 $term_class = sanitize_html_class( $term->slug, $term->term_id );
    631                 if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) {
    632                     $term_class = $term->term_id;
    633                 }
    634 
    635                 $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy );
    636                 $classes[] = 'term-' . $term_class;
    637                 $classes[] = 'term-' . $term->term_id;
    638             }
    639         }
    640     } elseif ( is_page() ) {
    641         $classes[] = 'page';
    642 
    643         $page_id = $wp_query->get_queried_object_id();
    644 
    645         $post = get_post($page_id);
    646 
    647         $classes[] = 'page-id-' . $page_id;
    648 
    649         if ( get_pages( array( 'parent' => $page_id, 'number' => 1 ) ) ) {
    650             $classes[] = 'page-parent';
    651         }
    652 
    653         if ( $post->post_parent ) {
    654             $classes[] = 'page-child';
    655             $classes[] = 'parent-pageid-' . $post->post_parent;
    656         }
    657         if ( is_page_template() ) {
    658             $classes[] = 'page-template';
    659 
    660             $template_slug  = get_page_template_slug( $page_id );
    661             $template_parts = explode( '/', $template_slug );
    662 
    663             foreach ( $template_parts as $part ) {
    664                 $classes[] = 'page-template-' . sanitize_html_class( str_replace( array( '.', '/' ), '-', basename( $part, '.php' ) ) );
    665             }
    666             $classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', $template_slug ) );
    667         } else {
    668             $classes[] = 'page-template-default';
    669         }
    670     }
    671 
    672     if ( is_user_logged_in() )
    673         $classes[] = 'logged-in';
    674 
    675     if ( is_admin_bar_showing() ) {
    676         $classes[] = 'admin-bar';
    677         $classes[] = 'no-customize-support';
    678     }
    679 
    680     if ( get_background_color() !== get_theme_support( 'custom-background', 'default-color' ) || get_background_image() )
    681         $classes[] = 'custom-background';
    682 
    683     $page = $wp_query->get( 'page' );
    684 
    685     if ( ! $page || $page < 2 )
    686         $page = $wp_query->get( 'paged' );
    687 
    688     if ( $page && $page > 1 && ! is_404() ) {
    689         $classes[] = 'paged-' . $page;
    690 
    691         if ( is_single() )
    692             $classes[] = 'single-paged-' . $page;
    693         elseif ( is_page() )
    694             $classes[] = 'page-paged-' . $page;
    695         elseif ( is_category() )
    696             $classes[] = 'category-paged-' . $page;
    697         elseif ( is_tag() )
    698             $classes[] = 'tag-paged-' . $page;
    699         elseif ( is_date() )
    700             $classes[] = 'date-paged-' . $page;
    701         elseif ( is_author() )
    702             $classes[] = 'author-paged-' . $page;
    703         elseif ( is_search() )
    704             $classes[] = 'search-paged-' . $page;
    705         elseif ( is_post_type_archive() )
    706             $classes[] = 'post-type-paged-' . $page;
    707     }
    708 
    709     if ( ! empty( $class ) ) {
    710         if ( !is_array( $class ) )
    711             $class = preg_split( '#\s+#', $class );
    712         $classes = array_merge( $classes, $class );
    713     } else {
    714         // Ensure that we always coerce class to being an array.
    715         $class = array();
    716     }
    717 
    718     $classes = array_map( 'esc_attr', $classes );
    719 
    720     /**
    721      * Filter the list of CSS body classes for the current post or page.
    722      *
    723      * @since 2.8.0
    724      *
    725      * @param array  $classes An array of body classes.
    726      * @param string $class   A comma-separated list of additional classes added to the body.
    727      */
    728     $classes = apply_filters( 'body_class', $classes, $class );
    729 
    730     return array_unique( $classes );
    731 }
    732 
    733 /**
    734  * Whether post requires password and correct password has been provided.
    735  *
    736  * @since 2.7.0
    737  *
    738  * @param int|WP_Post|null $post An optional post. Global $post used if not provided.
    739  * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
    740  */
    741 function post_password_required( $post = null ) {
    742     $post = get_post($post);
    743 
    744     if ( empty( $post->post_password ) )
    745         return false;
    746 
    747     if ( ! isset( $_COOKIE['wp-postpass_' . COOKIEHASH] ) )
    748         return true;
    749 
    750     require_once ABSPATH . WPINC . '/class-phpass.php';
    751     $hasher = new PasswordHash( 8, true );
    752 
    753     $hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] );
    754     if ( 0 !== strpos( $hash, '$P$B' ) )
    755         return true;
    756 
    757     return ! $hasher->CheckPassword( $post->post_password, $hash );
    758 }
    759 
    760 //
    761 // Page Template Functions for usage in Themes
    762 //
    763 
    764 /**
    765  * The formatted output of a list of pages.
    766  *
    767  * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
    768  * Quicktag one or more times). This tag must be within The Loop.
    769  *
    770  * @since 1.2.0
    771  *
    772  * @global int $page
    773  * @global int $numpages
    774  * @global int $multipage
    775  * @global int $more
    776  *
    777  * @param string|array $args {
    778  *     Optional. Array or string of default arguments.
    779  *
    780  *     @type string       $before           HTML or text to prepend to each link. Default is `<p> Pages:`.
    781  *     @type string       $after            HTML or text to append to each link. Default is `</p>`.
    782  *     @type string       $link_before      HTML or text to prepend to each link, inside the `<a>` tag.
    783  *                                          Also prepended to the current item, which is not linked. Default empty.
    784  *     @type string       $link_after       HTML or text to append to each Pages link inside the `<a>` tag.
    785  *                                          Also appended to the current item, which is not linked. Default empty.
    786  *     @type string       $next_or_number   Indicates whether page numbers should be used. Valid values are number
    787  *                                          and next. Default is 'number'.
    788  *     @type string       $separator        Text between pagination links. Default is ' '.
    789  *     @type string       $nextpagelink     Link text for the next page link, if available. Default is 'Next Page'.
    790  *     @type string       $previouspagelink Link text for the previous page link, if available. Default is 'Previous Page'.
    791  *     @type string       $pagelink         Format string for page numbers. The % in the parameter string will be
    792  *                                          replaced with the page number, so 'Page %' generates "Page 1", "Page 2", etc.
    793  *                                          Defaults to '%', just the page number.
    794  *     @type int|bool     $echo             Whether to echo or not. Accepts 1|true or 0|false. Default 1|true.
    795  * }
    796  * @return string Formatted output in HTML.
    797  */
    798 function wp_link_pages( $args = '' ) {
    799     global $page, $numpages, $multipage, $more;
    800 
    801     $defaults = array(
    802         'before'           => '<p>' . __( 'Pages:' ),
    803         'after'            => '</p>',
    804         'link_before'      => '',
    805         'link_after'       => '',
    806         'next_or_number'   => 'number',
    807         'separator'        => ' ',
    808         'nextpagelink'     => __( 'Next page' ),
    809         'previouspagelink' => __( 'Previous page' ),
    810         'pagelink'         => '%',
    811         'echo'             => 1
    812     );
    813 
    814     $params = wp_parse_args( $args, $defaults );
    815 
    816     /**
    817      * Filter the arguments used in retrieving page links for paginated posts.
    818      *
    819      * @since 3.0.0
    820      *
    821      * @param array $params An array of arguments for page links for paginated posts.
    822      */
    823     $r = apply_filters( 'wp_link_pages_args', $params );
    824 
    825     $output = '';
    826     if ( $multipage ) {
    827         if ( 'number' == $r['next_or_number'] ) {
    828             $output .= $r['before'];
    829             for ( $i = 1; $i <= $numpages; $i++ ) {
    830                 $link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
    831                 if ( $i != $page || ! $more && 1 == $page ) {
    832                     $link = _wp_link_page( $i ) . $link . '</a>';
    833                 }
    834                 /**
    835                  * Filter the HTML output of individual page number links.
    836                  *
    837                  * @since 3.6.0
    838                  *
    839                  * @param string $link The page number HTML output.
    840                  * @param int    $i    Page number for paginated posts' page links.
    841                  */
    842                 $link = apply_filters( 'wp_link_pages_link', $link, $i );
    843 
    844                 // Use the custom links separator beginning with the second link.
    845                 $output .= ( 1 === $i ) ? ' ' : $r['separator'];
    846                 $output .= $link;
    847             }
    848             $output .= $r['after'];
    849         } elseif ( $more ) {
    850             $output .= $r['before'];
    851             $prev = $page - 1;
    852             if ( $prev > 0 ) {
    853                 $link = _wp_link_page( $prev ) . $r['link_before'] . $r['previouspagelink'] . $r['link_after'] . '</a>';
    854 
    855                 /** This filter is documented in wp-includes/post-template.php */
    856                 $output .= apply_filters( 'wp_link_pages_link', $link, $prev );
    857             }
    858             $next = $page + 1;
    859             if ( $next <= $numpages ) {
    860                 if ( $prev ) {
    861                     $output .= $r['separator'];
    862                 }
    863                 $link = _wp_link_page( $next ) . $r['link_before'] . $r['nextpagelink'] . $r['link_after'] . '</a>';
    864 
    865                 /** This filter is documented in wp-includes/post-template.php */
    866                 $output .= apply_filters( 'wp_link_pages_link', $link, $next );
    867             }
    868             $output .= $r['after'];
    869         }
    870     }
    871 
    872     /**
    873      * Filter the HTML output of page links for paginated posts.
    874      *
    875      * @since 3.6.0
    876      *
    877      * @param string $output HTML output of paginated posts' page links.
    878      * @param array  $args   An array of arguments.
    879      */
    880     $html = apply_filters( 'wp_link_pages', $output, $args );
    881 
    882     if ( $r['echo'] ) {
    883         echo $html;
    884     }
    885     return $html;
    886 }
    887 
    888 /**
    889  * Helper function for wp_link_pages().
    890  *
    891  * @since 3.1.0
    892  * @access private
    893  *
    894  * @global WP_Rewrite $wp_rewrite
    895  *
    896  * @param int $i Page number.
    897  * @return string Link.
    898  */
    899 function _wp_link_page( $i ) {
    900     global $wp_rewrite;
    901     $post = get_post();
    902 
    903     if ( 1 == $i ) {
    904         $url = get_permalink();
    905     } else {
    906         if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
    907             $url = add_query_arg( 'page', $i, get_permalink() );
    908         elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
    909             $url = trailingslashit(get_permalink()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged');
    910         else
    911             $url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
    912     }
    913 
    914     if ( is_preview() ) {
    915         $url = add_query_arg( array(
    916             'preview' => 'true'
    917         ), $url );
    918 
    919         if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) {
    920             $url = add_query_arg( array(
    921                 'preview_id'    => wp_unslash( $_GET['preview_id'] ),
    922                 'preview_nonce' => wp_unslash( $_GET['preview_nonce'] )
    923             ), $url );
    924         }
    925     }
    926 
    927     return '<a href="' . esc_url( $url ) . '">';
    928 }
    929 
    930 //
    931 // Post-meta: Custom per-post fields.
    932 //
    933 
    934 /**
    935  * Retrieve post custom meta data field.
    936  *
    937  * @since 1.5.0
    938  *
    939  * @param string $key Meta data key name.
    940  * @return false|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
    941  */
    942 function post_custom( $key = '' ) {
    943     $custom = get_post_custom();
    944 
    945     if ( !isset( $custom[$key] ) )
    946         return false;
    947     elseif ( 1 == count($custom[$key]) )
    948         return $custom[$key][0];
    949     else
    950         return $custom[$key];
    951 }
    952 
    953 /**
    954  * Display list of post custom fields.
    955  *
    956  * @internal This will probably change at some point...
    957  * @since 1.2.0
    958  */
    959 function the_meta() {
    960     if ( $keys = get_post_custom_keys() ) {
    961         echo "<ul class='post-meta'>\n";
    962         foreach ( (array) $keys as $key ) {
    963             $keyt = trim($key);
    964             if ( is_protected_meta( $keyt, 'post' ) )
    965                 continue;
    966             $values = array_map('trim', get_post_custom_values($key));
    967             $value = implode($values,', ');
    968 
    969             /**
    970              * Filter the HTML output of the li element in the post custom fields list.
    971              *
    972              * @since 2.2.0
    973              *
    974              * @param string $html  The HTML output for the li element.
    975              * @param string $key   Meta key.
    976              * @param string $value Meta value.
    977              */
    978             echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value );
    979         }
    980         echo "</ul>\n";
    981     }
    982 }
    983 
    984 //
    985 // Pages
    986 //
    987 
    988 /**
    989  * Retrieve or display list of pages as a dropdown (select list).
    990  *
    991  * @since 2.1.0
    992  * @since 4.2.0 The `$value_field` argument was added.
    993  * @since 4.3.0 The `$class` argument was added.
    994  *
    995  * @param array|string $args {
    996  *     Optional. Array or string of arguments to generate a pages drop-down element.
    997  *
    998  *     @type int          $depth                 Maximum depth. Default 0.
    999  *     @type int          $child_of              Page ID to retrieve child pages of. Default 0.
    1000  *     @type int|string   $selected              Value of the option that should be selected. Default 0.
    1001  *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1,
    1002  *                                               or their bool equivalents. Default 1.
    1003  *     @type string       $name                  Value for the 'name' attribute of the select element.
    1004  *                                               Default 'page_id'.
    1005  *     @type string       $id                    Value for the 'id' attribute of the select element.
    1006  *     @type string       $class                 Value for the 'class' attribute of the select element. Default: none.
    1007  *                                               Defaults to the value of `$name`.
    1008  *     @type string       $show_option_none      Text to display for showing no pages. Default empty (does not display).
    1009  *     @type string       $show_option_no_change Text to display for "no change" option. Default empty (does not display).
    1010  *     @type string       $option_none_value     Value to use when no page is selected. Default empty.
    1011  *     @type string       $value_field           Post field used to populate the 'value' attribute of the option
    1012  *                                               elements. Accepts any valid post field. Default 'ID'.
    1013  * }
    1014  * @return string HTML content, if not displaying.
    1015  */
    1016 function wp_dropdown_pages( $args = '' ) {
    1017     $defaults = array(
    1018         'depth' => 0, 'child_of' => 0,
    1019         'selected' => 0, 'echo' => 1,
    1020         'name' => 'page_id', 'id' => '',
    1021         'class' => '',
    1022         'show_option_none' => '', 'show_option_no_change' => '',
    1023         'option_none_value' => '',
    1024         'value_field' => 'ID',
    1025     );
    1026 
    1027     $r = wp_parse_args( $args, $defaults );
    1028 
    1029     $pages = get_pages( $r );
    1030     $output = '';
    1031     // Back-compat with old system where both id and name were based on $name argument
    1032     if ( empty( $r['id'] ) ) {
    1033         $r['id'] = $r['name'];
    1034     }
    1035 
    1036     if ( ! empty( $pages ) ) {
    1037         $class = '';
    1038         if ( ! empty( $r['class'] ) ) {
    1039             $class = " class='" . esc_attr( $r['class'] ) . "'";
    1040         }
    1041 
    1042         $output = "<select name='" . esc_attr( $r['name'] ) . "'" . $class . " id='" . esc_attr( $r['id'] ) . "'>\n";
    1043         if ( $r['show_option_no_change'] ) {
    1044             $output .= "\t<option value=\"-1\">" . $r['show_option_no_change'] . "</option>\n";
    1045         }
    1046         if ( $r['show_option_none'] ) {
    1047             $output .= "\t<option value=\"" . esc_attr( $r['option_none_value'] ) . '">' . $r['show_option_none'] . "</option>\n";
    1048         }
    1049         $output .= walk_page_dropdown_tree( $pages, $r['depth'], $r );
    1050         $output .= "</select>\n";
    1051     }
    1052 
    1053     /**
    1054      * Filter the HTML output of a list of pages as a drop down.
    1055      *
    1056      * @since 2.1.0
    1057      * @since 4.4.0 `$r` and `$pages` added as arguments.
    1058      *
    1059      * @param string $output HTML output for drop down list of pages.
    1060      * @param array  $r      The parsed arguments array.
    1061      * @param array  $pages  List of WP_Post objects returned by `get_pages()`
    1062      */
    1063     $html = apply_filters( 'wp_dropdown_pages', $output, $r, $pages );
    1064 
    1065     if ( $r['echo'] ) {
    1066         echo $html;
    1067     }
    1068     return $html;
    1069 }
    1070 
    1071 /**
    1072  * Retrieve or display list of pages in list (li) format.
    1073  *
    1074  * @since 1.5.0
    1075  *
    1076  * @see get_pages()
    1077  *
    1078  * @global WP_Query $wp_query
    1079  *
    1080  * @param array|string $args {
    1081  *     Array or string of arguments. Optional.
    1082  *
    1083  *     @type int    $child_of     Display only the sub-pages of a single page by ID. Default 0 (all pages).
    1084  *     @type string $authors      Comma-separated list of author IDs. Default empty (all authors).
    1085  *     @type string $date_format  PHP date format to use for the listed pages. Relies on the 'show_date' parameter.
    1086  *                                Default is the value of 'date_format' option.
    1087  *     @type int    $depth        Number of levels in the hierarchy of pages to include in the generated list.
    1088  *                                Accepts -1 (any depth), 0 (all pages), 1 (top-level pages only), and n (pages to
    1089  *                                the given n depth). Default 0.
    1090  *     @type bool   $echo         Whether or not to echo the list of pages. Default true.
    1091  *     @type string $exclude      Comma-separated list of page IDs to exclude. Default empty.
    1092  *     @type array  $include      Comma-separated list of page IDs to include. Default empty.
    1093  *     @type string $link_after   Text or HTML to follow the page link label. Default null.
    1094  *     @type string $link_before  Text or HTML to precede the page link label. Default null.
    1095  *     @type string $post_type    Post type to query for. Default 'page'.
    1096  *     @type string $post_status  Comma-separated list of post statuses to include. Default 'publish'.
    1097  *     @type string $show_date    Whether to display the page publish or modified date for each page. Accepts
    1098  *                                'modified' or any other value. An empty value hides the date. Default empty.
    1099  *     @type string $sort_column  Comma-separated list of column names to sort the pages by. Accepts 'post_author',
    1100  *                                'post_date', 'post_title', 'post_name', 'post_modified', 'post_modified_gmt',
    1101  *                                'menu_order', 'post_parent', 'ID', 'rand', or 'comment_count'. Default 'post_title'.
    1102  *     @type string $title_li     List heading. Passing a null or empty value will result in no heading, and the list
    1103  *                                will not be wrapped with unordered list `<ul>` tags. Default 'Pages'.
    1104  *     @type Walker $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
    1105  * }
    1106  * @return string|void HTML list of pages.
    1107  */
    1108 function wp_list_pages( $args = '' ) {
    1109     $defaults = array(
    1110         'depth' => 0, 'show_date' => '',
    1111         'date_format' => get_option( 'date_format' ),
    1112         'child_of' => 0, 'exclude' => '',
    1113         'title_li' => __( 'Pages' ), 'echo' => 1,
    1114         'authors' => '', 'sort_column' => 'menu_order, post_title',
    1115         'link_before' => '', 'link_after' => '', 'walker' => '',
    1116     );
    1117 
    1118     $r = wp_parse_args( $args, $defaults );
    1119 
    1120     $output = '';
    1121     $current_page = 0;
    1122 
    1123     // sanitize, mostly to keep spaces out
    1124     $r['exclude'] = preg_replace( '/[^0-9,]/', '', $r['exclude'] );
    1125 
    1126     // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
    1127     $exclude_array = ( $r['exclude'] ) ? explode( ',', $r['exclude'] ) : array();
    1128 
    1129     /**
    1130      * Filter the array of pages to exclude from the pages list.
    1131      *
    1132      * @since 2.1.0
    1133      *
    1134      * @param array $exclude_array An array of page IDs to exclude.
    1135      */
    1136     $r['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) );
    1137 
    1138     // Query pages.
    1139     $r['hierarchical'] = 0;
    1140     $pages = get_pages( $r );
    1141 
    1142     if ( ! empty( $pages ) ) {
    1143         if ( $r['title_li'] ) {
    1144             $output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
    1145         }
    1146         global $wp_query;
    1147         if ( is_page() || is_attachment() || $wp_query->is_posts_page ) {
    1148             $current_page = get_queried_object_id();
    1149         } elseif ( is_singular() ) {
    1150             $queried_object = get_queried_object();
    1151             if ( is_post_type_hierarchical( $queried_object->post_type ) ) {
    1152                 $current_page = $queried_object->ID;
    1153             }
    1154         }
    1155 
    1156         $output .= walk_page_tree( $pages, $r['depth'], $current_page, $r );
    1157 
    1158         if ( $r['title_li'] ) {
    1159             $output .= '</ul></li>';
    1160         }
    1161     }
    1162 
    1163     /**
    1164      * Filter the HTML output of the pages to list.
    1165      *
    1166      * @since 1.5.1
    1167      * @since 4.4.0 `$pages` added as arguments.
    1168      *
    1169      * @see wp_list_pages()
    1170      *
    1171      * @param string $output HTML output of the pages list.
    1172      * @param array  $r      An array of page-listing arguments.
    1173      * @param array  $pages  List of WP_Post objects returned by `get_pages()`
    1174      */
    1175     $html = apply_filters( 'wp_list_pages', $output, $r, $pages );
    1176 
    1177     if ( $r['echo'] ) {
    1178         echo $html;
    1179     } else {
    1180         return $html;
    1181     }
    1182 }
    1183 
    1184 /**
    1185  * Display or retrieve list of pages with optional home link.
    1186  *
    1187  * The arguments are listed below and part of the arguments are for {@link
    1188  * wp_list_pages()} function. Check that function for more info on those
    1189  * arguments.
    1190  *
    1191  * @since 2.7.0
    1192  *
    1193  * @param array|string $args {
    1194  *     Optional. Arguments to generate a page menu. See wp_list_pages() for additional arguments.
    1195  *
    1196  *     @type string          $sort_column How to short the list of pages. Accepts post column names.
    1197  *                                        Default 'menu_order, post_title'.
    1198  *     @type string          $menu_class  Class to use for the div ID containing the page list. Default 'menu'.
    1199  *     @type bool            $echo        Whether to echo the list or return it. Accepts true (echo) or false (return).
    1200  *                                        Default true.
    1201  *     @type string          $link_before The HTML or text to prepend to $show_home text. Default empty.
    1202  *     @type string          $link_after  The HTML or text to append to $show_home text. Default empty.
    1203  *     @type int|bool|string $show_home   Whether to display the link to the home page. Can just enter the text
    1204  *                                        you'd like shown for the home link. 1|true defaults to 'Home'.
    1205  * }
    1206  * @return string|void HTML menu
    1207  */
    1208 function wp_page_menu( $args = array() ) {
    1209     $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
    1210     $args = wp_parse_args( $args, $defaults );
    1211 
    1212     /**
    1213      * Filter the arguments used to generate a page-based menu.
    1214      *
    1215      * @since 2.7.0
    1216      *
    1217      * @see wp_page_menu()
    1218      *
    1219      * @param array $args An array of page menu arguments.
    1220      */
    1221     $args = apply_filters( 'wp_page_menu_args', $args );
    1222 
    1223     $menu = '';
    1224 
    1225     $list_args = $args;
    1226 
    1227     // Show Home in the menu
    1228     if ( ! empty($args['show_home']) ) {
    1229         if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
    1230             $text = __('Home');
    1231         else
    1232             $text = $args['show_home'];
    1233         $class = '';
    1234         if ( is_front_page() && !is_paged() )
    1235             $class = 'class="current_page_item"';
    1236         $menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
    1237         // If the front page is a page, add it to the exclude list
    1238         if (get_option('show_on_front') == 'page') {
    1239             if ( !empty( $list_args['exclude'] ) ) {
    1240                 $list_args['exclude'] .= ',';
    1241             } else {
    1242                 $list_args['exclude'] = '';
    1243             }
    1244             $list_args['exclude'] .= get_option('page_on_front');
    1245         }
    1246     }
    1247 
    1248     $list_args['echo'] = false;
    1249     $list_args['title_li'] = '';
    1250     $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
    1251 
    1252     if ( $menu )
    1253         $menu = '<ul>' . $menu . '</ul>';
    1254 
    1255     $menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
    1256 
    1257     /**
    1258      * Filter the HTML output of a page-based menu.
    1259      *
    1260      * @since 2.7.0
    1261      *
    1262      * @see wp_page_menu()
    1263      *
    1264      * @param string $menu The HTML output.
    1265      * @param array  $args An array of arguments.
    1266      */
    1267     $menu = apply_filters( 'wp_page_menu', $menu, $args );
    1268     if ( $args['echo'] )
    1269         echo $menu;
    1270     else
    1271         return $menu;
    1272 }
    1273 
    1274 //
    1275 // Page helpers
    1276 //
    1277 
    1278 /**
    1279  * Retrieve HTML list content for page list.
    1280  *
    1281  * @uses Walker_Page to create HTML list content.
    1282  * @since 2.1.0
    1283  *
    1284  * @param array $pages
    1285  * @param int   $depth
    1286  * @param int   $current_page
    1287  * @param array $r
    1288  * @return string
    1289  */
    1290 function walk_page_tree( $pages, $depth, $current_page, $r ) {
    1291     if ( empty($r['walker']) )
    1292         $walker = new Walker_Page;
    1293     else
    1294         $walker = $r['walker'];
    1295 
    1296     foreach ( (array) $pages as $page ) {
    1297         if ( $page->post_parent )
    1298             $r['pages_with_children'][ $page->post_parent ] = true;
    1299     }
    1300 
    1301     $args = array($pages, $depth, $r, $current_page);
    1302     return call_user_func_array(array($walker, 'walk'), $args);
    1303 }
    1304 
    1305 /**
    1306  * Retrieve HTML dropdown (select) content for page list.
    1307  *
    1308  * @uses Walker_PageDropdown to create HTML dropdown content.
    1309  * @since 2.1.0
    1310  * @see Walker_PageDropdown::walk() for parameters and return description.
    1311  *
    1312  * @return string
    1313  */
    1314 function walk_page_dropdown_tree() {
    1315     $args = func_get_args();
    1316     if ( empty($args[2]['walker']) ) // the user's options are the third parameter
    1317         $walker = new Walker_PageDropdown;
    1318     else
    1319         $walker = $args[2]['walker'];
    1320 
    1321     return call_user_func_array(array($walker, 'walk'), $args);
    1322 }
    1323 
    1324 /**
    1325  * Create HTML list of pages.
    1326  *
    1327  * @since 2.1.0
    1328  * @uses Walker
    1329  */
    1330 class Walker_Page extends Walker {
    1331     /**
    1332      * @see Walker::$tree_type
    1333      * @since 2.1.0
    1334      * @var string
    1335      */
    1336     public $tree_type = 'page';
    1337 
    1338     /**
    1339      * @see Walker::$db_fields
    1340      * @since 2.1.0
    1341      * @todo Decouple this.
    1342      * @var array
    1343      */
    1344     public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
    1345 
    1346     /**
    1347      * @see Walker::start_lvl()
    1348      * @since 2.1.0
    1349      *
    1350      * @param string $output Passed by reference. Used to append additional content.
    1351      * @param int    $depth  Depth of page. Used for padding.
    1352      * @param array  $args
    1353      */
    1354     public function start_lvl( &$output, $depth = 0, $args = array() ) {
    1355         $indent = str_repeat("\t", $depth);
    1356         $output .= "\n$indent<ul class='children'>\n";
    1357     }
    1358 
    1359     /**
    1360      * @see Walker::end_lvl()
    1361      * @since 2.1.0
    1362      *
    1363      * @param string $output Passed by reference. Used to append additional content.
    1364      * @param int    $depth  Depth of page. Used for padding.
    1365      * @param array  $args
    1366      */
    1367     public function end_lvl( &$output, $depth = 0, $args = array() ) {
    1368         $indent = str_repeat("\t", $depth);
    1369         $output .= "$indent</ul>\n";
    1370     }
    1371 
    1372     /**
    1373      * @see Walker::start_el()
    1374      * @since 2.1.0
    1375      *
    1376      * @param string $output       Passed by reference. Used to append additional content.
    1377      * @param object $page         Page data object.
    1378      * @param int    $depth        Depth of page. Used for padding.
    1379      * @param int    $current_page Page ID.
    1380      * @param array  $args
    1381      */
    1382     public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
    1383         if ( $depth ) {
    1384             $indent = str_repeat( "\t", $depth );
    1385         } else {
    1386             $indent = '';
    1387         }
    1388 
    1389         $css_class = array( 'page_item', 'page-item-' . $page->ID );
    1390 
    1391         if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
    1392             $css_class[] = 'page_item_has_children';
    1393         }
    1394 
    1395         if ( ! empty( $current_page ) ) {
    1396             $_current_page = get_post( $current_page );
    1397             if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
    1398                 $css_class[] = 'current_page_ancestor';
    1399             }
    1400             if ( $page->ID == $current_page ) {
    1401                 $css_class[] = 'current_page_item';
    1402             } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
    1403                 $css_class[] = 'current_page_parent';
    1404             }
    1405         } elseif ( $page->ID == get_option('page_for_posts') ) {
    1406             $css_class[] = 'current_page_parent';
    1407         }
    1408 
    1409         /**
    1410          * Filter the list of CSS classes to include with each page item in the list.
    1411          *
    1412          * @since 2.8.0
    1413          *
    1414          * @see wp_list_pages()
    1415          *
    1416          * @param array   $css_class    An array of CSS classes to be applied
    1417          *                             to each list item.
    1418          * @param WP_Post $page         Page data object.
    1419          * @param int     $depth        Depth of page, used for padding.
    1420          * @param array   $args         An array of arguments.
    1421          * @param int     $current_page ID of the current page.
    1422          */
    1423         $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
    1424 
    1425         if ( '' === $page->post_title ) {
    1426             /* translators: %d: ID of a post */
    1427             $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
    1428         }
    1429 
    1430         $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
    1431         $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];
    1432 
    1433         /** This filter is documented in wp-includes/post-template.php */
    1434         $output .= $indent . sprintf(
    1435             '<li class="%s"><a href="%s">%s%s%s</a>',
    1436             $css_classes,
    1437             get_permalink( $page->ID ),
    1438             $args['link_before'],
    1439             apply_filters( 'the_title', $page->post_title, $page->ID ),
    1440             $args['link_after']
    1441         );
    1442 
    1443         if ( ! empty( $args['show_date'] ) ) {
    1444             if ( 'modified' == $args['show_date'] ) {
    1445                 $time = $page->post_modified;
    1446             } else {
    1447                 $time = $page->post_date;
    1448             }
    1449 
    1450             $date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
    1451             $output .= " " . mysql2date( $date_format, $time );
    1452         }
    1453     }
    1454 
    1455     /**
    1456      * @see Walker::end_el()
    1457      * @since 2.1.0
    1458      *
    1459      * @param string $output Passed by reference. Used to append additional content.
    1460      * @param object $page Page data object. Not used.
    1461      * @param int    $depth Depth of page. Not Used.
    1462      * @param array  $args
    1463      */
    1464     public function end_el( &$output, $page, $depth = 0, $args = array() ) {
    1465         $output .= "</li>\n";
    1466     }
    1467 
    1468 }
    14699
    147010/**
     
    153272    }
    153373}
    1534 
    1535 //
    1536 // Attachments
    1537 //
    1538 
    1539 /**
    1540  * Display an attachment page link using an image or icon.
    1541  *
    1542  * @since 2.0.0
    1543  *
    1544  * @param int|WP_Post $id Optional. Post ID or post object.
    1545  * @param bool        $fullsize     Optional, default is false. Whether to use full size.
    1546  * @param bool        $deprecated   Deprecated. Not used.
    1547  * @param bool        $permalink    Optional, default is false. Whether to include permalink.
    1548  */
    1549 function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
    1550     if ( !empty( $deprecated ) )
    1551         _deprecated_argument( __FUNCTION__, '2.5' );
    1552 
    1553     if ( $fullsize )
    1554         echo wp_get_attachment_link($id, 'full', $permalink);
    1555     else
    1556         echo wp_get_attachment_link($id, 'thumbnail', $permalink);
    1557 }
    1558 
    1559 /**
    1560  * Retrieve an attachment page link using an image or icon, if possible.
    1561  *
    1562  * @since 2.5.0
    1563  * @since 4.4.0 The `$id` parameter can now accept either a post ID or `WP_Post` object.
    1564  *
    1565  * @param int|WP_Post  $id        Optional. Post ID or post object.
    1566  * @param string       $size      Optional, default is 'thumbnail'. Size of image, either array or string.
    1567  * @param bool         $permalink Optional, default is false. Whether to add permalink to image.
    1568  * @param bool         $icon      Optional, default is false. Whether to include icon.
    1569  * @param string|bool  $text      Optional, default is false. If string, then will be link text.
    1570  * @param array|string $attr      Optional. Array or string of attributes.
    1571  * @return string HTML content.
    1572  */
    1573 function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) {
    1574     $_post = get_post( $id );
    1575 
    1576     if ( empty( $_post ) || ( 'attachment' != $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) )
    1577         return __( 'Missing Attachment' );
    1578 
    1579     if ( $permalink )
    1580         $url = get_attachment_link( $_post->ID );
    1581 
    1582     if ( $text ) {
    1583         $link_text = $text;
    1584     } elseif ( $size && 'none' != $size ) {
    1585         $link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr );
    1586     } else {
    1587         $link_text = '';
    1588     }
    1589 
    1590     if ( trim( $link_text ) == '' )
    1591         $link_text = $_post->post_title;
    1592 
    1593     /**
    1594      * Filter a retrieved attachment page link.
    1595      *
    1596      * @since 2.7.0
    1597      *
    1598      * @param string      $link_html The page link HTML output.
    1599      * @param int         $id        Post ID.
    1600      * @param string      $size      Image size. Default 'thumbnail'.
    1601      * @param bool        $permalink Whether to add permalink to image. Default false.
    1602      * @param bool        $icon      Whether to include an icon. Default false.
    1603      * @param string|bool $text      If string, will be link text. Default false.
    1604      */
    1605     return apply_filters( 'wp_get_attachment_link', "<a href='$url'>$link_text</a>", $id, $size, $permalink, $icon, $text );
    1606 }
    1607 
    1608 /**
    1609  * Wrap attachment in paragraph tag before content.
    1610  *
    1611  * @since 2.0.0
    1612  *
    1613  * @param string $content
    1614  * @return string
    1615  */
    1616 function prepend_attachment($content) {
    1617     $post = get_post();
    1618 
    1619     if ( empty($post->post_type) || $post->post_type != 'attachment' )
    1620         return $content;
    1621 
    1622     if ( wp_attachment_is( 'video', $post ) ) {
    1623         $meta = wp_get_attachment_metadata( get_the_ID() );
    1624         $atts = array( 'src' => wp_get_attachment_url() );
    1625         if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
    1626             $atts['width'] = (int) $meta['width'];
    1627             $atts['height'] = (int) $meta['height'];
    1628         }
    1629         if ( has_post_thumbnail() ) {
    1630             $atts['poster'] = wp_get_attachment_url( get_post_thumbnail_id() );
    1631         }
    1632         $p = wp_video_shortcode( $atts );
    1633     } elseif ( wp_attachment_is( 'audio', $post ) ) {
    1634         $p = wp_audio_shortcode( array( 'src' => wp_get_attachment_url() ) );
    1635     } else {
    1636         $p = '<p class="attachment">';
    1637         // show the medium sized image representation of the attachment if available, and link to the raw file
    1638         $p .= wp_get_attachment_link(0, 'medium', false);
    1639         $p .= '</p>';
    1640     }
    1641 
    1642     /**
    1643      * Filter the attachment markup to be prepended to the post content.
    1644      *
    1645      * @since 2.0.0
    1646      *
    1647      * @see prepend_attachment()
    1648      *
    1649      * @param string $p The attachment HTML output.
    1650      */
    1651     $p = apply_filters( 'prepend_attachment', $p );
    1652 
    1653     return "$p\n$content";
    1654 }
    1655 
    1656 //
    1657 // Misc
    1658 //
    1659 
    1660 /**
    1661  * Retrieve protected post password form content.
    1662  *
    1663  * @since 1.0.0
    1664  *
    1665  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
    1666  * @return string HTML content for password form for password protected post.
    1667  */
    1668 function get_the_password_form( $post = 0 ) {
    1669     $post = get_post( $post );
    1670     $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
    1671     $output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
    1672     <p>' . __( 'This content is password protected. To view it please enter your password below:' ) . '</p>
    1673     <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>
    1674     ';
    1675 
    1676     /**
    1677      * Filter the HTML output for the protected post password form.
    1678      *
    1679      * If modifying the password field, please note that the core database schema
    1680      * limits the password field to 20 characters regardless of the value of the
    1681      * size attribute in the form input.
    1682      *
    1683      * @since 2.7.0
    1684      *
    1685      * @param string $output The password form HTML output.
    1686      */
    1687     return apply_filters( 'the_password_form', $output );
    1688 }
    1689 
    1690 /**
    1691  * Whether currently in a page template.
    1692  *
    1693  * This template tag allows you to determine if you are in a page template.
    1694  * You can optionally provide a template name or array of template names
    1695  * and then the check will be specific to that template.
    1696  *
    1697  * @since 2.5.0
    1698  * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates.
    1699  *
    1700  * @param string|array $template The specific template name or array of templates to match.
    1701  * @return bool True on success, false on failure.
    1702  */
    1703 function is_page_template( $template = '' ) {
    1704     if ( ! is_page() )
    1705         return false;
    1706 
    1707     $page_template = get_page_template_slug( get_queried_object_id() );
    1708 
    1709     if ( empty( $template ) )
    1710         return (bool) $page_template;
    1711 
    1712     if ( $template == $page_template )
    1713         return true;
    1714 
    1715     if ( is_array( $template ) ) {
    1716         if ( ( in_array( 'default', $template, true ) && ! $page_template )
    1717             || in_array( $page_template, $template, true )
    1718         ) {
    1719             return true;
    1720         }
    1721     }
    1722 
    1723     return ( 'default' === $template && ! $page_template );
    1724 }
    1725 
    1726 /**
    1727  * Get the specific template name for a page.
    1728  *
    1729  * @since 3.4.0
    1730  *
    1731  * @param int $post_id Optional. The page ID to check. Defaults to the current post, when used in the loop.
    1732  * @return string|false Page template filename. Returns an empty string when the default page template
    1733  *  is in use. Returns false if the post is not a page.
    1734  */
    1735 function get_page_template_slug( $post_id = null ) {
    1736     $post = get_post( $post_id );
    1737     if ( ! $post || 'page' != $post->post_type )
    1738         return false;
    1739     $template = get_post_meta( $post->ID, '_wp_page_template', true );
    1740     if ( ! $template || 'default' == $template )
    1741         return '';
    1742     return $template;
    1743 }
    1744 
    1745 /**
    1746  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
    1747  *
    1748  * @since 2.6.0
    1749  *
    1750  * @param int|object $revision Revision ID or revision object.
    1751  * @param bool       $link     Optional, default is true. Link to revisions's page?
    1752  * @return string|false i18n formatted datetimestamp or localized 'Current Revision'.
    1753  */
    1754 function wp_post_revision_title( $revision, $link = true ) {
    1755     if ( !$revision = get_post( $revision ) )
    1756         return $revision;
    1757 
    1758     if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
    1759         return false;
    1760 
    1761     /* translators: revision date format, see http://php.net/date */
    1762     $datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
    1763     /* translators: 1: date */
    1764     $autosavef = _x( '%1$s [Autosave]', 'post revision title extra' );
    1765     /* translators: 1: date */
    1766     $currentf  = _x( '%1$s [Current Revision]', 'post revision title extra' );
    1767 
    1768     $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
    1769     if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
    1770         $date = "<a href='$link'>$date</a>";
    1771 
    1772     if ( !wp_is_post_revision( $revision ) )
    1773         $date = sprintf( $currentf, $date );
    1774     elseif ( wp_is_post_autosave( $revision ) )
    1775         $date = sprintf( $autosavef, $date );
    1776 
    1777     return $date;
    1778 }
    1779 
    1780 /**
    1781  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
    1782  *
    1783  * @since 3.6.0
    1784  *
    1785  * @param int|object $revision Revision ID or revision object.
    1786  * @param bool       $link     Optional, default is true. Link to revisions's page?
    1787  * @return string|false gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'.
    1788  */
    1789 function wp_post_revision_title_expanded( $revision, $link = true ) {
    1790     if ( !$revision = get_post( $revision ) )
    1791         return $revision;
    1792 
    1793     if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
    1794         return false;
    1795 
    1796     $author = get_the_author_meta( 'display_name', $revision->post_author );
    1797     /* translators: revision date format, see http://php.net/date */
    1798     $datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
    1799 
    1800     $gravatar = get_avatar( $revision->post_author, 24 );
    1801 
    1802     $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
    1803     if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
    1804         $date = "<a href='$link'>$date</a>";
    1805 
    1806     $revision_date_author = sprintf(
    1807         /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
    1808         _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
    1809         $gravatar,
    1810         $author,
    1811         human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
    1812         $date
    1813     );
    1814 
    1815     $autosavef = __( '%1$s [Autosave]' );
    1816     $currentf  = __( '%1$s [Current Revision]' );
    1817 
    1818     if ( !wp_is_post_revision( $revision ) )
    1819         $revision_date_author = sprintf( $currentf, $revision_date_author );
    1820     elseif ( wp_is_post_autosave( $revision ) )
    1821         $revision_date_author = sprintf( $autosavef, $revision_date_author );
    1822 
    1823     return $revision_date_author;
    1824 }
    1825 
    1826 /**
    1827  * Display list of a post's revisions.
    1828  *
    1829  * Can output either a UL with edit links or a TABLE with diff interface, and
    1830  * restore action links.
    1831  *
    1832  * @since 2.6.0
    1833  *
    1834  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
    1835  * @param string      $type    'all' (default), 'revision' or 'autosave'
    1836  */
    1837 function wp_list_post_revisions( $post_id = 0, $type = 'all' ) {
    1838     if ( ! $post = get_post( $post_id ) )
    1839         return;
    1840 
    1841     // $args array with (parent, format, right, left, type) deprecated since 3.6
    1842     if ( is_array( $type ) ) {
    1843         $type = ! empty( $type['type'] ) ? $type['type']  : $type;
    1844         _deprecated_argument( __FUNCTION__, '3.6' );
    1845     }
    1846 
    1847     if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
    1848         return;
    1849 
    1850     $rows = '';
    1851     foreach ( $revisions as $revision ) {
    1852         if ( ! current_user_can( 'read_post', $revision->ID ) )
    1853             continue;
    1854 
    1855         $is_autosave = wp_is_post_autosave( $revision );
    1856         if ( ( 'revision' === $type && $is_autosave ) || ( 'autosave' === $type && ! $is_autosave ) )
    1857             continue;
    1858 
    1859         $rows .= "\t<li>" . wp_post_revision_title_expanded( $revision ) . "</li>\n";
    1860     }
    1861 
    1862     echo "<div class='hide-if-js'><p>" . __( 'JavaScript must be enabled to use this feature.' ) . "</p></div>\n";
    1863 
    1864     echo "<ul class='post-revisions hide-if-no-js'>\n";
    1865     echo $rows;
    1866     echo "</ul>";
    1867 }
  • trunk/src/wp-includes/class-walker-page.php

    r34108 r34109  
    11<?php
    22/**
    3  * WordPress Post Template Functions.
    4  *
    5  * Gets content for the current post in the loop.
     3 * Post API: Walker_Page class
    64 *
    75 * @package WordPress
    86 * @subpackage Template
     7 * @since 4.4.0
    98 */
    10 
    11 /**
    12  * Display the ID of the current item in the WordPress Loop.
    13  *
    14  * @since 0.71
    15  */
    16 function the_ID() {
    17     echo get_the_ID();
    18 }
    19 
    20 /**
    21  * Retrieve the ID of the current item in the WordPress Loop.
    22  *
    23  * @since 2.1.0
    24  *
    25  * @return int|false The ID of the current item in the WordPress Loop. False if $post is not set.
    26  */
    27 function get_the_ID() {
    28     $post = get_post();
    29     return ! empty( $post ) ? $post->ID : false;
    30 }
    31 
    32 /**
    33  * Display or retrieve the current post title with optional content.
    34  *
    35  * @since 0.71
    36  *
    37  * @param string $before Optional. Content to prepend to the title.
    38  * @param string $after  Optional. Content to append to the title.
    39  * @param bool   $echo   Optional, default to true.Whether to display or return.
    40  * @return string|void String if $echo parameter is false.
    41  */
    42 function the_title( $before = '', $after = '', $echo = true ) {
    43     $title = get_the_title();
    44 
    45     if ( strlen($title) == 0 )
    46         return;
    47 
    48     $title = $before . $title . $after;
    49 
    50     if ( $echo )
    51         echo $title;
    52     else
    53         return $title;
    54 }
    55 
    56 /**
    57  * Sanitize the current title when retrieving or displaying.
    58  *
    59  * Works like {@link 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.
    61  *
    62  * The title before it is displayed will have the tags stripped and {@link
    63  * esc_attr()} before it is passed to the user or displayed. The default
    64  * as with {@link the_title()}, is to display the title.
    65  *
    66  * @since 2.3.0
    67  *
    68  * @param string|array $args {
    69  *     Title attribute arguments. Optional.
    70  *
    71  *     @type string  $before Markup to prepend 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.
    74  *     @type WP_Post $post   Current post object to retrieve the title for.
    75  * }
    76  * @return string|void String when echo is false.
    77  */
    78 function the_title_attribute( $args = '' ) {
    79     $defaults = array( 'before' => '', 'after' =>  '', 'echo' => true, 'post' => get_post() );
    80     $r = wp_parse_args( $args, $defaults );
    81 
    82     $title = get_the_title( $r['post'] );
    83 
    84     if ( strlen( $title ) == 0 ) {
    85         return;
    86     }
    87 
    88     $title = $r['before'] . $title . $r['after'];
    89     $title = esc_attr( strip_tags( $title ) );
    90 
    91     if ( $r['echo'] ) {
    92         echo $title;
    93     } else {
    94         return $title;
    95     }
    96 }
    97 
    98 /**
    99  * Retrieve post title.
    100  *
    101  * If the post is protected and the visitor is not an admin, then "Protected"
    102  * will be displayed before the post title. If the post is private, then
    103  * "Private" will be located before the post title.
    104  *
    105  * @since 0.71
    106  *
    107  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
    108  * @return string
    109  */
    110 function get_the_title( $post = 0 ) {
    111     $post = get_post( $post );
    112 
    113     $title = isset( $post->post_title ) ? $post->post_title : '';
    114     $id = isset( $post->ID ) ? $post->ID : 0;
    115 
    116     if ( ! is_admin() ) {
    117         if ( ! empty( $post->post_password ) ) {
    118 
    119             /**
    120              * Filter the text prepended to the post title for protected posts.
    121              *
    122              * The filter is only applied on the front end.
    123              *
    124              * @since 2.8.0
    125              *
    126              * @param string  $prepend Text displayed before the post title.
    127              *                         Default 'Protected: %s'.
    128              * @param WP_Post $post    Current post object.
    129              */
    130             $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ), $post );
    131             $title = sprintf( $protected_title_format, $title );
    132         } elseif ( isset( $post->post_status ) && 'private' == $post->post_status ) {
    133 
    134             /**
    135              * Filter the text prepended to the post title of private posts.
    136              *
    137              * The filter is only applied on the front end.
    138              *
    139              * @since 2.8.0
    140              *
    141              * @param string  $prepend Text displayed before the post title.
    142              *                         Default 'Private: %s'.
    143              * @param WP_Post $post    Current post object.
    144              */
    145             $private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ), $post );
    146             $title = sprintf( $private_title_format, $title );
    147         }
    148     }
    149 
    150     /**
    151      * Filter the post title.
    152      *
    153      * @since 0.71
    154      *
    155      * @param string $title The post title.
    156      * @param int    $id    The post ID.
    157      */
    158     return apply_filters( 'the_title', $title, $id );
    159 }
    160 
    161 /**
    162  * Display the Post Global Unique Identifier (guid).
    163  *
    164  * 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
    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 $id Optional. Post ID or post object.
    173  */
    174 function the_guid( $id = 0 ) {
    175     /**
    176      * Filter the escaped Global Unique Identifier (guid) of the post.
    177      *
    178      * @since 4.2.0
    179      *
    180      * @see get_the_guid()
    181      *
    182      * @param string $post_guid Escaped Global Unique Identifier (guid) of the post.
    183      */
    184     echo apply_filters( 'the_guid', get_the_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 }
    211 
    212 /**
    213  * Display the post content.
    214  *
    215  * @since 0.71
    216  *
    217  * @param string $more_link_text Optional. Content for when there is more text.
    218  * @param bool   $strip_teaser   Optional. Strip teaser content before the more text. Default is false.
    219  */
    220 function the_content( $more_link_text = null, $strip_teaser = false) {
    221     $content = get_the_content( $more_link_text, $strip_teaser );
    222 
    223     /**
    224      * Filter the post content.
    225      *
    226      * @since 0.71
    227      *
    228      * @param string $content Content of the current post.
    229      */
    230     $content = apply_filters( 'the_content', $content );
    231     $content = str_replace( ']]>', ']]&gt;', $content );
    232     echo $content;
    233 }
    234 
    235 /**
    236  * Retrieve the post content.
    237  *
    238  * @since 0.71
    239  *
    240  * @global int   $page
    241  * @global int   $more
    242  * @global bool  $preview
    243  * @global array $pages
    244  * @global int   $multipage
    245  *
    246  * @param string $more_link_text Optional. Content for when there is more text.
    247  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
    248  * @return string
    249  */
    250 function get_the_content( $more_link_text = null, $strip_teaser = false ) {
    251     global $page, $more, $preview, $pages, $multipage;
    252 
    253     $post = get_post();
    254 
    255     if ( null === $more_link_text )
    256         $more_link_text = __( '(more&hellip;)' );
    257 
    258     $output = '';
    259     $has_teaser = false;
    260 
    261     // If post password required and it doesn't match the cookie.
    262     if ( post_password_required( $post ) )
    263         return get_the_password_form( $post );
    264 
    265     if ( $page > count( $pages ) ) // if the requested page doesn't exist
    266         $page = count( $pages ); // give them the highest numbered page that DOES exist
    267 
    268     $content = $pages[$page - 1];
    269     if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) {
    270         $content = explode( $matches[0], $content, 2 );
    271         if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) )
    272             $more_link_text = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );
    273 
    274         $has_teaser = true;
    275     } else {
    276         $content = array( $content );
    277     }
    278 
    279     if ( false !== strpos( $post->post_content, '<!--noteaser-->' ) && ( ! $multipage || $page == 1 ) )
    280         $strip_teaser = true;
    281 
    282     $teaser = $content[0];
    283 
    284     if ( $more && $strip_teaser && $has_teaser )
    285         $teaser = '';
    286 
    287     $output .= $teaser;
    288 
    289     if ( count( $content ) > 1 ) {
    290         if ( $more ) {
    291             $output .= '<span id="more-' . $post->ID . '"></span>' . $content[1];
    292         } else {
    293             if ( ! empty( $more_link_text ) )
    294 
    295                 /**
    296                  * Filter the Read More link text.
    297                  *
    298                  * @since 2.8.0
    299                  *
    300                  * @param string $more_link_element Read More link element.
    301                  * @param string $more_link_text    Read More text.
    302                  */
    303                 $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-{$post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text );
    304             $output = force_balance_tags( $output );
    305         }
    306     }
    307 
    308     if ( $preview ) // Preview fix for JavaScript bug with foreign languages.
    309         $output =   preg_replace_callback( '/\%u([0-9A-F]{4})/', '_convert_urlencoded_to_entities', $output );
    310 
    311     return $output;
    312 }
    313 
    314 /**
    315  * Preview fix for JavaScript bug with foreign languages.
    316  *
    317  * @since 3.1.0
    318  * @access private
    319  * @param array $match Match array from preg_replace_callback
    320  * @return string
    321  */
    322 function _convert_urlencoded_to_entities( $match ) {
    323     return '&#' . base_convert( $match[1], 16, 10 ) . ';';
    324 }
    325 
    326 /**
    327  * Display the post excerpt.
    328  *
    329  * @since 0.71
    330  */
    331 function the_excerpt() {
    332 
    333     /**
    334      * Filter the displayed post excerpt.
    335      *
    336      * @since 0.71
    337      *
    338      * @see get_the_excerpt()
    339      *
    340      * @param string $post_excerpt The post excerpt.
    341      */
    342     echo apply_filters( 'the_excerpt', get_the_excerpt() );
    343 }
    344 
    345 /**
    346  * Retrieve the post excerpt.
    347  *
    348  * @since 0.71
    349  *
    350  * @param mixed $deprecated Not used.
    351  * @return string
    352  */
    353 function get_the_excerpt( $deprecated = '' ) {
    354     if ( !empty( $deprecated ) )
    355         _deprecated_argument( __FUNCTION__, '2.3' );
    356 
    357     $post = get_post();
    358     if ( empty( $post ) ) {
    359         return '';
    360     }
    361 
    362     if ( post_password_required() ) {
    363         return __( 'There is no excerpt because this is a protected post.' );
    364     }
    365 
    366     /**
    367      * Filter the retrieved post excerpt.
    368      *
    369      * @since 1.2.0
    370      *
    371      * @param string $post_excerpt The post excerpt.
    372      */
    373     return apply_filters( 'get_the_excerpt', $post->post_excerpt );
    374 }
    375 
    376 /**
    377  * Whether post has excerpt.
    378  *
    379  * @since 2.3.0
    380  *
    381  * @param int|WP_Post $id Optional. Post ID or post object.
    382  * @return bool
    383  */
    384 function has_excerpt( $id = 0 ) {
    385     $post = get_post( $id );
    386     return ( !empty( $post->post_excerpt ) );
    387 }
    388 
    389 /**
    390  * Display the classes for the post div.
    391  *
    392  * @since 2.7.0
    393  *
    394  * @param string|array $class One or more classes to add to the class list.
    395  * @param int|WP_Post $post_id Optional. Post ID or post object.
    396  */
    397 function post_class( $class = '', $post_id = null ) {
    398     // Separates classes with a single space, collates classes for post DIV
    399     echo 'class="' . join( ' ', get_post_class( $class, $post_id ) ) . '"';
    400 }
    401 
    402 /**
    403  * Retrieve the classes for the post div as an array.
    404  *
    405  * The class names are many. If the post is a sticky, then the 'sticky'
    406  * class name. The class 'hentry' is always added to each post. If the post has a
    407  * post thumbnail, 'has-post-thumbnail' is added as a class. For each taxonomy that
    408  * the post belongs to, a class will be added of the format '{$taxonomy}-{$slug}' -
    409  * eg 'category-foo' or 'my_custom_taxonomy-bar'. The 'post_tag' taxonomy is a special
    410  * case; the class has the 'tag-' prefix instead of 'post_tag-'. All classes are
    411  * passed through the filter, 'post_class' with the list of classes, followed by
    412  * $class parameter value, with the post ID as the last parameter.
    413  *
    414  * @since 2.7.0
    415  * @since 4.2.0 Custom taxonomy classes were added.
    416  *
    417  * @param string|array $class   One or more classes to add to the class list.
    418  * @param int|WP_Post  $post_id Optional. Post ID or post object.
    419  * @return array Array of classes.
    420  */
    421 function get_post_class( $class = '', $post_id = null ) {
    422     $post = get_post( $post_id );
    423 
    424     $classes = array();
    425 
    426     if ( $class ) {
    427         if ( ! is_array( $class ) ) {
    428             $class = preg_split( '#\s+#', $class );
    429         }
    430         $classes = array_map( 'esc_attr', $class );
    431     }
    432 
    433     if ( ! $post ) {
    434         return $classes;
    435     }
    436 
    437     $classes[] = 'post-' . $post->ID;
    438     if ( ! is_admin() )
    439         $classes[] = $post->post_type;
    440     $classes[] = 'type-' . $post->post_type;
    441     $classes[] = 'status-' . $post->post_status;
    442 
    443     // Post Format
    444     if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
    445         $post_format = get_post_format( $post->ID );
    446 
    447         if ( $post_format && !is_wp_error($post_format) )
    448             $classes[] = 'format-' . sanitize_html_class( $post_format );
    449         else
    450             $classes[] = 'format-standard';
    451     }
    452 
    453     // Post requires password
    454     if ( post_password_required( $post->ID ) ) {
    455         $classes[] = 'post-password-required';
    456     // Post thumbnails
    457     } elseif ( ! is_attachment( $post ) && current_theme_supports( 'post-thumbnails' ) && has_post_thumbnail( $post->ID ) ) {
    458         $classes[] = 'has-post-thumbnail';
    459     }
    460 
    461     // sticky for Sticky Posts
    462     if ( is_sticky( $post->ID ) ) {
    463         if ( is_home() && ! is_paged() ) {
    464             $classes[] = 'sticky';
    465         } elseif ( is_admin() ) {
    466             $classes[] = 'status-sticky';
    467         }
    468     }
    469 
    470     // hentry for hAtom compliance
    471     $classes[] = 'hentry';
    472 
    473     // All public taxonomies
    474     $taxonomies = get_taxonomies( array( 'public' => true ) );
    475     foreach ( (array) $taxonomies as $taxonomy ) {
    476         if ( is_object_in_taxonomy( $post->post_type, $taxonomy ) ) {
    477             foreach ( (array) get_the_terms( $post->ID, $taxonomy ) as $term ) {
    478                 if ( empty( $term->slug ) ) {
    479                     continue;
    480                 }
    481 
    482                 $term_class = sanitize_html_class( $term->slug, $term->term_id );
    483                 if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) {
    484                     $term_class = $term->term_id;
    485                 }
    486 
    487                 // 'post_tag' uses the 'tag' prefix for backward compatibility.
    488                 if ( 'post_tag' == $taxonomy ) {
    489                     $classes[] = 'tag-' . $term_class;
    490                 } else {
    491                     $classes[] = sanitize_html_class( $taxonomy . '-' . $term_class, $taxonomy . '-' . $term->term_id );
    492                 }
    493             }
    494         }
    495     }
    496 
    497     $classes = array_map( 'esc_attr', $classes );
    498 
    499     /**
    500      * Filter the list of CSS classes for the current post.
    501      *
    502      * @since 2.7.0
    503      *
    504      * @param array  $classes An array of post classes.
    505      * @param string $class   A comma-separated list of additional classes added to the post.
    506      * @param int    $post_id The post ID.
    507      */
    508     $classes = apply_filters( 'post_class', $classes, $class, $post->ID );
    509 
    510     return array_unique( $classes );
    511 }
    512 
    513 /**
    514  * Display the classes for the body element.
    515  *
    516  * @since 2.8.0
    517  *
    518  * @param string|array $class One or more classes to add to the class list.
    519  */
    520 function body_class( $class = '' ) {
    521     // Separates classes with a single space, collates classes for body element
    522     echo 'class="' . join( ' ', get_body_class( $class ) ) . '"';
    523 }
    524 
    525 /**
    526  * Retrieve the classes for the body element as an array.
    527  *
    528  * @since 2.8.0
    529  *
    530  * @global WP_Query $wp_query
    531  * @global wpdb     $wpdb
    532  *
    533  * @param string|array $class One or more classes to add to the class list.
    534  * @return array Array of classes.
    535  */
    536 function get_body_class( $class = '' ) {
    537     global $wp_query, $wpdb;
    538 
    539     $classes = array();
    540 
    541     if ( is_rtl() )
    542         $classes[] = 'rtl';
    543 
    544     if ( is_front_page() )
    545         $classes[] = 'home';
    546     if ( is_home() )
    547         $classes[] = 'blog';
    548     if ( is_archive() )
    549         $classes[] = 'archive';
    550     if ( is_date() )
    551         $classes[] = 'date';
    552     if ( is_search() ) {
    553         $classes[] = 'search';
    554         $classes[] = $wp_query->posts ? 'search-results' : 'search-no-results';
    555     }
    556     if ( is_paged() )
    557         $classes[] = 'paged';
    558     if ( is_attachment() )
    559         $classes[] = 'attachment';
    560     if ( is_404() )
    561         $classes[] = 'error404';
    562 
    563     if ( is_single() ) {
    564         $post_id = $wp_query->get_queried_object_id();
    565         $post = $wp_query->get_queried_object();
    566 
    567         $classes[] = 'single';
    568         if ( isset( $post->post_type ) ) {
    569             $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id);
    570             $classes[] = 'postid-' . $post_id;
    571 
    572             // Post Format
    573             if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
    574                 $post_format = get_post_format( $post->ID );
    575 
    576                 if ( $post_format && !is_wp_error($post_format) )
    577                     $classes[] = 'single-format-' . sanitize_html_class( $post_format );
    578                 else
    579                     $classes[] = 'single-format-standard';
    580             }
    581         }
    582 
    583         if ( is_attachment() ) {
    584             $mime_type = get_post_mime_type($post_id);
    585             $mime_prefix = array( 'application/', 'image/', 'text/', 'audio/', 'video/', 'music/' );
    586             $classes[] = 'attachmentid-' . $post_id;
    587             $classes[] = 'attachment-' . str_replace( $mime_prefix, '', $mime_type );
    588         }
    589     } elseif ( is_archive() ) {
    590         if ( is_post_type_archive() ) {
    591             $classes[] = 'post-type-archive';
    592             $post_type = get_query_var( 'post_type' );
    593             if ( is_array( $post_type ) )
    594                 $post_type = reset( $post_type );
    595             $classes[] = 'post-type-archive-' . sanitize_html_class( $post_type );
    596         } elseif ( is_author() ) {
    597             $author = $wp_query->get_queried_object();
    598             $classes[] = 'author';
    599             if ( isset( $author->user_nicename ) ) {
    600                 $classes[] = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID );
    601                 $classes[] = 'author-' . $author->ID;
    602             }
    603         } elseif ( is_category() ) {
    604             $cat = $wp_query->get_queried_object();
    605             $classes[] = 'category';
    606             if ( isset( $cat->term_id ) ) {
    607                 $cat_class = sanitize_html_class( $cat->slug, $cat->term_id );
    608                 if ( is_numeric( $cat_class ) || ! trim( $cat_class, '-' ) ) {
    609                     $cat_class = $cat->term_id;
    610                 }
    611 
    612                 $classes[] = 'category-' . $cat_class;
    613                 $classes[] = 'category-' . $cat->term_id;
    614             }
    615         } elseif ( is_tag() ) {
    616             $tag = $wp_query->get_queried_object();
    617             $classes[] = 'tag';
    618             if ( isset( $tag->term_id ) ) {
    619                 $tag_class = sanitize_html_class( $tag->slug, $tag->term_id );
    620                 if ( is_numeric( $tag_class ) || ! trim( $tag_class, '-' ) ) {
    621                     $tag_class = $tag->term_id;
    622                 }
    623 
    624                 $classes[] = 'tag-' . $tag_class;
    625                 $classes[] = 'tag-' . $tag->term_id;
    626             }
    627         } elseif ( is_tax() ) {
    628             $term = $wp_query->get_queried_object();
    629             if ( isset( $term->term_id ) ) {
    630                 $term_class = sanitize_html_class( $term->slug, $term->term_id );
    631                 if ( is_numeric( $term_class ) || ! trim( $term_class, '-' ) ) {
    632                     $term_class = $term->term_id;
    633                 }
    634 
    635                 $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy );
    636                 $classes[] = 'term-' . $term_class;
    637                 $classes[] = 'term-' . $term->term_id;
    638             }
    639         }
    640     } elseif ( is_page() ) {
    641         $classes[] = 'page';
    642 
    643         $page_id = $wp_query->get_queried_object_id();
    644 
    645         $post = get_post($page_id);
    646 
    647         $classes[] = 'page-id-' . $page_id;
    648 
    649         if ( get_pages( array( 'parent' => $page_id, 'number' => 1 ) ) ) {
    650             $classes[] = 'page-parent';
    651         }
    652 
    653         if ( $post->post_parent ) {
    654             $classes[] = 'page-child';
    655             $classes[] = 'parent-pageid-' . $post->post_parent;
    656         }
    657         if ( is_page_template() ) {
    658             $classes[] = 'page-template';
    659 
    660             $template_slug  = get_page_template_slug( $page_id );
    661             $template_parts = explode( '/', $template_slug );
    662 
    663             foreach ( $template_parts as $part ) {
    664                 $classes[] = 'page-template-' . sanitize_html_class( str_replace( array( '.', '/' ), '-', basename( $part, '.php' ) ) );
    665             }
    666             $classes[] = 'page-template-' . sanitize_html_class( str_replace( '.', '-', $template_slug ) );
    667         } else {
    668             $classes[] = 'page-template-default';
    669         }
    670     }
    671 
    672     if ( is_user_logged_in() )
    673         $classes[] = 'logged-in';
    674 
    675     if ( is_admin_bar_showing() ) {
    676         $classes[] = 'admin-bar';
    677         $classes[] = 'no-customize-support';
    678     }
    679 
    680     if ( get_background_color() !== get_theme_support( 'custom-background', 'default-color' ) || get_background_image() )
    681         $classes[] = 'custom-background';
    682 
    683     $page = $wp_query->get( 'page' );
    684 
    685     if ( ! $page || $page < 2 )
    686         $page = $wp_query->get( 'paged' );
    687 
    688     if ( $page && $page > 1 && ! is_404() ) {
    689         $classes[] = 'paged-' . $page;
    690 
    691         if ( is_single() )
    692             $classes[] = 'single-paged-' . $page;
    693         elseif ( is_page() )
    694             $classes[] = 'page-paged-' . $page;
    695         elseif ( is_category() )
    696             $classes[] = 'category-paged-' . $page;
    697         elseif ( is_tag() )
    698             $classes[] = 'tag-paged-' . $page;
    699         elseif ( is_date() )
    700             $classes[] = 'date-paged-' . $page;
    701         elseif ( is_author() )
    702             $classes[] = 'author-paged-' . $page;
    703         elseif ( is_search() )
    704             $classes[] = 'search-paged-' . $page;
    705         elseif ( is_post_type_archive() )
    706             $classes[] = 'post-type-paged-' . $page;
    707     }
    708 
    709     if ( ! empty( $class ) ) {
    710         if ( !is_array( $class ) )
    711             $class = preg_split( '#\s+#', $class );
    712         $classes = array_merge( $classes, $class );
    713     } else {
    714         // Ensure that we always coerce class to being an array.
    715         $class = array();
    716     }
    717 
    718     $classes = array_map( 'esc_attr', $classes );
    719 
    720     /**
    721      * Filter the list of CSS body classes for the current post or page.
    722      *
    723      * @since 2.8.0
    724      *
    725      * @param array  $classes An array of body classes.
    726      * @param string $class   A comma-separated list of additional classes added to the body.
    727      */
    728     $classes = apply_filters( 'body_class', $classes, $class );
    729 
    730     return array_unique( $classes );
    731 }
    732 
    733 /**
    734  * Whether post requires password and correct password has been provided.
    735  *
    736  * @since 2.7.0
    737  *
    738  * @param int|WP_Post|null $post An optional post. Global $post used if not provided.
    739  * @return bool false if a password is not required or the correct password cookie is present, true otherwise.
    740  */
    741 function post_password_required( $post = null ) {
    742     $post = get_post($post);
    743 
    744     if ( empty( $post->post_password ) )
    745         return false;
    746 
    747     if ( ! isset( $_COOKIE['wp-postpass_' . COOKIEHASH] ) )
    748         return true;
    749 
    750     require_once ABSPATH . WPINC . '/class-phpass.php';
    751     $hasher = new PasswordHash( 8, true );
    752 
    753     $hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] );
    754     if ( 0 !== strpos( $hash, '$P$B' ) )
    755         return true;
    756 
    757     return ! $hasher->CheckPassword( $post->post_password, $hash );
    758 }
    759 
    760 //
    761 // Page Template Functions for usage in Themes
    762 //
    763 
    764 /**
    765  * The formatted output of a list of pages.
    766  *
    767  * Displays page links for paginated posts (i.e. includes the <!--nextpage-->.
    768  * Quicktag one or more times). This tag must be within The Loop.
    769  *
    770  * @since 1.2.0
    771  *
    772  * @global int $page
    773  * @global int $numpages
    774  * @global int $multipage
    775  * @global int $more
    776  *
    777  * @param string|array $args {
    778  *     Optional. Array or string of default arguments.
    779  *
    780  *     @type string       $before           HTML or text to prepend to each link. Default is `<p> Pages:`.
    781  *     @type string       $after            HTML or text to append to each link. Default is `</p>`.
    782  *     @type string       $link_before      HTML or text to prepend to each link, inside the `<a>` tag.
    783  *                                          Also prepended to the current item, which is not linked. Default empty.
    784  *     @type string       $link_after       HTML or text to append to each Pages link inside the `<a>` tag.
    785  *                                          Also appended to the current item, which is not linked. Default empty.
    786  *     @type string       $next_or_number   Indicates whether page numbers should be used. Valid values are number
    787  *                                          and next. Default is 'number'.
    788  *     @type string       $separator        Text between pagination links. Default is ' '.
    789  *     @type string       $nextpagelink     Link text for the next page link, if available. Default is 'Next Page'.
    790  *     @type string       $previouspagelink Link text for the previous page link, if available. Default is 'Previous Page'.
    791  *     @type string       $pagelink         Format string for page numbers. The % in the parameter string will be
    792  *                                          replaced with the page number, so 'Page %' generates "Page 1", "Page 2", etc.
    793  *                                          Defaults to '%', just the page number.
    794  *     @type int|bool     $echo             Whether to echo or not. Accepts 1|true or 0|false. Default 1|true.
    795  * }
    796  * @return string Formatted output in HTML.
    797  */
    798 function wp_link_pages( $args = '' ) {
    799     global $page, $numpages, $multipage, $more;
    800 
    801     $defaults = array(
    802         'before'           => '<p>' . __( 'Pages:' ),
    803         'after'            => '</p>',
    804         'link_before'      => '',
    805         'link_after'       => '',
    806         'next_or_number'   => 'number',
    807         'separator'        => ' ',
    808         'nextpagelink'     => __( 'Next page' ),
    809         'previouspagelink' => __( 'Previous page' ),
    810         'pagelink'         => '%',
    811         'echo'             => 1
    812     );
    813 
    814     $params = wp_parse_args( $args, $defaults );
    815 
    816     /**
    817      * Filter the arguments used in retrieving page links for paginated posts.
    818      *
    819      * @since 3.0.0
    820      *
    821      * @param array $params An array of arguments for page links for paginated posts.
    822      */
    823     $r = apply_filters( 'wp_link_pages_args', $params );
    824 
    825     $output = '';
    826     if ( $multipage ) {
    827         if ( 'number' == $r['next_or_number'] ) {
    828             $output .= $r['before'];
    829             for ( $i = 1; $i <= $numpages; $i++ ) {
    830                 $link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'];
    831                 if ( $i != $page || ! $more && 1 == $page ) {
    832                     $link = _wp_link_page( $i ) . $link . '</a>';
    833                 }
    834                 /**
    835                  * Filter the HTML output of individual page number links.
    836                  *
    837                  * @since 3.6.0
    838                  *
    839                  * @param string $link The page number HTML output.
    840                  * @param int    $i    Page number for paginated posts' page links.
    841                  */
    842                 $link = apply_filters( 'wp_link_pages_link', $link, $i );
    843 
    844                 // Use the custom links separator beginning with the second link.
    845                 $output .= ( 1 === $i ) ? ' ' : $r['separator'];
    846                 $output .= $link;
    847             }
    848             $output .= $r['after'];
    849         } elseif ( $more ) {
    850             $output .= $r['before'];
    851             $prev = $page - 1;
    852             if ( $prev > 0 ) {
    853                 $link = _wp_link_page( $prev ) . $r['link_before'] . $r['previouspagelink'] . $r['link_after'] . '</a>';
    854 
    855                 /** This filter is documented in wp-includes/post-template.php */
    856                 $output .= apply_filters( 'wp_link_pages_link', $link, $prev );
    857             }
    858             $next = $page + 1;
    859             if ( $next <= $numpages ) {
    860                 if ( $prev ) {
    861                     $output .= $r['separator'];
    862                 }
    863                 $link = _wp_link_page( $next ) . $r['link_before'] . $r['nextpagelink'] . $r['link_after'] . '</a>';
    864 
    865                 /** This filter is documented in wp-includes/post-template.php */
    866                 $output .= apply_filters( 'wp_link_pages_link', $link, $next );
    867             }
    868             $output .= $r['after'];
    869         }
    870     }
    871 
    872     /**
    873      * Filter the HTML output of page links for paginated posts.
    874      *
    875      * @since 3.6.0
    876      *
    877      * @param string $output HTML output of paginated posts' page links.
    878      * @param array  $args   An array of arguments.
    879      */
    880     $html = apply_filters( 'wp_link_pages', $output, $args );
    881 
    882     if ( $r['echo'] ) {
    883         echo $html;
    884     }
    885     return $html;
    886 }
    887 
    888 /**
    889  * Helper function for wp_link_pages().
    890  *
    891  * @since 3.1.0
    892  * @access private
    893  *
    894  * @global WP_Rewrite $wp_rewrite
    895  *
    896  * @param int $i Page number.
    897  * @return string Link.
    898  */
    899 function _wp_link_page( $i ) {
    900     global $wp_rewrite;
    901     $post = get_post();
    902 
    903     if ( 1 == $i ) {
    904         $url = get_permalink();
    905     } else {
    906         if ( '' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending')) )
    907             $url = add_query_arg( 'page', $i, get_permalink() );
    908         elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') == $post->ID )
    909             $url = trailingslashit(get_permalink()) . user_trailingslashit("$wp_rewrite->pagination_base/" . $i, 'single_paged');
    910         else
    911             $url = trailingslashit(get_permalink()) . user_trailingslashit($i, 'single_paged');
    912     }
    913 
    914     if ( is_preview() ) {
    915         $url = add_query_arg( array(
    916             'preview' => 'true'
    917         ), $url );
    918 
    919         if ( ( 'draft' !== $post->post_status ) && isset( $_GET['preview_id'], $_GET['preview_nonce'] ) ) {
    920             $url = add_query_arg( array(
    921                 'preview_id'    => wp_unslash( $_GET['preview_id'] ),
    922                 'preview_nonce' => wp_unslash( $_GET['preview_nonce'] )
    923             ), $url );
    924         }
    925     }
    926 
    927     return '<a href="' . esc_url( $url ) . '">';
    928 }
    929 
    930 //
    931 // Post-meta: Custom per-post fields.
    932 //
    933 
    934 /**
    935  * Retrieve post custom meta data field.
    936  *
    937  * @since 1.5.0
    938  *
    939  * @param string $key Meta data key name.
    940  * @return false|string|array Array of values or single value, if only one element exists. False will be returned if key does not exist.
    941  */
    942 function post_custom( $key = '' ) {
    943     $custom = get_post_custom();
    944 
    945     if ( !isset( $custom[$key] ) )
    946         return false;
    947     elseif ( 1 == count($custom[$key]) )
    948         return $custom[$key][0];
    949     else
    950         return $custom[$key];
    951 }
    952 
    953 /**
    954  * Display list of post custom fields.
    955  *
    956  * @internal This will probably change at some point...
    957  * @since 1.2.0
    958  */
    959 function the_meta() {
    960     if ( $keys = get_post_custom_keys() ) {
    961         echo "<ul class='post-meta'>\n";
    962         foreach ( (array) $keys as $key ) {
    963             $keyt = trim($key);
    964             if ( is_protected_meta( $keyt, 'post' ) )
    965                 continue;
    966             $values = array_map('trim', get_post_custom_values($key));
    967             $value = implode($values,', ');
    968 
    969             /**
    970              * Filter the HTML output of the li element in the post custom fields list.
    971              *
    972              * @since 2.2.0
    973              *
    974              * @param string $html  The HTML output for the li element.
    975              * @param string $key   Meta key.
    976              * @param string $value Meta value.
    977              */
    978             echo apply_filters( 'the_meta_key', "<li><span class='post-meta-key'>$key:</span> $value</li>\n", $key, $value );
    979         }
    980         echo "</ul>\n";
    981     }
    982 }
    983 
    984 //
    985 // Pages
    986 //
    987 
    988 /**
    989  * Retrieve or display list of pages as a dropdown (select list).
    990  *
    991  * @since 2.1.0
    992  * @since 4.2.0 The `$value_field` argument was added.
    993  * @since 4.3.0 The `$class` argument was added.
    994  *
    995  * @param array|string $args {
    996  *     Optional. Array or string of arguments to generate a pages drop-down element.
    997  *
    998  *     @type int          $depth                 Maximum depth. Default 0.
    999  *     @type int          $child_of              Page ID to retrieve child pages of. Default 0.
    1000  *     @type int|string   $selected              Value of the option that should be selected. Default 0.
    1001  *     @type bool|int     $echo                  Whether to echo or return the generated markup. Accepts 0, 1,
    1002  *                                               or their bool equivalents. Default 1.
    1003  *     @type string       $name                  Value for the 'name' attribute of the select element.
    1004  *                                               Default 'page_id'.
    1005  *     @type string       $id                    Value for the 'id' attribute of the select element.
    1006  *     @type string       $class                 Value for the 'class' attribute of the select element. Default: none.
    1007  *                                               Defaults to the value of `$name`.
    1008  *     @type string       $show_option_none      Text to display for showing no pages. Default empty (does not display).
    1009  *     @type string       $show_option_no_change Text to display for "no change" option. Default empty (does not display).
    1010  *     @type string       $option_none_value     Value to use when no page is selected. Default empty.
    1011  *     @type string       $value_field           Post field used to populate the 'value' attribute of the option
    1012  *                                               elements. Accepts any valid post field. Default 'ID'.
    1013  * }
    1014  * @return string HTML content, if not displaying.
    1015  */
    1016 function wp_dropdown_pages( $args = '' ) {
    1017     $defaults = array(
    1018         'depth' => 0, 'child_of' => 0,
    1019         'selected' => 0, 'echo' => 1,
    1020         'name' => 'page_id', 'id' => '',
    1021         'class' => '',
    1022         'show_option_none' => '', 'show_option_no_change' => '',
    1023         'option_none_value' => '',
    1024         'value_field' => 'ID',
    1025     );
    1026 
    1027     $r = wp_parse_args( $args, $defaults );
    1028 
    1029     $pages = get_pages( $r );
    1030     $output = '';
    1031     // Back-compat with old system where both id and name were based on $name argument
    1032     if ( empty( $r['id'] ) ) {
    1033         $r['id'] = $r['name'];
    1034     }
    1035 
    1036     if ( ! empty( $pages ) ) {
    1037         $class = '';
    1038         if ( ! empty( $r['class'] ) ) {
    1039             $class = " class='" . esc_attr( $r['class'] ) . "'";
    1040         }
    1041 
    1042         $output = "<select name='" . esc_attr( $r['name'] ) . "'" . $class . " id='" . esc_attr( $r['id'] ) . "'>\n";
    1043         if ( $r['show_option_no_change'] ) {
    1044             $output .= "\t<option value=\"-1\">" . $r['show_option_no_change'] . "</option>\n";
    1045         }
    1046         if ( $r['show_option_none'] ) {
    1047             $output .= "\t<option value=\"" . esc_attr( $r['option_none_value'] ) . '">' . $r['show_option_none'] . "</option>\n";
    1048         }
    1049         $output .= walk_page_dropdown_tree( $pages, $r['depth'], $r );
    1050         $output .= "</select>\n";
    1051     }
    1052 
    1053     /**
    1054      * Filter the HTML output of a list of pages as a drop down.
    1055      *
    1056      * @since 2.1.0
    1057      * @since 4.4.0 `$r` and `$pages` added as arguments.
    1058      *
    1059      * @param string $output HTML output for drop down list of pages.
    1060      * @param array  $r      The parsed arguments array.
    1061      * @param array  $pages  List of WP_Post objects returned by `get_pages()`
    1062      */
    1063     $html = apply_filters( 'wp_dropdown_pages', $output, $r, $pages );
    1064 
    1065     if ( $r['echo'] ) {
    1066         echo $html;
    1067     }
    1068     return $html;
    1069 }
    1070 
    1071 /**
    1072  * Retrieve or display list of pages in list (li) format.
    1073  *
    1074  * @since 1.5.0
    1075  *
    1076  * @see get_pages()
    1077  *
    1078  * @global WP_Query $wp_query
    1079  *
    1080  * @param array|string $args {
    1081  *     Array or string of arguments. Optional.
    1082  *
    1083  *     @type int    $child_of     Display only the sub-pages of a single page by ID. Default 0 (all pages).
    1084  *     @type string $authors      Comma-separated list of author IDs. Default empty (all authors).
    1085  *     @type string $date_format  PHP date format to use for the listed pages. Relies on the 'show_date' parameter.
    1086  *                                Default is the value of 'date_format' option.
    1087  *     @type int    $depth        Number of levels in the hierarchy of pages to include in the generated list.
    1088  *                                Accepts -1 (any depth), 0 (all pages), 1 (top-level pages only), and n (pages to
    1089  *                                the given n depth). Default 0.
    1090  *     @type bool   $echo         Whether or not to echo the list of pages. Default true.
    1091  *     @type string $exclude      Comma-separated list of page IDs to exclude. Default empty.
    1092  *     @type array  $include      Comma-separated list of page IDs to include. Default empty.
    1093  *     @type string $link_after   Text or HTML to follow the page link label. Default null.
    1094  *     @type string $link_before  Text or HTML to precede the page link label. Default null.
    1095  *     @type string $post_type    Post type to query for. Default 'page'.
    1096  *     @type string $post_status  Comma-separated list of post statuses to include. Default 'publish'.
    1097  *     @type string $show_date    Whether to display the page publish or modified date for each page. Accepts
    1098  *                                'modified' or any other value. An empty value hides the date. Default empty.
    1099  *     @type string $sort_column  Comma-separated list of column names to sort the pages by. Accepts 'post_author',
    1100  *                                'post_date', 'post_title', 'post_name', 'post_modified', 'post_modified_gmt',
    1101  *                                'menu_order', 'post_parent', 'ID', 'rand', or 'comment_count'. Default 'post_title'.
    1102  *     @type string $title_li     List heading. Passing a null or empty value will result in no heading, and the list
    1103  *                                will not be wrapped with unordered list `<ul>` tags. Default 'Pages'.
    1104  *     @type Walker $walker       Walker instance to use for listing pages. Default empty (Walker_Page).
    1105  * }
    1106  * @return string|void HTML list of pages.
    1107  */
    1108 function wp_list_pages( $args = '' ) {
    1109     $defaults = array(
    1110         'depth' => 0, 'show_date' => '',
    1111         'date_format' => get_option( 'date_format' ),
    1112         'child_of' => 0, 'exclude' => '',
    1113         'title_li' => __( 'Pages' ), 'echo' => 1,
    1114         'authors' => '', 'sort_column' => 'menu_order, post_title',
    1115         'link_before' => '', 'link_after' => '', 'walker' => '',
    1116     );
    1117 
    1118     $r = wp_parse_args( $args, $defaults );
    1119 
    1120     $output = '';
    1121     $current_page = 0;
    1122 
    1123     // sanitize, mostly to keep spaces out
    1124     $r['exclude'] = preg_replace( '/[^0-9,]/', '', $r['exclude'] );
    1125 
    1126     // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array)
    1127     $exclude_array = ( $r['exclude'] ) ? explode( ',', $r['exclude'] ) : array();
    1128 
    1129     /**
    1130      * Filter the array of pages to exclude from the pages list.
    1131      *
    1132      * @since 2.1.0
    1133      *
    1134      * @param array $exclude_array An array of page IDs to exclude.
    1135      */
    1136     $r['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) );
    1137 
    1138     // Query pages.
    1139     $r['hierarchical'] = 0;
    1140     $pages = get_pages( $r );
    1141 
    1142     if ( ! empty( $pages ) ) {
    1143         if ( $r['title_li'] ) {
    1144             $output .= '<li class="pagenav">' . $r['title_li'] . '<ul>';
    1145         }
    1146         global $wp_query;
    1147         if ( is_page() || is_attachment() || $wp_query->is_posts_page ) {
    1148             $current_page = get_queried_object_id();
    1149         } elseif ( is_singular() ) {
    1150             $queried_object = get_queried_object();
    1151             if ( is_post_type_hierarchical( $queried_object->post_type ) ) {
    1152                 $current_page = $queried_object->ID;
    1153             }
    1154         }
    1155 
    1156         $output .= walk_page_tree( $pages, $r['depth'], $current_page, $r );
    1157 
    1158         if ( $r['title_li'] ) {
    1159             $output .= '</ul></li>';
    1160         }
    1161     }
    1162 
    1163     /**
    1164      * Filter the HTML output of the pages to list.
    1165      *
    1166      * @since 1.5.1
    1167      * @since 4.4.0 `$pages` added as arguments.
    1168      *
    1169      * @see wp_list_pages()
    1170      *
    1171      * @param string $output HTML output of the pages list.
    1172      * @param array  $r      An array of page-listing arguments.
    1173      * @param array  $pages  List of WP_Post objects returned by `get_pages()`
    1174      */
    1175     $html = apply_filters( 'wp_list_pages', $output, $r, $pages );
    1176 
    1177     if ( $r['echo'] ) {
    1178         echo $html;
    1179     } else {
    1180         return $html;
    1181     }
    1182 }
    1183 
    1184 /**
    1185  * Display or retrieve list of pages with optional home link.
    1186  *
    1187  * The arguments are listed below and part of the arguments are for {@link
    1188  * wp_list_pages()} function. Check that function for more info on those
    1189  * arguments.
    1190  *
    1191  * @since 2.7.0
    1192  *
    1193  * @param array|string $args {
    1194  *     Optional. Arguments to generate a page menu. See wp_list_pages() for additional arguments.
    1195  *
    1196  *     @type string          $sort_column How to short the list of pages. Accepts post column names.
    1197  *                                        Default 'menu_order, post_title'.
    1198  *     @type string          $menu_class  Class to use for the div ID containing the page list. Default 'menu'.
    1199  *     @type bool            $echo        Whether to echo the list or return it. Accepts true (echo) or false (return).
    1200  *                                        Default true.
    1201  *     @type string          $link_before The HTML or text to prepend to $show_home text. Default empty.
    1202  *     @type string          $link_after  The HTML or text to append to $show_home text. Default empty.
    1203  *     @type int|bool|string $show_home   Whether to display the link to the home page. Can just enter the text
    1204  *                                        you'd like shown for the home link. 1|true defaults to 'Home'.
    1205  * }
    1206  * @return string|void HTML menu
    1207  */
    1208 function wp_page_menu( $args = array() ) {
    1209     $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => '');
    1210     $args = wp_parse_args( $args, $defaults );
    1211 
    1212     /**
    1213      * Filter the arguments used to generate a page-based menu.
    1214      *
    1215      * @since 2.7.0
    1216      *
    1217      * @see wp_page_menu()
    1218      *
    1219      * @param array $args An array of page menu arguments.
    1220      */
    1221     $args = apply_filters( 'wp_page_menu_args', $args );
    1222 
    1223     $menu = '';
    1224 
    1225     $list_args = $args;
    1226 
    1227     // Show Home in the menu
    1228     if ( ! empty($args['show_home']) ) {
    1229         if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] )
    1230             $text = __('Home');
    1231         else
    1232             $text = $args['show_home'];
    1233         $class = '';
    1234         if ( is_front_page() && !is_paged() )
    1235             $class = 'class="current_page_item"';
    1236         $menu .= '<li ' . $class . '><a href="' . home_url( '/' ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
    1237         // If the front page is a page, add it to the exclude list
    1238         if (get_option('show_on_front') == 'page') {
    1239             if ( !empty( $list_args['exclude'] ) ) {
    1240                 $list_args['exclude'] .= ',';
    1241             } else {
    1242                 $list_args['exclude'] = '';
    1243             }
    1244             $list_args['exclude'] .= get_option('page_on_front');
    1245         }
    1246     }
    1247 
    1248     $list_args['echo'] = false;
    1249     $list_args['title_li'] = '';
    1250     $menu .= str_replace( array( "\r", "\n", "\t" ), '', wp_list_pages($list_args) );
    1251 
    1252     if ( $menu )
    1253         $menu = '<ul>' . $menu . '</ul>';
    1254 
    1255     $menu = '<div class="' . esc_attr($args['menu_class']) . '">' . $menu . "</div>\n";
    1256 
    1257     /**
    1258      * Filter the HTML output of a page-based menu.
    1259      *
    1260      * @since 2.7.0
    1261      *
    1262      * @see wp_page_menu()
    1263      *
    1264      * @param string $menu The HTML output.
    1265      * @param array  $args An array of arguments.
    1266      */
    1267     $menu = apply_filters( 'wp_page_menu', $menu, $args );
    1268     if ( $args['echo'] )
    1269         echo $menu;
    1270     else
    1271         return $menu;
    1272 }
    1273 
    1274 //
    1275 // Page helpers
    1276 //
    1277 
    1278 /**
    1279  * Retrieve HTML list content for page list.
    1280  *
    1281  * @uses Walker_Page to create HTML list content.
    1282  * @since 2.1.0
    1283  *
    1284  * @param array $pages
    1285  * @param int   $depth
    1286  * @param int   $current_page
    1287  * @param array $r
    1288  * @return string
    1289  */
    1290 function walk_page_tree( $pages, $depth, $current_page, $r ) {
    1291     if ( empty($r['walker']) )
    1292         $walker = new Walker_Page;
    1293     else
    1294         $walker = $r['walker'];
    1295 
    1296     foreach ( (array) $pages as $page ) {
    1297         if ( $page->post_parent )
    1298             $r['pages_with_children'][ $page->post_parent ] = true;
    1299     }
    1300 
    1301     $args = array($pages, $depth, $r, $current_page);
    1302     return call_user_func_array(array($walker, 'walk'), $args);
    1303 }
    1304 
    1305 /**
    1306  * Retrieve HTML dropdown (select) content for page list.
    1307  *
    1308  * @uses Walker_PageDropdown to create HTML dropdown content.
    1309  * @since 2.1.0
    1310  * @see Walker_PageDropdown::walk() for parameters and return description.
    1311  *
    1312  * @return string
    1313  */
    1314 function walk_page_dropdown_tree() {
    1315     $args = func_get_args();
    1316     if ( empty($args[2]['walker']) ) // the user's options are the third parameter
    1317         $walker = new Walker_PageDropdown;
    1318     else
    1319         $walker = $args[2]['walker'];
    1320 
    1321     return call_user_func_array(array($walker, 'walk'), $args);
    1322 }
    13239
    132410/**
     
    1467153
    1468154}
    1469 
    1470 /**
    1471  * Create HTML dropdown list of pages.
    1472  *
    1473  * @since 2.1.0
    1474  * @uses Walker
    1475  */
    1476 class Walker_PageDropdown extends Walker {
    1477     /**
    1478      * @see Walker::$tree_type
    1479      * @since 2.1.0
    1480      * @var string
    1481      */
    1482     public $tree_type = 'page';
    1483 
    1484     /**
    1485      * @see Walker::$db_fields
    1486      * @since 2.1.0
    1487      * @todo Decouple this
    1488      * @var array
    1489      */
    1490     public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
    1491 
    1492     /**
    1493      * @see Walker::start_el()
    1494      * @since 2.1.0
    1495      *
    1496      * @param string $output Passed by reference. Used to append additional content.
    1497      * @param object $page   Page data object.
    1498      * @param int    $depth  Depth of page in reference to parent pages. Used for padding.
    1499      * @param array  $args   Uses 'selected' argument for selected page to set selected HTML attribute for option
    1500      *                       element. Uses 'value_field' argument to fill "value" attribute. See {@see wp_dropdown_pages()}.
    1501      * @param int    $id
    1502      */
    1503     public function start_el( &$output, $page, $depth = 0, $args = array(), $id = 0 ) {
    1504         $pad = str_repeat('&nbsp;', $depth * 3);
    1505 
    1506         if ( ! isset( $args['value_field'] ) || ! isset( $page->{$args['value_field']} ) ) {
    1507             $args['value_field'] = 'ID';
    1508         }
    1509 
    1510         $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $page->{$args['value_field']} ) . "\"";
    1511         if ( $page->ID == $args['selected'] )
    1512             $output .= ' selected="selected"';
    1513         $output .= '>';
    1514 
    1515         $title = $page->post_title;
    1516         if ( '' === $title ) {
    1517             /* translators: %d: ID of a post */
    1518             $title = sprintf( __( '#%d (no title)' ), $page->ID );
    1519         }
    1520 
    1521         /**
    1522          * Filter the page title when creating an HTML drop-down list of pages.
    1523          *
    1524          * @since 3.1.0
    1525          *
    1526          * @param string $title Page title.
    1527          * @param object $page  Page data object.
    1528          */
    1529         $title = apply_filters( 'list_pages', $title, $page );
    1530         $output .= $pad . esc_html( $title );
    1531         $output .= "</option>\n";
    1532     }
    1533 }
    1534 
    1535 //
    1536 // Attachments
    1537 //
    1538 
    1539 /**
    1540  * Display an attachment page link using an image or icon.
    1541  *
    1542  * @since 2.0.0
    1543  *
    1544  * @param int|WP_Post $id Optional. Post ID or post object.
    1545  * @param bool        $fullsize     Optional, default is false. Whether to use full size.
    1546  * @param bool        $deprecated   Deprecated. Not used.
    1547  * @param bool        $permalink    Optional, default is false. Whether to include permalink.
    1548  */
    1549 function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $permalink = false ) {
    1550     if ( !empty( $deprecated ) )
    1551         _deprecated_argument( __FUNCTION__, '2.5' );
    1552 
    1553     if ( $fullsize )
    1554         echo wp_get_attachment_link($id, 'full', $permalink);
    1555     else
    1556         echo wp_get_attachment_link($id, 'thumbnail', $permalink);
    1557 }
    1558 
    1559 /**
    1560  * Retrieve an attachment page link using an image or icon, if possible.
    1561  *
    1562  * @since 2.5.0
    1563  * @since 4.4.0 The `$id` parameter can now accept either a post ID or `WP_Post` object.
    1564  *
    1565  * @param int|WP_Post  $id        Optional. Post ID or post object.
    1566  * @param string       $size      Optional, default is 'thumbnail'. Size of image, either array or string.
    1567  * @param bool         $permalink Optional, default is false. Whether to add permalink to image.
    1568  * @param bool         $icon      Optional, default is false. Whether to include icon.
    1569  * @param string|bool  $text      Optional, default is false. If string, then will be link text.
    1570  * @param array|string $attr      Optional. Array or string of attributes.
    1571  * @return string HTML content.
    1572  */
    1573 function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) {
    1574     $_post = get_post( $id );
    1575 
    1576     if ( empty( $_post ) || ( 'attachment' != $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) )
    1577         return __( 'Missing Attachment' );
    1578 
    1579     if ( $permalink )
    1580         $url = get_attachment_link( $_post->ID );
    1581 
    1582     if ( $text ) {
    1583         $link_text = $text;
    1584     } elseif ( $size && 'none' != $size ) {
    1585         $link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr );
    1586     } else {
    1587         $link_text = '';
    1588     }
    1589 
    1590     if ( trim( $link_text ) == '' )
    1591         $link_text = $_post->post_title;
    1592 
    1593     /**
    1594      * Filter a retrieved attachment page link.
    1595      *
    1596      * @since 2.7.0
    1597      *
    1598      * @param string      $link_html The page link HTML output.
    1599      * @param int         $id        Post ID.
    1600      * @param string      $size      Image size. Default 'thumbnail'.
    1601      * @param bool        $permalink Whether to add permalink to image. Default false.
    1602      * @param bool        $icon      Whether to include an icon. Default false.
    1603      * @param string|bool $text      If string, will be link text. Default false.
    1604      */
    1605     return apply_filters( 'wp_get_attachment_link', "<a href='$url'>$link_text</a>", $id, $size, $permalink, $icon, $text );
    1606 }
    1607 
    1608 /**
    1609  * Wrap attachment in paragraph tag before content.
    1610  *
    1611  * @since 2.0.0
    1612  *
    1613  * @param string $content
    1614  * @return string
    1615  */
    1616 function prepend_attachment($content) {
    1617     $post = get_post();
    1618 
    1619     if ( empty($post->post_type) || $post->post_type != 'attachment' )
    1620         return $content;
    1621 
    1622     if ( wp_attachment_is( 'video', $post ) ) {
    1623         $meta = wp_get_attachment_metadata( get_the_ID() );
    1624         $atts = array( 'src' => wp_get_attachment_url() );
    1625         if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
    1626             $atts['width'] = (int) $meta['width'];
    1627             $atts['height'] = (int) $meta['height'];
    1628         }
    1629         if ( has_post_thumbnail() ) {
    1630             $atts['poster'] = wp_get_attachment_url( get_post_thumbnail_id() );
    1631         }
    1632         $p = wp_video_shortcode( $atts );
    1633     } elseif ( wp_attachment_is( 'audio', $post ) ) {
    1634         $p = wp_audio_shortcode( array( 'src' => wp_get_attachment_url() ) );
    1635     } else {
    1636         $p = '<p class="attachment">';
    1637         // show the medium sized image representation of the attachment if available, and link to the raw file
    1638         $p .= wp_get_attachment_link(0, 'medium', false);
    1639         $p .= '</p>';
    1640     }
    1641 
    1642     /**
    1643      * Filter the attachment markup to be prepended to the post content.
    1644      *
    1645      * @since 2.0.0
    1646      *
    1647      * @see prepend_attachment()
    1648      *
    1649      * @param string $p The attachment HTML output.
    1650      */
    1651     $p = apply_filters( 'prepend_attachment', $p );
    1652 
    1653     return "$p\n$content";
    1654 }
    1655 
    1656 //
    1657 // Misc
    1658 //
    1659 
    1660 /**
    1661  * Retrieve protected post password form content.
    1662  *
    1663  * @since 1.0.0
    1664  *
    1665  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
    1666  * @return string HTML content for password form for password protected post.
    1667  */
    1668 function get_the_password_form( $post = 0 ) {
    1669     $post = get_post( $post );
    1670     $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID );
    1671     $output = '<form action="' . esc_url( site_url( 'wp-login.php?action=postpass', 'login_post' ) ) . '" class="post-password-form" method="post">
    1672     <p>' . __( 'This content is password protected. To view it please enter your password below:' ) . '</p>
    1673     <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>
    1674     ';
    1675 
    1676     /**
    1677      * Filter the HTML output for the protected post password form.
    1678      *
    1679      * If modifying the password field, please note that the core database schema
    1680      * limits the password field to 20 characters regardless of the value of the
    1681      * size attribute in the form input.
    1682      *
    1683      * @since 2.7.0
    1684      *
    1685      * @param string $output The password form HTML output.
    1686      */
    1687     return apply_filters( 'the_password_form', $output );
    1688 }
    1689 
    1690 /**
    1691  * Whether currently in a page template.
    1692  *
    1693  * This template tag allows you to determine if you are in a page template.
    1694  * You can optionally provide a template name or array of template names
    1695  * and then the check will be specific to that template.
    1696  *
    1697  * @since 2.5.0
    1698  * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates.
    1699  *
    1700  * @param string|array $template The specific template name or array of templates to match.
    1701  * @return bool True on success, false on failure.
    1702  */
    1703 function is_page_template( $template = '' ) {
    1704     if ( ! is_page() )
    1705         return false;
    1706 
    1707     $page_template = get_page_template_slug( get_queried_object_id() );
    1708 
    1709     if ( empty( $template ) )
    1710         return (bool) $page_template;
    1711 
    1712     if ( $template == $page_template )
    1713         return true;
    1714 
    1715     if ( is_array( $template ) ) {
    1716         if ( ( in_array( 'default', $template, true ) && ! $page_template )
    1717             || in_array( $page_template, $template, true )
    1718         ) {
    1719             return true;
    1720         }
    1721     }
    1722 
    1723     return ( 'default' === $template && ! $page_template );
    1724 }
    1725 
    1726 /**
    1727  * Get the specific template name for a page.
    1728  *
    1729  * @since 3.4.0
    1730  *
    1731  * @param int $post_id Optional. The page ID to check. Defaults to the current post, when used in the loop.
    1732  * @return string|false Page template filename. Returns an empty string when the default page template
    1733  *  is in use. Returns false if the post is not a page.
    1734  */
    1735 function get_page_template_slug( $post_id = null ) {
    1736     $post = get_post( $post_id );
    1737     if ( ! $post || 'page' != $post->post_type )
    1738         return false;
    1739     $template = get_post_meta( $post->ID, '_wp_page_template', true );
    1740     if ( ! $template || 'default' == $template )
    1741         return '';
    1742     return $template;
    1743 }
    1744 
    1745 /**
    1746  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
    1747  *
    1748  * @since 2.6.0
    1749  *
    1750  * @param int|object $revision Revision ID or revision object.
    1751  * @param bool       $link     Optional, default is true. Link to revisions's page?
    1752  * @return string|false i18n formatted datetimestamp or localized 'Current Revision'.
    1753  */
    1754 function wp_post_revision_title( $revision, $link = true ) {
    1755     if ( !$revision = get_post( $revision ) )
    1756         return $revision;
    1757 
    1758     if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
    1759         return false;
    1760 
    1761     /* translators: revision date format, see http://php.net/date */
    1762     $datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
    1763     /* translators: 1: date */
    1764     $autosavef = _x( '%1$s [Autosave]', 'post revision title extra' );
    1765     /* translators: 1: date */
    1766     $currentf  = _x( '%1$s [Current Revision]', 'post revision title extra' );
    1767 
    1768     $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
    1769     if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
    1770         $date = "<a href='$link'>$date</a>";
    1771 
    1772     if ( !wp_is_post_revision( $revision ) )
    1773         $date = sprintf( $currentf, $date );
    1774     elseif ( wp_is_post_autosave( $revision ) )
    1775         $date = sprintf( $autosavef, $date );
    1776 
    1777     return $date;
    1778 }
    1779 
    1780 /**
    1781  * Retrieve formatted date timestamp of a revision (linked to that revisions's page).
    1782  *
    1783  * @since 3.6.0
    1784  *
    1785  * @param int|object $revision Revision ID or revision object.
    1786  * @param bool       $link     Optional, default is true. Link to revisions's page?
    1787  * @return string|false gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'.
    1788  */
    1789 function wp_post_revision_title_expanded( $revision, $link = true ) {
    1790     if ( !$revision = get_post( $revision ) )
    1791         return $revision;
    1792 
    1793     if ( !in_array( $revision->post_type, array( 'post', 'page', 'revision' ) ) )
    1794         return false;
    1795 
    1796     $author = get_the_author_meta( 'display_name', $revision->post_author );
    1797     /* translators: revision date format, see http://php.net/date */
    1798     $datef = _x( 'F j, Y @ H:i:s', 'revision date format' );
    1799 
    1800     $gravatar = get_avatar( $revision->post_author, 24 );
    1801 
    1802     $date = date_i18n( $datef, strtotime( $revision->post_modified ) );
    1803     if ( $link && current_user_can( 'edit_post', $revision->ID ) && $link = get_edit_post_link( $revision->ID ) )
    1804         $date = "<a href='$link'>$date</a>";
    1805 
    1806     $revision_date_author = sprintf(
    1807         /* translators: post revision title: 1: author avatar, 2: author name, 3: time ago, 4: date */
    1808         _x( '%1$s %2$s, %3$s ago (%4$s)', 'post revision title' ),
    1809         $gravatar,
    1810         $author,
    1811         human_time_diff( strtotime( $revision->post_modified ), current_time( 'timestamp' ) ),
    1812         $date
    1813     );
    1814 
    1815     $autosavef = __( '%1$s [Autosave]' );
    1816     $currentf  = __( '%1$s [Current Revision]' );
    1817 
    1818     if ( !wp_is_post_revision( $revision ) )
    1819         $revision_date_author = sprintf( $currentf, $revision_date_author );
    1820     elseif ( wp_is_post_autosave( $revision ) )
    1821         $revision_date_author = sprintf( $autosavef, $revision_date_author );
    1822 
    1823     return $revision_date_author;
    1824 }
    1825 
    1826 /**
    1827  * Display list of a post's revisions.
    1828  *
    1829  * Can output either a UL with edit links or a TABLE with diff interface, and
    1830  * restore action links.
    1831  *
    1832  * @since 2.6.0
    1833  *
    1834  * @param int|WP_Post $post_id Optional. Post ID or WP_Post object. Default is global $post.
    1835  * @param string      $type    'all' (default), 'revision' or 'autosave'
    1836  */
    1837 function wp_list_post_revisions( $post_id = 0, $type = 'all' ) {
    1838     if ( ! $post = get_post( $post_id ) )
    1839         return;
    1840 
    1841     // $args array with (parent, format, right, left, type) deprecated since 3.6
    1842     if ( is_array( $type ) ) {
    1843         $type = ! empty( $type['type'] ) ? $type['type']  : $type;
    1844         _deprecated_argument( __FUNCTION__, '3.6' );
    1845     }
    1846 
    1847     if ( ! $revisions = wp_get_post_revisions( $post->ID ) )
    1848         return;
    1849 
    1850     $rows = '';
    1851     foreach ( $revisions as $revision ) {
    1852         if ( ! current_user_can( 'read_post', $revision->ID ) )
    1853             continue;
    1854 
    1855         $is_autosave = wp_is_post_autosave( $revision );
    1856         if ( ( 'revision' === $type && $is_autosave ) || ( 'autosave' === $type && ! $is_autosave ) )
    1857             continue;
    1858 
    1859         $rows .= "\t<li>" . wp_post_revision_title_expanded( $revision ) . "</li>\n";
    1860     }
    1861 
    1862     echo "<div class='hide-if-js'><p>" . __( 'JavaScript must be enabled to use this feature.' ) . "</p></div>\n";
    1863 
    1864     echo "<ul class='post-revisions hide-if-no-js'>\n";
    1865     echo $rows;
    1866     echo "</ul>";
    1867 }
  • trunk/src/wp-includes/post-template.php

    r34108 r34109  
    13221322}
    13231323
    1324 /**
    1325  * Create HTML list of pages.
    1326  *
    1327  * @since 2.1.0
    1328  * @uses Walker
    1329  */
    1330 class Walker_Page extends Walker {
    1331     /**
    1332      * @see Walker::$tree_type
    1333      * @since 2.1.0
    1334      * @var string
    1335      */
    1336     public $tree_type = 'page';
    1337 
    1338     /**
    1339      * @see Walker::$db_fields
    1340      * @since 2.1.0
    1341      * @todo Decouple this.
    1342      * @var array
    1343      */
    1344     public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
    1345 
    1346     /**
    1347      * @see Walker::start_lvl()
    1348      * @since 2.1.0
    1349      *
    1350      * @param string $output Passed by reference. Used to append additional content.
    1351      * @param int    $depth  Depth of page. Used for padding.
    1352      * @param array  $args
    1353      */
    1354     public function start_lvl( &$output, $depth = 0, $args = array() ) {
    1355         $indent = str_repeat("\t", $depth);
    1356         $output .= "\n$indent<ul class='children'>\n";
    1357     }
    1358 
    1359     /**
    1360      * @see Walker::end_lvl()
    1361      * @since 2.1.0
    1362      *
    1363      * @param string $output Passed by reference. Used to append additional content.
    1364      * @param int    $depth  Depth of page. Used for padding.
    1365      * @param array  $args
    1366      */
    1367     public function end_lvl( &$output, $depth = 0, $args = array() ) {
    1368         $indent = str_repeat("\t", $depth);
    1369         $output .= "$indent</ul>\n";
    1370     }
    1371 
    1372     /**
    1373      * @see Walker::start_el()
    1374      * @since 2.1.0
    1375      *
    1376      * @param string $output       Passed by reference. Used to append additional content.
    1377      * @param object $page         Page data object.
    1378      * @param int    $depth        Depth of page. Used for padding.
    1379      * @param int    $current_page Page ID.
    1380      * @param array  $args
    1381      */
    1382     public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
    1383         if ( $depth ) {
    1384             $indent = str_repeat( "\t", $depth );
    1385         } else {
    1386             $indent = '';
    1387         }
    1388 
    1389         $css_class = array( 'page_item', 'page-item-' . $page->ID );
    1390 
    1391         if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
    1392             $css_class[] = 'page_item_has_children';
    1393         }
    1394 
    1395         if ( ! empty( $current_page ) ) {
    1396             $_current_page = get_post( $current_page );
    1397             if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
    1398                 $css_class[] = 'current_page_ancestor';
    1399             }
    1400             if ( $page->ID == $current_page ) {
    1401                 $css_class[] = 'current_page_item';
    1402             } elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
    1403                 $css_class[] = 'current_page_parent';
    1404             }
    1405         } elseif ( $page->ID == get_option('page_for_posts') ) {
    1406             $css_class[] = 'current_page_parent';
    1407         }
    1408 
    1409         /**
    1410          * Filter the list of CSS classes to include with each page item in the list.
    1411          *
    1412          * @since 2.8.0
    1413          *
    1414          * @see wp_list_pages()
    1415          *
    1416          * @param array   $css_class    An array of CSS classes to be applied
    1417          *                             to each list item.
    1418          * @param WP_Post $page         Page data object.
    1419          * @param int     $depth        Depth of page, used for padding.
    1420          * @param array   $args         An array of arguments.
    1421          * @param int     $current_page ID of the current page.
    1422          */
    1423         $css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
    1424 
    1425         if ( '' === $page->post_title ) {
    1426             /* translators: %d: ID of a post */
    1427             $page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
    1428         }
    1429 
    1430         $args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
    1431         $args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];
    1432 
    1433         /** This filter is documented in wp-includes/post-template.php */
    1434         $output .= $indent . sprintf(
    1435             '<li class="%s"><a href="%s">%s%s%s</a>',
    1436             $css_classes,
    1437             get_permalink( $page->ID ),
    1438             $args['link_before'],
    1439             apply_filters( 'the_title', $page->post_title, $page->ID ),
    1440             $args['link_after']
    1441         );
    1442 
    1443         if ( ! empty( $args['show_date'] ) ) {
    1444             if ( 'modified' == $args['show_date'] ) {
    1445                 $time = $page->post_modified;
    1446             } else {
    1447                 $time = $page->post_date;
    1448             }
    1449 
    1450             $date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
    1451             $output .= " " . mysql2date( $date_format, $time );
    1452         }
    1453     }
    1454 
    1455     /**
    1456      * @see Walker::end_el()
    1457      * @since 2.1.0
    1458      *
    1459      * @param string $output Passed by reference. Used to append additional content.
    1460      * @param object $page Page data object. Not used.
    1461      * @param int    $depth Depth of page. Not Used.
    1462      * @param array  $args
    1463      */
    1464     public function end_el( &$output, $page, $depth = 0, $args = array() ) {
    1465         $output .= "</li>\n";
    1466     }
    1467 
    1468 }
    1469 
    1470 /**
    1471  * Create HTML dropdown list of pages.
    1472  *
    1473  * @since 2.1.0
    1474  * @uses Walker
    1475  */
    1476 class Walker_PageDropdown extends Walker {
    1477     /**
    1478      * @see Walker::$tree_type
    1479      * @since 2.1.0
    1480      * @var string
    1481      */
    1482     public $tree_type = 'page';
    1483 
    1484     /**
    1485      * @see Walker::$db_fields
    1486      * @since 2.1.0
    1487      * @todo Decouple this
    1488      * @var array
    1489      */
    1490     public $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
    1491 
    1492     /**
    1493      * @see Walker::start_el()
    1494      * @since 2.1.0
    1495      *
    1496      * @param string $output Passed by reference. Used to append additional content.
    1497      * @param object $page   Page data object.
    1498      * @param int    $depth  Depth of page in reference to parent pages. Used for padding.
    1499      * @param array  $args   Uses 'selected' argument for selected page to set selected HTML attribute for option
    1500      *                       element. Uses 'value_field' argument to fill "value" attribute. See {@see wp_dropdown_pages()}.
    1501      * @param int    $id
    1502      */
    1503     public function start_el( &$output, $page, $depth = 0, $args = array(), $id = 0 ) {
    1504         $pad = str_repeat('&nbsp;', $depth * 3);
    1505 
    1506         if ( ! isset( $args['value_field'] ) || ! isset( $page->{$args['value_field']} ) ) {
    1507             $args['value_field'] = 'ID';
    1508         }
    1509 
    1510         $output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $page->{$args['value_field']} ) . "\"";
    1511         if ( $page->ID == $args['selected'] )
    1512             $output .= ' selected="selected"';
    1513         $output .= '>';
    1514 
    1515         $title = $page->post_title;
    1516         if ( '' === $title ) {
    1517             /* translators: %d: ID of a post */
    1518             $title = sprintf( __( '#%d (no title)' ), $page->ID );
    1519         }
    1520 
    1521         /**
    1522          * Filter the page title when creating an HTML drop-down list of pages.
    1523          *
    1524          * @since 3.1.0
    1525          *
    1526          * @param string $title Page title.
    1527          * @param object $page  Page data object.
    1528          */
    1529         $title = apply_filters( 'list_pages', $title, $page );
    1530         $output .= $pad . esc_html( $title );
    1531         $output .= "</option>\n";
    1532     }
    1533 }
    1534 
    15351324//
    15361325// Attachments
  • trunk/src/wp-includes/post.php

    r33759 r34109  
    88 */
    99
     10/** Core posts functionality */
    1011require_once( ABSPATH . WPINC . '/post-functions.php' );
     12
     13/** Walker_Page class */
     14require_once( ABSPATH . WPINC . '/class-walker-page.php' );
     15
     16/** Walker_PageDropdown class */
     17require_once( ABSPATH . WPINC . '/class-walker-page-dropdown.php' );
     18
     19/** WP_Post class */
    1120require_once( ABSPATH . WPINC . '/class-wp-post.php' );
Note: See TracChangeset for help on using the changeset viewer.