{"id":402756,"date":"2026-11-12T05:20:20","date_gmt":"2026-11-12T05:20:20","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/shakewell-two-way-relationships-for-acf\/"},"modified":"2026-11-12T05:20:05","modified_gmt":"2026-11-12T05:20:05","slug":"shakewell-relationship-sync","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/shakewell-relationship-sync\/","author":23603011,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.1","stable_tag":"0.1.1","tested":"7.1.4","requires":"6.5","requires_php":"8.1","requires_plugins":null,"header_name":"Shakewell Two-way Relationships for ACF","header_author":"Shakewell","header_description":"Keeps ACF relationship and post object fields linked on both posts of a pair. Needs Advanced Custom Fields.","last_updated":"2026-11-12 05:20:05","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/shakewellagency\/shakewell-relationship-sync","header_author_uri":"https:\/\/shakewell.agency","rating":0,"author_block_rating":0,"active_installs":0,"downloads":46,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.1":{"tag":"0.1.1","author":"shakewellagency","date":"2026-11-12 05:20:05","revision":3797539}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.1"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[2211,2217,2213,77028,2219],"plugin_category":[59],"plugin_contributors":[292146],"plugin_business_model":[],"class_list":["post-402756","plugin","type-plugin","status-publish","hentry","plugin_tags-acf","plugin_tags-advanced-custom-fields","plugin_tags-bidirectional","plugin_tags-post-object","plugin_tags-relationship","plugin_category-utilities-and-tools","plugin_contributors-shakewellagency","plugin_committers-shakewellagency"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/shakewell-relationship-sync.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Link a book to its author and the author shows the book too. Remove the link on either side and it disappears from both.<\/p>\n\n<p>You tell the plugin which fields belong together. It then keeps both posts in step whenever Advanced Custom Fields saves one of them. It stores values exactly as ACF does, so nothing needs migrating and your REST output and templates do not change.<\/p>\n\n<p>How it behaves:<\/p>\n\n<ul>\n<li>Works with ACF relationship fields and post object fields, single or multiple.<\/li>\n<li>Adds the back-link at the end of the other list, so the order of existing links is kept. Linking twice never duplicates.<\/li>\n<li>A single-value side, or a relationship side that has reached its maximum, is left as it is. The plugin never replaces another link.<\/li>\n<li>Ignores revisions, autosaves and non-post locations such as options pages and users.<\/li>\n<li>Does not listen to trashing, restoring or deleting a post. Links to a trashed post stay until you change them.<\/li>\n<li>The other post is updated whenever the editor may save the first post. There is no separate capability check on the other post.<\/li>\n<li>It does not use ACF's own \"bidirectional\" setting, so it also works with data created before that setting existed.<\/li>\n<li>No settings screen, no database tables, no front-end output.<\/li>\n<\/ul>\n\n<p>Requires Advanced Custom Fields, free or Pro. WordPress cannot express \"free or Pro\" as a plugin dependency, so the plugin checks at run time and shows an admin notice if ACF is not active.<\/p>\n\n<h4>Setup<\/h4>\n\n<p>Add the pairs with the <code>shakewell_relationship_sync_pairs<\/code> filter, for example in your theme's <code>functions.php<\/code> or a small must-use plugin. Each pair is two field names or field keys. The pair works in both directions. A field that shares its name with the field on the other post type is paired with itself:<\/p>\n\n<pre><code>add_filter( 'shakewell_relationship_sync_pairs', function () {\n    return array(\n        \/\/ Same field name in both field groups.\n        array( 'book_author_relationship', 'book_author_relationship' ),\n        \/\/ Different names, matched by field key.\n        array( 'field_64a1b2c3d4e5f', 'field_64a1b2c3d4e60' ),\n    );\n} );\n<\/code><\/pre>\n\n<p>Field keys are shown in the field group editor when you turn on \"Field keys\" in the screen options.<\/p>\n\n<h4>Repair after an import<\/h4>\n\n<p>Imports and direct database edits skip ACF, so back-links can be missing. With WP-CLI:<\/p>\n\n<pre><code>wp shakewell-relationship-sync repair --dry-run\nwp shakewell-relationship-sync repair\n<\/code><\/pre>\n\n<p>The command walks every post that stores a paired field, in batches, and adds the missing back-links. It never removes anything and is safe to run again. It reports posts and links checked, back-links added, links left alone because the other side was full, and links that point at deleted posts.<\/p>\n\n<h4>External services<\/h4>\n\n<p>None. The plugin makes no outside requests and collects no data.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate Advanced Custom Fields.<\/li>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>, or install it with Composer, and activate it.<\/li>\n<li>Add your pairs with the filter shown in the description.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20acf%20pro%3F\"><h3>Do I need ACF Pro?<\/h3><\/dt>\n<dd><p>No. The free ACF plugin is enough.<\/p><\/dd>\n<dt id=\"is%20anything%20stored%20in%20a%20new%20format%3F\"><h3>Is anything stored in a new format?<\/h3><\/dt>\n<dd><p>No. Values are written the way ACF writes them: an array of ids as text for multiple fields, one id as text (or an empty string) for a single post object, plus the usual field reference row.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20both%20sides%20are%20saved%3F\"><h3>What happens if both sides are saved?<\/h3><\/dt>\n<dd><p>Nothing extra. The plugin writes the other post directly, without triggering ACF again, so there is no loop and saving twice changes nothing.<\/p><\/dd>\n<dt id=\"why%20was%20a%20link%20not%20added%20on%20the%20other%20post%3F\"><h3>Why was a link not added on the other post?<\/h3><\/dt>\n<dd><p>The other post has no paired field (check the field group location rules), or its side is single-value or at its maximum and already holds a different post.<\/p><\/dd>\n<dt id=\"a%20user%20cannot%20edit%20the%20other%20post.%20will%20it%20still%20be%20updated%3F\"><h3>A user cannot edit the other post. Will it still be updated?<\/h3><\/dt>\n<dd><p>Yes. Anyone who can save the first post can link it, and the back-link is written without checking their rights on the other post. Do not use this plugin where that is not acceptable.<\/p><\/dd>\n<dt id=\"where%20do%20i%20report%20a%20security%20problem%3F\"><h3>Where do I report a security problem?<\/h3><\/dt>\n<dd><p>Please do not open a public issue. Follow SECURITY.md in the plugin's repository.<\/p><\/dd>\n<dt id=\"moving%20from%20post%202%20post%20for%20acf\"><h3>Moving from Post 2 Post for ACF<\/h3><\/dt>\n<dd><p>Post 2 Post for ACF pairs fields that share a name across field groups. Add one pair per shared name with the filter, using the same field name on both sides. Stored data is already in the right format. The plugin stays silent while Post 2 Post for ACF is active, so you can install both, then deactivate and delete Post 2 Post for ACF. Run <code>wp shakewell-relationship-sync repair --dry-run<\/code> afterwards to confirm nothing is missing. The Post 2 Post tuning filters (<code>acf\/post2post\/...<\/code>) have no equivalent.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Readme and tests use neutral examples.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First release.<\/li>\n<\/ul>","raw_excerpt":"When a post is linked to another through an ACF relationship or post object field, the other post links back. Unlinking removes the link back.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/402756","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=402756"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/shakewellagency"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=402756"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=402756"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=402756"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=402756"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=402756"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=402756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}