How to Create a Custom Widget from Scratch in WordPress

In this WordPress tutorial, we’ll guide you through the process of creating a custom widget from scratch without using any plugins. Whether you’re a beginner or a seasoned developer, you’ll learn how to build a custom widget step-by-step, adhering to WordPress coding standards and best practices. We’ll start with the basic structure of a custom widget and then move on to an advanced example that demonstrates its capabilities. By the end of this tutorial, you’ll have a solid understanding of how to create your own custom widgets and extend the functionality of your WordPress website.

Before proceeding with any customizations in WordPress, it’s essential to set up a child theme. A child theme acts as a safe and efficient way to make modifications without affecting the parent theme. If you haven’t set up a child theme yet, follow this tutorial on How to Create a Child Theme for Customization. It will guide you through the process and ensure that your customizations remain intact even after theme updates.

Create the Custom Widget File – Basic Structure

In this step, we’ll create a new PHP file for our custom widget. We’ll name it “custom_widget.php“, but you can choose any appropriate name.

  1. Inside your child theme folder, create a new folder named “widgets“.
  2. Within the “widgets” folder, create a new file named “custom_widget.php“.
  3. Add the following boilerplate code to the “custom_widget.php” file:
<?php
/**
 * Custom Widget: My_Custom_Widget
 *
 * Description: Add a custom widget to your sidebar.
 */

class My_Custom_Widget extends WP_Widget {

	// Widget setup
	public function __construct() {
		parent::__construct(
			'yourthemename_my_custom_widget', // Base ID (Change 'yourthemename' to your theme's unique identifier)
			__( 'My Custom Widget', 'yourthemename' ), // Name
			array( 'description' => __( 'Add a custom widget to your sidebar.', 'yourthemename' ) ) // Widget description
		);
	}

	// Frontend display
	public function widget( $args, $instance ) {
		// Widget output goes here
	}

	// Backend settings form
	public function form( $instance ) {
		// Widget settings form goes here
	}

	// Save widget settings
	public function update( $new_instance, $old_instance ) {
		// Save widget settings here
	}
}

// Register the widget
function register_my_custom_widget() {
	register_widget( 'My_Custom_Widget' );
}
add_action( 'widgets_init', 'register_my_custom_widget' );
Code language: PHP (php)

Code Explanation:

  • We create a new class My_Custom_Widget that extends WP_Widget to define our custom widget.
  • In the constructor, we set the base ID, name, and description of the widget. Make sure to change 'yourthemename' to your theme’s unique identifier to avoid conflicts.
  • We use __() function for localization to make the widget name and description translatable. The text domain (‘yourthemename’) should match your theme’s text domain.
  • The widget() method defines the frontend display of the widget. It’s currently empty as this is the basic structure. We’ll add the content in the advanced example.
  • The form() method defines the backend settings form of the widget. It’s also empty in the basic structure, and we’ll populate it in the advanced example.
  • The update() method handles the saving of widget settings. It’s left empty in the basic structure as well.

Advanced Example – Adding Functionality to the Custom Widget

Now, let’s enhance the custom widget with additional functionality, such as displaying user input on the frontend and providing options in the backend.

  1. Inside the “custom_widget.php” file, replace the existing “widget()“, “form()“, and “update()” methods with the following code:
<?php
/**
 * Custom Widget: My_Custom_Widget
 *
 * Description: Add a custom widget to your sidebar.
 */

class My_Custom_Widget extends WP_Widget {

	// Widget setup
	public function __construct() {
		parent::__construct(
			'yourthemename_my_custom_widget', // Base ID (Change 'yourthemename' to your theme's unique identifier)
			__( 'My Custom Widget', 'yourthemename' ), // Name
			array( 'description' => __( 'Add a custom widget to your sidebar.', 'yourthemename' ) ) // Widget description
		);
	}

	// Frontend display
	public function widget( $args, $instance ) {
		$title   = apply_filters( 'widget_title', $instance['title'] );
		$content = '';

		// Check if content exists and set it to $content
		if ( isset( $instance['content'] ) ) {
			$content = $instance['content'];
		}

		echo $args['before_widget'];

		// Display the widget title if it's not empty
		if ( ! empty( $title ) ) {
			echo $args['before_title'] . $title . $args['after_title'];
		}

		// Display the widget content if it's not empty, otherwise show a default message
		if ( ! empty( $content ) ) {
			echo '<div class="custom-widget-content">' . $content . '</div>';
		} else {
			echo '<div class="custom-widget-content">';
			echo esc_html__( 'No content to display.', 'yourthemename' );
			echo '</div>';
		}

		echo $args['after_widget'];
	}

