{
    "$schema": "https://playground.wordpress.net/blueprint-schema.json",
    "landingPage": "/",
    "preferredVersions": {
        "php": "8.2",
        "wp": "latest"
    },
    "features": {
        "networking": true
    },
    "login": true,
    "steps": [
        {
            "step": "installPlugin",
            "pluginData": {
                "resource": "wordpress.org/plugins",
                "slug": "post-layouts"
            },
            "options": {
                "activate": true
            }
        },
        {
            "step": "runPHP",
            "code": "<?php\nrequire_once '/wordpress/wp-load.php';\nrequire_once ABSPATH . 'wp-admin/includes/image.php';\n\n// Generated placeholder images (rather than a bundled sample photo file):\n// this plugin ships no photo-like sample asset under a path that survives\n// .distignore filtering (only UI chrome - FontAwesome icon fonts/CSS - and\n// the .wordpress-org/ display assets, which are excluded from the actual\n// shipped plugin package and would break this demo on a real install, the\n// same trap a prior sibling blueprint pass in this org hit and fixed).\n// Generating the images inline with GD has no such dependency.\nif ( ! function_exists( 'imagecreatetruecolor' ) ) {\n\tthrow new RuntimeException( 'GD library is not available in this Playground PHP build.' );\n}\n\n$upload_dir = wp_upload_dir();\n$colors     = array(\n\tarray(\n\t\t'label' => 'One',\n\t\t'r'     => 66,\n\t\t'g'     => 133,\n\t\t'b'     => 244,\n\t),\n\tarray(\n\t\t'label' => 'Two',\n\t\t'r'     => 219,\n\t\t'g'     => 68,\n\t\t'b'     => 55,\n\t),\n\tarray(\n\t\t'label' => 'Three',\n\t\t'r'     => 244,\n\t\t'g'     => 180,\n\t\t'b'     => 0,\n\t),\n\tarray(\n\t\t'label' => 'Four',\n\t\t'r'     => 15,\n\t\t'g'     => 157,\n\t\t'b'     => 88,\n\t),\n\tarray(\n\t\t'label' => 'Five',\n\t\t'r'     => 171,\n\t\t'g'     => 71,\n\t\t'b'     => 188,\n\t),\n\tarray(\n\t\t'label' => 'Six',\n\t\t'r'     => 0,\n\t\t'g'     => 172,\n\t\t'b'     => 193,\n\t),\n);\n\n/**\n * Generates one solid-color placeholder PNG with a centered label, and\n * registers it as a real media library attachment. PNG rather than JPEG:\n * WordPress Playground's PHP-in-WebAssembly build has unreliable/absent\n * libjpeg support in its bundled GD extension, so imagejpeg() can silently\n * produce a broken or empty file there even though it works fine on a\n * normal server - PNG encoding has no such dependency.\n */\nfunction pl_demo_attachment( $color, $index, $upload_dir ) {\n\t$width  = 640;\n\t$height = 480;\n\t$image  = imagecreatetruecolor( $width, $height );\n\t$bg     = imagecolorallocate( $image, $color['r'], $color['g'], $color['b'] );\n\timagefill( $image, 0, 0, $bg );\n\n\t$white = imagecolorallocate( $image, 255, 255, 255 );\n\t$text  = 'Post Layouts Demo ' . $color['label'];\n\t$font  = 5;\n\t$tw    = imagefontwidth( $font ) * strlen( $text );\n\t$th    = imagefontheight( $font );\n\timagestring( $image, $font, (int) ( ( $width - $tw ) / 2 ), (int) ( ( $height - $th ) / 2 ), $text, $white );\n\n\t$filename  = 'post-layouts-demo-' . $index . '.png';\n\t$file_path = trailingslashit( $upload_dir['path'] ) . $filename;\n\timagepng( $image, $file_path );\n\timagedestroy( $image );\n\n\t$filetype      = wp_check_filetype( $filename, null );\n\t$attachment_id = wp_insert_attachment(\n\t\tarray(\n\t\t\t'post_mime_type' => $filetype['type'],\n\t\t\t'post_title'     => 'Post Layouts Demo Image ' . $color['label'],\n\t\t\t'post_content'   => '',\n\t\t\t'post_status'    => 'inherit',\n\t\t),\n\t\t$file_path\n\t);\n\tif ( is_wp_error( $attachment_id ) ) {\n\t\treturn 0;\n\t}\n\t$attachment_data = wp_generate_attachment_metadata( $attachment_id, $file_path );\n\twp_update_attachment_metadata( $attachment_id, $attachment_data );\n\n\treturn $attachment_id;\n}\n\n$sample_posts = array(\n\tarray(\n\t\t'title'   => '5 Tips for Building Beautiful Post Layouts',\n\t\t'content' => 'Post Layouts gives you ready-to-use grid and list templates for displaying your blog posts, with toggles for images, meta, excerpts and more - no coding required. Here are a few practical tips for making the most of it.',\n\t\t'cat'     => 'Design',\n\t),\n\tarray(\n\t\t'title'   => 'Grid vs List: Choosing the Right Layout',\n\t\t'content' => 'This plugin ships two grid templates and three list templates. This post walks through when a grid layout suits a homepage blog section better than a list, and vice versa.',\n\t\t'cat'     => 'Design',\n\t),\n\tarray(\n\t\t'title'   => '10 Blogging Trends Shaping 2026',\n\t\t'content' => 'From card-based post grids to minimal list views, here are the content-presentation trends worth paying attention to this year.',\n\t\t'cat'     => 'Blogging',\n\t),\n\tarray(\n\t\t'title'   => \"A Beginner's Guide to the Post Layouts Block\",\n\t\t'content' => 'New to this block? This guide covers the basics: picking a template, choosing how many posts to show, and toggling post meta like author, date, and comment count.',\n\t\t'cat'     => 'Tutorials',\n\t),\n\tarray(\n\t\t'title'   => 'Customizing Colors and Typography',\n\t\t'content' => 'Post Layouts includes per-element color and typography controls for the title, excerpt, meta, and call-to-action - this post covers how to match it to your site design.',\n\t\t'cat'     => 'Tutorials',\n\t),\n\tarray(\n\t\t'title'   => 'Featured Images: Landscape vs Square',\n\t\t'content' => 'The block can crop featured images as landscape or square. Here is how each option looks across the grid and list templates.',\n\t\t'cat'     => 'Design',\n\t),\n);\n\n$attachment_ids = array();\nforeach ( $colors as $index => $color ) {\n\t$attachment_ids[] = pl_demo_attachment( $color, $index + 1, $upload_dir );\n}\n\n$post_ids = array();\nforeach ( $sample_posts as $i => $sample_post ) {\n\t$term = term_exists( $sample_post['cat'], 'category' );\n\tif ( ! $term ) {\n\t\t$term = wp_insert_term( $sample_post['cat'], 'category' );\n\t}\n\t$cat_id = is_wp_error( $term ) ? 0 : (int) $term['term_id'];\n\n\t$post_id = wp_insert_post(\n\t\tarray(\n\t\t\t'post_title'    => $sample_post['title'],\n\t\t\t'post_content'  => $sample_post['content'],\n\t\t\t'post_status'   => 'publish',\n\t\t\t'post_type'     => 'post',\n\t\t\t'post_category' => $cat_id ? array( $cat_id ) : array(),\n\t\t),\n\t\ttrue\n\t);\n\tif ( is_wp_error( $post_id ) ) {\n\t\tthrow new RuntimeException( $post_id->get_error_message() );\n\t}\n\n\t$attachment_id = $attachment_ids[ $i % count( $attachment_ids ) ];\n\tif ( ! empty( $attachment_id ) ) {\n\t\tset_post_thumbnail( $post_id, $attachment_id );\n\t}\n\n\twp_set_object_terms( $post_id, array( 'Post Layouts Demo' ), 'post_tag', true );\n\n\t$post_ids[] = $post_id;\n}\n\n// Two sections on one demo page: the grid template (post-layouts/pl-blog-templates\n// with layoutopt=grid, layoutcount=1 - \"Grid template 1\") and a list template\n// (layoutopt=list, layoutcount=1 - \"List template 1\"), using this block's own\n// real registered attribute names (see src/blocks/index.php's\n// post_layouts_register_block_core_latest_posts()), not guessed ones.\n$grid_attrs = array(\n\t'block_id'               => 'demogrid1',\n\t'postsToShow'            => 6,\n\t'layoutopt'              => 'grid',\n\t'layoutcount'            => 1,\n\t'postLayout'             => 'grid',\n\t'columns'                => 3,\n\t'displayPostImage'       => true,\n\t'imageCrop'              => 'landscape',\n\t'displayPostCategory'    => true,\n\t'displayPostAuthor'      => true,\n\t'displayPostDate'        => true,\n\t'displayPostExcerpt'     => true,\n\t'wordsExcerpt'           => 20,\n\t'displayPostComments'    => true,\n\t'displayPostTag'         => true,\n\t'displayPostSocialshare' => true,\n\t'displayPostLink'        => true,\n\t'readMoreText'           => 'Read More',\n\t'readmoreView'           => 'pl-button',\n\t'titleTag'               => 'h3',\n\t'order'                  => 'desc',\n\t'orderBy'                => 'date',\n\t'align'                  => 'full',\n\t'width'                  => 'full',\n\t'isequalheight'          => true,\n);\n\n$list_attrs = array(\n\t'block_id'               => 'demolist1',\n\t'postsToShow'            => 4,\n\t'layoutopt'              => 'list',\n\t'layoutcount'            => 1,\n\t'postLayout'             => 'list',\n\t'displayPostImage'       => true,\n\t'imageCrop'              => 'square',\n\t'displayPostCategory'    => true,\n\t'displayPostAuthor'      => true,\n\t'displayPostDate'        => true,\n\t'displayPostExcerpt'     => true,\n\t'wordsExcerpt'           => 25,\n\t'displayPostComments'    => true,\n\t'displayPostTag'         => false,\n\t'displayPostSocialshare' => false,\n\t'displayPostLink'        => true,\n\t'readMoreText'           => 'Continue Reading',\n\t'readmoreView'           => 'text-only',\n\t'titleTag'               => 'h3',\n\t'order'                  => 'desc',\n\t'orderBy'                => 'date',\n\t'align'                  => 'full',\n\t'width'                  => 'full',\n\t'isequalheight'          => false,\n);\n\n// This block's own 'align'/'width' attributes don't do anything for real -\n// confirmed by grep: neither dist/blocks.style.build.css nor\n// dist/blocks.editor.build.css defines any .align-wide/.align-full/etc.\n// rule anywhere, so they're cosmetically inert. Genuine full-width (edge\n// to edge, breaking out of the theme's content column) instead comes from\n// wrapping each section in a core Group block with real align:full - the\n// theme (Astra here, confirmed via current_theme_supports('align-wide'))\n// renders that with its own supported CSS.\n$page_content  = \"<!-- wp:group {\\\"align\\\":\\\"full\\\",\\\"layout\\\":{\\\"type\\\":\\\"default\\\"}} -->\\n<div class=\\\"wp-block-group alignfull\\\">\\n\\n\";\n$page_content .= \"<!-- wp:heading --><h2>Grid Template</h2><!-- /wp:heading -->\\n\\n\";\n$page_content .= '<!-- wp:post-layouts/pl-blog-templates ' . wp_json_encode( $grid_attrs ) . ' /-->';\n$page_content .= \"\\n\\n</div>\\n<!-- /wp:group -->\\n\\n\";\n$page_content .= \"<!-- wp:group {\\\"align\\\":\\\"full\\\",\\\"layout\\\":{\\\"type\\\":\\\"default\\\"}} -->\\n<div class=\\\"wp-block-group alignfull\\\">\\n\\n\";\n$page_content .= \"<!-- wp:heading --><h2>List Template</h2><!-- /wp:heading -->\\n\\n\";\n$page_content .= '<!-- wp:post-layouts/pl-blog-templates ' . wp_json_encode( $list_attrs ) . ' /-->';\n$page_content .= \"\\n\\n</div>\\n<!-- /wp:group -->\";\n\n$page_id = wp_insert_post(\n\tarray(\n\t\t'post_title'   => 'Post Layouts Demo',\n\t\t'post_status'  => 'publish',\n\t\t'post_type'    => 'page',\n\t\t'post_content' => $page_content,\n\t),\n\ttrue\n);\nif ( is_wp_error( $page_id ) ) {\n\tthrow new RuntimeException( $page_id->get_error_message() );\n}\n\nupdate_option( 'show_on_front', 'page' );\nupdate_option( 'page_on_front', $page_id );\n"
        }
    ]
}
