With this plugin you can add typed, ordered relations between posts - editable from the block editor's document sidebar, the classic editor's meta box, or the Tools screen - and query them back with a WP_Query extension, a REST field, or a Query Loop block variation. The plugin is available on WordPress.org (slug content-relations; this repository is ph-wp-content-relations).
public/ is exactly what ships to wordpress.org; everything else is repository-only.
ph-content-relations.php in the root is a development wrapper that loads public/, so
the whole repository can be symlinked into wp-content/plugins during development.
Releases are cut by release-please from conventional commits and deployed to the wordpress.org SVN by GitHub Actions — see .github/WORKFLOWS.md. Contribution rules and the local setup are in CONTRIBUTING.md.
- Block editor: a Content Relations panel in the document sidebar, grouped by relation type. Saves with the rest of the post, the way a taxonomy does - no separate save button.
- Classic editor: the same editor (
src/shared/RelationsEditor.jsx), in a meta box instead of the sidebar. - Tools → Content Relations: every relation type in a sortable, searchable
WP_List_Table. Opening a type there lets you reorder or remove its relations across every post that uses it, grouped by source post.
All three write through the same paths: the block editor and meta box via the
content_relations_edit REST field (classes/rest-editor.php), the Tools screen's
per-type editor via /content-relations/v1/reorder.
- Related content block: a
core/queryvariation (src/query-loop/QueryLoopVariation.jsx,classes/query-loop.php) that lists the post it's placed on's own related posts under one chosen type, in their saved order (post__in+orderby=post__in) - drop it in wherever a "related articles" section belongs. - REST: a read-only
content_relationsfield on every post type's REST response, carrying both directions of a relation - only those whose both posts the current user may read, so visitors see relations between published posts. WP_Queryextension: see below.
| Hook | Type | Purpose |
|---|---|---|
content_relations_add_meta_box |
filter | false hides the classic meta box; receives $add, $post_type, $post |
content_relations_meta_box_title |
filter | the meta box title; receives $title, $post_type, $post |
content_relations_meta_box_post_types |
filter | the post types the editor's search offers |
content_relations_meta_box_find_query_args |
filter | the WP_Query arguments of that search |
content_relations_modify_rest_attribute_name |
filter | the name of the read-only REST field, default content_relations |
content_relations_modify_rest_json |
filter | the relations in that field; the plugin itself uses it at priority 10 to drop relations the current user may not read |
content_relations_meta_box_list_before / _after |
action | output before and after the meta box editor; receives $post |
Disable the meta box for some posts:
add_filter( 'content_relations_add_meta_box', function ( $add, $post_type, $post ) {
return 'page' !== $post_type;
}, 10, 3 );You can use the content_relations argument in new WP_Query($args) to get related posts.
$query = new WP_Query(array(
...
"content_relations" => array(
"from" => $post_id,
"to" => $post_id,
"with" => $post_id,
"type"=> String|Array of strings
)
));from ==> Get post relations created on post edit $post_id page
to ==> Get post relations created on related posts edit page
with ==> Get from AND to related posts
type ==> Get only posts with specified type or types
You can use the following functions in theme. Wrap with if function_exists.
$store = content_relations_get_store($post_id);Parameters:
$post_id ==> ID of the post we want relations for.
$relations = content_relations_get_relations_by_post_id($post_id);Parameters:
$post_id ==> ID of the post we want relations for.
Return
Array of objects as follows:
source_id ==> Post ID of source post. (The Post in which meta field the relation was created)
target_id ==> Post ID of related target.
type ==> Relation type slug.
weight ==> Weight of relation in list. (Used for sorting)
post_title ==> Title of related post.
post_type ==> Post type of related post.
Parameters:
$relations = content_relations_get_relations_by_post_id_and_type($post_id, $relation_type, $source_only = true);$post_id ==> ID of the post we want relations for.
$type_slug ==> Slug of relation type. Default: true
$source_only ==> Get only relations where post ID is source or all relations.
Return
Array of objects as follows:
source_id ==> Post ID of source post. (The Post in which meta field the relation was created)
target_id ==> Post ID of related target.
type ==> Relation type slug.
weight ==> Weight of relation in list. (Used for sorting)
post_title ==> Title of related post.
post_type ==> Post type of related post.
Please report vulnerabilities privately, see SECURITY.md.
GPL-3.0-or-later, see LICENSE.