3 * Customize API: WP_Customize_Partial class
6 * @subpackage Customize
11 * Core Customizer class for implementing selective refresh partials.
13 * Representation of a rendered region in the previewed page that gets
14 * selectively refreshed when an associated setting is changed.
15 * This class is analogous of WP_Customize_Control.
19 class WP_Customize_Partial {
26 * @var WP_Customize_Selective_Refresh
31 * Unique identifier for the partial.
33 * If the partial is used to display a single setting, this would generally
34 * be the same as the associated setting's ID.
48 * @type string $base ID base.
49 * @type array $keys Keys for multidimensional.
52 protected $id_data = array();
55 * Type of this partial.
61 public $type = 'default';
64 * The jQuery selector to find the container element for the partial.
73 * IDs for settings tied to the partial.
82 * The ID for the setting that this partial is primarily responsible for rendering.
84 * If not supplied, it will default to the ID of the first setting.
90 public $primary_setting;
93 * Capability required to edit this partial.
95 * Normally this is empty and the capability is derived from the capabilities
96 * of the associated `$settings`.
109 * @see WP_Customize_Partial::render()
110 * @var callable Callback is called with one argument, the instance of
111 * WP_Customize_Partial. The callback can either echo the
112 * partial or return the partial as a string, or return false if error.
114 public $render_callback;
117 * Whether the container element is included in the partial, or if only the contents are rendered.
123 public $container_inclusive = false;
126 * Whether to refresh the entire preview in case a partial cannot be refreshed.
128 * A partial render is considered a failure if the render_callback returns false.
134 public $fallback_refresh = true;
139 * Supplied `$args` override class property defaults.
141 * If `$args['settings']` is not defined, use the $id as the setting ID.
146 * @param WP_Customize_Selective_Refresh $component Customize Partial Refresh plugin instance.
147 * @param string $id Control ID.
148 * @param array $args {
149 * Optional. Arguments to override class property defaults.
151 * @type array|string $settings All settings IDs tied to the partial. If undefined, `$id` will be used.
154 public function __construct( WP_Customize_Selective_Refresh $component, $id, $args = array() ) {
155 $keys = array_keys( get_object_vars( $this ) );
156 foreach ( $keys as $key ) {
157 if ( isset( $args[ $key ] ) ) {
158 $this->$key = $args[ $key ];
162 $this->component = $component;
164 $this->id_data['keys'] = preg_split( '/\[/', str_replace( ']', '', $this->id ) );
165 $this->id_data['base'] = array_shift( $this->id_data['keys'] );
167 if ( empty( $this->render_callback ) ) {
168 $this->render_callback = array( $this, 'render_callback' );
172 if ( ! isset( $this->settings ) ) {
173 $this->settings = array( $id );
174 } else if ( is_string( $this->settings ) ) {
175 $this->settings = array( $this->settings );
178 if ( empty( $this->primary_setting ) ) {
179 $this->primary_setting = current( $this->settings );
184 * Retrieves parsed ID data for multidimensional setting.
190 * ID data for multidimensional partial.
192 * @type string $base ID base.
193 * @type array $keys Keys for multidimensional array.
196 final public function id_data() {
197 return $this->id_data;
201 * Renders the template partial involving the associated settings.
206 * @param array $container_context Optional. Array of context data associated with the target container (placement).
207 * Default empty array.
208 * @return string|array|false The rendered partial as a string, raw data array (for client-side JS template),
209 * or false if no render applied.
211 final public function render( $container_context = array() ) {
215 if ( ! empty( $this->render_callback ) ) {
217 $return_render = call_user_func( $this->render_callback, $this, $container_context );
218 $ob_render = ob_get_clean();
220 if ( null !== $return_render && '' !== $ob_render ) {
221 _doing_it_wrong( __FUNCTION__, __( 'Partial render must echo the content or return the content string (or array), but not both.' ), '4.5.0' );
225 * Note that the string return takes precedence because the $ob_render may just\
226 * include PHP warnings or notices.
228 $rendered = null !== $return_render ? $return_render : $ob_render;
232 * Filters partial rendering.
236 * @param string|array|false $rendered The partial value. Default false.
237 * @param WP_Customize_Partial $partial WP_Customize_Setting instance.
238 * @param array $container_context Optional array of context data associated with
239 * the target container.
241 $rendered = apply_filters( 'customize_partial_render', $rendered, $partial, $container_context );
244 * Filters partial rendering for a specific partial.
246 * The dynamic portion of the hook name, `$partial->ID` refers to the partial ID.
250 * @param string|array|false $rendered The partial value. Default false.
251 * @param WP_Customize_Partial $partial WP_Customize_Setting instance.
252 * @param array $container_context Optional array of context data associated with
253 * the target container.
255 $rendered = apply_filters( "customize_partial_render_{$partial->id}", $rendered, $partial, $container_context );
261 * Default callback used when invoking WP_Customize_Control::render().
263 * Note that this method may echo the partial *or* return the partial as
264 * a string or array, but not both. Output buffering is performed when this
265 * is called. Subclasses can override this with their specific logic, or they
266 * may provide an 'render_callback' argument to the constructor.
268 * This method may return an HTML string for straight DOM injection, or it
269 * may return an array for supporting Partial JS subclasses to render by
270 * applying to client-side templating.
275 * @param WP_Customize_Partial $partial Partial.
276 * @param array $context Context.
277 * @return string|array|false
279 public function render_callback( WP_Customize_Partial $partial, $context = array() ) {
280 unset( $partial, $context );
285 * Retrieves the data to export to the client via JSON.
290 * @return array Array of parameters passed to the JavaScript.
292 public function json() {
294 'settings' => $this->settings,
295 'primarySetting' => $this->primary_setting,
296 'selector' => $this->selector,
297 'type' => $this->type,
298 'fallbackRefresh' => $this->fallback_refresh,
299 'containerInclusive' => $this->container_inclusive,
305 * Checks if the user can refresh this partial.
307 * Returns false if the user cannot manipulate one of the associated settings,
308 * or if one of the associated settings does not exist.
313 * @return bool False if user can't edit one one of the related settings,
314 * or if one of the associated settings does not exist.
316 final public function check_capabilities() {
317 if ( ! empty( $this->capability ) && ! current_user_can( $this->capability ) ) {
320 foreach ( $this->settings as $setting_id ) {
321 $setting = $this->component->manager->get_setting( $setting_id );
322 if ( ! $setting || ! $setting->check_capabilities() ) {