Skip to content

feat(rawir): ACF Options Pages in RawIR as acf_options - #42

Merged
ABB65 merged 1 commit into
mainfrom
feat/acf-options
Sep 27, 2026
Merged

ABB65 merged 1 commit into
mainfrom
feat/acf-options

Conversation

@ABB65

@ABB65 ABB65 commented Sep 27, 2026

Copy link
Copy Markdown
Member

What

ACF Options Pages reach RawIR as acf_options (contract: Contentrain/ai#333, RawAcfOptionsPage[]). Until now an options page became Bridge's own acf-options-<slug> singleton only, so it never reached Migrate's REST-path conversion. The "Site settings" fields were lost on both paths.

  • Models::options_page() returns the page as RawIR holds it: {slug, title, post_id, fields}. The values are the same secret-filtered, default-language ones its singleton already holds.
  • Source::acf_fields_for_options_page() adds each field's ACF type and label (optional in RawAcfValue), so the reader types a post_object as a relation rather than an integer.
  • Jobs write bridge/acf-options.json when the site has options pages. Rawir and tools/prepare-migrate.mjs add acf_options beside options, so the two stay equal (BR-19 check in coverage-rawir.mjs).
  • README: one paragraph.

Dependency

Bridge writes JSON only and has no runtime dependency on the types release. The test pins (@contentrain/types 1.14.0, @contentrain/wp-import 0.5.7) do not read acf_options, so test:coverage, test:store and test:reader do not depend on ai#333. This PR does not wait for the pin bump. Migrate reads the field only after ai#333 is released and bumped. Release: 0.6.0 (together with draft parity); #41 (0.5.0) stays unchanged.

Checks

  • tests/run.sh: 384 PASS, including 5 new: all 4 pages in RawIR; title and post_id; value, field_key and type; the repeater's rows; each page carries only its own fields, and a custom post_id is kept
  • npm test green; test:coverage + test:store + test:reader 207 PASS (BR-19: rawir.json = the RawIR prepare-migrate builds)

Reviewer: t9

Each options page's slug, title, storage post_id and fields (the same
secret-filtered default-language values its singleton holds, with ACF
type and label) go to bridge/acf-options.json and RawIR acf_options, so
Migrate's REST-path conversion sees site settings. prepare-migrate
mirrors the field.
@ABB65

ABB65 commented Sep 27, 2026

Copy link
Copy Markdown
Member Author

ONAY 20c0a67 (t9)

Contract (RawAcfOptionsPage, ai#333): options_page() returns {slug (sanitize_title(menu_slug)), title, post_id (string), fields}. fields is (object) $raw, so an empty page is {}, not []. There's no early return, so no null item can land in the array. RawIR::write and prepare-migrate.mjs add the field under the same condition (only when the file exists), so BR-19 equality holds.

Secret filter: options fields go through the same Policy::secret_name + Acf::EXCLUDED rule as a post's ACF (source.php:183 ↔ :229). The B4 (#32) type-first rule is consistent on both paths, and the values come from the same acf_value. type and label are added, so a post_object is typed as a relation in wp-import.

Scope: acf_fields_for_options_page reads groups with options_page => menu_slug, so pages that share post_id: options still get only their own fields (the new check proves it).

Gates:

  • CI all green: syntax 7.4/8.3, metadata, small, large 64M/128M, acceptance
  • Acceptance log: 1023 PASS / 0 FAIL, all 5 new checks PASS, test:coverage/store/reader green
  • The pins don't read acf_options, so there's no dependency on the types release (as the description says).

Note: the ai#333 prefix/counter rule (acf-options- dropped, _2 + acf_options_renamed) applies on the reader side; the Bridge sends the slug raw, which is correct.

@ABB65
ABB65 merged commit fa8ad30 into main Sep 27, 2026
9 checks passed
@ABB65
ABB65 deleted the feat/acf-options branch September 27, 2026 09:09
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.

1 participant