This page provides detailed information about the backward compatibility measures implemented into Types 3.0. These functions run automatically and allow you to update to new post relationships while keeping your existing code functional.

Accessing parent post ID via the _wpcf_belongs_{$post_type_slug}_id postmeta

Previously, you would manipulate post meta with the _wpcf_belongs_{post_type_slug}_id key in order to access or set parent posts in legacy Types relationships.

With the new post relationships implementation, this will obviously not work. The postmeta is still there but it has a decreasing information value because it only holds connections from before you update your site to the new post relationships.

We minimize the impact by taking the following measures.

add_post_meta() and update_post_meta()

We perform a companion action: besides storing the _wpcf_belongs_{$post_type_slug}_id postmeta in the database, we:

  • Create a new association in the legacy relationship that matches the parent and child post types, if any.
  • Delete any existing relationship that might exist between that parent and child in the legacy relationship, if we are updating.


We use a filter that WordPress provides to hijack and short-circuit get_post_meta() on demand: get_post_metadata. In case the metadata refers to a legacy relationship that matches new post relationships association, we return the association parent ID; otherwise, we let the native function continue and get whatever there is in the postmeta entry, if any.


Support for deleting associations via delete_post_meta() is not implemented. We think that this is a very rare scenario, but we’re open to reconsidering based on the feedback from clients.

Important note about timing

The postmeta access compatibility layer is only available after init:11. This is because Types registers its post types at init:10 and we need them to be registered to query for legacy relationships at init:11 and compose the right hooks in postmeta access functions. Because of this, you will only be able to use this legacy layer on init:12 and later.

To be on the safe side, we advise to access these postmeta values as late as possible, but definitely not sooner than init:15. Even if you make it work earlier, we cannot guarantee that it will keep working this way with future updates.

Using _wpcf_belongs_{$post_type}_id in WP_Query

We check the postmeta query arguments and if we detect an understandable usage of the legacy relationship postmeta, transform it into a toolset_relationships query.

We check for:

  • meta_key and meta_value or meta_value_num
  • meta_query

However, there are several limitations to what we can parse:

  • Only legacy (migrated) relationships are supported.
  • It must be possible to determine a single relationship from the information passed to the query:
    • The postmeta already contains the parent post type slug.
    • For the child slug, either there’s some information in the post_type query argument, or we check against all post types. For example, if there are legacy relationships between the post types
      A >> B, A >> C, B >> C, we will always succeed with a meta_query for _wpcf_belongs_b_id (because there is only a single relationship that has B post type as a parent), but we will succeed with _wpcf_belongs_a_id only if the query also contains a post_type argument that doesn’t contain both B and C post types. Non-legacy relationships are completely ignored here.
  • Only the topmost level of the meta_query is processed, and we ignore anything nested.
  • meta_compare argument or compare within meta_query must be = (or missing, since this is the default value)
  • relation within meta_query must be AND (or missing).

If we hit any of these limitations, we don’t do anything and let the query run as-is.

Otherwise, the condition is turned into a toolset_relationships one and removed.

Note that we also remove meta_key together with meta_value / meta_value_num, which is necessary for the query to produce correct results. meta_key might theoretically be used for ordering, but it makes very little sense to order by IDs of parent post, so we took the risk.

This is all WPML-compatible and should produce results according to the allowed translation mode of post types involved in a relationship.

The usual timing restrictions apply: The later the better, and do not rely on this before init:15.

Using _wpcf_belongs_{$post_type}_id in wpv-conditional and wpv-if shortcodes

The wpv-conditional shortcode (and wpv-if as well, for that matter) are being used to check if a post is related to another (i.e. has a parent post) by checking its _wpcf_belongs_{$post_type}_id postmeta.

With the new post relationships, this approach becomes obsolete, but we specifically check for these postmeta keys when evaluating conditions, and replace any such value with the ID of the parent post in given relationship.

As usual, this works only for relationships migrated from the legacy implementation.

Backward-compatible legacy Types functions

The following functions have been recommended to clients in the past, and they will keep working for the migrated relationships after new post relationships are activated:

  • wpcf_pr_get_belongs()
  • wpcf_pr_post_get_belongs()
  • wpcf_pr_admin_get_belongs()
  • wpcf_pr_get_has()
  • wpcf_pr_admin_get_has()