Skip to content

Commit d93876f

Browse files
committed
feat(skill): enhance WordPress Block Pattern Validator with new validation checks for fontFamily attributes, font size classes, and non-WordPress comments
1 parent ef4325c commit d93876f

3 files changed

Lines changed: 236 additions & 2 deletions

File tree

.github/skills/wordpress-block-pattern-validator/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Validates and automatically fixes WordPress block pattern files to ensure HTML o
44

55
## Recent Updates
66

7+
**Comment Validation** - Now detects and flags non-WordPress block comments (descriptive HTML comments) that shouldn't exist in block templates!
8+
9+
**Critical Block Validation Error Detection** - Now detects redundant `fontFamily` attributes and malformed font size classes that cause WordPress editor validation errors!
10+
711
**Button Block Handling** - The validator now correctly validates button blocks by checking the inner `<a class="wp-block-button__link">` tag instead of the wrapper div, matching WordPress core rendering behavior. No more false positives!
812

913
**Custom Notation Support** - Now handles both `var:preset|` and `var:custom|` notation for colors, spacing, typography, and border properties.
@@ -43,6 +47,60 @@ node validate-patterns.cjs patterns/ --fix --dry-run
4347

4448
## What It Checks
4549

50+
### ⚠️ Critical Block Validation Errors
51+
52+
#### Redundant Font Family Attributes
53+
Detects when `fontFamily` is specified in block attributes but will be stripped by WordPress (causing validation errors):
54+
55+
```html
56+
<!-- ❌ CAUSES VALIDATION ERROR -->
57+
<!-- wp:heading {"style":{"typography":{"fontFamily":"var:preset|font-family|roboto-serif"}}} -->
58+
<h3 class="wp-block-heading">Text</h3>
59+
60+
<!-- ✅ FIXED - fontFamily removed -->
61+
<!-- wp:heading {} -->
62+
<h3 class="wp-block-heading">Text</h3>
63+
```
64+
65+
#### Malformed Font Size Classes
66+
Catches typos in font size class names:
67+
68+
```html
69+
<!-- ❌ WRONG - extra dash causes validation error -->
70+
<!-- wp:heading {"fontSize":"h3"} -->
71+
<h3 class="wp-block-heading has-h-3-font-size">Text</h3>
72+
73+
<!-- ✅ CORRECT -->
74+
<!-- wp:heading {"fontSize":"h3"} -->
75+
<h3 class="wp-block-heading has-h3-font-size">Text</h3>
76+
```
77+
78+
#### Invalid HTML Comments (Non-WordPress Block Comments)
79+
Detects descriptive HTML comments that shouldn't exist in block templates:
80+
81+
```html
82+
<!-- ❌ INVALID - Descriptive comment not allowed -->
83+
<!-- Social Media Icons -->
84+
<!-- wp:social-links {...} -->
85+
<ul class="wp-block-social-links">...</ul>
86+
<!-- /wp:social-links -->
87+
88+
<!-- ✅ VALID - Only WordPress block comments -->
89+
<!-- wp:social-links {...} -->
90+
<ul class="wp-block-social-links is-style-logos-only header-social">...</ul>
91+
<!-- /wp:social-links -->
92+
```
93+
94+
**Valid comments:**
95+
- `<!-- wp:blockname {...} -->` (opening block)
96+
- `<!-- /wp:blockname -->` (closing block)
97+
- `<!-- wp:namespace/blockname {...} -->` (third-party blocks like WooCommerce)
98+
99+
**Invalid comments (will be flagged):**
100+
- `<!-- Social Media Icons -->`
101+
- `<!-- Top Navigation Links -->`
102+
- `<!-- Newsletter Section -->`
103+
46104
### ✅ Color Classes
47105
- `backgroundColor``has-{color}-background-color has-background`
48106
- `textColor``has-{color}-color has-text-color`

.github/skills/wordpress-block-pattern-validator/SKILL.md

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,115 @@
22

33
## Description
44

5-
Expert in validating and fixing WordPress block pattern files to ensure HTML output matches block comment attributes according to WordPress core rendering rules. Detects and corrects mismatches between block attributes (JSON in comments) and their corresponding HTML output.
5+
Expert in validating and fixing WordPress block pattern files to ensure HTML output matches block comment attributes according to WordPress core rendering rules. Detects and corrects mismatches between block attributes (JSON in comments) and their corresponding HTML output, including redundant fontFamily attributes and malformed font size classes that cause block validation errors.
66

77
## Capabilities
88

99
- Parse WordPress block comments and extract JSON attributes
1010
- Validate HTML output against WordPress core rendering rules
1111
- Detect missing or incorrect CSS classes
1212
- Detect missing or incorrect inline styles
13+
- **Detect redundant `fontFamily` attributes that WordPress strips on save**
14+
- **Detect malformed font size classes (e.g., `has-h-3-font-size` vs `has-h3-font-size`)**
15+
- **Detect and flag non-WordPress block comments (descriptive HTML comments)**
1316
- Auto-fix common rendering errors in pattern files
1417
- Scan multiple pattern files for validation errors
1518
- Generate validation reports with line-by-line error details
1619

