initial commit
This commit is contained in:
parent
d066133bd4
commit
e6f71e3706
55 changed files with 11928 additions and 0 deletions
264
native/wordpress/maple-fonts-wp/CLAUDE.md
Normal file
264
native/wordpress/maple-fonts-wp/CLAUDE.md
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
# CLAUDE.md — Maple Local Fonts WordPress Plugin
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Document | When to Reference |
|
||||
|----------|-------------------|
|
||||
| **CLAUDE.md** (this file) | Architecture, file structure, build order |
|
||||
| **SECURITY.md** | Writing ANY PHP code |
|
||||
| **GOOGLE_FONTS_API.md** | Building the font downloader class |
|
||||
| **WORDPRESS_COMPATIBILITY.md** | Building the font registry, FSE integration |
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
Build a WordPress plugin called **Maple Local Fonts** that:
|
||||
1. Imports Google Fonts to local storage (one-time download)
|
||||
2. Registers them with WordPress's native Font Library API
|
||||
3. Fonts appear in FSE typography dropdowns alongside theme fonts
|
||||
|
||||
**Key principle:** Work WITH WordPress, not around it. We're a font importer — WordPress handles everything else.
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Minimum PHP:** 7.4
|
||||
- **Minimum WordPress:** 6.5 (required for Font Library API)
|
||||
- **License:** GPL-2.0-or-later
|
||||
|
||||
---
|
||||
|
||||
## User Flow
|
||||
|
||||
```
|
||||
Admin enters "Open Sans" → selects weights (400, 700) → selects styles (normal, italic)
|
||||
↓
|
||||
Plugin hits Google Fonts CSS2 API (ONE TIME)
|
||||
↓
|
||||
Downloads WOFF2 files to wp-content/fonts/
|
||||
↓
|
||||
Registers font via WP Font Library API
|
||||
↓
|
||||
Font appears in Appearance → Editor → Styles → Typography dropdown
|
||||
↓
|
||||
User applies font using standard WordPress FSE controls
|
||||
↓
|
||||
GOOGLE NEVER CONTACTED AGAIN — fonts served locally
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
maple-local-fonts/
|
||||
├── maple-local-fonts.php # Main plugin file
|
||||
├── index.php # Silence is golden
|
||||
├── uninstall.php # Clean removal
|
||||
├── readme.txt # WordPress.org readme
|
||||
├── includes/
|
||||
│ ├── index.php # Silence is golden
|
||||
│ ├── class-mlf-font-downloader.php
|
||||
│ ├── class-mlf-font-registry.php
|
||||
│ ├── class-mlf-admin-page.php
|
||||
│ └── class-mlf-ajax-handler.php
|
||||
├── assets/
|
||||
│ ├── index.php # Silence is golden
|
||||
│ ├── admin.css
|
||||
│ └── admin.js
|
||||
└── languages/
|
||||
├── index.php # Silence is golden
|
||||
└── maple-local-fonts.pot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Class Responsibilities
|
||||
|
||||
### MLF_Font_Downloader
|
||||
- Build Google Fonts CSS2 URL
|
||||
- Fetch CSS (with correct user-agent for WOFF2)
|
||||
- Parse CSS to extract font face data
|
||||
- Download WOFF2 files to wp-content/fonts/
|
||||
- **Reference:** GOOGLE_FONTS_API.md
|
||||
|
||||
### MLF_Font_Registry
|
||||
- Register fonts with WP Font Library (wp_font_family, wp_font_face post types)
|
||||
- Delete fonts (remove posts and files)
|
||||
- List imported fonts
|
||||
- **Reference:** WORDPRESS_COMPATIBILITY.md
|
||||
|
||||
### MLF_Admin_Page
|
||||
- Render settings page under Appearance menu
|
||||
- Font name input, weight checkboxes, style checkboxes
|
||||
- Display installed fonts with delete buttons
|
||||
- **Reference:** SECURITY.md for output escaping
|
||||
|
||||
### MLF_Ajax_Handler
|
||||
- Handle download requests
|
||||
- Handle delete requests
|
||||
- **Reference:** SECURITY.md for nonce/capability checks
|
||||
|
||||
---
|
||||
|
||||
## Admin Page UI
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Maple Local Fonts │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ IMPORT FROM GOOGLE FONTS │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Font Name: [Open Sans_________________________] │ │
|
||||
│ │ │ │
|
||||
│ │ Weights: │ │
|
||||
│ │ ☑ 400 (Regular) ☐ 300 (Light) ☐ 500 (Medium) │ │
|
||||
│ │ ☑ 700 (Bold) ☐ 600 (Semi) ☐ 800 (Extra) │ │
|
||||
│ │ │ │
|
||||
│ │ Styles: │ │
|
||||
│ │ ☑ Normal ☑ Italic │ │
|
||||
│ │ │ │
|
||||
│ │ Files to download: 4 │ │
|
||||
│ │ [Download & Install] │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ INSTALLED FONTS │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Open Sans │ │
|
||||
│ │ 400 normal, 400 italic, 700 normal, 700 italic │ │
|
||||
│ │ [Delete] │ │
|
||||
│ ├─────────────────────────────────────────────────────┤ │
|
||||
│ │ Roboto │ │
|
||||
│ │ 400 normal, 500 normal, 700 normal │ │
|
||||
│ │ [Delete] │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ℹ️ Use Appearance → Editor → Styles → Typography to │
|
||||
│ apply fonts to your site. │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Build Order
|
||||
|
||||
### Phase 1: Foundation
|
||||
1. `maple-local-fonts.php` — Plugin header, constants, autoloader, activation hook
|
||||
2. `index.php` files in all directories (silence is golden)
|
||||
3. `includes/class-mlf-ajax-handler.php` — With full security checks (nonce, capability, validation)
|
||||
|
||||
### Phase 2: Core Functionality
|
||||
4. `includes/class-mlf-font-downloader.php` — Google Fonts fetching/parsing/downloading
|
||||
5. `includes/class-mlf-font-registry.php` — WP Font Library integration
|
||||
|
||||
### Phase 3: Admin Interface
|
||||
6. `includes/class-mlf-admin-page.php` — Settings page render
|
||||
7. `assets/admin.css` — Admin page styles
|
||||
8. `assets/admin.js` — AJAX handling for download/delete
|
||||
|
||||
### Phase 4: Cleanup & Polish
|
||||
9. `uninstall.php` — Clean removal of fonts and data
|
||||
10. `readme.txt` — WordPress.org readme with privacy section
|
||||
11. Testing against all compatibility targets
|
||||
|
||||
---
|
||||
|
||||
## Critical Reminders
|
||||
|
||||
### Security (see SECURITY.md)
|
||||
- ABSPATH check on EVERY PHP file
|
||||
- index.php in EVERY directory
|
||||
- Nonce verification FIRST in every AJAX handler
|
||||
- Capability check SECOND
|
||||
- Input validation THIRD
|
||||
- Escape ALL output
|
||||
|
||||
### Performance
|
||||
- Zero JavaScript on frontend
|
||||
- Zero CSS on frontend
|
||||
- All plugin code is admin-side only (except lightweight font registration)
|
||||
- Timeout handling on all external requests
|
||||
- Maximum limits to prevent infinite loops
|
||||
|
||||
### GDPR
|
||||
- No user data collected
|
||||
- External requests only during admin import
|
||||
- Fonts served locally after import
|
||||
- Document in readme.txt
|
||||
|
||||
### Compatibility (see WORDPRESS_COMPATIBILITY.md)
|
||||
- Declare WooCommerce HPOS compatibility
|
||||
- Use wp_get_font_dir() not hardcoded paths
|
||||
- Use Font Library API (post types) not theme.json filtering
|
||||
- Don't touch frontend, let Global Styles handle everything
|
||||
|
||||
---
|
||||
|
||||
## Constants
|
||||
|
||||
```php
|
||||
define('MLF_VERSION', '1.0.0');
|
||||
define('MLF_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('MLF_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
define('MLF_PLUGIN_BASENAME', plugin_basename(__FILE__));
|
||||
|
||||
// Limits
|
||||
define('MLF_MAX_FONTS_PER_REQUEST', 10);
|
||||
define('MLF_MAX_WEIGHTS_PER_FONT', 9);
|
||||
define('MLF_REQUEST_TIMEOUT', 30);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## WordPress Hooks Used
|
||||
|
||||
```php
|
||||
// Activation
|
||||
register_activation_hook(__FILE__, 'mlf_activate');
|
||||
|
||||
// Admin menu
|
||||
add_action('admin_menu', 'mlf_register_menu');
|
||||
|
||||
// Admin assets (our page only)
|
||||
add_action('admin_enqueue_scripts', 'mlf_enqueue_admin_assets');
|
||||
|
||||
// AJAX (admin only, no nopriv)
|
||||
add_action('wp_ajax_mlf_download_font', 'mlf_ajax_download');
|
||||
add_action('wp_ajax_mlf_delete_font', 'mlf_ajax_delete');
|
||||
|
||||
// WooCommerce HPOS
|
||||
add_action('before_woocommerce_init', 'mlf_declare_hpos_compatibility');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Functional
|
||||
- [ ] Import Open Sans 400, 700 normal + italic → 4 files created
|
||||
- [ ] Font appears in FSE typography dropdown
|
||||
- [ ] Apply font in Global Styles → frontend shows local font
|
||||
- [ ] Delete font → files and posts removed
|
||||
- [ ] Re-import same font → appropriate error message
|
||||
|
||||
### Security
|
||||
- [ ] AJAX without nonce → 403
|
||||
- [ ] AJAX as subscriber → 403
|
||||
- [ ] Path traversal in font name → rejected
|
||||
- [ ] XSS in font name → sanitized
|
||||
- [ ] Direct PHP file access → blank/exit
|
||||
|
||||
### Performance
|
||||
- [ ] No frontend network requests from plugin
|
||||
- [ ] Import 5 fonts → completes without timeout
|
||||
- [ ] Admin page load < 500ms added time
|
||||
|
||||
### Compatibility
|
||||
- [ ] WordPress 6.5, 6.6+
|
||||
- [ ] Twenty Twenty-Five theme
|
||||
- [ ] WooCommerce (HPOS enabled)
|
||||
- [ ] Wordfence (enabled)
|
||||
- [ ] LearnDash
|
||||
- [ ] WPForms
|
||||
Loading…
Add table
Add a link
Reference in a new issue