Skip to content

Commit ce47cab

Browse files
committed
v0.4.2: Complete i18n (373 strings), new plugin icon, i18n tooling
- Fix POT: now includes all 373 translatable strings (PHP + JS), up from 154 - Wrap 30+ remaining hardcoded strings in field settings with __() - Add i18n:pot script (memory-safe POT generation) - Add i18n:audit script (detects unwrapped strings in TSX/JS) - Update WordPress.org icon from animated logo - Bump version to 0.4.2
1 parent 804733f commit ce47cab

16 files changed

Lines changed: 1390 additions & 60 deletions

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
---
11+
## [0.4.2] - 2026-02-24
1112

13+
### Fixed
14+
- **i18n: Complete POT file** — POT now includes all 373 translatable strings (PHP + JS), up from 154 (PHP-only). Fixed by increasing PHP memory limit for WP-CLI JS parser.
15+
- **i18n: Unwrapped strings** — Wrapped 30+ remaining hardcoded strings in field settings (descriptions, placeholders, loading states) with `__()`.
16+
17+
### Added
18+
- `pnpm i18n:pot` — Regenerate the POT file (PHP + JS) in one command
19+
- `pnpm i18n:audit` — Scan source files for potentially unwrapped strings
20+
- `pnpm i18n:audit:strict` — Same audit, exits 1 on findings (CI mode)
21+
- New animated plugin logo as WordPress.org icon
22+
23+
### Changed
24+
- Plugin icon updated on WordPress.org (extracted from animated logo)
25+
26+
---
1227
## [0.3.0] - 2026-02-20
1328

1429
### Security

