Greyd\\Preparred_Post is a data abstraction for WordPress posts that you can reliably export from one site and import into another. The class wraps a post’s core fields and augments them with everything needed for a safe round-trip: post meta, taxonomy terms, nested references found inside content or meta, attached media, language metadata, and optional menu resolution. It is used by Post Export and Global Content.
The class accepts a WP_Post, a post ID, or a plain array. During construction, it gathers and normalizes all required data. It also rewrites references to nested posts and terms in the block content into stable placeholders, so you can restore those references on import even if IDs differ across sites.
Architecture and flow
You instantiate Preparred_Post with a post (ID/object/array) and optional export_arguments. The constructor coerces the input into a WP_Post and then populates the public properties. The preparation sequence runs in a fixed order:
- Nested posts: It scans
post_contentusing patterns fromget_nested_post_patterns(). For each referenced post (by ID or slug/type), it collects minimal info and replaces the in-content reference with a placeholder{{<post_id>}}. This covers templates, forms, attachments, and other embedded resources. - Nested terms: It registers temporary dynamic taxonomies and scans
post_contentfor taxonomy references (including JSON structures such astaxQueryandadvancedFilter). It replaces found term IDs with placeholders like{{t_<term_id>}}and stores the referenced terms for later restoration. - Dynamic strings: It runs
Post_Export_Helper::replace_dynamic_strings()overpost_contentto normalize environment-dependent strings. - Post meta: It pulls all post meta, skips blacklisted or “maybe skip” keys, unserializes values, lets filters adjust values, and stores the result in
meta. During export/import, this ensures consistent treatment of complex meta. - Terms: It fetches all assigned terms per taxonomy using a low-level helper (
Helper::get_post_taxonomy_terms) to avoid language-related filter side effects. If the post represents a dynamic taxonomy (viaposttype_settingsmeta), it limits preparation to that taxonomy’s terms. - Media: If the post is an attachment, it records filename, absolute path, and URL, so importers can move the file or relink it.
- Language: If a translation tool is detected, it records the language code, tool metadata, and—when
export_arguments['translations']is enabled—the IDs of available translations for the post. - Menus (optional): When
export_arguments['resolve_menus']is true, it rewriteswp:navigation-linkblocks to custom links by expandingidbased references into plain URLs, removing tool-specific attributes that won’t survive across sites.
Throughout the process, the class logs progress using do_action( 'greyd_post_export_log', ... ) hooks, and exposes several filters to alter meta and content during preparation.
Import and conflict behavior flags
Two properties describe what should happen later during import:
conflict_actioncontrols how to react if a post with the samepost_nameandpost_typealready exists on the target site:keep(default): keep the existing post and insert the new one with a new ID.replace: replace the existing post with the new one.skip: skip importing this post.
import_actioncommunicates the desired final state after import:insert(default): insert the post (or update if the process supports it).draft: set post status to draft.trash: move to trash.delete: delete permanently.
Note: Preparred_Post does not execute import logic by itself. It only prepares data and signals intent via the properties above. Your importer applies these flags.
Placeholder strategy
The placeholder strategy is central to portability. IDs in content or JSON attributes are converted into {{<id>}} (posts) and {{t_<term_id>}} (terms). On import, you resolve placeholders to target-site IDs based on slugs, types, or other lookup rules, then replace placeholders back to concrete IDs.
Limitations and notes
The class avoids opinionated import behavior. It focuses on consistent extraction and marking of dependencies. Because it skips blacklisted meta and may normalize strings, always check filters and helper callbacks if you rely on site-specific meta. Menu resolution only runs when explicitly enabled. Translation handling depends on the active translation tool and helper functions in Post_Export_Helper.
Developer reference
Below is a reference of the public properties and methods you’ll interact with when preparing and transporting posts.
Public properties
ID(int): The source post ID.post_name(string): Post slug.post_title(string): Post title.post_type(string, defaultpost): Post type.post_date(stringY-m-d H:i:s): Local publish time.post_date_gmt(stringY-m-d H:i:s): GMT publish time.post_content(string): Post content, after placeholder replacement and optional menu resolution.guid(string): GUID as stored with the post.post_author(int): Author user ID.post_excerpt(string): Excerpt.post_status(string, defaultpublish): Status.comment_status(string, defaultopen): Comments open/closed.ping_status(string, defaultopen): Pings open/closed.post_password(string): Post password in plain text.to_ping(string): URLs queued to be pinged.pinged(string): URLs already pinged.post_modified(stringY-m-d H:i:s): Local modified time.post_modified_gmt(stringY-m-d H:i:s): GMT modified time.post_content_filtered(string): Utility field for content filters.post_parent(int): Parent ID.menu_order(int): Menu order.post_mime_type(string): Attachment MIME type.comment_count(int): Cached count.filter(string|null): Internal WordPress filter marker.meta(array): All prepared post meta. Keys are meta keys; values are arrays of values (unserialized and filtered). Blacklisted and skipped meta are excluded.terms(array): Assigned terms grouped by taxonomy. Each taxonomy key maps to a list of term arrays carrying the minimal importable details (IDs, slugs, hierarchy included viaget_term_parents()).nested(array): Referenced posts discovered inpost_content. Keys are post IDs. Values contain: ID, post_name, post_type, front_url.nested_terms(array): Referenced terms discovered inpost_content. Keys are term IDs; values areWP_Termobjects ornullif missing.media(array): Only for attachments; contains: name, path, url.language(array): Language metadata if a translation tool is active: code, tool, post_ids, args.export_arguments(array): Export options; constructor merges passed defaults with any values already set on the instance.conflict_action(string, one ofkeep|replace|skip, defaultkeep): Desired conflict handling on import.import_action(string, one ofinsert|draft|trash|delete, defaultinsert): Desired action after import.
Public methods
__construct( $post, $export_arguments = array() )
Accepts a post ID, WP_Post, object, or array and optional export arguments. Coerces input to a WP_Post, initializes core fields, merges export_arguments, and runs the preparation pipeline in order: prepare_nested_posts(), prepare_nested_terms(), prepare_strings(), prepare_meta(), prepare_terms(), prepare_media(), prepare_language(), prepare_menus().
Notes: If $post is invalid or missing an ID, the constructor returns early and the instance remains unprepared.
prepare_nested_posts(): void
Scans post_content for references to posts using patterns from get_nested_post_patterns( $this->ID, $this ). For each match, resolves the target by ID or by { post_name, post_type }, replaces content references with {{<ID>}}, and records minimal info in nested. Attachments get their front URL via wp_get_attachment_url(); other post types use get_permalink().
Logs: Emits granular debug lines via greyd_post_export_log.
prepare_nested_terms(): void
Registers dynamic taxonomies to stabilize parsing. Scans post_content for term references. It handles raw markup patterns as well as JSON fragments such as "taxQuery": {...} and "advancedFilter": [...]. It replaces each found term ID with {{t_<term_id>}} and records the term objects in nested_terms (or null if missing).
Why: This makes taxonomy-dependent content portable across sites with different term IDs.
prepare_strings(): void
Normalizes environment-dependent strings in post_content by delegating to Post_Export_Helper::replace_dynamic_strings( $content, $post_id ).
prepare_meta(): void
Loads all meta via get_post_meta( $this->ID ), skips blacklisted keys (Post_Export_Helper::blacklisted_meta()), applies “maybe skip” logic (Post_Export_Helper::maybe_skip_meta_option()), unserializes values, and exposes a filter for each meta key: apply_filters( 'greyd_export_post_meta-' . $meta_key, $value, $post_id, $export_arguments ). Adds each (possibly filtered) value to meta[ $meta_key ][].
prepare_terms(): void
Populates terms with assigned terms per taxonomy. When the post defines posttype_settings[is_taxonomy], it limits preparation to that taxonomy. Otherwise, it enumerates taxonomies and fetches terms using Helper::get_post_taxonomy_terms( $post_id, $taxonomy ) to avoid language filter interference. It resolves parent chains via get_term_parents() to preserve hierarchy.
get_term_parents( WP_Term $term, array $prepared ): WP_Term
Recursively resolves and rewrites a term’s parent to ensure parent terms are included and correctly referenced in terms. It prevents cycles with the $prepared list and logs each resolution step.
prepare_media(): void
If the current post is an attachment, it sets media with the file name, absolute path from get_attached_file( $ID ), and URL via wp_get_attachment_url( $ID ). This information allows importers to move or relink files.
prepare_language(): void
Initializes language with the detected translation tool (via Post_Export_Helper::get_translation_tool()). If a tool is active, it stores language details for the post and, when export_arguments['translations'] is true, collects translation post IDs via Post_Export_Helper::get_translated_post_ids( $this ).
prepare_menus(): void
Runs only when export_arguments['resolve_menus'] is truthy. It parses post_content for wp:navigation-link blocks and rewrites them to custom links by resolving referenced IDs to URLs, removing tool-specific attributes (type, id), and re-encoding the block with minimal attributes. Applies the filter greyd_post_export_resolve_menus to the final content.
Usage guidance
- Build a
Preparred_Postas the first step of any export. The instance contains everything you need to serialize it to JSON and ship it to another site. - On import, use
post_name+post_typefor lookups, then resolve placeholders inpost_contentand meta using your target-site IDs for posts and terms. - Respect
conflict_actionandimport_actionwhen applying changes to the target site. - If your content uses Navigation blocks and you want stable custom links on import, set
resolve_menusinexport_arguments. - If your project relies on translations, enable
translationsinexport_argumentsand integrate the language details during import.