20+
## Critical Block Validation Error Checks
21+
22+
### Redundant Font Family Attributes
23+
24+
WordPress optimizes saved content by stripping CSS properties that match theme defaults. This causes block validation errors when:
25+
26+
**Problem:**
27+
- Block attributes include: `"style":{"typography":{"fontFamily":"var:preset|font-family|roboto-serif"}}`
28+
- WordPress renders it in the editor with: `style="font-family:var(--wp--preset--font-family--roboto-serif)"`
29+
- But the saved database content omits it (because it matches the theme default)
30+
- Result: **Block validation error**
31+
32+
**Solution:**
33+
- Remove `fontFamily` from block attributes if it matches your `theme.json` default
34+
- The validator detects this pattern and warns you
35+
36+
**Example:**
37+
```html
38+
<!-- BEFORE (causes validation error) -->
39+
<!-- wp:heading {"style":{"typography":{"fontFamily":"var:preset|font-family|roboto-serif"}}} -->
40+
<h3 class="wp-block-heading">Text</h3>
41+
42+
<!-- AFTER (no validation error) -->
43+
<!-- wp:heading {} -->
44+
<h3 class="wp-block-heading">Text</h3>
45+
```
46+
47+
### Malformed Font Size Classes
48+
49+
Typos in font size class names cause block validation mismatches.
50+
51+
**Problem:**
52+
- Block attributes: `"fontSize":"h3"`
53+
- Expected HTML: `class="wp-block-heading has-h3-font-size"`
54+
- Actual HTML: `class="wp-block-heading has-h-3-font-size"` (extra dash)
55+
- Result: **Block validation error**
56+
57+
**Solution:**
58+
- Ensure font size class matches the pattern: `has-{fontSize}-font-size`
59+
- No extra dashes or characters in the slug
60+
61+
**Example:**
62+
```html
63+
<!-- WRONG (causes validation error) -->
64+
<!-- wp:heading {"fontSize":"h3"} -->
65+
<h3 class="wp-block-heading has-h-3-font-size">Text</h3>
66+
67+
<!-- CORRECT (no validation error) -->
68+
<!-- wp:heading {"fontSize":"h3"} -->
69+
<h3 class="wp-block-heading has-h3-font-size">Text</h3>
70+
```
71+
72+
### Invalid HTML Comments (Non-WordPress Block Comments)
73+
74+
WordPress block templates and patterns should **only** contain WordPress block comments. Descriptive HTML comments are not allowed and may interfere with block parsing.
75+
76+
**Problem:**
77+
- Template contains descriptive comments like: `<!-- Social Media Icons -->`, `<!-- Top Navigation Links -->`, `<!-- Newsletter Section -->`
78+
- These are standard HTML comments, not WordPress block comments
79+
- WordPress block template parser expects only block-related comments
80+
- Result: **Potential parsing issues** ❌ and template pollution
81+
82+
**Valid WordPress Block Comments:**
83+
- Opening block: `<!-- wp:blockname {...} -->`
84+
- Closing block: `<!-- /wp:blockname -->`
85+
- Third-party blocks: `<!-- wp:namespace/blockname {...} -->` (e.g., `<!-- wp:woocommerce/mini-cart -->`)
86+
87+
**Invalid Comments (will be flagged):**
88+
- `<!-- Social Media Icons -->`
89+
- `<!-- Top Navigation Links -->`
90+
- `<!-- Newsletter CTA Section -->`
91+
- `<!-- Column 1: About Us -->`
92+
93+
**Solution:**
94+
- Remove ALL descriptive HTML comments from block templates
95+
- WordPress block structure should be self-documenting through proper nesting and block types
96+
- Use meaningful class names instead of comments to identify sections
97+
98+
**Example:**
99+
```html
100+
<!-- WRONG (validator will flag these) -->
101+
<!-- Social Media Icons -->
102+
<!-- wp:social-links {...} -->
103+
<ul class="wp-block-social-links">...</ul>
104+
<!-- /wp:social-links -->
105+
106+
<!-- CORRECT (no descriptive comments) -->
107+
<!-- wp:social-links {...} -->
108+
<ul class="wp-block-social-links is-style-logos-only header-social">...</ul>
109+
<!-- /wp:social-links -->
110+
```
111+
112+
Note: The validator checks for any HTML comment that doesn't start with `wp:` or `/wp:` and flags it as an error.
113+
17114
## Common WordPress Block Rendering Rules
18115

19116
### Color Attributes

