Skip to content

feat(submissions): let submitters choose the content language#231

Merged
JohnRDOrazio merged 2 commits into
mainfrom
feat/submission-language-selector
Jun 16, 2026
Merged

feat(submissions): let submitters choose the content language#231
JohnRDOrazio merged 2 commits into
mainfrom
feat/submission-language-selector

Conversation

@JohnRDOrazio

@JohnRDOrazio JohnRDOrazio commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

Public submission forms (Submit Project, Refer Community Project, Refer Local Group) now expose a "Content language" dropdown at the top of the form. It defaults to the page's current locale via useLocale(). The value flows: dropdown → modal body → Next.js API route → WP REST handler, which validates against CDCF_LOCALE_NAMES and calls pll_set_post_language($post_id, $language) instead of the old hardcoded 'en'.

Result: a Spanish-speaking submitter on /es/proyectos clicks the referral button, gets a form preselected to Spanish, submits Spanish content that lands as a Spanish post in WordPress, and the auto-translation worker (now language-agnostic after #227/#228/#230) fans out to the other 5 languages with the Polylang group linked end-to-end. No more manual "change language to Spanish" step in wp-admin.

Why

The 2026-06-16 "Enciclopedia Católica" regression exposed three independent hardcoded-EN bugs in the submission-publish pipeline (PRs #227, #228, #230) — but the underlying root cause was that the submission flow forced every post into EN at creation time, so reviewers had to manually re-tag the language in wp-admin to recover Spanish/Italian/etc. content. This closes the loop: the language is correct from creation.

Changes

  • wordpress/themes/cdcf-headless/includes/security.php — new cdcf_validate_submission_language() helper (empty → 'en', allowlist via CDCF_LOCALE_NAMES, returns WP_Error invalid_language 400 otherwise)
  • 3 handlers (refer-community-project.php, refer-local-group.php, submit-project.php) — validate up front, pass the resolved language to pll_set_post_language
  • 3 route registrations (functions.php) — declare language arg with sanitize_text_field and default => ''
  • 3 Next.js API routes — pass body.language through to WP
  • 3 frontend modals — add a <select name="language"> defaulting to useLocale(), with the 6 options sourced from a new shared src/i18n/locale-labels.ts module (extracted from LanguageSwitcher.tsx)
  • Strings: common.submissionLanguage + common.submissionLanguageHint added to all 6 message files (translated)

Test plan

  • composer test --working-dir=wordpress/themes/cdcf-headless — 588/588 pass (+9 new tests in SubmissionHandlerTestBase: provided-honored, default-to-en, reject-unsupported × 3 handlers)
  • Verified RED first: 6/9 of the new tests failed against pre-fix code (3 defaults-to-en tests passed because that was the existing behavior)
  • npm run build — compiles successfully
  • Visual: started dev server pointing at production WP, navigated to /es/proyectos, opened the Refer Community Project modal — dropdown shows "Idioma del contenido" with "Espanol" preselected and the translated hint below
  • After merge + deploy: submit a real referral via /es/proyectos, approve in wp-admin, verify the source post is ES (no manual re-tag), then watch the worker auto-translate to the other 5 with the Polylang group linked

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a language selection field to community project, local group, and project submission forms.
    • Submissions now support 6 languages (English, Spanish, French, Italian, Portuguese, German) with automatic translation capabilities.
    • Selected language defaults to your current interface language.
  • Tests

    • Added comprehensive language validation and handling tests.

Public submission forms (Submit Project, Refer Community Project,
Refer Local Group) get a "Content language" dropdown at the top
that defaults to the page's current locale via useLocale(). The
selected language flows through the Next.js API route and lands on
the WP REST handler, which validates against CDCF_LOCALE_NAMES and
calls pll_set_post_language($post_id, $language) instead of the old
hardcoded 'en'.

Result: a Spanish-speaking submitter on /es/proyectos who clicks
"Referir un proyecto comunitario" gets a form preselected to Spanish,
submits Spanish content that lands as a Spanish post in WordPress,
and the auto-translation worker (combined with the now-language-
agnostic submission-publish pipeline shipped in PR #227/#228/#230)
fans out to the OTHER 5 languages with the Polylang group linked
end-to-end. No more manual "change to Spanish" step in wp-admin.

Server-side validation rejects any language not in CDCF_LOCALE_NAMES
with a 400, so a tampered request can't land posts in an
unconfigured Polylang language. Defaults to 'en' when the field is
absent so legacy callers keep working unchanged.

Strings live under common.submissionLanguage /
common.submissionLanguageHint in all 6 message files. The
LanguageSwitcher's local localeLabels map moves to a new shared
src/i18n/locale-labels.ts module so the modals can reuse it.

Tests: 3 shared scenarios added to SubmissionHandlerTestBase
(provided-honored, default-to-en, reject-unsupported) — 9 RED first
across the 3 handlers, 9 GREEN after wiring cdcf_validate_submission_language.
Full theme suite 588/588.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@JohnRDOrazio, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 27 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2cce9c7b-9908-4510-b6ed-dd7e63ca6bab

📥 Commits

Reviewing files that changed from the base of the PR and between c5c1a3b and dd700c0.

📒 Files selected for processing (1)
  • src/i18n/locale-labels.ts
📝 Walkthrough

Walkthrough

Adds an end-to-end submission language field across three public submission modals (refer community project, refer local group, submit project). A new shared localeLabels module centralizes locale display names. Each modal gains a language selector defaulting to the current locale. The selected language is forwarded through Next.js API proxy routes to WordPress REST endpoints, where a new validation helper and Polylang assignment replace the previously hard-coded 'en'.

Changes

Submission Language Field (End-to-End)

Layer / File(s) Summary
Shared locale-labels module and i18n strings
src/i18n/locale-labels.ts, components/LanguageSwitcher.tsx, messages/*.json
Creates a centrally exported localeLabels map; refactors LanguageSwitcher to import it; adds submissionLanguage and submissionLanguageHint translation keys to all six locale files.
Language selector UI in submission modals
components/sections/ReferCommunityProjectModal.tsx, components/sections/ReferLocalGroupModal.tsx, components/sections/SubmitProjectModal.tsx
Adds useLocale, tc common translations, and a required language <select> populated from locales/localeLabels to all three modals; extends send-code payload and stored form data to carry the selected language.
Next.js API route proxy: language field forwarding
app/api/refer-community-project/route.ts, app/api/refer-local-group/route.ts, app/api/submit-project/route.ts
Forwards body.language (string or '') in the proxied JSON payload sent to each corresponding WordPress REST endpoint.
WordPress language validation helper and REST schema
wordpress/themes/cdcf-headless/includes/security.php, wordpress/themes/cdcf-headless/functions.php
Adds cdcf_validate_submission_language() (allow-list against CDCF_LOCALE_NAMES, default 'en', WP_Error on invalid input) and registers the optional language argument on all three REST routes.
WordPress REST handlers: validation and Polylang assignment
wordpress/themes/cdcf-headless/includes/handlers/refer-community-project.php, .../refer-local-group.php, .../submit-project.php
Each handler validates language early and returns WP_Error on failure; after post creation, calls pll_set_post_language with the validated value instead of the hard-coded 'en'.
PHP tests for submission language handling
wordpress/themes/cdcf-headless/tests/SubmissionHandlerTestBase.php
Adds three shared test cases covering request-supplied language, empty-language default to 'en', and unsupported language rejection with invalid_language/400.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SubmissionModal as SubmissionModal (React)
  participant NextRoute as Next.js API Route
  participant WPRest as WordPress REST API
  participant Polylang

  User->>SubmissionModal: selects language, submits form
  SubmissionModal->>NextRoute: POST {fields..., language: "es"}
  NextRoute->>WPRest: proxied POST {fields..., language: "es"}
  WPRest->>WPRest: cdcf_validate_submission_language("es")
  alt valid language
    WPRest->>WPRest: wp_insert_post(pending)
    WPRest->>Polylang: pll_set_post_language(post_id, "es")
    WPRest-->>NextRoute: 200 OK
    NextRoute-->>SubmissionModal: success
  else invalid language
    WPRest-->>NextRoute: 400 WP_Error(invalid_language)
    NextRoute-->>SubmissionModal: error response
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • CatholicOS/cdcf-website#110: Introduced the submission REST handlers and SubmissionHandlerTestBase that this PR extends with language validation and Polylang assignment.
  • CatholicOS/cdcf-website#200: Also sets Polylang post language on community_project/local_group posts, directly intersecting with the Polylang assignment logic changed here.

Poem

🐇 A language field hops into each form,
From modals to WordPress, a new-found norm.
Six locales aligned in a neat little map,
Polylang now knows where each post lands — snap!
No more hard-coded English, the rabbit declares,
Auto-translated content, shared everywhere! 🌍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(submissions): let submitters choose the content language' clearly and concisely describes the main change—enabling submitters to select content language for their submissions across all public forms.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/submission-language-selector

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codacy-production

codacy-production Bot commented Jun 16, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 5 complexity · 12 duplication

Metric Results
Complexity 5
Duplication 12

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@JohnRDOrazio

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/sections/ReferCommunityProjectModal.tsx`:
- Line 57: The language field is being collected in the
ReferCommunityProjectModal component at line 57 but is not being forwarded by
the send-code proxy route. Update the send-code route handler in
app/api/refer-community-project/send-code/route.ts to include the language field
when constructing the payload to proxy to WordPress, ensuring the language value
is preserved end-to-end throughout the entire workflow.

In `@src/i18n/locale-labels.ts`:
- Around line 6-8: The locale label values for Spanish, French, and Portuguese
in the locale-labels configuration are missing their standard diacritical marks,
making them incorrect spellings of the language autonyms. For the es property,
add the accent to spell the language name correctly. For the fr property, add
the accent to the language name. For the pt property, add the accent to the
language name. These corrections ensure the user-visible language labels display
proper spelling with appropriate diacritics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b4f29ed8-93d8-4d48-bf2f-d293f0d0d30c

📥 Commits

Reviewing files that changed from the base of the PR and between 3410d56 and c5c1a3b.

📒 Files selected for processing (20)
  • app/api/refer-community-project/route.ts
  • app/api/refer-local-group/route.ts
  • app/api/submit-project/route.ts
  • components/LanguageSwitcher.tsx
  • components/sections/ReferCommunityProjectModal.tsx
  • components/sections/ReferLocalGroupModal.tsx
  • components/sections/SubmitProjectModal.tsx
  • messages/de.json
  • messages/en.json
  • messages/es.json
  • messages/fr.json
  • messages/it.json
  • messages/pt.json
  • src/i18n/locale-labels.ts
  • wordpress/themes/cdcf-headless/functions.php
  • wordpress/themes/cdcf-headless/includes/handlers/refer-community-project.php
  • wordpress/themes/cdcf-headless/includes/handlers/refer-local-group.php
  • wordpress/themes/cdcf-headless/includes/handlers/submit-project.php
  • wordpress/themes/cdcf-headless/includes/security.php
  • wordpress/themes/cdcf-headless/tests/SubmissionHandlerTestBase.php

Comment thread components/sections/ReferCommunityProjectModal.tsx
Comment thread src/i18n/locale-labels.ts Outdated
Locale labels migrated from LanguageSwitcher.tsx had been ASCII-stripped
(Espanol / Francais / Portugues) — restore the proper autonyms
(Español / Français / Português) so the language dropdown in the
submission modals and the existing language switcher display the
correctly-spelled native names. Per CodeRabbit review on PR #231.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JohnRDOrazio JohnRDOrazio merged commit 6a8554b into main Jun 16, 2026
13 checks passed
@JohnRDOrazio JohnRDOrazio deleted the feat/submission-language-selector branch June 16, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants