Over 05 years we help companies reach their financial and branding goals. webtechguru is a values-driven technology agency dedicated.

Gallery

Contacts

support@webtechguru.in

WordPress Me Custom Testimonial Slider Kaise Banaye

परिचय

नमस्ते दोस्तों,

इस ट्यूटोरियल में मैं आपको बताऊँगा कि कैसे हम वर्डप्रेस में एक Custom Testimonial Slider (Testimonial) बना सकते हैं एक कस्टम वर्डप्रेस प्लगइन के ज़रिए।

इस प्लगइन में हम एक कैरोसेल स्लाइडर बनाएँगे और “Testimonials” मेन्यू के अंदर एक सेटिंग्स सबमेन्यू जोड़ेंगे। इस सेटिंग्स पेज से आप स्लाइडर के ऑप्शन्स जैसे ऑटोप्ले, लूप, डॉट्स और टाइमिंग को कंट्रोल कर पाएँगे।

हम इसमें एक शॉर्टकोड कॉपी बटन भी जोड़ेंगे ताकि आप आसानी से शॉर्टकोड कॉपी करके वर्डप्रेस में कहीं भी पेस्ट कर सकें और टेस्टिमोनियल स्लाइडर दिखा सकें।

इसके अलावा हम डमी डेटा भी ऐड करेंगे, ताकि अगर आपके पास असली टेस्टिमोनियल्स न हों, तो डमी डेटा दिखाई दे जब तक कि आप अपने टेस्टिमोनियल्स ऐड न कर लें।

तो चलिए शुरू करते हैं।

ज़रूरी चीज़ें

सबसे पहले हमें अपने प्लगइन के लिए एक सिंपल फ़ोल्डर स्ट्रक्चर बनाना होगा।

1. फ़ोल्डर स्ट्रक्चर

हमें plugins डायरेक्टरी के अंदर एक नया फ़ोल्डर और एक मेन फ़ाइल बनानी होगी।

-- plugins (folder)
   -- custom-testimonial (folder)
      -- custom-testimonial.php (file)

फिर हमें custom-testimonial.php फ़ाइल में प्लगइन हेडर डिटेल्स ऐड करनी होंगी ताकि वर्डप्रेस इस प्लगइन को पहचान सके।

/*
Plugin Name: Custom Testimonials with Slider & Ratings
Description: Manage testimonials with Owl Carousel slider, role/company, and star ratings. Shortcode: [testimonial_slider]
Version: 1.3
Author: Your Name
*/

2. प्लगइन के स्टेप्स 

इस प्लगइन को हम स्टेप-बाय-स्टेप बनाएँगे:

  1. टेस्टिमोनियल के लिए Custom Post Type (CPT) बनाना
  2. Metabox: Role, Company, Rating (1–5 stars) जोड़ना
  3. फ्रंट-एंड Assets (CSS/JS) रजिस्टर करना
  4. शॉर्टकोड बनाना: [testimonial_slider]
  5. Admin Submenu: Slider Settings जोड़ना

3. Custom Post Type + Thumbnails

इस स्टेप में हम Testimonials के लिए CPT बनाएँगे।

इससे आप Admin पैनल से Testimonials को Add, Edit और Delete कर सकते हैं।

// =====================================================
// 1) Register Testimonial CPT + thumbnails
// =====================================================
function ct_register_testimonial_cpt() {
    $labels = array(
        'name'               => 'Testimonials',
        'singular_name'      => 'Testimonial',
        'menu_name'          => 'Testimonials',
        'name_admin_bar'     => 'Testimonial',
        'add_new'            => 'Add New',
        'add_new_item'       => 'Add New Testimonial',
        'new_item'           => 'New Testimonial',
        'edit_item'          => 'Edit Testimonial',
        'view_item'          => 'View Testimonial',
        'all_items'          => 'All Testimonials',
        'search_items'       => 'Search Testimonials',
    );
    $args = array(
        'labels'       => $labels,
        'public'       => true,
        'show_ui'      => true,
        'show_in_menu' => true,
        'menu_icon'    => 'dashicons-testimonial',
        'supports'     => array('title', 'editor', 'thumbnail'),
    );
    register_post_type('testimonial', $args);
}
add_action('init', 'ct_register_testimonial_cpt');

function ct_enable_testimonial_thumbs() {
    add_theme_support('post-thumbnails', array('testimonial'));
}
add_action('after_setup_theme', 'ct_enable_testimonial_thumbs');

Custom Testimonial Slider

 

4. Metabox (Role, Company, Rating)

अब हम Testimonials में extra fields (Role, Company, Rating) ऐड करेंगे।

For example:

  • Role
  • Company
  • Rating (1–5 stars)

This will allow you to store structured information along with the testimonial text.

