Skip to main content Accueil Créateurs petenelson wp-rest-api-log 10up-block-development
10up-block-development Create and modify Gutenberg blocks following 10up engineering standards. Covers block.json metadata, dynamic rendering with PHP, attributes, deprecations, editor components, and the useBlockProps pattern. Use when creating new blocks, fixing block errors, or modifying existing block code.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/petenelson/wp-rest-api-log --skill 10up-block-developmentLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Métiers associés SOC
Basé sur la classification professionnelle SOC
Explorateur de fichiers
3 fichiers name 10up-block-development description Create and modify Gutenberg blocks following 10up engineering standards. Covers block.json metadata, dynamic rendering with PHP, attributes, deprecations, editor components, and the useBlockProps pattern. Use when creating new blocks, fixing block errors, or modifying existing block code. license MIT compatibility WordPress 6.4+, PHP 8.0+, 10up-toolkit or @wordpress/scripts globs ["includes/blocks/**/*","src/blocks/**/*","blocks/**/*","**/block.json","**/edit.js","**/save.js","**/markup.php"] metadata {"author":"10up","version":"1.0"}
10up Block Development
This skill guides you through creating and modifying Gutenberg blocks following 10up engineering standards.
When to Use
Creating a new custom block
Modifying an existing block's attributes or behavior
Fixing "Invalid block" errors
Adding block settings or controls
Migrating blocks (deprecations)
Key Principle: Dynamic Blocks
10up Standard: Always use dynamic blocks with PHP rendering for client projects.
Markup stored in database stays minimal (just attributes)
Site-wide updates without re-editing posts
Complex logic handled server-side
Better long-term maintainability
Procedure
Step 0: Verify Prerequisites
Confirm build tools are available (10up-toolkit or @wordpress/scripts)
Identify the target directory (usually /blocks/ or /includes/blocks/)
Check existing blocks for naming conventions
Step 1: Define Block Structure Create the block directory with these files:
blocks/block-name/
├── block.json # Block metadata (required)
├── index.js # Block registration
├── edit.js # Editor component
├── markup.php # Server-side rendering (10up standard)
├── save.js # Save function (returns null for dynamic)
└── style.css # Block styles (optional)
Step 2: Configure block.json {
"$schema" : "https://schemas.wp.org/trunk/block.json" ,
"apiVersion" : 3 ,
"name" : "namespace/block-name" ,
"version" : "1.0.0" ,
"title" : "Block Title" ,
"category" : "common" ,
"description" : "What this block does" ,
"textdomain" : "theme-or-plugin" ,
"attributes" : { } ,
"supports" : { } ,
"editorScript" : "file:./index.js" ,
"render" : "file:./markup.php"
}
{
"attributes" : {
"title" : {
"type" : "string" ,
"default" : ""
} ,
"showImage" : {
"type" : "boolean" ,
"default" : true
} ,
"columns" : {
"type" : "number" ,
"default" : 3
} ,
"items" : {
"type" : "array" ,
"default" : [ ]
}
}
}
Step 3: Create the Editor Component (edit.js) Standard pattern using useBlockProps:
import { useBlockProps, RichText , InspectorControls } from '@wordpress/block-editor' ;
import { PanelBody , ToggleControl , RangeControl } from '@wordpress/components' ;
import { __ } from '@wordpress/i18n' ;
export const BlockEdit = ({ attributes, setAttributes } ) => {
const { title, showImage, columns } = attributes;
const blockProps = useBlockProps ({
className : `columns-${columns} `
});
return (
<>
<InspectorControls >
<PanelBody title ={__( 'Settings ', 'textdomain ')}>
<ToggleControl
label ={__( 'Show Image ', 'textdomain ')}
checked ={showImage}
onChange ={(value) => setAttributes({ showImage: value })}
/>
<RangeControl
label ={__( 'Columns ', 'textdomain ')}
value ={columns}
onChange ={(value) => setAttributes({ columns: value })}
min={1}
max={6}
/>
</PanelBody >
</InspectorControls >
<div {...blockProps }>
<RichText
tagName ="h2"
value ={title}
onChange ={(value) => setAttributes({ title: value })}
placeholder={__('Enter title...', 'textdomain')}
/>
</div >
</>
);
};
Content (text, images) → Main block area with inline editing
Settings (toggles, selects) → Inspector sidebar
Always provide default values
Use placeholder text for empty RichText
Step 4: Create the Save Function (save.js) For dynamic blocks (10up standard):
export const BlockSave = ( ) => {
return null ;
};
Returning null tells WordPress to use server-side rendering.
Step 5: Create PHP Render Template (markup.php) <?php
$title = $attributes ['title' ] ?? '' ;
$show_image = $attributes ['showImage' ] ?? true ;
$columns = $attributes ['columns' ] ?? 3 ;
$wrapper_attributes = get_block_wrapper_attributes ([
'class' => sprintf ('columns-%d' , $columns ),
]);
?>
<div <?php echo $wrapper_attributes ; ?> >
<?php if ($title ) : ?>
<h2><?php echo wp_kses_post ($title ); ?> </h2>
<?php endif ; ?>
<?php if ($show_image ) : ?>
<!-- Image markup -->
<?php endif ; ?>
<?php
echo $content ;
?>
</div>
Use get_block_wrapper_attributes() for proper block wrapper
Escape output: esc_html(), esc_attr(), wp_kses_post()
$content contains inner blocks (already escaped by WordPress)
Step 6: Register the Block (index.js) import { registerBlockType } from '@wordpress/blocks' ;
import metadata from './block.json' ;
import { BlockEdit } from './edit' ;
import { BlockSave } from './save' ;
registerBlockType (metadata.name , {
edit : BlockEdit ,
save : BlockSave ,
});
Step 7: Handle Block Deprecations When changing attributes or markup, add deprecations to prevent "Invalid block" errors:
const deprecated = [
{
attributes : {
oldAttribute : {
type : 'string' ,
},
},
migrate (attributes ) {
return {
...attributes,
newAttribute : attributes.oldAttribute ,
};
},
save ( ) {
return null ;
},
},
];
registerBlockType (metadata.name , {
edit : BlockEdit ,
save : BlockSave ,
deprecated,
});
Verification After creating/modifying a block:
Build assets: npm run build
Clear browser cache
Add block in editor - should appear without errors
Save post and view frontend
Check browser console for JavaScript errors
Verify existing blocks still validate (no "Invalid block")
Failure Modes
Attributes changed without deprecation
Save function output doesn't match stored content
Solution: Add deprecation entry with migrate function
Block not appearing in inserter:
Category doesn't exist
Block not registered (check console)
Build not complete
Missing useBlockProps in edit.js
Missing get_block_wrapper_attributes() in PHP
CSS not enqueued (check block.json paths)
Type mismatch in block.json
Missing setAttributes call
Invalid attribute name
Escalation
Unsure about attribute types for complex data
Block requires integration with external APIs
Existing deprecation chain is complex
Performance concerns with rendering