I’ll build this as a reusable advanced Gutenberg-style PHP template part: configurable alert types, icons, dismissible mode, ARIA accessibility, schema/meta hooks, safe escaping, block supports, and theme filter hooks.
Yes friend — create this file:
/template-parts/blocks/block-alert.php
Use it like:
get_template_part(
'template-parts/blocks/block-alert',
null,
array(
'type' => 'success',
'title' => 'Success!',
'message' => 'Your RX Theme alert block is working perfectly.',
'dismissible' => true,
)
);
Here is an advanced version:
<?php
/**
* Template Part: RX Theme Advanced Alert Block
*
* File: /template-parts/blocks/block-alert.php
*
* Usage:
*
* get_template_part(
* 'template-parts/blocks/block-alert',
* null,
* array(
* 'type' => 'info',
* 'title' => 'Important Notice',
* 'message' => 'This is an advanced RX Theme alert message.',
* 'dismissible' => true,
* )
* );
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
/**
* ------------------------------------------------------------
* Default Alert Configuration
* ------------------------------------------------------------
*/
$rx_alert_defaults = array(
/**
* Alert style type.
*
* Available:
* info, success, warning, error, danger, primary, secondary,
* medical, emergency, tip, note, update, custom
*/
'type' => 'info',
/**
* Content.
*/
'title' => '',
'subtitle' => '',
'message' => '',
'description' => '',
'content' => '',
/**
* Optional list items.
*/
'items' => array(),
/**
* Icon settings.
*/
'show_icon' => true,
'icon' => '',
'icon_label' => '',
'icon_markup' => '',
/**
* Layout settings.
*/
'layout' => 'default', // default, compact, wide, inline, card.
'align' => '', // left, center, right, wide, full.
'text_align' => 'left',
'width' => '',
'max_width' => '',
'min_height' => '',
'border_style' => '', // solid, dashed, dotted, none.
'shadow' => false,
'rounded' => true,
/**
* Behavior.
*/
'dismissible' => false,
'dismiss_label' => __( 'Dismiss alert', 'rx-theme' ),
'dismiss_storage' => false,
'dismiss_storage_id'=> '',
'auto_dismiss' => false,
'auto_dismiss_delay'=> 8000,
'is_collapsible' => false,
'is_open' => true,
/**
* Accessibility.
*/
'role' => '',
'aria_live' => '',
'aria_label' => '',
'tabindex' => '',
/**
* CTA buttons / links.
*/
'actions' => array(),
/**
* Extra HTML attributes.
*/
'id' => '',
'class' => '',
'classes' => array(),
'attributes' => array(),
'data' => array(),
/**
* Custom style values.
*/
'background' => '',
'color' => '',
'border_color' => '',
'accent_color' => '',
/**
* Optional meta.
*/
'meta' => '',
'time' => '',
'time_label' => '',
/**
* Advanced controls.
*/
'allow_html' => true,
'allowed_tags' => array(),
'print_schema' => false,
'animation' => '',
'priority' => '',
'is_preview' => false,
'block_name' => 'rx-alert',
'wrapper_tag' => 'div',
'inner_tag' => 'div',
);
/**
* ------------------------------------------------------------
* Merge User Args
* ------------------------------------------------------------
*/
$rx_alert_args = isset( $args ) && is_array( $args ) ? $args : array();
$rx_alert = wp_parse_args( $rx_alert_args, $rx_alert_defaults );
/**
* Allow child themes/plugins to modify alert args.
*/
$rx_alert = apply_filters( 'rx_theme_block_alert_args', $rx_alert, $rx_alert_args );
/**
* ------------------------------------------------------------
* Sanitization
* ------------------------------------------------------------
*/
$rx_alert_type = sanitize_key( $rx_alert['type'] );
$rx_allowed_types = array(
'info',
'success',
'warning',
'error',
'danger',
'primary',
'secondary',
'medical',
'emergency',
'tip',
'note',
'update',
'custom',
);
if ( ! in_array( $rx_alert_type, $rx_allowed_types, true ) ) {
$rx_alert_type = 'info';
}
$rx_block_name = sanitize_html_class( $rx_alert['block_name'] );
$rx_wrapper_tag = tag_escape( $rx_alert['wrapper_tag'] );
$rx_inner_tag = tag_escape( $rx_alert['inner_tag'] );
$rx_allowed_wrapper_tags = array( 'div', 'section', 'aside', 'article' );
$rx_allowed_inner_tags = array( 'div', 'section' );
if ( ! in_array( $rx_wrapper_tag, $rx_allowed_wrapper_tags, true ) ) {
$rx_wrapper_tag = 'div';
}
if ( ! in_array( $rx_inner_tag, $rx_allowed_inner_tags, true ) ) {
$rx_inner_tag = 'div';
}
$rx_alert_id = ! empty( $rx_alert['id'] )
? sanitize_html_class( $rx_alert['id'] )
: 'rx-alert-' . wp_unique_id();
$rx_title = is_string( $rx_alert['title'] ) ? $rx_alert['title'] : '';
$rx_subtitle = is_string( $rx_alert['subtitle'] ) ? $rx_alert['subtitle'] : '';
$rx_message = is_string( $rx_alert['message'] ) ? $rx_alert['message'] : '';
$rx_description = is_string( $rx_alert['description'] ) ? $rx_alert['description'] : '';
$rx_content = is_string( $rx_alert['content'] ) ? $rx_alert['content'] : '';
/**
* ------------------------------------------------------------
* Allowed HTML
* ------------------------------------------------------------
*/
$rx_default_allowed_tags = array(
'a' => array(
'href' => true,
'title' => true,
'target' => true,
'rel' => true,
'class' => true,
),
'br' => array(),
'em' => array(),
'strong' => array(),
'b' => array(),
'i' => array(),
'u' => array(),
'span' => array(
'class' => true,
),
'code' => array(),
'mark' => array(),
'small' => array(),
);
$rx_allowed_tags = ! empty( $rx_alert['allowed_tags'] ) && is_array( $rx_alert['allowed_tags'] )
? $rx_alert['allowed_tags']
: $rx_default_allowed_tags;
$rx_allowed_tags = apply_filters( 'rx_theme_block_alert_allowed_html', $rx_allowed_tags, $rx_alert );
$rx_kses = static function ( $content ) use ( $rx_alert, $rx_allowed_tags ) {
if ( empty( $content ) || ! is_string( $content ) ) {
return '';
}
if ( ! empty( $rx_alert['allow_html'] ) ) {
return wp_kses( $content, $rx_allowed_tags );
}
return esc_html( wp_strip_all_tags( $content ) );
};
/**
* ------------------------------------------------------------
* Icon System
* ------------------------------------------------------------
*/
$rx_default_icons = array(
'info' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M11 17h2v-6h-2v6zm0-8h2V7h-2v2zm1 13A10 10 0 1 1 12 2a10 10 0 0 1 0 20z"/></svg>',
'success' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M9.5 16.6 5.7 12.8l-1.4 1.4 5.2 5.2L20.3 8.6l-1.4-1.4-9.4 9.4z"/></svg>',
'warning' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>',
'error' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 2a10 10 0 1 0 .01 0H12zm5 13.6L15.6 17 12 13.4 8.4 17 7 15.6l3.6-3.6L7 8.4 8.4 7l3.6 3.6L15.6 7 17 8.4 13.4 12 17 15.6z"/></svg>',
'danger' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 2 1 21h22L12 2zm1 16h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>',
'medical' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2zm-1 11h-4v4h-4v-4H6v-4h4V6h4v4h4v4z"/></svg>',
'emergency' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M13 3h-2v10h2V3zm4.83 2.17-1.42 1.42A7 7 0 1 1 7.59 6.6L6.17 5.17A9 9 0 1 0 17.83 5.17z"/></svg>',
'tip' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M9 21h6v-1H9v1zm3-19a7 7 0 0 0-4 12.74V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.26A7 7 0 0 0 12 2z"/></svg>',
'note' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm-1 7V3.5L18.5 9H13z"/></svg>',
'update' => '<svg class="rx-alert__icon-svg" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 6V3L8 7l4 4V8a4 4 0 1 1-4 4H6a6 6 0 1 0 6-6z"/></svg>',
);
$rx_default_icons['primary'] = $rx_default_icons['info'];
$rx_default_icons['secondary'] = $rx_default_icons['note'];
$rx_default_icons['custom'] = $rx_default_icons['info'];
$rx_default_icons = apply_filters( 'rx_theme_block_alert_icons', $rx_default_icons, $rx_alert );
$rx_icon_markup = '';
if ( ! empty( $rx_alert['show_icon'] ) ) {
if ( ! empty( $rx_alert['icon_markup'] ) ) {
$rx_icon_markup = wp_kses(
$rx_alert['icon_markup'],
array(
'svg' => array(
'class' => true,
'width' => true,
'height' => true,
'viewBox' => true,
'aria-hidden' => true,
'focusable' => true,
'fill' => true,
'role' => true,
),
'path' => array(
'd' => true,
'fill' => true,
),
'span' => array(
'class' => true,
'aria-hidden' => true,
),
'i' => array(
'class' => true,
'aria-hidden' => true,
),
)
);
} elseif ( ! empty( $rx_alert['icon'] ) ) {
$rx_icon_markup = '<span class="rx-alert__icon-text" aria-hidden="true">' . esc_html( $rx_alert['icon'] ) . '</span>';
} elseif ( isset( $rx_default_icons[ $rx_alert_type ] ) ) {
$rx_icon_markup = $rx_default_icons[ $rx_alert_type ];
}
}
/**
* ------------------------------------------------------------
* Accessibility Logic
* ------------------------------------------------------------
*/
$rx_role = ! empty( $rx_alert['role'] ) ? sanitize_key( $rx_alert['role'] ) : '';
if ( empty( $rx_role ) ) {
$rx_role = in_array( $rx_alert_type, array( 'error', 'danger', 'emergency', 'warning' ), true ) ? 'alert' : 'status';
}
$rx_aria_live = ! empty( $rx_alert['aria_live'] ) ? sanitize_key( $rx_alert['aria_live'] ) : '';
if ( empty( $rx_aria_live ) ) {
$rx_aria_live = in_array( $rx_alert_type, array( 'error', 'danger', 'emergency', 'warning' ), true ) ? 'assertive' : 'polite';
}
$rx_aria_label = ! empty( $rx_alert['aria_label'] ) ? sanitize_text_field( $rx_alert['aria_label'] ) : '';
if ( empty( $rx_aria_label ) ) {
$rx_aria_label = ucfirst( $rx_alert_type ) . ' ' . __( 'alert', 'rx-theme' );
}
/**
* ------------------------------------------------------------
* Classes
* ------------------------------------------------------------
*/
$rx_classes = array(
$rx_block_name,
'rx-alert',
'rx-alert--' . $rx_alert_type,
'rx-alert--layout-' . sanitize_html_class( $rx_alert['layout'] ),
'has-alert-type-' . $rx_alert_type,
);
if ( ! empty( $rx_alert['align'] ) ) {
$rx_classes[] = 'align' . sanitize_html_class( $rx_alert['align'] );
}
if ( ! empty( $rx_alert['text_align'] ) ) {
$rx_classes[] = 'has-text-align-' . sanitize_html_class( $rx_alert['text_align'] );
}
if ( ! empty( $rx_alert['dismissible'] ) ) {
$rx_classes[] = 'is-dismissible';
}
if ( ! empty( $rx_alert['dismiss_storage'] ) ) {
$rx_classes[] = 'has-dismiss-storage';
}
if ( ! empty( $rx_alert['auto_dismiss'] ) ) {
$rx_classes[] = 'has-auto-dismiss';
}
if ( ! empty( $rx_alert['is_collapsible'] ) ) {
$rx_classes[] = 'is-collapsible';
$rx_classes[] = ! empty( $rx_alert['is_open'] ) ? 'is-open' : 'is-closed';
}
if ( ! empty( $rx_alert['shadow'] ) ) {
$rx_classes[] = 'has-shadow';
}
if ( ! empty( $rx_alert['rounded'] ) ) {
$rx_classes[] = 'has-rounded-corners';
}
if ( ! empty( $rx_alert['priority'] ) ) {
$rx_classes[] = 'has-priority-' . sanitize_html_class( $rx_alert['priority'] );
}
if ( ! empty( $rx_alert['animation'] ) ) {
$rx_classes[] = 'has-animation';
$rx_classes[] = 'has-animation-' . sanitize_html_class( $rx_alert['animation'] );
}
if ( ! empty( $rx_alert['is_preview'] ) ) {
$rx_classes[] = 'is-preview';
}
if ( ! empty( $rx_alert['class'] ) ) {
$rx_classes[] = sanitize_html_class( $rx_alert['class'] );
}
if ( ! empty( $rx_alert['classes'] ) && is_array( $rx_alert['classes'] ) ) {
foreach ( $rx_alert['classes'] as $rx_extra_class ) {
if ( is_string( $rx_extra_class ) && '' !== $rx_extra_class ) {
$rx_classes[] = sanitize_html_class( $rx_extra_class );
}
}
}
$rx_classes = array_filter( array_unique( $rx_classes ) );
$rx_classes = apply_filters( 'rx_theme_block_alert_classes', $rx_classes, $rx_alert );
/**
* ------------------------------------------------------------
* Inline CSS Variables
* ------------------------------------------------------------
*/
$rx_style_vars = array();
if ( ! empty( $rx_alert['background'] ) ) {
$rx_style_vars[] = '--rx-alert-background:' . sanitize_hex_color( $rx_alert['background'] );
}
if ( ! empty( $rx_alert['color'] ) ) {
$rx_style_vars[] = '--rx-alert-color:' . sanitize_hex_color( $rx_alert['color'] );
}
if ( ! empty( $rx_alert['border_color'] ) ) {
$rx_style_vars[] = '--rx-alert-border-color:' . sanitize_hex_color( $rx_alert['border_color'] );
}
if ( ! empty( $rx_alert['accent_color'] ) ) {
$rx_style_vars[] = '--rx-alert-accent-color:' . sanitize_hex_color( $rx_alert['accent_color'] );
}
if ( ! empty( $rx_alert['width'] ) ) {
$rx_style_vars[] = '--rx-alert-width:' . esc_attr( $rx_alert['width'] );
}
if ( ! empty( $rx_alert['max_width'] ) ) {
$rx_style_vars[] = '--rx-alert-max-width:' . esc_attr( $rx_alert['max_width'] );
}
if ( ! empty( $rx_alert['min_height'] ) ) {
$rx_style_vars[] = '--rx-alert-min-height:' . esc_attr( $rx_alert['min_height'] );
}
if ( ! empty( $rx_alert['border_style'] ) ) {
$rx_style_vars[] = '--rx-alert-border-style:' . esc_attr( $rx_alert['border_style'] );
}
$rx_style_attr = ! empty( $rx_style_vars ) ? implode( ';', $rx_style_vars ) . ';' : '';
/**
* ------------------------------------------------------------
* Attributes
* ------------------------------------------------------------
*/
$rx_attributes = array(
'id' => $rx_alert_id,
'class' => implode( ' ', $rx_classes ),
'role' => $rx_role,
'aria-live' => $rx_aria_live,
'aria-label' => $rx_aria_label,
'data-alert' => 'rx-theme',
'data-type' => $rx_alert_type,
);
if ( ! empty( $rx_style_attr ) ) {
$rx_attributes['style'] = $rx_style_attr;
}
if ( '' !== $rx_alert['tabindex'] ) {
$rx_attributes['tabindex'] = intval( $rx_alert['tabindex'] );
}
if ( ! empty( $rx_alert['dismissible'] ) ) {
$rx_attributes['data-dismissible'] = 'true';
}
if ( ! empty( $rx_alert['dismiss_storage'] ) ) {
$rx_attributes['data-dismiss-storage'] = 'true';
$rx_attributes['data-dismiss-storage-id'] = ! empty( $rx_alert['dismiss_storage_id'] )
? sanitize_key( $rx_alert['dismiss_storage_id'] )
: sanitize_key( $rx_alert_id );
}
if ( ! empty( $rx_alert['auto_dismiss'] ) ) {
$rx_attributes['data-auto-dismiss'] = 'true';
$rx_attributes['data-auto-dismiss-delay'] = absint( $rx_alert['auto_dismiss_delay'] );
}
if ( ! empty( $rx_alert['is_collapsible'] ) ) {
$rx_attributes['data-collapsible'] = 'true';
$rx_attributes['aria-expanded'] = ! empty( $rx_alert['is_open'] ) ? 'true' : 'false';
}
if ( ! empty( $rx_alert['animation'] ) ) {
$rx_attributes['data-animation'] = sanitize_key( $rx_alert['animation'] );
}
/**
* Extra data attributes.
*/
if ( ! empty( $rx_alert['data'] ) && is_array( $rx_alert['data'] ) ) {
foreach ( $rx_alert['data'] as $rx_data_key => $rx_data_value ) {
$rx_data_key = sanitize_key( $rx_data_key );
if ( '' === $rx_data_key ) {
continue;
}
$rx_attributes[ 'data-' . $rx_data_key ] = is_scalar( $rx_data_value )
? sanitize_text_field( (string) $rx_data_value )
: wp_json_encode( $rx_data_value );
}
}
/**
* Extra attributes.
*/
if ( ! empty( $rx_alert['attributes'] ) && is_array( $rx_alert['attributes'] ) ) {
foreach ( $rx_alert['attributes'] as $rx_attr_key => $rx_attr_value ) {
$rx_attr_key = sanitize_key( $rx_attr_key );
if ( '' === $rx_attr_key ) {
continue;
}
if ( in_array( $rx_attr_key, array( 'id', 'class', 'style' ), true ) ) {
continue;
}
$rx_attributes[ $rx_attr_key ] = is_scalar( $rx_attr_value )
? sanitize_text_field( (string) $rx_attr_value )
: '';
}
}
$rx_attributes = apply_filters( 'rx_theme_block_alert_attributes', $rx_attributes, $rx_alert );
$rx_render_attributes = static function ( $attributes ) {
$output = '';
foreach ( $attributes as $name => $value ) {
if ( '' === $value || null === $value || false === $value ) {
continue;
}
if ( true === $value ) {
$output .= ' ' . esc_attr( $name );
continue;
}
$output .= ' ' . esc_attr( $name ) . '="' . esc_attr( $value ) . '"';
}
return $output;
};
/**
* ------------------------------------------------------------
* Content Check
* ------------------------------------------------------------
*/
$rx_has_text_content = (
! empty( $rx_title ) ||
! empty( $rx_subtitle ) ||
! empty( $rx_message ) ||
! empty( $rx_description ) ||
! empty( $rx_content ) ||
! empty( $rx_alert['items'] ) ||
! empty( $rx_alert['actions'] )
);
if ( ! $rx_has_text_content ) {
return;
}
/**
* ------------------------------------------------------------
* Action Button Renderer
* ------------------------------------------------------------
*/
$rx_render_action = static function ( $action, $index ) {
if ( ! is_array( $action ) ) {
return '';
}
$label = isset( $action['label'] ) ? sanitize_text_field( $action['label'] ) : '';
if ( '' === $label ) {
return '';
}
$url = isset( $action['url'] ) ? esc_url( $action['url'] ) : '';
$type = isset( $action['type'] ) ? sanitize_key( $action['type'] ) : 'link';
$style = isset( $action['style'] ) ? sanitize_html_class( $action['style'] ) : 'primary';
$target = isset( $action['target'] ) ? sanitize_key( $action['target'] ) : '';
$rel = isset( $action['rel'] ) ? sanitize_text_field( $action['rel'] ) : '';
$aria = isset( $action['aria_label'] ) ? sanitize_text_field( $action['aria_label'] ) : $label;
$download = ! empty( $action['download'] );
$classes = array(
'rx-alert__action',
'rx-alert__action--' . $style,
'rx-button',
'rx-button--' . $style,
);
if ( 'button' === $type ) {
$button_type = isset( $action['button_type'] ) ? sanitize_key( $action['button_type'] ) : 'button';
if ( ! in_array( $button_type, array( 'button', 'submit', 'reset' ), true ) ) {
$button_type = 'button';
}
return sprintf(
'<button type="%1$s" class="%2$s" aria-label="%3$s" data-action-index="%4$d">%5$s</button>',
esc_attr( $button_type ),
esc_attr( implode( ' ', $classes ) ),
esc_attr( $aria ),
absint( $index ),
esc_html( $label )
);
}
if ( empty( $url ) ) {
return '';
}
$rel_parts = array();
if ( $rel ) {
$rel_parts[] = $rel;
}
if ( '_blank' === $target ) {
$rel_parts[] = 'noopener';
$rel_parts[] = 'noreferrer';
}
$rel_parts = array_unique( array_filter( $rel_parts ) );
$attrs = array(
'href' => $url,
'class' => implode( ' ', $classes ),
'aria-label' => $aria,
'data-action-index' => absint( $index ),
);
if ( $target ) {
$attrs['target'] = $target;
}
if ( ! empty( $rel_parts ) ) {
$attrs['rel'] = implode( ' ', $rel_parts );
}
if ( $download ) {
$attrs['download'] = true;
}
$attr_html = '';
foreach ( $attrs as $attr_name => $attr_value ) {
if ( true === $attr_value ) {
$attr_html .= ' ' . esc_attr( $attr_name );
} else {
$attr_html .= ' ' . esc_attr( $attr_name ) . '="' . esc_attr( $attr_value ) . '"';
}
}
return '<a' . $attr_html . '>' . esc_html( $label ) . '</a>';
};
/**
* ------------------------------------------------------------
* Schema Data
* ------------------------------------------------------------
*/
$rx_schema = array();
if ( ! empty( $rx_alert['print_schema'] ) ) {
$rx_schema = array(
'@context' => 'https://schema.org',
'@type' => 'WebPageElement',
'name' => wp_strip_all_tags( $rx_title ? $rx_title : $rx_aria_label ),
'description' => wp_strip_all_tags( $rx_message ? $rx_message : $rx_description ),
);
$rx_schema = apply_filters( 'rx_theme_block_alert_schema', $rx_schema, $rx_alert );
}
?>
<<?php echo esc_html( $rx_wrapper_tag ); ?><?php echo $rx_render_attributes( $rx_attributes ); ?>>
<?php if ( ! empty( $rx_alert['print_schema'] ) && ! empty( $rx_schema ) ) : ?>
<script type="application/ld+json">
<?php echo wp_json_encode( $rx_schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); ?>
</script>
<?php endif; ?>
<<?php echo esc_html( $rx_inner_tag ); ?> class="rx-alert__inner">
<?php if ( ! empty( $rx_icon_markup ) ) : ?>
<div class="rx-alert__icon" aria-hidden="true">
<?php echo $rx_icon_markup; ?>
<?php if ( ! empty( $rx_alert['icon_label'] ) ) : ?>
<span class="screen-reader-text">
<?php echo esc_html( $rx_alert['icon_label'] ); ?>
</span>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="rx-alert__body">
<?php if ( ! empty( $rx_alert['meta'] ) || ! empty( $rx_alert['time'] ) ) : ?>
<div class="rx-alert__meta">
<?php if ( ! empty( $rx_alert['meta'] ) ) : ?>
<span class="rx-alert__meta-text">
<?php echo esc_html( $rx_alert['meta'] ); ?>
</span>
<?php endif; ?>
<?php if ( ! empty( $rx_alert['time'] ) ) : ?>
<time class="rx-alert__time" datetime="<?php echo esc_attr( $rx_alert['time'] ); ?>">
<?php
echo esc_html(
! empty( $rx_alert['time_label'] )
? $rx_alert['time_label']
: $rx_alert['time']
);
?>
</time>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_title ) ) : ?>
<h3 class="rx-alert__title">
<?php echo $rx_kses( $rx_title ); ?>
</h3>
<?php endif; ?>
<?php if ( ! empty( $rx_subtitle ) ) : ?>
<p class="rx-alert__subtitle">
<?php echo $rx_kses( $rx_subtitle ); ?>
</p>
<?php endif; ?>
<?php if ( ! empty( $rx_message ) ) : ?>
<div class="rx-alert__message">
<?php echo wpautop( $rx_kses( $rx_message ) ); ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_description ) ) : ?>
<div class="rx-alert__description">
<?php echo wpautop( $rx_kses( $rx_description ) ); ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_content ) ) : ?>
<div class="rx-alert__content">
<?php echo wpautop( $rx_kses( $rx_content ) ); ?>
</div>
<?php endif; ?>
<?php if ( ! empty( $rx_alert['items'] ) && is_array( $rx_alert['items'] ) ) : ?>
<ul class="rx-alert__list">
<?php foreach ( $rx_alert['items'] as $rx_item ) : ?>
<?php if ( is_string( $rx_item ) && '' !== trim( $rx_item ) ) : ?>
<li class="rx-alert__list-item">
<?php echo $rx_kses( $rx_item ); ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if ( ! empty( $rx_alert['actions'] ) && is_array( $rx_alert['actions'] ) ) : ?>
<div class="rx-alert__actions">
<?php
foreach ( $rx_alert['actions'] as $rx_action_index => $rx_action ) {
echo $rx_render_action( $rx_action, $rx_action_index ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
</div>
<?php endif; ?>
</div>
<?php if ( ! empty( $rx_alert['dismissible'] ) ) : ?>
<button
type="button"
class="rx-alert__dismiss"
aria-label="<?php echo esc_attr( $rx_alert['dismiss_label'] ); ?>"
data-rx-alert-dismiss
>
<span aria-hidden="true">×</span>
</button>
<?php endif; ?>
</<?php echo esc_html( $rx_inner_tag ); ?>>
</<?php echo esc_html( $rx_wrapper_tag ); ?>>
Example with many features:
get_template_part(
'template-parts/blocks/block-alert',
null,
array(
'type' => 'medical',
'title' => 'Medical Notice',
'subtitle' => 'Please read carefully',
'message' => 'This article is for general health education only.',
'description' => 'Always consult a qualified doctor for diagnosis and treatment.',
'dismissible' => true,
'dismiss_storage' => true,
'dismiss_storage_id'=> 'rx-medical-notice-v1',
'show_icon' => true,
'layout' => 'card',
'shadow' => true,
'rounded' => true,
'animation' => 'fade-in',
'items' => array(
'Do not ignore emergency symptoms.',
'Do not stop medicine without medical advice.',
'Visit a doctor if symptoms become severe.',
),
'actions' => array(
array(
'label' => 'Read More',
'url' => home_url( '/health-disclaimer/' ),
'style' => 'primary',
),
array(
'label' => 'Contact Doctor',
'url' => home_url( '/contact/' ),
'style' => 'secondary',
),
),
)
);
For dismiss button, later add JS in:
/assets/js/components/alert.js
(function () {
'use strict';
document.addEventListener('click', function (event) {
const button = event.target.closest('[data-rx-alert-dismiss]');
if (!button) {
return;
}
const alert = button.closest('.rx-alert');
if (!alert) {
return;
}
const useStorage = alert.getAttribute('data-dismiss-storage') === 'true';
const storageId = alert.getAttribute('data-dismiss-storage-id');
alert.setAttribute('hidden', 'hidden');
if (useStorage && storageId && window.localStorage) {
localStorage.setItem('rx_alert_dismissed_' + storageId, '1');
}
});
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.rx-alert.has-dismiss-storage').forEach(function (alert) {
const storageId = alert.getAttribute('data-dismiss-storage-id');
if (storageId && window.localStorage && localStorage.getItem('rx_alert_dismissed_' + storageId) === '1') {
alert.setAttribute('hidden', 'hidden');
}
});
document.querySelectorAll('.rx-alert.has-auto-dismiss').forEach(function (alert) {
const delay = parseInt(alert.getAttribute('data-auto-dismiss-delay'), 10) || 8000;
window.setTimeout(function () {
alert.setAttribute('hidden', 'hidden');
}, delay);
});
});
})();
This file is safe, reusable, filterable, accessible, and advanced enough for RX Theme’s block system.