Basics of creating a wordpress widget

class-wp-nav-menu-widget.php (5.3 KB)
I have uploaded the default menu widget that is provided by the wordpress core located at this address →
/wp-includes/widgets/class-wp-nav-menu-widget.php.

What I was willing to do was to create a custom menu widget for the footer. Please check this live website. Currently, the menu here is hard-coded HTML, but I wish to give it a form of a Wordpress widget.

I was quite confused as I am a novice that from where to start, and I lost around 3-4 days in all this. I decided to read and study the default custom menu widget given by the WordPress.

This is the backend form given for that widget →

	public function form( $instance ) {
		global $wp_customize;
		$title = isset( $instance['title'] ) ? $instance['title'] : '';
		$nav_menu = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';

		// Get menus
		$menus = wp_get_nav_menus();

		// If no menus exists, direct the user to go and create some.
		?>
		<p class="nav-menu-widget-no-menus-message" <?php if ( ! empty( $menus ) ) { echo ' style="display:none" '; } ?>>
			<?php
			if ( $wp_customize instanceof WP_Customize_Manager ) {
				$url = 'javascript: wp.customize.panel( "nav_menus" ).focus();';
			} else {
				$url = admin_url( 'nav-menus.php' );
			}
			?>
			<?php echo sprintf( __( 'No menus have been created yet. <a href="%s">Create some</a>.' ), esc_attr( $url ) ); ?>
		</p>
		<div class="nav-menu-widget-form-controls" <?php if ( empty( $menus ) ) { echo ' style="display:none" '; } ?>>
			<p>
				<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ) ?></label>
				<input type="text" class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $title ); ?>"/>
			</p>
			<p>
				<label for="<?php echo $this->get_field_id( 'nav_menu' ); ?>"><?php _e( 'Select Menu:' ); ?></label>
				<select id="<?php echo $this->get_field_id( 'nav_menu' ); ?>" name="<?php echo $this->get_field_name( 'nav_menu' ); ?>">
					<option value="0"><?php _e( '&mdash; Select &mdash;' ); ?></option>
					<?php foreach ( $menus as $menu ) : ?>
						<option value="<?php echo esc_attr( $menu->term_id ); ?>" <?php selected( $nav_menu, $menu->term_id ); ?>>
							<?php echo esc_html( $menu->name ); ?>
						</option>
					<?php endforeach; ?>
				</select>
			</p>
			<?php if ( $wp_customize instanceof WP_Customize_Manager ) : ?>
				<p class="edit-selected-nav-menu" style="<?php if ( ! $nav_menu ) { echo 'display: none;'; } ?>">
					<button type="button" class="button"><?php _e( 'Edit Menu' ) ?></button>
				</p>
			<?php endif; ?>
		</div>
		<?php
	}

Primarily I wanted that my footer menu HTML/CSS should be used in this, but I do not know the clue for that.
My footer menu HTML looks like this → https://www.screencast.com/t/Y4wDrBCDk that means we have to use one extra class footer-menu How to do this?

Are we suppose to replace nav_menu by our own class footer-menu here →

		$nav_menu = isset( $instance['nav_menu'] ) ? $instance['nav_menu'] : '';

Can someone please help me over this.

It is good that you have experimented with an existing working widget. If it is a good best practice widget, then no harm. But you run the risk that you may be learning code you will want to rewrite later.

IMHO your next stop should be the Codex
https://codex.wordpress.org/Widgets_API

My typical dev workflow for stuff that is new to me is a lot of tweak-break-fix cycles, which may not be your workflow but …
What I would do is give that page a quick study, and take a look at the Resources and Related pages.
Then I would try the example “My_widget” and “Foo_widget” code.
Next I would try to keep the stuff I wanted the code to do and change it to do the things it didn’t do that I wanted - small steps at a time.

Actually, in last 2-3 months, things were going at a good pace. I learned a bit of HTML and WordPress, but I got stuck at this widget making. It is quite intimidating as If I know nothing and I do not know how many days and months will pass before I will become comfortable with this all.

I have studied that widget API + watched several videos, but I think that PHP stuff is like a bouncer to me and intimidating.

Did you manage to get the My_widget and Foo_widget examples to work?

My_Widget → Yes
Foo_Widget → Has some confusions.

For Example →

<p>
		<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label> 
		<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">

</p>

I am unable to understand these things →

$this->get_field_id( 'title' )

The example class method is

/**
 * Back-end widget form.
 *
 * @see WP_Widget::form()
 *
 * @param array $instance Previously saved values from database.
 */
public function form( $instance ) {
	$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'text_domain' );
	?>
	<p>
	<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label> 
	<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
	</p>
	<?php 
}

The $title variable will be assigned either the title value or “New title” if the title value is empty.
Note that “text_domain” is so gettext will be able to translate the String.

The method uses database values to create HTML eg.

<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label>

would become like

<label for="abc">Title:</label>

and

<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">

like

<input class="widefat" id="abc" name="awesome" type="text" value="Awesome"> 

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.