Make WordPress Core


Ignore:
Timestamp:
10/26/2016 08:06:43 AM (7 years ago)
Author:
swissspidy
Message:

Posts, Post Types: Add support for post type templates.

WordPress has supported custom page templates for over 12 years, allowing developers to create various layouts for specific pages.
While this feature is very helpful, it has always been limited to the 'page' post type and not was not available to other post types.

By opening up the page template functionality to all post types, we continue to improve the template hierarchy's flexibility.

In addition to the Template Name file header, the post types supported by a template can be specified using Template Post Type: post, foo, bar.
When at least one template exists for a post type, the 'Post Attributes' meta box will be displayed in the back end, without the need to add post type support for 'page-attributes'. 'Post Attributes' can be customized per post type using the 'attributes' label when registering a post type.

Props johnbillion, Mte90, dipesh.kakadiya, swissspidy.
Fixes #18375.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme.php

    r38839 r38951  
    539539     * @access private
    540540     *
    541      * @param string $key Type of data to store (theme, screenshot, headers, page_templates)
     541     * @param string $key Type of data to store (theme, screenshot, headers, post_templates)
    542542     * @param string $data Data to store
    543543     * @return bool Return value from wp_cache_add()
     
    555555     * @access private
    556556     *
    557      * @param string $key Type of data to retrieve (theme, screenshot, headers, page_templates)
     557     * @param string $key Type of data to retrieve (theme, screenshot, headers, post_templates)
    558558     * @return mixed Retrieved data
    559559     */
     
    569569     */
    570570    public function cache_delete() {
    571         foreach ( array( 'theme', 'screenshot', 'headers', 'page_templates' ) as $key )
     571        foreach ( array( 'theme', 'screenshot', 'headers', 'post_templates' ) as $key )
    572572            wp_cache_delete( $key . '-' . $this->cache_hash, 'themes' );
    573573        $this->template = $this->textdomain_loaded = $this->theme_root_uri = $this->parent = $this->errors = $this->headers_sanitized = $this->name_translated = null;
     
    10071007
    10081008    /**
    1009      * Returns the theme's page templates.
    1010      *
    1011      * @since 3.4.0
    1012      * @access public
    1013      *
    1014      * @param WP_Post|null $post Optional. The post being edited, provided for context.
     1009     * Returns the theme's post templates.
     1010     *
     1011     * @since 4.7.0
     1012     * @access public
     1013     *
     1014     * @return array Array of page templates, keyed by filename and post type,
     1015     *               with the value of the translated header name.
     1016     */
     1017    public function get_post_templates() {
     1018        // If you screw up your current theme and we invalidate your parent, most things still work. Let it slide.
     1019        if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) ) {
     1020            return array();
     1021        }
     1022
     1023        $post_templates = $this->cache_get( 'post_templates' );
     1024
     1025        if ( ! is_array( $post_templates ) ) {
     1026            $post_templates = array();
     1027
     1028            $files = (array) $this->get_files( 'php', 1 );
     1029
     1030            foreach ( $files as $file => $full_path ) {
     1031                if ( ! preg_match( '|Template Name:(.*)$|mi', file_get_contents( $full_path ), $header ) ) {
     1032                    continue;
     1033                }
     1034
     1035                $types = array( 'page' );
     1036                if ( preg_match( '|Template Post Type:(.*)$|mi', file_get_contents( $full_path ), $type ) ) {
     1037                    $types = explode( ',', _cleanup_header_comment( $type[1] ) );
     1038                }
     1039
     1040                foreach ( $types as $type ) {
     1041                    $type = trim( $type );
     1042                    if ( ! isset( $post_templates[ $type ] ) ) {
     1043                        $post_templates[ $type ] = array();
     1044                    }
     1045
     1046                    $post_templates[ $type ][ $file ] = _cleanup_header_comment( $header[1] );
     1047                }
     1048            }
     1049
     1050            $this->cache_add( 'post_templates', $post_templates );
     1051        }
     1052
     1053        if ( $this->load_textdomain() ) {
     1054            foreach ( $post_templates as &$post_type ) {
     1055                foreach ( $post_type as &$post_template ) {
     1056                    $post_template = $this->translate_header( 'Template Name', $post_template );
     1057                }
     1058            }
     1059        }
     1060
     1061        return $post_templates;
     1062    }
     1063
     1064    /**
     1065     * Returns the theme's post templates for a given post type.
     1066     *
     1067     * @since 3.4.0
     1068     * @since 4.7.0 Added the `$post_type` parameter.
     1069     * @access public
     1070     *
     1071     * @param WP_Post|null $post      Optional. The post being edited, provided for context.
     1072     * @param string       $post_type Optional. Post type to get the templates for. Default 'page'.
     1073     *                                If a post is provided, its post type is used.
    10151074     * @return array Array of page templates, keyed by filename, with the value of the translated header name.
    10161075     */
    1017     public function get_page_templates( $post = null ) {
    1018         // If you screw up your current theme and we invalidate your parent, most things still work. Let it slide.
    1019         if ( $this->errors() && $this->errors()->get_error_codes() !== array( 'theme_parent_invalid' ) )
    1020             return array();
    1021 
    1022         $page_templates = $this->cache_get( 'page_templates' );
    1023 
    1024         if ( ! is_array( $page_templates ) ) {
    1025             $page_templates = array();
    1026 
    1027             $files = (array) $this->get_files( 'php', 1 );
    1028 
    1029             foreach ( $files as $file => $full_path ) {
    1030                 if ( ! preg_match( '|Template Name:(.*)$|mi', file_get_contents( $full_path ), $header ) )
    1031                     continue;
    1032                 $page_templates[ $file ] = _cleanup_header_comment( $header[1] );
    1033             }
    1034 
    1035             $this->cache_add( 'page_templates', $page_templates );
    1036         }
    1037 
    1038         if ( $this->load_textdomain() ) {
    1039             foreach ( $page_templates as &$page_template ) {
    1040                 $page_template = $this->translate_header( 'Template Name', $page_template );
    1041             }
    1042         }
    1043 
    1044         if ( $this->parent() )
    1045             $page_templates += $this->parent()->get_page_templates( $post );
     1076    public function get_page_templates( $post = null, $post_type = 'page' ) {
     1077        if ( $post ) {
     1078            $post_type = get_post_type( $post );
     1079        }
     1080
     1081        $post_templates = $this->get_post_templates();
     1082        $post_templates = isset( $post_templates[ $post_type ] ) ? $post_templates[ $post_type ] : array();
     1083
     1084        if ( $this->parent() ) {
     1085            $post_templates += $this->parent()->get_page_templates( $post );
     1086        }
    10461087
    10471088        /**
    10481089         * Filters list of page templates for a theme.
    10491090         *
     1091         * The dynamic portion of the hook name, `$post_type`, refers to the post type.
     1092         *
    10501093         * @since 3.9.0
    10511094         * @since 4.4.0 Converted to allow complete control over the `$page_templates` array.
     1095         * @since 4.7.0 Added the `$post_type` parameter.
    10521096         *
    1053          * @param array        $page_templates Array of page templates. Keys are filenames,
     1097         * @param array        $post_templates Array of page templates. Keys are filenames,
    10541098         *                                     values are translated names.
    10551099         * @param WP_Theme     $this           The theme object.
    10561100         * @param WP_Post|null $post           The post being edited, provided for context, or null.
     1101         * @param string       $post_type      Post type to get the templates for.
    10571102         */
    1058         return (array) apply_filters( 'theme_page_templates', $page_templates, $this, $post );
     1103        return (array) apply_filters( "theme_{$post_type}_templates", $post_templates, $this, $post, $post_type );
    10591104    }
    10601105
Note: See TracChangeset for help on using the changeset viewer.