	// Backend settings form
	public function form( $instance ) {
		$title   = '';
		$content = '';

		// Check if title and content exist and set them to $title and $content respectively
		if ( isset( $instance['title'] ) ) {
			$title = esc_attr( $instance['title'] );
		}

		if ( isset( $instance['content'] ) ) {
			$content = esc_textarea( $instance['content'] );
		}
		?>
		<p>
			<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'yourthemename' ); ?></label>
			<input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $title; ?>">
		</p>
		<p>
			<label for="<?php echo $this->get_field_id( 'content' ); ?>"><?php _e( 'Content:', 'yourthemename' ); ?></label>
			<textarea class="widefat" rows="5" id="<?php echo $this->get_field_id( 'content' ); ?>" name="<?php echo $this->get_field_name( 'content' ); ?>"><?php echo $content; ?></textarea>
		</p>
		<?php
	}

	// Save widget settings
	public function update( $new_instance, $old_instance ) {
		$instance = array();

		// Save and sanitize the title and content if they exist, otherwise set them to empty strings
		if ( isset( $new_instance['title'] ) ) {
			$instance['title'] = sanitize_text_field( $new_instance['title'] );
		} else {
			$instance['title'] = '';
		}

		if ( isset( $new_instance['content'] ) ) {
			$instance['content'] = sanitize_textarea_field( $new_instance['content'] );
		} else {
			$instance['content'] = '';
		}

		return $instance;
	}
}

// Register the widget
function register_my_custom_widget() {
	register_widget( 'My_Custom_Widget' );
}
add_action( 'widgets_init', 'register_my_custom_widget' );

Code language: PHP (php)

Code Explanation:

  • In the advanced example, we’ve updated the widget() method to display the custom title and content provided by the user in the backend.
  • We’ve used __() and _e() functions for localization in the backend form.
  • We’ve also added proper sanitization using sanitize_text_field() and sanitize_textarea_field() for user input to ensure data integrity and security.
  • We’ve also enhanced the form() method to include a textarea field for users to input content for the widget.
  • The update() method now saves and sanitizes the user input for both title and content.

Add CSS Styling (Optional)

Optionally, you can add CSS styling to your widget to make it visually appealing. In your child theme’s “style.css“, add the necessary CSS for your widget. For example:

/* Custom Widget Styles */
.custom-widget-content {
    background-color: #f2f2f2;
    padding: 10px;
    border: 1px solid #ccc;
}
Code language: CSS (css)

Add an Icon to the Custom Widget

To add an icon to your custom widget in the WordPress admin dashboard, modify the widget setup in the “custom_widget.php” file as follows:

public function __construct() {
	parent::__construct(
		'yourthemename_my_custom_widget', // Base ID (Change 'yourthemename' to your theme's unique identifier)
		__( 'My Custom Widget', 'yourthemename' ), // Name
		array(
			'description'                 => __( 'Add a custom widget to your sidebar.', 'yourthemename' ),
			'classname'                   => 'yourthemename-custom-widget', // Add your custom CSS class for the widget here
			'customize_selective_refresh' => true, // Enable selective refresh for faster widget updates
			'icon'                        => 'dashicons-admin-tools', // Add your desired Dashicon here (https://developer.wordpress.org/resource/dashicons/)
		)
	);
}

Code language: PHP (php)

Code Explanation:

  • We’ve added the ‘classname‘ parameter to specify a custom CSS class for the widget. You can add your custom CSS styles to this class in your theme’s “style.css” file.
  • The ‘customize_selective_refresh‘ parameter enables selective refresh, which allows faster widget updates when customizing your website.
  • The ‘icon‘ parameter sets the icon for your custom widget in the WordPress admin dashboard. You can choose from available Dashicons (https://developer.wordpress.org/resource/dashicons/).

Place the Widget in the Sidebar

To add your custom widget to the sidebar, follow these steps:

  1. Go to your WordPress admin dashboard.
  2. Navigate to “Appearance” > “Widgets”.
  3. Find your custom widget (named “My Custom Widget”) in the “Available Widgets” section.
  4. Drag and drop the widget to the desired sidebar in the “Widget Area” section.
  5. Configure the widget settings and click “Save”.

That’s it! You’ve successfully created a custom widget from scratch in WordPress. The advanced example now allows users to add custom content and a title, which will be displayed on the frontend. You can further customize and extend this widget based on your website’s needs and provide a richer experience to your users.

Leave your feedback and help us improve šŸ¶

We hope you found this article helpful! If you have any questions, feedback, or spot any errors, please let us know in the comments. Your input is valuable and helps us improve. If you liked this article, please consider sharing it with others. And if you really enjoyed it, you can show your support by buying us a cup of coffee ā˜•ļø or donating via PayPal šŸ’°.

More free knowledge, because why not?

Your thoughts matter, leave a reply šŸ’¬

Your email address will not be published. Required fields are marked *