WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 9 months ago

#38715 new enhancement

Facilitate posts storing raw JSON in post_content by short-circuiting KSES and other filters

Reported by: westonruter Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: Posts, Post Types Keywords: needs-patch reporter-feedback 2nd-opinion
Focuses: Cc:
PR Number:

Description

When attempting to store arbitrary JSON in WordPress, the post_content field is the logical choice. Using post_content to store arbitrary JSON instead of postmeta is more performant and it also means that the JSON content will automatically get support for revisions.

Storing JSON is done in core now for customize_changeset posts and it is done in the widget_instance post type in the Customize Widgets Plus plugin. In both cases, however, there are challenges when storing the JSON due to filters that may apply on content_save_pre. In particular, the KSES filters will apply on the post_content and strip out markup that is intended to be contained within JSON strings. The solution taken by changesets is to wrap the updates to the customize_changeset post type by the \WP_Customize_Manager::save_changeset_post() method. Before this method calls wp_update_post()/wp_insert_post() it suspends the KSES filters temporarily:

<?php
$has_kses = ( false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' ) );
if ( $has_kses ) {
        kses_remove_filters(); // Prevent KSES from corrupting JSON in post_content.
}
wp_update_post( /*...*/ );
if ( $has_kses ) {
        kses_init_filters();
}

This works, however it is ugly. It also means that post updates via WP-CLI and via the REST API won't work as expected because the filters won't be suspended as in this wrapper method.

One idea is that we could introduce a new post_type_support for json_content, and when the post type supports that, it could bypass any content_save_pre filters applying.

See also #15515.

Change History (4)

#1 @TobiasBg
3 years ago

This would indeed be nice, I've been doing similar tricks in my TablePress plugin, which stores JSON-encoded two-dimensional arrays in post_content:
https://github.com/TobiasBg/TablePress/blob/master/models/model-post.php#L157-L174

#2 @desrosj
9 months ago

  • Keywords needs-patch reporter-feedback 2nd-opinion added

@westonruter Is this still of interest to you? Are you able to take a first pass?

#3 @westonruter
9 months ago

@desrosj It's not a priority on my radar now, sorry!

#4 @TobiasBg
9 months ago

Also see #46316 on why this would be nice after #43187 added another filter on content_save_pre that needs to be removed to be able to store JSON content safely.

Note: See TracTickets for help on using tickets.