# Contact Details Widget

> Adds a "Contact Details" widget for your address, phone number, email and opening hours, with tap-to-call and spam-protected email links.

- Type: PHP
- Runs: Run everywhere
- Category: [Widgets](https://wpide.com/library/category/widgets/)
- Tags: widgets, contact, business
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/contact-details-widget/

## Code

```php
if ( ! class_exists( 'WPIDE_Contact_Details_Widget' ) ) {
    class WPIDE_Contact_Details_Widget extends WP_Widget {
        private $fields = array(
            'address' => 'Address',
            'phone'   => 'Phone',
            'email'   => 'Email',
            'hours'   => 'Opening hours',
        );

        public function __construct() {
            parent::__construct( 'wpide_contact_details', 'Contact Details', array(
                'description'                 => 'Your address, phone, email and opening hours.',
                'customize_selective_refresh' => true,
            ) );
        }

        public function widget( $args, $instance ) {
            $instance = wp_parse_args( (array) $instance, array_fill_keys( array_merge( array( 'title' ), array_keys( $this->fields ) ), '' ) );
            $title    = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );

            echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput -- markup from the theme.

            if ( '' !== (string) $title ) {
                echo $args['before_title'] . esc_html( $title ) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput
            }

            echo '<address class="wpide-contact-details" style="font-style:normal;">';

            if ( '' !== $instance['address'] ) {
                echo '<p>' . nl2br( esc_html( $instance['address'] ) ) . '</p>';
            }

            if ( '' !== $instance['phone'] ) {
                echo '<p><a href="tel:' . esc_attr( preg_replace( '/[^0-9+]/', '', $instance['phone'] ) ) . '">' . esc_html( $instance['phone'] ) . '</a></p>';
            }

            if ( is_email( $instance['email'] ) ) {
                echo '<p><a href="mailto:' . antispambot( $instance['email'], 1 ) . '">' . antispambot( $instance['email'] ) . '</a></p>';
            }

            if ( '' !== $instance['hours'] ) {
                echo '<p>' . nl2br( esc_html( $instance['hours'] ) ) . '</p>';
            }

            echo '</address>';
            echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput
        }

        public function form( $instance ) {
            $instance = wp_parse_args( (array) $instance, array_fill_keys( array_merge( array( 'title' ), array_keys( $this->fields ) ), '' ) );

            echo '<p><label for="' . esc_attr( $this->get_field_id( 'title' ) ) . '">Title:</label><input class="widefat" type="text" id="' . esc_attr( $this->get_field_id( 'title' ) ) . '" name="' . esc_attr( $this->get_field_name( 'title' ) ) . '" value="' . esc_attr( $instance['title'] ) . '" /></p>';

            foreach ( $this->fields as $key => $label ) {
                $id   = $this->get_field_id( $key );
                $name = $this->get_field_name( $key );

                if ( in_array( $key, array( 'address', 'hours' ), true ) ) {
                    echo '<p><label for="' . esc_attr( $id ) . '">' . esc_html( $label ) . ':</label><textarea class="widefat" rows="3" id="' . esc_attr( $id ) . '" name="' . esc_attr( $name ) . '">' . esc_textarea( $instance[ $key ] ) . '</textarea></p>';
                } else {
                    echo '<p><label for="' . esc_attr( $id ) . '">' . esc_html( $label ) . ':</label><input class="widefat" type="text" id="' . esc_attr( $id ) . '" name="' . esc_attr( $name ) . '" value="' . esc_attr( $instance[ $key ] ) . '" /></p>';
                }
            }

            return '';
        }

        public function update( $new_instance, $old_instance ) {
            return array(
                'title'   => sanitize_text_field( isset( $new_instance['title'] ) ? $new_instance['title'] : '' ),
                'address' => sanitize_textarea_field( isset( $new_instance['address'] ) ? $new_instance['address'] : '' ),
                'phone'   => sanitize_text_field( isset( $new_instance['phone'] ) ? $new_instance['phone'] : '' ),
                'email'   => sanitize_email( isset( $new_instance['email'] ) ? $new_instance['email'] : '' ),
                'hours'   => sanitize_textarea_field( isset( $new_instance['hours'] ) ? $new_instance['hours'] : '' ),
            );
        }
    }
}

add_action( 'widgets_init', function () {
    register_widget( 'WPIDE_Contact_Details_Widget' );
} );
```

## Notes

Add it under Appearance > Widgets (as a Legacy Widget in the block widget editor).

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Contact Details Widget" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
