Development
The source is on GitHub. Read CONTRIBUTING.md before opening a pull request.
Setup
composer install
npm install && npm run build
bin/setup-dev.shsetup-dev.sh installs WordPress on SQLite in .dev/wp, with no Docker or MySQL needed. It links the plugin and adds demo fields. The admin login is saved to .dev/credentials.
wp --path=.dev/wp server --port=8889Tests and linting
composer test
composer lint
npm run lint:jsTests run PHPUnit against a real WordPress with a throwaway database.
Performance
These numbers come from bin/benchmark.php: 100 fields plus a repeater with 1,000 rows × 3 sub fields, on the SQLite emulation of the dev environment. MySQL writes faster.
| Operation | Time | Queries |
|---|---|---|
| Save 1,000 new rows | 2.6 s | 6,003 (1 INSERT per value) |
| Save again, nothing changed | 26 ms | 1 |
| Change 2 values | 24 ms | 5 |
get_fields() with a cold cache | 39 ms | 1 |
have_rows() over 1,000 rows with 3 get_sub_field() | 45 ms | 1 |
| Render a meta box with 1,000 rows | 110 ms, 2.4 MB of HTML | 1 |
To run the benchmark after composer test:
WPFF_DB_FILE=wpff-tests.sqlite wp --path=.dev/wp eval-file bin/benchmark.phpTranslations
The template is languages/freeform-fields.pot. A Russian translation ships with the plugin: freeform-fields-ru_RU.po, .mo, and JSON files for scripts.
After you change strings:
- Run
npm run build && npm run i18n. - Translate the new strings in the
.pofile. - Run
npm run i18nagain.
Credits
- Map editor: Leaflet (BSD-2-Clause). Map data © OpenStreetMap contributors (ODbL).
- Builder drag and drop: dnd kit (MIT).
- Thanks to the authors of Advanced Custom Fields for the conventions this plugin is compatible with.
License
GPL-2.0-or-later. Copyright © 2026 kiberberik and WP Freeform Fields contributors.