Opened 8 years ago
Last modified 6 years ago
#38715 new enhancement
Facilitate posts storing raw JSON in post_content by short-circuiting KSES and other filters
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | |
Component: | Posts, Post Types | Keywords: | needs-patch reporter-feedback 2nd-opinion |
Focuses: | Cc: |
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.
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