// =====================================================
// 2) Metabox: Role, Company, Rating (1–5)
// =====================================================
function ct_add_testimonial_metabox() {
    add_meta_box(
        'ct_testimonial_details',
        'Testimonial Details',
        'ct_testimonial_metabox_html',
        'testimonial',
        'normal',
        'default'
    );
}
add_action('add_meta_boxes', 'ct_add_testimonial_metabox');

function ct_testimonial_metabox_html($post) {
    wp_nonce_field('ct_testimonial_save_meta', 'ct_testimonial_nonce');

    $role    = get_post_meta($post->ID, '_testimonial_role', true);
    $company = get_post_meta($post->ID, '_testimonial_company', true);
    $rating  = get_post_meta($post->ID, '_testimonial_rating', true);
    if ($rating === '' || $rating === null) { $rating = 5; }
    ?>
    <p>
        <label><strong>Role / Designation</strong></label><br>
        <input type="text" name="testimonial_role" value="<?php echo esc_attr($role); ?>" style="width:100%">
    </p>
    <p>
        <label><strong>Company</strong></label><br>
        <input type="text" name="testimonial_company" value="<?php echo esc_attr($company); ?>" style="width:100%">
    </p>
    <p>
        <label><strong>Rating (1–5)</strong></label><br>
        <select name="testimonial_rating">
            <?php for ($i=1; $i<=5; $i++): ?>
                <option value="<?php echo $i; ?>" <?php selected(intval($rating), $i); ?>>
                    <?php echo $i; ?> <?php echo $i>1 ? 'stars' : 'star'; ?>
                </option>
            <?php endfor; ?>
        </select>
    </p>
    <?php
}

function ct_save_testimonial_meta($post_id) {
    if (!isset($_POST['ct_testimonial_nonce']) || !wp_verify_nonce($_POST['ct_testimonial_nonce'], 'ct_testimonial_save_meta')) {
        return;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; }
    if (isset($_POST['post_type']) && 'testimonial' === $_POST['post_type']) {
        if (!current_user_can('edit_post', $post_id)) { return; }
    } else {
        return;
    }

    if (isset($_POST['testimonial_role'])) {
        update_post_meta($post_id, '_testimonial_role', sanitize_text_field($_POST['testimonial_role']));
    }
    if (isset($_POST['testimonial_company'])) {
        update_post_meta($post_id, '_testimonial_company', sanitize_text_field($_POST['testimonial_company']));
    }
    if (isset($_POST['testimonial_rating'])) {
        $r = max(1, min(5, intval($_POST['testimonial_rating'])));
        update_post_meta($post_id, '_testimonial_rating', $r);
    }
}
add_action('save_post', 'ct_save_testimonial_meta');

Custom Testimonial Slider

 

5. Front-end Assets

Owl Carousel की CSS और JS फाइल्स लोड करेंगे ताकि स्लाइडर काम करे।

