Requirements
- PHP 7.4+ (PHP 8.0+ recommended for best performance)
- WordPress 6.0+
- Lang Forge plugin activated
- MySQL 5.7+ or MariaDB 10.3+
Shared Forge Suite Diagnostics
When Lang Forge is active, the shared Forge Suite > Setup & Health panel is available in WordPress admin. Its read-only AJAX action is forge_suite_health_check; it requires manage_options and the localized forge_suite_health_check nonce. The response returns diagnostics for active Forge plugins, local license records, credits widget readiness, Avakode API /health, permalinks, and migration/integration source plugins. It does not call AI endpoints, spend credits, write migration data, or change license/Freemius state.
The shared manual license fallback uses wp_ajax_forge_suite_resolve_license_scope before activation. It requires activate_plugins, the localized forge_suite_resolve_license_scope nonce, and POST fields license_key plus product; it calls Avakode /licenses/validate with resolve_products:true and returns the Worker’s valid, license_product, is_bundle, matched_product, and error_code fields so the JS activates only a Bundle fan-out or the one matching standalone plugin.
How Lang Forge Works Under the Hood
Lang Forge stores each translation as a separate WordPress post. A Russian “About Us” page and its English equivalent are two distinct posts in wp_posts, linked through the wp_lf_translations table. Each post carries a _lf_language meta value that tells Lang Forge which language it belongs to. This design means every WordPress API function (get_post(), WP_Query, get_permalink()) works naturally with translated content. There is no hidden serialization or custom post type wrapper.
The plugin hooks into pre_get_posts to filter archive and search queries by the current language, rewrites permalinks to include language prefixes, and provides helper functions for retrieving translations in your theme templates.
Making a Theme Translation-Ready
Lang Forge works with any WordPress theme. To make your theme fully multilingual, follow these steps:
Step 1: Configure languages. Set a default language and add at least one additional language in Lang Forge > Settings. The default language determines which content is shown when no language prefix is present in the URL. Step 2: Assign languages to existing content. Every post and page needs a_lf_language meta value. You can do this in bulk from the admin, or programmatically:
// functions.php or a custom script
// Assign English as language for all posts that have no language set
$posts = get_posts([
'posts_per_page' => -1,
'post_type' => 'any',
'meta_query' => [
[
'key' => '_lf_language',
'compare' => 'NOT EXISTS',
],
],
]);
foreach ($posts as $post) {
update_post_meta($post->ID, '_lf_language', 'en');
}For larger sites, use WP-CLI for better performance:
wp langforge set-language 0 en --all-unassigned// header.php - Complete multilingual header example
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<header class="site-header">
<div class="site-branding">
<?php the_custom_logo(); ?>
<h1 class="site-title">
<a href="<?php echo esc_url(home_url('/')); ?>">
<?php bloginfo('name'); ?>
</a>
</h1>
</div>
<nav class="main-navigation" role="navigation">
<?php
// Load language-specific menu if available
$lang = lf_get_current_language();
$menu_location = 'primary_' . $lang;
if (has_nav_menu($menu_location)) {
wp_nav_menu(['theme_location' => $menu_location]);
} else {
wp_nav_menu(['theme_location' => 'primary']);
}
?>
</nav>
<div class="language-selector">
<?php echo lf_language_switcher(['style' => 'dropdown', 'show_flags' => true]); ?>
</div>
</header>__(), _e(), esc_html__(), or esc_html_e():
// archive.php
<?php if (have_posts()) : ?>
<h1 class="page-title"><?php echo esc_html__('Search Results', 'theme'); ?></h1>
<?php while (have_posts()) : the_post(); ?>
<article <?php post_class(); ?>>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<?php the_excerpt(); ?>
<a href="<?php the_permalink(); ?>" class="read-more-link">
<?php echo esc_html__('Read More', 'theme'); ?>
</a>
</article>
<?php endwhile; ?>
<?php else : ?>
<p><?php echo esc_html__('No posts found', 'theme'); ?></p>
<?php endif; ?>post and page are enabled. If your theme registers custom post types (portfolios, testimonials, etc.), enable them here.
// Programmatically enable a custom post type for translation
add_filter('lf_translatable_post_types', function ($post_types) {
$post_types[] = 'portfolio';
$post_types[] = 'testimonial';
return $post_types;
});Verifying Your Setup
After completing the steps above, verify that everything works:
// Add this temporarily to your theme's functions.php to debug
add_action('wp_footer', function () {
if (!current_user_can('manage_options')) return;
echo '<!-- Lang Forge Debug: ';
echo 'Current: ' . lf_get_current_language() . ' | ';
echo 'Default: ' . lf_get_default_language() . ' | ';
echo 'Languages: ' . implode(', ', array_keys(lf_get_languages())) . ' | ';
if (is_singular()) {
echo 'Post Lang: ' . lf_get_post_language(get_the_ID()) . ' | ';
echo 'Translations: ' . wp_json_encode(lf_get_post_translations(get_the_ID()));
}
echo ' -->';
});> Note: Remember to remove the debug code before deploying to production.
—