Skip to content

First Translation Walkthrough

This guide walks through the complete first-translation workflow with verification steps at each stage. Use it when onboarding a new site, confirming a customer’s installation is healthy, or reproducing a reported issue in a clean environment.

  • Omnalingo plugin installed and activated
  • A valid API key (required for AI translation; gathering, scanning, and manual translation work without it)
  • WordPress permalinks set to any “pretty” format — wp-admin → Settings → Permalinks should not be set to “Plain”

  1. Set the source language

    Go to wp-admin → Omnalingo → Settings → General.

    The source language is the entry marked is_default: true in the languages configuration. Confirm it matches the language the site content is written in.

    If the wrong language is set as default, the translation engine will translate from the wrong source. Fix it before proceeding — changing the source language after translations exist will not automatically re-translate anything.

  2. Add a target language

    Go to wp-admin → Omnalingo → Settings → Languages and add a target language (e.g., German — de_DE).

    After saving, verify the language appears in the list with the Active toggle enabled.

    Database verification:

    SELECT option_value FROM wp_options WHERE option_name = 'omnalingo_options';

    In the JSON output, find general.languages and confirm:

    • The new language entry has "active": true
    • The source language has "is_default": true
    • The new language has a unique slug (e.g., "de")
  3. Wait for language pack download

    Immediately after saving, Omnalingo triggers a download of the WordPress language pack for the new language. The admin sidebar shows a progress widget. Wait for it to complete before scanning.

    A language pack download that gets stuck can be diagnosed via:

    SELECT option_value FROM wp_options WHERE option_name = 'omnalingo_langpack_status';

    A status field stuck in downloading_core or downloading_packs for more than 5 minutes means the download process crashed. Delete the option to reset:

    DELETE FROM wp_options WHERE option_name = 'omnalingo_langpack_status';

    Then trigger a re-download by saving the language settings again.


  1. Select content types

    Still in wp-admin → Omnalingo → Settings → General, find the content type selection.

    For a typical site, enable post and page. For WooCommerce stores, also enable product. For taxonomy archives, enable the relevant taxonomies.

    If you want all public content types included automatically, enable Sync All Content. This ignores the manual selections and includes everything.

    Database verification:

    SELECT option_value FROM wp_options WHERE option_name = 'omnalingo_options';

    Look for sync_post_types, sync_taxonomies, and sync_all_content in the JSON.


  1. Run Gather Content

    Go to wp-admin → Omnalingo → Dashboard and click Gather Content.

    Gathering reads the WordPress database to discover every published URL for the selected content types. It does not make HTTP requests and is typically fast (seconds to a minute for large sites).

    Verification:

    SELECT COUNT(*), content_type FROM wp_omnalingo_urls GROUP BY content_type;

    This should show URL counts grouped by post type. If the count is 0, gathering either did not run or the content types are not configured correctly (go back to Stage 2).

    Expected result: One row in wp_omnalingo_urls per published page/post/product/term.


  1. Run Scan Content

    Click Scan Content on the Dashboard.

    Scanning visits each indexed URL via an internal HTTP request (wp_remote_get() with ?omnalingo_scan=1), captures the fully-rendered HTML via PHP output buffering, and extracts text nodes using StringParserService (the DOM parser).

    Each extracted string is stored in wp_omnalingo_strings with MD5-based deduplication. The junction table wp_omnalingo_url_strings links strings to their source URLs.

    During scanning, watch for:

    • The progress bar incrementing. If it stays at 0 for more than 2 minutes, see Scan Not Working.
    • “Keep this tab open” advice — the dashboard’s Work-While-Polling pattern processes extra batches on each status check, measurably speeding up completion.

    Verification after scanning completes:

    SELECT COUNT(*) FROM wp_omnalingo_strings;
    SELECT COUNT(*), type FROM wp_omnalingo_strings GROUP BY type;

    You should see html type strings (page content) and potentially gettext type strings (WordPress/plugin UI strings with gettext gap coverage). A completely empty result means scanning found nothing — check the caching layer and loopback connectivity (see Scan Not Working).


  1. Choose a translation method

    You have three options:

    Option A: Bulk Translation (recommended for initial setup)

    In the Dashboard, select your target language and click Translate All. This queues all untranslated strings for AI processing via Action Scheduler.

    Monitor progress via the REST endpoint:

    Terminal window
    curl -H "X-WP-Nonce: $NONCE" \
    https://yoursite.com/wp-json/omnalingo/v1/languages/de/translations/status

    Option B: Translate a single page

    Click the translate icon on any dashboard row to open the Visual Editor for that page. Use the AI Translate button in the sidebar or type translations manually.

    Option C: Manual translation via the Visual Editor

    Open wp-admin → Omnalingo → Dashboard, click any page’s edit icon. The visual editor loads the page in an iframe. Click any text element in the iframe; the sidebar scrolls to the matching string and opens the appropriate input template. Type the translation. All changes save automatically.

  2. Verify translations in the database

    After a bulk translation completes, verify rows exist in the language translation table:

    SELECT COUNT(*), translated_by
    FROM wp_omnalingo_translations_de
    GROUP BY translated_by;

    You should see translated_by = 'ai' for AI-translated strings. translated_by = 'manual' means a human edited the translation via the Visual Editor.

    If the table does not exist, the language was never added correctly (the table is created by MaintenanceRepository::syncLanguageTables() when the language is saved).


  1. Visit the translated URL

    Open a browser and navigate to the translated version of a page. Translated pages are served at URLs prefixed with the language slug:

    • Default language: https://yoursite.com/about/
    • German: https://yoursite.com/de/about/
    • French: https://yoursite.com/fr/about/

    If the page returns 404: flush rewrite rules via wp-admin → Settings → Permalinks → Save Changes.

    If the page loads but shows English: work through Translations Not Showing.

  2. Check a string directly

    Pick a specific visible string. Find its translation in the database:

    SELECT s.original_string, t.translated_string, t.translated_by
    FROM wp_omnalingo_strings s
    JOIN wp_omnalingo_translations_de t ON s.id = t.string_id
    WHERE s.original_string LIKE '%your text here%';

    If the row exists with a translated_string but the page still shows English, the issue is in the replacement layer — check caching plugins and the TranslationReplacementService.


After completing the workflow, this SQL gives a snapshot of the installation state:

-- URL count
SELECT COUNT(*) AS url_count FROM wp_omnalingo_urls;
-- String counts by type
SELECT type, COUNT(*) AS count FROM wp_omnalingo_strings GROUP BY type;
-- Translation coverage for German (replace 'de' as needed)
SELECT
(SELECT COUNT(*) FROM wp_omnalingo_strings WHERE type = 'html') AS total_html,
(SELECT COUNT(*) FROM wp_omnalingo_translations_de) AS translated_de,
ROUND(
(SELECT COUNT(*) FROM wp_omnalingo_translations_de) /
(SELECT COUNT(*) FROM wp_omnalingo_strings WHERE type = 'html') * 100, 1
) AS coverage_pct;