SEO Forge uses a template system for generating default meta titles and descriptions with variable placeholders. Templates reduce the need to set custom titles on every post.
Available Template Variables
| Variable | Description | Example Output | |
|---|---|---|---|
{{title}} | Post/page title | My Blog Post | |
{{siteName}} | Site name from Settings > General | My Website | |
{{siteDesc}} | Site tagline from Settings > General | Just another WordPress site | |
{{excerpt}} | Post excerpt, or auto-generated from first paragraph | Learn how to optimize... | |
{{author}} | Author display name | John Doe | |
{{category}} | Primary category name | Tutorials | |
{{date}} | Publish date in localized format | January 15, 2024 | |
{{modifiedDate}} | Last modified date in localized format | January 20, 2024 | |
{{currentYear}} | Current four-digit year | 2024 | |
{{currentMonth}} | Current month name | January | |
{{separator}} | Configurable separator character | | |
{{field:NAME}} or %field:NAME% | Custom field value (FieldForge / ACF) on the same post | Premium Italian leather |
Custom field tokens (field:NAME)
Both %field:custom_summary% and {{field:custom_summary}} are accepted in
manual overrides AND template strings. Resolution order:
apply_filters('seoforge_resolve_meta_token', null, $name, $post_id)— return a string to short-circuit (handy for computed values that aren’t in postmeta).get_field($name, $post_id)when ACF or FieldForge ACF-compat is loaded.get_post_meta($post_id, $name, true)— flat fallback.
Empty / missing fields render as empty string and the cleanup step drops dangling separators. Arrays / objects get JSON-encoded so output never reads Array in a attribute.
php
// Theme override: compute a value at render time
add_filter('seoforge_resolve_meta_token', function ($value, $name, $post_id) {
if ($name === 'in_stock_count') {
return wc_get_product($post_id)->get_stock_quantity() . ' available';
}
return $value;
}, 10, 3);
// Editor sets meta description: "Only %field:in_stock_count% — order today"
// Renders: "Only 42 available — order today"Template Cascade Priority
When SEO Forge resolves a meta title or description, it follows this cascade. The first non-empty value wins:
- Post-level manual override —
_seoforge_meta_title/_seoforge_meta_descriptionpost meta - Taxonomy-level template — Stored in
seoforge_tax_templatesoption - Global template per post type — Stored in
seoforge_title_templatesoption - Default template — Built-in defaults (
{{title}} {{separator}} {{siteName}}) - WordPress fallback — Raw post title / first 160 chars of content
Programmatic Template Resolution
php
$templates = SEOFORGE_Meta_Templates::instance();
// Resolve a template string for a specific post
$resolved = $templates->resolve( '{{title}} {{separator}} {{siteName}}', $post_id );
// Returns: "My Blog Post | My Website"
// Get the fully resolved meta title using the full cascade
$title = $templates->get_resolved_meta( $post_id, 'title' );
// Get the fully resolved meta description using the cascade
$desc = $templates->get_resolved_meta( $post_id, 'description' );
// Get the configured separator character
$sep = $templates->get_separator(); // '|' by default
// Get all available variables with descriptions
$vars = $templates->get_available_variables();Setting Custom Templates
php
// Set global templates per post type
update_option( 'seoforge_title_templates', [
'post' => [
'title' => '{{title}} - {{category}} {{separator}} {{siteName}}',
'description' => '{{excerpt}}',
],
'page' => [
'title' => '{{title}} {{separator}} {{siteName}}',
'description' => '{{excerpt}}',
],
'product' => [
'title' => 'Buy {{title}} {{separator}} {{siteName}}',
'description' => '{{excerpt}} | Free shipping available.',
],
] );
// Set taxonomy-level template (overrides global for posts in this category)
$tax_templates = get_option( 'seoforge_tax_templates', [] );
$tax_templates['category_5'] = [
'title' => '{{title}} - Tutorials {{separator}} {{siteName}}',
'description' => '{{excerpt}} Learn more in our tutorials section.',
];
update_option( 'seoforge_tax_templates', $tax_templates );
// Change the separator character
update_option( 'seoforge_title_separator', '-' );—