`menu_id`, `container`, `before`, `after`, and `walker` arguments. * @since 4.7.0 Added the `item_spacing` argument. * * @param array|string $args { * Optional. Array or string of arguments to generate a page menu. See wp_list_pages() for additional arguments. * * @type string $sort_column How to sort the list of pages. Accepts post column names. * Default 'menu_order, post_title'. * @type string $menu_id ID for the div containing the page list. Default is empty string. * @type string $menu_class Class to use for the element containing the page list. Default 'menu'. * @type string $container Element to use for the element containing the page list. Default 'div'. * @type bool $echo Whether to echo the list or return it. Accepts true (echo) or false (return). * Default true. * @type int|bool|string $show_home Whether to display the link to the home page. Can just enter the text * you'd like shown for the home link. 1|true defaults to 'Home'. * @type string $link_before The HTML or text to prepend to $show_home text. Default empty. * @type string $link_after The HTML or text to append to $show_home text. Default empty. * @type string $before The HTML or text to prepend to the menu. Default is ''. * @type string $item_spacing Whether to preserve whitespace within the menu's HTML. Accepts 'preserve' * or 'discard'. Default 'discard'. * @type Walker $walker Walker instance to use for listing pages. Default empty which results in a * Walker_Page instance being used. * } * @return void|string Void if 'echo' argument is true, HTML menu if 'echo' is false. */ function wp_page_menu( $args = array() ) { $defaults = array( 'sort_column' => 'menu_order, post_title', 'menu_id' => '', 'menu_class' => 'menu', 'container' => 'div', 'echo' => true, 'link_before' => '', 'link_after' => '', 'before' => '', 'item_spacing' => 'discard', 'walker' => '', ); $args = wp_parse_args( $args, $defaults ); if ( ! in_array( $args['item_spacing'], array( 'preserve', 'discard' ), true ) ) { // Invalid value, fall back to default. $args['item_spacing'] = $defaults['item_spacing']; } if ( 'preserve' === $args['item_spacing'] ) { $t = "\t"; $n = "\n"; } else { $t = ''; $n = ''; } /** * Filters the arguments used to generate a page-based menu. * * @since 2.7.0 * * @see wp_page_menu() * * @param array $args An array of page menu arguments. See wp_page_menu() * for information on accepted arguments. */ $args = apply_filters( 'wp_page_menu_args', $args ); $menu = ''; $list_args = $args; // Show Home in the menu. if ( ! empty( $args['show_home'] ) ) { if ( true === $args['show_home'] || '1' === $args['show_home'] || 1 === $args['show_home'] ) { $text = __( 'Home' ); } else { $text = $args['show_home']; } $class = ''; if ( is_front_page() && ! is_paged() ) { $class = 'class="current_page_item"'; } $menu .= '
  • ' . $args['link_before'] . $text . $args['link_after'] . '
  • '; // If the front page is a page, add it to the exclude list. if ( 'page' === get_option( 'show_on_front' ) ) { if ( ! empty( $list_args['exclude'] ) ) { $list_args['exclude'] .= ','; } else { $list_args['exclude'] = ''; } $list_args['exclude'] .= get_option( 'page_on_front' ); } } $list_args['echo'] = false; $list_args['title_li'] = ''; $menu .= wp_list_pages( $list_args ); $container = sanitize_text_field( $args['container'] ); // Fallback in case `wp_nav_menu()` was called without a container. if ( empty( $container ) ) { $container = 'div'; } if ( $menu ) { // wp_nav_menu() doesn't set before and after. if ( isset( $args['fallback_cb'] ) && 'wp_page_menu' === $args['fallback_cb'] && 'ul' !== $container ) { $args['before'] = "'; } $menu = $args['before'] . $menu . $args['after']; } $attrs = ''; if ( ! empty( $args['menu_id'] ) ) { $attrs .= ' id="' . esc_attr( $args['menu_id'] ) . '"'; } if ( ! empty( $args['menu_class'] ) ) { $attrs .= ' class="' . esc_attr( $args['menu_class'] ) . '"'; } $menu = "<{$container}{$attrs}>" . $menu . "{$n}"; /** * Filters the HTML output of a page-based menu. * * @since 2.7.0 * * @see wp_page_menu() * * @param string $menu The HTML output. * @param array $args An array of arguments. See wp_page_menu() * for information on accepted arguments. */ $menu = apply_filters( 'wp_page_menu', $menu, $args ); if ( $args['echo'] ) { echo $menu; } else { return $menu; } } // // Page helpers. // /** * Retrieves HTML list content for page list. * * @uses Walker_Page to create HTML list content. * @since 2.1.0 * * @param array $pages * @param int $depth * @param int $current_page * @param array $args * @return string */ function walk_page_tree( $pages, $depth, $current_page, $args ) { if ( empty( $args['walker'] ) ) { $walker = new Walker_Page; } else { /** * @var Walker $walker */ $walker = $args['walker']; } foreach ( (array) $pages as $page ) { if ( $page->post_parent ) { $args['pages_with_children'][ $page->post_parent ] = true; } } return $walker->walk( $pages, $depth, $args, $current_page ); } /** * Retrieves HTML dropdown (select) content for page list. * * @since 2.1.0 * @since 5.3.0 Formalized the existing `...$args` parameter by adding it * to the function signature. * * @uses Walker_PageDropdown to create HTML dropdown content. * @see Walker_PageDropdown::walk() for parameters and return description. * * @param mixed ...$args Elements array, maximum hierarchical depth and optional additional arguments. * @return string */ function walk_page_dropdown_tree( ...$args ) { if ( empty( $args[2]['walker'] ) ) { // The user's options are the third parameter. $walker = new Walker_PageDropdown; } else { /** * @var Walker $walker */ $walker = $args[2]['walker']; } return $walker->walk( ...$args ); } // // Attachments. // /** * Displays an attachment page link using an image or icon. * * @since 2.0.0 * * @param int|WP_Post $post Optional. Post ID or post object. * @param bool $fullsize Optional. Whether to use full size. Default false. * @param bool $deprecated Deprecated. Not used. * @param bool $permalink Optional. Whether to include permalink. Default false. */ function the_attachment_link( $post = 0, $fullsize = false, $deprecated = false, $permalink = false ) { if ( ! empty( $deprecated ) ) { _deprecated_argument( __FUNCTION__, '2.5.0' ); } if ( $fullsize ) { echo wp_get_attachment_link( $post, 'full', $permalink ); } else { echo wp_get_attachment_link( $post, 'thumbnail', $permalink ); } } /** * Retrieves an attachment page link using an image or icon, if possible. * * @since 2.5.0 * @since 4.4.0 The `$post` parameter can now accept either a post ID or `WP_Post` object. * * @param int|WP_Post $post Optional. Post ID or post object. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $permalink Optional. Whether to add permalink to image. Default false. * @param bool $icon Optional. Whether the attachment is an icon. Default false. * @param string|false $text Optional. Link text to use. Activated by passing a string, false otherwise. * Default false. * @param array|string $attr Optional. Array or string of attributes. Default empty. * @return string HTML content. */ function wp_get_attachment_link( $post = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false, $attr = '' ) { $_post = get_post( $post ); if ( empty( $_post ) || ( 'attachment' !== $_post->post_type ) || ! wp_get_attachment_url( $_post->ID ) ) { return __( 'Missing Attachment' ); } $url = wp_get_attachment_url( $_post->ID ); if ( $permalink ) { $url = get_attachment_link( $_post->ID ); } if ( $text ) { $link_text = $text; } elseif ( $size && 'none' !== $size ) { $link_text = wp_get_attachment_image( $_post->ID, $size, $icon, $attr ); } else { $link_text = ''; } if ( '' === trim( $link_text ) ) { $link_text = $_post->post_title; } if ( '' === trim( $link_text ) ) { $link_text = esc_html( pathinfo( get_attached_file( $_post->ID ), PATHINFO_FILENAME ) ); } $link_html = "$link_text"; /** * Filters a retrieved attachment page link. * * @since 2.7.0 * @since 5.1.0 Added the `$attr` parameter. * * @param string $link_html The page link HTML output. * @param int|WP_Post $post Post ID or object. Can be 0 for the current global post. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param bool $permalink Whether to add permalink to image. Default false. * @param bool $icon Whether to include an icon. * @param string|false $text If string, will be link text. * @param array|string $attr Array or string of attributes. */ return apply_filters( 'wp_get_attachment_link', $link_html, $post, $size, $permalink, $icon, $text, $attr ); } /** * Wraps attachment in paragraph tag before content. * * @since 2.0.0 * * @param string $content * @return string */ function prepend_attachment( $content ) { $post = get_post(); if ( empty( $post->post_type ) || 'attachment' !== $post->post_type ) { return $content; } if ( wp_attachment_is( 'video', $post ) ) { $meta = wp_get_attachment_metadata( get_the_ID() ); $atts = array( 'src' => wp_get_attachment_url() ); if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $atts['width'] = (int) $meta['width']; $atts['height'] = (int) $meta['height']; } if ( has_post_thumbnail() ) { $atts['poster'] = wp_get_attachment_url( get_post_thumbnail_id() ); } $p = wp_video_shortcode( $atts ); } elseif ( wp_attachment_is( 'audio', $post ) ) { $p = wp_audio_shortcode( array( 'src' => wp_get_attachment_url() ) ); } else { $p = '

    '; // Show the medium sized image representation of the attachment if available, and link to the raw file. $p .= wp_get_attachment_link( 0, 'medium', false ); $p .= '

    '; } /** * Filters the attachment markup to be prepended to the post content. * * @since 2.0.0 * * @see prepend_attachment() * * @param string $p The attachment HTML output. */ $p = apply_filters( 'prepend_attachment', $p ); return "$p\n$content"; } // // Misc. // /** * Retrieves protected post password form content. * * @since 1.0.0 * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @return string HTML content for password form for password protected post. */ function get_the_password_form( $post = 0 ) { $post = get_post( $post ); $label = 'pwbox-' . ( empty( $post->ID ) ? rand() : $post->ID ); $output = '

    ' . __( 'This content is password protected. To view it please enter your password below:' ) . '

    '; /** * Filters the HTML output for the protected post password form. * * If modifying the password field, please note that the core database schema * limits the password field to 20 characters regardless of the value of the * size attribute in the form input. * * @since 2.7.0 * @since 5.8.0 Added the `$post` parameter. * * @param string $output The password form HTML output. * @param WP_Post $post Post object. */ return apply_filters( 'the_password_form', $output, $post ); } /** * Determines whether the current post uses a page template. * * This template tag allows you to determine if you are in a page template. * You can optionally provide a template filename or array of template filenames * and then the check will be specific to that template. * * For more information on this and similar theme functions, check out * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ * Conditional Tags} article in the Theme Developer Handbook. * * @since 2.5.0 * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates. * @since 4.7.0 Now works with any post type, not just pages. * * @param string|string[] $template The specific template filename or array of templates to match. * @return bool True on success, false on failure. */ function is_page_template( $template = '' ) { if ( ! is_singular() ) { return false; } $page_template = get_page_template_slug( get_queried_object_id() ); if ( empty( $template ) ) { return (bool) $page_template; } if ( $template == $page_template ) { return true; } if ( is_array( $template ) ) { if ( ( in_array( 'default', $template, true ) && ! $page_template ) || in_array( $page_template, $template, true ) ) { return true; } } return ( 'default' === $template && ! $page_template ); } /** * Gets the specific template filename for a given post. * * @since 3.4.0 * @since 4.7.0 Now works with any post type, not just pages. * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @return string|false Page template filename. Returns an empty string when the default page template * is in use. Returns false if the post does not exist. */ function get_page_template_slug( $post = null ) { $post = get_post( $post ); if ( ! $post ) { return false; } $template = get_post_meta( $post->ID, '_wp_page_template', true ); if ( ! $template || 'default' === $template ) { return ''; } return $template; } /** * Retrieves formatted date timestamp of a revision (linked to that revisions's page). * * @since 2.6.0 * * @param int|object $revision Revision ID or revision object. * @param bool $link Optional. Whether to link to revision's page. Default true. * @return string|false i18n formatted datetimestamp or localized 'Current Revision'. */ function wp_post_revision_title( $revision, $link = true ) { $revision = get_post( $revision ); if ( ! $revision ) { return $revision; } if ( ! in_array( $revision->post_type, array( 'post', 'page', 'revision' ), true ) ) { return false; } /* translators: Revision date format, see https://www.php.net/manual/datetime.format.php */ $datef = _x( 'F j, Y @ H:i:s', 'revision date format' ); /* translators: %s: Revision date. */ $autosavef = __( '%s [Autosave]' ); /* translators: %s: Revision date. */ $currentf = __( '%s [Current Revision]' ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); $edit_link = get_edit_post_link( $revision->ID ); if ( $link && current_user_can( 'edit_post', $revision->ID ) && $edit_link ) { $date = "$date"; } if ( ! wp_is_post_revision( $revision ) ) { $date = sprintf( $currentf, $date ); } elseif ( wp_is_post_autosave( $revision ) ) { $date = sprintf( $autosavef, $date ); } return $date; } /** * Retrieves formatted date timestamp of a revision (linked to that revisions's page). * * @since 3.6.0 * * @param int|object $revision Revision ID or revision object. * @param bool $link Optional. Whether to link to revision's page. Default true. * @return string|false gravatar, user, i18n formatted datetimestamp or localized 'Current Revision'. */ function wp_post_revision_title_expanded( $revision, $link = true ) { $revision = get_post( $revision ); if ( ! $revision ) { return $revision; } if ( ! in_array( $revision->post_type, array( 'post', 'page', 'revision' ), true ) ) { return false; } $author = get_the_author_meta( 'display_name', $revision->post_author ); /* translators: Revision date format, see https://www.php.net/manual/datetime.format.php */ $datef = _x( 'F j, Y @ H:i:s', 'revision date format' ); $gravatar = get_avatar( $revision->post_author, 24 ); $date = date_i18n( $datef, strtotime( $revision->post_modified ) ); $edit_link = get_edit_post_link( $revision->ID ); if ( $link && current_user_can( 'edit_post', $revision->ID ) && $edit_link ) { $date = "$date"; } $revision_date_author = sprintf( /* translators: Post revision title. 1: Author avatar, 2: Author name, 3: Time ago, 4: Date. */ __( '%1$s %2$s, %3$s ago (%4$s)' ), $gravatar, $author, human_time_diff( strtotime( $revision->post_modified_gmt ) ), $date ); /* translators: %s: Revision date with author avatar. */ $autosavef = __( '%s [Autosave]' ); /* translators: %s: Revision date with author avatar. */ $currentf = __( '%s [Current Revision]' ); if ( ! wp_is_post_revision( $revision ) ) { $revision_date_author = sprintf( $currentf, $revision_date_author ); } elseif ( wp_is_post_autosave( $revision ) ) { $revision_date_author = sprintf( $autosavef, $revision_date_author ); } /** * Filters the formatted author and date for a revision. * * @since 4.4.0 * * @param string $revision_date_author The formatted string. * @param WP_Post $revision The revision object. * @param bool $link Whether to link to the revisions page, as passed into * wp_post_revision_title_expanded(). */ return apply_filters( 'wp_post_revision_title_expanded', $revision_date_author, $revision, $link ); } /** * Displays a list of a post's revisions. * * Can output either a UL with edit links or a TABLE with diff interface, and * restore action links. * * @since 2.6.0 * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @param string $type 'all' (default), 'revision' or 'autosave' */ function wp_list_post_revisions( $post = 0, $type = 'all' ) { $post = get_post( $post ); if ( ! $post ) { return; } // $args array with (parent, format, right, left, type) deprecated since 3.6. if ( is_array( $type ) ) { $type = ! empty( $type['type'] ) ? $type['type'] : $type; _deprecated_argument( __FUNCTION__, '3.6.0' ); } $revisions = wp_get_post_revisions( $post->ID ); if ( ! $revisions ) { return; } $rows = ''; foreach ( $revisions as $revision ) { if ( ! current_user_can( 'read_post', $revision->ID ) ) { continue; } $is_autosave = wp_is_post_autosave( $revision ); if ( ( 'revision' === $type && $is_autosave ) || ( 'autosave' === $type && ! $is_autosave ) ) { continue; } $rows .= "\t
  • " . wp_post_revision_title_expanded( $revision ) . "
  • \n"; } echo "

    " . __( 'JavaScript must be enabled to use this feature.' ) . "

    \n"; echo "'; } /** * Retrieves the parent post object for the given post. * * @since 5.7.0 * * @param int|WP_Post|null $post Optional. Post ID or WP_Post object. Default is global $post. * @return WP_Post|null Parent post object, or null if there isn't one. */ function get_post_parent( $post = null ) { $wp_post = get_post( $post ); return ! empty( $wp_post->post_parent ) ? get_post( $wp_post->post_parent ) : null; } /** * Returns whether the given post has a parent post. * * @since 5.7.0 * * @param int|WP_Post|null $post Optional. Post ID or WP_Post object. Default is global $post. * @return bool Whether the post has a parent post. */ function has_post_parent( $post = null ) { return (bool) get_post_parent( $post ); }