Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

Clean Markup Widget for WordPress

[ WP Clean Markup Widget ]
Squeaky clean.
When adding content to your sidebar, it’s nice to be able to output clean, well-formatted markup. There are several ways to do this, including adding HTML directly in the theme template, installing a plugin, or simply using a widget. Widgets provide a great way of customizing sidebars and other widgetized areas, but as you may have seen in the source-code, the HTML is treated with all sorts of additional attributes, elements, and classes. Sometimes, you just need a widget that outputs exactly what you tell it to, without adding or changing anything.

A widget for clean, well-formatted markup

So I created a “clean-markup” widget that I use around some of my sites. It’s great for adding straight-up HTML (lists, paragraphs, et al), but also for adding template code for advertisements and other 3rd-party snippets, where unmodified HTML is key to proper display and/or functionality. Really it’s nothing fancy, just a simple WordPress widget that outputs exactly what you tell it to. No fuss, no muss. Here is a screenshot of the widget in action here at Perishable Press:

[ WP Clean Markup Widget ]

How to install & use

Just add the following code to your theme’s functions.php file (or add via plugin), no editing required:

<?php // Clean Markup Widget
// @ https://perishablepress.com/clean-markup-widget/

class Clean_Markup_Widget extends WP_Widget {
	public function __construct() {
		$id = 'clean_markup_widget';
		$title = esc_html__('Clean Markup Widget', 'custom-widget');
		$options = array(
			'classname' => 'clean-markup-widget',
			'description' => esc_html__('Adds clean markup that is not modified by WordPress.', 'custom-widget')
		parent::__construct( $id, $title, $options );
	public function widget( $args, $instance ) {
		// extract( $args );
		$markup = '';
		if ( isset( $instance['markup'] ) ) {
			echo wp_kses_post( $instance['markup'] );
	public function update( $new_instance, $old_instance ) {
		$instance = array();
		if ( isset( $new_instance['markup'] ) && ! empty( $new_instance['markup'] ) ) {
			$instance['markup'] = $new_instance['markup'];
		return $instance;
	public function form( $instance ) {
		$id = $this->get_field_id( 'markup' );
		$for = $this->get_field_id( 'markup' );
		$name = $this->get_field_name( 'markup' );
		$label = __( 'Markup/text:', 'custom-widget' );
		$markup = '<p>'. __( 'Clean, well-formatted markup.', 'custom-widget' ) .'</p>'; 
		if ( isset( $instance['markup'] ) && ! empty( $instance['markup'] ) ) {
			$markup = $instance['markup'];
			<label for="<?php echo esc_attr( $for ); ?>"><?php echo esc_html( $label ); ?></label>
			<textarea class="widefat" id="<?php echo esc_attr( $id ); ?>" name="<?php echo esc_attr( $name ); ?>"><?php echo esc_textarea( $markup ); ?></textarea>
<?php }


// register widget
function myplugin_register_widgets() {
	register_widget( 'Clean_Markup_Widget' );
add_action( 'widgets_init', 'myplugin_register_widgets' );


Once the widget code is in place and uploaded to the server, visit the Appearance > Widgets and you’ll see the clean-markup widget ready for use, just like any other awesome WP widget :)


I hope this helps anyone else out there looking for a good way to add clean markup via WordPress widget. As always, your suggestions and ideas are welcome!

About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
Digging Into WordPress: Take your WordPress skills to the next level.

9 responses to “Clean Markup Widget for WordPress”

  1. Knut Sparhell 2012/06/20 8:25 pm

    If I add this code to my functions.php file, and later I update my theme, this is gone. Add it again. No way, no “enjoy”!

    I can make a child theme for myself, or I can create a simple plugin with this code.

    Why do you recommend adding raw code to functions.php when better solutions are available?

    • Jeff Starr 2012/06/20 8:37 pm

      Hi Knut, thanks for the feedback. It’s just a piece of code, really. It works 100% awesome in functions.php for me, but if it makes more sense for you to use as a plugin or child-theme, then go for it — that’s why I took the time to share it with you :)

  2. I wonder if there is a remove_filter()-way to do it globally for all existing widgets similiar to the wpautop-hack on the_content()?

    @Knut: In a way, adding raw code to functions.php in your theme is what functions.php was made for.

    • Jeff Starr 2012/06/21 1:03 am

      Yes good point — I believe there is a way to disable it globally, but quite a few widgets rely on auto-formatting for output, so in general.. risky.

  3. Really great widget – I’ve been struggling with some issues revolving around having all kinds of junk passed to the “text” widget and didn’t know where to start to do this.

    Thanks for this!

  4. I like it!

  5. Jadwal Training 2012/08/06 3:20 pm

    Hi Jeff, Thanks for usefull post… :)

  6. can you please create this plugin so that we can download it!?

    • Jeff Starr 2012/12/05 2:53 pm

      Hi arron, it’s actually meant to be added to a theme’s functions.php file.. if such file doesn’t exist, you can create a blank PHP file named “functions.php” and add the code directly.

Comments are closed for this post. Something to add? Let me know.
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
The Tao of WordPress: Master the art of WordPress.
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.