// =====================================================
// 3) Front-end assets
// =====================================================
function ct_enqueue_owl_assets() {
    wp_enqueue_style('owl-carousel', 'https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css', array(), '2.3.4');
    wp_enqueue_style('owl-theme', 'https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.theme.default.min.css', array('owl-carousel'), '2.3.4');
    wp_enqueue_script('owl-carousel', 'https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js', array('jquery'), '2.3.4', true);

    $css = '
    .ct-testimonial-card { background:#fff; border:1px solid #eee; border-radius:12px; padding:24px; box-shadow:0 4px 12px rgba(0,0,0,0.06); text-align:center; }
    .ct-testimonial-card .ct-photo { border-radius:50%; object-fit:cover; display:block; margin:0 auto 12px; }
    .ct-testimonial-card .ct-name { font-weight:700; margin:6px 0 0; }
    .ct-testimonial-card .ct-meta { color:#6c757d; font-size:12px; margin-bottom:8px; }
    .ct-testimonial-card .ct-stars { color:#f5b50a; font-size:18px; margin:6px 0; letter-spacing:1px; }
    .ct-testimonial-card .ct-text { color:#444; font-size:14px; margin-top:8px; }
    ';
    wp_add_inline_style('owl-carousel', $css);
}
add_action('wp_enqueue_scripts', 'ct_enqueue_owl_assets');

6. Shortcode

अब हम [testimonial_slider] शॉर्टकोड बनाएँगे।

इसे कहीं भी पोस्ट/पेज में डालकर Testimonials शो कर सकते हैं।

// =====================================================
// 4) Shortcode: [testimonial_slider]
// =====================================================
function ct_testimonial_slider_shortcode() {
    $defaults = array(
        'items'      => 3,
        'autoplay'   => true,
        'loop'       => true,
        'speed'      => 3000,
        'nav'        => true,
        'dots'       => true,
        'image_size' => 80,
    );
    $settings = wp_parse_args(get_option('ct_slider_settings', array()), $defaults);

    $q = new WP_Query(array(
        'post_type'      => 'testimonial',
        'posts_per_page' => -1,
        'post_status'    => 'publish',
    ));

    // Dummy testimonials if no posts exist
    $dummy_testimonials = array(
        array(
            'name' => 'John Doe',
            'text' => 'This product is absolutely amazing! Highly recommended.',
            'role' => 'CEO',
            'company' => 'TechCorp',
            'rating' => 5,
            'image' => plugins_url('images/testimonial1.png', __FILE__),
        ),
        array(
            'name' => 'Jane Smith',
            'text' => 'Fantastic support and great features. Love it!',
            'role' => 'Marketing Manager',
            'company' => 'BizWorld',
            'rating' => 4,
            'image' => plugins_url('images/testimonial2.png', __FILE__),
        ),
        array(
            'name' => 'Michael Lee',
            'text' => 'Very easy to use and setup. Five stars from me.',
            'role' => 'Freelancer',
            'company' => '',
            'rating' => 5,
            'image' => plugins_url('images/testimonial3.png', __FILE__),
        ),
    );

    ob_start();
    ?>
    <div class="owl-carousel ct-testimonial-slider">
        <?php if ($q->have_posts()): while ($q->have_posts()): $q->the_post();
            $img = get_the_post_thumbnail_url(get_the_ID(), 'thumbnail');
            if (!$img) {
                $img = 'https://via.placeholder.com/' . intval($settings['image_size']);
            }
            $role    = get_post_meta(get_the_ID(), '_testimonial_role', true);
            $company = get_post_meta(get_the_ID(), '_testimonial_company', true);
            $rating  = intval(get_post_meta(get_the_ID(), '_testimonial_rating', true));
            if ($rating < 1) { $rating = 5; }
            ?>
            <div class="ct-testimonial-card">
                <img class="ct-photo" src="<?php echo esc_url($img); ?>"
                     alt="<?php echo esc_attr(get_the_title()); ?>"
                     style="width:<?php echo intval($settings['image_size']); ?>px!important;height:<?php echo intval($settings['image_size']); ?>px!important;object-fit: cover;object-position: center;border-radius: 50px!important;">

                <div class="ct-stars">
                    <?php for ($i = 1; $i <= 5; $i++) echo $i <= $rating ? '★' : '☆'; ?>
                </div>

                <div class="ct-text"><?php echo wp_kses_post(get_the_content()); ?></div>

                <div class="ct-name"><?php echo esc_html(get_the_title()); ?></div>
                <?php if ($role || $company): ?>
                    <div class="ct-meta">
                        <?php
                        $parts = array();
                        if ($role)    { $parts[] = esc_html($role); }
                        if ($company) { $parts[] = esc_html($company); }
                        echo implode(' at ', $parts);
                        ?>
                    </div>
                <?php endif; ?>
            </div>
        <?php endwhile; wp_reset_postdata();
        else:
            foreach ($dummy_testimonials as $d): ?>
                <div class="ct-testimonial-card">
                    <img class="ct-photo" src="<?php echo esc_url($d['image']); ?>"
                         alt="<?php echo esc_attr($d['name']); ?>"
                         style="width:<?php echo intval($settings['image_size']); ?>px!important;height:<?php echo intval($settings['image_size']); ?>px!important;object-fit: cover;object-position: center;border-radius: 50px!important;">

                    <div class="ct-stars">
                        <?php for ($i = 1; $i <= 5; $i++) echo $i <= $d['rating'] ? '★' : '☆'; ?>
                    </div>

                    <div class="ct-text"><?php echo esc_html($d['text']); ?></div>

                    <div class="ct-name"><?php echo esc_html($d['name']); ?></div>
                    <?php if ($d['role'] || $d['company']): ?>
                        <div class="ct-meta">
                            <?php
                            $parts = array();
                            if ($d['role'])    { $parts[] = esc_html($d['role']); }
                            if ($d['company']) { $parts[] = esc_html($d['company']); }
                            echo implode(' at ', $parts);
                            ?>
                        </div>
                    <?php endif; ?>
                </div>
            <?php endforeach;
        endif; ?>
    </div>

    <script>
    jQuery(document).ready(function($){
        $(".ct-testimonial-slider").owlCarousel({
            items: <?php echo intval($settings['items']); ?>,
            autoplay: <?php echo !empty($settings['autoplay']) ? 'true' : 'false'; ?>,
            loop: <?php echo !empty($settings['loop']) ? 'true' : 'false'; ?>,
            nav: <?php echo !empty($settings['nav']) ? 'true' : 'false'; ?>,
            dots: <?php echo !empty($settings['dots']) ? 'true' : 'false'; ?>,
            autoplayTimeout: <?php echo intval($settings['speed']); ?>,
            margin: 20,
            responsive:{
                0:{items:1},
                768:{items:Math.min(2, <?php echo intval($settings['items']); ?>)},
                1024:{items:<?php echo intval($settings['items']); ?>}
            }
        });
    });
    </script>
    <?php
    return ob_get_clean();
}
add_shortcode('testimonial_slider', 'ct_testimonial_slider_shortcode');

7. Admin Submenu – Slider Settings

Admin Panel में Testimonials के अंदर एक Submenu बनाएँगे जहाँ से Slider Control किया जा सके।

  • Enable/disable autoplay
  • Enable/disable loop
  • Show/hide dots
  • Set time interval for the carousel
// =====================================================
// 5) Admin submenu: Slider Settings
// =====================================================
function ct_register_slider_settings_page() {
    add_submenu_page(
        'edit.php?post_type=testimonial',
        'Slider Settings',
        'Slider Settings',
        'manage_options',
        'ct-slider-settings',
        'ct_slider_settings_page'
    );
}
add_action('admin_menu', 'ct_register_slider_settings_page');

function ct_slider_settings_page() {
    if (isset($_POST['save_ct_settings'])) {
        if (!current_user_can('manage_options')) { return; }

        $settings = array(
            'items'      => isset($_POST['items']) ? intval($_POST['items']) : 3,
            'autoplay'   => !empty($_POST['autoplay']),
            'loop'       => !empty($_POST['loop']),
            'speed'      => isset($_POST['speed']) ? intval($_POST['speed']) : 3000,
            'nav'        => !empty($_POST['nav']),
            'dots'       => !empty($_POST['dots']),
            'image_size' => isset($_POST['image_size']) ? max(40, intval($_POST['image_size'])) : 80,
        );
        update_option('ct_slider_settings', $settings);
        echo '<div class="updated"><p>Settings Saved.</p></div>';
    }

    $defaults = array(
        'items'      => 3,
        'autoplay'   => true,
        'loop'       => true,
        'speed'      => 3000,
        'nav'        => true,
        'dots'       => true,
        'image_size' => 80,
    );
    $settings = wp_parse_args(get_option('ct_slider_settings', array()), $defaults);
    ?>
    <div class="wrap">
        <h1>Testimonial Slider Settings</h1>
        <form method="post">
            <table class="form-table">
                <tr>
                    <th scope="row">Items Visible</th>
                    <td><input type="number" name="items" min="1" max="10" value="<?php echo esc_attr($settings['items']); ?>"></td>
                </tr>
                <tr>
                    <th scope="row">Autoplay</th>
                    <td><input type="checkbox" name="autoplay" <?php checked($settings['autoplay'], true); ?>></td>
                </tr>
                <tr>
                    <th scope="row">Loop</th>
                    <td><input type="checkbox" name="loop" <?php checked($settings['loop'], true); ?>></td>
                </tr>
                <tr>
                    <th scope="row">Show Navigation Arrows</th>
                    <td><input type="checkbox" name="nav" <?php checked($settings['nav'], true); ?>></td>
                </tr>
                <tr>
                    <th scope="row">Show Dots</th>
                    <td><input type="checkbox" name="dots" <?php checked($settings['dots'], true); ?>></td>
                </tr>
                <tr>
                    <th scope="row">Autoplay Speed (ms)</th>
                    <td><input type="number" name="speed" min="1000" step="100" value="<?php echo esc_attr($settings['speed']); ?>"></td>
                </tr>
                <tr>
                    <th scope="row">Image Size (px)</th>
                    <td><input type="number" name="image_size" min="40" max="300" value="<?php echo esc_attr($settings['image_size']); ?>"></td>
                </tr>
            </table>
            <p><input type="submit" name="save_ct_settings" class="button-primary" value="Save Settings"></p>
        </form>

        <h2>Use this Shortcode</h2>
        <p>
            <input type="text" value="[testimonial_slider]" id="ct-shortcode" readonly style="width:260px;">
            <button type="button" class="button"
                onclick="navigator.clipboard.writeText(document.getElementById('ct-shortcode').value)">Copy</button>
        </p>
    </div>
    <?php
}

Custom Testimonial Slider

 

निष्कर्ष (Conclusion)

इस ट्यूटोरियल में हमने सीखा:

  • Testimonials के लिए Custom Post Type बनाना
  • Extra Fields (Role, Company, Rating) जोड़ना
  • Owl Carousel से Slider बनाना
  • Shortcode [testimonial_slider] बनाना
  • Admin Settings Page ऐड करना

अब आप इस प्लगइन से WordPress में अपने Testimonials Slider को पूरी तरह से Customize कर सकते हैं।

If you need any help, feel free to connect with me — I will be available for you.

Thank you.

Author

Admin

Leave a comment

Your email address will not be published. Required fields are marked *