admin/src/fields/PostObjectFieldSettings.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export function PostObjectFieldSettings({ field, onSettingsChange }: PostObjectF
7575
disabled={loading}
7676
>
7777
<SelectTrigger>
78-
<SelectValue placeholder={loading ? "Loading..." : "Select post type"} />
78+
<SelectValue placeholder={loading ? __('Loading...', 'codeideal-open-fields') : __('Select post type', 'codeideal-open-fields')} />
7979
</SelectTrigger>
8080
<SelectContent>
8181
{postTypes.map((type) => (
@@ -86,7 +86,7 @@ export function PostObjectFieldSettings({ field, onSettingsChange }: PostObjectF
8686
</SelectContent>
8787
</Select>
8888
<p className="text-xs text-muted-foreground">
89-
Select which post type to search from
89+
{__('Select which post type to search from', 'codeideal-open-fields')}
9090
</p>
9191
</div>
9292

@@ -95,7 +95,7 @@ export function PostObjectFieldSettings({ field, onSettingsChange }: PostObjectF
9595
<div className="space-y-0.5">
9696
<Label>{__('Select Multiple', 'codeideal-open-fields')}</Label>
9797
<p className="text-xs text-muted-foreground">
98-
Allow selecting multiple posts
98+
{__('Allow selecting multiple posts', 'codeideal-open-fields')}
9999
</p>
100100
</div>
101101
<Switch
@@ -112,15 +112,15 @@ export function PostObjectFieldSettings({ field, onSettingsChange }: PostObjectF
112112
onValueChange={(value) => updateSetting('return_format', value)}
113113
>
114114
<SelectTrigger>
115-
<SelectValue placeholder="Select return format" />
115+
<SelectValue placeholder={__('Select return format', 'codeideal-open-fields')} />
116116
</SelectTrigger>
117117
<SelectContent>
118118
<SelectItem value="object">{__('Post Object', 'codeideal-open-fields')}</SelectItem>
119119
<SelectItem value="id">{__('Post ID', 'codeideal-open-fields')}</SelectItem>
120120
</SelectContent>
121121
</Select>
122122
<p className="text-xs text-muted-foreground">
123-
Format of the value returned by get_field()
123+
{__('Format of the value returned by get_field()', 'codeideal-open-fields')}
124124
</p>
125125
</div>
126126

@@ -129,7 +129,7 @@ export function PostObjectFieldSettings({ field, onSettingsChange }: PostObjectF
129129
<div className="space-y-0.5">
130130
<Label>{__('Allow Null', 'codeideal-open-fields')}</Label>
131131
<p className="text-xs text-muted-foreground">
132-
Allow empty value
132+
{__('Allow empty value', 'codeideal-open-fields')}
133133
</p>
134134
</div>
135135
<Switch

admin/src/fields/RepeaterFieldSettings.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function RepeaterFieldSettings({ field, onSettingsChange }: FieldSettings
4949
placeholder="0"
5050
/>
5151
<p className="text-xs text-muted-foreground">
52-
Minimum number of rows required
52+
{__('Minimum number of rows required', 'codeideal-open-fields')}
5353
</p>
5454
</div>
5555
<div className="space-y-2">
@@ -60,10 +60,10 @@ export function RepeaterFieldSettings({ field, onSettingsChange }: FieldSettings
6060
min={0}
6161
value={max}
6262
onChange={(e) => handleChange('max', parseInt(e.target.value, 10) || 0)}
63-
placeholder="0 (unlimited)"
63+
placeholder={__('0 (unlimited)', 'codeideal-open-fields')}
6464
/>
6565
<p className="text-xs text-muted-foreground">
66-
Maximum allowed (0 = unlimited)
66+
{__('Maximum allowed (0 = unlimited)', 'codeideal-open-fields')}
6767
</p>
6868
</div>
6969
</div>
@@ -76,7 +76,7 @@ export function RepeaterFieldSettings({ field, onSettingsChange }: FieldSettings
7676
onValueChange={(value) => handleChange('layout', value)}
7777
>
7878
<SelectTrigger id="repeater-layout">
79-
<SelectValue placeholder="Select layout" />
79+
<SelectValue placeholder={__('Select layout', 'codeideal-open-fields')} />
8080
</SelectTrigger>
8181
<SelectContent>
8282
<SelectItem value="table">{__('Table', 'codeideal-open-fields')}</SelectItem>
@@ -85,7 +85,7 @@ export function RepeaterFieldSettings({ field, onSettingsChange }: FieldSettings
8585
</SelectContent>
8686
</Select>
8787
<p className="text-xs text-muted-foreground">
88-
How repeater rows should be displayed
88+
{__('How repeater rows should be displayed', 'codeideal-open-fields')}
8989
</p>
9090
</div>
9191

@@ -100,16 +100,14 @@ export function RepeaterFieldSettings({ field, onSettingsChange }: FieldSettings
100100
placeholder={__('Add Row', 'codeideal-open-fields')}
101101
/>
102102
<p className="text-xs text-muted-foreground">
103-
Text displayed on the add row button
103+
{__('Text displayed on the add row button', 'codeideal-open-fields')}
104104
</p>
105105
</div>
106106

107107
{/* Sub-fields Note */}
108108
<div className="rounded-md bg-muted p-3">
109109
<p className="text-sm text-muted-foreground">
110-
<strong>{__('Sub-fields:', 'codeideal-open-fields')}</strong> Add sub-fields by clicking the "Add Field" button
111-
inside this repeater in the field list above. Sub-fields will be repeated
112-
for each row.
110+
<strong>{__('Sub-fields:', 'codeideal-open-fields')}</strong> {__('Add sub-fields by clicking the "Add Field" button inside this repeater in the field list above. Sub-fields will be repeated for each row.', 'codeideal-open-fields')}
113111
</p>
114112
</div>
115113
</div>

admin/src/fields/SelectFieldSettings.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function SelectFieldSettings({ field, onSettingsChange }: FieldSettingsPr
101101
onValueChange={(value) => onSettingsChange({ layout: value })}
102102
>
103103
<SelectTrigger>
104-
<SelectValue placeholder="Select layout" />
104+
<SelectValue placeholder={__('Select layout', 'codeideal-open-fields')} />
105105
</SelectTrigger>
106106
<SelectContent>
107107
<SelectItem value="vertical">{__('Vertical', 'codeideal-open-fields')}</SelectItem>
@@ -162,7 +162,7 @@ export function SelectFieldSettings({ field, onSettingsChange }: FieldSettingsPr
162162
onValueChange={(value) => onSettingsChange({ return_format: value })}
163163
>
164164
<SelectTrigger id={`return-format-${field.id}`}>
165-
<SelectValue placeholder="Select format" />
165+
<SelectValue placeholder={__('Select format', 'codeideal-open-fields')} />
166166
</SelectTrigger>
167167
<SelectContent>
168168
<SelectItem value="value">{__('Value', 'codeideal-open-fields')}</SelectItem>

admin/src/fields/TaxonomyFieldSettings.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
7070
disabled={loading}
7171
>
7272
<SelectTrigger>
73-
<SelectValue placeholder={loading ? "Loading..." : "Select taxonomy"} />
73+
<SelectValue placeholder={loading ? __('Loading...', 'codeideal-open-fields') : __('Select taxonomy', 'codeideal-open-fields')} />
7474
</SelectTrigger>
7575
<SelectContent>
7676
{taxonomies.map((tax) => (
@@ -81,7 +81,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
8181
</SelectContent>
8282
</Select>
8383
<p className="text-xs text-muted-foreground">
84-
Select which taxonomy to choose terms from
84+
{__('Select which taxonomy to choose terms from', 'codeideal-open-fields')}
8585
</p>
8686
</div>
8787

@@ -93,7 +93,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
9393
onValueChange={(value) => updateSetting('field_type', value)}
9494
>
9595
<SelectTrigger>
96-
<SelectValue placeholder="Select appearance" />
96+
<SelectValue placeholder={__('Select appearance', 'codeideal-open-fields')} />
9797
</SelectTrigger>
9898
<SelectContent>
9999
<SelectItem value="select">{__('Dropdown', 'codeideal-open-fields')}</SelectItem>
@@ -102,7 +102,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
102102
</SelectContent>
103103
</Select>
104104
<p className="text-xs text-muted-foreground">
105-
How the field should be displayed
105+
{__('How the field should be displayed', 'codeideal-open-fields')}
106106
</p>
107107
</div>
108108

@@ -112,7 +112,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
112112
<div className="space-y-0.5">
113113
<Label>{__('Select Multiple', 'codeideal-open-fields')}</Label>
114114
<p className="text-xs text-muted-foreground">
115-
Allow selecting multiple terms
115+
{__('Allow selecting multiple terms', 'codeideal-open-fields')}
116116
</p>
117117
</div>
118118
<Switch
@@ -130,15 +130,15 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
130130
onValueChange={(value) => updateSetting('return_format', value)}
131131
>
132132
<SelectTrigger>
133-
<SelectValue placeholder="Select return format" />
133+
<SelectValue placeholder={__('Select return format', 'codeideal-open-fields')} />
134134
</SelectTrigger>
135135
<SelectContent>
136136
<SelectItem value="id">{__('Term ID', 'codeideal-open-fields')}</SelectItem>
137137
<SelectItem value="object">{__('Term Object', 'codeideal-open-fields')}</SelectItem>
138138
</SelectContent>
139139
</Select>
140140
<p className="text-xs text-muted-foreground">
141-
Format of the value returned by get_field()
141+
{__('Format of the value returned by get_field()', 'codeideal-open-fields')}
142142
</p>
143143
</div>
144144

@@ -147,7 +147,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
147147
<div className="space-y-0.5">
148148
<Label>{__('Save Terms', 'codeideal-open-fields')}</Label>
149149
<p className="text-xs text-muted-foreground">
150-
Connect selected terms to the post
150+
{__('Connect selected terms to the post', 'codeideal-open-fields')}
151151
</p>
152152
</div>
153153
<Switch
@@ -161,7 +161,7 @@ export function TaxonomyFieldSettings({ field, onSettingsChange }: TaxonomyField
161161
<div className="space-y-0.5">
162162
<Label>{__('Load Terms', 'codeideal-open-fields')}</Label>
163163
<p className="text-xs text-muted-foreground">
164-
Load value from the post's terms
164+
{__('Load value from the post\'s terms', 'codeideal-open-fields')}
165165
</p>
166166
</div>
167167
<Switch

admin/src/fields/UserFieldSettings.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
7070
disabled={loading}
7171
>
7272
<SelectTrigger>
73-
<SelectValue placeholder={loading ? "Loading..." : "All Roles"} />
73+
<SelectValue placeholder={loading ? __('Loading...', 'codeideal-open-fields') : __('All Roles', 'codeideal-open-fields')} />
7474
</SelectTrigger>
7575
<SelectContent>
7676
<SelectItem value="__all__">{__('All Roles', 'codeideal-open-fields')}</SelectItem>
@@ -82,7 +82,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
8282
</SelectContent>
8383
</Select>
8484
<p className="text-xs text-muted-foreground">
85-
Filter users by role (leave empty for all)
85+
{__('Filter users by role (leave empty for all)', 'codeideal-open-fields')}
8686
</p>
8787
</div>
8888

@@ -91,7 +91,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
9191
<div className="space-y-0.5">
9292
<Label>{__('Select Multiple', 'codeideal-open-fields')}</Label>
9393
<p className="text-xs text-muted-foreground">
94-
Allow selecting multiple users
94+
{__('Allow selecting multiple users', 'codeideal-open-fields')}
9595
</p>
9696
</div>
9797
<Switch
@@ -108,7 +108,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
108108
onValueChange={(value) => updateSetting('return_format', value)}
109109
>
110110
<SelectTrigger>
111-
<SelectValue placeholder="Select return format" />
111+
<SelectValue placeholder={__('Select return format', 'codeideal-open-fields')} />
112112
</SelectTrigger>
113113
<SelectContent>
114114
<SelectItem value="array">{__('User Array', 'codeideal-open-fields')}</SelectItem>
@@ -117,7 +117,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
117117
</SelectContent>
118118
</Select>
119119
<p className="text-xs text-muted-foreground">
120-
Format of the value returned by get_field()
120+
{__('Format of the value returned by get_field()', 'codeideal-open-fields')}
121121
</p>
122122
</div>
123123

@@ -126,7 +126,7 @@ export function UserFieldSettings({ field, onSettingsChange }: UserFieldSettings
126126
<div className="space-y-0.5">
127127
<Label>{__('Allow Null', 'codeideal-open-fields')}</Label>
128128
<p className="text-xs text-muted-foreground">
129-
Allow empty value
129+
{__('Allow empty value', 'codeideal-open-fields')}
130130
</p>
131131
</div>
132132
<Switch

admin/src/pages/FieldsetEditor/components/CopyFieldDialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ export function CopyFieldDialog({
201201
onValueChange={setSelectedFieldsetId}
202202
>
203203
<SelectTrigger className="mt-1">
204-
<SelectValue placeholder="Select fieldset..." />
204+
<SelectValue placeholder={__('Select fieldset...', 'codeideal-open-fields')} />
205205
</SelectTrigger>
206206
<SelectContent>
207207
<SelectItem value="current">

admin/src/pages/FieldsetEditor/components/MoveFieldDialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export function MoveFieldDialog({ field, allFields, maxDepth }: MoveFieldDialogP
109109
onValueChange={setSelectedParent}
110110
>
111111
<SelectTrigger id="move-location" className="mt-2">
112-
<SelectValue placeholder="Select location" />
112+
<SelectValue placeholder={__('Select location', 'codeideal-open-fields')} />
113113
</SelectTrigger>
114114
<SelectContent>
115115
<SelectItem value="_root">

admin/src/pages/FieldsetEditor/components/TypeSpecificSettings.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
import { fieldRegistry } from '../../../lib/field-registry';
12+
import { __ } from '@wordpress/i18n';
1213
import { GeneralFieldSettings } from '../../../fields/GeneralFieldSettings';
1314
import type { Field } from '../../../types';
1415

@@ -28,7 +29,7 @@ export function TypeSpecificSettings({
2829
<>
2930
{/* General Settings - Apply to ALL fields */}
3031
<div className="border-t pt-4">
31-
<h4 className="text-sm font-medium mb-3">General Settings</h4>
32+
<h4 className="text-sm font-medium mb-3">{__('General Settings', 'codeideal-open-fields')}</h4>
3233
<GeneralFieldSettings
3334
field={field}
3435
onSettingsChange={onSettingsChange}

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openfields",
3-
"version": "0.4.1",
3+
"version": "0.4.2",
44
"type": "module",
55
"description": "Modern custom fields builder for WordPress. Create and manage custom field groups with an intuitive interface.",
66
"author": "Codeideal",
@@ -18,6 +18,9 @@
1818
"format": "prettier --write \"admin/src/**/*.{ts,tsx,css}\"",
1919
"test": "vitest",
2020
"test:ui": "vitest --ui",
21+
"i18n:pot": "bash scripts/i18n-pot.sh",
22+
"i18n:audit": "tsx scripts/i18n-audit.ts",
23+
"i18n:audit:strict": "tsx scripts/i18n-audit.ts --strict",
2124
"release": "tsx scripts/release.ts",
2225
"release:svn": "tsx scripts/release.ts --svn",
2326
"release:github": "tsx scripts/release.ts --github",

0 commit comments

Comments
 (0)