Make WordPress Core

Changeset 39346


Ignore:
Timestamp:
11/23/2016 09:52:27 AM (10 years ago)
Author:
helen
Message:

Theme starter content: Add support for featured images and page templates.

Featured image support means that attachments can now be imported. Media can be sideloaded from within theme or plugin directories. Like other posts, attachments are auto-drafts until customizer changes are published, and are not duplicated when they already exist in the customized state. Attachment IDs can be used for any number of purposes, much like post IDs. Twenty Seventeen now includes 3 images used as featured images to best showcase the multi-section homepage setup.

As featured image IDs are stored in post meta, it also made sense to add support for page templates. Twenty Seventeen does not include any such templates, but the functionality can be quite important for displaying themes to their best effect.

props westonruter, helen, flixos90.
fixes #38615.

Location:
trunk
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-content/themes/twentyseventeen/functions.php

    r39317 r39346  
    124124                'posts' => array(
    125125                        'home',
    126                         'about',
    127                         'contact',
    128                         'blog',
    129                         'homepage-section',
     126                        'about' => array(
     127                                'thumbnail' => '{{image-sandwich}}',
     128                        ),
     129                        'contact' => array(
     130                                'thumbnail' => '{{image-espresso}}',
     131                        ),
     132                        'blog' => array(
     133                                'thumbnail' => '{{image-coffee}}',
     134                        ),
     135                        'homepage-section' => array(
     136                                'thumbnail' => '{{image-espresso}}',
     137                        ),
     138                ),
     139
     140                'attachments' => array(
     141                        'image-espresso' => array(
     142                                'post_title' => _x( 'Espresso', 'Theme starter content' ),
     143                                'file' => 'assets/images/espresso.jpg',
     144                        ),
     145                        'image-sandwich' => array(
     146                                'post_title' => _x( 'Sandwich', 'Theme starter content' ),
     147                                'file' => 'assets/images/sandwich.jpg',
     148                        ),
     149                        'image-coffee' => array(
     150                                'post_title' => _x( 'Coffee', 'Theme starter content' ),
     151                                'file' => 'assets/images/coffee.jpg',
     152                        ),
    130153                ),
    131154
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r39345 r39346  
    917917
    918918                $sidebars_widgets = isset( $starter_content['widgets'] ) && ! empty( $this->widgets ) ? $starter_content['widgets'] : array();
     919                $attachments = isset( $starter_content['attachments'] ) && ! empty( $this->nav_menus ) ? $starter_content['attachments'] : array();
    919920                $posts = isset( $starter_content['posts'] ) && ! empty( $this->nav_menus ) ? $starter_content['posts'] : array();
    920921                $options = isset( $starter_content['options'] ) ? $starter_content['options'] : array();
     
    966967                }
    967968
     969                $starter_content_auto_draft_post_ids = array();
     970                if ( ! empty( $changeset_data['nav_menus_created_posts']['value'] ) ) {
     971                        $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, $changeset_data['nav_menus_created_posts']['value'] );
     972                }
     973
     974                $existing_starter_content_posts = array();
     975                if ( ! empty( $starter_content_auto_draft_post_ids ) ) {
     976                        $existing_posts_query = new WP_Query( array(
     977                                'post__in' => $starter_content_auto_draft_post_ids,
     978                                'post_status' => 'auto-draft',
     979                                'post_type' => 'any',
     980                                'number' => -1,
     981                        ) );
     982                        foreach ( $existing_posts_query->posts as $existing_post ) {
     983                                $existing_starter_content_posts[ $existing_post->post_type . ':' . $existing_post->post_name ] = $existing_post;
     984                        }
     985                }
     986
     987                // Attachments are technically posts but handled differently.
     988                if ( ! empty( $attachments ) ) {
     989                        // Such is The WordPress Way.
     990                        require_once( ABSPATH . 'wp-admin/includes/file.php' );
     991                        require_once( ABSPATH . 'wp-admin/includes/media.php' );
     992                        require_once( ABSPATH . 'wp-admin/includes/image.php' );
     993
     994                        $attachment_ids = array();
     995
     996                        foreach ( $attachments as $symbol => $attachment ) {
     997
     998                                // A file is required and URLs to files are not currently allowed.
     999                                if ( empty( $attachment['file'] ) || preg_match( '#^https?://$#', $attachment['file'] ) ) {
     1000                                        continue;
     1001                                }
     1002
     1003                                $file_array = array();
     1004                                $file_path = null;
     1005                                if ( file_exists( $attachment['file'] ) ) {
     1006                                        $file_path = $attachment['file']; // Could be absolute path to file in plugin.
     1007                                } elseif ( is_child_theme() && file_exists( get_stylesheet_directory() . '/' . $attachment['file'] ) ) {
     1008                                        $file_path = get_stylesheet_directory() . '/' . $attachment['file'];
     1009                                } elseif ( file_exists( get_template_directory() . '/' . $attachment['file'] ) ) {
     1010                                        $file_path = get_template_directory() . '/' . $attachment['file'];
     1011                                } else {
     1012                                        continue;
     1013                                }
     1014                                $file_array['name'] = basename( $attachment['file'] );
     1015
     1016                                // Skip file types that are not recognized.
     1017                                $checked_filetype = wp_check_filetype( $file_array['name'] );
     1018                                if ( empty( $checked_filetype['type'] ) ) {
     1019                                        continue;
     1020                                }
     1021
     1022                                // Ensure post_name is set since not automatically derived from post_title for new auto-draft posts.
     1023                                if ( empty( $attachment['post_name'] ) ) {
     1024                                        if ( ! empty( $attachment['post_title'] ) ) {
     1025                                                $attachment['post_name'] = sanitize_title( $attachment['post_title'] );
     1026                                        } else {
     1027                                                $attachment['post_name'] = sanitize_title( preg_replace( '/\.\w+$/', '', $file_array['name'] ) );
     1028                                        }
     1029                                }
     1030
     1031                                $attachment_id = null;
     1032                                $attached_file = null;
     1033                                if ( isset( $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ] ) ) {
     1034                                        $attachment_post = $existing_starter_content_posts[ 'attachment:' . $attachment['post_name'] ];
     1035                                        $attachment_id = $attachment_post->ID;
     1036                                        $attached_file = get_attached_file( $attachment_id );
     1037                                        if ( empty( $attached_file ) || ! file_exists( $attached_file ) ) {
     1038                                                $attachment_id = null;
     1039                                                $attached_file = null;
     1040                                        } elseif ( $this->get_stylesheet() !== get_post_meta( $attachment_post->ID, '_starter_content_theme', true ) ) {
     1041
     1042                                                // Re-generate attachment metadata since it was previously generated for a different theme.
     1043                                                $metadata = wp_generate_attachment_metadata( $attachment_post->ID, $attached_file );
     1044                                                wp_update_attachment_metadata( $attachment_id, $metadata );
     1045                                                update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() );
     1046                                        }
     1047                                }
     1048
     1049                                // Insert the attachment auto-draft because it doesn't yet exist or the attached file is gone.
     1050                                if ( ! $attachment_id ) {
     1051
     1052                                        // Copy file to temp location so that original file won't get deleted from theme after sideloading.
     1053                                        $temp_file_name = wp_tempnam( basename( $file_path ) );
     1054                                        if ( $temp_file_name && copy( $file_path, $temp_file_name ) ) {
     1055                                                $file_array['tmp_name'] = $temp_file_name;
     1056                                        }
     1057                                        if ( empty( $file_array['tmp_name'] ) ) {
     1058                                                continue;
     1059                                        }
     1060
     1061                                        $attachment_post_data = array_merge(
     1062                                                wp_array_slice_assoc( $attachment, array( 'post_title', 'post_content', 'post_excerpt', 'post_name' ) ),
     1063                                                array(
     1064                                                        'post_status' => 'auto-draft', // So attachment will be garbage collected in a week if changeset is never published.
     1065                                                )
     1066                                        );
     1067
     1068                                        // In PHP < 5.6 filesize() returns 0 for the temp files unless we clear the file status cache.
     1069                                        // Technically, PHP < 5.6.0 || < 5.5.13 || < 5.4.29 but no need to be so targeted.
     1070                                        // See https://bugs.php.net/bug.php?id=65701
     1071                                        if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
     1072                                                clearstatcache();
     1073                                        }
     1074
     1075                                        $attachment_id = media_handle_sideload( $file_array, 0, null, $attachment_post_data );
     1076                                        if ( is_wp_error( $attachment_id ) ) {
     1077                                                continue;
     1078                                        }
     1079                                        update_post_meta( $attachment_id, '_starter_content_theme', $this->get_stylesheet() );
     1080                                }
     1081
     1082                                $attachment_ids[ $symbol ] = $attachment_id;
     1083                                $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, array_values( $attachment_ids ) );
     1084                        }
     1085                }
     1086
    9681087                // Posts & pages.
    9691088                if ( ! empty( $posts ) ) {
    970                         $nav_menus_created_posts = array();
    971                         if ( ! empty( $changeset_data['nav_menus_created_posts']['value'] ) ) {
    972                                 $nav_menus_created_posts = $changeset_data['nav_menus_created_posts']['value'];
    973                         }
    974 
    975                         $existing_posts = array();
    976                         if ( ! empty( $nav_menus_created_posts ) ) {
    977                                 $existing_posts_query = new WP_Query( array(
    978                                         'post__in' => $nav_menus_created_posts,
    979                                         'post_status' => 'auto-draft',
    980                                         'post_type' => 'any',
    981                                         'number' => -1,
    982                                 ) );
    983                                 foreach ( $existing_posts_query->posts as $existing_post ) {
    984                                         $existing_posts[ $existing_post->post_type . ':' . $existing_post->post_name ] = $existing_post;
    985                                 }
    986                         }
    987 
    9881089                        foreach ( array_keys( $posts ) as $post_symbol ) {
    9891090                                if ( empty( $posts[ $post_symbol ]['post_type'] ) ) {
     
    10001101
    10011102                                // Use existing auto-draft post if one already exists with the same type and name.
    1002                                 if ( isset( $existing_posts[ $post_type . ':' . $post_name ] ) ) {
    1003                                         $posts[ $post_symbol ]['ID'] = $existing_posts[ $post_type . ':' . $post_name ]->ID;
     1103                                if ( isset( $existing_starter_content_posts[ $post_type . ':' . $post_name ] ) ) {
     1104                                        $posts[ $post_symbol ]['ID'] = $existing_starter_content_posts[ $post_type . ':' . $post_name ]->ID;
    10041105                                        continue;
     1106                                }
     1107
     1108                                // Translate the featured image symbol.
     1109                                if ( ! empty( $posts[ $post_symbol ]['thumbnail'] )
     1110                                        && preg_match( '/^{{(?P<symbol>.+)}}$/', $posts[ $post_symbol ]['thumbnail'], $matches )
     1111                                        && isset( $attachment_ids[ $matches['symbol'] ] ) ) {
     1112                                        $posts[ $post_symbol ]['meta_input']['_thumbnail_id'] = $attachment_ids[ $matches['symbol'] ];
     1113                                }
     1114
     1115                                if ( ! empty( $posts[ $post_symbol ]['template'] ) ) {
     1116                                        $posts[ $post_symbol ]['meta_input']['_wp_page_template'] = $posts[ $post_symbol ]['template'];
    10051117                                }
    10061118
     
    10111123                        }
    10121124
    1013                         // The nav_menus_created_posts setting is why nav_menus component is dependency for adding posts.
     1125                        $starter_content_auto_draft_post_ids = array_merge( $starter_content_auto_draft_post_ids, wp_list_pluck( $posts, 'ID' ) );
     1126                }
     1127
     1128                // The nav_menus_created_posts setting is why nav_menus component is dependency for adding posts.
     1129                if ( ! empty( $this->nav_menus ) && ! empty( $starter_content_auto_draft_post_ids ) ) {
    10141130                        $setting_id = 'nav_menus_created_posts';
    1015                         if ( empty( $changeset_data[ $setting_id ] ) || ! empty( $changeset_data[ $setting_id ]['starter_content'] ) ) {
    1016                                 $nav_menus_created_posts = array_unique( array_merge( $nav_menus_created_posts, wp_list_pluck( $posts, 'ID' ) ) );
    1017                                 $this->set_post_value( $setting_id, array_values( $nav_menus_created_posts ) );
    1018                                 $this->pending_starter_content_settings_ids[] = $setting_id;
    1019                         }
     1131                        $this->set_post_value( $setting_id, array_unique( array_values( $starter_content_auto_draft_post_ids ) ) );
     1132                        $this->pending_starter_content_settings_ids[] = $setting_id;
    10201133                }
    10211134
  • trunk/src/wp-includes/class-wp-customize-nav-menus.php

    r39241 r39346  
    11921192                if ( ! empty( $post_ids ) ) {
    11931193                        foreach ( $post_ids as $post_id ) {
     1194                                $target_status = 'attachment' === get_post_type( $post_id ) ? 'inherit' : 'publish';
     1195
    11941196                                // Note that wp_publish_post() cannot be used because unique slugs need to be assigned.
    1195                                 wp_update_post( array( 'ID' => $post_id, 'post_status' => 'publish' ) );
     1197                                wp_update_post( array( 'ID' => $post_id, 'post_status' => $target_status ) );
    11961198                        }
    11971199                }
  • trunk/src/wp-includes/post.php

    r39278 r39346  
    30593059
    30603060        $post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status'];
    3061         if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash' ) ) ) {
     3061        if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) {
    30623062                $post_status = 'inherit';
    30633063        }
  • trunk/src/wp-includes/theme.php

    r39338 r39346  
    19871987                        case 'widgets' :
    19881988                                foreach ( $config[ $type ] as $sidebar_id => $widgets ) {
    1989                                         foreach ( $widgets as $widget ) {
     1989                                        foreach ( $widgets as $id => $widget ) {
    19901990                                                if ( is_array( $widget ) ) {
     1991
     1992                                                        // Item extends core content.
     1993                                                        if ( ! empty( $core_content[ $type ][ $id ] ) ) {
     1994                                                                $widget = array(
     1995                                                                        $core_content[ $type ][ $id ][0],
     1996                                                                        array_merge( $core_content[ $type ][ $id ][1], $widget ),
     1997                                                                );
     1998                                                        }
     1999
    19912000                                                        $content[ $type ][ $sidebar_id ][] = $widget;
    19922001                                                } elseif ( is_string( $widget ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $widget ] ) ) {
     
    20082017                                        $content[ $type ][ $nav_menu_location ]['name'] = $nav_menu['name'];
    20092018
    2010                                         foreach ( $nav_menu['items'] as $nav_menu_item ) {
     2019                                        foreach ( $nav_menu['items'] as $id => $nav_menu_item ) {
    20112020                                                if ( is_array( $nav_menu_item ) ) {
     2021
     2022                                                        // Item extends core content.
     2023                                                        if ( ! empty( $core_content[ $type ][ $id ] ) ) {
     2024                                                                $nav_menu_item = array_merge( $core_content[ $type ][ $id ], $nav_menu_item );
     2025                                                        }
     2026
    20122027                                                        $content[ $type ][ $nav_menu_location ]['items'][] = $nav_menu_item;
    20132028                                                } elseif ( is_string( $nav_menu_item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $nav_menu_item ] ) ) {
     
    20182033                                break;
    20192034
    2020                         // Everything else should map at the next level.
    2021                         default :
    2022                                 foreach( $config[ $type ] as $i => $item ) {
     2035                        // Attachments are posts but have special treatment.
     2036                        case 'attachments' :
     2037                                foreach ( $config[ $type ] as $id => $item ) {
     2038                                        if ( ! empty( $item['file'] ) ) {
     2039                                                $content[ $type ][ $id ] = $item;
     2040                                        }
     2041                                }
     2042                                break;
     2043
     2044                        // All that's left now are posts (besides attachments). Not a default case for the sake of clarity and future work.
     2045                        case 'posts' :
     2046                                foreach ( $config[ $type ] as $id => $item ) {
    20232047                                        if ( is_array( $item ) ) {
    2024                                                 $content[ $type ][ $i ] = $item;
    2025                                         } elseif ( is_string( $item ) && ! empty( $core_content[ $type ] ) && ! empty( $core_content[ $type ][ $item ] ) ) {
     2048
     2049                                                // Item extends core content.
     2050                                                if ( ! empty( $core_content[ $type ][ $id ] ) ) {
     2051                                                        $item = array_merge( $core_content[ $type ][ $id ], $item );
     2052                                                }
     2053
     2054                                                // Enforce a subset of fields.
     2055                                                $content[ $type ][ $id ] = wp_array_slice_assoc(
     2056                                                        $item,
     2057                                                        array(
     2058                                                                'post_type',
     2059                                                                'post_title',
     2060                                                                'post_excerpt',
     2061                                                                'post_name',
     2062                                                                'post_content',
     2063                                                                'menu_order',
     2064                                                                'comment_status',
     2065                                                                'thumbnail',
     2066                                                                'template',
     2067                                                        )
     2068                                                );
     2069                                        } elseif ( is_string( $item ) && ! empty( $core_content[ $type ][ $item ] ) ) {
    20262070                                                $content[ $type ][ $item ] = $core_content[ $type ][ $item ];
    20272071                                        }
  • trunk/tests/phpunit/tests/customize/manager.php

    r39332 r39346  
    314314        function test_import_theme_starter_content() {
    315315                wp_set_current_user( self::$admin_user_id );
     316                register_nav_menu( 'top', 'Top' );
    316317
    317318                global $wp_customize;
     
    344345                        'posts' => array(
    345346                                'home',
    346                                 'about',
     347                                'about' => array(
     348                                        'template' => 'sample-page-template.php',
     349                                ),
    347350                                'blog',
    348351                                'custom' => array(
    349352                                        'post_type' => 'post',
    350353                                        'post_title' => 'Custom',
     354                                        'thumbnail' => '{{featured-image-logo}}',
     355                                ),
     356                        ),
     357                        'attachments' => array(
     358                                'featured-image-logo' => array(
     359                                        'post_title' => 'Featured Image',
     360                                        'post_content' => 'Attachment Description',
     361                                        'post_excerpt' => 'Attachment Caption',
     362                                        'file' => DIR_TESTDATA . '/images/waffles.jpg',
    351363                                ),
    352364                        ),
     
    395407
    396408                $posts_by_name = array();
     409                $this->assertCount( 5, $changeset_values['nav_menus_created_posts'] );
    397410                foreach ( $changeset_values['nav_menus_created_posts'] as $post_id ) {
    398411                        $post = get_post( $post_id );
     
    400413                        $posts_by_name[ $post->post_name ] = $post->ID;
    401414                }
     415                $this->assertEquals( array( 'featured-image', 'home', 'about', 'blog', 'custom' ), array_keys( $posts_by_name ) );
     416                $this->assertEquals( 'Custom', get_post( $posts_by_name['custom'] )->post_title );
     417                $this->assertEquals( 'sample-page-template.php', get_page_template_slug( $posts_by_name['about'] ) );
     418                $this->assertEquals( '', get_page_template_slug( $posts_by_name['blog'] ) );
     419                $this->assertEquals( $posts_by_name['featured-image'], get_post_thumbnail_id( $posts_by_name['custom'] ) );
     420                $this->assertEquals( '', get_post_thumbnail_id( $posts_by_name['blog'] ) );
     421                $attachment_metadata = wp_get_attachment_metadata( $posts_by_name['featured-image'] );
     422                $this->assertEquals( 'Featured Image', get_post( $posts_by_name['featured-image'] )->post_title );
     423                $this->assertArrayHasKey( 'file', $attachment_metadata );
     424                $this->assertContains( 'waffles', $attachment_metadata['file'] );
    402425
    403426                $this->assertEquals( 'page', $changeset_values['show_on_front'] );
     
    419442                }
    420443
     444                // Ensure that re-importing doesn't cause auto-drafts to balloon.
     445                $wp_customize->import_theme_starter_content();
     446                $changeset_data = $wp_customize->changeset_data();
     447                $this->assertEqualSets( array_values( $posts_by_name ), $changeset_data['nav_menus_created_posts']['value'], 'Auto-drafts should not get re-created and amended with each import.' );
     448
    421449                // Test that saving non-starter content on top of the changeset clears the starter_content flag.
    422450                $wp_customize->save_changeset_post( array(
     
    443471                $this->assertNotEquals( $previous_blogdescription, $changeset_data['blogdescription']['value'] );
    444472                $this->assertArrayHasKey( 'starter_content', $changeset_data['blogdescription'] );
     473
     474                // Publish.
     475                $this->assertEquals( 'auto-draft', get_post( $posts_by_name['about'] )->post_status );
     476                $this->assertEquals( 'auto-draft', get_post( $posts_by_name['featured-image'] )->post_status );
     477                $this->assertNotEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) );
     478                $r = $wp_customize->save_changeset_post( array( 'status' => 'publish' ) );
     479                $this->assertInternalType( 'array', $r );
     480                $this->assertEquals( 'publish', get_post( $posts_by_name['about'] )->post_status );
     481                $this->assertEquals( 'inherit', get_post( $posts_by_name['featured-image'] )->post_status );
     482                $this->assertEquals( $changeset_data['blogname']['value'], get_option( 'blogname' ) );
    445483        }
    446484
  • trunk/tests/phpunit/tests/theme/getThemeStarterContent.php

    r39276 r39346  
    4242                                'sidebar-1' => array(
    4343                                        'text_business_info',
    44                                         'text_about',
     44                                        'text_about' => array(
     45                                                'title' => 'Our Story',
     46                                        ),
    4547                                        'archives',
    4648                                        'calendar',
     
    6466                                                'page_blog',
    6567                                                'page_news',
    66                                                 'page_contact',
     68                                                'page_contact' => array(
     69                                                        'title' => 'Email Us',
     70                                                ),
    6771                                                'link_email',
    6872                                                'link_facebook',
     
    8791                                'about',
    8892                                'contact',
    89                                 'blog',
     93                                'blog' => array(
     94                                        'template' => 'blog.php',
     95                                        'post_excerpt' => 'Extended',
     96                                ),
    9097                                'news',
    9198                                'homepage-section',
     
    94101                                        'post_type' => 'post',
    95102                                        'post_title' => 'Custom',
     103                                        'thumbnail' => '{{featured-image-logo}}',
     104                                ),
     105                        ),
     106                        'attachments' => array(
     107                                'featured-image-logo' => array(
     108                                        'post_title' => 'Title',
     109                                        'post_content' => 'Description',
     110                                        'post_excerpt' => 'Caption',
     111                                        'file' => DIR_TESTDATA . '/images/waffles.jpg',
     112                                ),
     113                                'featured-image-skipped' => array(
     114                                        'post_title' => 'Skipped',
    96115                                ),
    97116                        ),
     
    116135                $this->assertCount( 16, $hydrated_starter_content['nav_menus']['top']['items'], 'Unknown should be dropped, custom should be present.' );
    117136                $this->assertCount( 10, $hydrated_starter_content['widgets']['sidebar-1'], 'Unknown should be dropped.' );
     137                $this->assertCount( 1, $hydrated_starter_content['attachments'], 'Attachment with missing file is filtered out.' );
     138                $this->assertArrayHasKey( 'featured-image-logo', $hydrated_starter_content['attachments'] );
     139                $this->assertSame( $dehydrated_starter_content['attachments']['featured-image-logo'], $hydrated_starter_content['attachments']['featured-image-logo'] );
    118140
    119141                foreach ( $hydrated_starter_content['widgets']['sidebar-1'] as $widget ) {
     
    124146                        $this->assertArrayHasKey( 'title', $widget[1] );
    125147                }
     148                $this->assertEquals( 'text', $hydrated_starter_content['widgets']['sidebar-1'][1][0], 'Core content extended' );
     149                $this->assertEquals( 'Our Story', $hydrated_starter_content['widgets']['sidebar-1'][1][1]['title'], 'Core content extended' );
    126150
    127151                foreach ( $hydrated_starter_content['nav_menus']['top']['items'] as $nav_menu_item ) {
     
    129153                        $this->assertTrue( ! empty( $nav_menu_item['object_id'] ) || ! empty( $nav_menu_item['url'] ) );
    130154                }
     155                $this->assertEquals( 'Email Us', $hydrated_starter_content['nav_menus']['top']['items'][4]['title'], 'Core content extended' );
    131156
    132157                foreach ( $hydrated_starter_content['posts'] as $key => $post ) {
     
    137162                        $this->assertArrayHasKey( 'post_title', $post );
    138163                }
     164                $this->assertEquals( 'Extended', $hydrated_starter_content['posts']['blog']['post_excerpt'], 'Core content extended' );
     165                $this->assertEquals( 'blog.php', $hydrated_starter_content['posts']['blog']['template'], 'Core content extended' );
     166                $this->assertEquals( '{{featured-image-logo}}', $hydrated_starter_content['posts']['custom']['thumbnail'], 'Core content extended' );
    139167        }
    140168
Note: See TracChangeset for help on using the changeset viewer.