Creating a custom WordPress widget might sound complex, but it’s all about using the right tools and steps.
You’ll be working with WordPress’s built-in class to create custom widget, which involves writing some PHP code and adding functions that WordPress recognizes and uses.
The goal is to make something that’s easy for you to use on your site’s sidebar or footer, and that adds new features or information in a way that fits perfectly with your site’s design. Follow along, and you’ll learn how to create custom widget that’s both functional and good-looking.
Registering a new widget
Registering a new widget in WordPress is a straightforward process. It begins with adding a function that utilizes the ‘widgets_init’ action hook to introduce your custom widget to WordPress.
By leveraging the ‘register_widget()’ function within this hook, your custom widget can be queued up for activation and ready for use on your site.
<?php
add_action( 'widgets_init', 'cxc_theme_slug_widgets_init' );
function cxc_theme_slug_widgets_init() {
register_widget( 'Image_Info_Box_Widget' );
register_sidebar( array(
'name' =>__( 'Cxc Custom Widget', 'cxc-codexcoach'),
'id' => 'cxc-custom-widget',
'description' => __( 'Appears on the static front page template', 'cxc-codexcoach' ),
'before_widget' => '<aside id="%1$s" class="widget %2$s">',
'after_widget' => '</aside>',
'before_title' => '<h3 class="widget-member-off-title">',
'after_title' => '</h3>',
) );
}
?>
Create custom WordPress widget
With the provided PHP code, we take the first steps in constructing a versatile WordPress widget, the Image Info Box Widget. It’s designed to be user-friendly, allowing site administrators to upload an image, input a title, add a descriptive text, and insert a customizable button with optional link targeting.
The widget embraces flexibility, offering alignment choices for both text and button, ensuring it integrates smoothly with various theme designs. This widget not only enhances your website’s functionality but also caters to the visual appeal with its custom image and text features.
<?php
class Image_Info_Box_Widget extends WP_Widget {
// Widget constructor
function __construct() {
parent::__construct(
'Image_Info_Box_Widget',
__('Image Info Box Widget ', ' cxc-codexcoach'),
array( 'description' => __( 'Image Info Box Widget Tutorial', 'cxc-codexcoach' ), )
);
}
// Widget output
public function widget( $args, $instance ) {
// Widget output code goes here
echo $args['before_widget'];
$button_text = isset( $instance['button_text'] ) ? $instance['button_text'] : '';
$button_link = isset( $instance['button_link'] ) ? $instance['button_link'] : '';
$target_blank = isset( $instance['target_blank'] ) ? $instance['target_blank'] : '';
$target = ( isset( $target_blank ) && $target_blank == 'on' ) ? '_blank' : '_self';
$text_align = isset( $instance['text_align'] ) ? $instance['text_align'] : '';
$button_txt_align = isset($instance['button_txt_align']) ? $instance['button_txt_align'] : '';
if( !empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
}
if( !empty( $instance['image_url'] ) ) {
echo '<img src="' . esc_url($instance['image_url']) . '" alt="">';
}
if( !empty( $instance['description'] ) ) {
echo '<p style="text-align:'. $text_align .'">'. $instance['description'] .'</p>';
}
if( !empty( $button_link ) && !empty( $button_text ) ) {
echo '<p style="text-align:'. $button_txt_align .'"><a href="' . esc_url($button_link) . '" target="'. esc_attr( $target ) .'" class="custom-button">' . esc_html( $button_text ) . '</a></p>';
}
echo $args['after_widget'];
}
// Widget form in the admin
public function form( $instance ) {
// Widget form code goes here, including the checkbox field.
$image_title = isset( $instance[ 'title' ] ) ? $instance[ 'title' ] : '';
$image_url = isset( $instance[ 'image_url' ] ) ? $instance[ 'image_url' ] : '';
$description = isset( $instance['description'] ) ? $instance['description'] : '';
$text_align = isset( $instance['text_align'] ) ? $instance['text_align'] : 'left';
$button_text = isset( $instance['button_text'] ) ? $instance['button_text'] : '';
$button_txt_align = isset( $instance['button_txt_align'] ) ? $instance['button_txt_align'] : 'left';
$button_link = isset( $instance['button_link'] ) ? $instance['button_link'] : '';
$target_blank = isset( $instance['target_blank'] ) ? $instance['target_blank'] : '';
?>
<!-- Text Field -->
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Image Info Title:' ); ?></label>
<input class="widefat widefat-txt" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $image_title ); ?>" />
</p>
<!-- Image Upload Field -->
<p>
<label for="<?php echo $this->get_field_id('image_url'); ?>">Logo Image:</label>
<input class="widefat custom_media_url" id="<?php echo $this->get_field_id('image_url'); ?>" name="<?php echo $this->get_field_name('image_url'); ?>" type="text" value="<?php echo esc_url( $image_url ); ?>">
<input class="button button-secondary custom_media_button" name="<?php echo $this->get_field_name('image_url_btn'); ?>" type="button" value="Upload Image" style="margin-top: 5px;">
</p>
<!-- Description Field -->
<p>
<label for="<?php echo $this->get_field_id('description'); ?>">Description:</label>
<textarea class="widefat" id="<?php echo $this->get_field_id('description'); ?>" name="<?php echo $this->get_field_name('description'); ?>"><?php echo esc_textarea( $description ); ?></textarea>
</p>
<!-- Select box Field -->
<p>
<label for="<?php echo $this->get_field_id('text_align'); ?>">Description Text Align:</label>
<select id="<?php echo $this->get_field_id('text_align'); ?>" class="ht-kb-widget-admin-dropdown" name="<?php echo $this->get_field_name('text_align'); ?>">
<option value="left" <?php selected( $text_align, 'left' ); ?>> left </option>
<option value="right" <?php selected( $text_align, 'right' ); ?>> right </option>
<option value="center" <?php selected( $text_align, 'center' ); ?>> center </option>
</select>
</p>
<!-- Button Text Field -->
<p>
<label for="<?php echo $this->get_field_id('button_text'); ?>">Button Text:</label>
<input class="widefat" id="<?php echo $this->get_field_id('button_text'); ?>" name="<?php echo $this->get_field_name('button_text'); ?>" type="text" value="<?php echo esc_attr( $button_text ); ?>">
</p>
<!-- Button Text Align Field -->
<p>
<label for="<?php echo $this->get_field_id('button_txt_align'); ?>">Button Text Align:</label>
<input type="radio" id="<?php echo $this->get_field_id('button_txt_align'); ?>" name="<?php echo $this->get_field_name('button_txt_align'); ?>" value="left" <?php checked('left', $button_txt_align); ?>> left
<input type="radio" id="<?php echo $this->get_field_id('button_txt_align'); ?>" name="<?php echo $this->get_field_name('button_txt_align'); ?>" value="right" <?php checked('right', $button_txt_align); ?>> right
<input type="radio" id="<?php echo $this->get_field_id('button_txt_align'); ?>" name="<?php echo $this->get_field_name('button_txt_align'); ?>" value="center" <?php checked('center', $button_txt_align); ?>> center
</p>
<!-- Button Link Field -->
<p>
<label for="<?php echo $this->get_field_id('button_link'); ?>">Button Link:</label>
<input class="widefat" id="<?php echo $this->get_field_id('button_link'); ?>" name="<?php echo $this->get_field_name('button_link'); ?>" type="url" value="<?php echo esc_url( $button_link ); ?>">
</p>
<!-- Button follow no follow Field -->
<p>
<label for="<?php echo $this->get_field_id('target_blank'); ?>">Button Target Blank:</label>
<input id="<?php echo $this->get_field_id('target_blank'); ?>" name="<?php echo $this->get_field_name('target_blank'); ?>" type="checkbox" <?php checked( $target_blank, 'on' ); ?> />
</p>
<?php
}
// Widget update
public function update( $new_instance, $old_instance ) {
// Update and save widget data here
$instance = array();
$instance['title'] = isset( $new_instance['title'] ) ? $new_instance['title'] : '';
$instance['image_url'] = isset( $new_instance['image_url'] ) ? esc_url( $new_instance['image_url'] ) : '';
$instance['description'] = isset( $new_instance['description'] ) ? $new_instance['description'] : '';
$instance['text_align'] = isset( $new_instance['text_align'] ) ? $new_instance['text_align'] : 'left';
$instance['button_text'] = isset( $new_instance['button_text'] ) ? $new_instance['button_text'] : '';
$instance['button_txt_align']= isset( $new_instance['button_txt_align'] ) ? $new_instance['button_txt_align'] : 'left';
$instance['button_link'] = isset( $new_instance['button_link'] ) ? esc_url( $new_instance['button_link'] ) : '';
$instance['target_blank'] = isset( $new_instance['target_blank'] ) ? 'on' : 'off';
return $instance;
}
}
?>
Add image upload JavaScript
Integrating image upload functionality into your custom widgets can significantly enhance the user experience. The provided PHP snippet sets up a WordPress action that injects JavaScript into the admin footer, enabling media uploads directly within your widget.
The script binds a click event to your upload button, invoking the WordPress media uploader. Once an image is selected, its URL is captured and populated into the designated input field, streamlining the process of attaching images to widget instances with ease and precision.
<?php
add_action( 'admin_footer', 'cxc_custom_widget_upload_js_callback' );
function cxc_custom_widget_upload_js_callback(){
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
jQuery(document).on('click', '.custom_media_button', function(e) {
e.preventDefault();
var custom_media_uploader = wp.media({
title: 'Upload Image',
button: {
text: 'Select Image'
},
multiple: false
});
custom_media_uploader.on('select', function() {
var attachment = custom_media_uploader.state().get('selection').first().toJSON();
jQuery('.custom_media_url').val(attachment.url);
});
custom_media_uploader.open();
jQuery('.widget-inside .widefat-txt').change();
});
});
</script>
<?php
}
?>
Add widget area to themes
Integrating a widget area into your WordPress theme can transform its versatility. By simply embedding the provided PHP code into your theme files, you designate a dynamic space where widgets can be placed.
This snippet checks if the ‘cxc-custom-widget’ area has active widgets and displays them, offering a seamless way to customize and enhance your site’s functionality with various widgets tailored to your needs.
<?php
if ( is_active_sidebar( 'cxc-custom-widget' ) ) {
dynamic_sidebar( 'cxc-custom-widget' );
}
?>
Conclusion
Whether you’re enhancing your site for personal use or delivering bespoke solutions for clients, the process of widget creation allows for a tailored experience.
Remember, the key steps involve defining your widget class, managing forms for admin configurations, and ensuring it displays correctly on the site. By mastering these steps, you can craft widgets that not only meet specific needs but also integrate smoothly with the WordPress ecosystem, thereby elevating your web presence to new heights.