{"id":13759628,"url":"https://github.com/10up/distributor","last_synced_at":"2025-08-07T22:59:24.197Z","repository":{"id":37470731,"uuid":"64331416","full_name":"10up/distributor","owner":"10up","description":"Share content between your websites.","archived":false,"fork":false,"pushed_at":"2025-05-07T04:36:46.000Z","size":14256,"stargazers_count":662,"open_issues_count":236,"forks_count":158,"subscribers_count":116,"default_branch":"develop","last_synced_at":"2025-05-07T05:27:37.833Z","etag":null,"topics":["content","content-distribution-network","content-distributor","content-management","distribution","hacktoberfest","management","syndication","wordpress"],"latest_commit_sha":null,"homepage":"https://distributorplugin.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/10up.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-07-27T18:14:01.000Z","updated_at":"2025-04-28T13:23:08.000Z","dependencies_parsed_at":"2023-09-23T16:53:24.867Z","dependency_job_id":"4b21e3bb-a464-4ed6-82a6-7dbf8c59fd72","html_url":"https://github.com/10up/distributor","commit_stats":null,"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/10up%2Fdistributor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/10up%2Fdistributor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/10up%2Fdistributor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/10up%2Fdistributor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/10up","download_url":"https://codeload.github.com/10up/distributor/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253397479,"owners_count":21902027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["content","content-distribution-network","content-distributor","content-management","distribution","hacktoberfest","management","syndication","wordpress"],"created_at":"2024-08-03T13:00:56.482Z","updated_at":"2025-08-07T22:59:24.186Z","avatar_url":"https://github.com/10up.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# Distributor\n\n![Distributor](https://github.com/10up/distributor/blob/develop/assets/img/banner-1544x500.png)\n\n[![Support Level](https://img.shields.io/badge/support-active-green.svg)](#support-level) [![Release Version](https://img.shields.io/github/release/10up/distributor.svg)](https://github.com/10up/distributor/releases/latest) ![WordPress tested up to version](https://img.shields.io/badge/WordPress-v6.8%20tested-success.svg) [![License](https://img.shields.io/github/license/10up/distributor.svg)](https://github.com/10up/distributor/blob/develop/LICENSE.md) [![Dependency Review](https://github.com/10up/distributor/actions/workflows/dependency-review.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/dependency-review.yml) [![WordPress Playground Demo](https://img.shields.io/badge/Playground_Demo-8A2BE2?logo=wordpress\u0026logoColor=FFFFFF\u0026labelColor=3858E9\u0026color=3858E9)](https://playground.wordpress.net/?blueprint-url=https://raw.githubusercontent.com/10up/distributor/refs/heads/develop/.github/blueprints/blueprint.json)\n[![E2E Tests](https://github.com/10up/distributor/actions/workflows/cypress.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/cypress.yml) [![PHPUnit Tests](https://github.com/10up/distributor/actions/workflows/test.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/test.yml) [![Linting](https://github.com/10up/distributor/actions/workflows/lint.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/lint.yml) [![Code scanning](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/10up/distributor/actions/workflows/codeql-analysis.yml)\n\n\u003e Distributor is a WordPress plugin that makes it easy to distribute and reuse content across your websites — whether in a single multisite or across the web.\n\n*You can learn more about Distributor's features at [DistributorPlugin.com](https://distributorplugin.com) and documentation at the [Distributor documentation site](https://10up.github.io/distributor/).*\n\n*Note:* The latest stable version of the plugin is the *stable* branch. [Download the stable branch]((https://github.com/10up/distributor/archive/stable.zip)) if you are intending to use the plugin in a Production environment.\n\n## Overview\n\nDistributor supports safe, SEO-friendly content reuse and sharing via \"pushing\" and \"pulling\".\n\nWhile logged in and editing or viewing any single post (or custom post type) that can be distributed, a `Distributor` admin bar item will appear, that will facilitate sharing (\"pushing\") that content to any `connection`.\n\n\u003ca href=\"http://distributorplugin.com/\"\u003e\u003cimg src=\"https://distributorplugin.com/wp-content/themes/distributor-theme/assets/img/push-screenshot.jpg\" alt=\"Push the content you’re editing or viewing to any of your other sites from the admin bar\" width=\"600\"\u003e\u003c/a\u003e\n\nIn the admin dashboard, a top level Distributor menu item links to the \"pull\" screen. Here, editors can share (\"pull\") content from any `connection` into the current site.\n\n\u003ca href=\"http://distributorplugin.com/\"\u003e\u003cimg src=\"https://distributorplugin.com/wp-content/themes/distributor-theme/assets/img/pull-screenshot.jpg\" alt=\"Pull content from another site from the Distributor admin menu\" width=\"600\"\u003e\u003c/a\u003e\n\nContent this is distributed (via Push or Pull) is connected to the original.  Reposted content receives updates from the original, canonical source automatically.\n\n\u003ca href=\"http://distributorplugin.com/\"\u003e\u003cimg alt=\"Distributor intuitively presents the origin and status of any reused content\" class=\"browser-frame\" src=\"https://distributorplugin.com/wp-content/themes/distributor-theme/assets/img/syndicated-screenshot.jpg\" width=\"600\"\u003e\u003c/a\u003e\n\nThere are two connection types: `internal` and `external`.\n* Internal connections are other sites inside of the same multisite network. Any user logged into the network can distribute any content in the network to any other sites in the network where that user has permission to publish posts (assuming the site supports the same post type).\n* External connections are external websites, connected by the JSON REST API using the Authorization Setup Wizard for External Connections leveraging Application Passwords. External connections can be added in the WordPress admin dashboard under `Distributor` \u003e `External Connections`. Administrators can decide which user roles are allowed to distribute content to and from that connection (Editors and Administrators by default). All users with those roles will inherit the permissions of the user account used to establish the remote connection.\n\n### Extendability\n\nDistributor is built with the same extensible approach as WordPress itself, with [fully documented hooks and filters](https://10up.github.io/distributor/) to customize its default behavior and create custom distribution workflows.  You can even create connections to other platforms.\n\n## Requirements\n\n* PHP 7.4+\n* [WordPress](http://wordpress.org) 6.5+\n* External connections require HTTP Basic Authentication or [WordPress.com OAuth2](https://developer.wordpress.com/docs/oauth2/) (must be on [WordPress VIP](https://wpvip.com/)) be set up on the remote website. For Basic Auth, we recommend using [Application Passwords](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/#Getting-Credentials) built in to WordPress.\n* For external connections, Distributor needs to be installed on BOTH sides of the connection.\n* Version 2.0.0 of Distributor requires version 2.0.0 on BOTH sides of all connections. For other version 2.0.0 specific changes, please see our [migration guide](https://10up.github.io/distributor/tutorial-migration-guide-version-1-to-version-2.html).\n\n## Installation\n\nFor Production use, we recommend [registering and downloading the plugin from DistributorPlugin.com](https://distributorplugin.com/#cta) – it's 100% free. You will be emailed a direct link to download the latest, production-ready build. Alternatively, you can [download the latest release from GitHub](https://github.com/10up/distributor/archive/trunk.zip).\n\nYou can upload and install the archived (zip) plugin via the WordPress dashboard (`Plugins` \u003e `Add New` -\u003e `Upload Plugin`) or manually inside of the `wp-content/plugins` directory, and activate on the Plugins dashboard.\n\n### Registration\n\nTo help inform our roadmap, keep adopters apprised of major updates and changes that could impact their websites, and solicit opportunities for beta testing and feedback, we’re asking for a little bit of information in exchange for a free key that unlocks update notifications and 1-click upgrades inside the WordPress dashboard. Your information is kept confidential. You can [register here](https://distributorplugin.com/#cta) and input your key in Distributor settings in the dashboard (network dashboard for multisite users).  Note that you need to input the email address you used to register Distributor (included in the email with your registration key) as that is linked to the registration key.\n\n### Set up External Connections\n\n1. Ensure that the current version of Distributor is active on BOTH sites being connected.  We'll refer to these as mainsite.com and remotesite.com.\n1. On mainsite.com, navigate to `Distributor` \u003e `External Connections` and click `Add New`.\n1. Enter a label for the connection (e.g., `remotesite`).\n1. Enter the URL (e.g. `https://remotesite.com`) for your remote site below the External Site URL and press the `Authorize Connection` button.\n1. You will be prompted to enter the user name and password of an administrative role of the `remotesite.com` if you are not already logged into `remotesite.com` and then redirected to the Authorize Application screen.\n1. At the Authorize Application screen, enter the name of the main site and press the 'Yes, I approve of this connection' button\n1. Review the roles selected in `Roles Allowed to Push` are the ones you want to support, update if necessary, then press the `Update Connection` button.\n\n## How to Distribute Content\n\nThere are two methods for distributing content between multiple WordPress sites, Push and Pull.  Pushing allows you to share content from your site to one or more connected sites while Pulling allows you to bring content into your site from one of your connected sites.  In either method, once content has been distributed it will stay in sync with any changes made to the origin post (when Pushing the origin is the site being Pushed from, when Pulling the origin is the site being Pulled from).\n\n### Pushing Content\n\nThe `Distributor` menu in the WP Admin Bar will appear after a piece of content has been published.  Hovering over that menu item will expose the Push menu that displays the list of connected sites on the left, the list of sites that have been selected for push distribution on the right, and a button to `Distribute` the content to those selected sites.\n\n\u003cimg src=\"/.github/screenshots/screenshot-1.png\" alt=\"Push menu exposed when viewing published content on the front-end\" width=\"300\"\u003e\n\nThe same Push menu and set of Distributor options are also available after publishing a piece of content within the WordPress Block Editor.\n\n\u003cimg src=\"/.github/screenshots/screenshot-2.png\" alt=\"Push menu exposed when viewing published content in the Block Editor\" width=\"300\"\u003e\n\nAfter you click the `Distribute` button, Distributor will push the content to the selected connected sites, showing a `View` link when those pieces of content have been distributed, and noting `Post successfully distributed.` once the content has completed distributing to selected sites.\n\n\u003cimg src=\"/.github/screenshots/screenshot-3.png\" alt=\"Push menu showing details after content distribution\" width=\"300\"\u003e\n\nWhen viewing that piece of content in the Block Editor, there will be a Distributor notice in the `Status \u0026 visibility` section noting how many sites the content has been distributed to.\n\n\u003cimg src=\"/.github/screenshots/screenshot-4.png\" alt=\"Block Editor sidebar showing Distributor count of sites that content has been distributed to (via Push and Pull)\" width=\"300\"\u003e\n\nThe same Push menu is available in the WP Admin Bar if you are using the Classic Editor.  The Distributor notice is also available in the `Publish` metabox noting how many sites the content has been distributed to.\n\n\u003cimg src=\"/.github/screenshots/screenshot-5.png\" alt=\"Classic Editor showing the Push menu and metabox showing Distributor count of sites that content has been distributed to (via Push and Pull)\" width=\"300\"\u003e\n\n### Pulling Content\n\nNavigating to the `Distributor` \u003e `Pull Content` screen in the WP Admin will present you with a dropdown to select any of the sites you are connected to and will display all available pieces of content that can be Pulled into the current site.  You can select Posts, Pages, and other Custom Post Types to filter on this screen; you can use the Bulk Edit menu to Pull or Skip more than one piece of content at a time; and you can use individual row actions on each piece of content pull, view, or skip each piece of content.\n\n\u003cimg src=\"/.github/screenshots/screenshot-6.png\" alt=\"Pull Content screen showing row actions and a single post selected for Pulling\" width=\"300\"\u003e\n\nAfter you have Bulk Pulled several pieces of content or used the row actions to Pull a single piece of content, the Pull Content screen will show a confirmation message that the Pull action was successful and redirect you to the `Pulled` list view to see all the items that have been pulled into the current site.  The same process will happen if you opt to Skip specific piece(s) of content.\n\n\u003cimg src=\"/.github/screenshots/screenshot-7.png\" alt=\"Pull Content screen showing confirmation on content being pulled\" width=\"300\"\u003e\n\nYou can navigate to the `Posts` \u003e `All Posts` table list view to see all content that has been pushed or pulled to the current site via the Distributor column denoted with the Distributor icon (\u003cimg alt=\"Distributor icon\" src=\"https://github.com/10up/distributor/blob/trunk/assets/img/icon.svg\" height=\"45\" width=\"45\"\u003e).  Rows that include the Distributor icon will link off that icon to the origin site and post where that content was either pushed or pulled from.\n\n\u003cimg src=\"/.github/screenshots/screenshot-8.png\" alt=\"All Posts screen showing Distributor links for pushed and pulled content\" width=\"300\"\u003e\n\n## Support Level\n\n**Active:** 10up is actively working on this, and we expect to continue work for the foreseeable future including keeping tested up to the most recent version of WordPress.  Bug reports, feature requests, questions, and pull requests are welcome.\n\n## Known Caveats/Issues\n\n### Remote Request Timeouts\n\nWith external connections, HTTP requests are sent back and forth - creating posts, transferring images, syncing post updates, etc. In certain situations, mostly commonly when distributing posts with a large number of images (or very large file sizes), using poorly configured or saturated servers / hosts, or using plugins that add significant weight to post creation, Distributor requests can fail. Although we do some error handling, there are certain cases in which post distribution can fail silently. If distribution requests are taking a long time to load and/or failing, consider adjusting the timeout; you can filter the timeout for pushing external posts using the [`dt_push_post_timeout` filter](https://10up.github.io/distributor/dt_push_post_timeout.html). More advanced handling of large content requests, and improved error handling is on the road map for a future update.\n\n### Post Meta Associations\n\nA distributed post includes all of the post meta from the original version. Sometimes arbitrary post meta references an ID for another piece of content on the original site. Distributor _does not_ \"bring along\" the referenced content or update references for arbitrary post meta (it will take care of updating references in the case of core WordPress features, such as the featured image ID). This issue is very common when using field management plugins like Advanced Custom Fields (ACF). This can be addressed on a case-by-case basis by extending the plugin. Distributor provides the `distributor_register_data` helper function for [stored ID handling](https://10up.github.io/distributor/tutorial-stored-id-handling.html). Additionally, for external connections, you can manually handle post meta associations using [the `dt_push_post` hook](https://github.com/10up/distributor/blob/f7b60740e679bce4671ccd69a670abadce4f2f93/includes/classes/ExternalConnections/WordPressExternalConnection.php#L646). For internal connections, use the [`dt_push_post` hook](https://10up.github.io/distributor/dt_push_post.html). Note that while named the same, these hooks accept different parameters.\n\n### Stored ID Handling\n\nDistributor often deals with data stored as ID references. This is common in WordPress, where IDs are used in block attributes, shortcodes, or post meta by popular plugins like ACF, Elementor, and Gravity Forms. However, when content is distributed to another site, these stored IDs may not match, leading to data loss or unexpected content.\n\nTo address this, Distributor provides a helper function: `distributor_register_data`. This function allows developers to register data references, specify where the data is located, define how to extract the ID, and register callbacks to process the data on both the source and target sites. More information can be found [here](https://10up.github.io/distributor/tutorial-stored-id-handling.html).\n\n### Deleting Distributed Posts\n\nWhen a post that has been distributed is deleted, the distributed copies will become unlinked (\"forked\") from the original and thus become editable. Similarly, when a distributed post is unpublished, distributed copies will not be unpublished. More sophisticated \"removal\" workflow is on the road map for a future update.\n\n### Gutenberg Block Mismatch\n\nWhen distributing a Gutenberg post to another site that supports Gutenberg, if a block in the post does not exist on the receiving site, the block will be converted to a \"Classic\" HTML block.\n\n### Parent Posts\n\nDistributor does not \"bring along\" parent (or child posts). If your post (or custom post type) has a parent or a child, it will distribute it as if it's an orphan.\n\n### Custom Post Type Support\n\nInternal Connections (multisite) support multiple post types. In order for distribution to work with External Connections that have custom post type content, that post type needs to be registered with the argument `show_in_rest =\u003e true` on the external site.\n\n### Unable to Push to New Custom Post Types\n\nIf new Custom Post Types are created after establishing an External Connection, you will only be able to `Pull` those from an External Connection. To ensure you are able to `Push` new Custom Post Types to an External Connection, you will need to update the External Connection by editing it and then clicking the `Update connection` button.\n\n### Backwards Compatibility\n\nWhile we strive to be mindful of backwards compatibility much the same way WordPress itself is, we do not currently guarantee continued interoperability between different versions of Distributor. We assume the current userbase for this plugin has a high degree of control over any site that has been set up as an external connection and urge you to keep Distributor up to date.\n\n### Distributing Post content\n\nBy default, post content is rendered before being copied.  This means that shortcodes are expanded before being distributed and remote posts will not have the shortcode, but rather the expanded HTML content.\n\n### Distributing Authors\n\nBy default, distributed posts reference the original site as the \"author\" with a link to it.  This can be altered by extending Distributor with custom code to make it sync authors.\n\n### Distributing Post Date\n\nBy default, the \"post date\" on distributed posts is the date its published on the remote site, not the date published on the origin site.  This can be overridden by extending Distributor with custom code to make it preserve the post date.\n\n### Distributing Canonical URL\n\nBy default, canonical URL of distributed post will point to original content, which corresponds to SEO best practices. This can be overridden by extending Distributor with custom code and removing Distributor's default front end canonical URL filtering (look for `'get_canonical_url'` and `'wpseo_canonical'`).\n\n### Drafts as Preferred Status\n\nBy default, drafts are the preferred status and can't be changed at the source site.\n\n### Conflicts with Security plugins\n\nOftentimes the communication Distributor attempts to make across sites using the REST API will be flagged by various security plugins and surreptitiously blocked.  If you run into an issue like this, please reach out to the support for your security plugin and ask about getting Distributor unblocked ([here is an example for doing so with Wordfence](https://wordpress.org/support/topic/distributor-plugin-being-blocked/)).\n\n## Developers\n\nSee [Distributor Developer Documentation](https://10up.github.io/distributor/#developers).\n\n## Changelog\n\nA complete listing of all notable changes to Distributor are documented in [CHANGELOG.md](https://github.com/10up/distributor/blob/develop/CHANGELOG.md).\n\n## Contributing\n\nPlease read [CODE_OF_CONDUCT.md](https://github.com/10up/distributor/blob/develop/CODE_OF_CONDUCT.md) for details on our code of conduct and [CONTRIBUTING.md](https://github.com/10up/distributor/blob/develop/CONTRIBUTING.md) for details on the process for submitting pull requests to us.\n\n## Like what you see?\n\n\u003ca href=\"http://10up.com/contact/\"\u003e\u003cimg src=\"https://github.com/10up/.github/blob/trunk/profile/10up-github-banner.jpg\" width=\"850\" alt=\"Work with the 10up WordPress Practice at Fueled\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F10up%2Fdistributor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F10up%2Fdistributor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F10up%2Fdistributor/lists"}