.github/skills/wordpress-block-pattern-validator/validate-patterns.cjs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ class WordPressBlockValidator {
220220
const errors = [];
221221
const missingClasses = [];
222222
const extraClasses = [];
223+
const warnings = [];
223224

224225
// Check for missing classes
225226
expectedClasses.forEach(expectedClass => {
@@ -244,14 +245,46 @@ class WordPressBlockValidator {
244245
}
245246
}
246247

247-
if (missingClasses.length > 0 || missingStyles.length > 0) {
248+
// NEW CHECK: Detect redundant fontFamily that WordPress strips
249+
if (block.attributes.style?.typography?.fontFamily) {
250+
const fontFamilyValue = this.convertPresetNotation(block.attributes.style.typography.fontFamily);
251+
if (html.styles && html.styles.includes(`font-family:${fontFamilyValue}`)) {
252+
warnings.push({
253+
type: 'redundant-font-family',
254+
message: `Block has fontFamily in attributes that appears in HTML but WordPress may strip it if it matches theme default: ${fontFamilyValue}`,
255+
fix: 'Remove fontFamily from block attributes if it matches your theme.json default',
256+
});
257+
}
258+
}
259+
260+
// NEW CHECK: Detect malformed font size classes (e.g., has-h-3-font-size instead of has-h3-font-size)
261+
if (block.attributes.fontSize) {
262+
const expectedFontSizeClass = `has-${block.attributes.fontSize}-font-size`;
263+
// Check for common typo: extra dashes in font size slug
264+
const malformedPattern = html.classes.find(cls => {
265+
return cls.startsWith('has-') && cls.endsWith('-font-size') && cls !== expectedFontSizeClass;
266+
});
267+
268+
if (malformedPattern && !html.classes.includes(expectedFontSizeClass)) {
269+
warnings.push({
270+
type: 'malformed-font-size-class',
271+
message: `Font size class is malformed: "${malformedPattern}" should be "${expectedFontSizeClass}"`,
272+
current: malformedPattern,
273+
expected: expectedFontSizeClass,
274+
fix: `Change "${malformedPattern}" to "${expectedFontSizeClass}"`,
275+
});
276+
}
277+
}
278+
279+
if (missingClasses.length > 0 || missingStyles.length > 0 || warnings.length > 0) {
248280
return {
249281
lineNumber,
250282
blockType: block.blockType,
251283
blockComment,
252284
htmlTag,
253285
missingClasses,
254286
missingStyles,
287+
warnings,
255288
expectedClasses,
256289
expectedStyles,
257290
currentClasses: html.classes,
@@ -309,6 +342,35 @@ class WordPressBlockValidator {
309342
for (let i = 0; i < lines.length; i++) {
310343
const line = lines[i];
311344

345+
// Check for non-WordPress block comments (these are not allowed)
346+
const htmlCommentMatch = line.match(/<!--\s*(.+?)\s*-->/);
347+
if (htmlCommentMatch) {
348+
const commentContent = htmlCommentMatch[1].trim();
349+
// Valid WordPress block comments start with "wp:" or "/wp:"
350+
const isWordPressComment = commentContent.startsWith('wp:') || commentContent.startsWith('/wp:');
351+
352+
if (!isWordPressComment) {
353+
fileErrors.push({
354+
lineNumber: i + 1,
355+
blockType: 'invalid-comment',
356+
blockComment: line,
357+
htmlTag: '',
358+
missingClasses: [],
359+
missingStyles: [],
360+
warnings: [{
361+
type: 'non-wordpress-comment',
362+
message: `Invalid comment: Only WordPress block comments are allowed`,
363+
current: htmlCommentMatch[0],
364+
fix: 'Remove this comment. WordPress block templates should only contain block comments (<!-- wp:blocktype --> or <!-- /wp:blocktype -->)',
365+
}],
366+
expectedClasses: [],
367+
expectedStyles: '',
368+
currentClasses: [],
369+
currentStyles: '',
370+
});
371+
}
372+
}
373+
312374
// Check if this is a WordPress block comment
313375
if (line.includes('<!-- wp:')) {
314376
// Get the next non-empty line
@@ -378,6 +440,23 @@ class WordPressBlockValidator {
378440
console.log(` Block: ${error.blockType} (Line ${error.lineNumber})`);
379441
console.log(` HTML Tag: Line ${error.htmlLineNumber}`);
380442

443+
// Show warnings first (these are critical issues causing validation errors)
444+
if (error.warnings && error.warnings.length > 0) {
445+
error.warnings.forEach(warning => {
446+
if (warning.type === 'non-wordpress-comment') {
447+
console.log(` ⚠️ ERROR: ${warning.message}`);
448+
console.log(` Comment: ${warning.current}`);
449+
console.log(` Fix: ${warning.fix}`);
450+
} else if (warning.type === 'malformed-font-size-class') {
451+
console.log(` ⚠️ CRITICAL: ${warning.message}`);
452+
console.log(` Fix: ${warning.fix}`);
453+
} else if (warning.type === 'redundant-font-family') {
454+
console.log(` ⚠️ WARNING: ${warning.message}`);
455+
console.log(` Fix: ${warning.fix}`);
456+
}
457+
});
458+
}
459+
381460
if (error.missingClasses.length > 0) {
382461
console.log(` Missing classes: ${error.missingClasses.join(', ')}`);
383462
}

0 commit comments

Comments
 (0)