I’ll build this as a reusable
inc/shortcodes/buttons.php file for your RX theme, with secure shortcode attributes, multiple button styles, icons, tracking attributes, accessibility labels, grouped buttons, and helper rendering.Yes, my friend. Create this file:
rx-theme/inc/shortcodes/buttons.php
Then paste the full code below. This file uses WordPress Shortcode API with add_shortcode(). WordPress officially says shortcode callbacks receive attributes, content, and shortcode tag name, and only one callback can exist for each shortcode name, so I used unique rx_ shortcode names to avoid conflict.
<?php
/**
* RX Theme Button Shortcodes
*
* File: inc/shortcodes/buttons.php
*
* Shortcodes:
* [rx_button]
* [rx_buttons]
* [rx_button_group]
* [rx_cta_button]
* [rx_download_button]
* [rx_whatsapp_button]
* [rx_phone_button]
* [rx_email_button]
* [rx_copy_button]
*
* @package RX_Theme
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'RX_Theme_Button_Shortcodes' ) ) :
final class RX_Theme_Button_Shortcodes {
/**
* CSS printed once.
*
* @var bool
*/
private static $css_printed = false;
/**
* JS printed once.
*
* @var bool
*/
private static $js_printed = false;
/**
* Bootstrap.
*/
public static function init() {
add_action( 'init', array( __CLASS__, 'register_shortcodes' ) );
add_action( 'wp_footer', array( __CLASS__, 'print_inline_assets' ), 30 );
}
/**
* Register shortcodes.
*/
public static function register_shortcodes() {
add_shortcode( 'rx_button', array( __CLASS__, 'button_shortcode' ) );
add_shortcode( 'rx_btn', array( __CLASS__, 'button_shortcode' ) );
add_shortcode( 'rx_buttons', array( __CLASS__, 'buttons_shortcode' ) );
add_shortcode( 'rx_button_group', array( __CLASS__, 'buttons_shortcode' ) );
add_shortcode( 'rx_cta_button', array( __CLASS__, 'cta_button_shortcode' ) );
add_shortcode( 'rx_download_button', array( __CLASS__, 'download_button_shortcode' ) );
add_shortcode( 'rx_whatsapp_button', array( __CLASS__, 'whatsapp_button_shortcode' ) );
add_shortcode( 'rx_phone_button', array( __CLASS__, 'phone_button_shortcode' ) );
add_shortcode( 'rx_email_button', array( __CLASS__, 'email_button_shortcode' ) );
add_shortcode( 'rx_copy_button', array( __CLASS__, 'copy_button_shortcode' ) );
}
/**
* Main button shortcode.
*
* Example:
* [rx_button text="Read More" url="/about" style="primary" size="lg" icon="→"]
*/
public static function button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => '',
'url' => '#',
'type' => 'link', // link, button, submit.
'style' => 'primary', // primary, secondary, success, danger, warning, info, light, dark, outline, ghost, gradient.
'size' => 'md', // xs, sm, md, lg, xl.
'shape' => 'rounded', // square, rounded, pill, circle.
'align' => '', // left, center, right, full.
'width' => '', // auto, full, custom.
'custom_width' => '',
'icon' => '',
'icon_position' => 'left', // left, right.
'target' => '',
'rel' => '',
'title' => '',
'aria_label' => '',
'id' => '',
'class' => '',
'download' => '',
'disabled' => 'false',
'nofollow' => 'false',
'sponsored' => 'false',
'ugc' => 'false',
'noopener' => 'true',
'noreferrer' => 'false',
'data_event' => '',
'data_category' => '',
'data_label' => '',
'data_value' => '',
'data_location' => '',
'data_rx' => '',
'bg' => '',
'color' => '',
'border' => '',
'hover_bg' => '',
'hover_color' => '',
'tooltip' => '',
'loading' => 'false',
'loading_text' => 'Loading...',
'confirm' => '',
'extra_attrs' => '',
),
$atts,
$tag
);
$text = trim( $atts['text'] );
if ( '' === $text && null !== $content ) {
$text = trim( wp_strip_all_tags( do_shortcode( $content ) ) );
}
if ( '' === $text ) {
$text = __( 'Button', 'rx-theme' );
}
return self::render_button( $atts, $text );
}
/**
* Button group shortcode.
*
* Example:
* [rx_buttons align="center" gap="md"]
* [rx_button text="Start" url="/start"]
* [rx_button text="Learn" url="/learn" style="outline"]
* [/rx_buttons]
*/
public static function buttons_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'align' => 'center',
'gap' => 'md',
'stack' => 'mobile',
'class' => '',
'id' => '',
'role' => '',
'aria_label' => '',
),
$atts,
$tag
);
$classes = array(
'rx-button-group',
'rx-button-group--align-' . sanitize_html_class( $atts['align'] ),
'rx-button-group--gap-' . sanitize_html_class( $atts['gap'] ),
'rx-button-group--stack-' . sanitize_html_class( $atts['stack'] ),
);
if ( ! empty( $atts['class'] ) ) {
$classes[] = sanitize_html_class( $atts['class'] );
}
$attrs = array(
'class' => implode( ' ', array_filter( $classes ) ),
);
if ( ! empty( $atts['id'] ) ) {
$attrs['id'] = sanitize_html_class( $atts['id'] );
}
if ( ! empty( $atts['role'] ) ) {
$attrs['role'] = sanitize_key( $atts['role'] );
}
if ( ! empty( $atts['aria_label'] ) ) {
$attrs['aria-label'] = sanitize_text_field( $atts['aria_label'] );
}
return '<div ' . self::build_attrs( $attrs ) . '>' . do_shortcode( $content ) . '</div>';
}
/**
* CTA button shortcode.
*/
public static function cta_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Get Started',
'url' => '#',
'subtext' => '',
'style' => 'gradient',
'size' => 'lg',
'icon' => '→',
'icon_position' => 'right',
'target' => '',
'class' => '',
),
$atts,
$tag
);
$atts['class'] .= ' rx-button--cta';
$text = sanitize_text_field( $atts['text'] );
if ( ! empty( $atts['subtext'] ) ) {
$text .= '<span class="rx-button__subtext">' . esc_html( $atts['subtext'] ) . '</span>';
}
return self::render_button( $atts, $text, true );
}
/**
* Download button shortcode.
*/
public static function download_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Download',
'url' => '#',
'file_name' => '',
'style' => 'success',
'size' => 'md',
'icon' => '⬇',
'target' => '',
'class' => '',
),
$atts,
$tag
);
$atts['download'] = ! empty( $atts['file_name'] ) ? sanitize_file_name( $atts['file_name'] ) : 'true';
$atts['class'] .= ' rx-button--download';
return self::render_button( $atts, sanitize_text_field( $atts['text'] ) );
}
/**
* WhatsApp button shortcode.
*/
public static function whatsapp_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Chat on WhatsApp',
'phone' => '',
'message' => '',
'style' => 'success',
'size' => 'md',
'icon' => '💬',
'target' => '_blank',
'class' => '',
),
$atts,
$tag
);
$phone = preg_replace( '/[^0-9]/', '', $atts['phone'] );
$message = rawurlencode( sanitize_text_field( $atts['message'] ) );
if ( empty( $phone ) ) {
return '';
}
$atts['url'] = 'https://wa.me/' . $phone . ( $message ? '?text=' . $message : '' );
$atts['class'] .= ' rx-button--whatsapp';
return self::render_button( $atts, sanitize_text_field( $atts['text'] ) );
}
/**
* Phone button shortcode.
*/
public static function phone_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Call Now',
'phone' => '',
'style' => 'primary',
'size' => 'md',
'icon' => '☎',
'class' => '',
),
$atts,
$tag
);
$phone = preg_replace( '/[^0-9+]/', '', $atts['phone'] );
if ( empty( $phone ) ) {
return '';
}
$atts['url'] = 'tel:' . $phone;
$atts['class'] .= ' rx-button--phone';
return self::render_button( $atts, sanitize_text_field( $atts['text'] ) );
}
/**
* Email button shortcode.
*/
public static function email_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Email Us',
'email' => '',
'subject' => '',
'body' => '',
'style' => 'secondary',
'size' => 'md',
'icon' => '✉',
'class' => '',
),
$atts,
$tag
);
$email = sanitize_email( $atts['email'] );
if ( ! is_email( $email ) ) {
return '';
}
$args = array();
if ( ! empty( $atts['subject'] ) ) {
$args['subject'] = sanitize_text_field( $atts['subject'] );
}
if ( ! empty( $atts['body'] ) ) {
$args['body'] = sanitize_textarea_field( $atts['body'] );
}
$query = $args ? '?' . http_build_query( $args ) : '';
$atts['url'] = 'mailto:' . antispambot( $email ) . $query;
$atts['class'] .= ' rx-button--email';
return self::render_button( $atts, sanitize_text_field( $atts['text'] ) );
}
/**
* Copy button shortcode.
*/
public static function copy_button_shortcode( $atts, $content = null, $tag = '' ) {
$atts = shortcode_atts(
array(
'text' => 'Copy',
'copy' => '',
'copied_text' => 'Copied!',
'style' => 'dark',
'size' => 'sm',
'icon' => '📋',
'class' => '',
),
$atts,
$tag
);
$copy_text = $atts['copy'];
if ( '' === $copy_text && null !== $content ) {
$copy_text = wp_strip_all_tags( do_shortcode( $content ) );
}
if ( '' === trim( $copy_text ) ) {
return '';
}
$atts['type'] = 'button';
$atts['url'] = '#';
$atts['class'] .= ' rx-button--copy';
$atts['data_rx'] = 'copy';
$atts['data_label'] = sanitize_text_field( $copy_text );
$atts['data_event'] = sanitize_text_field( $atts['copied_text'] );
$atts['aria_label'] = sanitize_text_field( $atts['text'] );
return self::render_button( $atts, sanitize_text_field( $atts['text'] ) );
}
/**
* Render button.
*/
private static function render_button( $atts, $text, $allow_html_text = false ) {
$type = sanitize_key( $atts['type'] ?? 'link' );
$url = isset( $atts['url'] ) ? trim( $atts['url'] ) : '#';
$disabled = self::to_bool( $atts['disabled'] ?? false );
$classes = array(
'rx-button',
'rx-button--' . sanitize_html_class( $atts['style'] ?? 'primary' ),
'rx-button--size-' . sanitize_html_class( $atts['size'] ?? 'md' ),
'rx-button--shape-' . sanitize_html_class( $atts['shape'] ?? 'rounded' ),
);
if ( ! empty( $atts['align'] ) ) {
$classes[] = 'rx-button--align-' . sanitize_html_class( $atts['align'] );
}
if ( ! empty( $atts['width'] ) ) {
$classes[] = 'rx-button--width-' . sanitize_html_class( $atts['width'] );
}
if ( self::to_bool( $atts['loading'] ?? false ) ) {
$classes[] = 'is-loading';
}
if ( $disabled ) {
$classes[] = 'is-disabled';
}
if ( ! empty( $atts['class'] ) ) {
$extra_classes = explode( ' ', $atts['class'] );
foreach ( $extra_classes as $extra_class ) {
$classes[] = sanitize_html_class( $extra_class );
}
}
$style = self::build_inline_style( $atts );
$attrs = array(
'class' => implode( ' ', array_filter( array_unique( $classes ) ) ),
);
if ( ! empty( $style ) ) {
$attrs['style'] = $style;
}
if ( ! empty( $atts['id'] ) ) {
$attrs['id'] = sanitize_html_class( $atts['id'] );
}
if ( ! empty( $atts['title'] ) ) {
$attrs['title'] = sanitize_text_field( $atts['title'] );
}
if ( ! empty( $atts['tooltip'] ) ) {
$attrs['data-tooltip'] = sanitize_text_field( $atts['tooltip'] );
}
if ( ! empty( $atts['aria_label'] ) ) {
$attrs['aria-label'] = sanitize_text_field( $atts['aria_label'] );
}
if ( ! empty( $atts['data_event'] ) ) {
$attrs['data-event'] = sanitize_text_field( $atts['data_event'] );
}
if ( ! empty( $atts['data_category'] ) ) {
$attrs['data-category'] = sanitize_text_field( $atts['data_category'] );
}
if ( ! empty( $atts['data_label'] ) ) {
$attrs['data-label'] = sanitize_text_field( $atts['data_label'] );
}
if ( ! empty( $atts['data_value'] ) ) {
$attrs['data-value'] = sanitize_text_field( $atts['data_value'] );
}
if ( ! empty( $atts['data_location'] ) ) {
$attrs['data-location'] = sanitize_text_field( $atts['data_location'] );
}
if ( ! empty( $atts['data_rx'] ) ) {
$attrs['data-rx'] = sanitize_key( $atts['data_rx'] );
}
if ( ! empty( $atts['loading_text'] ) ) {
$attrs['data-loading-text'] = sanitize_text_field( $atts['loading_text'] );
}
if ( ! empty( $atts['confirm'] ) ) {
$attrs['data-confirm'] = sanitize_text_field( $atts['confirm'] );
}
$label = $allow_html_text ? wp_kses_post( $text ) : esc_html( $text );
$icon = self::render_icon( $atts['icon'] ?? '', $atts['icon_position'] ?? 'left' );
if ( ! empty( $icon ) && 'right' === sanitize_key( $atts['icon_position'] ?? 'left' ) ) {
$inner = '<span class="rx-button__text">' . $label . '</span>' . $icon;
} elseif ( ! empty( $icon ) ) {
$inner = $icon . '<span class="rx-button__text">' . $label . '</span>';
} else {
$inner = '<span class="rx-button__text">' . $label . '</span>';
}
if ( 'button' === $type || 'submit' === $type ) {
$attrs['type'] = 'submit' === $type ? 'submit' : 'button';
if ( $disabled ) {
$attrs['disabled'] = 'disabled';
$attrs['aria-disabled'] = 'true';
}
return '<button ' . self::build_attrs( $attrs ) . '>' . $inner . '</button>';
}
$attrs['href'] = esc_url( $url );
if ( ! empty( $atts['target'] ) ) {
$attrs['target'] = sanitize_key( $atts['target'] );
}
$rel = self::build_rel( $atts );
if ( ! empty( $rel ) ) {
$attrs['rel'] = $rel;
}
if ( ! empty( $atts['download'] ) ) {
$attrs['download'] = 'true' === $atts['download'] ? '' : sanitize_file_name( $atts['download'] );
}
if ( $disabled ) {
$attrs['href'] = '#';
$attrs['aria-disabled'] = 'true';
$attrs['tabindex'] = '-1';
}
return '<a ' . self::build_attrs( $attrs ) . '>' . $inner . '</a>';
}
/**
* Render icon.
*/
private static function render_icon( $icon, $position = 'left' ) {
$icon = trim( wp_kses_post( $icon ) );
if ( '' === $icon ) {
return '';
}
$class = 'rx-button__icon rx-button__icon--' . sanitize_html_class( $position );
return '<span class="' . esc_attr( $class ) . '" aria-hidden="true">' . $icon . '</span>';
}
/**
* Build rel attribute.
*/
private static function build_rel( $atts ) {
$rel = array();
if ( ! empty( $atts['rel'] ) ) {
$custom_rel = explode( ' ', $atts['rel'] );
foreach ( $custom_rel as $item ) {
$rel[] = sanitize_key( $item );
}
}
if ( '_blank' === ( $atts['target'] ?? '' ) && self::to_bool( $atts['noopener'] ?? true ) ) {
$rel[] = 'noopener';
}
if ( self::to_bool( $atts['noreferrer'] ?? false ) ) {
$rel[] = 'noreferrer';
}
if ( self::to_bool( $atts['nofollow'] ?? false ) ) {
$rel[] = 'nofollow';
}
if ( self::to_bool( $atts['sponsored'] ?? false ) ) {
$rel[] = 'sponsored';
}
if ( self::to_bool( $atts['ugc'] ?? false ) ) {
$rel[] = 'ugc';
}
return implode( ' ', array_filter( array_unique( $rel ) ) );
}
/**
* Build inline style.
*/
private static function build_inline_style( $atts ) {
$styles = array();
if ( ! empty( $atts['bg'] ) ) {
$styles[] = '--rx-btn-bg:' . sanitize_hex_color( $atts['bg'] );
}
if ( ! empty( $atts['color'] ) ) {
$styles[] = '--rx-btn-color:' . sanitize_hex_color( $atts['color'] );
}
if ( ! empty( $atts['border'] ) ) {
$styles[] = '--rx-btn-border:' . sanitize_hex_color( $atts['border'] );
}
if ( ! empty( $atts['hover_bg'] ) ) {
$styles[] = '--rx-btn-hover-bg:' . sanitize_hex_color( $atts['hover_bg'] );
}
if ( ! empty( $atts['hover_color'] ) ) {
$styles[] = '--rx-btn-hover-color:' . sanitize_hex_color( $atts['hover_color'] );
}
if ( ! empty( $atts['custom_width'] ) ) {
$width = preg_replace( '/[^0-9a-zA-Z.%\-]/', '', $atts['custom_width'] );
$styles[] = '--rx-btn-custom-width:' . $width;
}
return implode( ';', array_filter( $styles ) );
}
/**
* Build HTML attributes.
*/
private static function build_attrs( $attrs ) {
$html = '';
foreach ( $attrs as $name => $value ) {
if ( null === $value || false === $value ) {
continue;
}
$name = sanitize_key( $name );
if ( '' === $value ) {
$html .= ' ' . esc_attr( $name );
} else {
$html .= ' ' . esc_attr( $name ) . '="' . esc_attr( $value ) . '"';
}
}
return trim( $html );
}
/**
* Convert shortcode bool.
*/
private static function to_bool( $value ) {
if ( is_bool( $value ) ) {
return $value;
}
$value = strtolower( trim( (string) $value ) );
return in_array( $value, array( '1', 'true', 'yes', 'on' ), true );
}
/**
* Print inline CSS and JS once.
*/
public static function print_inline_assets() {
self::print_css();
self::print_js();
}
/**
* Print CSS.
*/
private static function print_css() {
if ( self::$css_printed ) {
return;
}
self::$css_printed = true;
?>
<style id="rx-button-shortcodes-css">
.rx-button {
--rx-btn-bg: #2563eb;
--rx-btn-color: #ffffff;
--rx-btn-border: #2563eb;
--rx-btn-hover-bg: #1d4ed8;
--rx-btn-hover-color: #ffffff;
--rx-btn-radius: 10px;
--rx-btn-custom-width: auto;
display: inline-flex;
align-items: center;
justify-content: center;
gap: .5em;
width: var(--rx-btn-custom-width);
padding: .75em 1.15em;
border: 1px solid var(--rx-btn-border);
border-radius: var(--rx-btn-radius);
background: var(--rx-btn-bg);
color: var(--rx-btn-color);
font-weight: 700;
line-height: 1.2;
text-decoration: none;
cursor: pointer;
transition: transform .2s ease, box-shadow .2s ease, background .2s ease, color .2s ease, border-color .2s ease;
box-shadow: 0 8px 20px rgba(15, 23, 42, .12);
position: relative;
vertical-align: middle;
}
.rx-button:hover,
.rx-button:focus {
background: var(--rx-btn-hover-bg);
color: var(--rx-btn-hover-color);
text-decoration: none;
transform: translateY(-1px);
box-shadow: 0 12px 28px rgba(15, 23, 42, .18);
}
.rx-button:focus-visible {
outline: 3px solid rgba(37, 99, 235, .35);
outline-offset: 3px;
}
.rx-button__icon {
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.rx-button__text {
display: inline-flex;
align-items: center;
gap: .35em;
}
.rx-button__subtext {
display: block;
font-size: .72em;
font-weight: 500;
opacity: .9;
margin-top: .15rem;
}
.rx-button--primary {
--rx-btn-bg: #2563eb;
--rx-btn-border: #2563eb;
--rx-btn-hover-bg: #1d4ed8;
}
.rx-button--secondary {
--rx-btn-bg: #475569;
--rx-btn-border: #475569;
--rx-btn-hover-bg: #334155;
}
.rx-button--success {
--rx-btn-bg: #16a34a;
--rx-btn-border: #16a34a;
--rx-btn-hover-bg: #15803d;
}
.rx-button--danger {
--rx-btn-bg: #dc2626;
--rx-btn-border: #dc2626;
--rx-btn-hover-bg: #b91c1c;
}
.rx-button--warning {
--rx-btn-bg: #f59e0b;
--rx-btn-border: #f59e0b;
--rx-btn-color: #111827;
--rx-btn-hover-bg: #d97706;
--rx-btn-hover-color: #111827;
}
.rx-button--info {
--rx-btn-bg: #0891b2;
--rx-btn-border: #0891b2;
--rx-btn-hover-bg: #0e7490;
}
.rx-button--light {
--rx-btn-bg: #f8fafc;
--rx-btn-color: #0f172a;
--rx-btn-border: #e2e8f0;
--rx-btn-hover-bg: #e2e8f0;
--rx-btn-hover-color: #0f172a;
}
.rx-button--dark {
--rx-btn-bg: #0f172a;
--rx-btn-border: #0f172a;
--rx-btn-hover-bg: #020617;
}
.rx-button--outline {
--rx-btn-bg: transparent;
--rx-btn-color: #2563eb;
--rx-btn-border: #2563eb;
--rx-btn-hover-bg: #2563eb;
--rx-btn-hover-color: #ffffff;
}
.rx-button--ghost {
--rx-btn-bg: transparent;
--rx-btn-color: #2563eb;
--rx-btn-border: transparent;
--rx-btn-hover-bg: rgba(37, 99, 235, .08);
--rx-btn-hover-color: #1d4ed8;
box-shadow: none;
}
.rx-button--gradient {
--rx-btn-bg: linear-gradient(135deg, #2563eb, #7c3aed);
--rx-btn-border: transparent;
--rx-btn-hover-bg: linear-gradient(135deg, #1d4ed8, #6d28d9);
}
.rx-button--size-xs {
font-size: .75rem;
padding: .45em .7em;
}
.rx-button--size-sm {
font-size: .875rem;
padding: .55em .85em;
}
.rx-button--size-md {
font-size: 1rem;
}
.rx-button--size-lg {
font-size: 1.125rem;
padding: .9em 1.35em;
}
.rx-button--size-xl {
font-size: 1.25rem;
padding: 1em 1.6em;
}
.rx-button--shape-square {
--rx-btn-radius: 0;
}
.rx-button--shape-rounded {
--rx-btn-radius: 10px;
}
.rx-button--shape-pill {
--rx-btn-radius: 999px;
}
.rx-button--shape-circle {
--rx-btn-radius: 999px;
aspect-ratio: 1 / 1;
padding-left: .9em;
padding-right: .9em;
}
.rx-button--width-full,
.rx-button--align-full {
display: flex;
width: 100%;
}
.rx-button--width-custom {
width: var(--rx-btn-custom-width);
}
.rx-button--align-center {
margin-left: auto;
margin-right: auto;
}
.rx-button--align-right {
margin-left: auto;
}
.rx-button.is-disabled,
.rx-button[disabled] {
opacity: .55;
pointer-events: none;
cursor: not-allowed;
transform: none;
}
.rx-button.is-loading {
pointer-events: none;
opacity: .8;
}
.rx-button.is-loading::after {
content: "";
width: 1em;
height: 1em;
border: 2px solid currentColor;
border-right-color: transparent;
border-radius: 999px;
animation: rxButtonSpin .75s linear infinite;
}
.rx-button[data-tooltip]::before {
content: attr(data-tooltip);
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
transform: translateX(-50%);
padding: .35rem .55rem;
border-radius: 6px;
background: #111827;
color: #ffffff;
font-size: .75rem;
white-space: nowrap;
opacity: 0;
visibility: hidden;
pointer-events: none;
transition: opacity .2s ease, visibility .2s ease;
}
.rx-button[data-tooltip]:hover::before,
.rx-button[data-tooltip]:focus::before {
opacity: 1;
visibility: visible;
}
.rx-button-group {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .75rem;
margin: 1rem 0;
}
.rx-button-group--align-left {
justify-content: flex-start;
}
.rx-button-group--align-center {
justify-content: center;
}
.rx-button-group--align-right {
justify-content: flex-end;
}
.rx-button-group--align-between {
justify-content: space-between;
}
.rx-button-group--gap-xs {
gap: .25rem;
}
.rx-button-group--gap-sm {
gap: .5rem;
}
.rx-button-group--gap-md {
gap: .75rem;
}
.rx-button-group--gap-lg {
gap: 1rem;
}
.rx-button-group--gap-xl {
gap: 1.5rem;
}
.rx-button--cta {
min-width: 220px;
min-height: 58px;
}
.rx-button--copy.is-copied {
--rx-btn-bg: #16a34a;
--rx-btn-border: #16a34a;
--rx-btn-hover-bg: #15803d;
}
@keyframes rxButtonSpin {
to {
transform: rotate(360deg);
}
}
@media (max-width: 640px) {
.rx-button-group--stack-mobile {
flex-direction: column;
align-items: stretch;
}
.rx-button-group--stack-mobile .rx-button {
width: 100%;
}
}
</style>
<?php
}
/**
* Print JS.
*/
private static function print_js() {
if ( self::$js_printed ) {
return;
}
self::$js_printed = true;
?>
<script id="rx-button-shortcodes-js">
(function () {
'use strict';
document.addEventListener('click', function (event) {
var button = event.target.closest('.rx-button');
if (!button) {
return;
}
var confirmMessage = button.getAttribute('data-confirm');
if (confirmMessage && !window.confirm(confirmMessage)) {
event.preventDefault();
return;
}
if (button.getAttribute('data-rx') === 'copy') {
event.preventDefault();
var copyText = button.getAttribute('data-label') || '';
var copiedText = button.getAttribute('data-event') || 'Copied!';
var originalTextElement = button.querySelector('.rx-button__text');
var originalText = originalTextElement ? originalTextElement.textContent : '';
if (!copyText) {
return;
}
function setCopiedState() {
button.classList.add('is-copied');
if (originalTextElement) {
originalTextElement.textContent = copiedText;
}
window.setTimeout(function () {
button.classList.remove('is-copied');
if (originalTextElement) {
originalTextElement.textContent = originalText;
}
}, 1600);
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(copyText).then(setCopiedState);
} else {
var textarea = document.createElement('textarea');
textarea.value = copyText;
textarea.style.position = 'fixed';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
setCopiedState();
} catch (error) {}
document.body.removeChild(textarea);
}
}
if (button.getAttribute('data-loading-text')) {
var textElement = button.querySelector('.rx-button__text');
if (textElement && !button.classList.contains('is-loading')) {
button.setAttribute('data-original-text', textElement.textContent);
textElement.textContent = button.getAttribute('data-loading-text');
}
button.classList.add('is-loading');
}
});
})();
</script>
<?php
}
}
RX_Theme_Button_Shortcodes::init();
endif;
Now include it in your functions.php:
/**
* RX Theme Shortcodes.
*/
$rx_buttons_file = get_template_directory() . '/inc/shortcodes/buttons.php';
if ( file_exists( $rx_buttons_file ) ) {
require_once $rx_buttons_file;
}
Usage examples:
[rx_button text="Read More" url="/about" style="primary" size="lg" icon="→" icon_position="right"]
[rx_button text="Download Report" url="/file.pdf" style="success" download="report.pdf" icon="⬇"]
[rx_buttons align="center" gap="lg"]
[rx_button text="Start Now" url="/start" style="gradient" size="lg"]
[rx_button text="Learn More" url="/learn" style="outline" size="lg"]
[/rx_buttons]
[rx_cta_button text="Join RX Health Mission" subtext="A global war against illness" url="/join"]
[rx_whatsapp_button phone="8801700000000" message="Hello RX Harun" text="Chat With Us"]
[rx_phone_button phone="+8801700000000" text="Call Doctor"]
[rx_email_button email="hello@example.com" subject="Appointment Request" text="Send Email"]
[rx_copy_button copy="RXHARUN2026" text="Copy Coupon"]
This is safe for theme use because it sanitizes shortcode input, escapes output, supports accessibility labels, and uses unique rx_ shortcode names.