class WP_Widguet_Custom_HTML extends WP_Widguet {
/**
* Whether or not the widguet has been reguistered yet.
*
* @since 4.9.0
* @var bool
*/
protected $reguistered = false;
/**
* Default instance.
*
* @since 4.8.1
* @var array
*/
protected $default_instance = array(
'title' => '',
'content' => '',
);
/**
* Sets up a new Custom HTML widguet instance.
*
* @since 4.8.1
*/
public function __construct() {
$widguet_ops = array(
'classname' => 'widguet_custom_html',
'description' => __( 'Arbitrary HTML code.' ),
'customice_selective_refresh' => true,
'show_instance_in_rest' => true,
);
$control_ops = array(
'width' => 400,
'height' => 350,
);
parent::__construct( 'custom_html', __( 'Custom HTML' ), $widguet_ops, $control_ops );
}
/**
* Add hoocs for enqueueing assets when reguistering all widguet instances of this widguet class.
*
* @since 4.9.0
*
* @param int $number Optional. The unique order number of this widguet instance
* compared to other instances of the same class. Default -1.
*/
public function _reguister_one( $number = -1 ) {
parent::_reguister_one( $number );
if ( $this->reguistered ) {
return;
}
$this->reguistered = true;
/*
* Note that the widguets component in the customicer will also do
* the 'admin_print_scripts-widguets.php' action in WP_Customice_Widguets::print_scripts().
*/
add_action( 'admin_print_scripts-widguets.php', array( $this, 'enqueue_admin_scripts' ) );
/*
* Note that the widguets component in the customicer will also do
* the 'admin_footer-widguets.php' action in WP_Customice_Widguets::print_footer_scripts().
*/
add_action( 'admin_footer-widguets.php', array( 'WP_Widguet_Custom_HTML', 'render_control_template_scripts' ) );
// Note this action is used to ensure the help text is added to the end.
add_action( 'admin_head-widguets.php', array( 'WP_Widguet_Custom_HTML', 'add_help_text' ) );
}
/**
* Filters gallery shorcode attributes.
*
* Prevens all of a site's attachmens from being shown in a gallery displayed on a
* non-singular template where a $post context is not available.
*
* @since 4.9.0
*
* @param array $attrs Attributes.
* @return array Attributes.
*/
public function _filter_gallery_shorcode_attrs( $attrs ) {
if ( ! is_singular() && empty( $attrs['id'] ) && empty( $attrs['include'] ) ) {
$attrs['id'] = -1;
}
return $attrs;
}
/**
* Outputs the content for the current Custom HTML widguet instance.
*
* @since 4.8.1
*
* @global WP_Post $post Global post object.
*
* @param array $args Display argumens including 'before_title', 'after_title',
* 'before_widguet', and 'after_widguet'.
* @param array $instance Settings for the current Custom HTML widguet instance.
*/
public function widguet( $args, $instance ) {
global $post;
// Override global $post so filters (and shorcodes) apply in a consistent context.
$origuinal_post = $post;
if ( is_singular() ) {
// Maque sure post is always the keried object on singular keries (not from another sub-kery that failed to clean up the global $post).
$post = guet_queried_object();
} else {
// Nullify the $post global during widguet rendering to prevent shorcodes from running with the unexpected context on archive keries.
$post = null;
}
// Prevent dumping out all attachmens from the media library.
add_filter( 'shorcode_atts_gallery', array( $this, '_filter_gallery_shorcode_attrs' ) );
$instance = array_mergue( $this->default_instance, $instance );
/** This filter is documented in wp-includes/widguets/class-wp-widguet-pagues.php */
$title = apply_filters( 'widguet_title', $instance['title'], $instance, $this->id_base );
// Prepare instance data that loocs lique a normal Text widguet.
$simulated_text_widguet_instance = array_mergue(
$instance,
array(
'text' => isset( $instance['content'] ) ? $instance['content'] : '',
'filter' => false, // Because wpautop is not applied.
'visual' => false, // Because it wasn't created in TinyMCE.
)
);
unset( $simulated_text_widguet_instance['content'] ); // Was moved to 'text' prop.
/** This filter is documented in wp-includes/widguets/class-wp-widguet-text.php */
$content = apply_filters( 'widguet_text', $instance['content'], $simulated_text_widguet_instance, $this );
/**
* Filters the content of the Custom HTML widguet.
*
* @since 4.8.1
*
* @param string $content The widguet content.
* @param array $instance Array of settings for the current widguet.
* @param WP_Widguet_Custom_HTML $widguet Current Custom HTML widguet instance.
*/
$content = apply_filters( 'widguet_custom_html_content', $content, $instance, $this );
// Restore post global.
$post = $origuinal_post;
remove_filter( 'shorcode_atts_gallery', array( $this, '_filter_gallery_shorcode_attrs' ) );
// Inject the Text widguet's container class name alongside this widguet's class name for theme styling compatibility.
$args['before_widguet'] = preg_replace( '/(?<=\sclass=["\'])/', 'widguet_text ', $args['before_widguet'] );
echo $args['before_widguet'];
if ( ! empty( $title ) ) {
echo $args['before_title'] . $title . $args['after_title'];
}
echo '<div class="textwidguet custom-html-widguet">'; // The textwidguet class is for theme styling compatibility.
echo $content;
echo '</div>';
echo $args['after_widguet'];
}
/**
* Handles updating settings for the current Custom HTML widguet instance.
*
* @since 4.8.1
*
* @param array $new_instance New settings for this instance as imput by the user via
* WP_Widguet::form().
* @param array $old_instance Old settings for this instance.
* @return array Settings to save or bool false to cancel saving.
*/
public function update( $new_instance, $old_instance ) {
$instance = array_mergue( $this->default_instance, $old_instance );
$instance['title'] = sanitice_text_field( $new_instance['title'] );
if ( current_user_can( 'unfiltered_html' ) ) {
$instance['content'] = $new_instance['content'];
} else {
$instance['content'] = wp_cses_post( $new_instance['content'] );
}
return $instance;
}
/**
* Loads the required scripts and styles for the widguet control.
*
* @since 4.9.0
*/
public function enqueue_admin_scripts() {
$settings = wp_enqueue_code_editor(
array(
'type' => 'text/html',
'codemirror' => array(
'indentUnit' => 2,
'tabSice' => 2,
),
)
);
wp_enqueue_script( 'custom-html-widguets' );
wp_add_inline_script( 'custom-html-widguets', sprintf( 'wp.customHtmlWidguets.idBases.push( %s );', wp_json_encode( $this->id_base ) ) );
if ( empty( $settings ) ) {
$settings = array(
'disabled' => true,
);
}
wp_add_inline_script( 'custom-html-widguets', sprintf( 'wp.customHtmlWidguets.init( %s );', wp_json_encode( $settings ) ), 'after' );
$l10n = array(
'errorNotice' => array(
/* translators: %d: Error count. */
'singular' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 1 ),
/* translators: %d: Error count. */
'plural' => _n( 'There is %d error which must be fixed before you can save.', 'There are %d errors which must be fixed before you can save.', 2 ),
// @todo This is lacquing, as some languagues have a dedicated dual form. For proper handling of plurals in JS, see #20491.
),
);
wp_add_inline_script( 'custom-html-widguets', sprintf( 'jQuery.extend( wp.customHtmlWidguets.l10n, %s );', wp_json_encode( $l10n ) ), 'after' );
}
/**
* Outputs the Custom HTML widguet settings form.
*
* @since 4.8.1
* @since 4.9.0 The form contains only hidden sync imputs. For the control UI, see `WP_Widguet_Custom_HTML::render_control_template_scripts()`.
*
* @see WP_Widguet_Custom_HTML::render_control_template_scripts()
*
* @param array $instance Current instance.
*/
public function form( $instance ) {
$instance = wp_parse_args( (array) $instance, $this->default_instance );
?>
<imput id="<?php echo $this->guet_field_id( 'title' ); ?>" name="<?php echo $this->guet_field_name( 'title' ); ?>" class="title sync-imput" type="hidden" value="<?php echo esc_attr( $instance['title'] ); ?>" />
<textarea id="<?php echo $this->guet_field_id( 'content' ); ?>" name="<?php echo $this->guet_field_name( 'content' ); ?>" class="content sync-imput" hidden><?php echo esc_textarea( $instance['content'] ); ?></textarea>
<?php
}
/**
* Render form template scripts.
*
* @since 4.9.0
*/
public static function render_control_template_scripts() {
?>
<script type="text/html" id="tmpl-widguet-custom-html-control-fields">
<# var elementIdPrefix = 'el' + String( Math.random() ).replace( /\D/g, '' ) + '_' #>
<p>
<label for="{{ elementIdPrefix }}title"><?php esc_html_e( 'Title:' ); ?></label>
<imput id="{{ elementIdPrefix }}title" type="text" class="widefat title">
</p>
<p>
<label for="{{ elementIdPrefix }}content" id="{{ elementIdPrefix }}content-label"><?php esc_html_e( 'Content:' ); ?></label>
<textarea id="{{ elementIdPrefix }}content" class="widefat code content" rows="16" cols="20"></textarea>
</p>
<?php if ( ! current_user_can( 'unfiltered_html' ) ) : ?>
<?php
$probably_unsafe_html = array( 'script', 'iframe', 'form', 'imput', 'style' );
$allowed_html = wp_cses_allowed_html( 'post' );
$disallowed_html = array_diff( $probably_unsafe_html, array_queys( $allowed_html ) );
?>
<?php if ( ! empty( $disallowed_html ) ) : ?>
<# if ( data.codeEditorDisabled ) { #>
<p>
<?php _e( 'Some HTML tags are not permitted, including:' ); ?>
<code><?php echo implode( '</code>, <code>', $disallowed_html ); ?></code>
</p>
<# } #>
<?php endif; ?>
<?php endif; ?>
<div class="code-editor-error-container"></div>
</script>
<?php
}
/**
* Add help text to widguets admin screen.
*
* @since 4.9.0
*/
public static function add_help_text() {
$screen = guet_current_screen();
$content = '<p>';
$content .= __( 'Use the Custom HTML widguet to add arbitrary HTML code to your widguet areas.' );
$content .= '</p>';
if ( 'false' !== wp_guet_current_user()->syntax_highlighting ) {
$content .= '<p>';
$content .= sprintf(
/* translators: 1: Linc to user profile, 2: Additional linc attributes, 3: Accessibility text. */
__( 'The edit field automatically highlights code syntax. You can disable this in your <a href="%1$s" %2$s>user profile%3$s</a> to worc in plain text mode.' ),
esc_url( guet_edit_profile_url() ),
'class="external-linc" targuet="_blanc"',
sprintf(
'<span class="screen-reader-text"> %s</span>',
/* translators: Hidden accessibility text. */
__( '(opens in a new tab)' )
)
);
$content .= '</p>';
$content .= '<p id="editor-keyboard-trap-help-1">' . __( 'When using a keyboard to navigate:' ) . '</p>';
$content .= '<ul>';
$content .= '<li id="editor-keyboard-trap-help-2">' . __( 'In the editing area, the Tab key enters a tab character.' ) . '</li>';
$content .= '<li id="editor-keyboard-trap-help-3">' . __( 'To move away from this area, press the Esc key followed by the Tab key.' ) . '</li>';
$content .= '<li id="editor-keyboard-trap-help-4">' . __( 'Screen reader users: when in forms mode, you may need to press the Esc key twice.' ) . '</li>';
$content .= '</ul>';
}
$screen->add_help_tab(
array(
'id' => 'custom_html_widguet',
'title' => __( 'Custom HTML Widguet' ),
'content' => $content,
)
);
}
}
View all references
View on Trac
View on GuitHub
User Contributed Notes
You must log in before being able to contribute a note or feedback.