A WordPress plugin for managing YAML frontmatter schemas in theme templates and partials. Define structured content with an intuitive interface and ACF-like template functions.
- YAML Schema Management - Define schemas for page templates and template partials
- 15+ Field Types - String, rich-text, images, blocks, taxonomies, data objects, and more
- Easy-to-use Admin Interface - Manage schemas and data with a clean, intuitive UI
-
Three-level Data Hierarchy:
- Per-page data - Individual customization stored in post meta
- Per-template global data - Shared across all posts using the same template
- Site-wide global data - For partials like headers and footers
-
Per-field Global/Local Toggle - Each field can independently use template global data or page-specific data
-
Visual Dual-field Interface - See both template global and page-specific values side-by-side
-
Auto-merge Data Hierarchy - Intelligent data priority: page > template global > site global
- Data Objects - Manage structured, reusable data (universities, companies, team members, etc.)
- Data Validation - Review imported content for consistency
- Export/Import - Consolidated functionality for settings, page data, and data objects
- Simple Template Functions - ACF-like syntax with auto-merge behavior
- WordPress Coding Standards Compliant
- Administrator-only Access for security
- Clean Uninstall - Removes all database records
- Scoped Dependencies - No conflicts with other plugins using Symfony components
| Field Type | Description |
|---|---|
| string | Single-line text with min/max length |
| text | Multi-line textarea |
| rich-text | WordPress WYSIWYG editor |
| code | Code editor with syntax highlighting |
| boolean | Checkbox for true/false values |
| number | Number input with min/max constraints |
| date | Date picker with optional time |
| select | Dropdown with single/multiple selection |
| taxonomy | WordPress categories, tags, or custom taxonomies |
| post_type | Dropdown to select registered post types |
| data_object | Reference to structured data objects |
| image | WordPress media uploader for images |
| file | WordPress media uploader for any file |
| object | Nested group of fields |
| block | Repeatable blocks for flexible page builders |
- Log in to your WordPress admin dashboard
- Navigate to Plugins → Add New
- Search for "YAML Custom Fields"
- Click Install Now next to the YAML Custom Fields plugin
- Click Activate after installation completes
- Go to YAML Custom Fields in the admin menu to configure your schemas
- Download the plugin ZIP file
- Log in to your WordPress admin dashboard
- Navigate to Plugins → Add New → Upload Plugin
- Choose the ZIP file and click Install Now
- Click Activate after installation completes
- Go to YAML Custom Fields in the admin menu to configure your schemas
- WordPress 5.0 or higher
- PHP 7.4 or higher
- The plugin includes all necessary dependencies
- Go to YAML Custom Fields in the admin menu
- Find your template (e.g.,
page.php) in the list - Toggle Enable YAML to ON
- Click Add Schema
fields:
- name: hero_title
label: Hero Title
type: string
required: true
options:
maxlength: 100
- name: hero_image
label: Hero Image
type: image
- name: category
label: Category
type: taxonomy
options:
taxonomy: category
- name: features
label: Features
type: block
list: true
blockKey: type
blocks:
- name: feature
label: Feature Block
fields:
- name: title
label: Title
type: string
- name: icon
label: Icon
type: image<?php
// Get field values
$hero_title = ycf_get_field('hero_title');
$hero_image = ycf_get_image('hero_image', null, 'full');
$category = ycf_get_term('category');
$features = ycf_get_field('features');
?>
<div class="hero">
<?php if ($hero_image): ?>
<img src="<?php echo esc_url($hero_image['url']); ?>"
alt="<?php echo esc_attr($hero_image['alt']); ?>">
<?php endif; ?>
<h1><?php echo esc_html($hero_title); ?></h1>
<?php if ($category): ?>
<span class="category"><?php echo esc_html($category->name); ?></span>
<?php endif; ?>
</div>
<?php if (!empty($features)): ?>
<div class="features">
<?php foreach ($features as $block): ?>
<?php
$title = ycf_get_field('title', null, $block);
$icon = ycf_get_image('icon', null, 'thumbnail', $block);
?>
<div class="feature">
<?php if ($icon): ?>
<img src="<?php echo esc_url($icon['url']); ?>">
<?php endif; ?>
<h3><?php echo esc_html($title); ?></h3>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>// Basic usage
$value = ycf_get_field('field_name');
// Specific post ID
$value = ycf_get_field('field_name', 123);
// From partial
$value = ycf_get_field('logo', 'partial:header.php');
// From block context
$value = ycf_get_field('title', null, $block);$image = ycf_get_image('field_name', null, 'full');
// Returns: array('id', 'url', 'alt', 'title', 'caption', 'description', 'width', 'height')$file = ycf_get_file('field_name');
// Returns: array('id', 'url', 'path', 'filename', 'filesize', 'mime_type', 'title')$term = ycf_get_term('field_name');
// Returns: WP_Term object or array of WP_Term objects (for multiple selection)$post_type = ycf_get_post_type('field_name');
// Returns: WP_Post_Type object or null$university = ycf_get_data_object('field_name');
// Returns: Array with data object entry fields or null
// Get all entries of a data object type
$all_universities = ycf_get_data_objects('universities');if (ycf_has_field('hero_title')) {
echo ycf_get_field('hero_title');
}Template Global Fields allow you to define default values shared across all posts using the same template, while still allowing individual posts to override specific fields.
- Go to YAML Custom Fields admin page
- Enable YAML for your template (e.g.,
page.php) - Click Add Template Global to define the template global schema
- Define fields that should have shared default values
- Click Manage Template Global Data to set the default values
When editing a post that uses a template with Template Global fields, you'll see a dual-field interface:
- Template Global (All Pages) - Read-only display showing the default value (with Edit link)
- Page-Specific Value - Editable field for this post only
- Checkbox - "Use template global for this field" - Toggle per field
- Consistency: Set default values once, use across all posts
- Flexibility: Override any field on any post individually
- Clarity: See both global and local values side-by-side
- Efficiency: Update template global to affect all posts at once
When using template functions, data is returned in this priority order:
- Page-specific value (if "use template global" is unchecked)
- Template global value (if "use template global" is checked)
- Site-wide global value (if template has site-wide global enabled)
- null (if no value exists)
For custom partials, add the @ycf marker in the file header:
<?php
/**
* Custom Navigation Partial
* @ycf
*/Then click Refresh Template List in the YAML Custom Fields admin page.
Data Objects allow you to manage structured, reusable data independently from posts and pages.
Use Cases:
- Universities or educational institutions
- Companies or organizations
- Team members or staff
- Locations or venues
- Products or services
How to Use:
- Go to YAML Custom Fields → Data Objects
- Create a new data object type (e.g., "universities")
- Define the schema with fields
- Add entries for each university
- Reference in your page schemas using the
data_objectfield type
If you're developing or modifying the plugin, follow these steps:
- PHP 7.4 or higher
- Composer
# Clone the repository
git clone https://github.com/maliMirkec/yaml-custom-fields.git
cd yaml-custom-fields
# Install Composer dependencies
composer install
# Build scoped dependencies (prevents conflicts with other plugins)
chmod +x build-scoped.sh
./build-scoped.shThe build-scoped.sh script uses PHP-Scoper to namespace the Symfony YAML dependencies under the YamlCF\Vendor namespace, preventing conflicts with other plugins.
- Make your changes to the plugin files
- If you modify Composer dependencies, run
./build-scoped.shagain - Test the plugin in a WordPress development environment
- Commit your changes (the
build/directory is included in the repository)
- Page/Post data: Post meta with key
_yaml_cf_data - Template Global preferences: Post meta with key
_yaml_cf_use_template_global_fields - Template Global schemas: Options table with key
yaml_cf_template_global_schemas - Template Global data: Options table with key
yaml_cf_template_global_data - Site-wide global schema: Options table with key
yaml_cf_global_schema - Site-wide global data: Options table with key
yaml_cf_global_data - Partial data: Options table with key
yaml_cf_partial_data - Schemas: Options table with key
yaml_cf_schemas - Data Object Types: Options table with key
yaml_cf_data_object_types - Data Object Entries: Options table with keys
yaml_cf_data_object_entries_{type_slug}
The plugin provides several hooks for extensibility:
// Modify field output before rendering
add_filter('yaml_cf_field_value', function($value, $field_name, $post_id) {
// Your custom logic
return $value;
}, 10, 3);YAML frontmatter is a structured way to define metadata for content. It's commonly used in static site generators and headless CMS systems. YAML Custom Fields brings this approach to WordPress themes.
While ACF is a comprehensive custom fields solution, YAML Custom Fields focuses on YAML-based schemas that are portable and version-controllable. It's ideal for developers who prefer code-first approaches and want simpler, more predictable data structures.
Yes! YAML Custom Fields works with any WordPress theme. You define schemas for your templates and use simple PHP functions to retrieve the data in your template files.
Yes, YAML Custom Fields is compatible with both the Classic and Block (Gutenberg) editors. The custom fields appear below the editor regardless of which editor you're using.
Your data remains in the database. Only when you delete the plugin (not just deactivate) will it clean up all settings, schemas, and custom field data.
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes following WordPress Coding Standards
- Test your changes thoroughly
- Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Documentation: Plugin Documentation
- Issues: Report Issues
- WordPress Support: WordPress.org Plugin Support
- REFACTOR: Assets Folder Structure - Reorganized assets for WordPress.org compliance
- IMPROVED: File Organization - Separated admin assets (CSS/JS) into 'admin-assets' folder
- IMPROVED: Plugin Assets - Moved WordPress.org assets (icons, banners, screenshots) to 'assets' folder
- UPDATED: File References - Updated all asset paths in templates and AssetManager
- FIX: Dynamic Block Fields - Fixed taxonomy, post_type, and data_object fields not rendering correctly in dynamically added blocks
- NEW: JavaScript Field Handlers - Added missing post_type and data_object field support to JavaScript block rendering
- IMPROVED: Field Type Parity - All field types now work identically in both static (PHP) and dynamic (JavaScript) rendering
- IMPROVED: Data Localization - Enhanced controllers to pass taxonomy terms, post types, and data objects to JavaScript
- UPDATED: Symfony Libraries - Updated Symfony YAML Component to 6.4 and Deprecation Contracts to 3.6.0 for PHP 8.1+ compatibility
- SECURITY: Nonce Verification - Fixed GET parameter access to verify nonces before accessing other parameters
- IMPROVED: Script Enqueuing - Converted all inline scripts to proper wp_enqueue_script usage with wp_localize_script
- REQUIREMENT: PHP 8.1+ - Minimum PHP version requirement (Symfony 6.4 LTS supports PHP 8.1+)
- FIX: Export/Import - Template global schemas and data now properly exported and imported
- FIX: Page Data Export - Schema is now included in page data exports (form-based and AJAX)
- FIX: Page Data Import - Now correctly handles both single-post and multi-post export formats
- NEW: Template Global Readonly Display - Template-global-only fields now display as readonly in post editor
- NEW: Auto-fallback for Template Global Fields -
ycf_get_field()now automatically retrieves template global data - Fixed browser autocomplete issues with template global form fields
- NEW: Template Global Fields - Define shared default values for all posts using the same template
- NEW: Per-field global/local toggle - Each field can independently use template global or page-specific data
- NEW: Dual-field interface - Visual side-by-side comparison of template global and page-specific values
- NEW: Auto-merge data hierarchy - Intelligent data priority system (page > template global > site global)
- Enhanced post editor UI with clear visual indicators for global vs local data
- Improved field rendering system with unique IDs for dual fields
- Added per-field preferences storage for granular control
- Better reset functionality that preserves global data
- Enhanced documentation with Template Global Fields guide
- Improved admin interface organization for template management
- Improved code quality and WordPress Coding Standards compliance
- Consolidated Export/Import functionality into single admin page
- Enhanced database query performance with optimized caching strategy
- Improved input sanitization and output escaping for better security
- Added production-safe logging system with WordPress hooks
- Better file upload validation and error handling
- Initial release
- Support for 15+ field types
- Template and partial support
- ACF-like template functions
- Data Objects feature
- Export/Import functionality
- Administrator-only access
- Clean uninstall
YAML Custom Fields does not collect, store, or transmit any user data outside of your WordPress installation. All data is stored locally in your WordPress database.
This plugin includes the following third-party libraries:
- Symfony YAML Component (v5.4) - Licensed under MIT License (GPL-compatible)
- Author: Silvestar Bistrovic
- Contributors: View all contributors
This plugin is licensed under the GPL v2 or later.
YAML Custom Fields
Copyright (C) 2024 Silvestar Bistrovic
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Last Updated: 2026-01-06 Plugin Version: 1.2.4 Maintained By: Silvestar Bistrović
Made with ❤️ by Silvestar Bistrovic