Lang Forge translates arbitrary strings (text that is not post content) using standard WordPress translation functions. This covers theme labels, button text, widget titles, page builder content, and any other hardcoded strings in your templates.
7.1 Automatic String Registration via gettext
Lang Forge automatically registers strings from allowed text domains when they appear on the frontend. Simply use standard WordPress __() and _e() in your theme:
// In your theme template — standard WordPress i18n:
echo __('Read More', 'flavor-theme');
_e('Contact Us', 'flavor-theme');
echo esc_html__('Subscribe to Newsletter', 'flavor-theme');When a visitor loads a page containing these strings, Lang Forge detects them through WordPress’s gettext filter and auto-registers them in the wp_lf_strings database table. They then appear in Lang Forge > String Translation, ready to be translated.
- Go to Lang Forge > Languages (Settings page)
- Find “String Auto-Registration Domains” in the Content section
- Enter text domains to auto-register (one per line). Default: your active theme’s text domain
- Save settings
// single.php
<article <?php post_class(); ?>>
<header class="entry-header">
<h1><?php the_title(); ?></h1>
<div class="entry-meta">
<span class="posted-on">
<?php echo esc_html__('Posted on', 'theme'); ?>
<time datetime="<?php echo get_the_date('c'); ?>">
<?php echo get_the_date(); ?>
</time>
</span>
<span class="byline">
<?php echo esc_html__('by', 'theme'); ?>
<?php the_author(); ?>
</span>
</div>
</header>
<div class="entry-content">
<?php the_content(); ?>
</div>
<footer class="entry-footer">
<?php if (comments_open()) : ?>
<a href="#comments"><?php _e('Leave a Comment', 'theme'); ?></a>
<?php else : ?>
<p><?php _e('Comments are closed', 'theme'); ?></p>
<?php endif; ?>
</footer>
</article>- Lang Forge hooks into WordPress’s
gettext,gettext_with_context, andngettextfilters - On cache miss (string not in DB), the string is queued for registration
- Queued strings are batch-inserted via
INSERT IGNOREon theshutdownhook (one query, no duplicates) - In-memory deduplication prevents the same string from being queued twice per request
- The filter only runs on the frontend (
!is_admin()) to avoid interfering with WordPress admin translations - WordPress Core (
default), empty domains, and Forge Suite domains are always skipped
default(WordPress core)langforge,seoforge,formforge,fieldforge- Empty domain
7.2 Importing from PO Files
Programmatically import existing .po file translations into Lang Forge’s database:
// Import a Russian PO file for your theme
$count = LF_String_Translation::instance()->import_from_po(
'/path/to/theme-ru.po',
'my-theme', // domain
'ru' // target language
);
echo "Imported $count strings";
// Import translations for multiple languages
$po_files = [
'en' => get_template_directory() . '/languages/en_US.po',
'de' => get_template_directory() . '/languages/de_DE.po',
'fr' => get_template_directory() . '/languages/fr_FR.po',
];
foreach ($po_files as $lang => $file) {
if (file_exists($file)) {
$count = LF_String_Translation::instance()->import_from_po($file, 'my-theme', $lang);
echo "Imported $count $lang stringsn";
}
}7.3 Translating Dynamic Strings
For strings that contain dynamic values, translate the template and inject values afterward:
// In the template — use sprintf with a translated template
$template = __('Showing %1$d-%2$d of %3$d results', 'theme');
echo sprintf($template, $start, $end, $total);
// English: "Showing 1-10 of 42 results"
// Russian: "Показаны 1-10 из 42 результатов"—