/**
* Proto-Blocks Examples Knowledge Module
* Complete working examples from basic to expert level
*/
export function getExamplesKnowledge() {
return `# Proto-Blocks Examples: Complete Collection
Working examples from basic to expert level. Each example includes complete, ready-to-use code.
---
## Complexity Levels
| Level | Description | Features Used |
|-------|-------------|---------------|
| Basic | Simple blocks | 1-2 fields, minimal controls |
| Intermediate | Standard blocks | Multiple fields, controls, conditions |
| Advanced | Complex blocks | Repeaters, inner blocks, styling |
| Expert | Full-featured | Interactivity API, all features |
---
${getBasicExamples()}
${getIntermediateExamples()}
${getAdvancedExamples()}
${getExpertExamples()}
`;
}
export function getExampleByComplexity(complexity) {
switch (complexity) {
case 'basic':
return `# Basic Proto-Blocks Examples\n\n${getBasicExamples()}`;
case 'intermediate':
return `# Intermediate Proto-Blocks Examples\n\n${getIntermediateExamples()}`;
case 'advanced':
return `# Advanced Proto-Blocks Examples\n\n${getAdvancedExamples()}`;
case 'expert':
return `# Expert Proto-Blocks Examples\n\n${getExpertExamples()}`;
default:
return `Unknown complexity level: ${complexity}. Use: basic, intermediate, advanced, or expert.`;
}
}
function getBasicExamples() {
return `## Basic Examples
### 1. Simple Quote Block
A simple block with just text content.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/simple-quote",
"title": "Simple Quote",
"category": "proto-blocks",
"icon": "format-quote",
"description": "A simple quote block",
"supports": {
"html": false,
"anchor": true,
"color": {
"background": true,
"text": true
}
},
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"quote": {
"type": "wysiwyg"
},
"author": {
"type": "text",
"tagName": "cite"
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$quote = $attributes['quote'] ?? '';
$author = $attributes['author'] ?? '';
$wrapper_attributes = get_block_wrapper_attributes([
'class' => 'simple-quote',
]);
?>
<blockquote <?php echo $wrapper_attributes; ?>>
<div class="simple-quote__text" data-proto-field="quote">
<?php echo wp_kses_post($quote); ?>
</div>
<?php if ($author || !isset($block)) : ?>
<cite class="simple-quote__author" data-proto-field="author">
<?php echo esc_html($author); ?>
</cite>
<?php endif; ?>
</blockquote>
\`\`\`
**style.css**
\`\`\`css
.simple-quote {
padding: 1.5rem 2rem;
border-left: 4px solid #3b82f6;
background: #f8fafc;
font-style: italic;
}
.simple-quote__text {
font-size: 1.125rem;
line-height: 1.7;
margin-bottom: 0.75rem;
}
.simple-quote__author {
display: block;
font-style: normal;
font-weight: 600;
color: #64748b;
}
.simple-quote__author:empty::before {
content: 'Add author name';
color: #94a3b8;
}
\`\`\`
---
### 2. Call to Action Button
A simple button with link and customizable text.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/cta-button",
"title": "CTA Button",
"category": "proto-blocks",
"icon": "button",
"description": "A call-to-action button",
"supports": {
"html": false,
"align": ["left", "center", "right"]
},
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"link": {
"type": "link",
"tagName": "a"
}
},
"controls": {
"size": {
"type": "select",
"label": "Button Size",
"default": "medium",
"options": [
{ "key": "small", "label": "Small" },
{ "key": "medium", "label": "Medium" },
{ "key": "large", "label": "Large" }
]
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$link = $attributes['link'] ?? null;
$size = $attributes['size'] ?? 'medium';
$wrapper_attributes = get_block_wrapper_attributes([
'class' => 'cta-button-wrapper',
]);
?>
<div <?php echo $wrapper_attributes; ?>>
<a
href="<?php echo esc_url($link['url'] ?? '#'); ?>"
class="cta-button cta-button--<?php echo esc_attr($size); ?>"
data-proto-field="link"
<?php echo !empty($link['target']) ? 'target="' . esc_attr($link['target']) . '"' : ''; ?>
<?php echo !empty($link['rel']) ? 'rel="' . esc_attr($link['rel']) . '"' : ''; ?>
>
<?php echo esc_html($link['text'] ?? 'Click Here'); ?>
</a>
</div>
\`\`\`
**style.css**
\`\`\`css
.cta-button-wrapper {
display: flex;
}
.cta-button {
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: 600;
text-decoration: none;
background: #3b82f6;
color: white;
border-radius: 6px;
transition: background 0.2s;
}
.cta-button:hover {
background: #2563eb;
}
.cta-button--small {
padding: 0.5rem 1rem;
font-size: 0.875rem;
}
.cta-button--medium {
padding: 0.75rem 1.5rem;
font-size: 1rem;
}
.cta-button--large {
padding: 1rem 2rem;
font-size: 1.125rem;
}
\`\`\`
`;
}
function getIntermediateExamples() {
return `## Intermediate Examples
### 3. Feature Card
A card with image, title, description, and link.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/feature-card",
"title": "Feature Card",
"category": "proto-blocks",
"icon": "id-alt",
"description": "A feature card with image and content",
"supports": {
"html": false,
"anchor": true,
"align": ["wide"]
},
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"image": {
"type": "image",
"sizes": ["medium", "large"]
},
"title": {
"type": "text",
"tagName": "h3"
},
"description": {
"type": "wysiwyg"
},
"link": {
"type": "link"
}
},
"controls": {
"layout": {
"type": "select",
"label": "Layout",
"default": "vertical",
"options": [
{ "key": "vertical", "label": "Vertical" },
{ "key": "horizontal", "label": "Horizontal" }
]
},
"imagePosition": {
"type": "radio",
"label": "Image Position",
"default": "left",
"options": [
{ "key": "left", "label": "Left" },
{ "key": "right", "label": "Right" }
],
"conditions": {
"visible": {
"layout": ["horizontal"]
}
}
},
"showLink": {
"type": "toggle",
"label": "Show Link",
"default": true
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$image = $attributes['image'] ?? null;
$title = $attributes['title'] ?? '';
$description = $attributes['description'] ?? '';
$link = $attributes['link'] ?? null;
$layout = $attributes['layout'] ?? 'vertical';
$image_position = $attributes['imagePosition'] ?? 'left';
$show_link = $attributes['showLink'] ?? true;
$classes = ['feature-card', "feature-card--{$layout}"];
if ($layout === 'horizontal') {
$classes[] = "feature-card--image-{$image_position}";
}
$wrapper_attributes = get_block_wrapper_attributes([
'class' => implode(' ', $classes),
]);
?>
<article <?php echo $wrapper_attributes; ?>>
<div class="feature-card__image" data-proto-field="image">
<?php if ($image && !empty($image['url'])) : ?>
<img
src="<?php echo esc_url($image['url']); ?>"
alt="<?php echo esc_attr($image['alt'] ?? ''); ?>"
loading="lazy"
/>
<?php else : ?>
<div class="feature-card__image-placeholder">
<span>+</span>
</div>
<?php endif; ?>
</div>
<div class="feature-card__content">
<h3 class="feature-card__title" data-proto-field="title">
<?php echo esc_html($title); ?>
</h3>
<div class="feature-card__description" data-proto-field="description">
<?php echo wp_kses_post($description); ?>
</div>
<?php if ($show_link) : ?>
<a
href="<?php echo esc_url($link['url'] ?? '#'); ?>"
class="feature-card__link"
data-proto-field="link"
<?php echo !empty($link['target']) ? 'target="' . esc_attr($link['target']) . '"' : ''; ?>
>
<?php echo esc_html($link['text'] ?? 'Learn More'); ?> →
</a>
<?php endif; ?>
</div>
</article>
\`\`\`
**style.css**
\`\`\`css
.feature-card {
display: flex;
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.feature-card--vertical {
flex-direction: column;
}
.feature-card--horizontal {
flex-direction: row;
}
.feature-card--image-right {
flex-direction: row-reverse;
}
.feature-card__image {
flex-shrink: 0;
}
.feature-card--vertical .feature-card__image {
height: 200px;
}
.feature-card--horizontal .feature-card__image {
width: 40%;
}
.feature-card__image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.feature-card__image-placeholder {
width: 100%;
height: 100%;
min-height: 150px;
display: flex;
align-items: center;
justify-content: center;
background: #f1f5f9;
color: #94a3b8;
font-size: 2rem;
}
.feature-card__content {
flex: 1;
padding: 1.5rem;
}
.feature-card__title {
margin: 0 0 0.75rem;
font-size: 1.25rem;
font-weight: 600;
}
.feature-card__title:empty::before {
content: 'Enter title';
color: #94a3b8;
}
.feature-card__description {
color: #64748b;
margin-bottom: 1rem;
}
.feature-card__link {
display: inline-flex;
align-items: center;
gap: 0.25rem;
color: #3b82f6;
font-weight: 500;
text-decoration: none;
}
.feature-card__link:hover {
text-decoration: underline;
}
\`\`\`
---
### 4. Testimonial Block
A testimonial with quote, author info, and rating.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/testimonial",
"title": "Testimonial",
"category": "proto-blocks",
"icon": "testimonial",
"description": "Customer testimonial with rating",
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"quote": {
"type": "wysiwyg"
},
"authorImage": {
"type": "image",
"sizes": ["thumbnail"]
},
"authorName": {
"type": "text",
"tagName": "strong"
},
"authorTitle": {
"type": "text",
"tagName": "span"
}
},
"controls": {
"rating": {
"type": "range",
"label": "Star Rating",
"min": 1,
"max": 5,
"default": 5
},
"showAvatar": {
"type": "toggle",
"label": "Show Avatar",
"default": true
},
"style": {
"type": "select",
"label": "Style",
"default": "card",
"options": [
{ "key": "card", "label": "Card" },
{ "key": "minimal", "label": "Minimal" },
{ "key": "featured", "label": "Featured" }
]
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$quote = $attributes['quote'] ?? '';
$author_image = $attributes['authorImage'] ?? null;
$author_name = $attributes['authorName'] ?? '';
$author_title = $attributes['authorTitle'] ?? '';
$rating = $attributes['rating'] ?? 5;
$show_avatar = $attributes['showAvatar'] ?? true;
$style = $attributes['style'] ?? 'card';
$wrapper_attributes = get_block_wrapper_attributes([
'class' => "testimonial testimonial--{$style}",
]);
?>
<figure <?php echo $wrapper_attributes; ?>>
<?php if ($rating > 0) : ?>
<div class="testimonial__rating">
<?php for ($i = 1; $i <= 5; $i++) : ?>
<span class="testimonial__star <?php echo $i <= $rating ? 'is-filled' : ''; ?>">★</span>
<?php endfor; ?>
</div>
<?php endif; ?>
<blockquote class="testimonial__quote" data-proto-field="quote">
<?php echo wp_kses_post($quote); ?>
</blockquote>
<figcaption class="testimonial__author">
<?php if ($show_avatar) : ?>
<div class="testimonial__avatar" data-proto-field="authorImage">
<?php if ($author_image && !empty($author_image['url'])) : ?>
<img src="<?php echo esc_url($author_image['url']); ?>" alt="" />
<?php else : ?>
<span class="testimonial__avatar-placeholder">👤</span>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="testimonial__author-info">
<strong data-proto-field="authorName">
<?php echo esc_html($author_name); ?>
</strong>
<span data-proto-field="authorTitle">
<?php echo esc_html($author_title); ?>
</span>
</div>
</figcaption>
</figure>
\`\`\`
`;
}
function getAdvancedExamples() {
return `## Advanced Examples
### 5. Feature Grid (Repeater)
A grid of features using the repeater field.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/feature-grid",
"title": "Feature Grid",
"category": "proto-blocks",
"icon": "grid-view",
"description": "A grid of features with icons",
"supports": {
"html": false,
"align": ["wide", "full"]
},
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"heading": {
"type": "text",
"tagName": "h2"
},
"features": {
"type": "repeater",
"min": 1,
"max": 12,
"itemLabel": "title",
"collapsible": true,
"fields": {
"icon": {
"type": "image",
"sizes": ["thumbnail"]
},
"title": {
"type": "text",
"tagName": "h3"
},
"description": {
"type": "wysiwyg"
}
}
}
},
"controls": {
"columns": {
"type": "range",
"label": "Columns",
"min": 2,
"max": 4,
"default": 3
},
"showIcons": {
"type": "toggle",
"label": "Show Icons",
"default": true
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$heading = $attributes['heading'] ?? '';
$features = $attributes['features'] ?? [];
$columns = $attributes['columns'] ?? 3;
$show_icons = $attributes['showIcons'] ?? true;
// Default features for editor
if (empty($features)) {
$features = [
['icon' => null, 'title' => 'Feature 1', 'description' => ''],
['icon' => null, 'title' => 'Feature 2', 'description' => ''],
['icon' => null, 'title' => 'Feature 3', 'description' => ''],
];
}
$wrapper_attributes = get_block_wrapper_attributes([
'class' => 'feature-grid',
'style' => "--columns: {$columns};",
]);
?>
<section <?php echo $wrapper_attributes; ?>>
<?php if ($heading || !isset($block)) : ?>
<h2 class="feature-grid__heading" data-proto-field="heading">
<?php echo esc_html($heading); ?>
</h2>
<?php endif; ?>
<div class="feature-grid__items" data-proto-repeater="features">
<?php foreach ($features as $feature) : ?>
<article class="feature-grid__item" data-proto-repeater-item>
<?php if ($show_icons) : ?>
<div class="feature-grid__icon" data-proto-field="icon">
<?php if (!empty($feature['icon']['url'])) : ?>
<img src="<?php echo esc_url($feature['icon']['url']); ?>" alt="" />
<?php else : ?>
<span class="feature-grid__icon-placeholder">✦</span>
<?php endif; ?>
</div>
<?php endif; ?>
<h3 class="feature-grid__title" data-proto-field="title">
<?php echo esc_html($feature['title'] ?? ''); ?>
</h3>
<div class="feature-grid__description" data-proto-field="description">
<?php echo wp_kses_post($feature['description'] ?? ''); ?>
</div>
</article>
<?php endforeach; ?>
</div>
</section>
\`\`\`
**style.css**
\`\`\`css
.feature-grid {
padding: 3rem 0;
}
.feature-grid__heading {
text-align: center;
margin: 0 0 2.5rem;
font-size: 2rem;
}
.feature-grid__items {
display: grid;
grid-template-columns: repeat(var(--columns, 3), 1fr);
gap: 2rem;
}
@media (max-width: 768px) {
.feature-grid__items {
grid-template-columns: 1fr;
}
}
.feature-grid__item {
text-align: center;
padding: 1.5rem;
}
.feature-grid__icon {
width: 64px;
height: 64px;
margin: 0 auto 1rem;
}
.feature-grid__icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.feature-grid__icon-placeholder {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: #f1f5f9;
border-radius: 12px;
font-size: 1.5rem;
}
.feature-grid__title {
margin: 0 0 0.5rem;
font-size: 1.125rem;
}
.feature-grid__description {
color: #64748b;
font-size: 0.9375rem;
}
\`\`\`
---
### 6. Hero Section (Inner Blocks)
A hero section with inner blocks for flexible content.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/hero",
"title": "Hero Section",
"category": "proto-blocks",
"icon": "cover-image",
"description": "A hero section with background image",
"supports": {
"html": false,
"align": ["full"]
},
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"backgroundImage": {
"type": "image",
"sizes": ["large", "full"]
},
"content": {
"type": "innerblocks",
"allowedBlocks": [
"core/heading",
"core/paragraph",
"core/buttons"
],
"template": [
["core/heading", { "level": 1, "placeholder": "Hero Title", "textAlign": "center" }],
["core/paragraph", { "placeholder": "Hero description goes here...", "align": "center" }],
["core/buttons", { "layout": { "justifyContent": "center" } }, [
["core/button", { "text": "Get Started" }]
]]
]
}
},
"controls": {
"minHeight": {
"type": "range",
"label": "Minimum Height (vh)",
"min": 30,
"max": 100,
"default": 60
},
"overlayOpacity": {
"type": "range",
"label": "Overlay Opacity",
"min": 0,
"max": 100,
"default": 40
},
"overlayColor": {
"type": "color",
"label": "Overlay Color",
"default": "#000000"
},
"contentWidth": {
"type": "select",
"label": "Content Width",
"default": "medium",
"options": [
{ "key": "narrow", "label": "Narrow" },
{ "key": "medium", "label": "Medium" },
{ "key": "wide", "label": "Wide" }
]
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$bg_image = $attributes['backgroundImage'] ?? null;
$min_height = $attributes['minHeight'] ?? 60;
$overlay_opacity = ($attributes['overlayOpacity'] ?? 40) / 100;
$overlay_color = $attributes['overlayColor'] ?? '#000000';
$content_width = $attributes['contentWidth'] ?? 'medium';
$bg_style = $bg_image && !empty($bg_image['url'])
? "background-image: url('" . esc_url($bg_image['url']) . "');"
: '';
$wrapper_attributes = get_block_wrapper_attributes([
'class' => 'hero',
'style' => "min-height: {$min_height}vh; {$bg_style}",
]);
// Convert hex to rgba
$hex = ltrim($overlay_color, '#');
$r = hexdec(substr($hex, 0, 2));
$g = hexdec(substr($hex, 2, 2));
$b = hexdec(substr($hex, 4, 2));
$overlay_rgba = "rgba({$r}, {$g}, {$b}, {$overlay_opacity})";
?>
<section <?php echo $wrapper_attributes; ?>>
<?php if (!$bg_image || empty($bg_image['url'])) : ?>
<div class="hero__bg-placeholder" data-proto-field="backgroundImage">
Click to add background image
</div>
<?php endif; ?>
<div class="hero__overlay" style="background-color: <?php echo esc_attr($overlay_rgba); ?>;"></div>
<div class="hero__content hero__content--<?php echo esc_attr($content_width); ?>" data-proto-inner-blocks>
<?php echo $content; ?>
</div>
</section>
\`\`\`
**style.css**
\`\`\`css
.hero {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
background-position: center;
color: white;
}
.hero__bg-placeholder {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: rgba(255, 255, 255, 0.7);
cursor: pointer;
}
.hero__overlay {
position: absolute;
inset: 0;
pointer-events: none;
}
.hero__content {
position: relative;
z-index: 1;
padding: 3rem 1.5rem;
width: 100%;
}
.hero__content--narrow {
max-width: 600px;
}
.hero__content--medium {
max-width: 800px;
}
.hero__content--wide {
max-width: 1000px;
}
\`\`\`
`;
}
function getExpertExamples() {
return `## Expert Examples
### 7. Accordion (Interactivity API)
A fully interactive accordion with the WordPress Interactivity API.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/accordion",
"title": "Accordion",
"category": "proto-blocks",
"icon": "list-view",
"description": "Interactive accordion with multiple sections",
"supports": {
"html": false,
"interactivity": true
},
"viewScriptModule": "file:./view.js",
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"fields": {
"items": {
"type": "repeater",
"min": 1,
"max": 20,
"itemLabel": "title",
"collapsible": true,
"fields": {
"title": {
"type": "text",
"tagName": "span"
},
"content": {
"type": "wysiwyg"
}
}
}
},
"controls": {
"allowMultiple": {
"type": "toggle",
"label": "Allow Multiple Open",
"default": false
},
"firstOpen": {
"type": "toggle",
"label": "First Item Open",
"default": true
},
"iconPosition": {
"type": "radio",
"label": "Icon Position",
"default": "right",
"options": [
{ "key": "left", "label": "Left" },
{ "key": "right", "label": "Right" }
]
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$items = $attributes['items'] ?? [];
$allow_multiple = $attributes['allowMultiple'] ?? false;
$first_open = $attributes['firstOpen'] ?? true;
$icon_position = $attributes['iconPosition'] ?? 'right';
// Default items for editor
if (empty($items)) {
$items = [
['title' => 'Section 1', 'content' => '<p>Content for section 1...</p>'],
['title' => 'Section 2', 'content' => '<p>Content for section 2...</p>'],
['title' => 'Section 3', 'content' => '<p>Content for section 3...</p>'],
];
}
$context = [
'allowMultiple' => $allow_multiple,
'openItems' => $first_open ? [0] : [],
];
$wrapper_attributes = get_block_wrapper_attributes([
'class' => "accordion accordion--icon-{$icon_position}",
'data-wp-interactive' => 'proto-blocks/accordion',
'data-wp-context' => wp_json_encode($context),
]);
?>
<div <?php echo $wrapper_attributes; ?> data-proto-repeater="items">
<?php foreach ($items as $index => $item) : ?>
<div
class="accordion__item"
data-proto-repeater-item
data-wp-context='{"index": <?php echo $index; ?>}'
data-wp-class--is-open="state.isOpen"
>
<button
class="accordion__trigger"
type="button"
data-wp-on--click="actions.toggle"
aria-expanded="false"
data-wp-bind--aria-expanded="state.isOpen"
>
<span class="accordion__title" data-proto-field="title">
<?php echo esc_html($item['title'] ?? ''); ?>
</span>
<span class="accordion__icon" aria-hidden="true" data-wp-text="state.icon"></span>
</button>
<div
class="accordion__panel"
data-wp-bind--hidden="!state.isOpen"
>
<div class="accordion__content" data-proto-field="content">
<?php echo wp_kses_post($item['content'] ?? ''); ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
\`\`\`
**view.js**
\`\`\`javascript
import { store, getContext } from '@wordpress/interactivity';
store('proto-blocks/accordion', {
state: {
get isOpen() {
const context = getContext();
return context.openItems.includes(context.index);
},
get icon() {
const context = getContext();
return context.openItems.includes(context.index) ? '−' : '+';
},
},
actions: {
toggle() {
const context = getContext();
const { index, allowMultiple, openItems } = context;
if (openItems.includes(index)) {
// Close this item
context.openItems = openItems.filter(i => i !== index);
} else {
// Open this item
if (allowMultiple) {
context.openItems = [...openItems, index];
} else {
context.openItems = [index];
}
}
},
},
});
\`\`\`
**style.css**
\`\`\`css
.accordion {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.accordion__item {
border-bottom: 1px solid #e2e8f0;
}
.accordion__item:last-child {
border-bottom: none;
}
.accordion__trigger {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 1rem 1.25rem;
background: #f8fafc;
border: none;
cursor: pointer;
text-align: left;
font-size: 1rem;
font-weight: 500;
transition: background 0.2s;
}
.accordion--icon-left .accordion__trigger {
flex-direction: row-reverse;
}
.accordion__trigger:hover {
background: #f1f5f9;
}
.accordion__item.is-open .accordion__trigger {
background: #e2e8f0;
}
.accordion__icon {
font-size: 1.25rem;
font-weight: 300;
color: #64748b;
}
.accordion__panel {
overflow: hidden;
}
.accordion__panel[hidden] {
display: none;
}
.accordion__content {
padding: 1.25rem;
background: white;
}
.accordion__content p:last-child {
margin-bottom: 0;
}
\`\`\`
---
### 8. Tailwind Card (Complete Example)
A complete card using Tailwind CSS with all features.
**block.json**
\`\`\`json
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "proto-blocks/tailwind-card",
"title": "Tailwind Card",
"category": "proto-blocks",
"icon": "id-alt",
"description": "A feature card styled with Tailwind CSS",
"protoBlocks": {
"version": "1.0",
"template": "template.php",
"useTailwind": true,
"fields": {
"image": {
"type": "image",
"sizes": ["medium", "large"]
},
"badge": {
"type": "text",
"tagName": "span"
},
"title": {
"type": "text",
"tagName": "h3"
},
"description": {
"type": "wysiwyg"
},
"link": {
"type": "link"
}
},
"controls": {
"variant": {
"type": "select",
"label": "Card Variant",
"default": "default",
"options": [
{ "key": "default", "label": "Default" },
{ "key": "elevated", "label": "Elevated" },
{ "key": "bordered", "label": "Bordered" }
]
},
"showBadge": {
"type": "toggle",
"label": "Show Badge",
"default": true
}
}
}
}
\`\`\`
**template.php**
\`\`\`php
<?php
$image = $attributes['image'] ?? null;
$badge = $attributes['badge'] ?? '';
$title = $attributes['title'] ?? '';
$description = $attributes['description'] ?? '';
$link = $attributes['link'] ?? null;
$variant = $attributes['variant'] ?? 'default';
$show_badge = $attributes['showBadge'] ?? true;
$variant_classes = [
'default' => 'bg-white',
'elevated' => 'bg-white shadow-lg hover:shadow-xl',
'bordered' => 'bg-white border-2 border-gray-200',
];
$wrapper_attributes = get_block_wrapper_attributes([
'class' => 'group rounded-xl overflow-hidden transition-all duration-300 ' . ($variant_classes[$variant] ?? $variant_classes['default']),
]);
?>
<article <?php echo $wrapper_attributes; ?>>
<div class="relative aspect-video overflow-hidden" data-proto-field="image">
<?php if ($image && !empty($image['url'])) : ?>
<img
src="<?php echo esc_url($image['url']); ?>"
alt="<?php echo esc_attr($image['alt'] ?? ''); ?>"
class="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
/>
<?php else : ?>
<div class="w-full h-full bg-gradient-to-br from-primary-100 to-primary-200 flex items-center justify-center">
<span class="text-primary-400 text-4xl">+</span>
</div>
<?php endif; ?>
<?php if ($show_badge) : ?>
<span
class="absolute top-3 left-3 px-3 py-1 bg-primary-600 text-white text-xs font-medium rounded-full"
data-proto-field="badge"
>
<?php echo esc_html($badge ?: 'Featured'); ?>
</span>
<?php endif; ?>
</div>
<div class="p-6">
<h3
class="text-xl font-bold text-gray-900 mb-2 empty:before:content-['Enter_title'] empty:before:text-gray-400"
data-proto-field="title"
>
<?php echo esc_html($title); ?>
</h3>
<div
class="text-gray-600 mb-4 [&>p:last-child]:mb-0"
data-proto-field="description"
>
<?php echo wp_kses_post($description); ?>
</div>
<a
href="<?php echo esc_url($link['url'] ?? '#'); ?>"
class="inline-flex items-center gap-1 text-primary-600 font-semibold hover:text-primary-700 transition-colors"
data-proto-field="link"
<?php echo !empty($link['target']) ? 'target="' . esc_attr($link['target']) . '"' : ''; ?>
>
<?php echo esc_html($link['text'] ?? 'Learn More'); ?>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</a>
</div>
</article>
\`\`\`
`;
}