Title: Managing Posts
Author: liranadia
Published: September 2, 2026

---

 1. [Plugins](https://docs.wpvip.com/plugins/)
 2. [Automattic plugins](https://docs.wpvip.com/plugins/automattic-plugins/)
 3. [Safe Publish](https://docs.wpvip.com/plugins/automattic-plugins/safe-publish/)
 4. Managing Posts

#  Managing Posts

## Browsing and managing posts

With the Integration activated, **Safe Publish → Manage** opens the catalog of source
content, named for the source it is reading from. Use the **Type**, **Title or URL**,**
Published Date**, **Local State**, and **Source Status** controls to filter the 
table.

![The Safe Publish Manage screen in WP Admin, listing source posts with their published
date, local state, local status, and source status.](https://docs.wpvip.com/wp-content/
uploads/sites/2/2026/08/safe-publish-manage.png)

The Local State control provides 4 views:

 * **All** — every source post, including imported posts.
 * **Not imported** — the post does not currently have an active destination import.
 * **Up to date** — the post has been imported, and the source has not changed since.
 * **Outdated** — the post has been imported, but the source has changed since the
   last import. Re-import to bring the destination copy up to date.

## Importing content

Safe Publish imports a single post or many posts at once. Both produce the same 
result for each post: media is downloaded to the destination, source URLs in the
content are rewritten to point at the destination, taxonomy terms and metadata are
applied, and the operation is recorded and can be rolled back.

### Import a single post

 1. On **Manage → Posts**, use the **Import** row action.
 2. The import starts right away. If the destination post is already live — published
    or private — confirm the overwrite first, because it changes the live site immediately.

By default, importing a child post fails if its parent is not present on the destination,
to avoid creating orphaned content. Developers can change this with the `safe_publish_import_allow_orphans`
filter (see [Filters](https://docs.wpvip.com/plugins/automattic-plugins/safe-publish/managing-posts?output_format=md#filters)).

### Import multiple posts (bulk import)

 1. On **Manage → Posts**, select the posts to import.
 2. Review the confirmation, which names the affected posts grouped by what each group
    receives: posts imported as new drafts, and posts updated with the latest source
    content. The grouping predicts what the import will do; the results reported after
    the run are authoritative.
 3. Start the bulk import.

Safe Publish records the selected posts in one history session and reports each 
item’s result independently. If one post fails, the others are not rolled back. 
When the selection includes posts with parent–child relationships, the plugin orders
the import so that parents are created before their children.

## Previewing changes with Compare

The Compare action on **Manage → Posts** fetches fresh source content and compares
it with the current destination post, covering the title, content, excerpt, featured
image, metadata, and taxonomy terms, including each term’s parent and description.

The comparison is shown side by side, and block-editor content is compared block
by block so editors can see which blocks were added, removed, or changed. The modal
also offers an **Update** button that re-imports the post from the source.

## Rolling back imports

Rollback reverses a single import:

 * If the post was newly created, the post is deleted.
 * If the post was updated, the previous content is restored. Safe Publish captures
   that content at import time; in the rare case where no copy was captured, the
   post is deleted instead.

A rollback reverses the changes made by that one import. If a post has gone through
a series of changes, each change can be rolled back sequentially. Rolling back an
update leaves the post imported. The row normally returns to **Outdated**, because
the source still has the newer content, and the Edit action remains available.

Multiple rows can be selected on the Posts tab and rolled back in a single action.

**Note:** **Rolling back a newly created post deletes that post on the destination**,
and the deletion cannot be undone. Confirm the affected posts before rolling back.
The post remains on the source and can be imported again.

## Needs attention

**Manage → Needs attention** collects post-import problems in one place, so a bulk
run that mostly succeeded does not hide the few items that did not. Each row reports
the Content it affects, a Type of **Failed** or **Degraded**, a Detail describing
the problem, a Severity of Error or Warning, and when it happened. **View** opens
the underlying record.

### What lands in Needs attention

 * **Failures.** The import errored, and no local post was created, or a re-import
   of an existing post failed. Nothing on the destination changed.
 * **Degradations.** The post imported, but something could not be carried over.
   Typical causes are an unresolved block reference, a taxonomy the destination 
   does not register, or term fields that could not be reconciled with the source.

A degradation that another import can resolve carries a hint saying whether that
import has happened yet: **Resolvable now** means retrying will reconnect the reference,
and **Waiting on import** means the post or term it points at is still missing from
the destination. A degradation that only a site change can fix, such as a taxonomy
on the source that is not registered on the destination, carries no hint and offers
no Retry. Registering that taxonomy on the destination makes a retry available.

### Clearing an item

 * **Retry** re-runs the reconciliation. Use it on a **Resolvable now** item directly.
   For a **Waiting on import** item, import the missing target first, then retry.
   A bulk Retry reports how many issues resolved, how many are still waiting on 
   an import, and how many failed.
 * **Ignore** sets an item aside without deleting it, moving it to the Ignored view.
   Use it for a problem that has been identified and is not going to be fixed now.
 * **Un-ignore** returns an ignored item to the Open list. Ignoring is always reversible.
 * **Remove** permanently deletes a failure record. It is offered for failures only,
   because a degraded post still exists on the destination.

Fixing the underlying cause is what clears a degradation for good. Import a missing
parent or referenced post, register a missing taxonomy on the destination, then 
retry.

## How media and content are processed

When a post is imported, Safe Publish processes its content so that it renders correctly
on the destination without depending on the source site:

 * **Featured images and inline media** referenced from the source site are downloaded
   and added to the destination’s media library. This includes media in `img`, `
   video`, `audio`, and `source` elements, and file links in classic HTML and in
   block markup.
 * **Source URLs are rewritten** to point at the destination’s copies, so the imported
   content no longer links back to the source.
 * **Media is deduplicated** by its original URL. If Safe Publish has already imported
   the same source file, it reuses the existing attachment on the destination instead
   of downloading it again.
 * **Third-party media is left untouched.** Safe Publish does not download files
   hosted on domains other than the source site; it preserves their original URLs
   as written.

Safe Publish records where imported content came from in post metadata — including
the source post ID and source permalink — so that subsequent imports of the same
post update the existing post rather than duplicating it.

## Author attribution

Safe Publish attributes each imported post to a user on the destination site, matched
by the source author’s email address. The matched user becomes the imported post’s
author.

If the source author’s email does not match any user on the destination, Safe Publish
does not guess. By default, the import stops with an error identifying the unmatched
author, so an administrator can create a matching user and re-import. Developers
can relax this with the `safe_publish_import_allow_author_fallback` filter: when
enabled, a new post whose author cannot be matched is attributed to the user running
the import, an updated post keeps its existing author, and a warning is recorded
in the import history.

The source author’s email and username are stored in post metadata for reference,
regardless of how attribution is resolved.

## Audit events

Safe Publish writes an audit log of security- and content-relevant actions to the
destination site. Logged events include authenticated cross-site requests, content
exports, the result of each imported item, rollbacks, and changes to the connection
settings.

Each event records a channel (such as authentication, content, export, import, or
media), a severity level (informational, warning, or error), the event type, a timestamp,
and structured details. The export history is surfaced in the admin interface; the
full log is available to developers through the plugin’s query interface and through
the `safe_publish_event_logged` action (see [Filters](https://docs.wpvip.com/plugins/automattic-plugins/safe-publish/managing-posts?output_format=md#filters)).

## Custom post types

Safe Publish imports any registered post type, not only posts and pages. The source
catalog can be filtered by post type, and custom post types are imported the same
way as standard ones.

For a post type to appear in the source catalog, it must be registered on the source
with `show_in_rest` set to `true` and `public` set to `true`. Both values must be
the boolean `true`: a truthy value such as `1` registers the REST route but excludes
the type from the catalog. Safe Publish additionally allows `wp_navigation` and `
wp_block`, which are not public but whose posts are content. Attachments are excluded
because they are files rather than content posts.

The catalog reports each type’s REST API base, which can differ from its registered
slug, and which of the `title`, `content`, and `excerpt` raw fields the type supports.
Import and Compare require only the fields the source declares, so a type that does
not support all three — a navigation post, which has no excerpt — imports without
reporting a missing field.

A post type registered with a custom `rest_controller_class` must expose a standard
WordPress item schema, and each supported field must declare a `properties.raw` 
definition. A field absent from both the catalog metadata and the response is treated
as unsupported.

A custom post type must be registered with the same slug on the destination for 
its content to import cleanly. Safe Publish does not remap a source post type slug
to a different slug on the destination; if the slugs differ, the import will not
place the content under the destination’s post type.

## Filters

Safe Publish exposes the following filters for developers.

| Filter | Default | Purpose | 
| `safe_publish_import_kses` | `false` | Enable `wp_kses` sanitization of imported content. | 
| `safe_publish_import_kses_allowed_html` | `wp_kses_allowed_html( 'post' )` | Customize the allowed HTML used when `safe_publish_import_kses` sanitization is enabled. Receives the allowed-tags array and the name of the field being sanitized. | 
| `safe_publish_import_allow_orphans` | `false` | Allow importing a child post when its parent is not present on the destination. | 
| `safe_publish_import_allow_author_fallback` | `false` | When the source author cannot be matched on the destination, attribute new posts to the importing user and keep the existing author on updates, instead of aborting the import. | 
| `safe_publish_auth_max_time_diff` | `300` | Maximum allowed difference, in seconds, between a signed request’s timestamp and the current time. | 
| `safe_publish_request_timeout` | `10` | Timeout, in seconds, for HTTP requests to the source site. | 
| `safe_publish_request_args` | — | Customize the arguments passed to the HTTP request made to the source site. | 
| `safe_publish_dev_ssl_verify` | `false` | Development only: skip SSL verification for requests to non-localhost hosts. Leave disabled in production. |

The `safe_publish_event_logged` action fires each time an audit event is recorded,
receiving the channel, event type, and event data. Use it to forward audit events
to external monitoring.

    ```lang-php
    add_action(
    	'safe_publish_event_logged',
    	function ( string $channel, string $event, array $data ): void {
    		// Forward the event to an external log or monitoring service.
    	},
    	10,
    	3
    );
    ```

Last updated: September 02, 2026